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