Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/Assertions.h>
9#include <AK/StringBuilder.h>
10#include <LibGUI/Painter.h>
11#include <LibGUI/Progressbar.h>
12#include <LibGfx/Palette.h>
13
14REGISTER_WIDGET(GUI, Progressbar)
15REGISTER_WIDGET(GUI, VerticalProgressbar)
16REGISTER_WIDGET(GUI, HorizontalProgressbar)
17
18namespace GUI {
19
20Progressbar::Progressbar(Orientation orientation)
21 : m_orientation(orientation)
22{
23 REGISTER_STRING_PROPERTY("text", text, set_text);
24 REGISTER_ENUM_PROPERTY("format", format, set_format, Format,
25 { Format::NoText, "NoText" },
26 { Format::Percentage, "Percentage" },
27 { Format::ValueSlashMax, "ValueSlashMax" });
28 REGISTER_INT_PROPERTY("min", min, set_min);
29 REGISTER_INT_PROPERTY("max", max, set_max);
30
31 set_preferred_size(SpecialDimension::Fit);
32}
33
34void Progressbar::set_value(int value)
35{
36 if (m_value == value)
37 return;
38 m_value = value;
39 update();
40}
41
42void Progressbar::set_range(int min, int max)
43{
44 VERIFY(min <= max);
45 m_min = min;
46 m_max = max;
47 m_value = clamp(m_value, m_min, m_max);
48}
49
50void Progressbar::paint_event(PaintEvent& event)
51{
52 Frame::paint_event(event);
53
54 Painter painter(*this);
55 auto rect = frame_inner_rect();
56 painter.add_clip_rect(rect);
57 painter.add_clip_rect(event.rect());
58
59 DeprecatedString progress_text;
60 if (m_format != Format::NoText) {
61 // Then we draw the progress text over the gradient.
62 // We draw it twice, once offset (1, 1) for a drop shadow look.
63 StringBuilder builder;
64 builder.append(m_text);
65 if (m_format == Format::Percentage) {
66 float range_size = m_max - m_min;
67 float progress = (m_value - m_min) / range_size;
68 builder.appendff("{}%", (int)(progress * 100));
69 } else if (m_format == Format::ValueSlashMax) {
70 builder.appendff("{}/{}", m_value, m_max);
71 }
72 progress_text = builder.to_deprecated_string();
73 }
74
75 Gfx::StylePainter::paint_progressbar(painter, rect, palette(), m_min, m_max, m_value, progress_text, m_orientation);
76}
77
78void Progressbar::set_orientation(Orientation value)
79{
80 if (m_orientation == value)
81 return;
82 m_orientation = value;
83 update();
84}
85
86Optional<UISize> Progressbar::calculated_preferred_size() const
87{
88 if (orientation() == Gfx::Orientation::Vertical)
89 return { { 22, SpecialDimension::OpportunisticGrow } };
90 return { { SpecialDimension::OpportunisticGrow, 22 } };
91}
92
93}