diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index f487413d32..1fc3f749f4 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -114,7 +114,7 @@ GWindow* create_settings_window(Terminal& terminal, RefPtr config) slider_container->set_fill_with_background_color(true); slider_container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); slider_container->set_preferred_size({ 100, 50 }); - auto* slider = new GSlider(slider_container); + auto* slider = new GSlider(Orientation::Horizontal, slider_container); slider->set_fill_with_background_color(true); slider->set_background_color(Color::WarmGray); diff --git a/Demos/WidgetGallery/main.cpp b/Demos/WidgetGallery/main.cpp index 5fb1cd91f1..93fe3273a5 100755 --- a/Demos/WidgetGallery/main.cpp +++ b/Demos/WidgetGallery/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char** argv) GApplication app(argc, argv); auto* window = new GWindow; - window->set_rect(100, 100, 320, 480); + window->set_rect(100, 100, 320, 620); window->set_title("Widget Gallery"); auto* main_widget = new GWidget; @@ -66,11 +66,23 @@ int main(int argc, char** argv) auto* spinbox2 = new GSpinBox(main_widget); spinbox2->set_enabled(false); - auto* slider1 = new GSlider(main_widget); + auto* vertical_slider_container = new GWidget(main_widget); + vertical_slider_container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); + vertical_slider_container->set_preferred_size({ 0, 100 }); + vertical_slider_container->set_layout(make(Orientation::Horizontal)); + auto* vslider1 = new GSlider(Orientation::Vertical, vertical_slider_container); + (void)vslider1; + auto* vslider2 = new GSlider(Orientation::Vertical, vertical_slider_container); + vslider2->set_enabled(false); + auto* vslider3 = new GSlider(Orientation::Vertical, vertical_slider_container); + vslider3->set_max(5); + vslider3->set_knob_size_mode(GSlider::KnobSizeMode::Proportional); + + auto* slider1 = new GSlider(Orientation::Horizontal, main_widget); (void)slider1; - auto* slider2 = new GSlider(main_widget); + auto* slider2 = new GSlider(Orientation::Horizontal, main_widget); slider2->set_enabled(false); - auto* slider3 = new GSlider(main_widget); + auto* slider3 = new GSlider(Orientation::Horizontal, main_widget); slider3->set_max(5); slider3->set_knob_size_mode(GSlider::KnobSizeMode::Proportional); diff --git a/DevTools/VisualBuilder/VBWidgetRegistry.cpp b/DevTools/VisualBuilder/VBWidgetRegistry.cpp index 6463c0e875..a528935b0e 100644 --- a/DevTools/VisualBuilder/VBWidgetRegistry.cpp +++ b/DevTools/VisualBuilder/VBWidgetRegistry.cpp @@ -107,7 +107,7 @@ static GWidget* build_gwidget(VBWidgetType type, GWidget* parent) return bar; } case VBWidgetType::GSlider: { - auto* slider = new GSlider(parent); + auto* slider = new GSlider(Orientation::Horizontal, parent); slider->set_range(0, 100); slider->set_value(50); return slider; diff --git a/Libraries/LibGUI/GSlider.cpp b/Libraries/LibGUI/GSlider.cpp index 3a821e9d41..ea1eddbc6f 100755 --- a/Libraries/LibGUI/GSlider.cpp +++ b/Libraries/LibGUI/GSlider.cpp @@ -1,9 +1,10 @@ +#include #include #include -#include -GSlider::GSlider(GWidget* parent) +GSlider::GSlider(Orientation orientation, GWidget* parent) : GWidget(parent) + , m_orientation(orientation) { } @@ -46,8 +47,15 @@ void GSlider::paint_event(GPaintEvent& event) GPainter painter(*this); painter.add_clip_rect(event.rect()); - Rect track_rect { inner_rect().x(), 0, inner_rect().width(), track_height() }; - track_rect.center_vertically_within(inner_rect()); + Rect track_rect; + + if (orientation() == Orientation::Horizontal) { + track_rect = { inner_rect().x(), 0, inner_rect().width(), track_size() }; + track_rect.center_vertically_within(inner_rect()); + } else { + track_rect = { 0, inner_rect().y(), track_size(), inner_rect().height() }; + track_rect.center_horizontally_within(inner_rect()); + } StylePainter::paint_frame(painter, track_rect, FrameShape::Panel, FrameShadow::Sunken, 1); StylePainter::paint_button(painter, knob_rect(), ButtonStyle::Normal, false, m_knob_hovered); @@ -57,28 +65,28 @@ Rect GSlider::knob_rect() const { auto inner_rect = this->inner_rect(); Rect rect; - rect.set_y(0); - rect.set_height(knob_height()); + rect.set_secondary_offset_for_orientation(orientation(), 0); + rect.set_secondary_size_for_orientation(orientation(), knob_secondary_size()); if (knob_size_mode() == KnobSizeMode::Fixed) { + if (m_max - m_min) { + float scale = (float)inner_rect.primary_size_for_orientation(orientation()) / (float)(m_max - m_min); + rect.set_primary_offset_for_orientation(orientation(), inner_rect.primary_offset_for_orientation(orientation()) + ((int)(m_value * scale)) - (knob_fixed_primary_size() / 2)); + } else + rect.set_primary_size_for_orientation(orientation(), 0); + rect.set_primary_size_for_orientation(orientation(), knob_fixed_primary_size()); + } else { + float scale = (float)inner_rect.primary_size_for_orientation(orientation()) / (float)(m_max - m_min + 1); + rect.set_primary_offset_for_orientation(orientation(), inner_rect.primary_offset_for_orientation(orientation()) + ((int)(m_value * scale))); if (m_max - m_min) - { - float scale = (float)inner_rect.width() / (float)(m_max - m_min); - rect.set_x(inner_rect.x() + ((int)(m_value * scale)) - (knob_fixed_width() / 2)); - } + rect.set_primary_size_for_orientation(orientation(), ::max((int)(scale), knob_fixed_primary_size())); else - rect.set_x(0); - rect.set_width(knob_fixed_width()); + rect.set_primary_size_for_orientation(orientation(), inner_rect.primary_size_for_orientation(orientation())); } - else { - float scale = (float)inner_rect.width() / (float)(m_max - m_min + 1); - rect.set_x(inner_rect.x() + ((int)(m_value * scale))); - if (m_max - m_min) - rect.set_width(::max((int)(scale), knob_fixed_width())); - else - rect.set_width(inner_rect.width()); - } - rect.center_vertically_within(inner_rect); + if (orientation() == Orientation::Horizontal) + rect.center_vertically_within(inner_rect); + else + rect.center_horizontally_within(inner_rect); return rect; } @@ -92,11 +100,10 @@ void GSlider::mousedown_event(GMouseEvent& event) m_drag_origin = event.position(); m_drag_origin_value = m_value; return; - } - else { - if (event.position().x() > knob_rect().right()) + } else { + if (event.position().primary_offset_for_orientation(orientation()) > knob_rect().last_edge_for_orientation(orientation())) set_value(m_value + 1); - else if (event.position().x() < knob_rect().left()) + else if (event.position().primary_offset_for_orientation(orientation()) < knob_rect().first_edge_for_orientation(orientation())) set_value(m_value - 1); } } @@ -109,8 +116,8 @@ void GSlider::mousemove_event(GMouseEvent& event) return; set_knob_hovered(knob_rect().contains(event.position())); if (m_dragging) { - float delta = event.position().x() - m_drag_origin.x(); - float scrubbable_range = inner_rect().width(); + float delta = event.position().primary_offset_for_orientation(orientation()) - m_drag_origin.primary_offset_for_orientation(orientation()); + float scrubbable_range = inner_rect().primary_size_for_orientation(orientation()); float value_steps_per_scrubbed_pixel = (m_max - m_min) / scrubbable_range; float new_value = m_drag_origin_value + (value_steps_per_scrubbed_pixel * delta); set_value((int)new_value); diff --git a/Libraries/LibGUI/GSlider.h b/Libraries/LibGUI/GSlider.h index a9791ae409..bfd787cbd3 100755 --- a/Libraries/LibGUI/GSlider.h +++ b/Libraries/LibGUI/GSlider.h @@ -4,11 +4,16 @@ class GSlider : public GWidget { public: - enum class KnobSizeMode { Fixed, Proportional }; + enum class KnobSizeMode { + Fixed, + Proportional, + }; - explicit GSlider(GWidget*); + GSlider(Orientation, GWidget*); virtual ~GSlider() override; + Orientation orientation() const { return m_orientation; } + int value() const { return m_value; } int min() const { return m_min; } int max() const { return m_max; } @@ -22,12 +27,18 @@ public: void set_knob_size_mode(KnobSizeMode mode) { m_knob_size_mode = mode; } KnobSizeMode knob_size_mode() const { return m_knob_size_mode; } - int track_height() const { return 2; } - int knob_fixed_width() const { return 8; } - int knob_height() const { return 20; } + int track_size() const { return 2; } + int knob_fixed_primary_size() const { return 8; } + int knob_secondary_size() const { return 20; } Rect knob_rect() const; - Rect inner_rect() const { return rect().shrunken(20, 0); } + + Rect inner_rect() const + { + if (orientation() == Orientation::Horizontal) + return rect().shrunken(20, 0); + return rect().shrunken(0, 20); + } Function on_value_changed; @@ -45,11 +56,10 @@ private: int m_value { 0 }; int m_min { 0 }; int m_max { 100 }; - bool m_knob_hovered { false }; bool m_dragging { false }; int m_drag_origin_value { 0 }; Point m_drag_origin; - KnobSizeMode m_knob_size_mode { KnobSizeMode::Fixed }; + Orientation m_orientation { Orientation::Horizontal }; };