]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/container.qc
OK weapons: Better secondary attack code.
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / container.qc
1 #include "container.qh"
2
3         void Container_enterSubitem(entity me, entity sub)
4         {
5                 me.enterLieSubitem(me, sub.Container_origin, sub.Container_size, sub.Container_fontscale, sub.Container_alpha);
6         }
7
8         void Container_enterLieSubitem(entity me, vector o, vector s, vector f, float a)
9         {
10                 me.Container_save_shift = draw_shift;
11                 me.Container_save_scale = draw_scale;
12                 me.Container_save_alpha = draw_alpha;
13                 me.Container_save_fontscale = draw_fontscale;
14
15                 draw_shift = boxToGlobal(o, draw_shift, draw_scale);
16                 draw_scale = boxToGlobalSize(s, draw_scale);
17                 if (f != '0 0 0') draw_fontscale = boxToGlobalSize(f, draw_fontscale);
18                 draw_alpha *= a;
19         }
20
21         void Container_leaveSubitem(entity me)
22         {
23                 draw_shift = me.Container_save_shift;
24                 draw_scale = me.Container_save_scale;
25                 draw_alpha = me.Container_save_alpha;
26                 draw_fontscale = me.Container_save_fontscale;
27         }
28
29         void Container_showNotify(entity me)
30         {
31                 entity e;
32                 if (me.shown) return;
33                 me.shown = 1;
34                 for (e = me.firstChild; e; e = e.nextSibling)
35                         if (e.Container_alpha > 0) e.showNotify(e);
36         }
37
38         void Container_hideNotify(entity me)
39         {
40                 entity e;
41                 if (!me.shown) return;
42                 me.shown = 0;
43                 for (e = me.firstChild; e; e = e.nextSibling)
44                         if (e.Container_alpha > 0) e.hideNotify(e);
45         }
46
47         void Container_setAlphaOf(entity me, entity other, float theAlpha)
48         {
49                 if (theAlpha <= 0)
50                 {
51                         if (other.Container_alpha > 0) other.hideNotify(other);
52                 }
53                 else  // value > 0
54                 {
55                         if (other.Container_alpha <= 0) other.showNotify(other);
56                 }
57                 other.Container_alpha = theAlpha;
58         }
59
60         void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField, .vector fontScaleField)
61         {
62                 entity e;
63                 vector o, s;
64                 float d;
65                 for (e = me.firstChild; e; e = e.nextSibling)
66                 {
67                         o = e.(originField);
68                         s = e.(sizeField);
69                         me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha);
70                         e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
71                         me.leaveSubitem(me);
72                 }
73                 do
74                 {
75                         d = 0;
76                         for (e = me.firstChild; e; e = e.nextSibling)
77                                 if (e.resized)
78                                 {
79                                         e.resized = 0;
80                                         d = 1;
81                                         o = e.(originField);
82                                         s = e.(sizeField);
83                                         me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha);
84                                         e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
85                                         me.leaveSubitem(me);
86                                 }
87                 }
88                 while (d);
89                 SUPER(Container).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
90         }
91
92         void Container_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
93         {
94                 me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size, Container_fontscale);
95         }
96
97         entity Container_itemFromPoint(entity me, vector pos)
98         {
99                 entity e;
100                 vector o, s;
101                 for (e = me.lastChild; e; e = e.prevSibling)
102                 {
103                         o = e.Container_origin;
104                         s = e.Container_size;
105                         if (pos.x < o.x) continue;
106                         if (pos.y < o.y) continue;
107                         if (pos.x >= o.x + s.x) continue;
108                         if (pos.y >= o.y + s.y) continue;
109                         return e;
110                 }
111                 return NULL;
112         }
113
114         void Container_draw(entity me)
115         {
116                 entity e;
117
118                 me.focusable = 0;
119                 for (e = me.firstChild; e; e = e.nextSibling)
120                 {
121                         if (e.focusable) me.focusable += 1;
122                         if (e.Container_alpha < 0.003)  // can't change color values anyway
123                                 continue;
124                         me.enterSubitem(me, e);
125                         e.draw(e);
126                         me.leaveSubitem(me);
127                 }
128
129                 SUPER(Container).draw(me);
130         }
131
132         void Container_focusLeave(entity me)
133         {
134                 me.setFocus(me, NULL);
135         }
136
137         float Container_keyUp(entity me, float scan, float ascii, float shift)
138         {
139                 entity f;
140                 float r;
141                 f = me.focusedChild;
142                 if (f)
143                 {
144                         me.enterSubitem(me, f);
145                         r = f.keyUp(f, scan, ascii, shift);
146                         me.leaveSubitem(me);
147                         return r;
148                 }
149                 return 0;
150         }
151
152         float Container_keyDown(entity me, float scan, float ascii, float shift)
153         {
154                 entity f;
155                 float r;
156                 f = me.focusedChild;
157                 if (f)
158                 {
159                         me.enterSubitem(me, f);
160                         r = f.keyDown(f, scan, ascii, shift);
161                         me.leaveSubitem(me);
162                         return r;
163                 }
164                 return 0;
165         }
166
167         float Container_mouseMove(entity me, vector pos)
168         {
169                 entity f;
170                 float r;
171                 f = me.focusedChild;
172                 if (f)
173                 {
174                         me.enterSubitem(me, f);
175                         r = f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size));
176                         me.leaveSubitem(me);
177                         return r;
178                 }
179                 return 0;
180         }
181         float Container_mousePress(entity me, vector pos)
182         {
183                 entity f;
184                 float r;
185                 f = me.focusedChild;
186                 if (f)
187                 {
188                         me.enterSubitem(me, f);
189                         r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
190                         me.leaveSubitem(me);
191                         return r;
192                 }
193                 return 0;
194         }
195         float Container_mouseDrag(entity me, vector pos)
196         {
197                 entity f;
198                 float r;
199                 f = me.focusedChild;
200                 if (f)
201                 {
202                         me.enterSubitem(me, f);
203                         r = f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size));
204                         me.leaveSubitem(me);
205                         return r;
206                 }
207                 return 0;
208         }
209         float Container_mouseRelease(entity me, vector pos)
210         {
211                 entity f;
212                 float r;
213                 f = me.focusedChild;
214                 if (f)
215                 {
216                         me.enterSubitem(me, f);
217                         r = f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size));
218                         me.leaveSubitem(me);
219                         return r;
220                 }
221                 return 0;
222         }
223
224         void Container_addItemCentered(entity me, entity other, vector theSize, float theAlpha)
225         {
226                 me.addItem(me, other, '0.5 0.5 0' - 0.5 * theSize, theSize, theAlpha);
227         }
228
229         void Container_addItemRightCentered(entity me, entity other, vector theSize, float theAlpha)
230         {
231                 me.addItem(me, other, '1 0.5 0' - 0.5 * theSize, theSize, theAlpha);
232         }
233
234         void Container_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
235         {
236                 if (other.parent) error("Can't add already added item!");
237
238                 if (other.focusable) me.focusable += 1;
239
240                 if (theSize.x > 1)
241                 {
242                         theOrigin.x -= 0.5 * (theSize.x - 1);
243                         theSize.x = 1;
244                 }
245                 if (theSize.y > 1)
246                 {
247                         theOrigin.y -= 0.5 * (theSize.y - 1);
248                         theSize.y = 1;
249                 }
250                 theOrigin.x = bound(0, theOrigin.x, 1 - theSize.x);
251                 theOrigin.y = bound(0, theOrigin.y, 1 - theSize.y);
252
253                 other.parent = me;
254                 other.Container_origin = theOrigin;
255                 other.Container_size = theSize;
256
257                 // don't call setAlphaOf, it would uneccessarily trigger showNotify
258                 //me.setAlphaOf(me, other, theAlpha);
259                 other.Container_alpha = theAlpha;
260
261                 entity l;
262                 l = me.lastChild;
263
264                 if (l) l.nextSibling = other;
265                 else me.firstChild = other;
266
267                 other.prevSibling = l;
268                 other.nextSibling = NULL;
269                 me.lastChild = other;
270         }
271
272         void Container_removeItem(entity me, entity other)
273         {
274                 if (other.parent != me) error("Can't remove from wrong container!");
275
276                 if (other.focusable) me.focusable -= 1;
277
278                 other.parent = NULL;
279
280                 entity n, p;
281                 n = other.nextSibling;
282                 p = other.prevSibling;
283
284                 if (p) p.nextSibling = n;
285                 else me.firstChild = n;
286
287                 if (n) n.prevSibling = p;
288                 else me.lastChild = p;
289         }
290
291         void Container_setFocus(entity me, entity other)
292         {
293                 if (me.focusedChild == other) return;
294
295                 if (me.focusedChild)
296                 {
297                         me.focusedChild.focused = 0;
298                         me.focusedChild.focusLeave(me.focusedChild);
299                         me.focusedChild = NULL;
300                 }
301
302                 if (other)
303                 {
304                         if (!me.focused) error("Trying to set focus in a non-focused control!");
305
306                         if (me.savedFocus)
307                         {
308                                 me.focusedChild = me.savedFocus;
309                                 me.savedFocus = NULL;
310                                 me.focusedChild.focused = 1;
311                                 me.focusedChild.focusEnter(me.focusedChild);
312
313                                 if (me.focusedChild.instanceOfContainer) me.focusedChild.setFocus(me.focusedChild, me.focusedChild.savedFocus);
314                         }
315                         else
316                         {
317                                 me.focusedChild = other;
318                                 me.focusedChild.focused = 1;
319                                 me.focusedChild.focusEnter(me.focusedChild);
320                         }
321                 }
322         }
323
324         void Container_saveFocus(entity me)
325         {
326                 me.savedFocus = me.focusedChild;
327
328                 if (me.focusedChild.instanceOfContainer) me.focusedChild.saveFocus(me.focusedChild);
329         }
330
331         void Container_moveItemAfter(entity me, entity other, entity dest)
332         {
333                 // first: remove other from the chain
334                 entity n, p;
335
336                 if (other.parent != me) error("Can't move in wrong container!");
337
338                 n = other.nextSibling;
339                 p = other.prevSibling;
340
341                 if (p) p.nextSibling = n;
342                 else me.firstChild = n;
343
344                 if (n) n.prevSibling = p;
345                 else me.lastChild = p;
346
347                 // now other got removed. Insert it behind dest now.
348                 other.prevSibling = dest;
349                 if (dest) other.nextSibling = dest.nextSibling;
350                 else other.nextSibling = me.firstChild;
351
352                 if (dest) dest.nextSibling = other;
353                 else me.firstChild = other;
354
355                 if (other.nextSibling) other.nextSibling.prevSibling = other;
356                 else me.lastChild = other;
357         }
358
359         entity Container_preferredFocusedGrandChild(entity me)
360         {
361                 entity e, e2;
362                 entity best;
363
364                 best = NULL;
365
366                 for (e = me.firstChild; e; e = e.nextSibling)
367                 {
368                         if (e.instanceOfContainer)
369                         {
370                                 e2 = e.preferredFocusedGrandChild(e);
371                                 if (e2)
372                                         if (!best || best.preferredFocusPriority < e2.preferredFocusPriority) best = e2;
373                         }
374                         if (e)
375                                 if (!best || best.preferredFocusPriority < e.preferredFocusPriority) best = e;
376                 }
377
378                 return best;
379         }