diff --git a/Cargo.toml b/Cargo.toml index 4ebdbf3..a75dc77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,33 @@ version = "0.1.0" edition = "2024" [dependencies] +iced = { git = "https://github.com/iced-rs/iced.git", features = [ + "debug", + "advanced", + +] } tokio = { version = "1.45.1", features = ["full"] } -iced = { git = "https://github.com/iced-rs/iced.git" } -iced_aw = { git = "https://github.com/iced-rs/iced_aw.git" } +iced_aw = { git = "https://github.com/iced-rs/iced_aw.git", features = [ + "badge", + "card", + "number_input", + "date_picker", + "color_picker", + "grid", + "tab_bar", + "tabs", + "time_picker", + "slide_bar", + "wrap", + "selection_list", + "quad", + "context_menu", + "spinner", + "drop_down", + "menu", + "sidebar", + "labeled_frame", +] } reqwest = "0.12.20" tracing-subscriber = { version = "0.3.19", features = [ "chrono", @@ -24,3 +48,4 @@ registry = "1.3.0" anyhow = { version = "1.0.98", features = ["backtrace"] } log = "0.4.27" env_logger = "0.11.8" +iced_fonts = { version = "0.2.1", features = ["full"] } diff --git a/fonts/LICENSE.txt b/fonts/LICENSE.txt new file mode 100644 index 0000000..9a34ddc --- /dev/null +++ b/fonts/LICENSE.txt @@ -0,0 +1,10 @@ +Font license info + + +## Font Awesome + + Copyright (C) 2016 by Dave Gandy + + Author: Dave Gandy + License: SIL () + Homepage: http://fortawesome.github.com/Font-Awesome/ diff --git a/fonts/config.json b/fonts/config.json new file mode 100644 index 0000000..5859216 --- /dev/null +++ b/fonts/config.json @@ -0,0 +1,40 @@ +{ + "name": "icons", + "css_prefix_text": "icon-", + "css_use_suffix": false, + "hinting": true, + "units_per_em": 1000, + "ascent": 850, + "glyphs": [ + { + "uid": "8b80d36d4ef43889db10bc1f0dc9a862", + "css": "user", + "code": 59392, + "src": "fontawesome" + }, + { + "uid": "d73eceadda1f594cec0536087539afbf", + "css": "heart", + "code": 59393, + "src": "fontawesome" + }, + { + "uid": "1ee2aeb352153a403df4b441a8bc9bda", + "css": "calc", + "code": 61932, + "src": "fontawesome" + }, + { + "uid": "98687378abd1faf8f6af97c254eb6cd6", + "css": "cog-alt", + "code": 59394, + "src": "fontawesome" + }, + { + "uid": "5211af474d3a9848f67f945e2ccaf143", + "css": "cancel", + "code": 59395, + "src": "fontawesome" + } + ] +} diff --git a/fonts/icons.ttf b/fonts/icons.ttf new file mode 100644 index 0000000..abfc4eb Binary files /dev/null and b/fonts/icons.ttf differ diff --git a/src/main.rs b/src/main.rs index 79c39d0..efc50fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,6 @@ mod ui; mod utils; mod winsparkle; fn main() { - #[cfg(debug_assertions)] tracing_subscriber::fmt::init(); + ui::main_window::main_window(); } diff --git a/src/ui/home_page.rs b/src/ui/home_page.rs index e69de29..e48d136 100644 --- a/src/ui/home_page.rs +++ b/src/ui/home_page.rs @@ -0,0 +1,52 @@ +use iced::{ + Alignment, Element, + alignment::{Horizontal, Vertical}, + widget::{Column, Container}, +}; + +use crate::ui::main_window::{MainWindowMsg, TabFrame}; +pub struct HomePage {} + +impl Default for HomePage { + fn default() -> Self { + Self {} + } +} +impl HomePage { + pub fn update(&mut self, msg: HomePageMsg) { + match msg { + HomePageMsg::Nothing => { + println!("HomePage::Message::Nothing"); + } + } + } +} + +#[derive(Debug, Clone)] +pub enum HomePageMsg { + Nothing, +} + +impl TabFrame for HomePage { + type Message = MainWindowMsg; + + fn title(&self) -> String { + "HomePage".to_owned() + } + + fn tab_label(&self) -> iced_aw::TabLabel { + iced_aw::TabLabel::Text("HomePage".to_owned()) + } + + fn container(&self) -> iced::Element<'_, Self::Message> { + let content: Element<'_, HomePageMsg> = Container::new( + Column::new() + .align_x(Alignment::Center) + .push(iced::widget::button("Homepage Button").on_press(HomePageMsg::Nothing)), + ) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .into(); + content.map(MainWindowMsg::HomePageMsg) + } +} diff --git a/src/ui/jlc_downloader.rs b/src/ui/jlc_downloader.rs index e69de29..526f4a8 100644 --- a/src/ui/jlc_downloader.rs +++ b/src/ui/jlc_downloader.rs @@ -0,0 +1,13 @@ +use iced::{ + Alignment, Element, + alignment::{Horizontal, Vertical}, + widget::{Column, Container}, +}; + +use crate::ui::main_window::{MainWindowMsg, TabFrame}; + +pub struct JlcDownloader {} + +pub enum JlcDownloaderMsg { + Nothing, +} diff --git a/src/ui/main_window.rs b/src/ui/main_window.rs index 8b13789..3c5fbc8 100644 --- a/src/ui/main_window.rs +++ b/src/ui/main_window.rs @@ -1 +1,119 @@ +use super::db_browser; +use super::home_page; +use super::jlc_downloader; +use super::part_viewer; +use iced::widget as w; +use iced::{ + Element, Length, + alignment::{Horizontal, Vertical}, + widget::{Column, Container, Text}, +}; +use iced_aw::Tabs; +use iced_aw::iced_fonts; +struct MainWindow { + title: String, + theme: iced::Theme, + curr_tab: TabId, + tab_pos: iced_aw::tabs::TabBarPosition, + home_page: home_page::HomePage, +} +impl Default for MainWindow { + fn default() -> Self { + Self { + title: Default::default(), + theme: Default::default(), + curr_tab: Default::default(), + tab_pos: iced_aw::tabs::TabBarPosition::Top, + home_page: Default::default(), + } + } +} + +const ICON_BYTES: &[u8] = include_bytes!("./../../fonts/icons.ttf"); +const ICON: iced::Font = iced::Font::with_name("icons"); + +pub fn main_window() { + iced::application(MainWindow::default, MainWindow::update, MainWindow::view) + .title(MainWindow::title) + .font(iced_fonts::REQUIRED_FONT_BYTES) + .font(ICON_BYTES) + .run(); +} + +#[derive(Debug, Clone)] +pub enum MainWindowMsg { + TabSelected(TabId), + TabClosed(TabId), + ThemeChanged(iced::Theme), + TitleChanged(String), + HomePageMsg(home_page::HomePageMsg), + Nothing, +} + +#[derive(Debug, Default, Clone, PartialEq, Eq)] +enum TabId { + #[default] + HomePage, + JlcDownloader, + DbBrowser, + PartViewer, +} + +impl MainWindow { + fn title(&self) -> String { + self.title.clone() + } + fn update(&mut self, msg: MainWindowMsg) { + match msg { + MainWindowMsg::ThemeChanged(theme) => { + self.theme = theme; + } + MainWindowMsg::TitleChanged(title) => { + self.title = title; + } + MainWindowMsg::Nothing => { + println!("Nothing"); + iced::debug::time("Test".to_owned()); + } + MainWindowMsg::HomePageMsg(message) => { + self.home_page.update(message); + } + MainWindowMsg::TabSelected(tab_id) => { + self.curr_tab = tab_id; + } + MainWindowMsg::TabClosed(tab_id) => todo!(), + } + } + fn view(&self) -> Element<'_, MainWindowMsg> { + let t = Tabs::new(MainWindowMsg::TabSelected) + .tab_icon_position(iced_aw::tabs::Position::Left) + .on_close(MainWindowMsg::TabClosed) + .push( + TabId::HomePage, + self.home_page.tab_label(), + self.home_page.view(), + ) + .set_active_tab(&self.curr_tab) + .icon_font(ICON) + .tab_bar_style(Box::new(iced_aw::style::tab_bar::primary)) + .tab_bar_position(self.tab_pos.clone()); + w::button("ClickMe").on_press(MainWindowMsg::Nothing).into() + } +} + +pub trait TabFrame { + type Message; + fn title(&self) -> String; + fn tab_label(&self) -> iced_aw::TabLabel; + fn container(&self) -> Element<'_, Self::Message>; + fn view(&self) -> Element<'_, Self::Message> { + w::Container::new(self.container()) + .width(Length::Fill) + .height(Length::Fill) + .align_x(Horizontal::Left) + .align_y(Vertical::Top) + .padding(5) + .into() + } +} diff --git a/src/utils/app_settings.rs b/src/utils/app_settings.rs index 7023c96..6f1a849 100644 --- a/src/utils/app_settings.rs +++ b/src/utils/app_settings.rs @@ -1,12 +1,14 @@ use registry::Security; const APP_REG_PATH: &str = r"Software\HardwareToolkit\"; +#[allow(dead_code)] pub fn get_lib_dir() -> Result { let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?; let path = reg.value("lib_path")?; Ok(path.to_string()) } +#[allow(dead_code)] pub fn set_lib_dir(path: &str) -> Result<(), anyhow::Error> { let path = utfx::U16CString::from_str(path)?; let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?; @@ -14,12 +16,14 @@ pub fn set_lib_dir(path: &str) -> Result<(), anyhow::Error> { Ok(()) } +#[allow(dead_code)] pub fn get_odbc_name() -> Result { let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?; let name = reg.value("odbc_name")?; Ok(name.to_string()) } +#[allow(dead_code)] pub fn set_odbc_name(name: &str) -> Result<(), anyhow::Error> { let name = utfx::U16CString::from_str(name)?; registry::Hive::CurrentUser @@ -28,12 +32,14 @@ pub fn set_odbc_name(name: &str) -> Result<(), anyhow::Error> { Ok(()) } +#[allow(dead_code)] pub fn get_step_dir() -> Result { let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?; let path = reg.value("step_path")?; Ok(path.to_string()) } +#[allow(dead_code)] pub fn set_step_dir(path: &str) -> Result<(), anyhow::Error> { let path = utfx::U16CString::from_str(path)?; let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?; @@ -41,11 +47,14 @@ pub fn set_step_dir(path: &str) -> Result<(), anyhow::Error> { Ok(()) } +#[allow(dead_code)] pub fn set_curr_page(c: u32) -> Result<(), anyhow::Error> { let reg = registry::Hive::CurrentUser.create(APP_REG_PATH, Security::AllAccess)?; reg.set_value("curr_page", ®istry::Data::U32(c))?; Ok(()) } + +#[allow(dead_code)] pub fn get_curr_page() -> Result { let reg = registry::Hive::CurrentUser.open(APP_REG_PATH, Security::AllAccess)?; match reg.value("curr_page")? { @@ -59,6 +68,7 @@ pub fn get_curr_page() -> Result { Ok(0) } +#[allow(dead_code)] #[cfg(test)] mod app_settings_test { use crate::utils::app_settings::{get_step_dir, set_step_dir}; diff --git a/src/winsparkle/mod.rs b/src/winsparkle/mod.rs index d0bf91f..e69de29 100644 --- a/src/winsparkle/mod.rs +++ b/src/winsparkle/mod.rs @@ -1 +0,0 @@ -pub mod winsparkle;