summaryrefslogtreecommitdiff
path: root/src/imgui_helper.cpp
blob: 3c771e934c0bf8da560fb898970cdc09612e3997 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#if SPECIAL
#include "main.h"
#endif

// Widgets not directly related to drawing UI.

// Returns a normalized UV position of the composition
static v2
ImGui_ScreenPointToCompUV(ImVec2 ViewportMin, ImVec2 CompPos, ImVec2 CompZoom, ImVec2 MousePos)
{
    ImVec2 LocalMousePos = MousePos - ViewportMin;
    ImVec2 LocalCompPos = CompPos - ViewportMin;
    ImVec2 MouseScreenUV = LocalMousePos - LocalCompPos;
    ImVec2 Result = MouseScreenUV / CompZoom;
    return V2(Result);
}

// NOTE(fox): We have to do a bit of hackery here to tell how many times the
// mouse has been warped during a drag, since it doesn't seem like we can rely
// on SDL_WarpMouseGlobal to update on the first frame of a WantSetPos request.

static void
ImGui_WarpMouse(project_state *State, ImVec2 MousePos, ImVec2 Min, ImVec2 Max, int Direction)
{
    if (Direction & 1) {
        if (MousePos.x < Min.x) {
            State->Warp_WantSetPos = true;
            State->Warp_PositionToSet = ImVec2(Max.x - 5, MousePos.y);
            State->Warp_PositionInitial = MousePos.x;
            State->Warp_Direction = 0;
        }
        if (MousePos.x > Max.x) {
            State->Warp_WantSetPos = true;
            State->Warp_PositionToSet = ImVec2(Min.x + 5, MousePos.y);
            State->Warp_PositionInitial = MousePos.x;
            State->Warp_Direction = 1;
        }
    }
    if (Direction & 2) {
        if (MousePos.y < Min.y) {
            State->Warp_WantSetPos = true;
            State->Warp_PositionToSet = ImVec2(MousePos.x, Max.y - 5);
            State->Warp_PositionInitial = MousePos.y;
            State->Warp_Direction = 2;
        }
        if (MousePos.y > Max.y) {
            State->Warp_WantSetPos = true;
            State->Warp_PositionToSet = ImVec2(MousePos.x, Min.y + 5);
            State->Warp_PositionInitial = MousePos.y;
            State->Warp_Direction = 3;
        }
    }
}

// We record the initial position and the direction of the wrap, and only
// increment the wrap amount when MousePos actually is measured to be what we expect.

static void
ImGui_WarpMouseFinish(project_state *State, ImVec2 MousePos)
{
    if (State->Warp_Direction == 0) {
        if (MousePos.x < State->Warp_PositionInitial) State->Warp_X--;
    } else if (State->Warp_Direction == 1) {
        if (MousePos.x > State->Warp_PositionInitial) State->Warp_X++;
    } else if (State->Warp_Direction == 2) {
        if (MousePos.y < State->Warp_PositionInitial) State->Warp_Y--;
    } else if (State->Warp_Direction == 3) {
        if (MousePos.y > State->Warp_PositionInitial) State->Warp_Y++;
    } else {
        Assert(0);
    }
}

static bool32
ImGui_TestBoxSelection_Point(ImVec2 Pos, ImGuiIO &io, bool32 *Test)
{
    bool32 Result = 0;
    real32 Y_Top =    (io.MouseClickedPos[0].y < io.MousePos.y) ? io.MouseClickedPos[0].y : io.MousePos.y;
    real32 Y_Bottom = (io.MouseClickedPos[0].y > io.MousePos.y) ? io.MouseClickedPos[0].y : io.MousePos.y;
    real32 X_Left =   (io.MouseClickedPos[0].x < io.MousePos.x) ? io.MouseClickedPos[0].x : io.MousePos.x;
    real32 X_Right =  (io.MouseClickedPos[0].x > io.MousePos.x) ? io.MouseClickedPos[0].x : io.MousePos.x;

    if (Pos.y >= Y_Top  && Pos.y <= Y_Bottom &&
        Pos.x >= X_Left && Pos.x <= X_Right)
    {
        if (!(*Test)) {
            *Test = 1;
            Result = 1;
        }
    } else if (!io.KeyShift) {
        *Test = 0;
    }
    return Result;
}