diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 113101820d..fa6a616f3e 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -1020,39 +1020,51 @@ void TriggerButton::GetContentDimensions(const UIContext &dc, float &w, float &h bool Slider::Key(const KeyInput &input) { if (HasFocus() && (input.flags & KEY_DOWN)) { - switch (input.keyCode) { - case NKCODE_DPAD_LEFT: - case NKCODE_MINUS: - case NKCODE_NUMPAD_SUBTRACT: - *value_ -= step_; - break; - case NKCODE_DPAD_RIGHT: - case NKCODE_PLUS: - case NKCODE_NUMPAD_ADD: - *value_ += step_; - break; - case NKCODE_PAGE_UP: - *value_ -= step_ * 10; - break; - case NKCODE_PAGE_DOWN: - *value_ += step_ * 10; - break; - case NKCODE_MOVE_HOME: - *value_ = minValue_; - break; - case NKCODE_MOVE_END: - *value_ = maxValue_; - break; - default: - return false; + if (ApplyKey(input.keyCode)) { + Clamp(); + repeat_ = 0; + repeatCode_ = input.keyCode; + return true; } - Clamp(); - return true; + return false; + } else if ((input.flags & KEY_UP) && input.keyCode == repeatCode_) { + repeat_ = -1; + return false; } else { return false; } } +bool Slider::ApplyKey(int keyCode) { + switch (keyCode) { + case NKCODE_DPAD_LEFT: + case NKCODE_MINUS: + case NKCODE_NUMPAD_SUBTRACT: + *value_ -= step_; + break; + case NKCODE_DPAD_RIGHT: + case NKCODE_PLUS: + case NKCODE_NUMPAD_ADD: + *value_ += step_; + break; + case NKCODE_PAGE_UP: + *value_ -= step_ * 10; + break; + case NKCODE_PAGE_DOWN: + *value_ += step_ * 10; + break; + case NKCODE_MOVE_HOME: + *value_ = minValue_; + break; + case NKCODE_MOVE_END: + *value_ = maxValue_; + break; + default: + return false; + } + return true; +} + void Slider::Touch(const TouchInput &input) { // Calling it afterwards, so dragging_ hasn't been set false yet when checking it above. Clickable::Touch(input); @@ -1066,6 +1078,9 @@ void Slider::Touch(const TouchInput &input) { params.f = (float)(*value_); OnChange.Trigger(params); } + + // Cancel any key repeat. + repeat_ = -1; } void Slider::Clamp() { @@ -1093,6 +1108,23 @@ void Slider::Draw(UIContext &dc) { dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER); } +void Slider::Update(const InputState &input_state) { + if (repeat_ >= 0) { + repeat_++; + } + + if (repeat_ >= 47) { + ApplyKey(repeatCode_); + if ((maxValue_ - minValue_) / step_ >= 300) { + ApplyKey(repeatCode_); + } + Clamp(); + } else if (repeat_ >= 12 && (repeat_ & 1) == 1) { + ApplyKey(repeatCode_); + Clamp(); + } +} + void Slider::GetContentDimensions(const UIContext &dc, float &w, float &h) const { // TODO w = 100; @@ -1101,39 +1133,51 @@ void Slider::GetContentDimensions(const UIContext &dc, float &w, float &h) const bool SliderFloat::Key(const KeyInput &input) { if (HasFocus() && (input.flags & KEY_DOWN)) { - switch (input.keyCode) { - case NKCODE_DPAD_LEFT: - case NKCODE_MINUS: - case NKCODE_NUMPAD_SUBTRACT: - *value_ -= (maxValue_ - minValue_) / 20.0f; - break; - case NKCODE_DPAD_RIGHT: - case NKCODE_PLUS: - case NKCODE_NUMPAD_ADD: - *value_ += (maxValue_ - minValue_) / 30.0f; - break; - case NKCODE_PAGE_UP: - *value_ -= (maxValue_ - minValue_) / 5.0f; - break; - case NKCODE_PAGE_DOWN: - *value_ += (maxValue_ - minValue_) / 5.0f; - break; - case NKCODE_MOVE_HOME: - *value_ = minValue_; - break; - case NKCODE_MOVE_END: - *value_ = maxValue_; - break; - default: + if (ApplyKey(input.keyCode)) { + Clamp(); + repeat_ = 0; + repeatCode_ = input.keyCode; return true; } - Clamp(); - return true; + return false; + } else if ((input.flags & KEY_UP) && input.keyCode == repeatCode_) { + repeat_ = -1; + return false; } else { return false; } } +bool SliderFloat::ApplyKey(int keyCode) { + switch (keyCode) { + case NKCODE_DPAD_LEFT: + case NKCODE_MINUS: + case NKCODE_NUMPAD_SUBTRACT: + *value_ -= (maxValue_ - minValue_) / 50.0f; + break; + case NKCODE_DPAD_RIGHT: + case NKCODE_PLUS: + case NKCODE_NUMPAD_ADD: + *value_ += (maxValue_ - minValue_) / 50.0f; + break; + case NKCODE_PAGE_UP: + *value_ -= (maxValue_ - minValue_) / 5.0f; + break; + case NKCODE_PAGE_DOWN: + *value_ += (maxValue_ - minValue_) / 5.0f; + break; + case NKCODE_MOVE_HOME: + *value_ = minValue_; + break; + case NKCODE_MOVE_END: + *value_ = maxValue_; + break; + default: + return false; + } + return true; +} + void SliderFloat::Touch(const TouchInput &input) { Clickable::Touch(input); if (dragging_) { @@ -1146,6 +1190,9 @@ void SliderFloat::Touch(const TouchInput &input) { params.f = (float)(*value_); OnChange.Trigger(params); } + + // Cancel any key repeat. + repeat_ = -1; } void SliderFloat::Clamp() { @@ -1170,6 +1217,20 @@ void SliderFloat::Draw(UIContext &dc) { dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER); } +void SliderFloat::Update(const InputState &input_state) { + if (repeat_ >= 0) { + repeat_++; + } + + if (repeat_ >= 47) { + ApplyKey(repeatCode_); + Clamp(); + } else if (repeat_ >= 12 && (repeat_ & 1) == 1) { + ApplyKey(repeatCode_); + Clamp(); + } +} + void SliderFloat::GetContentDimensions(const UIContext &dc, float &w, float &h) const { // TODO w = 100; diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index ec2222cbeb..7611326405 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -509,15 +509,16 @@ private: class Slider : public Clickable { public: Slider(int *value, int minValue, int maxValue, LayoutParams *layoutParams = 0) - : Clickable(layoutParams), value_(value), showPercent_(false), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70), step_(1) {} + : Clickable(layoutParams), value_(value), showPercent_(false), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70), step_(1), repeat_(-1) {} Slider(int *value, int minValue, int maxValue, int step = 1, LayoutParams *layoutParams = 0) - : Clickable(layoutParams), value_(value), showPercent_(false), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70) { + : Clickable(layoutParams), value_(value), showPercent_(false), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70), repeat_(-1) { step_ = step <= 0 ? 1 : step; } void Draw(UIContext &dc) override; bool Key(const KeyInput &input) override; void Touch(const TouchInput &input) override; + void Update(const InputState &input_state) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void SetShowPercent(bool s) { showPercent_ = s; } @@ -527,6 +528,8 @@ public: Event OnChange; private: + bool ApplyKey(int keyCode); + int *value_; bool showPercent_; int minValue_; @@ -534,15 +537,18 @@ private: float paddingLeft_; float paddingRight_; int step_; + int repeat_; + int repeatCode_; }; class SliderFloat : public Clickable { public: SliderFloat(float *value, float minValue, float maxValue, LayoutParams *layoutParams = 0) - : Clickable(layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70) {} + : Clickable(layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70), repeat_(-1) {} void Draw(UIContext &dc) override; bool Key(const KeyInput &input) override; void Touch(const TouchInput &input) override; + void Update(const InputState &input_state) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; // OK to call this from the outside after having modified *value_ @@ -551,11 +557,15 @@ public: Event OnChange; private: + bool ApplyKey(int keyCode); + float *value_; float minValue_; float maxValue_; float paddingLeft_; float paddingRight_; + int repeat_; + int repeatCode_; }; // Basic button that modifies a bitfield based on the pressed status. Supports multitouch.