From 42f8bbde50c7a5e736445aaed61575d81a24b484 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 5 Sep 2016 16:14:01 -0700 Subject: [PATCH 1/2] UI: Make sliders increase with button held. --- ext/native/ui/view.cpp | 167 ++++++++++++++++++++++++++++------------- ext/native/ui/view.h | 16 +++- 2 files changed, 127 insertions(+), 56 deletions(-) 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. From b3b96ad9936e4127ff280854671af0cbb726d90c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 5 Sep 2016 16:15:16 -0700 Subject: [PATCH 2/2] UI: Use powered slider repeat on all devices. Some devices send through repeats, but we want to do the increased speed thing. It might be ideal to use its repeat rate settings, but we don't have a good way to do that cross platform... Fixes #8696. --- ext/native/ui/view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index fa6a616f3e..752fb9cebc 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -1019,7 +1019,7 @@ void TriggerButton::GetContentDimensions(const UIContext &dc, float &w, float &h } bool Slider::Key(const KeyInput &input) { - if (HasFocus() && (input.flags & KEY_DOWN)) { + if (HasFocus() && (input.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) { if (ApplyKey(input.keyCode)) { Clamp(); repeat_ = 0; @@ -1132,7 +1132,7 @@ void Slider::GetContentDimensions(const UIContext &dc, float &w, float &h) const } bool SliderFloat::Key(const KeyInput &input) { - if (HasFocus() && (input.flags & KEY_DOWN)) { + if (HasFocus() && (input.flags & (KEY_DOWN | KEY_IS_REPEAT)) == KEY_DOWN) { if (ApplyKey(input.keyCode)) { Clamp(); repeat_ = 0;