]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/nexposee.qc
Merge branch 'master' into TimePath/scrollpanel
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / nexposee.qc
1 #include "nexposee.qh"
2
3         void Nexposee_close(entity me)
4         {
5                 // user must override this
6         }
7
8         void ExposeeCloseButton_Click(entity button, entity other)
9         {
10                 other.selectedChild = other.focusedChild;
11                 other.setFocus(other, NULL);
12                 other.animationState = 3;
13         }
14
15         void Nexposee_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
16         {
17                 me.calc(me);
18                 me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize, Nexposee_initialFontScale);
19         }
20
21         void Nexposee_Calc_Scale(entity me, float scale)
22         {
23                 entity e;
24                 for (e = me.firstChild; e; e = e.nextSibling)
25                 {
26                         e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter;
27                         e.Nexposee_smallSize = e.Nexposee_initialSize * scale;
28                         if (e.Nexposee_align.x > 0) e.Nexposee_smallOrigin_x = 1 - e.Nexposee_align.x * scale;
29                         if (e.Nexposee_align.x < 0) e.Nexposee_smallOrigin_x = -e.Nexposee_smallSize.x + e.Nexposee_align.x * scale;
30                         if (e.Nexposee_align.y > 0) e.Nexposee_smallOrigin_y = 1 - e.Nexposee_align.y * scale;
31                         if (e.Nexposee_align.y < 0) e.Nexposee_smallOrigin_y = -e.Nexposee_smallSize.y + e.Nexposee_align.y * scale;
32                 }
33         }
34
35         void Nexposee_calc(entity me)
36         {
37                 /*
38                  * patented by Apple
39                  * can't put that here ;)
40                  */
41                 float scale;
42                 entity e, e2;
43                 vector emins, emaxs, e2mins, e2maxs;
44
45                 for (scale = 0.7; ; scale *= 0.99)
46                 {
47                         Nexposee_Calc_Scale(me, scale);
48
49                         for (e = me.firstChild; e; e = e.nextSibling)
50                         {
51                                 emins = e.Nexposee_smallOrigin;
52                                 emaxs = emins + e.Nexposee_smallSize;
53                                 for (e2 = e.nextSibling; e2; e2 = e2.nextSibling)
54                                 {
55                                         e2mins = e2.Nexposee_smallOrigin;
56                                         e2maxs = e2mins + e2.Nexposee_smallSize;
57
58                                         // two intervals [amins, amaxs] and [bmins, bmaxs] overlap if:
59                                         //   amins < bmins < amaxs < bmaxs
60                                         // for which suffices
61                                         //   bmins < amaxs
62                                         //   amins < bmaxs
63                                         if ((e2mins.x - emaxs.x) * (emins.x - e2maxs.x) > 0)     // x overlap
64                                                 if ((e2mins.y - emaxs.y) * (emins.y - e2maxs.y) > 0) // y overlap
65                                                         goto have_overlap;
66                                 }
67                         }
68
69                         break;
70 LABEL(have_overlap)
71                 }
72
73                 scale *= 0.95;
74
75                 Nexposee_Calc_Scale(me, scale);
76         }
77
78         void Nexposee_setNexposee(entity me, entity other, vector scalecenter, float a0, float a1)
79         {
80                 other.Nexposee_scaleCenter = scalecenter;
81                 other.Nexposee_smallAlpha = a0;
82                 me.setAlphaOf(me, other, a0);
83                 other.Nexposee_mediumAlpha = a1;
84         }
85
86         void Nexposee_draw(entity me)
87         {
88                 float a;
89                 float a0;
90                 entity e;
91                 float f;
92                 vector fs;
93
94                 if (me.animationState == -1) me.animationState = 0;
95
96                 f = min(1, frametime * 5);
97                 switch (me.animationState)
98                 {
99                         case 0:
100                                 me.animationFactor = 0;
101                                 break;
102                         case 1:
103                                 me.animationFactor += f;
104                                 if (me.animationFactor >= 1)
105                                 {
106                                         me.animationFactor = 1;
107                                         me.animationState = 2;
108                                         SUPER(Nexposee).setFocus(me, me.selectedChild);
109                                 }
110                                 break;
111                         case 2:
112                                 me.animationFactor = 1;
113                                 break;
114                         case 3:
115                                 me.animationFactor -= f;
116                                 me.mouseFocusedChild = me.itemFromPoint(me, me.mousePosition);
117                                 if (me.animationFactor <= 0)
118                                 {
119                                         me.animationFactor = 0;
120                                         me.animationState = 0;
121                                         me.selectedChild = me.mouseFocusedChild;
122                                 }
123                                 break;
124                 }
125
126                 f = min(1, frametime * 10);
127                 for (e = me.firstChild; e; e = e.nextSibling)
128                 {
129                         if (e == me.selectedChild)
130                         {
131                                 e.Container_origin = e.Nexposee_smallOrigin * (1 - me.animationFactor) + e.Nexposee_initialOrigin * me.animationFactor;
132                                 e.Container_size = e.Nexposee_smallSize * (1 - me.animationFactor) + e.Nexposee_initialSize * me.animationFactor;
133                                 e.Nexposee_animationFactor = me.animationFactor;
134                                 a0 = e.Nexposee_mediumAlpha;
135                                 if (me.animationState == 3)
136                                         if (e != me.mouseFocusedChild) a0 = e.Nexposee_smallAlpha;
137                                 a = a0 * (1 - me.animationFactor) + me.animationFactor;
138                         }
139                         else
140                         {
141                                 // minimum theSize counts
142                                 e.Container_origin = e.Nexposee_smallOrigin;
143                                 e.Container_size = e.Nexposee_smallSize;
144                                 e.Nexposee_animationFactor = 0;
145                                 a = e.Nexposee_smallAlpha * (1 - me.animationFactor);
146                         }
147                         me.setAlphaOf(me, e, e.Container_alpha * (1 - f) + a * f);
148
149                         fs = globalToBoxSize(e.Container_size, e.Nexposee_initialSize);
150                         e.Container_fontscale_x = fs.x * e.Nexposee_initialFontScale.x;
151                         e.Container_fontscale_y = fs.y * e.Nexposee_initialFontScale.y;
152                 }
153
154                 SUPER(Nexposee).draw(me);
155         }
156
157         METHOD(Nexposee, mousePress, bool(Nexposee this, vector pos))
158         {
159                 if (this.animationState == 0)
160                 {
161                         this.mouseFocusedChild = NULL;
162                         Nexposee_mouseMove(this, pos);
163                         if (this.mouseFocusedChild)
164                         {
165                                 m_play_click_sound(MENU_SOUND_OPEN);
166                                 this.animationState = 1;
167                                 SUPER(Nexposee).setFocus(this, NULL);
168                         }
169                         else
170                         {
171                                 this.close(this);
172                         }
173                         return true;
174                 }
175                 else if (this.animationState == 2)
176                 {
177                         if (!(SUPER(Nexposee).mousePress(this, pos)))
178                         {
179                                 m_play_click_sound(MENU_SOUND_CLOSE);
180                                 this.animationState = 3;
181                                 SUPER(Nexposee).setFocus(this, NULL);
182                         }
183                         return true;
184                 }
185                 return false;
186         }
187
188         float Nexposee_mouseRelease(entity me, vector pos)
189         {
190                 if (me.animationState == 2) return SUPER(Nexposee).mouseRelease(me, pos);
191                 return 0;
192         }
193
194         float Nexposee_mouseDrag(entity me, vector pos)
195         {
196                 if (me.animationState == 2) return SUPER(Nexposee).mouseDrag(me, pos);
197                 return 0;
198         }
199
200         float Nexposee_mouseMove(entity me, vector pos)
201         {
202                 entity e;
203                 me.mousePosition = pos;
204                 e = me.mouseFocusedChild;
205                 me.mouseFocusedChild = me.itemFromPoint(me, pos);
206                 if (me.animationState == 2) return SUPER(Nexposee).mouseMove(me, pos);
207                 if (me.animationState == 0)
208                 {
209                         if (me.mouseFocusedChild)
210                                 if (me.mouseFocusedChild != e || me.mouseFocusedChild != me.selectedChild) me.selectedChild = me.mouseFocusedChild;
211                         return 1;
212                 }
213                 return 0;
214         }
215
216         float Nexposee_keyUp(entity me, float scan, float ascii, float shift)
217         {
218                 if (me.animationState == 2) return SUPER(Nexposee).keyUp(me, scan, ascii, shift);
219                 return 0;
220         }
221
222         float Nexposee_keyDown(entity me, float scan, float ascii, float shift)
223         {
224                 float nexposeeKey = 0;
225                 if (me.animationState == 2)
226                         if (SUPER(Nexposee).keyDown(me, scan, ascii, shift)) return 1;
227                 if (scan == K_TAB)
228                 {
229                         if (me.animationState == 0)
230                         {
231                                 if (shift & S_SHIFT)
232                                 {
233                                         if (me.selectedChild) me.selectedChild = me.selectedChild.prevSibling;
234                                         if (!me.selectedChild) me.selectedChild = me.lastChild;
235                                 }
236                                 else
237                                 {
238                                         if (me.selectedChild) me.selectedChild = me.selectedChild.nextSibling;
239                                         if (!me.selectedChild) me.selectedChild = me.firstChild;
240                                 }
241                         }
242                 }
243                 switch (me.animationState)
244                 {
245                         default:
246                         case 0:
247                         case 3:
248                                 nexposeeKey = ((scan == K_SPACE) || (scan == K_ENTER) || (scan == K_KP_ENTER));
249                                 break;
250                         case 1:
251                         case 2:
252                                 nexposeeKey = (scan == K_ESCAPE);
253                                 break;
254                 }
255                 if (nexposeeKey)
256                 {
257                         switch (me.animationState)
258                         {
259                                 default:
260                                 case 0:
261                                 case 3:
262                                         m_play_click_sound(MENU_SOUND_OPEN);
263                                         me.animationState = 1;
264                                         break;
265                                 case 1:
266                                 case 2:
267                                         m_play_click_sound(MENU_SOUND_CLOSE);
268                                         me.animationState = 3;
269                                         break;
270                         }
271                         if (me.focusedChild) me.selectedChild = me.focusedChild;
272                         if (!me.selectedChild) me.animationState = 0;
273                         SUPER(Nexposee).setFocus(me, NULL);
274                         return 1;
275                 }
276                 return 0;
277         }
278
279         void Nexposee_addItem(entity me, entity other, vector theOrigin, vector theSize, float theAlpha)
280         {
281                 SUPER(Nexposee).addItem(me, other, theOrigin, theSize, theAlpha);
282                 other.Nexposee_initialFontScale = other.Container_fontscale;
283                 other.Nexposee_initialSize = other.Container_size;
284                 other.Nexposee_initialOrigin = other.Container_origin;
285                 other.Nexposee_initialAlpha = other.Container_alpha;
286                 if (other.Nexposee_initialFontScale == '0 0 0') other.Nexposee_initialFontScale = '1 1 0';
287         }
288
289         void Nexposee_focusEnter(entity me)
290         {
291                 if (me.animationState == 2) SUPER(Nexposee).setFocus(me, me.selectedChild);
292         }
293
294         void Nexposee_pullNexposee(entity me, entity other, vector theAlign)
295         {
296                 other.Nexposee_align = theAlign;
297         }