From cd8987b33bbe299af0383609db28fecd6546bffe Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 18 Jul 2013 10:25:30 +0200 Subject: [PATCH] Add basic slider control --- ui/ui_screen.cpp | 6 ++++++ ui/ui_screen.h | 12 ++++++++++++ ui/view.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ ui/view.h | 19 ++++++++++++++++++- 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/ui/ui_screen.cpp b/ui/ui_screen.cpp index c00b3cb91b..97143bfb39 100644 --- a/ui/ui_screen.cpp +++ b/ui/ui_screen.cpp @@ -108,3 +108,9 @@ UI::EventReturn ListPopupScreen::OnListChoice(UI::EventParams &e) { void ListPopupScreen::OnCompleted() { callback_(adaptor_.GetSelected()); } + + +void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { + using namespace UI; + slider_ = parent->Add(new Slider(value_, minValue_, maxValue_)); +} diff --git a/ui/ui_screen.h b/ui/ui_screen.h index 66a87e4c5d..81c6ba4523 100644 --- a/ui/ui_screen.h +++ b/ui/ui_screen.h @@ -66,3 +66,15 @@ private: std::function callback_; }; + +class SliderPopupScreen : public PopupScreen { +public: + SliderPopupScreen(int *value, int minValue, int maxValue, const std::string &title) : PopupScreen(title), value_(value), minValue_(minValue), maxValue_(maxValue) {} + void CreatePopupContents(UI::ViewGroup *parent); + +private: + UI::Slider *slider_; + int *value_; + int minValue_; + int maxValue_; +}; \ No newline at end of file diff --git a/ui/view.cpp b/ui/view.cpp index b9c29bc310..dea4038e08 100644 --- a/ui/view.cpp +++ b/ui/view.cpp @@ -2,6 +2,7 @@ #include "base/display.h" #include "base/mutex.h" #include "input/input_state.h" +#include "input/keycodes.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture.h" #include "gfx/texture_atlas.h" @@ -418,6 +419,50 @@ void TriggerButton::GetContentDimensions(const UIContext &dc, float &w, float &h h = image.h; } +void Slider::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 Slider::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 Slider::Clamp() { + if (*value_ < minValue_) *value_ = minValue_; + else if (*value_ > maxValue_) *value_ = maxValue_; +} + +void Slider::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 Slider::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 c574b2cb64..1af686aa88 100644 --- a/ui/view.h +++ b/ui/view.h @@ -79,6 +79,7 @@ struct Theme { int uiFontSmaller; int checkOn; int checkOff; + int sliderKnob; int whiteImage; Style buttonStyle; @@ -401,6 +402,23 @@ private: std::string text_; }; +class Slider : public Clickable { +public: + Slider(int *value, int minValue, int 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(); + int *value_; + int minValue_; + int maxValue_; +}; + + // Basic button that modifies a bitfield based on the pressed status. Supports multitouch. // Suitable for controller simulation (ABXY etc). class TriggerButton : public View { @@ -517,7 +535,6 @@ private: std::string smallText_; }; - // These are for generic use. class Spacer : public InertView {