diff --git a/ui/ui_screen.cpp b/ui/ui_screen.cpp index 38f5b64c81..f904cc28ec 100644 --- a/ui/ui_screen.cpp +++ b/ui/ui_screen.cpp @@ -113,8 +113,12 @@ void ListPopupScreen::OnCompleted() { callback_(adaptor_.GetSelected()); } - void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { using namespace UI; slider_ = parent->Add(new Slider(value_, minValue_, maxValue_)); } + +void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + slider_ = parent->Add(new SliderFloat(value_, minValue_, maxValue_)); +} diff --git a/ui/ui_screen.h b/ui/ui_screen.h index 81c6ba4523..0901481eac 100644 --- a/ui/ui_screen.h +++ b/ui/ui_screen.h @@ -77,4 +77,16 @@ private: int *value_; int minValue_; int maxValue_; +}; + +class SliderFloatPopupScreen : public PopupScreen { +public: + SliderFloatPopupScreen(float *value, float minValue, float maxValue, const std::string &title) : PopupScreen(title), value_(value), minValue_(minValue), maxValue_(maxValue) {} + void CreatePopupContents(UI::ViewGroup *parent); + +private: + UI::SliderFloat *slider_; + float *value_; + float minValue_; + float maxValue_; }; \ No newline at end of file diff --git a/ui/view.cpp b/ui/view.cpp index dea4038e08..de91e11693 100644 --- a/ui/view.cpp +++ b/ui/view.cpp @@ -463,6 +463,50 @@ void Slider::GetContentDimensions(const UIContext &dc, float &w, float &h) const h = 50; } +void SliderFloat::Key(const KeyInput &input) { + if (HasFocus() && input.flags & KEY_DOWN) { + switch (input.keyCode) { + case KEYCODE_DPAD_LEFT: + case KEYCODE_MINUS: + case KEYCODE_NUMPAD_SUBTRACT: + *value_ -= 1; + break; + case KEYCODE_DPAD_RIGHT: + case KEYCODE_PLUS: + case KEYCODE_NUMPAD_ADD: + *value_ -= 1; + break; + } + Clamp(); + } +} + +void SliderFloat::Touch(const TouchInput &input) { + if (dragging_ || bounds_.Contains(input.x, input.y)) { + float relativeX = (input.x - bounds_.x) / bounds_.w; + *value_ = floorf(relativeX * (maxValue_ - minValue_) + minValue_ + 0.5f); + Clamp(); + } +} + +void SliderFloat::Clamp() { + if (*value_ < minValue_) *value_ = minValue_; + else if (*value_ > maxValue_) *value_ = maxValue_; +} + +void SliderFloat::Draw(UIContext &dc) { + float knobX = ((float)(*value_) - minValue_) / (maxValue_ - minValue_) * bounds_.w + bounds_.x; + dc.FillRect(Drawable(0xFFFFFFFF), Bounds(bounds_.x, bounds_.centerY() - 2, knobX - bounds_.x, 4)); + dc.FillRect(Drawable(0xFF808080), Bounds(knobX, bounds_.centerY() - 2, bounds_.x + bounds_.w - knobX, 4)); + dc.Draw()->DrawImage(dc.theme->sliderKnob, knobX, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); +} + +void SliderFloat::GetContentDimensions(const UIContext &dc, float &w, float &h) const { + // TODO + w = 100; + h = 50; +} + /* TabStrip::TabStrip() diff --git a/ui/view.h b/ui/view.h index 1af686aa88..f09c6810e2 100644 --- a/ui/view.h +++ b/ui/view.h @@ -418,6 +418,21 @@ private: int maxValue_; }; +class SliderFloat : public Clickable { +public: + SliderFloat(float *value, float minValue, float maxValue, LayoutParams *layoutParams = 0) + : Clickable(layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue) {} + virtual void Draw(UIContext &dc); + virtual void Key(const KeyInput &input); + virtual void Touch(const TouchInput &input); + virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const; + +private: + void Clamp(); + float *value_; + float minValue_; + float maxValue_; +}; // Basic button that modifies a bitfield based on the pressed status. Supports multitouch. // Suitable for controller simulation (ABXY etc).