4 #include "../UI/ComponentStackWidget.h"
5 #include "../UI/Helpers.h"
6 #include "../Property.h"
11 namespace Gorgon {
namespace Widgets {
15 enum class SliderInteractivity {
21 HandleAndJump = HandleOnly | Jump,
22 HandleAndPage = HandleOnly | Page,
23 DualHandleAndJump = DualHandle | Jump,
24 DualHandleAndPage = DualHandle | Page,
27 enum class SliderValueMapping {
33 inline bool operator &(SliderInteractivity l, SliderInteractivity r) {
return (
int(l)&
int(r)) != 0; }
44 float(*DIV_)(T_, T_, T_) = FloatDivider<T_>,
45 T_(*VAL_)(float, T_, T_) = FloatToValue<T_>,
46 template<
class C_,
class PT_, PT_(C_::*Getter_)()
const,
void(C_::*Setter_)(
const PT_ &)>
class P_ =
Gorgon::NumericProperty,
48 internal::SliderValueMapping valuemapping = internal::SliderValueMapping::OneValue
70 UI::internal::prophelper<SliderBase<T_, DIV_, VAL_, P_, interactive, valuemapping>, T_>,
78 float(*DIV1_)(T1_, T1_, T1_),
79 T1_(*VAL1_)(float, T1_, T1_),
83 PT_(C_::*Getter_)() const,
84 void(C_::*Setter_)(const PT_&)
86 internal::SliderInteractivity I2_,
87 internal::SliderValueMapping V2_
95 explicit
SliderBase(T_ cur, T_ max, Registry::TemplateType type = Registry::Progress_Regular) :
108 ComponentStackWidget(temp),
118 stack.SetValueTransitionSpeed({changespeed, 0, 0, 0});
120 setupinteractivity();
127 void SetValue(
const T_ &value,
bool instant =
false) {
128 setval(value, instant);
133 return this->
operator T_();
141 if(valuemapping == internal::SliderValueMapping::ValueAndRange) {
142 SetSmoothChangeSpeedRatio(changespeed);
145 if(!setval(this->value))
159 if(valuemapping == internal::SliderValueMapping::ValueAndRange) {
160 SetSmoothChangeSpeedRatio(changespeed);
163 if(!setval(this->value))
174 if(exchange && min > max) {
183 if(valuemapping == internal::SliderValueMapping::ValueAndRange) {
184 SetSmoothChangeSpeedRatio(changespeed);
187 if(setval(this->value))
206 auto r = DIV_(value, min, max);
215 if(valuemapping == internal::SliderValueMapping::ValueAndRange) {
216 SetSmoothChangeSpeedRatio(changespeed);
219 this->refreshvalue();
233 this->refreshvalue();
247 this->refreshvalue();
257 operator T_()
const {
267 SetSmoothChangeSpeed(0);
273 SetSmoothChangeSpeedRatio(DIV_(value, min, max));
280 if(valuemapping == internal::SliderValueMapping::OneValue) {
281 stack.SetValueTransitionSpeed({value, 0, 0, 0});
283 else if(valuemapping == internal::SliderValueMapping::ValueAndRange) {
284 auto r = DIV_(range, min, max);
285 auto m = DIV_(max, min, max);
286 if(m == 0 || r == 1) {
287 stack.SetValueTransitionSpeed({value, 0, 0, 0});
290 stack.SetValueTransitionSpeed({value / (1 - r), 0, 0, 0});
298 return FloatToValue(changespeed, min, max);
309 return changespeed != 0;
343 template<
internal::Sl
iderValueMapping vm = valuemapping>
344 typename std::enable_if<vm == internal::SliderValueMapping::ValueAndRange, T_>::type
349 template<
internal::Sl
iderValueMapping vm = valuemapping>
350 typename std::enable_if<vm != internal::SliderValueMapping::ValueAndRange, T_>::type
355 bool setval(T_ val,
bool instant =
false) {
356 auto v = DIV_(val, min, actualmax());
370 refreshvalue(instant);
387 T_ smallchange = T_{1};
388 T_ largechange = T_{10};
393 float changespeed = 1;
403 template<
internal::Sl
iderValueMapping vm = valuemapping>
404 typename std::enable_if<vm == internal::SliderValueMapping::OneValue, void>::type
405 refreshme(
bool instant =
false) {
406 float val = DIV_(this->value, min, max);
408 stack.SetValue(val, 0, 0, instant);
411 template<
internal::Sl
iderValueMapping vm = valuemapping>
412 typename std::enable_if<vm == internal::SliderValueMapping::ValueAndRange, void>::type
413 refreshme(
bool instant =
false) {
414 float val = DIV_(this->value, this->min, this->max-this->range);
415 float v1 = DIV_(this->value, this->min, this->max);
416 float v2 = DIV_(this->value+this->range, this->min, this->max);
417 float r = DIV_(this->range, this->min, this->max);
419 if(DIV_(max, min, max) == 0) {
423 stack.SetValue(val, v1, v2, r, instant);
426 template<
internal::Sl
iderInteractivity si =
interactive>
427 typename std::enable_if<si == internal::SliderInteractivity::None, void>::type
428 setupinteractivity() {
432 template<
internal::Sl
iderInteractivity si =
interactive>
433 typename std::enable_if<si != internal::SliderInteractivity::None, void>::type
434 setupinteractivity() {
437 stack.SetClickEvent([
this](
auto tag,
auto location,
auto btn) {
439 auto ind = stack.ComponentAt(location);
441 tag = stack.GetTemplate(ind).GetTag();
448 if(val == std::numeric_limits<float>::infinity())
451 val =
Clamp(val, 0.f, 1.f);
453 setval(VAL_(val, this->min, this->max));
455 if((interactive & internal::SliderInteractivity::Page)) {
459 auto curval = DIV_(value, this->min, this->max);
462 SetValue(GetValue() + largechange);
464 else if(val < curval) {
465 SetValue(GetValue() - largechange);
469 SetValue(GetValue() + largechange);
472 SetValue(GetValue() - largechange);
478 stack.SetMouseDownEvent([
this](
auto tag,
auto location,
auto btn) {
480 auto ind = stack.ComponentAt(location);
482 tag = stack.GetTemplate(ind).GetTag();
485 if((interactive & internal::SliderInteractivity::HandleOnly)) {
488 downlocation = location;
489 downvalue = stack.GetValue()[0];
490 grab = internal::SliderInteractivity::HandleOnly;
496 stack.SetMouseUpEvent([
this](
auto,
auto,
auto btn) {
503 if((interactive & internal::SliderInteractivity::HandleOnly) && grab == internal::SliderInteractivity::HandleOnly) {
505 if(val == std::numeric_limits<float>::infinity())
510 val =
Clamp(val, 0.f, 1.f);
512 setval(VAL_(val, this->min, this->max));
518 SetValue(T_(GetValue() - amount * smallchange));
527 struct UI::internal::prophelper<SliderBase<T_, DIV_, VAL_, P_, interactive, valuemapping>, T_> helper = UI::internal::prophelper<SliderBase<T_, DIV_, VAL_, P_, interactive, valuemapping>, T_>(
this);