]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu-div0test/item/nexposee.c
add somewhat working listbox; but it can't do anything useful yet
[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.9)
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.9;
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         entity e;
126         float f;
127
128         if(me.animationState == -1)
129         {
130                 me.animationState = 0;
131                 me.calc(me);
132         }
133
134         //print(ftos(me.animationState), "\n");
135
136         f = min(1, frametime * 5);
137         switch(me.animationState)
138         {
139                 case 0:
140                         me.animationFactor = 0;
141                         break;
142                 case 1:
143                         me.animationFactor += f;
144                         if(me.animationFactor >= 1)
145                         {
146                                 me.animationFactor = 1;
147                                 me.animationState = 2;
148                                 setFocusContainer(me, me.selectedChild);
149                         }
150                         break;
151                 case 2:
152                         me.animationFactor = 1;
153                         break;
154                 case 3:
155                         me.animationFactor -= f;
156                         me.mouseFocusedChild = me.itemFromPoint(me, me.mousePosition);
157                         if(me.animationFactor <= 0)
158                         {
159                                 me.animationFactor = 0;
160                                 me.animationState = 0;
161                                 me.selectedChild = me.mouseFocusedChild;
162                         }
163                         break;
164         }
165
166         f = min(1, frametime * 10);
167         for(e = me.firstChild; e; e = e.nextSibling)
168         {
169                 float a;
170                 float a0;
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 float mousePressNexposee(entity me, vector pos)
195 {
196         if(me.animationState == 0)
197         {
198                 me.mouseFocusedChild = NULL;
199                 mouseMoveNexposee(me, pos);
200                 if(me.mouseFocusedChild)
201                 {
202                         me.animationState = 1;
203                         setFocusContainer(me, NULL);
204                 }
205                 else
206                         me.close(me);
207                 return 1;
208         }
209         else if(me.animationState == 2)
210         {
211                 if(!mousePressContainer(me, pos))
212                 {
213                         me.animationState = 3;
214                         setFocusContainer(me, NULL);
215                 }
216                 return 1;
217         }
218         return 0;
219 }
220
221 float mouseReleaseNexposee(entity me, vector pos)
222 {
223         if(me.animationState == 2)
224                 return mouseReleaseContainer(me, pos);
225         return 0;
226 }
227
228 float mouseDragNexposee(entity me, vector pos)
229 {
230         if(me.animationState == 2)
231                 return mouseDragContainer(me, pos);
232         return 0;
233 }
234
235 float mouseMoveNexposee(entity me, vector pos)
236 {
237         entity e;
238         me.mousePosition = pos;
239         e = me.mouseFocusedChild;
240         me.mouseFocusedChild = me.itemFromPoint(me, pos);
241         if(me.animationState == 2)
242                 return mouseMoveContainer(me, pos);
243         if(me.animationState == 0)
244         {
245                 if(me.mouseFocusedChild)
246                         if(me.mouseFocusedChild != e)
247                                 me.selectedChild = me.mouseFocusedChild;
248                 return 1;
249         }
250         return 0;
251 }
252
253 float keyUpNexposee(entity me, float scan, float ascii, float shift)
254 {
255         if(me.animationState == 2)
256                 return keyUpContainer(me, scan, ascii, shift);
257         return 0;
258 }
259
260 float keyDownNexposee(entity me, float scan, float ascii, float shift)
261 {
262         float nexposeeKey;
263         if(me.animationState == 2)
264                 if(keyDownContainer(me, scan, ascii, shift))
265                         return 1;
266         if(scan == K_TAB)
267         {
268                 if(me.animationState == 0)
269                 {
270                         if(shift & S_SHIFT)
271                         {
272                                 if(me.selectedChild)
273                                         me.selectedChild = me.selectedChild.prevSibling;
274                                 if(!me.selectedChild)
275                                         me.selectedChild = me.lastChild;
276                         }
277                         else
278                         {
279                                 if(me.selectedChild)
280                                         me.selectedChild = me.selectedChild.nextSibling;
281                                 if(!me.selectedChild)
282                                         me.selectedChild = me.firstChild;
283                         }
284                 }
285         }
286         switch(me.animationState)
287         {
288                 case 0:
289                 case 3:
290                         nexposeeKey = ((scan == K_SPACE) || (scan == K_ENTER));
291                         break;
292                 case 1:
293                 case 2:
294                         nexposeeKey = (scan == K_ESCAPE);
295                         break;
296         }
297         if(nexposeeKey)
298         {
299                 switch(me.animationState)
300                 {
301                         case 0:
302                         case 3:
303                                 me.animationState = 1;
304                                 break;
305                         case 1:
306                         case 2:
307                                 me.animationState = 3;
308                                 break;
309                 }
310                 if(me.focusedChild)
311                         me.selectedChild = me.focusedChild;
312                 if(!me.selectedChild)
313                         me.animationState = 0;
314                 setFocusContainer(me, NULL);
315                 return 1;
316         }
317         return 0;
318 }
319
320 void addItemNexposee(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
321 {
322         addItemContainer(me, other, theOrigin, theSize, theAlpha);
323         other.Nexposee_initialSize = other.Container_size;
324         other.Nexposee_initialOrigin = other.Container_origin;
325         other.Nexposee_initialAlpha = other.Container_alpha;
326 }
327
328 void focusEnterNexposee(entity me)
329 {
330         if(me.animationState == 2)
331                 setFocusContainer(me, me.selectedChild);
332 }
333 #endif