mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +00:00
LibGUI: Adjust content area and focus rect of tab buttons
This improves the look of tabs and their focus rects. In particular, the concept of a "text rect" is removed, and whatever tab content area is left over after the icon and close button are added is used as the area to draw the text into. This approach is simpler than having a separate text rect.
This commit is contained in:
parent
22ec21bd61
commit
4959fa4f1e
1 changed files with 47 additions and 18 deletions
|
@ -213,6 +213,11 @@ void TabWidget::paint_event(PaintEvent& event)
|
|||
painter.draw_scaled_bitmap(icon_rect, *icon, icon->rect());
|
||||
text_rect.set_x(icon_rect.right() + 1 + 4);
|
||||
text_rect.intersect(button_rect);
|
||||
|
||||
// We want to be in perfect alignment with the icon rect at all times.
|
||||
auto icon_rect_difference = icon_rect.top() - text_rect.top();
|
||||
text_rect.set_top(text_rect.top() + icon_rect_difference);
|
||||
text_rect.set_height(text_rect.height() - icon_rect_difference);
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < m_tabs.size(); ++i) {
|
||||
|
@ -221,17 +226,21 @@ void TabWidget::paint_event(PaintEvent& event)
|
|||
bool hovered = i == m_hovered_tab_index;
|
||||
auto button_rect = this->button_rect(i);
|
||||
Gfx::StylePainter::paint_tab_button(painter, button_rect, palette(), false, hovered, m_tabs[i].widget->is_enabled(), m_tab_position == TabPosition::Top, window()->is_active());
|
||||
auto tab_button_content_rect = button_rect.translated(4, m_tab_position == TabPosition::Top ? 1 : 0);
|
||||
|
||||
// First we get rid of the 1px sheen on the left, then the 2px shadow
|
||||
// on the right. Finally we shrink 3px from each side.
|
||||
auto tab_button_content_rect = button_rect.shrunken(2, 0);
|
||||
tab_button_content_rect.set_width(tab_button_content_rect.width() - 1);
|
||||
tab_button_content_rect.shrink(6, 0);
|
||||
if (m_tab_position == TabPosition::Top) {
|
||||
tab_button_content_rect.set_top(tab_button_content_rect.top() + 1);
|
||||
tab_button_content_rect.set_height(tab_button_content_rect.height() - 1);
|
||||
}
|
||||
|
||||
paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, tab_button_content_rect);
|
||||
tab_button_content_rect.set_width(tab_button_content_rect.width() - (m_close_button_enabled ? 16 : 2));
|
||||
tab_button_content_rect.set_width(tab_button_content_rect.width() - (m_close_button_enabled ? 16 : 0));
|
||||
|
||||
Gfx::IntRect text_rect { 0, 0, min(tab_button_content_rect.width(), font().width(m_tabs[i].title)), font().glyph_height() };
|
||||
text_rect.inflate(6, 4);
|
||||
text_rect.align_within(tab_button_content_rect, m_text_alignment);
|
||||
text_rect.intersect(tab_button_content_rect);
|
||||
|
||||
painter.draw_text(text_rect, m_tabs[i].title, Gfx::TextAlignment::CenterLeft, palette().button_text(), Gfx::TextElision::Right);
|
||||
painter.draw_text(tab_button_content_rect, m_tabs[i].title, m_text_alignment, palette().button_text(), Gfx::TextElision::Right);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_tabs.size(); ++i) {
|
||||
|
@ -240,19 +249,28 @@ void TabWidget::paint_event(PaintEvent& event)
|
|||
bool hovered = i == m_hovered_tab_index;
|
||||
auto button_rect = this->button_rect(i);
|
||||
Gfx::StylePainter::paint_tab_button(painter, button_rect, palette(), true, hovered, m_tabs[i].widget->is_enabled(), m_tab_position == TabPosition::Top, window()->is_active());
|
||||
auto tab_button_content_rect = button_rect.translated(4, m_tab_position == TabPosition::Top ? 1 : 0);
|
||||
|
||||
// First we get rid of the 1px sheen on the left, then the 2px shadow
|
||||
// on the right. Finally we shrink 3px from each side.
|
||||
auto tab_button_content_rect = button_rect.shrunken(2, 0);
|
||||
tab_button_content_rect.set_width(tab_button_content_rect.width() - 1);
|
||||
tab_button_content_rect.shrink(6, 0);
|
||||
if (m_tab_position == TabPosition::Top) {
|
||||
tab_button_content_rect.set_top(tab_button_content_rect.top() + 1);
|
||||
tab_button_content_rect.set_height(tab_button_content_rect.height() - 1);
|
||||
}
|
||||
|
||||
paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, tab_button_content_rect);
|
||||
tab_button_content_rect.set_width(tab_button_content_rect.width() - (m_close_button_enabled ? 16 : 2));
|
||||
tab_button_content_rect.set_width(tab_button_content_rect.width() - (m_close_button_enabled ? 16 : 0));
|
||||
|
||||
Gfx::IntRect text_rect { 0, 0, min(tab_button_content_rect.width(), font().width(m_tabs[i].title)), font().glyph_height() };
|
||||
text_rect.inflate(6, 4);
|
||||
text_rect.align_within(tab_button_content_rect, m_text_alignment);
|
||||
text_rect.intersect(tab_button_content_rect);
|
||||
|
||||
painter.draw_text(text_rect, m_tabs[i].title, Gfx::TextAlignment::CenterLeft, palette().button_text(), Gfx::TextElision::Right);
|
||||
painter.draw_text(tab_button_content_rect, m_tabs[i].title, m_text_alignment, palette().button_text(), Gfx::TextElision::Right);
|
||||
|
||||
if (is_focused()) {
|
||||
painter.draw_focus_rect(text_rect, palette().focus_outline());
|
||||
Gfx::IntRect focus_rect { 0, 0, min(tab_button_content_rect.width(), font().width(m_tabs[i].title)), font().glyph_height() };
|
||||
focus_rect.align_within(tab_button_content_rect, m_text_alignment);
|
||||
focus_rect.inflate(6, 4);
|
||||
|
||||
painter.draw_focus_rect(focus_rect, palette().focus_outline());
|
||||
}
|
||||
|
||||
if (m_tab_position == TabPosition::Top) {
|
||||
|
@ -339,7 +357,18 @@ Gfx::IntRect TabWidget::close_button_rect(size_t index) const
|
|||
|
||||
int TabWidget::TabData::width(const Gfx::Font& font) const
|
||||
{
|
||||
return 16 + font.width(title) + (icon ? (16 + 4) : 0);
|
||||
auto width = 16 + font.width(title) + (icon ? (16 + 4) : 0);
|
||||
// NOTE: This needs to always be an odd number, because the button rect
|
||||
// includes 3px of light and shadow on the left and right edges. If
|
||||
// the button rect width is not an odd number, the area left for the
|
||||
// text and the focus rect has an odd number of pixels, and this
|
||||
// causes the text (and subsequently the focus rect) to not be aligned
|
||||
// to the center perfectly.
|
||||
if (width % 2 == 0) {
|
||||
width++;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
void TabWidget::mousedown_event(MouseEvent& event)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue