]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu-div0test/item/nexposee.c
Add gecko.c and support for DP's gecko system to msys.h and mbuiltin.qh
[divverent/nexuiz.git] / data / qcsrc / menu-div0test / item / nexposee.c
1 #ifdef INTERFACE
2 CLASS(Nexposee) EXTENDS(Container)
3         METHOD(Nexposee, draw, void(entity))
4         METHOD(Nexposee, keyDown, float(entity, float, float, float))
5         METHOD(Nexposee, keyUp, float(entity, float, float, float))
6         METHOD(Nexposee, mousePress, float(entity, vector))
7         METHOD(Nexposee, mouseMove, float(entity, vector))
8         METHOD(Nexposee, mouseRelease, float(entity, vector))
9         METHOD(Nexposee, mouseDrag, float(entity, vector))
10         METHOD(Nexposee, resizeNotify, void(entity, vector, vector, vector, vector))
11         METHOD(Nexposee, focusEnter, void(entity))
12         METHOD(Nexposee, close, void(entity))
13
14         ATTRIB(Nexposee, animationState, float, -1)
15         ATTRIB(Nexposee, animationFactor, float, 0)
16         ATTRIB(Nexposee, selectedChild, entity, NULL)
17         ATTRIB(Nexposee, mouseFocusedChild, entity, NULL)
18         METHOD(Nexposee, addItem, void(entity, entity, vector, vector, float))
19         METHOD(Nexposee, calc, void(entity))
20         METHOD(Nexposee, setNexposee, void(entity, entity, vector, float, float))
21         ATTRIB(Nexposee, mousePosition, vector, '0 0 0')
22 ENDCLASS(Nexposee)
23
24 void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the current state
25 #endif
26
27 // animation states:
28 //   0 = thumbnails seen
29 //   1 = zooming in
30 //   2 = zoomed in
31 //   3 = zooming out
32 // animation factor: 0 = minimum theSize, 1 = maximum theSize
33
34 #ifdef IMPLEMENTATION
35
36 .vector Nexposee_initialSize;
37 .vector Nexposee_initialOrigin;
38 .float Nexposee_initialAlpha;
39
40 .vector Nexposee_smallSize;
41 .vector Nexposee_smallOrigin;
42 .float Nexposee_smallAlpha;
43 .float Nexposee_mediumAlpha;
44 .vector Nexposee_scaleCenter;
45
46 void closeNexposee(entity me)
47 {
48         // user must override this
49 }
50
51 void ExposeeCloseButton_Click(entity button, entity other)
52 {
53         other.selectedChild = other.focusedChild;
54         other.setFocus(other, NULL);
55         other.animationState = 3;
56 }
57
58 void resizeNotifyNexposee(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
59 {
60         me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize);
61 }
62
63 void calcNexposee(entity me)
64 {
65         /*
66          * patented by Apple
67          * can't put that here ;)
68          */
69         float scale;
70         entity e, e2;
71         vector emins, emaxs, e2mins, e2maxs;
72         
73         for(scale = 0.7;; scale *= 0.99)
74         {
75                 for(e = me.firstChild; e; e = e.nextSibling)
76                 {
77                         e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter;
78                         e.Nexposee_smallSize = e.Nexposee_initialSize * scale;
79                 }
80
81                 for(e = me.firstChild; e; e = e.nextSibling)
82                 {
83                         emins = e.Nexposee_smallOrigin;
84                         emaxs = emins + e.Nexposee_smallSize;
85                         for(e2 = e.nextSibling; e2; e2 = e2.nextSibling)
86                         {
87                                 e2mins = e2.Nexposee_smallOrigin;
88                                 e2maxs = e2mins + e2.Nexposee_smallSize;
89
90                                 // two intervals [amins, amaxs] and [bmins, bmaxs] overlap if:
91                                 //   amins < bmins < amaxs < bmaxs
92                                 // for which suffices
93                                 //   bmins < amaxs
94                                 //   amins < bmaxs
95                                 if((e2mins_x - emaxs_x) * (emins_x - e2maxs_x) > 0) // x overlap
96                                         if((e2mins_y - emaxs_y) * (emins_y - e2maxs_y) > 0) // y overlap
97                                         {
98                                                 goto have_overlap;
99                                         }
100                         }
101                 }
102
103                 break;
104 :have_overlap
105         }
106
107         scale *= 0.95;
108         for(e = me.firstChild; e; e = e.nextSibling)
109         {
110                 e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter;
111                 e.Nexposee_smallSize = e.Nexposee_initialSize * scale;
112         }
113 }
114
115 void setNexposeeNexposee(entity me, entity other, vector scalecenter, float a0, float a1)
116 {
117         other.Nexposee_scaleCenter = scalecenter;
118         other.Nexposee_smallAlpha = a0;
119         me.setAlphaOf(me, other, a0);
120         other.Nexposee_mediumAlpha = a1;
121 }
122
123 void drawNexposee(entity me)
124 {
125         float a;
126         float a0;
127         entity e;
128         float f;
129
130         if(me.animationState == -1)
131         {
132                 me.animationState = 0;
133                 me.calc(me);
134         }
135
136         //print(ftos(me.animationState), "\n");
137
138         f = min(1, frametime * 5);
139         switch(me.animationState)
140         {
141                 case 0:
142                         me.animationFactor = 0;
143                         break;
144                 case 1:
145                         me.animationFactor += f;
146                         if(me.animationFactor >= 1)
147                         {
148                                 me.animationFactor = 1;
149                                 me.animationState = 2;
150                                 setFocusContainer(me, me.selectedChild);
151                         }
152                         break;
153                 case 2:
154                         me.animationFactor = 1;
155                         break;
156                 case 3:
157                         me.animationFactor -= f;
158                         me.mouseFocusedChild = me.itemFromPoint(me, me.mousePosition);
159                         if(me.animationFactor <= 0)
160                         {
161                                 me.animationFactor = 0;
162                                 me.animationState = 0;
163                                 me.selectedChild = me.mouseFocusedChild;
164                         }
165                         break;
166         }
167
168         f = min(1, frametime * 10);
169         for(e = me.firstChild; e; e = e.nextSibling)
170         {
171                 if(e == me.selectedChild)
172                 {
173                         e.Container_origin = e.Nexposee_smallOrigin * (1 - me.animationFactor) + e.Nexposee_initialOrigin * me.animationFactor;
174                         e.Container_size = e.Nexposee_smallSize * (1 - me.animationFactor) + e.Nexposee_initialSize * me.animationFactor;
175                         a0 = e.Nexposee_mediumAlpha;
176                         if(me.animationState == 3)
177                                 if(e != me.mouseFocusedChild)
178                                         a0 = e.Nexposee_smallAlpha;
179                         a = a0 * (1 - me.animationFactor) + me.animationFactor;
180                 }
181                 else
182                 {
183                         // minimum theSize counts
184                         e.Container_origin = e.Nexposee_smallOrigin;
185                         e.Container_size = e.Nexposee_smallSize;
186                         a = e.Nexposee_smallAlpha * (1 - me.animationFactor);
187                 }
188                 me.setAlphaOf(me, e, e.Container_alpha * (1 - f) + a * f);
189         }
190
191         drawContainer(me);
192
193         /*
194         for(e = me.firstChild; e; e = e.nextSibling)
195         {
196                 vector t, fs;
197                 a0 = e.Container_alpha;
198                 if(a0 < e.Nexposee_smallAlpha)
199                         a = 0.3 * (a0 - 0) / (e.Nexposee_smallAlpha - 0);
200                 else if(a0 < e.Nexposee_mediumAlpha)
201                         a = 0.3 + 0.5 * (a0 - e.Nexposee_smallAlpha)  / (e.Nexposee_mediumAlpha - e.Nexposee_smallAlpha);
202                 else
203                         a = 0.8 - 0.8 * (a0 - e.Nexposee_mediumAlpha) / (1 - e.Nexposee_mediumAlpha);
204                 fs = (eX * (1 / draw_scale_x) + eY * (1 / draw_scale_y)) * 36;
205                 t = draw_TextWidth(e.title, FALSE) * eX * fs_x + eY * fs_y;
206                 draw_Text(e.Container_origin + (e.Container_size_x * eX - t) * 0.5 - 0.5 * eY * t_y, e.title, fs, e.color, a, FALSE);
207         }
208         */
209 };
210
211 float mousePressNexposee(entity me, vector pos)
212 {
213         if(me.animationState == 0)
214         {
215                 me.mouseFocusedChild = NULL;
216                 mouseMoveNexposee(me, pos);
217                 if(me.mouseFocusedChild)
218                 {
219                         me.animationState = 1;
220                         setFocusContainer(me, NULL);
221                 }
222                 else
223                         me.close(me);
224                 return 1;
225         }
226         else if(me.animationState == 2)
227         {
228                 if not(mousePressContainer(me, pos))
229                 {
230                         me.animationState = 3;
231                         setFocusContainer(me, NULL);
232                 }
233                 return 1;
234         }
235         return 0;
236 }
237
238 float mouseReleaseNexposee(entity me, vector pos)
239 {
240         if(me.animationState == 2)
241                 return mouseReleaseContainer(me, pos);
242         return 0;
243 }
244
245 float mouseDragNexposee(entity me, vector pos)
246 {
247         if(me.animationState == 2)
248                 return mouseDragContainer(me, pos);
249         return 0;
250 }
251
252 float mouseMoveNexposee(entity me, vector pos)
253 {
254         entity e;
255         me.mousePosition = pos;
256         e = me.mouseFocusedChild;
257         me.mouseFocusedChild = me.itemFromPoint(me, pos);
258         if(me.animationState == 2)
259                 return mouseMoveContainer(me, pos);
260         if(me.animationState == 0)
261         {
262                 if(me.mouseFocusedChild)
263                         if(me.mouseFocusedChild != e)
264                                 me.selectedChild = me.mouseFocusedChild;
265                 return 1;
266         }
267         return 0;
268 }
269
270 float keyUpNexposee(entity me, float scan, float ascii, float shift)
271 {
272         if(me.animationState == 2)
273                 return keyUpContainer(me, scan, ascii, shift);
274         return 0;
275 }
276
277 float keyDownNexposee(entity me, float scan, float ascii, float shift)
278 {
279         float nexposeeKey;
280         if(me.animationState == 2)
281                 if(keyDownContainer(me, scan, ascii, shift))
282                         return 1;
283         if(scan == K_TAB)
284         {
285                 if(me.animationState == 0)
286                 {
287                         if(shift & S_SHIFT)
288                         {
289                                 if(me.selectedChild)
290                                         me.selectedChild = me.selectedChild.prevSibling;
291                                 if not(me.selectedChild)
292                                         me.selectedChild = me.lastChild;
293                         }
294                         else
295                         {
296                                 if(me.selectedChild)
297                                         me.selectedChild = me.selectedChild.nextSibling;
298                                 if not(me.selectedChild)
299                                         me.selectedChild = me.firstChild;
300                         }
301                 }
302         }
303         switch(me.animationState)
304         {
305                 case 0:
306                 case 3:
307                         nexposeeKey = ((scan == K_SPACE) || (scan == K_ENTER));
308                         break;
309                 case 1:
310                 case 2:
311                         nexposeeKey = (scan == K_ESCAPE);
312                         break;
313         }
314         if(nexposeeKey)
315         {
316                 switch(me.animationState)
317                 {
318                         case 0:
319                         case 3:
320                                 me.animationState = 1;
321                                 break;
322                         case 1:
323                         case 2:
324                                 me.animationState = 3;
325                                 break;
326                 }
327                 if(me.focusedChild)
328                         me.selectedChild = me.focusedChild;
329                 if not(me.selectedChild)
330                         me.animationState = 0;
331                 setFocusContainer(me, NULL);
332                 return 1;
333         }
334         return 0;
335 }
336
337 void addItemNexposee(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
338 {
339         addItemContainer(me, other, theOrigin, theSize, theAlpha);
340         other.Nexposee_initialSize = other.Container_size;
341         other.Nexposee_initialOrigin = other.Container_origin;
342         other.Nexposee_initialAlpha = other.Container_alpha;
343 }
344
345 void focusEnterNexposee(entity me)
346 {
347         if(me.animationState == 2)
348                 setFocusContainer(me, me.selectedChild);
349 }
350 #endif