Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
modalcontroller.qc
Go to the documentation of this file.
1#include "modalcontroller.qh"
2
3#include "button.qh"
4
14
16 {
17 me.hideAll(me, 1);
18 me.showChild(me, root, '0 0 0', '0 0 0', 1); // someone else animates for us
19 }
20
21 void TabButton_Click(entity button, entity tab)
22 {
23 if (tab.ModalController_state == 1)
24 return;
25 tab.parent.hideAll(tab.parent, 0);
26 button.forcePressed = true;
27 tab.ModalController_controllingButton = button;
28 tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0);
29 }
30
32 {
33 DialogOpenButton_Click_withCoords(button, tab, button.origin, button.size);
34 }
35
36 void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize)
37 {
38 if (tab.ModalController_state)
39 return;
40 if (button)
41 button.forcePressed = true;
42 if (tab.parent.focusedChild)
43 tab.parent.focusedChild.saveFocus(tab.parent.focusedChild);
44 tab.ModalController_controllingButton = button;
45 tab.parent.showChild(tab.parent, tab, theOrigin, theSize, 0);
46 }
47
49 {
50 tab.parent.hideChild(tab.parent, tab, 0);
51 }
52
53 void ModalController_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
54 {
55 me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, ModalController_initialOrigin, ModalController_initialSize, ModalController_initialFontScale);
56 }
57
58 void ModalController_switchState(entity me, entity other, float state, float skipAnimation)
59 {
60 float previousState = other.ModalController_state;
61 if (state == previousState && !skipAnimation)
62 return;
63 other.ModalController_state = state;
64 switch (state)
65 {
66 case 0:
67 other.ModalController_factor = 1 - other.Container_alpha / other.ModalController_initialAlpha;
68 // fading out
69 break;
70 case 1:
71 other.ModalController_factor = other.Container_alpha / other.ModalController_initialAlpha;
72 if (previousState == 0 && !skipAnimation)
73 {
74 other.Container_origin = other.ModalController_buttonOrigin;
75 other.Container_size = other.ModalController_buttonSize;
76 }
77 // zooming in
78 break;
79 case 2:
80 other.ModalController_factor = bound(0, (1 - other.Container_alpha / other.ModalController_initialAlpha) / me.fadedAlpha, 1);
81 // fading out halfway
82 break;
83 }
84 if (skipAnimation) other.ModalController_factor = 1;
85 }
86
88 {
89 entity e;
90 float f; // animation factor
91 float df; // animation step size
92 float prevFactor, targetFactor;
93 vector targetOrigin, targetSize;
94 float targetAlpha;
95
96 entity front = NULL;
97 for (e = me.firstChild; e; e = e.nextSibling)
98 if (e.ModalController_state)
99 {
100 if (front)
101 me.switchState(me, front, 2, 0);
102 front = e;
103 }
104 if (front)
105 me.switchState(me, front, 1, 0);
106
107 df = frametime * 3; // animation speed
108
109 bool animating = false;
110 for (e = me.firstChild; e; e = e.nextSibling)
111 {
112 if (e.ModalController_state == 2)
113 {
114 // fading out partially
115 targetOrigin = e.Container_origin; // stay as is
116 targetSize = e.Container_size; // stay as is
117 targetAlpha = me.fadedAlpha * e.ModalController_initialAlpha;
118 }
119 else if (e.ModalController_state == 1)
120 {
121 // zooming in
122 targetOrigin = e.ModalController_initialOrigin;
123 targetSize = e.ModalController_initialSize;
124 targetAlpha = e.ModalController_initialAlpha;
125 }
126 else
127 {
128 // fading out
129 targetOrigin = e.Container_origin; // stay as is
130 targetSize = e.Container_size; // stay as is
131 targetAlpha = 0;
132 }
133
134 f = (e.ModalController_factor = min(1, e.ModalController_factor + df));
135 if (f == 1)
136 {
137 prevFactor = 0;
138 targetFactor = 1;
139 e.Container_origin = targetOrigin;
140 e.Container_size = targetSize;
141 me.setAlphaOf(me, e, targetAlpha);
142 }
143 else
144 {
145 prevFactor = (1 - f) / (1 - f + df);
146 if (!e.ModalController_state) // optimize code and avoid precision errors
147 me.setAlphaOf(me, e, e.Container_alpha * prevFactor);
148 else
149 {
150 animating = true;
151 targetFactor = df / (1 - f + df);
152
153 if (e.ModalController_state == 1)
154 {
155 e.Container_origin = e.Container_origin * prevFactor + targetOrigin * targetFactor;
156 e.Container_size = e.Container_size * prevFactor + targetSize * targetFactor;
157 }
158 me.setAlphaOf(me, e, e.Container_alpha * prevFactor + targetAlpha * targetFactor);
159 }
160 }
161 // assume: o == to * f_prev + X * (1 - f_prev)
162 // make: o' = to * f + X * (1 - f)
163 // -->
164 // X == (o - to * f_prev) / (1 - f_prev)
165 // o' = to * f + (o - to * f_prev) / (1 - f_prev) * (1 - f)
166 // --> (maxima)
167 // o' = (to * (f - f_prev) + o * (1 - f)) / (1 - f_prev)
168
169 if (e.ModalController_state == 1)
170 {
171 vector fs = globalToBoxSize(e.Container_size, e.ModalController_initialSize);
172 e.Container_fontscale.x = fs.x * e.ModalController_initialFontScale.x;
173 e.Container_fontscale.y = fs.y * e.ModalController_initialFontScale.y;
174 }
175 }
176
177 if (animating || !me.focused)
178 me.setFocus(me, NULL);
179 else
180 me.setFocus(me, front);
181 SUPER(ModalController).draw(me);
182 }
183
185 {
186 me.addItem(me, other, '0 0 0', '1 1 1', 1);
187 tabButton.onClick = TabButton_Click;
188 tabButton.onClickEntity = other;
189 other.tabSelectingButton = tabButton;
190 if (other == me.firstChild)
191 {
192 tabButton.forcePressed = true;
193 other.ModalController_controllingButton = tabButton;
194 me.showChild(me, other, '0 0 0', '0 0 0', 1);
195 }
196 }
197
198 void ModalController_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
199 {
200 SUPER(ModalController).addItem(me, other, theOrigin, theSize, (other == me.firstChild) ? theAlpha : 0);
201 other.ModalController_initialFontScale = other.Container_fontscale;
202 other.ModalController_initialSize = other.Container_size;
203 other.ModalController_initialOrigin = other.Container_origin;
204 other.ModalController_initialAlpha = theAlpha; // hope Container never modifies this
205 if (other.ModalController_initialFontScale == '0 0 0')
206 other.ModalController_initialFontScale = '1 1 0';
207 }
208
209 void ModalController_showChild(entity me, entity other, vector theOrigin, vector theSize, float skipAnimation)
210 {
211 if (other.ModalController_state == 0 || skipAnimation)
212 {
213 me.setFocus(me, NULL);
214 if (!skipAnimation)
215 {
216 other.ModalController_buttonOrigin = globalToBox(theOrigin, me.origin, me.size);
217 other.ModalController_buttonSize = globalToBoxSize(theSize, me.size);
218 }
219 me.switchState(me, other, 1, skipAnimation);
220 } // zoom in from button (factor increases)
221 }
222
223 void ModalController_hideAll(entity me, float skipAnimation)
224 {
225 entity e;
226 for (e = me.firstChild; e; e = e.nextSibling)
227 me.hideChild(me, e, skipAnimation);
228 }
229
230 void ModalController_hideChild(entity me, entity other, float skipAnimation)
231 {
232 if (other.ModalController_state || skipAnimation)
233 {
234 me.setFocus(me, NULL);
235 me.switchState(me, other, 0, skipAnimation);
236 if (other.ModalController_controllingButton)
237 {
238 other.ModalController_controllingButton.forcePressed = false;
239 other.ModalController_controllingButton = NULL;
240 }
241 } // just alpha fade out (factor increases and decreases alpha)
242 }
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
entity other
float frametime
int state
vector globalToBox(vector v, vector theOrigin, vector theScale)
Definition draw.qc:30
vector globalToBoxSize(vector v, vector theScale)
Definition draw.qc:38
float bound(float min, float value, float max)
float min(float f,...)
vector ModalController_initialFontScale
void ModalController_hideAll(entity me, float skipAnimation)
vector ModalController_initialOrigin
void ModalController_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
void ModalController_initializeDialog(entity me, entity root)
void DialogCloseButton_Click(entity button, entity tab)
void TabButton_Click(entity button, entity tab)
vector ModalController_buttonSize
void ModalController_showChild(entity me, entity other, vector theOrigin, vector theSize, float skipAnimation)
void ModalController_addTab(entity me, entity other, entity tabButton)
void ModalController_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
void ModalController_draw(entity me)
void DialogOpenButton_Click(entity button, entity tab)
void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize)
vector ModalController_initialSize
void ModalController_switchState(entity me, entity other, float state, float skipAnimation)
vector ModalController_buttonOrigin
float ModalController_initialAlpha
entity ModalController_controllingButton
float ModalController_state
void ModalController_hideChild(entity me, entity other, float skipAnimation)
float ModalController_factor
#define SUPER(cname)
Definition oo.qh:236
#define NULL
Definition post.qh:14
vector
Definition self.qh:96