mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 09:49:15 +03:00
LibGUI+LibGfx: Implement upside-down appearance for bottom-side tabs
GUI::TabWidget has long has a TabPosition::Bottom option, but we still rendered the tab buttons the same as TabPosition::Top. This patch implements a custom look for bottom-side tabs. I've done my best to match the look of the top-side ones, but there might be some improvements we can make here. :^)
This commit is contained in:
parent
59172e2714
commit
03c576acc5
Notes:
sideshowbarker
2024-07-19 03:15:10 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/03c576acc54
@ -178,8 +178,8 @@ void TabWidget::paint_event(PaintEvent& event)
|
||||
continue;
|
||||
bool hovered = static_cast<int>(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());
|
||||
auto text_rect = button_rect.translated(0, 1);
|
||||
Gfx::StylePainter::paint_tab_button(painter, button_rect, palette(), false, hovered, m_tabs[i].widget->is_enabled(), m_tab_position == TabPosition::Top);
|
||||
auto text_rect = button_rect.translated(0, m_tab_position == TabPosition::Top ? 1 : 0);
|
||||
paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, text_rect);
|
||||
painter.draw_text(text_rect, m_tabs[i].title, m_text_alignment, palette().button_text(), Gfx::TextElision::Right);
|
||||
}
|
||||
@ -189,11 +189,17 @@ void TabWidget::paint_event(PaintEvent& event)
|
||||
continue;
|
||||
bool hovered = static_cast<int>(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());
|
||||
auto text_rect = button_rect.translated(0, 1);
|
||||
Gfx::StylePainter::paint_tab_button(painter, button_rect, palette(), true, hovered, m_tabs[i].widget->is_enabled(), m_tab_position == TabPosition::Top);
|
||||
auto text_rect = button_rect.translated(0, m_tab_position == TabPosition::Top ? 1 : 0);
|
||||
paint_tab_icon_if_needed(m_tabs[i].icon, button_rect, text_rect);
|
||||
painter.draw_text(text_rect, m_tabs[i].title, m_text_alignment, palette().button_text(), Gfx::TextElision::Right);
|
||||
painter.draw_line(button_rect.bottom_left().translated(1, 1), button_rect.bottom_right().translated(-1, 1), palette().button());
|
||||
if (m_tab_position == TabPosition::Top) {
|
||||
painter.draw_line(button_rect.bottom_left().translated(1, 1), button_rect.bottom_right().translated(-1, 1), palette().button());
|
||||
} else if (m_tab_position == TabPosition::Bottom) {
|
||||
painter.set_pixel(button_rect.top_left().translated(0, -1), palette().threed_highlight());
|
||||
painter.draw_line(button_rect.top_left().translated(1, -1), button_rect.top_right().translated(-2, -1), palette().button());
|
||||
painter.draw_line(button_rect.top_left().translated(1, -2), button_rect.top_right().translated(-2, -2), palette().button());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -226,7 +232,7 @@ Gfx::IntRect TabWidget::button_rect(int index) const
|
||||
}
|
||||
Gfx::IntRect rect { x_offset, 0, m_uniform_tabs ? uniform_tab_width() : m_tabs[index].width(font()), bar_height() };
|
||||
if (m_tabs[index].widget != m_active_widget) {
|
||||
rect.move_by(0, 2);
|
||||
rect.move_by(0, m_tab_position == TabPosition::Top ? 2 : 0);
|
||||
rect.set_height(rect.height() - 2);
|
||||
} else {
|
||||
rect.move_by(-2, 0);
|
||||
|
@ -25,6 +25,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/ClassicStylePainter.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
@ -32,7 +33,7 @@
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
void ClassicStylePainter::paint_tab_button(Painter& painter, const IntRect& rect, const Palette& palette, bool active, bool hovered, bool enabled)
|
||||
void ClassicStylePainter::paint_tab_button(Painter& painter, const IntRect& rect, const Palette& palette, bool active, bool hovered, bool enabled, bool top)
|
||||
{
|
||||
Color base_color = palette.button();
|
||||
Color highlight_color2 = palette.threed_highlight();
|
||||
@ -45,32 +46,50 @@ void ClassicStylePainter::paint_tab_button(Painter& painter, const IntRect& rect
|
||||
PainterStateSaver saver(painter);
|
||||
painter.translate(rect.location());
|
||||
|
||||
// Base
|
||||
painter.fill_rect({ 1, 1, rect.width() - 2, rect.height() - 1 }, base_color);
|
||||
if (top) {
|
||||
// Base
|
||||
painter.fill_rect({ 1, 1, rect.width() - 2, rect.height() - 1 }, base_color);
|
||||
|
||||
// Top line
|
||||
painter.draw_line({ 2, 0 }, { rect.width() - 3, 0 }, highlight_color2);
|
||||
// Top line
|
||||
painter.draw_line({ 2, 0 }, { rect.width() - 3, 0 }, highlight_color2);
|
||||
|
||||
// Left side
|
||||
painter.draw_line({ 0, 2 }, { 0, rect.height() - 1 }, highlight_color2);
|
||||
painter.set_pixel({ 1, 1 }, highlight_color2);
|
||||
// Left side
|
||||
painter.draw_line({ 0, 2 }, { 0, rect.height() - 1 }, highlight_color2);
|
||||
painter.set_pixel({ 1, 1 }, highlight_color2);
|
||||
|
||||
// Right side
|
||||
painter.draw_line({
|
||||
rect.width() - 1,
|
||||
2,
|
||||
},
|
||||
{ rect.width() - 1, rect.height() - 1 }, shadow_color2);
|
||||
painter.draw_line({
|
||||
rect.width() - 2,
|
||||
2,
|
||||
},
|
||||
{ rect.width() - 2, rect.height() - 1 }, shadow_color1);
|
||||
painter.set_pixel({
|
||||
rect.width() - 2,
|
||||
1,
|
||||
},
|
||||
shadow_color2);
|
||||
// Right side
|
||||
|
||||
IntPoint top_right_outer { rect.width() - 1, 2 };
|
||||
IntPoint bottom_right_outer { rect.width() - 1, rect.height() - 1 };
|
||||
painter.draw_line(top_right_outer, bottom_right_outer, shadow_color2);
|
||||
|
||||
IntPoint top_right_inner { rect.width() - 2, 2 };
|
||||
IntPoint bottom_right_inner { rect.width() - 2, rect.height() - 1 };
|
||||
painter.draw_line(top_right_inner, bottom_right_inner, shadow_color1);
|
||||
|
||||
painter.set_pixel(rect.width() - 2, 1, shadow_color2);
|
||||
} else {
|
||||
// Base
|
||||
painter.fill_rect({ 0, 0, rect.width() - 1, rect.height() }, base_color);
|
||||
|
||||
// Bottom line
|
||||
painter.draw_line({ 2, rect.height() - 1 }, { rect.width() - 3, rect.height() - 1 }, shadow_color2);
|
||||
|
||||
// Left side
|
||||
painter.draw_line({ 0, 0 }, { 0, rect.height() - 3 }, highlight_color2);
|
||||
painter.set_pixel({ 1, rect.height() - 2 }, highlight_color2);
|
||||
|
||||
// Right side
|
||||
IntPoint top_right_outer { rect.width() - 1, 0 };
|
||||
IntPoint bottom_right_outer { rect.width() - 1, rect.height() - 3 };
|
||||
painter.draw_line(top_right_outer, bottom_right_outer, shadow_color2);
|
||||
|
||||
IntPoint top_right_inner { rect.width() - 2, 0 };
|
||||
IntPoint bottom_right_inner { rect.width() - 2, rect.height() - 3 };
|
||||
painter.draw_line(top_right_inner, bottom_right_inner, shadow_color1);
|
||||
|
||||
painter.set_pixel(rect.width() - 2, rect.height() - 2, shadow_color2);
|
||||
}
|
||||
}
|
||||
|
||||
static void paint_button_new(Painter& painter, const IntRect& rect, const Palette& palette, bool pressed, bool checked, bool hovered, bool enabled)
|
||||
@ -326,5 +345,4 @@ void ClassicStylePainter::paint_radio_button(Painter& painter, const IntRect& re
|
||||
auto& bitmap = circle_bitmap(is_checked, is_being_pressed);
|
||||
painter.blit(rect.location(), bitmap, bitmap.rect());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace Gfx {
|
||||
class ClassicStylePainter : public BaseStylePainter {
|
||||
public:
|
||||
void paint_button(Painter&, const IntRect&, const Palette&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true) override;
|
||||
void paint_tab_button(Painter&, const IntRect&, const Palette&, bool active, bool hovered, bool enabled) override;
|
||||
void paint_tab_button(Painter&, const IntRect&, const Palette&, bool active, bool hovered, bool enabled, bool top) override;
|
||||
void paint_surface(Painter&, const IntRect&, const Palette&, bool paint_vertical_lines = true, bool paint_top_line = true) override;
|
||||
void paint_frame(Painter&, const IntRect&, const Palette&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false) override;
|
||||
void paint_window_frame(Painter&, const IntRect&, const Palette&) override;
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
void draw_triangle(const IntPoint&, const IntPoint&, const IntPoint&, Color);
|
||||
void draw_ellipse_intersecting(const IntRect&, Color, int thickness = 1);
|
||||
void set_pixel(const IntPoint&, Color);
|
||||
void set_pixel(int x, int y, Color color) { set_pixel({ x, y }, color); }
|
||||
void draw_line(const IntPoint&, const IntPoint&, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
|
||||
void draw_quadratic_bezier_curve(const IntPoint& control_point, const IntPoint&, const IntPoint&, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
|
||||
void draw_elliptical_arc(const IntPoint& p1, const IntPoint& p2, const IntPoint& center, const FloatPoint& radii, float x_axis_rotation, float theta_1, float theta_delta, Color, int thickness = 1, LineStyle style = LineStyle::Solid);
|
||||
|
@ -38,9 +38,9 @@ BaseStylePainter& StylePainter::current()
|
||||
return style;
|
||||
}
|
||||
|
||||
void StylePainter::paint_tab_button(Painter& painter, const IntRect& rect, const Palette& palette, bool active, bool hovered, bool enabled)
|
||||
void StylePainter::paint_tab_button(Painter& painter, const IntRect& rect, const Palette& palette, bool active, bool hovered, bool enabled, bool top)
|
||||
{
|
||||
current().paint_tab_button(painter, rect, palette, active, hovered, enabled);
|
||||
current().paint_tab_button(painter, rect, palette, active, hovered, enabled, top);
|
||||
}
|
||||
|
||||
void StylePainter::paint_button(Painter& painter, const IntRect& rect, const Palette& palette, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled)
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
virtual ~BaseStylePainter() { }
|
||||
|
||||
virtual void paint_button(Painter&, const IntRect&, const Palette&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true) = 0;
|
||||
virtual void paint_tab_button(Painter&, const IntRect&, const Palette&, bool active, bool hovered, bool enabled) = 0;
|
||||
virtual void paint_tab_button(Painter&, const IntRect&, const Palette&, bool active, bool hovered, bool enabled, bool top) = 0;
|
||||
virtual void paint_surface(Painter&, const IntRect&, const Palette&, bool paint_vertical_lines = true, bool paint_top_line = true) = 0;
|
||||
virtual void paint_frame(Painter&, const IntRect&, const Palette&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false) = 0;
|
||||
virtual void paint_window_frame(Painter&, const IntRect&, const Palette&) = 0;
|
||||
@ -72,7 +72,7 @@ public:
|
||||
|
||||
// FIXME: These are here for API compatibility, we should probably remove them and move BaseStylePainter into here
|
||||
static void paint_button(Painter&, const IntRect&, const Palette&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true);
|
||||
static void paint_tab_button(Painter&, const IntRect&, const Palette&, bool active, bool hovered, bool enabled);
|
||||
static void paint_tab_button(Painter&, const IntRect&, const Palette&, bool active, bool hovered, bool enabled, bool top);
|
||||
static void paint_surface(Painter&, const IntRect&, const Palette&, bool paint_vertical_lines = true, bool paint_top_line = true);
|
||||
static void paint_frame(Painter&, const IntRect&, const Palette&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false);
|
||||
static void paint_window_frame(Painter&, const IntRect&, const Palette&);
|
||||
|
Loading…
Reference in New Issue
Block a user