From 3e71080e6aba758d379ac436288ad39b1bca10c3 Mon Sep 17 00:00:00 2001 From: DTPA101 <154043471+DTPA101@users.noreply.github.com> Date: Thu, 22 Aug 2024 20:41:25 +0800 Subject: [PATCH] feat(ui): finish setting page (#21) * feat:some basic laying * feat(ui): basic laying on the page * ui laying primary draft * feat(ui): callbacks and root * attempt to fill in .cc and .slint * callbacks fiied * feat: setting page * feat: change theme when app start * chore: clean up code * feat(ui): add scroll view in setting page --------- Co-authored-by: Serein <2075337935@qq.com> --- src/Controller/View/SettingPage.cc | 56 +++++++++++- src/Infrastructure/Utils/Config.h | 56 ++++++++++++ ui/views/page/setting.slint | 142 ++++++++++++++++++++++++----- 3 files changed, 232 insertions(+), 22 deletions(-) diff --git a/src/Controller/View/SettingPage.cc b/src/Controller/View/SettingPage.cc index 571532b6..2d105762 100644 --- a/src/Controller/View/SettingPage.cc +++ b/src/Controller/View/SettingPage.cc @@ -1,13 +1,67 @@ #include +#include EVENTO_UI_START SettingPage::SettingPage(slint::ComponentHandle uiEntry, UiBridge& bridge) : BasicView(bridge) - , GlobalAgent(uiEntry) {} + , GlobalAgent(uiEntry) { + auto& self = *this; + + const auto [languageIdx, minimalToTray, noticeBegin, noticeEnd, themeIdx] = evento::settings; + + self->set_language_index(languageIdx); + self->set_minimal_to_tray(minimalToTray); + self->set_notice_begin(noticeBegin); + self->set_notice_end(noticeEnd); + self->set_theme_index(themeIdx); + + self->invoke_change_theme(); +} void SettingPage::onCreate() { auto& self = *this; + + const auto [languageIdx, minimalToTray, noticeBegin, noticeEnd, themeIdx] = evento::settings; + + config.insert_or_assign("setting", + toml::table{ + {"language", languageIdx}, + {"minimal-to-tray", minimalToTray}, + {"notice-begin", noticeBegin}, + {"notice-end", noticeEnd}, + {"theme", themeIdx}, + }); + + self->on_language_changed([this]() { + auto& self = *this; + auto& setting = config["setting"].ref(); + setting.insert_or_assign("language", self->get_language_index()); + }); + + self->on_minimal_to_tray_changed([this]() { + auto& self = *this; + auto& setting = config["setting"].ref(); + setting.insert_or_assign("minimal-to-tray", self->get_minimal_to_tray()); + }); + + self->on_notice_begin_changed([this]() { + auto& self = *this; + auto& setting = config["setting"].ref(); + setting.insert_or_assign("notice-begin", self->get_notice_begin()); + }); + + self->on_notice_end_changed([this]() { + auto& self = *this; + auto& setting = config["setting"].ref(); + setting.insert_or_assign("notice-end", self->get_notice_end()); + }); + + self->on_theme_changed([this]() { + auto& self = *this; + auto& setting = config["setting"].ref(); + setting.insert_or_assign("theme", self->get_theme_index()); + }); } EVENTO_UI_END \ No newline at end of file diff --git a/src/Infrastructure/Utils/Config.h b/src/Infrastructure/Utils/Config.h index b4d75764..d66d4201 100644 --- a/src/Infrastructure/Utils/Config.h +++ b/src/Infrastructure/Utils/Config.h @@ -5,6 +5,18 @@ #include #include +/* +[account.] +expire = + +[setting] +language = +minimal-to-tray = +notice-begin = +notice-end = +theme = +*/ + namespace evento { namespace details { @@ -20,6 +32,47 @@ const std::filesystem::path configDir = inline toml::table config; +inline struct Setting { + int language; + bool minimalToTray; + bool noticeBegin; + bool noticeEnd; + int theme; +} settings; + +static void loadSetting() { + if (!config.contains("setting")) { + config.insert("setting", toml::table{}); + } + auto& setting = config["setting"].ref(); + + auto languageIdx = setting["language"].value_or(0); + if (languageIdx > 2) { + languageIdx = 0; + } + auto themeIdx = setting["theme"].value_or(0); + if (themeIdx > 2) { + themeIdx = 0; + } + auto noticeBegin = setting["notice-begin"].value_or(false); + auto noticeEnd = setting["notice-end"].value_or(false); + auto minimalToTray = setting["minimal-to-tray"].value_or(false); + + evento::settings = { + .language = languageIdx, + .minimalToTray = minimalToTray, + .noticeBegin = noticeBegin, + .noticeEnd = noticeEnd, + .theme = themeIdx, + }; +} + +static void loadAccount() { + if (!config.contains("account")) { + config.insert("account", toml::table{}); + } +} + inline void initConfig() { if (!std::filesystem::exists(details::configDir)) { spdlog::info("Config directory does not exist, creating..."); @@ -36,6 +89,9 @@ inline void initConfig() { spdlog::error("\"{}\" could not be opened for parsing.", path.string()); config = toml::parse(""); } + + loadSetting(); + loadAccount(); } inline void saveConfig() { diff --git a/ui/views/page/setting.slint b/ui/views/page/setting.slint index 1e8c5db7..1cb59ae7 100644 --- a/ui/views/page/setting.slint +++ b/ui/views/page/setting.slint @@ -1,31 +1,131 @@ import { Token } from "../../global.slint"; import { Page, Empty } from "../../components/index.slint"; +import { Switch, ComboBox, ScrollView } from "std-widgets.slint"; -export global SettingPageBridge { } +export global SettingPageBridge { + in-out property language-index: 0; + in-out property theme-index: 0; + in-out property notice-begin: false; + in-out property notice-end: false; + in-out property minimal-to-tray: false; -export component SettingPage inherits Page { - // TODO: implement Setting - // optional - background := Empty { } - - layout := VerticalLayout { - visible: false; - x: 0; - y: 0; - width: 100%; - height: 100%; + public function change-theme() { + if (theme-index == 1) { + Token.set-display-mode(ColorScheme.light); + } else if (theme-index == 2) { + Token.set-display-mode(ColorScheme.dark); + } else { + Token.set-display-mode(ColorScheme.unknown); + } + } + + callback language-changed(); + callback theme-changed(); + callback notice-begin-changed(); + callback notice-end-changed(); + callback minimal-to-tray-changed(); +} + +component SettingItem { + in property name; + in property supported: true; + HorizontalLayout { + alignment: LayoutAlignment.space-between; + Text { + text: name; + color: root.supported ? Token.color.on-surface : Token.color.outline; + font-size: Token.font.body.large.size; + font-weight: Token.font.body.large.weight; + vertical-alignment: center; + } + + @children } +} - body := Empty { - x: 0; - y: 0; - width: 100%; - height: 100%; - placeholder := Rectangle { - border-width: 4px; - border-color: red; +component Divider inherits Rectangle { + background: Token.color.outline-variant; + width: 80%; + height: 1px; +} + +export component SettingPage inherits Page { + ScrollView { + VerticalLayout { + alignment: LayoutAlignment.start; + padding: 50px; + spacing: 15px; Text { - text: "设置\n "; + text: "设置"; + font-size: Token.font.display.medium.size; + font-weight: Token.font.display.medium.weight; + } + + Divider { } + + SettingItem { + name: "主题"; + ComboBox { + width: 200px; + model: ["跟随系统", "浅色", "深色"]; + current-index <=> SettingPageBridge.theme-index; + selected => { + SettingPageBridge.change-theme(); + SettingPageBridge.theme-changed(); + } + } + } + + SettingItem { + name: "语言"; + supported: false; + ComboBox { + width: 200px; + enabled: false; + model: ["简体中文", "繁體中文", "English"]; + current-index <=> SettingPageBridge.language-index; + selected => { + SettingPageBridge.language-changed(); + } + } + } + + Divider { } + + SettingItem { + supported: false; + name: "活动开始前提醒"; + Switch { + enabled: false; + checked <=> SettingPageBridge.notice-begin; + toggled => { + SettingPageBridge.notice-begin-changed(); + } + } + } + + SettingItem { + supported: false; + name: "活动结束后提醒反馈"; + Switch { + enabled: false; + checked <=> SettingPageBridge.notice-end; + toggled => { + SettingPageBridge.notice-end-changed(); + } + } + } + + SettingItem { + supported: false; + name: "关闭窗口后最小化到托盘"; + Switch { + enabled: false; + checked <=> SettingPageBridge.minimal-to-tray; + toggled => { + SettingPageBridge.minimal-to-tray-changed(); + } + } } } }