1 #include "container.qh"
3 void Container_enterSubitem(entity me, entity sub)
5 me.enterLieSubitem(me, sub.Container_origin, sub.Container_size, sub.Container_fontscale, sub.Container_alpha);
8 void Container_enterLieSubitem(entity me, vector o, vector s, vector f, float a)
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;
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);
21 void Container_leaveSubitem(entity me)
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;
29 void Container_showNotify(entity me)
34 for (e = me.firstChild; e; e = e.nextSibling)
35 if (e.Container_alpha > 0) e.showNotify(e);
38 void Container_hideNotify(entity me)
41 if (!me.shown) return;
43 for (e = me.firstChild; e; e = e.nextSibling)
44 if (e.Container_alpha > 0) e.hideNotify(e);
47 void Container_setAlphaOf(entity me, entity other, float theAlpha)
51 if (other.Container_alpha > 0) other.hideNotify(other);
55 if (other.Container_alpha <= 0) other.showNotify(other);
57 other.Container_alpha = theAlpha;
60 void Container_resizeNotifyLie(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField, .vector fontScaleField)
65 for (e = me.firstChild; e; e = e.nextSibling)
69 me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha);
70 e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
76 for (e = me.firstChild; e; e = e.nextSibling)
83 me.enterLieSubitem(me, o, s, e.(fontScaleField), e.Container_alpha);
84 e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize));
89 SUPER(Container).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
92 void Container_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
94 me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size, Container_fontscale);
97 entity Container_itemFromPoint(entity me, vector pos)
101 for (e = me.lastChild; e; e = e.prevSibling)
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;
114 void Container_draw(entity me)
119 for (e = me.firstChild; e; e = e.nextSibling)
121 if (e.focusable) me.focusable += 1;
122 if (e.Container_alpha < 0.003) // can't change color values anyway
124 me.enterSubitem(me, e);
129 SUPER(Container).draw(me);
132 void Container_focusLeave(entity me)
134 me.setFocus(me, NULL);
137 float Container_keyUp(entity me, float scan, float ascii, float shift)
144 me.enterSubitem(me, f);
145 r = f.keyUp(f, scan, ascii, shift);
152 float Container_keyDown(entity me, float scan, float ascii, float shift)
159 me.enterSubitem(me, f);
160 r = f.keyDown(f, scan, ascii, shift);
167 float Container_mouseMove(entity me, vector pos)
174 me.enterSubitem(me, f);
175 r = f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size));
181 float Container_mousePress(entity me, vector pos)
188 me.enterSubitem(me, f);
189 r = f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size));
195 float Container_mouseDrag(entity me, vector pos)
202 me.enterSubitem(me, f);
203 r = f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size));
209 float Container_mouseRelease(entity me, vector pos)
216 me.enterSubitem(me, f);
217 r = f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size));
224 void Container_addItemCentered(entity me, entity other, vector theSize, float theAlpha)
226 me.addItem(me, other, '0.5 0.5 0' - 0.5 * theSize, theSize, theAlpha);
229 void Container_addItemRightCentered(entity me, entity other, vector theSize, float theAlpha)
231 me.addItem(me, other, '1 0.5 0' - 0.5 * theSize, theSize, theAlpha);
234 void Container_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
236 if (other.parent) error("Can't add already added item!");
238 if (other.focusable) me.focusable += 1;
242 theOrigin.x -= 0.5 * (theSize.x - 1);
247 theOrigin.y -= 0.5 * (theSize.y - 1);
250 theOrigin.x = bound(0, theOrigin.x, 1 - theSize.x);
251 theOrigin.y = bound(0, theOrigin.y, 1 - theSize.y);
254 other.Container_origin = theOrigin;
255 other.Container_size = theSize;
257 // don't call setAlphaOf, it would uneccessarily trigger showNotify
258 //me.setAlphaOf(me, other, theAlpha);
259 other.Container_alpha = theAlpha;
264 if (l) l.nextSibling = other;
265 else me.firstChild = other;
267 other.prevSibling = l;
268 other.nextSibling = NULL;
269 me.lastChild = other;
272 void Container_removeItem(entity me, entity other)
274 if (other.parent != me) error("Can't remove from wrong container!");
276 if (other.focusable) me.focusable -= 1;
281 n = other.nextSibling;
282 p = other.prevSibling;
284 if (p) p.nextSibling = n;
285 else me.firstChild = n;
287 if (n) n.prevSibling = p;
288 else me.lastChild = p;
291 void Container_setFocus(entity me, entity other)
293 if (me.focusedChild == other) return;
297 me.focusedChild.focused = 0;
298 me.focusedChild.focusLeave(me.focusedChild);
299 me.focusedChild = NULL;
304 if (!me.focused) error("Trying to set focus in a non-focused control!");
308 me.focusedChild = me.savedFocus;
309 me.savedFocus = NULL;
310 me.focusedChild.focused = 1;
311 me.focusedChild.focusEnter(me.focusedChild);
313 if (me.focusedChild.instanceOfContainer) me.focusedChild.setFocus(me.focusedChild, me.focusedChild.savedFocus);
317 me.focusedChild = other;
318 me.focusedChild.focused = 1;
319 me.focusedChild.focusEnter(me.focusedChild);
324 void Container_saveFocus(entity me)
326 me.savedFocus = me.focusedChild;
328 if (me.focusedChild.instanceOfContainer) me.focusedChild.saveFocus(me.focusedChild);
331 void Container_moveItemAfter(entity me, entity other, entity dest)
333 // first: remove other from the chain
336 if (other.parent != me) error("Can't move in wrong container!");
338 n = other.nextSibling;
339 p = other.prevSibling;
341 if (p) p.nextSibling = n;
342 else me.firstChild = n;
344 if (n) n.prevSibling = p;
345 else me.lastChild = p;
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;
352 if (dest) dest.nextSibling = other;
353 else me.firstChild = other;
355 if (other.nextSibling) other.nextSibling.prevSibling = other;
356 else me.lastChild = other;
359 entity Container_preferredFocusedGrandChild(entity me)
366 for (e = me.firstChild; e; e = e.nextSibling)
368 if (e.instanceOfContainer)
370 e2 = e.preferredFocusedGrandChild(e);
372 if (!best || best.preferredFocusPriority < e2.preferredFocusPriority) best = e2;
375 if (!best || best.preferredFocusPriority < e.preferredFocusPriority) best = e;