diff options
author | MacDue <macdue@dueutil.tech> | 2022-03-27 20:32:32 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-02 21:50:41 +0200 |
commit | 04b6a060ca134ab809c1ff68901de9f78df217d1 (patch) | |
tree | ac088dc5b153b378100c46dac49f503c9a80b7f2 | |
parent | 8fa0409ae145b0dcbe784679a43b70ec91de900e (diff) | |
download | serenity-04b6a060ca134ab809c1ff68901de9f78df217d1.zip |
DisplaySettings: Add theme selection and preview
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")); |