Statusbar.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibGUI/BoxLayout.h>
  7. #include <LibGUI/Painter.h>
  8. #include <LibGUI/ResizeCorner.h>
  9. #include <LibGUI/Statusbar.h>
  10. #include <LibGUI/Window.h>
  11. #include <LibGfx/Palette.h>
  12. #include <LibGfx/StylePainter.h>
  13. REGISTER_WIDGET(GUI, Statusbar)
  14. namespace GUI {
  15. Statusbar::Statusbar(int count)
  16. {
  17. set_fixed_height(18);
  18. set_layout<HorizontalBoxLayout>();
  19. layout()->set_margins(0);
  20. layout()->set_spacing(2);
  21. m_corner = add<ResizeCorner>();
  22. set_segment_count(count);
  23. REGISTER_STRING_PROPERTY("text", text, set_text);
  24. REGISTER_INT_PROPERTY("segment_count", segment_count, set_segment_count);
  25. }
  26. Statusbar::~Statusbar()
  27. {
  28. }
  29. NonnullRefPtr<Statusbar::Segment> Statusbar::create_segment()
  30. {
  31. auto widget = Segment::construct();
  32. insert_child_before(*widget, *m_corner);
  33. return widget;
  34. }
  35. void Statusbar::set_segment_count(size_t count)
  36. {
  37. if (count <= 1)
  38. count = 1;
  39. for (auto i = m_segments.size(); i < count; i++) {
  40. auto segment = create_segment();
  41. m_segments.append(move(segment));
  42. }
  43. }
  44. void Statusbar::update_segment(size_t index)
  45. {
  46. auto& segment = m_segments.at(index);
  47. if (segment.mode() == Segment::Mode::Auto) {
  48. if (segment.restored_text().is_empty())
  49. segment.set_visible(false);
  50. else {
  51. constexpr auto horizontal_padding { 10 };
  52. auto width = font().width(segment.restored_text()) + horizontal_padding;
  53. segment.set_restored_width(width);
  54. segment.set_fixed_width(width);
  55. }
  56. } else if (segment.mode() == Segment::Mode::Fixed) {
  57. if (segment.max_width() != -1)
  58. segment.set_restored_width(segment.max_width());
  59. segment.set_fixed_width(segment.max_width());
  60. }
  61. if (segment.override_text().is_null()) {
  62. for (size_t i = 1; i < m_segments.size(); i++) {
  63. if (!text(i).is_empty())
  64. m_segments[i].set_visible(true);
  65. }
  66. segment.set_text(segment.restored_text());
  67. segment.set_frame_shape(Gfx::FrameShape::Panel);
  68. if (segment.mode() != Segment::Mode::Proportional)
  69. segment.set_fixed_width(segment.restored_width());
  70. } else {
  71. for (size_t i = 1; i < m_segments.size(); i++) {
  72. if (!m_segments[i].is_clickable())
  73. m_segments[i].set_visible(false);
  74. }
  75. segment.set_text(segment.override_text());
  76. segment.set_frame_shape(Gfx::FrameShape::NoFrame);
  77. if (segment.mode() != Segment::Mode::Proportional)
  78. segment.set_fixed_width(-1);
  79. }
  80. }
  81. String Statusbar::text(size_t index) const
  82. {
  83. return m_segments.at(index).text();
  84. }
  85. void Statusbar::set_text(String text)
  86. {
  87. set_text(0, move(text));
  88. }
  89. void Statusbar::set_text(size_t index, String text)
  90. {
  91. m_segments.at(index).m_restored_text = move(text);
  92. update_segment(index);
  93. }
  94. void Statusbar::set_override_text(String override_text)
  95. {
  96. m_segments.at(0).m_override_text = move(override_text);
  97. update_segment(0);
  98. }
  99. void Statusbar::paint_event(PaintEvent& event)
  100. {
  101. Painter painter(*this);
  102. painter.add_clip_rect(event.rect());
  103. painter.fill_rect(rect(), palette().button());
  104. }
  105. void Statusbar::resize_event(ResizeEvent& event)
  106. {
  107. if (auto* window = this->window()) {
  108. m_corner->set_visible(window->is_resizable() && !window->is_maximized());
  109. }
  110. Widget::resize_event(event);
  111. }
  112. Statusbar::Segment::Segment()
  113. {
  114. set_fixed_height(18);
  115. set_focus_policy(GUI::FocusPolicy::NoFocus);
  116. set_button_style(Gfx::ButtonStyle::Tray);
  117. set_text_alignment(Gfx::TextAlignment::CenterLeft);
  118. }
  119. void Statusbar::Segment::paint_event(PaintEvent& event)
  120. {
  121. Painter painter(*this);
  122. painter.add_clip_rect(event.rect());
  123. Gfx::StylePainter::current().paint_frame(painter, rect(), palette(), m_shape, Gfx::FrameShadow::Sunken, m_thickness, spans_entire_window_horizontally());
  124. if (is_clickable())
  125. Button::paint_event(event);
  126. else if (!text().is_empty())
  127. painter.draw_text(rect().shrunken(font().max_glyph_width(), 0), text(), text_alignment(), palette().color(foreground_role()), Gfx::TextElision::Right, Gfx::TextWrapping::DontWrap);
  128. }
  129. void Statusbar::Segment::mousedown_event(MouseEvent& event)
  130. {
  131. if (!is_clickable())
  132. return;
  133. Button::mousedown_event(event);
  134. }
  135. void Statusbar::Segment::mouseup_event(MouseEvent& event)
  136. {
  137. if (!is_clickable())
  138. return;
  139. Button::mouseup_event(event);
  140. }
  141. }