mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 14:47:34 +00:00
GSlider: Add support for vertical sliders.
You now have to pass an Orientation to the GSlider constructor. It's not possible to change the orientation after construction. Added some vertical GSliders to the WidgetGallery demo for testing. :^)
This commit is contained in:
parent
8ab1923abe
commit
c59b053ad6
5 changed files with 70 additions and 41 deletions
|
@ -114,7 +114,7 @@ GWindow* create_settings_window(Terminal& terminal, RefPtr<CConfigFile> config)
|
||||||
slider_container->set_fill_with_background_color(true);
|
slider_container->set_fill_with_background_color(true);
|
||||||
slider_container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
slider_container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||||
slider_container->set_preferred_size({ 100, 50 });
|
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_fill_with_background_color(true);
|
||||||
slider->set_background_color(Color::WarmGray);
|
slider->set_background_color(Color::WarmGray);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ int main(int argc, char** argv)
|
||||||
GApplication app(argc, argv);
|
GApplication app(argc, argv);
|
||||||
|
|
||||||
auto* window = new GWindow;
|
auto* window = new GWindow;
|
||||||
window->set_rect(100, 100, 320, 480);
|
window->set_rect(100, 100, 320, 620);
|
||||||
window->set_title("Widget Gallery");
|
window->set_title("Widget Gallery");
|
||||||
|
|
||||||
auto* main_widget = new GWidget;
|
auto* main_widget = new GWidget;
|
||||||
|
@ -66,11 +66,23 @@ int main(int argc, char** argv)
|
||||||
auto* spinbox2 = new GSpinBox(main_widget);
|
auto* spinbox2 = new GSpinBox(main_widget);
|
||||||
spinbox2->set_enabled(false);
|
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<GBoxLayout>(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;
|
(void)slider1;
|
||||||
auto* slider2 = new GSlider(main_widget);
|
auto* slider2 = new GSlider(Orientation::Horizontal, main_widget);
|
||||||
slider2->set_enabled(false);
|
slider2->set_enabled(false);
|
||||||
auto* slider3 = new GSlider(main_widget);
|
auto* slider3 = new GSlider(Orientation::Horizontal, main_widget);
|
||||||
slider3->set_max(5);
|
slider3->set_max(5);
|
||||||
slider3->set_knob_size_mode(GSlider::KnobSizeMode::Proportional);
|
slider3->set_knob_size_mode(GSlider::KnobSizeMode::Proportional);
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ static GWidget* build_gwidget(VBWidgetType type, GWidget* parent)
|
||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
case VBWidgetType::GSlider: {
|
case VBWidgetType::GSlider: {
|
||||||
auto* slider = new GSlider(parent);
|
auto* slider = new GSlider(Orientation::Horizontal, parent);
|
||||||
slider->set_range(0, 100);
|
slider->set_range(0, 100);
|
||||||
slider->set_value(50);
|
slider->set_value(50);
|
||||||
return slider;
|
return slider;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
#include <LibDraw/StylePainter.h>
|
||||||
#include <LibGUI/GPainter.h>
|
#include <LibGUI/GPainter.h>
|
||||||
#include <LibGUI/GSlider.h>
|
#include <LibGUI/GSlider.h>
|
||||||
#include <LibDraw/StylePainter.h>
|
|
||||||
|
|
||||||
GSlider::GSlider(GWidget* parent)
|
GSlider::GSlider(Orientation orientation, GWidget* parent)
|
||||||
: GWidget(parent)
|
: GWidget(parent)
|
||||||
|
, m_orientation(orientation)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +47,15 @@ void GSlider::paint_event(GPaintEvent& event)
|
||||||
GPainter painter(*this);
|
GPainter painter(*this);
|
||||||
painter.add_clip_rect(event.rect());
|
painter.add_clip_rect(event.rect());
|
||||||
|
|
||||||
Rect track_rect { inner_rect().x(), 0, inner_rect().width(), track_height() };
|
Rect track_rect;
|
||||||
track_rect.center_vertically_within(inner_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_frame(painter, track_rect, FrameShape::Panel, FrameShadow::Sunken, 1);
|
||||||
StylePainter::paint_button(painter, knob_rect(), ButtonStyle::Normal, false, m_knob_hovered);
|
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();
|
auto inner_rect = this->inner_rect();
|
||||||
Rect rect;
|
Rect rect;
|
||||||
rect.set_y(0);
|
rect.set_secondary_offset_for_orientation(orientation(), 0);
|
||||||
rect.set_height(knob_height());
|
rect.set_secondary_size_for_orientation(orientation(), knob_secondary_size());
|
||||||
|
|
||||||
if (knob_size_mode() == KnobSizeMode::Fixed) {
|
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)
|
if (m_max - m_min)
|
||||||
{
|
rect.set_primary_size_for_orientation(orientation(), ::max((int)(scale), knob_fixed_primary_size()));
|
||||||
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));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
rect.set_x(0);
|
rect.set_primary_size_for_orientation(orientation(), inner_rect.primary_size_for_orientation(orientation()));
|
||||||
rect.set_width(knob_fixed_width());
|
|
||||||
}
|
}
|
||||||
else {
|
if (orientation() == Orientation::Horizontal)
|
||||||
float scale = (float)inner_rect.width() / (float)(m_max - m_min + 1);
|
rect.center_vertically_within(inner_rect);
|
||||||
rect.set_x(inner_rect.x() + ((int)(m_value * scale)));
|
else
|
||||||
if (m_max - m_min)
|
rect.center_horizontally_within(inner_rect);
|
||||||
rect.set_width(::max((int)(scale), knob_fixed_width()));
|
|
||||||
else
|
|
||||||
rect.set_width(inner_rect.width());
|
|
||||||
}
|
|
||||||
rect.center_vertically_within(inner_rect);
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,11 +100,10 @@ void GSlider::mousedown_event(GMouseEvent& event)
|
||||||
m_drag_origin = event.position();
|
m_drag_origin = event.position();
|
||||||
m_drag_origin_value = m_value;
|
m_drag_origin_value = m_value;
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else {
|
if (event.position().primary_offset_for_orientation(orientation()) > knob_rect().last_edge_for_orientation(orientation()))
|
||||||
if (event.position().x() > knob_rect().right())
|
|
||||||
set_value(m_value + 1);
|
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);
|
set_value(m_value - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,8 +116,8 @@ void GSlider::mousemove_event(GMouseEvent& event)
|
||||||
return;
|
return;
|
||||||
set_knob_hovered(knob_rect().contains(event.position()));
|
set_knob_hovered(knob_rect().contains(event.position()));
|
||||||
if (m_dragging) {
|
if (m_dragging) {
|
||||||
float delta = event.position().x() - m_drag_origin.x();
|
float delta = event.position().primary_offset_for_orientation(orientation()) - m_drag_origin.primary_offset_for_orientation(orientation());
|
||||||
float scrubbable_range = inner_rect().width();
|
float scrubbable_range = inner_rect().primary_size_for_orientation(orientation());
|
||||||
float value_steps_per_scrubbed_pixel = (m_max - m_min) / scrubbable_range;
|
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);
|
float new_value = m_drag_origin_value + (value_steps_per_scrubbed_pixel * delta);
|
||||||
set_value((int)new_value);
|
set_value((int)new_value);
|
||||||
|
|
|
@ -4,11 +4,16 @@
|
||||||
|
|
||||||
class GSlider : public GWidget {
|
class GSlider : public GWidget {
|
||||||
public:
|
public:
|
||||||
enum class KnobSizeMode { Fixed, Proportional };
|
enum class KnobSizeMode {
|
||||||
|
Fixed,
|
||||||
|
Proportional,
|
||||||
|
};
|
||||||
|
|
||||||
explicit GSlider(GWidget*);
|
GSlider(Orientation, GWidget*);
|
||||||
virtual ~GSlider() override;
|
virtual ~GSlider() override;
|
||||||
|
|
||||||
|
Orientation orientation() const { return m_orientation; }
|
||||||
|
|
||||||
int value() const { return m_value; }
|
int value() const { return m_value; }
|
||||||
int min() const { return m_min; }
|
int min() const { return m_min; }
|
||||||
int max() const { return m_max; }
|
int max() const { return m_max; }
|
||||||
|
@ -22,12 +27,18 @@ public:
|
||||||
void set_knob_size_mode(KnobSizeMode mode) { m_knob_size_mode = mode; }
|
void set_knob_size_mode(KnobSizeMode mode) { m_knob_size_mode = mode; }
|
||||||
KnobSizeMode knob_size_mode() const { return m_knob_size_mode; }
|
KnobSizeMode knob_size_mode() const { return m_knob_size_mode; }
|
||||||
|
|
||||||
int track_height() const { return 2; }
|
int track_size() const { return 2; }
|
||||||
int knob_fixed_width() const { return 8; }
|
int knob_fixed_primary_size() const { return 8; }
|
||||||
int knob_height() const { return 20; }
|
int knob_secondary_size() const { return 20; }
|
||||||
|
|
||||||
Rect knob_rect() const;
|
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<void(int)> on_value_changed;
|
Function<void(int)> on_value_changed;
|
||||||
|
|
||||||
|
@ -45,11 +56,10 @@ private:
|
||||||
int m_value { 0 };
|
int m_value { 0 };
|
||||||
int m_min { 0 };
|
int m_min { 0 };
|
||||||
int m_max { 100 };
|
int m_max { 100 };
|
||||||
|
|
||||||
bool m_knob_hovered { false };
|
bool m_knob_hovered { false };
|
||||||
bool m_dragging { false };
|
bool m_dragging { false };
|
||||||
int m_drag_origin_value { 0 };
|
int m_drag_origin_value { 0 };
|
||||||
Point m_drag_origin;
|
Point m_drag_origin;
|
||||||
|
|
||||||
KnobSizeMode m_knob_size_mode { KnobSizeMode::Fixed };
|
KnobSizeMode m_knob_size_mode { KnobSizeMode::Fixed };
|
||||||
|
Orientation m_orientation { Orientation::Horizontal };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue