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