Xonotic
slider.qc
Go to the documentation of this file.
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  }
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:
139  }
140  return 0;
141  }
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  float f = bound(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1);
161  v = f * (me.valueMax - me.valueMin) + me.valueMin;
162  // there's no need to round min and max value... also if we did, v could be set
163  // to an out of bounds value due to precision errors
164  if (f > 0 && f < 1 && me.valueStep)
165  v = floor(0.5 + v / me.valueStep) * me.valueStep;
166  me.setValue_noAnim(me, v);
167  if(me.applyButton)
168  if(me.previousValue != me.value)
169  me.applyButton.disabled = false;
170  }
171  else
172  {
173  me.setValue(me, me.previousValue);
174  }
175  }
176 
177  return 1;
178  }
179  METHOD(Slider, mousePress, bool(Slider this, vector pos))
180  {
181  float controlCenter;
182  if (this.disabled) return false;
183  if (pos.x < 0) return false;
184  if (pos.y < 0) return false;
185  if (pos.x >= 1 - this.textSpace) return false;
186  if (pos.y >= 1) return false;
187  controlCenter = (this.value - this.valueMin) / (this.valueMax - this.valueMin) * (1 - this.textSpace - this.controlWidth) + 0.5 * this.controlWidth;
188  if (fabs(pos.x - controlCenter) <= 0.5 * this.controlWidth)
189  {
190  this.pressed = 1;
191  this.pressOffset = pos.x - controlCenter;
192  this.previousValue = this.value;
193  // this.mouseDrag(this, pos);
194  }
195  else
196  {
197  float clickValue, pageValue, inRange;
198  clickValue = median(0, (pos.x - this.pressOffset - 0.5 * this.controlWidth) / (1 - this.textSpace - this.controlWidth), 1) * (this.valueMax - this.valueMin) + this.valueMin;
199  inRange = (almost_in_bounds(this.valueMin, this.value, this.valueMax));
200  if (pos.x < controlCenter)
201  {
202  pageValue = this.value - this.valuePageStep;
203  if (this.valueStep) clickValue = floor(clickValue / this.valueStep) * this.valueStep;
204  pageValue = max(pageValue, clickValue);
205  }
206  else
207  {
208  pageValue = this.value + this.valuePageStep;
209  if (this.valueStep) clickValue = ceil(clickValue / this.valueStep) * this.valueStep;
210  pageValue = min(pageValue, clickValue);
211  }
212  if (inRange) this.setValue(this, median(this.valueMin, pageValue, this.valueMax));
213  else this.setValue(this, this.valueMax);
214  if(this.applyButton)
215  this.applyButton.disabled = false;
216  if (pageValue == clickValue)
217  {
218  controlCenter = (this.value - this.valueMin) / (this.valueMax - this.valueMin) * (1 - this.textSpace - this.controlWidth) + 0.5 * this.controlWidth;
219  this.pressed = 1;
220  this.pressOffset = pos.x - controlCenter;
221  this.previousValue = this.value;
222  // this.mouseDrag(this, pos);
223  }
224  }
225  return true;
226  }
228  {
229  me.pressed = 0;
230  if (me.disabled) return 0;
232  return 1;
233  }
235  {
236  me.focusable = !me.disabled;
237  }
239  {
240  float controlLeft;
241  float save;
242  me.focusable = !me.disabled;
243  save = draw_alpha;
244  if (me.disabled) draw_alpha *= me.disabledAlpha;
245  draw_ButtonPicture('0 0 0', strcat(me.src, "_s"), eX * (1 - me.textSpace) + eY, me.color2, 1);
246  if (me.valueMax > me.valueMin) // valid?
247  if (almost_in_bounds(me.valueMin, me.sliderValue, me.valueMax))
248  {
249  controlLeft = (me.sliderValue - me.valueMin) / (me.valueMax - me.valueMin) * (1 - me.textSpace - me.controlWidth);
250  if (me.disabled) draw_Picture(eX * controlLeft, strcat(me.src, "_d"), eX * me.controlWidth + eY, me.colorD, 1);
251  else if (me.pressed) draw_Picture(eX * controlLeft, strcat(me.src, "_c"), eX * me.controlWidth + eY, me.colorC, 1);
252  else if (me.focused) draw_Picture(eX * controlLeft, strcat(me.src, "_f"), eX * me.controlWidth + eY, me.colorF, 1);
253  else draw_Picture(eX * controlLeft, strcat(me.src, "_n"), eX * me.controlWidth + eY, me.color, 1);
254  }
255 
256  if (me.sliderAnim)
257  if (me.sliderAnim.isFinished(me.sliderAnim))
258  {
259  anim.removeObjAnim(anim, me);
260  me.sliderAnim = NULL;
261  }
262 
263  if (me.valueMax > me.valueMin) // valid?
264  me.setText(me, me.valueToText(me, me.value));
265  draw_alpha = save;
266  SUPER(Slider).draw(me);
267  me.text = string_null; // TEMPSTRING!
268  }
float K_KP_RIGHTARROW
Definition: keycodes.qc:60
ERASEABLE float median(float a, float b, float c)
Definition: math.qh:216
ERASEABLE float almost_in_bounds(float a, float b, float c)
Definition: math.qh:236
ERASEABLE string ftos_decimals(float number, int decimals)
converts a number to a string with the indicated number of decimals
Definition: string.qh:450
string string_null
Definition: nil.qh:9
void Slider_setValue_noAnim(entity me, float val)
Definition: slider.qc:22
const vector eY
Definition: vector.qh:45
string Slider_valueToText(entity me, float val)
Definition: slider.qc:43
float Slider_keyUp(entity me, float key, float ascii, float shift)
Definition: slider.qc:121
float K_HOME
Definition: keycodes.qc:41
void Slider_showNotify(entity me)
Definition: slider.qc:234
entity() spawn
bool disabled
void Slider_draw(entity me)
Definition: slider.qc:238
float K_KP_PGDN
Definition: keycodes.qc:55
#define METHOD(cname, name, prototype)
Definition: oo.qh:257
float K_RIGHTARROW
Definition: keycodes.qc:18
#define SUPER(cname)
Definition: oo.qh:219
entity applyButton
Definition: slider.qc:6
void Slider_setValue_allowAnim(entity me, float val, bool allowAnim)
Definition: slider.qc:8
void Slider_setValue(entity me, float val)
Definition: slider.qc:26
void Slider_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
Definition: slider.qc:38
float K_PGDN
Definition: keycodes.qc:39
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
float easingQuadOut(float tickTime, float animDuration, float animStart, float animDelta)
Definition: easing.qc:42
float Slider_keyDown(entity me, float key, float ascii, float shift)
Definition: slider.qc:72
#define NULL
Definition: post.qh:17
entity makeHostedEasing(entity obj, void(entity, float) objSetter, float(float, float, float, float) func, float animDuration, float animStartValue, float animEnd)
Definition: easing.qc:6
float K_END
Definition: keycodes.qc:42
string Slider_toString(entity me)
Definition: slider.qc:34
float K_MWHEELDOWN
Definition: keycodes.qc:133
vector(float skel, float bonenum) _skel_get_boneabs_hidden
vector v
Definition: ent_cs.qc:116
void Slider_configureSliderValues(entity me, float theValueMin, float theValue, float theValueMax, float theValueStep, float theValueKeyStep, float theValuePageStep)
Definition: slider.qc:55
const vector eX
Definition: vector.qh:44
float K_KP_HOME
Definition: keycodes.qc:62
float Slider_mouseRelease(entity me, vector pos)
Definition: slider.qc:227
float Slider_mouseDrag(entity me, vector pos)
Definition: slider.qc:142
float K_LEFTARROW
Definition: keycodes.qc:17
bool pressed
Definition: picker.qc:3
Definition: slider.qh:6
float K_KP_END
Definition: keycodes.qc:51
if(IS_DEAD(this))
Definition: impulse.qc:92
float K_KP_PGUP
Definition: keycodes.qc:66
float K_KP_LEFTARROW
Definition: keycodes.qc:57
float K_PGUP
Definition: keycodes.qc:40
float K_MWHEELUP
Definition: keycodes.qc:132
void Slider_configureSliderVisuals(entity me, float sz, float theAlign, float theTextSpace, string gfx)
Definition: slider.qc:48
void Slider_setSliderValue(entity me, float val)
Definition: slider.qc:30