]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu-div0test/item/container.c
support for team select dialog, disabled buttons and grid layout; updated mbuiltin.qc
[divverent/nexuiz.git] / data / qcsrc / menu-div0test / item / container.c
1 #ifdef INTERFACE
2 CLASS(Container) EXTENDS(Item)
3         METHOD(Container, draw, void(entity))
4         METHOD(Container, keyUp, float(entity, float, float, float))
5         METHOD(Container, keyDown, float(entity, float, float, float))
6         METHOD(Container, mouseMove, float(entity, vector))
7         METHOD(Container, mousePress, float(entity, vector))
8         METHOD(Container, mouseDrag, float(entity, vector))
9         METHOD(Container, mouseRelease, float(entity, vector))
10         METHOD(Container, focusLeave, void(entity))
11         METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector))
12         METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector))
13         METHOD(Container, addItem, void(entity, entity, vector, vector, float))
14         METHOD(Container, moveItemAfter, void(entity, entity, entity))
15         METHOD(Container, removeItem, void(entity, entity))
16         METHOD(Container, setFocus, void(entity, entity))
17         METHOD(Container, itemFromPoint, entity(entity, vector))
18         METHOD(Container, open, void(entity))
19         ATTRIB(Container, focusable, float, 0)
20         ATTRIB(Container, firstChild, entity, NULL)
21         ATTRIB(Container, lastChild, entity, NULL)
22         ATTRIB(Container, focusedChild, entity, NULL)
23 ENDCLASS(Container)
24 #endif
25
26 #ifdef IMPLEMENTATION
27 .vector Container_origin;
28 .vector Container_size;
29 .float Container_alpha;
30 .entity nextSibling;
31 .entity prevSibling;
32
33 void openContainer(entity me)
34 {
35         entity e;
36         for(e = me.firstChild; e; e = e.nextSibling)
37                 e.open(e);
38 }
39
40 void resizeNotifyLieContainer(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField)
41 {
42         entity e;
43         vector o, s;
44         for(e = me.firstChild; e; e = e.nextSibling)
45         {
46                 o = e.originField;
47                 s = e.sizeField;
48                 e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
49         }
50         resizeNotifyItem(me, relOrigin, relSize, absOrigin, absSize);
51 }
52
53 void resizeNotifyContainer(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
54 {
55         me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size);
56 }
57
58 entity itemFromPointContainer(entity me, vector pos)
59 {
60         entity e;
61         vector o, s;
62         for(e = me.lastChild; e; e = e.prevSibling)
63         {
64                 o = e.Container_origin;
65                 s = e.Container_size;
66                 if(pos_x < o_x) continue;
67                 if(pos_y < o_y) continue;
68                 if(pos_x >= o_x + s_x) continue;
69                 if(pos_y >= o_y + s_y) continue;
70                 return e;
71         }
72         return NULL;
73 }
74
75 void drawContainer(entity me)
76 {
77         vector oldshift;
78         vector oldscale;
79         float oldalpha;
80         entity e;
81
82         oldshift = draw_shift;
83         oldscale = draw_scale;
84         oldalpha = draw_alpha;
85         me.focusable = 0;
86         for(e = me.firstChild; e; e = e.nextSibling)
87         {
88                 if(e.focusable)
89                         me.focusable += 1;
90                 if(!e.Container_alpha)
91                         continue;
92                 draw_shift = boxToGlobal(e.Container_origin, oldshift, oldscale);
93                 draw_scale = boxToGlobalSize(e.Container_size, oldscale);
94                 draw_alpha *= e.Container_alpha;
95                 e.draw(e);
96                 draw_shift = oldshift;
97                 draw_scale = oldscale;
98                 draw_alpha = oldalpha;
99         }
100 };
101
102 void focusLeaveContainer(entity me)
103 {
104         me.setFocus(me, NULL);
105 }
106
107 float keyUpContainer(entity me, float scan, float ascii, float shift)
108 {
109         entity f;
110         f = me.focusedChild;
111         if(f)
112                 return f.keyUp(f, scan, ascii, shift);
113         return 0;
114 }
115
116 float keyDownContainer(entity me, float scan, float ascii, float shift)
117 {
118         entity f;
119         f = me.focusedChild;
120         if(f)
121                 return f.keyDown(f, scan, ascii, shift);
122         return 0;
123 }
124
125 float mouseMoveContainer(entity me, vector pos)
126 {
127         entity f;
128         f = me.focusedChild;
129         if(f)
130                 return f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size));
131         return 0;
132 }
133 float mousePressContainer(entity me, vector pos)
134 {
135         entity f;
136         f = me.focusedChild;
137         if(f)
138                 return f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
139         return 0;
140 }
141 float mouseDragContainer(entity me, vector pos)
142 {
143         entity f;
144         f = me.focusedChild;
145         if(f)
146                 return f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size));
147         return 0;
148 }
149 float mouseReleaseContainer(entity me, vector pos)
150 {
151         entity f;
152         f = me.focusedChild;
153         if(f)
154                 return f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size));
155         return 0;
156 }
157
158 void addItemContainer(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
159 {
160         if(other.parent)
161                 error("Can't add already added item!");
162
163         if(other.focusable)
164                 me.focusable += 1;
165
166         other.parent = me;
167         other.Container_origin = theOrigin;
168         other.Container_size = theSize;
169         other.Container_alpha = theAlpha;
170
171         entity f, l;
172         f = me.firstChild;
173         l = me.lastChild;
174
175         if(l)
176                 l.nextSibling = other;
177         else
178                 me.firstChild = other;
179
180         other.prevSibling = l;
181         other.nextSibling = NULL;
182         me.lastChild = other;
183
184         draw_NeedResizeNotify = 1;
185 }
186
187 void removeItemContainer(entity me, entity other)
188 {
189         if(other.parent != me)
190                 error("Can't remove from wrong container!");
191
192         if(other.focusable)
193                 me.focusable -= 1;
194
195         other.parent = NULL;
196
197         entity n, p, f, l;
198         f = me.firstChild;
199         l = me.lastChild;
200         n = other.nextSibling;
201         p = other.prevSibling;
202
203         if(p)
204                 p.nextSibling = n;
205         else
206                 me.firstChild = n;
207
208         if(n)
209                 n.prevSibling = p;
210         else
211                 me.lastChild = p;
212 }
213
214 void setFocusContainer(entity me, entity other)
215 {
216         if(other)
217                 if(!me.focused)
218                         error("Trying to set focus in a non-focused control!");
219         if(me.focusedChild == other)
220                 return;
221         //print(etos(me), ": focus changes from ", etos(me.focusedChild), " to ", etos(other), "\n");
222         if(me.focusedChild)
223         {
224                 me.focusedChild.focused = 0;
225                 me.focusedChild.focusLeave(me.focusedChild);
226         }
227         if(other)
228         {
229                 other.focused = 1;
230                 other.focusEnter(other);
231         }
232         me.focusedChild = other;
233 }
234
235 void moveItemAfterContainer(entity me, entity other, entity dest)
236 {
237         // first: remove other from the chain
238         entity n, p, f, l;
239
240         if(other.parent != me)
241                 error("Can't move in wrong container!");
242
243         f = me.firstChild;
244         l = me.lastChild;
245         n = other.nextSibling;
246         p = other.prevSibling;
247
248         if(p)
249                 p.nextSibling = n;
250         else
251                 me.firstChild = n;
252
253         if(n)
254                 n.prevSibling = p;
255         else
256                 me.lastChild = p;
257         
258         // now other got removed. Insert it behind dest now.
259         other.prevSibling = dest;
260         if(dest)
261                 other.nextSibling = dest.nextSibling;
262         else
263                 other.nextSibling = me.firstChild;
264
265         if(dest)
266                 dest.nextSibling = other;
267         else
268                 me.firstChild = other;
269
270         if(other.nextSibling)
271                 other.nextSibling.prevSibling = other;
272         else
273                 me.lastChild = other;
274 }
275 #endif