1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 11:28:11 +00:00

GTabWidget: Allow putting the tabs on the bottom of the widget.

They're still painted as if they are top tabs, but the subwidget placement
logic is all there.
This commit is contained in:
Andreas Kling 2019-07-28 17:39:04 +02:00
parent 59e122f8ba
commit 7f82e86fb8
2 changed files with 47 additions and 3 deletions

View file

@ -45,7 +45,13 @@ void GTabWidget::resize_event(GResizeEvent& event)
Rect GTabWidget::child_rect_for_size(const Size& size) const
{
return { { container_padding(), bar_height() + container_padding() }, { size.width() - container_padding() * 2, size.height() - bar_height() - container_padding() * 2 } };
switch (m_tab_position) {
case TabPosition::Top:
return { { container_padding(), bar_height() + container_padding() }, { size.width() - container_padding() * 2, size.height() - bar_height() - container_padding() * 2 } };
case TabPosition::Bottom:
return { { container_padding(), container_padding() }, { size.width() - container_padding() * 2, size.height() - bar_height() - container_padding() * 2 } };
}
ASSERT_NOT_REACHED();
}
void GTabWidget::child_event(CChildEvent& event)
@ -73,7 +79,24 @@ void GTabWidget::child_event(CChildEvent& event)
Rect GTabWidget::bar_rect() const
{
return { 0, 0, width(), bar_height() };
switch (m_tab_position) {
case TabPosition::Top:
return { 0, 0, width(), bar_height() };
case TabPosition::Bottom:
return { 0, height() - bar_height(), width(), bar_height() };
}
ASSERT_NOT_REACHED();
}
Rect GTabWidget::container_rect() const
{
switch (m_tab_position) {
case TabPosition::Top:
return { 0, bar_height(), width(), height() - bar_height() };
case TabPosition::Bottom:
return { 0, 0, width(), height() - bar_height() };
}
ASSERT_NOT_REACHED();
}
void GTabWidget::paint_event(GPaintEvent& event)
@ -81,7 +104,7 @@ void GTabWidget::paint_event(GPaintEvent& event)
GPainter painter(*this);
painter.add_clip_rect(event.rect());
Rect container_rect { 0, bar_height(), width(), height() - bar_height() };
auto container_rect = this->container_rect();
auto padding_rect = container_rect;
for (int i = 0; i < container_padding(); ++i) {
painter.draw_rect(padding_rect, background_color());
@ -124,6 +147,7 @@ Rect GTabWidget::button_rect(int index) const
rect.move_by(-2, 0);
rect.set_width(rect.width() + 4);
}
rect.move_by(bar_rect().location());
return rect;
}
@ -174,3 +198,13 @@ void GTabWidget::update_bar()
invalidation_rect.set_height(invalidation_rect.height() + 1);
update(invalidation_rect);
}
void GTabWidget::set_tab_position(TabPosition tab_position)
{
if (m_tab_position == tab_position)
return;
m_tab_position = tab_position;
if (m_active_widget)
m_active_widget->set_relative_rect(child_rect_for_size(size()));
update();
}

View file

@ -5,9 +5,17 @@
class GTabWidget : public GWidget {
C_OBJECT(GTabWidget)
public:
enum TabPosition {
Top,
Bottom,
};
explicit GTabWidget(GWidget* parent);
virtual ~GTabWidget() override;
TabPosition tab_position() const { return m_tab_position; }
void set_tab_position(TabPosition);
GWidget* active_widget() const { return m_active_widget; }
void set_active_widget(GWidget*);
@ -28,6 +36,7 @@ private:
Rect child_rect_for_size(const Size&) const;
Rect button_rect(int index) const;
Rect bar_rect() const;
Rect container_rect() const;
void update_bar();
GWidget* m_active_widget { nullptr };
@ -39,5 +48,6 @@ private:
GWidget* widget { nullptr };
};
Vector<TabData> m_tabs;
TabPosition m_tab_position { TabPosition::Top };
int m_hovered_tab_index { -1 };
};