From 37d19ed98f0fe6068ce9ac34274607e9880025a5 Mon Sep 17 00:00:00 2001 From: z_lenovo Date: Mon, 23 Jun 2025 23:25:37 +0800 Subject: [PATCH] add the theme selector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真tm难,但是之前遇到的问题大部分都解决了,在考虑要不要后边把这个软件给重构一下? --- src/main.rs | 3 +++ src/ui/home_page.rs | 54 ++++++++++++++++++++++++++++++++++----- src/ui/main_window.rs | 37 +++++++++++++++------------ src/utils/app_settings.rs | 21 +++++++++++++++ src/utils/winsparkle.rs | 4 +++ 5 files changed, 96 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index 15c595f..9434358 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,9 @@ fn main() { win_sparkle_set_appcast_url( "https://dl.wuembed.com/hardware_tk/appcast.xml\0".as_ptr() as *const i8 ); + win_sparkle_set_eddsa_public_key( + "pXr0FyLTCvtX2BP7d/i3Ot8T9hL+ODBQforwfBp2oLo=\0".as_ptr() as *const i8 + ); win_sparkle_init(); } ui::main_window::main_window(); diff --git a/src/ui/home_page.rs b/src/ui/home_page.rs index a6bd0e6..ffae9c3 100644 --- a/src/ui/home_page.rs +++ b/src/ui/home_page.rs @@ -3,24 +3,63 @@ use iced::{Length, alignment::Horizontal, widget::Column}; #[allow(unused_imports)] use crate::ui::main_window::{MainWindowMsg, TabContent}; -#[derive(Default)] -pub struct HomePage {} +pub struct HomePage { + step_dir: String, + pub theme: iced::Theme, +} +impl Default for HomePage { + fn default() -> Self { + Self { + step_dir: crate::utils::app_settings::get_step_dir().unwrap(), + theme: Default::default(), + } + } +} #[derive(Debug, Default, Clone, PartialEq, Eq)] pub enum HomePageMsg { #[default] Nothing, + CheckUpdate, + OpenStepDir, + ChooseStepDir, } impl TabContent for HomePage { fn content(&self) -> iced::Element<'_, MainWindowMsg> { - let btn = iced::widget::button("HomePage") - .on_press(MainWindowMsg::HomePage(HomePageMsg::Nothing)); - + let info = iced::widget::row![ + iced::widget::text("版本:"), + iced::widget::text(env!("CARGO_PKG_VERSION")), + iced::widget::horizontal_space(), + iced::widget::button("检查更新") + .on_press(MainWindowMsg::HomePage(HomePageMsg::CheckUpdate)), + ]; + let stp_path_set = iced::widget::row![ + iced::widget::text("Step下载路径:"), + iced::widget::text(self.step_dir.clone()), + iced::widget::button("打开") + .on_press(MainWindowMsg::HomePage(HomePageMsg::OpenStepDir)), + iced::widget::button("浏览") + .on_press(MainWindowMsg::HomePage(HomePageMsg::ChooseStepDir)) + ] + .spacing(16.0); + let theme = iced::widget::row![ + iced::widget::text("主题选择:"), + iced::widget::pick_list( + iced::Theme::ALL, + Some(&self.theme), + MainWindowMsg::ThemeChanged + ) + .width(480), + ] + .spacing(16.0); Column::new() .align_x(Horizontal::Left) .width(Length::Fill) .height(Length::Fill) - .push(btn) + .push(info) + .push(stp_path_set) + .push(theme) + .spacing(5.0) .into() } @@ -31,6 +70,9 @@ impl TabContent for HomePage { HomePageMsg::Nothing => { println!("This way ok."); } + _ => { + println!("Is the message you should process ? =====>> {msg:?}"); + } } } } diff --git a/src/ui/main_window.rs b/src/ui/main_window.rs index 4db274b..4a6154c 100644 --- a/src/ui/main_window.rs +++ b/src/ui/main_window.rs @@ -1,4 +1,5 @@ use crate::ui::db_browser::DbBrowserMsg; +use crate::ui::home_page::HomePage; use crate::ui::home_page::HomePageMsg; use crate::ui::jlc_downloader::JlcDownloaderMsg; use crate::ui::part_viewer::PartViewerMsg; @@ -25,6 +26,7 @@ use iced::{ widget::{Column, Container, Text, column}, }; use std::fmt::Display; +use std::ops::Index; #[allow(dead_code)] struct MainWindow { @@ -38,11 +40,17 @@ struct MainWindow { } impl Default for MainWindow { fn default() -> Self { + let mut home_page = HomePage::default(); + let mut theme = Theme::default(); + if let Ok(saved_theme) = crate::utils::app_settings::get_curr_theme() { + theme = Theme::ALL[saved_theme as usize % Theme::ALL.len()].clone(); + home_page.theme = theme.clone(); + } Self { title: "HardwareToolkit".into(), - theme: Default::default(), + theme, curr_tab: Default::default(), - home_page: Default::default(), + home_page, jlc_downloader: Default::default(), db_browser: Default::default(), part_viewer: Default::default(), @@ -52,6 +60,7 @@ impl Default for MainWindow { pub fn main_window() { let _ = iced::application(MainWindow::default, MainWindow::update, MainWindow::view) + .theme(MainWindow::theme) .default_font(iced::Font::with_name("微软雅黑")) .title(MainWindow::title) .run(); @@ -93,27 +102,18 @@ impl Display for TabId { ) } } -fn btn_active_style(_theme: &Theme, _status: Status) -> Style { - let mut s = Style::default(); - let bgcolor = iced::Color::from_rgba8(30, 200, 200, 1.0); - s.background = Some(iced::Background::Color(bgcolor)); - s -} -fn btn_deactive_style(_theme: &Theme, _status: Status) -> Style { - let mut s = Style::default(); - let bgcolor = iced::Color::from_rgba8(220, 200, 100, 1.0); - s.background = Some(iced::Background::Color(bgcolor)); - s -} impl MainWindow { fn title(&self) -> String { self.title.clone() } + fn theme(&self) -> Theme { + self.theme.clone() + } fn create_tab_btn(&self, tab: TabId) -> Element<'_, MainWindowMsg> { let bstyle = if self.curr_tab == tab { - btn_active_style + button::danger } else { - btn_deactive_style + button::primary }; let txt = format!("{tab}"); @@ -125,7 +125,10 @@ impl MainWindow { println!("Process the msg: {msg:?}"); match msg { MainWindowMsg::ThemeChanged(theme) => { - self.theme = theme; + self.theme = theme.clone(); + if let Some(idx) = Theme::ALL.iter().position(|x| x == &theme) { + crate::utils::app_settings::set_curr_theme(idx as u32).unwrap(); + } } MainWindowMsg::TitleChanged(title) => { self.title = title; diff --git a/src/utils/app_settings.rs b/src/utils/app_settings.rs index 6f1a849..29cbaa6 100644 --- a/src/utils/app_settings.rs +++ b/src/utils/app_settings.rs @@ -47,6 +47,27 @@ pub fn set_step_dir(path: &str) -> Result<(), anyhow::Error> { Ok(()) } +#[allow(dead_code)] +pub fn set_curr_theme(c: u32) -> Result<(), anyhow::Error> { + let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?; + reg.set_value("curr_theme", ®istry::Data::U32(c))?; + Ok(()) +} + +#[allow(dead_code)] +pub fn get_curr_theme() -> Result { + let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?; + match reg.value("curr_theme")? { + registry::Data::U32(v) => { + return Ok(v); + } + _ => { + log::info!("The curr_page is an empty value."); + } + } + Ok(0) +} + #[allow(dead_code)] pub fn set_curr_page(c: u32) -> Result<(), anyhow::Error> { let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?; diff --git a/src/utils/winsparkle.rs b/src/utils/winsparkle.rs index 6f29f04..7f69164 100644 --- a/src/utils/winsparkle.rs +++ b/src/utils/winsparkle.rs @@ -35,6 +35,10 @@ unsafe extern "C" { /// returns 1 if valid DSA public key provided, 0 otherwise. pub fn win_sparkle_set_dsa_pub_pem(dsa_pub_pem: *const i8) -> i32; + /// Set EDDSA public key. + /// The function above should not be used. + pub unsafe fn win_sparkle_set_eddsa_public_key(eddsa_pub_pem: *const i8) -> i32; + /// Set the path in the registry where WinSparkle will store its settings. /// /// This sets the path where WinSparkle will store its settings in the registry.