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