add the theme selector

真tm难,但是之前遇到的问题大部分都解决了,在考虑要不要后边把这个软件给重构一下?
This commit is contained in:
z_lenovo 2025-06-23 23:25:37 +08:00
parent 88d23ca773
commit 37d19ed98f
5 changed files with 96 additions and 23 deletions

View File

@ -9,6 +9,9 @@ fn main() {
win_sparkle_set_appcast_url( win_sparkle_set_appcast_url(
"https://dl.wuembed.com/hardware_tk/appcast.xml\0".as_ptr() as *const i8 "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(); win_sparkle_init();
} }
ui::main_window::main_window(); ui::main_window::main_window();

View File

@ -3,24 +3,63 @@ use iced::{Length, alignment::Horizontal, widget::Column};
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::ui::main_window::{MainWindowMsg, TabContent}; 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)] #[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum HomePageMsg { pub enum HomePageMsg {
#[default] #[default]
Nothing, Nothing,
CheckUpdate,
OpenStepDir,
ChooseStepDir,
} }
impl TabContent for HomePage { impl TabContent for HomePage {
fn content(&self) -> iced::Element<'_, MainWindowMsg> { fn content(&self) -> iced::Element<'_, MainWindowMsg> {
let btn = iced::widget::button("HomePage") let info = iced::widget::row![
.on_press(MainWindowMsg::HomePage(HomePageMsg::Nothing)); 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() Column::new()
.align_x(Horizontal::Left) .align_x(Horizontal::Left)
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.push(btn) .push(info)
.push(stp_path_set)
.push(theme)
.spacing(5.0)
.into() .into()
} }
@ -31,6 +70,9 @@ impl TabContent for HomePage {
HomePageMsg::Nothing => { HomePageMsg::Nothing => {
println!("This way ok."); println!("This way ok.");
} }
_ => {
println!("Is the message you should process ? =====>> {msg:?}");
}
} }
} }
} }

View File

@ -1,4 +1,5 @@
use crate::ui::db_browser::DbBrowserMsg; use crate::ui::db_browser::DbBrowserMsg;
use crate::ui::home_page::HomePage;
use crate::ui::home_page::HomePageMsg; use crate::ui::home_page::HomePageMsg;
use crate::ui::jlc_downloader::JlcDownloaderMsg; use crate::ui::jlc_downloader::JlcDownloaderMsg;
use crate::ui::part_viewer::PartViewerMsg; use crate::ui::part_viewer::PartViewerMsg;
@ -25,6 +26,7 @@ use iced::{
widget::{Column, Container, Text, column}, widget::{Column, Container, Text, column},
}; };
use std::fmt::Display; use std::fmt::Display;
use std::ops::Index;
#[allow(dead_code)] #[allow(dead_code)]
struct MainWindow { struct MainWindow {
@ -38,11 +40,17 @@ struct MainWindow {
} }
impl Default for MainWindow { impl Default for MainWindow {
fn default() -> Self { 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 { Self {
title: "HardwareToolkit".into(), title: "HardwareToolkit".into(),
theme: Default::default(), theme,
curr_tab: Default::default(), curr_tab: Default::default(),
home_page: Default::default(), home_page,
jlc_downloader: Default::default(), jlc_downloader: Default::default(),
db_browser: Default::default(), db_browser: Default::default(),
part_viewer: Default::default(), part_viewer: Default::default(),
@ -52,6 +60,7 @@ impl Default for MainWindow {
pub fn main_window() { pub fn main_window() {
let _ = iced::application(MainWindow::default, MainWindow::update, MainWindow::view) let _ = iced::application(MainWindow::default, MainWindow::update, MainWindow::view)
.theme(MainWindow::theme)
.default_font(iced::Font::with_name("微软雅黑")) .default_font(iced::Font::with_name("微软雅黑"))
.title(MainWindow::title) .title(MainWindow::title)
.run(); .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 { impl MainWindow {
fn title(&self) -> String { fn title(&self) -> String {
self.title.clone() self.title.clone()
} }
fn theme(&self) -> Theme {
self.theme.clone()
}
fn create_tab_btn(&self, tab: TabId) -> Element<'_, MainWindowMsg> { fn create_tab_btn(&self, tab: TabId) -> Element<'_, MainWindowMsg> {
let bstyle = if self.curr_tab == tab { let bstyle = if self.curr_tab == tab {
btn_active_style button::danger
} else { } else {
btn_deactive_style button::primary
}; };
let txt = format!("{tab}"); let txt = format!("{tab}");
@ -125,7 +125,10 @@ impl MainWindow {
println!("Process the msg: {msg:?}"); println!("Process the msg: {msg:?}");
match msg { match msg {
MainWindowMsg::ThemeChanged(theme) => { 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) => { MainWindowMsg::TitleChanged(title) => {
self.title = title; self.title = title;

View File

@ -47,6 +47,27 @@ pub fn set_step_dir(path: &str) -> Result<(), anyhow::Error> {
Ok(()) 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", &registry::Data::U32(c))?;
Ok(())
}
#[allow(dead_code)]
pub fn get_curr_theme() -> Result<u32, anyhow::Error> {
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)] #[allow(dead_code)]
pub fn set_curr_page(c: u32) -> Result<(), anyhow::Error> { pub fn set_curr_page(c: u32) -> Result<(), anyhow::Error> {
let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?; let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?;

View File

@ -35,6 +35,10 @@ unsafe extern "C" {
/// returns 1 if valid DSA public key provided, 0 otherwise. /// returns 1 if valid DSA public key provided, 0 otherwise.
pub fn win_sparkle_set_dsa_pub_pem(dsa_pub_pem: *const i8) -> i32; 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. /// 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. /// This sets the path where WinSparkle will store its settings in the registry.