mirror of
https://github.com/RGBCube/serenity
synced 2025-05-18 21:35:06 +00:00

This widget is far from finished, but it's off to a good start. Also added a GResizeEvent and GWidget::resize_event() so that widgets can react to being resized.
120 lines
2.9 KiB
C++
120 lines
2.9 KiB
C++
#include <LibGUI/GScrollBar.h>
|
|
#include <SharedGraphics/GraphicsBitmap.h>
|
|
#include <SharedGraphics/Painter.h>
|
|
|
|
GScrollBar::GScrollBar(GWidget* parent)
|
|
: GWidget(parent)
|
|
{
|
|
}
|
|
|
|
GScrollBar::~GScrollBar()
|
|
{
|
|
}
|
|
|
|
void GScrollBar::set_range(int min, int max)
|
|
{
|
|
ASSERT(min <= max);
|
|
if (m_min == min && m_max == max)
|
|
return;
|
|
|
|
m_min = min;
|
|
m_max = max;
|
|
|
|
int old_value = m_value;
|
|
if (m_value < m_min)
|
|
m_value = m_min;
|
|
if (m_value > m_max)
|
|
m_value = m_max;
|
|
if (on_change && m_value != old_value)
|
|
on_change(m_value);
|
|
|
|
update();
|
|
}
|
|
|
|
void GScrollBar::set_value(int value)
|
|
{
|
|
if (value < m_min)
|
|
value = m_min;
|
|
if (value > m_max)
|
|
value = m_max;
|
|
if (value == m_value)
|
|
return;
|
|
m_value = value;
|
|
if (on_change)
|
|
on_change(value);
|
|
update();
|
|
}
|
|
|
|
Rect GScrollBar::up_button_rect() const
|
|
{
|
|
return { 0, 0, button_size(), button_size() };
|
|
}
|
|
|
|
Rect GScrollBar::down_button_rect() const
|
|
{
|
|
return { 0, height() - button_size(), button_size(), button_size() };
|
|
}
|
|
|
|
Rect GScrollBar::pgup_rect() const
|
|
{
|
|
return { 0, button_size(), button_size(), scrubber_rect().top() - button_size() };
|
|
}
|
|
|
|
Rect GScrollBar::pgdn_rect() const
|
|
{
|
|
auto scrubber_rect = this->scrubber_rect();
|
|
return { 0, scrubber_rect.bottom(), button_size(), height() - button_size() - scrubber_rect.bottom() };
|
|
}
|
|
|
|
Rect GScrollBar::scrubber_rect() const
|
|
{
|
|
int range_size = m_max - m_min;
|
|
if (range_size == 0)
|
|
return { 0, button_size(), button_size(), height() - button_size() * 2 };
|
|
float available_y = height() - button_size() * 3;
|
|
float y_step = available_y / range_size;
|
|
float y = button_size() + (y_step * m_value);
|
|
return { 0, (int)y, button_size(), button_size() };
|
|
}
|
|
|
|
void GScrollBar::paint_event(GPaintEvent&)
|
|
{
|
|
Painter painter(*this);
|
|
|
|
painter.fill_rect(rect(), Color(0xc0c0c0));
|
|
|
|
painter.draw_rect(up_button_rect(), Color::DarkGray, true);
|
|
painter.fill_rect(up_button_rect().shrunken(2, 2), Color::LightGray);
|
|
|
|
painter.draw_rect(down_button_rect(), Color::DarkGray, true);
|
|
painter.fill_rect(down_button_rect().shrunken(2, 2), Color::LightGray);
|
|
|
|
painter.fill_rect(pgup_rect(), Color::Magenta);
|
|
painter.fill_rect(pgdn_rect(), Color::Yellow);
|
|
|
|
painter.fill_rect(scrubber_rect(), Color::Red);
|
|
|
|
dbgprintf("Paint!\n");
|
|
}
|
|
|
|
void GScrollBar::mousedown_event(GMouseEvent& event)
|
|
{
|
|
if (event.button() != GMouseButton::Left)
|
|
return;
|
|
if (up_button_rect().contains(event.position())) {
|
|
set_value(value() - m_step);
|
|
return;
|
|
}
|
|
if (down_button_rect().contains(event.position())) {
|
|
set_value(value() + m_step);
|
|
return;
|
|
}
|
|
if (pgup_rect().contains(event.position())) {
|
|
set_value(value() - m_big_step);
|
|
return;
|
|
}
|
|
if (pgdn_rect().contains(event.position())) {
|
|
set_value(value() + m_big_step);
|
|
return;
|
|
}
|
|
}
|