]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/inputcontainer.qc
ce263889da47092273776f5942cb51634d5db5d0
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / inputcontainer.qc
1 #include "inputcontainer.qh"
2 #ifndef ITEM_INPUTCONTAINER_H
3         #define ITEM_INPUTCONTAINER_H
4         #include "container.qc"
5         CLASS(InputContainer, Container)
6                 METHOD(InputContainer, keyDown, float(entity, float, float, float));
7                 METHOD(InputContainer, mouseMove, float(entity, vector));
8                 METHOD(InputContainer, mousePress, float(entity, vector));
9                 METHOD(InputContainer, mouseRelease, float(entity, vector));
10                 METHOD(InputContainer, mouseDrag, float(entity, vector));
11                 METHOD(InputContainer, focusLeave, void(entity));
12                 METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector));
13
14                 METHOD(InputContainer, _changeFocusXY, bool(entity this, vector pos));
15                 ATTRIB(InputContainer, mouseFocusedChild, entity, NULL)
16                 ATTRIB(InputContainer, isTabRoot, float, 0)
17         ENDCLASS(InputContainer)
18 #endif
19
20 #ifdef IMPLEMENTATION
21         void InputContainer_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
22         {
23                 SUPER(InputContainer).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
24                 /*
25                 if(me.parent.instanceOfInputContainer)
26                     me.isTabRoot = 0;
27                 else
28                     me.isTabRoot = 1;
29                 */
30         }
31
32         void InputContainer_focusLeave(entity me)
33         {
34                 SUPER(InputContainer).focusLeave(me);
35                 me.mouseFocusedChild = NULL;
36         }
37
38         float InputContainer_keyDown(entity me, float scan, float ascii, float shift)
39         {
40                 entity f, ff;
41                 if (SUPER(InputContainer).keyDown(me, scan, ascii, shift)) return 1;
42                 if (scan == K_ESCAPE)
43                 {
44                         f = me.focusedChild;
45                         if (f)
46                         {
47                                 me.setFocus(me, NULL);
48                                 return 1;
49                         }
50                         return 0;
51                 }
52                 if (scan == K_TAB)
53                 {
54                         f = me.focusedChild;
55                         if (shift & S_SHIFT)
56                         {
57                                 if (f)
58                                 {
59                                         for (ff = f.prevSibling; ff; ff = ff.prevSibling)
60                                         {
61                                                 if (!ff.focusable) continue;
62                                                 me.setFocus(me, ff);
63                                                 return 1;
64                                         }
65                                 }
66                                 if (!f || me.isTabRoot)
67                                 {
68                                         for (ff = me.lastChild; ff; ff = ff.prevSibling)
69                                         {
70                                                 if (!ff.focusable) continue;
71                                                 me.setFocus(me, ff);
72                                                 return 1;
73                                         }
74                                         return 0;  // AIIIIEEEEE!
75                                 }
76                         }
77                         else
78                         {
79                                 if (f)
80                                 {
81                                         for (ff = f.nextSibling; ff; ff = ff.nextSibling)
82                                         {
83                                                 if (!ff.focusable) continue;
84                                                 me.setFocus(me, ff);
85                                                 return 1;
86                                         }
87                                 }
88                                 if (!f || me.isTabRoot)
89                                 {
90                                         for (ff = me.firstChild; ff; ff = ff.nextSibling)
91                                         {
92                                                 if (!ff.focusable) continue;
93                                                 me.setFocus(me, ff);
94                                                 return 1;
95                                         }
96                                         return 0;  // AIIIIEEEEE!
97                                 }
98                         }
99                 }
100                 return 0;
101         }
102
103         bool InputContainer__changeFocusXY(entity this, vector pos)
104         {
105                 entity e = this.itemFromPoint(this, pos);
106                 if (e && !e.focusable) e = NULL;
107                 entity prev = this.mouseFocusedChild;
108                 this.mouseFocusedChild = e;
109                 if (!e) return false;  // keep focus when hovering over non-focusable elements
110                 if (e != prev)
111                 {
112                         this.setFocus(this, e);
113                         if (e.instanceOfInputContainer)
114                         {
115                                 e.focusedChild = NULL;
116                                 e._changeFocusXY(e, globalToBox(pos, e.Container_origin, e.Container_size));
117                         }
118                 }
119                 return true;  // have focus
120         }
121
122         float InputContainer_mouseDrag(entity me, vector pos)
123         {
124                 if (SUPER(InputContainer).mouseDrag(me, pos)) return 1;
125                 if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return 1;
126                 return 0;
127         }
128         float InputContainer_mouseMove(entity me, vector pos)
129         {
130                 if (me.mouseFocusedChild != me.focusedChild) // if the keyboard moved the focus away
131                         me.mouseFocusedChild = NULL;             // force focusing
132                 if (me._changeFocusXY(me, pos))
133                         if (SUPER(InputContainer).mouseMove(me, pos)) return 1;
134                 if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return 1;
135                 return 0;
136         }
137         float InputContainer_mousePress(entity me, vector pos)
138         {
139                 me.mouseFocusedChild = NULL;  // force focusing
140                 if (me._changeFocusXY(me, pos))
141                         if (SUPER(InputContainer).mousePress(me, pos)) return 1;
142                 if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return 1;
143                 return 0;
144         }
145         float InputContainer_mouseRelease(entity me, vector pos)
146         {
147                 SUPER(InputContainer).mouseRelease(me, pos); // return value?
148                 if (me.focused)                              // am I still eligible for this? (UGLY HACK, but a mouse event could have changed focus away)
149                         if (me._changeFocusXY(me, pos)) return 1;
150                 if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return 1;
151                 return 0;
152         }
153 #endif