]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/slider.qc
Merge branch 'master' into Mario/wepent_experimental
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / slider.qc
1 #include "slider.qh"
2
3 #include "../anim/easing.qh"
4 #include "../anim/animhost.qh"
5
6 .entity applyButton;
7
8         void Slider_setValue_allowAnim(entity me, float val, bool allowAnim)
9         {
10                 if (allowAnim && me.animated)
11                 {
12                         float t = 0.5;
13                         if (!me.sliderAnim) me.sliderAnim = makeHostedEasing(me, Slider_setSliderValue, easingQuadOut, t, me.sliderValue, val);
14                         else me.sliderAnim.update(me.sliderAnim, t, me.sliderValue, val);
15                 }
16                 else
17                 {
18                         me.setSliderValue(me, val);
19                 }
20                 me.value = val;
21         }
22         void Slider_setValue_noAnim(entity me, float val)
23         {
24                 Slider_setValue_allowAnim(me, val, false);
25         }
26         void Slider_setValue(entity me, float val)
27         {
28                 Slider_setValue_allowAnim(me, val, true);
29         }
30         void Slider_setSliderValue(entity me, float val)
31         {
32                 me.sliderValue = val;
33         }
34         string Slider_toString(entity me)
35         {
36                 return sprintf("%d (%s)", me.value, me.valueToText(me, me.value));
37         }
38         void Slider_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
39         {
40                 SUPER(Slider).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
41                 me.controlWidth = absSize.x == 0 ? 0 : (absSize.y / absSize.x);
42         }
43         string Slider_valueToText(entity me, float val)
44         {
45                 if (almost_in_bounds(me.valueMin, val, me.valueMax)) return ftos_decimals(val * me.valueDisplayMultiplier, me.valueDigits);
46                 return "";
47         }
48         void Slider_configureSliderVisuals(entity me, float sz, float theAlign, float theTextSpace, string gfx)
49         {
50                 SUPER(Slider).configureLabel(me, string_null, sz, theAlign);
51                 me.textSpace = theTextSpace;
52                 me.keepspaceLeft = (theTextSpace == 0) ? 0 : (1 - theTextSpace);
53                 me.src = gfx;
54         }
55         void Slider_configureSliderValues(entity me, float theValueMin, float theValue, float theValueMax, float theValueStep, float theValueKeyStep, float theValuePageStep)
56         {
57                 me.value = theValue;
58                 me.sliderValue = theValue;
59                 me.valueStep = theValueStep;
60                 me.valueMin = theValueMin;
61                 me.valueMax = theValueMax;
62                 me.valueKeyStep = theValueKeyStep;
63                 me.valuePageStep = theValuePageStep;
64                 me.valueDigits = 3;
65                 if (fabs(floor(me.valueStep * 100 + 0.5) - (me.valueStep * 100)) < 0.01) // about a whole number of 100ths
66                         me.valueDigits = 2;
67                 if (fabs(floor(me.valueStep * 10 + 0.5) - (me.valueStep * 10)) < 0.01)   // about a whole number of 10ths
68                         me.valueDigits = 1;
69                 if (fabs(floor(me.valueStep * 1 + 0.5) - (me.valueStep * 1)) < 0.01)     // about a whole number
70                         me.valueDigits = 0;
71         }
72         float Slider_keyDown(entity me, float key, float ascii, float shift)
73         {
74                 float inRange;
75                 float ret_value = 0;
76                 if (me.disabled) return 0;
77                 inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax));
78                 if (key == K_LEFTARROW || key == K_KP_LEFTARROW || key == K_MWHEELDOWN)
79                 {
80                         if (inRange) me.setValue(me, median(me.valueMin, me.value - me.valueKeyStep, me.valueMax));
81                         else me.setValue(me, me.valueMax);
82                         ret_value = 1;
83                 }
84                 if (key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MWHEELUP)
85                 {
86                         if (inRange) me.setValue(me, median(me.valueMin, me.value + me.valueKeyStep, me.valueMax));
87                         else me.setValue(me, me.valueMin);
88                         ret_value = 1;
89                 }
90                 if (key == K_PGDN || key == K_KP_PGDN)
91                 {
92                         if (inRange) me.setValue(me, median(me.valueMin, me.value - me.valuePageStep, me.valueMax));
93                         else me.setValue(me, me.valueMax);
94                         ret_value = 1;
95                 }
96                 if (key == K_PGUP || key == K_KP_PGUP)
97                 {
98                         if (inRange) me.setValue(me, median(me.valueMin, me.value + me.valuePageStep, me.valueMax));
99                         else me.setValue(me, me.valueMin);
100                         ret_value = 1;
101                 }
102                 if (key == K_HOME || key == K_KP_HOME)
103                 {
104                         me.setValue(me, me.valueMin);
105                         ret_value = 1;
106                 }
107                 if (key == K_END || key == K_KP_END)
108                 {
109                         me.setValue(me, me.valueMax);
110                         ret_value = 1;
111                 }
112                 if(ret_value == 1)
113                 {
114                         if(me.applyButton)
115                                 me.applyButton.disabled = false;
116                         return 1;
117                 }
118                 // TODO more keys (NOTE also add them to Slider_keyUp)
119                 return 0;
120         }
121         float Slider_keyUp(entity me, float key, float ascii, float shift)
122         {
123                 if (me.disabled) return 0;
124                 switch (key)
125                 {
126                         case K_LEFTARROW:
127                         case K_KP_LEFTARROW:
128                         case K_RIGHTARROW:
129                         case K_KP_RIGHTARROW:
130                         case K_PGUP:
131                         case K_KP_PGUP:
132                         case K_PGDN:
133                         case K_KP_PGDN:
134                         case K_HOME:
135                         case K_KP_HOME:
136                         case K_END:
137                         case K_KP_END:
138                                 m_play_click_sound(MENU_SOUND_SLIDE);
139                 }
140                 return 0;
141         }
142         float Slider_mouseDrag(entity me, vector pos)
143         {
144                 float hit;
145                 float v;
146                 if (me.disabled) return 0;
147
148                 if (me.pressed)
149                 {
150                         hit = 1;
151                         if (pos.x < 0 - me.tolerance.x) hit = 0;
152                         if (pos.y < 0 - me.tolerance.y) hit = 0;
153                         if (pos.x >= 1 - me.textSpace + me.tolerance.x) hit = 0;
154                         if (pos.y >= 1 + me.tolerance.y) hit = 0;
155                         if (hit)
156                         {
157                                 // handle dragging
158                                 me.pressed = 2;
159
160                                 v = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin;
161                                 if (me.valueStep) v = floor(0.5 + v / me.valueStep) * me.valueStep;
162                                 me.setValue_noAnim(me, v);
163                                 if(me.applyButton)
164                                 if(me.previousValue != me.value)
165                                         me.applyButton.disabled = false;
166                         }
167                         else
168                         {
169                                 me.setValue(me, me.previousValue);
170                         }
171                 }
172
173                 return 1;
174         }
175         float Slider_mousePress(entity me, vector pos)
176         {
177                 float controlCenter;
178                 if (me.disabled) return 0;
179                 if (pos.x < 0) return 0;
180                 if (pos.y < 0) return 0;
181                 if (pos.x >= 1 - me.textSpace) return 0;
182                 if (pos.y >= 1) return 0;
183                 controlCenter = (me.value - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth) + 0.5 * me.controlWidth;
184                 if (fabs(pos.x - controlCenter) <= 0.5 * me.controlWidth)
185                 {
186                         me.pressed = 1;
187                         me.pressOffset = pos.x - controlCenter;
188                         me.previousValue = me.value;
189                         // me.mouseDrag(me, pos);
190                 }
191                 else
192                 {
193                         float clickValue, pageValue, inRange;
194                         clickValue = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin;
195                         inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax));
196                         if (pos.x < controlCenter)
197                         {
198                                 pageValue = me.value - me.valuePageStep;
199                                 if (me.valueStep) clickValue = floor(clickValue / me.valueStep) * me.valueStep;
200                                 pageValue = max(pageValue, clickValue);
201                         }
202                         else
203                         {
204                                 pageValue = me.value + me.valuePageStep;
205                                 if (me.valueStep) clickValue = ceil(clickValue / me.valueStep) * me.valueStep;
206                                 pageValue = min(pageValue, clickValue);
207                         }
208                         if (inRange) me.setValue(me, median(me.valueMin, pageValue, me.valueMax));
209                         else me.setValue(me, me.valueMax);
210                         if(me.applyButton)
211                                 me.applyButton.disabled = false;
212                         if (pageValue == clickValue)
213                         {
214                                 controlCenter = (me.value - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth) + 0.5 * me.controlWidth;
215                                 me.pressed = 1;
216                                 me.pressOffset = pos.x - controlCenter;
217                                 me.previousValue = me.value;
218                                 // me.mouseDrag(me, pos);
219                         }
220                 }
221                 return 1;
222         }
223         float Slider_mouseRelease(entity me, vector pos)
224         {
225                 me.pressed = 0;
226                 if (me.disabled) return 0;
227                 m_play_click_sound(MENU_SOUND_SLIDE);
228                 return 1;
229         }
230         void Slider_showNotify(entity me)
231         {
232                 me.focusable = !me.disabled;
233         }
234         void Slider_draw(entity me)
235         {
236                 float controlLeft;
237                 float save;
238                 me.focusable = !me.disabled;
239                 save = draw_alpha;
240                 if (me.disabled) draw_alpha *= me.disabledAlpha;
241                 draw_ButtonPicture('0 0 0', strcat(me.src, "_s"), eX * (1 - me.textSpace) + eY, me.color2, 1);
242                 if (me.valueMax > me.valueMin) // valid?
243                 if (almost_in_bounds(me.valueMin, me.sliderValue, me.valueMax))
244                 {
245                         controlLeft = (me.sliderValue - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth);
246                         if (me.disabled) draw_Picture(eX * controlLeft, strcat(me.src, "_d"), eX * me.controlWidth + eY, me.colorD, 1);
247                         else if (me.pressed) draw_Picture(eX * controlLeft, strcat(me.src, "_c"), eX * me.controlWidth + eY, me.colorC, 1);
248                         else if (me.focused) draw_Picture(eX * controlLeft, strcat(me.src, "_f"), eX * me.controlWidth + eY, me.colorF, 1);
249                         else draw_Picture(eX * controlLeft, strcat(me.src, "_n"), eX * me.controlWidth + eY, me.color, 1);
250                 }
251
252                 if (me.sliderAnim)
253                         if (me.sliderAnim.isFinished(me.sliderAnim))
254                         {
255                                 anim.removeObjAnim(anim, me);
256                                 me.sliderAnim = NULL;
257                         }
258
259                 if (me.valueMax > me.valueMin) // valid?
260                         me.setText(me, me.valueToText(me, me.value));
261                 draw_alpha = save;
262                 SUPER(Slider).draw(me);
263                 me.text = string_null;  // TEMPSTRING!
264         }