summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2022-03-27 20:32:32 +0100
committerAndreas Kling <kling@serenityos.org>2022-04-02 21:50:41 +0200
commit04b6a060ca134ab809c1ff68901de9f78df217d1 (patch)
treeac088dc5b153b378100c46dac49f503c9a80b7f2
parent8fa0409ae145b0dcbe784679a43b70ec91de900e (diff)
downloadserenity-04b6a060ca134ab809c1ff68901de9f78df217d1.zip
DisplaySettings: Add theme selection and preview
-rw-r--r--Userland/Applications/DisplaySettings/CMakeLists.txt6
-rw-r--r--Userland/Applications/DisplaySettings/ThemePreviewWidget.cpp50
-rw-r--r--Userland/Applications/DisplaySettings/ThemePreviewWidget.h29
-rw-r--r--Userland/Applications/DisplaySettings/ThemesSettings.gml32
-rw-r--r--Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp52
-rw-r--r--Userland/Applications/DisplaySettings/ThemesSettingsWidget.h37
-rw-r--r--Userland/Applications/DisplaySettings/main.cpp2
7 files changed, 208 insertions, 0 deletions
diff --git a/Userland/Applications/DisplaySettings/CMakeLists.txt b/Userland/Applications/DisplaySettings/CMakeLists.txt
index 84c88b9987..9ee81640e6 100644
--- a/Userland/Applications/DisplaySettings/CMakeLists.txt
+++ b/Userland/Applications/DisplaySettings/CMakeLists.txt
@@ -8,6 +8,7 @@ compile_gml(MonitorSettings.gml MonitorSettingsGML.h monitor_settings_window_gml
compile_gml(BackgroundSettings.gml BackgroundSettingsGML.h background_settings_gml)
compile_gml(DesktopSettings.gml DesktopSettingsGML.h desktop_settings_gml)
compile_gml(FontSettings.gml FontSettingsGML.h font_settings_gml)
+compile_gml(ThemesSettings.gml ThemesSettingsGML.h themes_settings_gml)
set(SOURCES
BackgroundSettingsGML.h
@@ -19,6 +20,11 @@ set(SOURCES
MonitorSettingsWidget.cpp
MonitorSettingsGML.h
MonitorWidget.cpp
+ ThemePreviewWidget.h
+ ThemePreviewWidget.cpp
+ ThemesSettingsWidget.h
+ ThemesSettingsWidget.cpp
+ ThemesSettingsGML.h
main.cpp
)
diff --git a/Userland/Applications/DisplaySettings/ThemePreviewWidget.cpp b/Userland/Applications/DisplaySettings/ThemePreviewWidget.cpp
new file mode 100644
index 0000000000..aaba61d6bc
--- /dev/null
+++ b/Userland/Applications/DisplaySettings/ThemePreviewWidget.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022, MacDue <macdue@dueutil.tech>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "ThemePreviewWidget.h"
+#include <AK/Array.h>
+#include <LibCore/File.h>
+#include <LibGUI/Painter.h>
+#include <LibGfx/Painter.h>
+#include <LibGfx/StylePainter.h>
+
+namespace DisplaySettings {
+
+ThemePreviewWidget::ThemePreviewWidget(Gfx::Palette const& palette)
+ : GUI::AbstractThemePreview(palette)
+{
+ set_fixed_size(304, 201);
+}
+
+void ThemePreviewWidget::set_theme(String path)
+{
+ set_theme_from_file(*Core::File::open(path, Core::OpenMode::ReadOnly).release_value_but_fixme_should_propagate_errors());
+}
+
+void ThemePreviewWidget::paint_preview(GUI::PaintEvent&)
+{
+ GUI::Painter painter(*this);
+
+ auto active_window_rect = rect().shrunken(48, 100).translated(4, 26);
+ auto inactive_window_rect = active_window_rect.translated(-8, -32);
+ auto message_box = active_window_rect.shrunken(100, 60);
+
+ paint_window("Inactive Window", inactive_window_rect, Gfx::WindowTheme::WindowState::Inactive, inactive_window_icon());
+ paint_window("Active Window", active_window_rect, Gfx::WindowTheme::WindowState::Active, active_window_icon());
+ paint_window("Alert", message_box, Gfx::WindowTheme::WindowState::Highlighted, active_window_icon(), 1);
+
+ auto draw_centered_button = [&](auto window_rect, auto text, int button_width, int button_height) {
+ auto box_center = window_rect.center();
+ Gfx::IntRect button_rect { box_center.x() - button_width / 2, box_center.y() - button_height / 2, button_width, button_height };
+ Gfx::StylePainter::paint_button(
+ painter, button_rect, preview_palette(), Gfx::ButtonStyle::Normal, false, false, false, true, false, false);
+ painter.draw_text(button_rect, text, Gfx::TextAlignment::Center, preview_palette().color(foreground_role()), Gfx::TextElision::Right, Gfx::TextWrapping::DontWrap);
+ };
+
+ draw_centered_button(message_box, "Ok", 32, 16);
+}
+
+}
diff --git a/Userland/Applications/DisplaySettings/ThemePreviewWidget.h b/Userland/Applications/DisplaySettings/ThemePreviewWidget.h
new file mode 100644
index 0000000000..370db19339
--- /dev/null
+++ b/Userland/Applications/DisplaySettings/ThemePreviewWidget.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022, MacDue <macdue@dueutil.tech>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibGUI/AbstractThemePreview.h>
+#include <LibGUI/Widget.h>
+#include <LibGfx/Bitmap.h>
+#include <LibGfx/Palette.h>
+#include <LibGfx/WindowTheme.h>
+
+namespace DisplaySettings {
+
+class ThemePreviewWidget final : public GUI::AbstractThemePreview {
+ C_OBJECT(ThemePreviewWidget);
+
+public:
+ void set_theme(String path);
+
+private:
+ explicit ThemePreviewWidget(Gfx::Palette const& palette);
+
+ void paint_preview(GUI::PaintEvent& event) override;
+};
+
+}
diff --git a/Userland/Applications/DisplaySettings/ThemesSettings.gml b/Userland/Applications/DisplaySettings/ThemesSettings.gml
new file mode 100644
index 0000000000..2556404e75
--- /dev/null
+++ b/Userland/Applications/DisplaySettings/ThemesSettings.gml
@@ -0,0 +1,32 @@
+@GUI::Widget {
+ fill_with_background_color: true
+ layout: @GUI::VerticalBoxLayout {
+ margins: [8]
+ }
+
+ @GUI::Frame {
+ layout: @GUI::HorizontalBoxLayout {}
+ name: "preview_frame"
+ fixed_width: 304
+ fixed_height: 201
+ }
+
+ @GUI::Widget {
+ fixed_height: 20
+ }
+
+ @GUI::Widget {
+ shrink_to_fit: true
+ layout: @GUI::HorizontalBoxLayout {}
+
+ @GUI::Label {
+ text: "Theme:"
+ text_alignment: "CenterLeft"
+ fixed_width: 95
+ }
+
+ @GUI::ComboBox {
+ name: "themes_combo"
+ }
+ }
+}
diff --git a/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp
new file mode 100644
index 0000000000..5d86a07cac
--- /dev/null
+++ b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022, MacDue <macdue@dueutil.tech>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "ThemesSettingsWidget.h"
+#include <AK/LexicalPath.h>
+#include <AK/QuickSort.h>
+#include <Applications/DisplaySettings/ThemesSettingsGML.h>
+#include <LibCore/DirIterator.h>
+#include <LibGUI/ConnectionToWindowServer.h>
+#include <LibGUI/ItemListModel.h>
+
+namespace DisplaySettings {
+
+ThemesSettingsWidget::ThemesSettingsWidget()
+{
+ load_from_gml(themes_settings_gml);
+ m_themes = Gfx::list_installed_system_themes();
+
+ auto current_theme_name = GUI::ConnectionToWindowServer::the().get_system_theme();
+
+ size_t current_theme_index;
+ m_theme_names.ensure_capacity(m_themes.size());
+ for (auto& theme_meta : m_themes) {
+ m_theme_names.append(theme_meta.name);
+ if (current_theme_name == theme_meta.name) {
+ m_selected_theme = &theme_meta;
+ current_theme_index = m_theme_names.size() - 1;
+ }
+ }
+ VERIFY(m_selected_theme);
+
+ m_theme_preview = find_descendant_of_type_named<GUI::Frame>("preview_frame")->add<ThemePreviewWidget>(palette());
+ m_themes_combo = *find_descendant_of_type_named<GUI::ComboBox>("themes_combo");
+ m_themes_combo->set_only_allow_values_from_model(true);
+ m_themes_combo->set_model(*GUI::ItemListModel<String>::create(m_theme_names));
+ m_themes_combo->on_change = [this](auto&, const GUI::ModelIndex& index) {
+ m_selected_theme = &m_themes.at(index.row());
+ m_theme_preview->set_theme(m_selected_theme->path);
+ };
+ m_themes_combo->set_selected_index(current_theme_index);
+}
+
+void ThemesSettingsWidget::apply_settings()
+{
+ if (m_selected_theme)
+ VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(m_selected_theme->path, m_selected_theme->name));
+}
+
+}
diff --git a/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h
new file mode 100644
index 0000000000..520a754642
--- /dev/null
+++ b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022, MacDue <macdue@dueutil.tech>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/String.h>
+#include <AK/Vector.h>
+#include <LibGUI/ComboBox.h>
+#include <LibGUI/SettingsWindow.h>
+#include <LibGfx/SystemTheme.h>
+
+#include "ThemePreviewWidget.h"
+
+namespace DisplaySettings {
+
+class ThemesSettingsWidget final : public GUI::SettingsWindow::Tab {
+ C_OBJECT(ThemesSettingsWidget);
+
+public:
+ virtual void apply_settings() override;
+
+private:
+ Vector<Gfx::SystemThemeMetaData> m_themes;
+ Vector<String> m_theme_names;
+
+ RefPtr<GUI::ComboBox> m_themes_combo;
+ RefPtr<ThemePreviewWidget> m_theme_preview;
+
+ Gfx::SystemThemeMetaData const* m_selected_theme { nullptr };
+
+ ThemesSettingsWidget();
+};
+
+}
diff --git a/Userland/Applications/DisplaySettings/main.cpp b/Userland/Applications/DisplaySettings/main.cpp
index d968d75d93..b8b2fef93a 100644
--- a/Userland/Applications/DisplaySettings/main.cpp
+++ b/Userland/Applications/DisplaySettings/main.cpp
@@ -10,6 +10,7 @@
#include "DesktopSettingsWidget.h"
#include "FontSettingsWidget.h"
#include "MonitorSettingsWidget.h"
+#include "ThemesSettingsWidget.h"
#include <LibConfig/Client.h>
#include <LibCore/System.h>
#include <LibGUI/Application.h>
@@ -28,6 +29,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto window = TRY(GUI::SettingsWindow::create("Display Settings"));
(void)TRY(window->add_tab<DisplaySettings::BackgroundSettingsWidget>("Background"));
+ (void)TRY(window->add_tab<DisplaySettings::ThemesSettingsWidget>("Themes"));
(void)TRY(window->add_tab<DisplaySettings::FontSettingsWidget>("Fonts"));
(void)TRY(window->add_tab<DisplaySettings::MonitorSettingsWidget>("Monitor"));
(void)TRY(window->add_tab<DisplaySettings::DesktopSettingsWidget>("Workspaces"));