mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 12:25:12 +00:00
LibGUI: Add Banner concept to AbstractScrollableWidget
Banners are abstract widgets which can house additional controls and information on a temporary basis, popping in from the top of their parent when needed.
This commit is contained in:
parent
c2cc01c920
commit
3c4a563415
2 changed files with 42 additions and 6 deletions
|
@ -40,6 +40,19 @@ AbstractScrollableWidget::AbstractScrollableWidget()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractScrollableWidget::set_banner_widget(Widget* widget)
|
||||||
|
{
|
||||||
|
if (m_banner_widget == widget)
|
||||||
|
return;
|
||||||
|
if (m_banner_widget)
|
||||||
|
remove_child(*m_banner_widget);
|
||||||
|
if (!widget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_banner_widget = widget;
|
||||||
|
add_child(*m_banner_widget);
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractScrollableWidget::handle_wheel_event(MouseEvent& event, Widget& event_source)
|
void AbstractScrollableWidget::handle_wheel_event(MouseEvent& event, Widget& event_source)
|
||||||
{
|
{
|
||||||
if (!m_scrollbars_enabled) {
|
if (!m_scrollbars_enabled) {
|
||||||
|
@ -77,16 +90,25 @@ void AbstractScrollableWidget::mousewheel_event(MouseEvent& event)
|
||||||
void AbstractScrollableWidget::custom_layout()
|
void AbstractScrollableWidget::custom_layout()
|
||||||
{
|
{
|
||||||
auto inner_rect = frame_inner_rect_for_size(size());
|
auto inner_rect = frame_inner_rect_for_size(size());
|
||||||
|
int height_wanted_by_banner_widget = m_banner_widget && m_banner_widget->is_visible() ? m_banner_widget->effective_min_size().height().as_int() : 0;
|
||||||
int height_wanted_by_horizontal_scrollbar = m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->effective_min_size().height().as_int() : 0;
|
int height_wanted_by_horizontal_scrollbar = m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->effective_min_size().height().as_int() : 0;
|
||||||
int width_wanted_by_vertical_scrollbar = m_vertical_scrollbar->is_visible() ? m_vertical_scrollbar->effective_min_size().width().as_int() : 0;
|
int width_wanted_by_vertical_scrollbar = m_vertical_scrollbar->is_visible() ? m_vertical_scrollbar->effective_min_size().width().as_int() : 0;
|
||||||
|
|
||||||
|
if (m_banner_widget && m_banner_widget->is_visible()) {
|
||||||
|
m_banner_widget->set_relative_rect(
|
||||||
|
inner_rect.left(),
|
||||||
|
inner_rect.top(),
|
||||||
|
inner_rect.width(),
|
||||||
|
height_wanted_by_banner_widget);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int vertical_scrollbar_width = m_vertical_scrollbar->effective_min_size().width().as_int();
|
int vertical_scrollbar_width = m_vertical_scrollbar->effective_min_size().width().as_int();
|
||||||
m_vertical_scrollbar->set_relative_rect(
|
m_vertical_scrollbar->set_relative_rect(
|
||||||
inner_rect.right() + 1 - vertical_scrollbar_width,
|
inner_rect.right() + 1 - vertical_scrollbar_width,
|
||||||
inner_rect.top(),
|
inner_rect.top() + height_wanted_by_banner_widget,
|
||||||
vertical_scrollbar_width,
|
vertical_scrollbar_width,
|
||||||
inner_rect.height() - height_wanted_by_horizontal_scrollbar);
|
inner_rect.height() - height_wanted_by_horizontal_scrollbar - height_wanted_by_banner_widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -160,7 +182,7 @@ void AbstractScrollableWidget::update_scrollbar_visibility()
|
||||||
if (m_min_content_size == Gfx::IntSize {})
|
if (m_min_content_size == Gfx::IntSize {})
|
||||||
effective_min_content_size = m_content_size;
|
effective_min_content_size = m_content_size;
|
||||||
int horizontal_buffer = rect().width() - 2 * frame_thickness() - effective_min_content_size.width();
|
int horizontal_buffer = rect().width() - 2 * frame_thickness() - effective_min_content_size.width();
|
||||||
int vertical_buffer = rect().height() - 2 * frame_thickness() - effective_min_content_size.height();
|
int vertical_buffer = rect().height() - 2 * frame_thickness() - effective_min_content_size.height() - height_occupied_by_banner_widget();
|
||||||
bool horizontal_scrollbar_should_be_visible = false, vertical_scrollbar_should_be_visible = false;
|
bool horizontal_scrollbar_should_be_visible = false, vertical_scrollbar_should_be_visible = false;
|
||||||
vertical_scrollbar_should_be_visible = vertical_buffer < 0;
|
vertical_scrollbar_should_be_visible = vertical_buffer < 0;
|
||||||
if (vertical_scrollbar_should_be_visible)
|
if (vertical_scrollbar_should_be_visible)
|
||||||
|
@ -198,6 +220,11 @@ void AbstractScrollableWidget::set_size_occupied_by_fixed_elements(Gfx::IntSize
|
||||||
update_scrollbar_ranges();
|
update_scrollbar_ranges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AbstractScrollableWidget::height_occupied_by_banner_widget() const
|
||||||
|
{
|
||||||
|
return m_banner_widget && m_banner_widget->is_visible() ? m_banner_widget->height() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int AbstractScrollableWidget::height_occupied_by_horizontal_scrollbar() const
|
int AbstractScrollableWidget::height_occupied_by_horizontal_scrollbar() const
|
||||||
{
|
{
|
||||||
return m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->height() : 0;
|
return m_horizontal_scrollbar->is_visible() ? m_horizontal_scrollbar->height() : 0;
|
||||||
|
@ -210,7 +237,7 @@ int AbstractScrollableWidget::width_occupied_by_vertical_scrollbar() const
|
||||||
|
|
||||||
Margins AbstractScrollableWidget::content_margins() const
|
Margins AbstractScrollableWidget::content_margins() const
|
||||||
{
|
{
|
||||||
return Frame::content_margins() + Margins { 0, width_occupied_by_vertical_scrollbar(), height_occupied_by_horizontal_scrollbar(), 0 };
|
return Frame::content_margins() + Margins { height_occupied_by_banner_widget(), width_occupied_by_vertical_scrollbar(), height_occupied_by_horizontal_scrollbar(), 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntRect AbstractScrollableWidget::visible_content_rect() const
|
Gfx::IntRect AbstractScrollableWidget::visible_content_rect() const
|
||||||
|
@ -312,7 +339,8 @@ Gfx::IntRect AbstractScrollableWidget::widget_inner_rect() const
|
||||||
{
|
{
|
||||||
auto rect = frame_inner_rect();
|
auto rect = frame_inner_rect();
|
||||||
rect.set_width(rect.width() - width_occupied_by_vertical_scrollbar());
|
rect.set_width(rect.width() - width_occupied_by_vertical_scrollbar());
|
||||||
rect.set_height(rect.height() - height_occupied_by_horizontal_scrollbar());
|
rect.set_height(rect.height() - height_occupied_by_horizontal_scrollbar() - height_occupied_by_banner_widget());
|
||||||
|
rect.set_top(rect.top() + height_occupied_by_banner_widget());
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +364,9 @@ Optional<UISize> AbstractScrollableWidget::calculated_min_size() const
|
||||||
{
|
{
|
||||||
auto vertical_scrollbar = m_vertical_scrollbar->effective_min_size().height().as_int();
|
auto vertical_scrollbar = m_vertical_scrollbar->effective_min_size().height().as_int();
|
||||||
auto horizontal_scrollbar = m_horizontal_scrollbar->effective_min_size().width().as_int();
|
auto horizontal_scrollbar = m_horizontal_scrollbar->effective_min_size().width().as_int();
|
||||||
return { { horizontal_scrollbar + corner_widget().width() + frame_thickness() * 2, vertical_scrollbar + corner_widget().height() + frame_thickness() * 2 } };
|
auto banner = m_banner_widget && m_banner_widget->is_visible() ? m_banner_widget->effective_min_size().width().as_int() : 0;
|
||||||
|
auto max_width = max(banner, horizontal_scrollbar + corner_widget().width() + frame_thickness() * 2);
|
||||||
|
return { { max_width, vertical_scrollbar + corner_widget().height() + frame_thickness() * 2 + height_occupied_by_banner_widget() } };
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,10 @@ public:
|
||||||
Widget& corner_widget() { return *m_corner_widget; }
|
Widget& corner_widget() { return *m_corner_widget; }
|
||||||
Widget const& corner_widget() const { return *m_corner_widget; }
|
Widget const& corner_widget() const { return *m_corner_widget; }
|
||||||
|
|
||||||
|
void set_banner_widget(Widget*);
|
||||||
|
Widget* banner_widget() { return m_banner_widget; }
|
||||||
|
Widget const* banner_widget() const { return m_banner_widget; }
|
||||||
|
|
||||||
void scroll_to_top();
|
void scroll_to_top();
|
||||||
void scroll_to_bottom();
|
void scroll_to_bottom();
|
||||||
|
|
||||||
|
@ -58,6 +62,7 @@ public:
|
||||||
|
|
||||||
int width_occupied_by_vertical_scrollbar() const;
|
int width_occupied_by_vertical_scrollbar() const;
|
||||||
int height_occupied_by_horizontal_scrollbar() const;
|
int height_occupied_by_horizontal_scrollbar() const;
|
||||||
|
int height_occupied_by_banner_widget() const;
|
||||||
|
|
||||||
virtual Margins content_margins() const override;
|
virtual Margins content_margins() const override;
|
||||||
|
|
||||||
|
@ -111,6 +116,7 @@ private:
|
||||||
RefPtr<AbstractScrollableWidgetScrollbar> m_vertical_scrollbar;
|
RefPtr<AbstractScrollableWidgetScrollbar> m_vertical_scrollbar;
|
||||||
RefPtr<AbstractScrollableWidgetScrollbar> m_horizontal_scrollbar;
|
RefPtr<AbstractScrollableWidgetScrollbar> m_horizontal_scrollbar;
|
||||||
RefPtr<Widget> m_corner_widget;
|
RefPtr<Widget> m_corner_widget;
|
||||||
|
WeakPtr<Widget> m_banner_widget;
|
||||||
Gfx::IntSize m_content_size;
|
Gfx::IntSize m_content_size;
|
||||||
Gfx::IntSize m_min_content_size;
|
Gfx::IntSize m_min_content_size;
|
||||||
Gfx::IntSize m_size_occupied_by_fixed_elements;
|
Gfx::IntSize m_size_occupied_by_fixed_elements;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue