123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2022, the SerenityOS developers.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <LibGUI/BoxLayout.h>
- #include <LibGUI/Painter.h>
- #include <LibGUI/ResizeCorner.h>
- #include <LibGUI/Statusbar.h>
- #include <LibGUI/Window.h>
- #include <LibGfx/Palette.h>
- #include <LibGfx/StylePainter.h>
- REGISTER_WIDGET(GUI, Statusbar)
- namespace GUI {
- Statusbar::Statusbar(int count)
- {
- set_fixed_height(18);
- set_layout<HorizontalBoxLayout>(0, 2);
- m_corner = add<ResizeCorner>();
- set_segment_count(count);
- REGISTER_STRING_PROPERTY("text", text, set_text);
- REGISTER_INT_PROPERTY("segment_count", segment_count, set_segment_count);
- }
- NonnullRefPtr<Statusbar::Segment> Statusbar::create_segment()
- {
- auto widget = Segment::construct();
- insert_child_before(*widget, *m_corner);
- return widget;
- }
- void Statusbar::child_event(Core::ChildEvent& event)
- {
- auto& event_to_forward = event;
- // To ensure that the ResizeCorner is always the last widget, and thus stays in the corner,
- // we replace ChildAdded events that do not request specific placement with events that request placement before the corner
- if (event.type() == Event::ChildAdded && is<Widget>(*event.child()) && !event.insertion_before_child()) {
- Core::ChildEvent new_event(Event::ChildAdded, *event.child(), m_corner.ptr());
- event_to_forward = new_event;
- }
- return Widget::child_event(event_to_forward);
- }
- 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().is_int()) {
- segment.set_restored_width(segment.max_width().as_int());
- 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(String::from_utf8(segment.restored_text()).release_value_but_fixme_should_propagate_errors());
- 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(String::from_utf8(segment.override_text()).release_value_but_fixme_should_propagate_errors());
- segment.set_frame_shape(Gfx::FrameShape::NoFrame);
- if (segment.mode() != Segment::Mode::Proportional)
- segment.set_fixed_width(SpecialDimension::Grow);
- }
- }
- DeprecatedString Statusbar::text(size_t index) const
- {
- return m_segments.at(index).text().to_deprecated_string();
- }
- void Statusbar::set_text(DeprecatedString text)
- {
- set_text(0, move(text));
- }
- void Statusbar::set_text(size_t index, DeprecatedString text)
- {
- m_segments.at(index).m_restored_text = move(text);
- update_segment(index);
- }
- void Statusbar::set_override_text(DeprecatedString override_text)
- {
- m_segments.at(0).m_override_text = move(override_text);
- update_segment(0);
- }
- void Statusbar::paint_event(PaintEvent& event)
- {
- Painter painter(*this);
- painter.add_clip_rect(event.rect());
- painter.fill_rect(rect(), palette().button());
- }
- void Statusbar::resize_event(ResizeEvent& event)
- {
- if (auto* window = this->window()) {
- m_corner->set_visible(window->is_resizable() && !window->is_maximized());
- }
- 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);
- }
- }
|