Listbox: highlight item under the cursor
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / inputcontainer.qc
1 #ifdef INTERFACE
2 CLASS(InputContainer) EXTENDS(Container)
3         METHOD(InputContainer, keyDown, float(entity, float, float, float))
4         METHOD(InputContainer, mouseMove, float(entity, vector))
5         METHOD(InputContainer, mousePress, float(entity, vector))
6         METHOD(InputContainer, mouseRelease, float(entity, vector))
7         METHOD(InputContainer, mouseDrag, float(entity, vector))
8         METHOD(InputContainer, focusLeave, void(entity))
9         METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector))
10
11         METHOD(InputContainer, _changeFocusXY, float(entity, vector))
12         ATTRIB(InputContainer, mouseFocusedChild, entity, NULL)
13         ATTRIB(InputContainer, isTabRoot, float, 0)
14 ENDCLASS(InputContainer)
15 #endif
16
17 #ifdef IMPLEMENTATION
18 void InputContainer_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
19 {
20         SUPER(InputContainer).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
21         /*
22         if(me.parent.instanceOfInputContainer)
23                 me.isTabRoot = 0;
24         else
25                 me.isTabRoot = 1;
26         */
27 }
28
29 void InputContainer_focusLeave(entity me)
30 {
31         SUPER(InputContainer).focusLeave(me);
32         me.mouseFocusedChild = NULL;
33 }
34
35 float InputContainer_keyDown(entity me, float scan, float ascii, float shift)
36 {
37         entity f, ff;
38         if(SUPER(InputContainer).keyDown(me, scan, ascii, shift))
39                 return 1;
40         if(scan == K_ESCAPE)
41         {
42                 f = me.focusedChild;
43                 if(f)
44                 {
45                         me.setFocus(me, NULL);
46                         return 1;
47                 }
48                 return 0;
49         }
50         if(scan == K_TAB)
51         {
52                 f = me.focusedChild;
53                 if(shift & S_SHIFT)
54                 {
55                         if(f)
56                         {
57                                 for(ff = f.prevSibling; ff; ff = ff.prevSibling)
58                                 {
59                                         if (!ff.focusable)
60                                                 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)
70                                                 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)
84                                                 continue;
85                                         me.setFocus(me, ff);
86                                         return 1;
87                                 }
88                         }
89                         if(!f || me.isTabRoot)
90                         {
91                                 for(ff = me.firstChild; ff; ff = ff.nextSibling)
92                                 {
93                                         if (!ff.focusable)
94                                                 continue;
95                                         me.setFocus(me, ff);
96                                         return 1;
97                                 }
98                                 return 0; // AIIIIEEEEE!
99                         }
100                 }
101         }
102         return 0;
103 }
104
105 float InputContainer__changeFocusXY(entity me, vector pos)
106 {
107         entity e, ne;
108         e = me.mouseFocusedChild;
109         ne = me.itemFromPoint(me, pos);
110         if(ne)
111                 if (!ne.focusable)
112                         ne = NULL;
113         me.mouseFocusedChild = ne;
114         if(ne)
115                 if(ne != e)
116                 {
117                         me.setFocus(me, ne);
118                         if(ne.instanceOfInputContainer)
119                         {
120                                 ne.focusedChild = NULL;
121                                 ne._changeFocusXY(e, globalToBox(pos, ne.Container_origin, ne.Container_size));
122                         }
123                 }
124         return (ne != NULL);
125 }
126
127 float InputContainer_mouseDrag(entity me, vector pos)
128 {
129         if(SUPER(InputContainer).mouseDrag(me, pos))
130                 return 1;
131         if(pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1)
132                 return 1;
133         return 0;
134 }
135 float InputContainer_mouseMove(entity me, vector pos)
136 {
137         if(me.mouseFocusedChild != me.focusedChild) // if the keyboard moved the focus away
138                 me.mouseFocusedChild = NULL; // force focusing
139         if(me._changeFocusXY(me, pos))
140                 if(SUPER(InputContainer).mouseMove(me, pos))
141                         return 1;
142         if(pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1)
143                 return 1;
144         return 0;
145 }
146 float InputContainer_mousePress(entity me, vector pos)
147 {
148         me.mouseFocusedChild = NULL; // force focusing
149         if(me._changeFocusXY(me, pos))
150                 if(SUPER(InputContainer).mousePress(me, pos))
151                         return 1;
152         if(pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1)
153                 return 1;
154         return 0;
155 }
156 float InputContainer_mouseRelease(entity me, vector pos)
157 {
158         SUPER(InputContainer).mouseRelease(me, pos); // return value?
159         if(me.focused) // am I still eligible for this? (UGLY HACK, but a mouse event could have changed focus away)
160                 if(me._changeFocusXY(me, pos))
161                         return 1;
162         if(pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1)
163                 return 1;
164         return 0;
165 }
166 #endif