1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:37:36 +00:00

LibGfx+Userland: Merge FrameShape and FrameShadow into FrameStyle

Previously, Frames could set both these properties along with a
thickness to confusing effect: Most shapes of the same shadowing only
differentiated at a thickness >= 2, and some not at all. This led
to a lot of creative but ultimately superfluous choices in the code.

Instead let's streamline our options, automate thickness, and get
the right look without so much guesswork.

Plain shadowing has been consolidated into a single Plain style,
and 0 thickness can be had by setting style to NoFrame.
This commit is contained in:
thankyouverycool 2023-04-29 16:47:52 -04:00 committed by Andreas Kling
parent 4c9933bfb7
commit f7e034d4b2
58 changed files with 148 additions and 208 deletions

View file

@ -49,9 +49,7 @@ private:
m_label->set_background_role(Gfx::ColorRole::Tooltip);
m_label->set_foreground_role(Gfx::ColorRole::TooltipText);
m_label->set_fill_with_background_color(true);
m_label->set_frame_thickness(1);
m_label->set_frame_shape(Gfx::FrameShape::Container);
m_label->set_frame_shadow(Gfx::FrameShadow::Plain);
m_label->set_frame_style(Gfx::FrameStyle::Plain);
m_label->set_autosize(true);
}

View file

@ -97,8 +97,7 @@ AutocompleteBox::AutocompleteBox(TextEditor& editor)
main_widget->set_layout<GUI::VerticalBoxLayout>();
m_suggestion_view = main_widget->add<GUI::TableView>();
m_suggestion_view->set_frame_shadow(Gfx::FrameShadow::Plain);
m_suggestion_view->set_frame_thickness(1);
m_suggestion_view->set_frame_style(Gfx::FrameStyle::Plain);
m_suggestion_view->set_column_headers_visible(false);
m_suggestion_view->set_visible(false);
m_suggestion_view->on_activation = [&](GUI::ModelIndex const& index) {

View file

@ -65,7 +65,7 @@ ComboBox::ComboBox()
set_preferred_size({ SpecialDimension::OpportunisticGrow, 22 });
m_editor = add<ComboBoxEditor>();
m_editor->set_frame_thickness(0);
m_editor->set_frame_style(Gfx::FrameStyle::NoFrame);
m_editor->on_return_pressed = [this] {
if (on_return_pressed)
on_return_pressed();
@ -120,8 +120,7 @@ ComboBox::ComboBox()
m_list_view->set_should_hide_unnecessary_scrollbars(true);
m_list_view->set_alternating_row_colors(false);
m_list_view->set_hover_highlighting(true);
m_list_view->set_frame_thickness(1);
m_list_view->set_frame_shadow(Gfx::FrameShadow::Plain);
m_list_view->set_frame_style(Gfx::FrameStyle::Plain);
m_list_view->set_activates_on_selection(true);
m_list_view->on_selection_change = [this] {
VERIFY(model());

View file

@ -183,7 +183,7 @@ CommandPalette::CommandPalette(GUI::Window& parent_window, ScreenPosition screen
collect_actions(parent_window);
auto main_widget = set_main_widget<GUI::Frame>().release_value_but_fixme_should_propagate_errors();
main_widget->set_frame_shape(Gfx::FrameShape::Window);
main_widget->set_frame_style(Gfx::FrameStyle::Window);
main_widget->set_fill_with_background_color(true);
main_widget->set_layout<GUI::VerticalBoxLayout>(4);

View file

@ -1,5 +1,5 @@
@GUI::Frame {
shape: "Window"
style: "Window"
fill_with_background_color: true
layout: @GUI::VerticalBoxLayout {
margins: [4]

View file

@ -16,40 +16,51 @@ namespace GUI {
Frame::Frame()
{
set_frame_thickness(2);
set_frame_shape(Gfx::FrameShape::Container);
set_frame_shadow(Gfx::FrameShadow::Sunken);
set_frame_style(Gfx::FrameStyle::SunkenContainer);
REGISTER_INT_PROPERTY("thickness", frame_thickness, set_frame_thickness);
REGISTER_ENUM_PROPERTY("shadow", frame_shadow, set_frame_shadow, Gfx::FrameShadow,
{ Gfx::FrameShadow::Plain, "Plain" },
{ Gfx::FrameShadow::Raised, "Raised" },
{ Gfx::FrameShadow::Sunken, "Sunken" });
REGISTER_ENUM_PROPERTY("shape", frame_shape, set_frame_shape, Gfx::FrameShape,
{ Gfx::FrameShape::NoFrame, "NoFrame" },
{ Gfx::FrameShape::Box, "Box" },
{ Gfx::FrameShape::Container, "Container" },
{ Gfx::FrameShape::Panel, "Panel" },
{ Gfx::FrameShape::Window, "Window" });
REGISTER_ENUM_PROPERTY("style", frame_style, set_frame_style, Gfx::FrameStyle,
{ Gfx::FrameStyle::NoFrame, "NoFrame" },
{ Gfx::FrameStyle::Window, "Window" },
{ Gfx::FrameStyle::Plain, "Plain" },
{ Gfx::FrameStyle::RaisedBox, "RaisedBox" },
{ Gfx::FrameStyle::SunkenBox, "SunkenBox" },
{ Gfx::FrameStyle::RaisedContainer, "RaisedContainer" },
{ Gfx::FrameStyle::SunkenContainer, "SunkenContainer" },
{ Gfx::FrameStyle::RaisedPanel, "RaisedPanel" },
{ Gfx::FrameStyle::SunkenPanel, "SunkenPanel" });
}
void Frame::set_frame_thickness(int thickness)
void Frame::set_frame_style(Gfx::FrameStyle style)
{
if (m_thickness == thickness)
if (m_style == style)
return;
m_thickness = thickness;
set_grabbable_margins(thickness);
m_style = style;
set_grabbable_margins(frame_thickness());
layout_relevant_change_occurred();
}
int Frame::frame_thickness() const
{
switch (m_style) {
case Gfx::FrameStyle::NoFrame:
return 0;
case Gfx::FrameStyle::Plain:
case Gfx::FrameStyle::RaisedPanel:
case Gfx::FrameStyle::SunkenPanel:
return 1;
default:
return 2;
}
}
void Frame::paint_event(PaintEvent& event)
{
if (m_shape == Gfx::FrameShape::NoFrame)
if (m_style == Gfx::FrameStyle::NoFrame)
return;
Painter painter(*this);
painter.add_clip_rect(event.rect());
Gfx::StylePainter::paint_frame(painter, rect(), palette(), m_shape, m_shadow, m_thickness, spans_entire_window_horizontally());
Gfx::StylePainter::paint_frame(painter, rect(), palette(), m_style, spans_entire_window_horizontally());
}
Gfx::IntRect Frame::children_clip_rect() const

View file

@ -17,18 +17,14 @@ class Frame : public Widget {
public:
virtual ~Frame() override = default;
int frame_thickness() const { return m_thickness; }
void set_frame_thickness(int thickness);
int frame_thickness() const;
virtual Margins content_margins() const override { return { frame_thickness() }; }
Gfx::FrameShadow frame_shadow() const { return m_shadow; }
void set_frame_shadow(Gfx::FrameShadow shadow) { m_shadow = shadow; }
Gfx::FrameStyle frame_style() const { return m_style; }
void set_frame_style(Gfx::FrameStyle);
Gfx::FrameShape frame_shape() const { return m_shape; }
void set_frame_shape(Gfx::FrameShape shape) { m_shape = shape; }
Gfx::IntRect frame_inner_rect_for_size(Gfx::IntSize size) const { return { m_thickness, m_thickness, size.width() - m_thickness * 2, size.height() - m_thickness * 2 }; }
Gfx::IntRect frame_inner_rect_for_size(Gfx::IntSize size) const { return { frame_thickness(), frame_thickness(), size.width() - frame_thickness() * 2, size.height() - frame_thickness() * 2 }; }
Gfx::IntRect frame_inner_rect() const { return frame_inner_rect_for_size(size()); }
virtual Gfx::IntRect children_clip_rect() const override;
@ -38,9 +34,7 @@ protected:
void paint_event(PaintEvent&) override;
private:
int m_thickness { 0 };
Gfx::FrameShadow m_shadow { Gfx::FrameShadow::Plain };
Gfx::FrameShape m_shape { Gfx::FrameShape::NoFrame };
Gfx::FrameStyle m_style { Gfx::FrameStyle::NoFrame };
};
}

View file

@ -40,7 +40,7 @@ void GroupBox::paint_event(PaintEvent& event)
0, (!m_title.is_empty() ? font().pixel_size_rounded_up() / 2 : 0),
width(), height() - (!m_title.is_empty() ? font().pixel_size_rounded_up() / 2 : 0)
};
Gfx::StylePainter::paint_frame(painter, frame_rect, palette(), Gfx::FrameShape::Box, Gfx::FrameShadow::Sunken, 2);
Gfx::StylePainter::paint_frame(painter, frame_rect, palette(), Gfx::FrameStyle::SunkenBox);
if (!m_title.is_empty()) {
Gfx::IntRect text_rect { 6, 1, font().width_rounded_up(m_title) + 6, font().pixel_size_rounded_up() };

View file

@ -20,9 +20,7 @@ ImageWidget::ImageWidget(StringView)
: m_timer(Core::Timer::try_create().release_value_but_fixme_should_propagate_errors())
{
set_frame_thickness(0);
set_frame_shadow(Gfx::FrameShadow::Plain);
set_frame_shape(Gfx::FrameShape::NoFrame);
set_frame_style(Gfx::FrameStyle::NoFrame);
set_auto_resize(true);
REGISTER_BOOL_PROPERTY("auto_resize", auto_resize, set_auto_resize);

View file

@ -24,11 +24,7 @@ Label::Label(String text)
set_preferred_size({ SpecialDimension::OpportunisticGrow });
set_min_size({ SpecialDimension::Shrink });
set_frame_thickness(0);
set_frame_shadow(Gfx::FrameShadow::Plain);
set_frame_shape(Gfx::FrameShape::NoFrame);
set_frame_style(Gfx::FrameStyle::NoFrame);
set_foreground_role(Gfx::ColorRole::WindowText);
REGISTER_STRING_PROPERTY("text", text, set_text);

View file

@ -79,7 +79,7 @@ public:
virtual RefPtr<Widget> create_widget() override
{
auto textbox = TextBox::construct();
textbox->set_frame_shape(Gfx::FrameShape::NoFrame);
textbox->set_frame_style(Gfx::FrameStyle::NoFrame);
textbox->on_return_pressed = [this] {
commit();

View file

@ -132,7 +132,7 @@ void OpacitySlider::paint_event(PaintEvent& event)
painter.draw_text(inner_rect, percent_text, Gfx::TextAlignment::Center, Color::White);
// Frame
Gfx::StylePainter::paint_frame(painter, rect(), palette(), Gfx::FrameShape::Container, Gfx::FrameShadow::Sunken, 2);
Gfx::StylePainter::paint_frame(painter, rect(), palette(), Gfx::FrameStyle::SunkenContainer);
}
int OpacitySlider::value_at(Gfx::IntPoint position) const

View file

@ -44,7 +44,7 @@ void Slider::paint_event(PaintEvent& event)
track_rect = { 0, inner_rect().y(), track_size(), inner_rect().height() - shadow_thickness };
track_rect.center_horizontally_within(inner_rect());
}
Gfx::StylePainter::paint_frame(painter, track_rect, palette(), Gfx::FrameShape::Panel, Gfx::FrameShadow::Sunken, shadow_thickness);
Gfx::StylePainter::paint_frame(painter, track_rect, palette(), Gfx::FrameStyle::SunkenPanel);
if (is_enabled())
Gfx::StylePainter::paint_button(painter, knob_rect(), palette(), Gfx::ButtonStyle::Normal, false, m_knob_hovered);
else

View file

@ -85,7 +85,7 @@ void Statusbar::update_segment(size_t index)
m_segments[i]->set_visible(true);
}
segment->set_text(String::from_utf8(segment->restored_text()).release_value_but_fixme_should_propagate_errors());
segment->set_frame_shape(Gfx::FrameShape::Panel);
segment->set_frame_style(Gfx::FrameStyle::SunkenPanel);
if (segment->mode() != Segment::Mode::Proportional)
segment->set_fixed_width(segment->restored_width());
} else {
@ -94,7 +94,7 @@ void Statusbar::update_segment(size_t index)
m_segments[i]->set_visible(false);
}
segment->set_text(String::from_utf8(segment->override_text()).release_value_but_fixme_should_propagate_errors());
segment->set_frame_shape(Gfx::FrameShape::NoFrame);
segment->set_frame_style(Gfx::FrameStyle::NoFrame);
if (segment->mode() != Segment::Mode::Proportional)
segment->set_fixed_width(SpecialDimension::Grow);
}
@ -152,7 +152,7 @@ void Statusbar::Segment::paint_event(PaintEvent& event)
painter.add_clip_rect(event.rect());
bool skip_vertical_lines = window()->is_maximized() && spans_entire_window_horizontally();
Gfx::StylePainter::current().paint_frame(painter, rect(), palette(), m_shape, Gfx::FrameShadow::Sunken, m_thickness, skip_vertical_lines);
Gfx::StylePainter::current().paint_frame(painter, rect(), palette(), m_style, skip_vertical_lines);
if (is_clickable())
Button::paint_event(event);

View file

@ -48,7 +48,7 @@ public:
private:
Segment();
void set_frame_shape(Gfx::FrameShape shape) { m_shape = shape; }
void set_frame_style(Gfx::FrameStyle style) { m_style = style; }
void set_restored_width(int width) { m_restored_width = width; }
int restored_width() const { return m_restored_width; }
DeprecatedString const& override_text() const { return m_override_text; }
@ -58,9 +58,8 @@ public:
DeprecatedString m_restored_text;
bool m_clickable { false };
int m_restored_width { 0 };
int m_thickness { 1 };
Mode m_mode { Mode::Proportional };
Gfx::FrameShape m_shape { Gfx::FrameShape::Panel };
Gfx::FrameStyle m_style { Gfx::FrameStyle::SunkenPanel };
};
Segment& segment(size_t index) { return m_segments.at(index); }

View file

@ -243,7 +243,7 @@ void TabWidget::paint_event(PaintEvent& event)
painter.fill_rect(event.rect(), palette().button());
if (!m_container_margins.is_null()) {
Gfx::StylePainter::paint_frame(painter, container_rect(), palette(), Gfx::FrameShape::Container, Gfx::FrameShadow::Raised, 2);
Gfx::StylePainter::paint_frame(painter, container_rect(), palette(), Gfx::FrameStyle::RaisedContainer);
}
auto paint_tab_icon_if_needed = [&](auto& icon, auto& button_rect, auto& text_rect) {
@ -284,7 +284,7 @@ void TabWidget::paint_event(PaintEvent& event)
auto close_button_rect = this->close_button_rect(i);
if (hovered_close_button)
Gfx::StylePainter::paint_frame(painter, close_button_rect, palette(), Gfx::FrameShape::Box, pressed_close_button ? Gfx::FrameShadow::Sunken : Gfx::FrameShadow::Raised, 1);
Gfx::StylePainter::paint_frame(painter, close_button_rect, palette(), pressed_close_button ? Gfx::FrameStyle::SunkenPanel : Gfx::FrameStyle::RaisedPanel);
Gfx::IntRect icon_rect { close_button_rect.x() + 3, close_button_rect.y() + 3, 6, 6 };
if (!m_tabs[i].modified) {
@ -358,7 +358,7 @@ void TabWidget::paint_event(PaintEvent& event)
}
if (hovered_close_button)
Gfx::StylePainter::paint_frame(painter, close_button_rect, palette(), Gfx::FrameShape::Box, pressed_close_button ? Gfx::FrameShadow::Sunken : Gfx::FrameShadow::Raised, 1);
Gfx::StylePainter::paint_frame(painter, close_button_rect, palette(), pressed_close_button ? Gfx::FrameStyle::SunkenPanel : Gfx::FrameStyle::RaisedPanel);
Gfx::IntRect icon_rect { close_button_rect.x() + 3, close_button_rect.y() + 3, 6, 6 };
if (!m_tabs[i].modified) {

View file

@ -18,11 +18,7 @@ ToolbarContainer::ToolbarContainer(Gfx::Orientation orientation)
: m_orientation(orientation)
{
set_fill_with_background_color(true);
set_frame_thickness(2);
set_frame_shape(Gfx::FrameShape::Box);
set_frame_shadow(Gfx::FrameShadow::Sunken);
set_frame_style(Gfx::FrameStyle::SunkenBox);
set_layout<VerticalBoxLayout>(GUI::Margins {}, 2);
set_shrink_to_fit(true);
}

View file

@ -87,7 +87,7 @@ void ValueSlider::paint_event(PaintEvent& event)
unfilled_rect.set_left(knob_rect().right());
painter.fill_rect(unfilled_rect, palette().base());
Gfx::StylePainter::paint_frame(painter, bar_rect(), palette(), Gfx::FrameShape::Container, Gfx::FrameShadow::Sunken, 2);
Gfx::StylePainter::paint_frame(painter, bar_rect(), palette(), Gfx::FrameStyle::SunkenContainer);
Gfx::StylePainter::paint_button(painter, knob_rect(), palette(), Gfx::ButtonStyle::Normal, false, m_hovered);
auto paint_knurl = [&](int x, int y) {