SystemMonitor: Define graphs by ColorRole, not by Color

Currently, graphs are defined in terms of graph color. This means that
when the system palette is changed, the old colors are still used. We
switch to storing the color roles and looking up the palette colors on
paint events. We also define the graph line background color as the
graph color at half-transparency.
This commit is contained in:
Sahan Fernando 2021-02-14 20:04:38 +11:00 committed by Andreas Kling
parent 6ee499aeb0
commit ca731e2cdd
3 changed files with 21 additions and 16 deletions

View file

@ -25,6 +25,7 @@
*/ */
#include "GraphWidget.h" #include "GraphWidget.h"
#include <LibGUI/Application.h>
#include <LibGUI/Painter.h> #include <LibGUI/Painter.h>
#include <LibGfx/Font.h> #include <LibGfx/Font.h>
#include <LibGfx/Palette.h> #include <LibGfx/Palette.h>
@ -47,6 +48,8 @@ void GraphWidget::add_value(Vector<int, 1>&& value)
void GraphWidget::paint_event(GUI::PaintEvent& event) void GraphWidget::paint_event(GUI::PaintEvent& event)
{ {
const auto& system_palette = GUI::Application::the()->palette();
GUI::Frame::paint_event(event); GUI::Frame::paint_event(event);
GUI::Painter painter(*this); GUI::Painter painter(*this);
painter.add_clip_rect(event.rect()); painter.add_clip_rect(event.rect());
@ -60,8 +63,11 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
// Draw one set of values at a time // Draw one set of values at a time
for (size_t k = 0; k < m_value_format.size(); k++) { for (size_t k = 0; k < m_value_format.size(); k++) {
const auto& format = m_value_format[k]; const auto& format = m_value_format[k];
if (format.line_color == Color::Transparent && format.background_color == Color::Transparent) if (format.graph_color_role == ColorRole::Base) {
continue; continue;
}
const auto& line_color = system_palette.color(format.graph_color_role);
const auto& background_color = line_color.with_alpha(0x7f);
m_calculated_points.clear_with_capacity(); m_calculated_points.clear_with_capacity();
for (size_t i = 0; i < m_values.size(); i++) { for (size_t i = 0; i < m_values.size(); i++) {
int x = inner_rect.right() - (i * 2) + 1; int x = inner_rect.right() - (i * 2) + 1;
@ -83,7 +89,7 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
m_calculated_points.append(current_point); m_calculated_points.append(current_point);
} }
ASSERT(m_calculated_points.size() <= m_values.size()); ASSERT(m_calculated_points.size() <= m_values.size());
if (format.background_color != Color::Transparent) { if (format.graph_color_role != ColorRole::Base) {
// Fill the background for the area we have values for // Fill the background for the area we have values for
Gfx::Path path; Gfx::Path path;
size_t points_in_path = 0; size_t points_in_path = 0;
@ -99,11 +105,11 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
path.line_to({ current_point->x() - 1, inner_rect.bottom() + 1 }); path.line_to({ current_point->x() - 1, inner_rect.bottom() + 1 });
path.line_to({ first_point->x() + 1, inner_rect.bottom() + 1 }); path.line_to({ first_point->x() + 1, inner_rect.bottom() + 1 });
path.close(); path.close();
painter.fill_path(path, format.background_color, Gfx::Painter::WindingRule::EvenOdd); painter.fill_path(path, background_color, Gfx::Painter::WindingRule::EvenOdd);
} else if (points_in_path == 1 && current_point) { } else if (points_in_path == 1 && current_point) {
// Can't fill any area, we only have one data point. // Can't fill any area, we only have one data point.
// Just draw a vertical line as a "fill"... // Just draw a vertical line as a "fill"...
painter.draw_line(*current_point, { current_point->x(), inner_rect.bottom() }, format.background_color); painter.draw_line(*current_point, { current_point->x(), inner_rect.bottom() }, background_color);
} }
path = {}; path = {};
points_in_path = 0; points_in_path = 0;
@ -128,7 +134,7 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
} }
check_fill_area(); check_fill_area();
} }
if (format.line_color != Color::Transparent) { if (format.graph_color_role != ColorRole::Base) {
// Draw the line for the data points we have // Draw the line for the data points we have
const Gfx::IntPoint* previous_point = nullptr; const Gfx::IntPoint* previous_point = nullptr;
for (size_t i = 0; i < m_calculated_points.size(); i++) { for (size_t i = 0; i < m_calculated_points.size(); i++) {
@ -138,7 +144,7 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
continue; continue;
} }
if (previous_point) if (previous_point)
painter.draw_line(*previous_point, current_point, format.line_color); painter.draw_line(*previous_point, current_point, line_color);
previous_point = &current_point; previous_point = &current_point;
} }
} }
@ -150,6 +156,7 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
int y = 0; int y = 0;
for (size_t i = 0; i < min(m_value_format.size(), current_values.size()); i++) { for (size_t i = 0; i < min(m_value_format.size(), current_values.size()); i++) {
const auto& format = m_value_format[i]; const auto& format = m_value_format[i];
const auto& graph_color = system_palette.color(format.graph_color_role);
if (!format.text_formatter) if (!format.text_formatter)
continue; continue;
auto constrain_rect = inner_rect.shrunken(8, 8); auto constrain_rect = inner_rect.shrunken(8, 8);
@ -158,7 +165,7 @@ void GraphWidget::paint_event(GUI::PaintEvent& event)
auto text = format.text_formatter(current_values[i]); auto text = format.text_formatter(current_values[i]);
if (format.text_shadow_color != Color::Transparent) if (format.text_shadow_color != Color::Transparent)
painter.draw_text(text_rect.translated(1, 1), text.characters(), Gfx::TextAlignment::CenterRight, format.text_shadow_color); painter.draw_text(text_rect.translated(1, 1), text.characters(), Gfx::TextAlignment::CenterRight, format.text_shadow_color);
painter.draw_text(text_rect, text.characters(), Gfx::TextAlignment::CenterRight, format.line_color); painter.draw_text(text_rect, text.characters(), Gfx::TextAlignment::CenterRight, graph_color);
y += text_rect.height() + 4; y += text_rect.height() + 4;
} }
} }

View file

@ -28,6 +28,7 @@
#include <AK/CircularQueue.h> #include <AK/CircularQueue.h>
#include <LibGUI/Frame.h> #include <LibGUI/Frame.h>
#include <LibGfx/SystemTheme.h>
class GraphWidget final : public GUI::Frame { class GraphWidget final : public GUI::Frame {
C_OBJECT(GraphWidget) C_OBJECT(GraphWidget)
@ -40,8 +41,7 @@ public:
void add_value(Vector<int, 1>&&); void add_value(Vector<int, 1>&&);
struct ValueFormat { struct ValueFormat {
Color line_color { Color::Transparent }; Gfx::ColorRole graph_color_role { Gfx::ColorRole::Base };
Color background_color { Color::Transparent };
Color text_shadow_color { Color::Transparent }; Color text_shadow_color { Color::Transparent };
Function<String(int)> text_formatter; Function<String(int)> text_formatter;
}; };

View file

@ -573,8 +573,6 @@ NonnullRefPtr<GUI::Widget> build_graphs_tab()
auto graphs_container = GUI::LazyWidget::construct(); auto graphs_container = GUI::LazyWidget::construct();
graphs_container->on_first_show = [](GUI::LazyWidget& self) { graphs_container->on_first_show = [](GUI::LazyWidget& self) {
const auto system_palette = GUI::Application::the()->palette();
self.set_fill_with_background_color(true); self.set_fill_with_background_color(true);
self.set_background_role(ColorRole::Button); self.set_background_role(ColorRole::Button);
self.set_layout<GUI::VerticalBoxLayout>(); self.set_layout<GUI::VerticalBoxLayout>();
@ -589,13 +587,13 @@ NonnullRefPtr<GUI::Widget> build_graphs_tab()
auto& cpu_graph = cpu_graph_group_box.add<GraphWidget>(); auto& cpu_graph = cpu_graph_group_box.add<GraphWidget>();
cpu_graph.set_max(100); cpu_graph.set_max(100);
cpu_graph.set_value_format(0, { cpu_graph.set_value_format(0, {
.line_color = system_palette.syntax_preprocessor_statement(), .graph_color_role = ColorRole::SyntaxPreprocessorStatement,
.text_formatter = [](int value) { .text_formatter = [](int value) {
return String::formatted("Total: {}%", value); return String::formatted("Total: {}%", value);
}, },
}); });
cpu_graph.set_value_format(1, { cpu_graph.set_value_format(1, {
.line_color = system_palette.syntax_preprocessor_value(), .graph_color_role = ColorRole::SyntaxPreprocessorValue,
.text_formatter = [](int value) { .text_formatter = [](int value) {
return String::formatted("Kernel: {}%", value); return String::formatted("Kernel: {}%", value);
}, },
@ -614,19 +612,19 @@ NonnullRefPtr<GUI::Widget> build_graphs_tab()
auto& memory_graph = memory_graph_group_box.add<GraphWidget>(); auto& memory_graph = memory_graph_group_box.add<GraphWidget>();
memory_graph.set_stack_values(true); memory_graph.set_stack_values(true);
memory_graph.set_value_format(0, { memory_graph.set_value_format(0, {
.line_color = system_palette.syntax_comment(), .graph_color_role = ColorRole::SyntaxComment,
.text_formatter = [&memory_graph](int value) { .text_formatter = [&memory_graph](int value) {
return String::formatted("Committed: {} KiB", value); return String::formatted("Committed: {} KiB", value);
}, },
}); });
memory_graph.set_value_format(1, { memory_graph.set_value_format(1, {
.line_color = system_palette.syntax_preprocessor_statement(), .graph_color_role = ColorRole::SyntaxPreprocessorStatement,
.text_formatter = [&memory_graph](int value) { .text_formatter = [&memory_graph](int value) {
return String::formatted("Allocated: {} KiB", value); return String::formatted("Allocated: {} KiB", value);
}, },
}); });
memory_graph.set_value_format(2, { memory_graph.set_value_format(2, {
.line_color = system_palette.syntax_preprocessor_value(), .graph_color_role = ColorRole::SyntaxPreprocessorValue,
.text_formatter = [&memory_graph](int value) { .text_formatter = [&memory_graph](int value) {
return String::formatted("Kernel heap: {} KiB", value); return String::formatted("Kernel heap: {} KiB", value);
}, },