1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:17:45 +00:00

LibGUI+Apps: Convert Statusbar Labels to Segments

Segments inherit from Button and let us add clickable widgets
to status bars. This patch also adds proportional, fixed and
autosized modes for segments and lets the status bar consume
all non-clickable segments for override text.
This commit is contained in:
thankyouverycool 2022-02-22 07:20:05 -05:00 committed by Andreas Kling
parent e113e3ccaa
commit 3aa95dd4d5
7 changed files with 159 additions and 80 deletions

View file

@ -5,7 +5,6 @@
*/
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Label.h>
#include <LibGUI/Painter.h>
#include <LibGUI/ResizeCorner.h>
#include <LibGUI/Statusbar.h>
@ -17,7 +16,7 @@ REGISTER_WIDGET(GUI, Statusbar)
namespace GUI {
Statusbar::Statusbar(int label_count)
Statusbar::Statusbar(int count)
{
set_fixed_height(18);
set_layout<HorizontalBoxLayout>();
@ -25,26 +24,76 @@ Statusbar::Statusbar(int label_count)
layout()->set_spacing(2);
m_corner = add<ResizeCorner>();
set_label_count(label_count);
set_segment_count(count);
REGISTER_STRING_PROPERTY("text", text, set_text);
REGISTER_INT_PROPERTY("label_count", label_count, set_label_count);
REGISTER_INT_PROPERTY("segment_count", segment_count, set_segment_count);
}
Statusbar::~Statusbar()
{
}
NonnullRefPtr<Label> Statusbar::create_label()
NonnullRefPtr<Statusbar::Segment> Statusbar::create_segment()
{
auto label = Label::construct();
insert_child_before(*label, *m_corner);
label->set_frame_shadow(Gfx::FrameShadow::Sunken);
label->set_frame_shape(Gfx::FrameShape::Panel);
label->set_frame_thickness(1);
label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
label->set_text_wrapping(Gfx::TextWrapping::DontWrap);
return label;
auto widget = Segment::construct();
insert_child_before(*widget, *m_corner);
return widget;
}
void Statusbar::set_segment_count(size_t count)
{
if (count <= 1)
count = 1;
for (auto i = m_segments.size(); i < count; i++) {
auto segment = create_segment();
m_segments.append(move(segment));
}
}
void Statusbar::update_segment(size_t index)
{
auto& segment = m_segments.at(index);
if (segment.mode() == Segment::Mode::Auto) {
if (segment.restored_text().is_empty())
segment.set_visible(false);
else {
constexpr auto horizontal_padding { 10 };
auto width = font().width(segment.restored_text()) + horizontal_padding;
segment.set_restored_width(width);
segment.set_fixed_width(width);
}
} else if (segment.mode() == Segment::Mode::Fixed) {
if (segment.max_width() != -1)
segment.set_restored_width(segment.max_width());
segment.set_fixed_width(segment.max_width());
}
if (segment.override_text().is_null()) {
for (size_t i = 1; i < m_segments.size(); i++) {
if (!text(i).is_empty())
m_segments[i].set_visible(true);
}
segment.set_text(segment.restored_text());
segment.set_frame_shape(Gfx::FrameShape::Panel);
if (segment.mode() != Segment::Mode::Proportional)
segment.set_fixed_width(segment.restored_width());
} else {
for (size_t i = 1; i < m_segments.size(); i++) {
if (!m_segments[i].is_clickable())
m_segments[i].set_visible(false);
}
segment.set_text(segment.override_text());
segment.set_frame_shape(Gfx::FrameShape::NoFrame);
if (segment.mode() != Segment::Mode::Proportional)
segment.set_fixed_width(-1);
}
}
String Statusbar::text(size_t index) const
{
return m_segments.at(index).text();
}
void Statusbar::set_text(String text)
@ -52,60 +101,16 @@ void Statusbar::set_text(String text)
set_text(0, move(text));
}
String Statusbar::text() const
{
return text(0);
}
void Statusbar::set_text(size_t index, String text)
{
m_segments.at(index).text = move(text);
update_label(index);
}
void Statusbar::set_label_count(size_t label_count)
{
if (label_count <= 1)
label_count = 1;
for (auto i = m_segments.size(); i < label_count; i++) {
m_segments.append(Segment {
.label = create_label(),
.text = {},
.override_text = {},
});
}
}
void Statusbar::update_label(size_t index)
{
auto& segment = m_segments.at(index);
if (segment.override_text.is_null()) {
segment.label->set_frame_shadow(Gfx::FrameShadow::Sunken);
segment.label->set_frame_shape(Gfx::FrameShape::Panel);
segment.label->set_text(segment.text);
} else {
segment.label->set_frame_shadow(Gfx::FrameShadow::Plain);
segment.label->set_frame_shape(Gfx::FrameShape::NoFrame);
segment.label->set_text(segment.override_text);
}
}
String Statusbar::text(size_t index) const
{
return m_segments.at(index).label->text();
m_segments.at(index).m_restored_text = move(text);
update_segment(index);
}
void Statusbar::set_override_text(String override_text)
{
set_override_text(0, move(override_text));
}
void Statusbar::set_override_text(size_t index, String override_text)
{
m_segments.at(index).override_text = move(override_text);
update_label(index);
m_segments.at(0).m_override_text = move(override_text);
update_segment(0);
}
void Statusbar::paint_event(PaintEvent& event)
@ -123,4 +128,40 @@ void Statusbar::resize_event(ResizeEvent& event)
Widget::resize_event(event);
}
Statusbar::Segment::Segment()
{
set_fixed_height(18);
set_focus_policy(GUI::FocusPolicy::NoFocus);
set_button_style(Gfx::ButtonStyle::Tray);
set_text_alignment(Gfx::TextAlignment::CenterLeft);
}
void Statusbar::Segment::paint_event(PaintEvent& event)
{
Painter painter(*this);
painter.add_clip_rect(event.rect());
Gfx::StylePainter::current().paint_frame(painter, rect(), palette(), m_shape, Gfx::FrameShadow::Sunken, m_thickness, spans_entire_window_horizontally());
if (is_clickable())
Button::paint_event(event);
else if (!text().is_empty())
painter.draw_text(rect().shrunken(font().max_glyph_width(), 0), text(), text_alignment(), palette().color(foreground_role()), Gfx::TextElision::Right, Gfx::TextWrapping::DontWrap);
}
void Statusbar::Segment::mousedown_event(MouseEvent& event)
{
if (!is_clickable())
return;
Button::mousedown_event(event);
}
void Statusbar::Segment::mouseup_event(MouseEvent& event)
{
if (!is_clickable())
return;
Button::mouseup_event(event);
}
}