From d21a2500813b3fea4892fff9dbbf572e37b5d70d Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 8 Feb 2026 14:47:28 +0000 Subject: start task-085 --- requirements/kanban.md | 3 +-- requirements/tasks/task-085.md | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/requirements/kanban.md b/requirements/kanban.md index 6ebb1c8..5e09287 100644 --- a/requirements/kanban.md +++ b/requirements/kanban.md @@ -4,8 +4,7 @@ | -------- | -------- | -------- | | | | epic-000 | | ======== | ======== | ======== | -| | task-085 | | -| | task-001 | | +| | task-001 | task-085 | | | task-064 | | | | task-086 | | | | task-030 | | diff --git a/requirements/tasks/task-085.md b/requirements/tasks/task-085.md index 1e1e66d..04267d4 100644 --- a/requirements/tasks/task-085.md +++ b/requirements/tasks/task-085.md @@ -11,6 +11,8 @@ It should have these columns: - Quantity - Balance +Status: doing + Epic: epic-000 Source: ui-designs/desktop-views, req-048, task-001 -- cgit v1.2.3 From d5f1554949321f2ebfda89efe39b0477a6ff2e55 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 8 Feb 2026 15:15:24 +0000 Subject: task-085: transactions view has transactions --- schist_desktop_gui/src/gui/components.rs | 2 + .../src/gui/components/account_navigation_entry.rs | 34 +++++++ .../src/gui/components/transactions_view.rs | 106 +++++++++------------ .../src/gui/screens/main_screen/main_screen.rs | 2 +- 4 files changed, 83 insertions(+), 61 deletions(-) create mode 100644 schist_desktop_gui/src/gui/components/account_navigation_entry.rs diff --git a/schist_desktop_gui/src/gui/components.rs b/schist_desktop_gui/src/gui/components.rs index bb5590f..606c418 100644 --- a/schist_desktop_gui/src/gui/components.rs +++ b/schist_desktop_gui/src/gui/components.rs @@ -1,3 +1,4 @@ +mod account_navigation_entry; pub mod balances_view; pub mod bucket_navigation_entry; pub mod buckets_view; @@ -7,6 +8,7 @@ pub mod panel; pub mod text; pub mod transactions_view; +pub use account_navigation_entry::AccountNavigationEntry; pub use balances_view::BalancesView; pub use bucket_navigation_entry::BucketNavigationEntry; pub use buckets_view::BucketsView; diff --git a/schist_desktop_gui/src/gui/components/account_navigation_entry.rs b/schist_desktop_gui/src/gui/components/account_navigation_entry.rs new file mode 100644 index 0000000..6a582a7 --- /dev/null +++ b/schist_desktop_gui/src/gui/components/account_navigation_entry.rs @@ -0,0 +1,34 @@ +use iced::Element; +use schist_models::Account; + +use crate::{ + gui::components::{navigation, Text}, + impl_focusable, +}; + +#[derive(Clone, Debug, PartialEq)] +pub struct AccountNavigationEntry { + pub account: Account, + is_focused: bool, +} + +impl AccountNavigationEntry { + pub fn new(account: Account) -> Self { + Self { + account, + is_focused: false, + } + } +} + +impl<'a> From<&'a AccountNavigationEntry> + for Element<'a, navigation::Message> +{ + fn from(account_navigation_entry: &'a AccountNavigationEntry) -> Self { + Text::default(&account_navigation_entry.account.name) + .highlight_maybe(account_navigation_entry.is_focused) + .into() + } +} + +impl_focusable!(AccountNavigationEntry); diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 1cb569c..59d7ae3 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -1,26 +1,28 @@ +use std::collections::HashMap; + use iced::{ alignment, widget::{column, row, Container}, Element, Length, }; -use schist_models::Account; +use itertools::Itertools; +use schist_models::{Account, Transaction}; use crate::{ - gui::components::{navigation, Navigation, Text}, + gui::components::{navigation, AccountNavigationEntry, Navigation, Text}, style::SPACING_LG, traits::{Component, Viewable}, }; #[derive(Clone, Debug)] pub struct TransactionsView { - accounts: Vec, - greeting: String, - navigation: Navigation, + navigation: Navigation, + transactions_by_account_id: HashMap>, } #[derive(Clone, Debug)] pub enum Message { - NavigationMessage(navigation::Message), + NavigationMessage(navigation::Message), SelectNextTransaction, SelectPrevTransaction, SetAccounts(Vec), @@ -31,13 +33,20 @@ pub enum Action { } impl TransactionsView { - pub fn new(accounts: Vec, greeting: &str) -> Self { - let account_names = view_account_names(accounts.clone()); - let navigation = Navigation::new(account_names.clone().first().cloned(), account_names); + pub fn new(accounts: Vec, transactions: Vec) -> Self { + let account_navigation_entries: Vec = accounts + .into_iter() + .map(AccountNavigationEntry::new) + .collect(); + let navigation = Navigation::new( + account_navigation_entries.first().cloned(), + account_navigation_entries, + ); Self { - accounts: accounts, - greeting: greeting.to_owned(), navigation: navigation, + transactions_by_account_id: transactions + .into_iter() + .into_group_map_by(|t| t.account_id), } } } @@ -45,7 +54,20 @@ impl TransactionsView { impl<'a> Viewable<'a, Message> for TransactionsView { fn view(&'a self) -> Element<'a, Message> { let navigation = self.navigation.view().map(Message::NavigationMessage); - let main_content = column![Text::default(&self.greeting).as_element()]; + let main_content = column![ + Text::default("Hello, transactions!").as_element(), + Text::default(&format!( + "{} transactions in this account.", + self.navigation.active_option.clone().map_or( + 0, + |AccountNavigationEntry { account, .. }| self + .transactions_by_account_id + .get(&account.id) + .map_or(0, |transactions| transactions.len()) + ) + )) + .as_element(), + ]; row![ Container::new(navigation).width(Length::FillPortion(1)), Container::new(main_content).width(Length::FillPortion(3)), @@ -61,62 +83,26 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { fn update(&mut self, message: Message) -> Action { match message { Message::NavigationMessage(message) => { - match self.navigation.update(message) { - navigation::Action::ActivateOption(group_name) - | navigation::Action::SelectOption(group_name) => { - self.greeting = make_greeting(group_name); - Action::None - } - navigation::Action::None => Action::None, - }; + self.navigation.update(message); Action::None } Message::SetAccounts(accounts) => { - self.accounts = accounts.clone(); - match self - .navigation - .update(navigation::Message::SetOptions(view_account_names( - accounts, - ))) { - navigation::Action::ActivateOption(option) - | navigation::Action::SelectOption(option) => { - self.greeting = make_greeting(option); - Action::None - } - navigation::Action::None => Action::None, - } + let account_navigation_entries: Vec = accounts + .into_iter() + .map(AccountNavigationEntry::new) + .collect(); + self.navigation + .update(navigation::Message::SetOptions(account_navigation_entries)); + Action::None } Message::SelectNextTransaction => { - match self.navigation.update(navigation::Message::SelectNext) { - navigation::Action::ActivateOption(option) - | navigation::Action::SelectOption(option) => { - self.greeting = make_greeting(option); - Action::None - } - navigation::Action::None => Action::None, - } + self.navigation.update(navigation::Message::SelectNext); + Action::None } Message::SelectPrevTransaction => { - match self.navigation.update(navigation::Message::SelectPrev) { - navigation::Action::ActivateOption(option) - | navigation::Action::SelectOption(option) => { - self.greeting = make_greeting(option); - Action::None - } - navigation::Action::None => Action::None, - } + self.navigation.update(navigation::Message::SelectPrev); + Action::None } } } } - -fn make_greeting(account_name: Text) -> String { - format!("Hello, {} account!", account_name.content) -} - -fn view_account_names(accounts: Vec) -> Vec { - accounts - .iter() - .map(|acc| Text::new(acc.name.as_str())) - .collect() -} diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 5ed4b30..e526dc5 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -197,7 +197,7 @@ impl MainScreen { balances_view: BalancesView::new(Vec::new()), buckets: Vec::new(), buckets_view: BucketsView::new(Vec::new(), "Hello, buckets!"), - transactions_view: TransactionsView::new(Vec::new(), "Hello, transactions!"), + transactions_view: TransactionsView::new(Vec::new(), Vec::new()), active_view: View::Balances, view_navigation: Navigation::new(Some(View::Balances), View::views()), } -- cgit v1.2.3 From 5b592ca899ad5a9090c1acd5776221f79e44d121 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 8 Feb 2026 15:16:13 +0000 Subject: task-085: rename SelectNextTransaction -> SelectNext Account as this was always a mis-nomer --- schist_desktop_gui/src/gui/components/transactions_view.rs | 8 ++++---- schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 59d7ae3..d28629d 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -23,8 +23,8 @@ pub struct TransactionsView { #[derive(Clone, Debug)] pub enum Message { NavigationMessage(navigation::Message), - SelectNextTransaction, - SelectPrevTransaction, + SelectNextAccount, + SelectPrevAccount, SetAccounts(Vec), } @@ -95,11 +95,11 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { .update(navigation::Message::SetOptions(account_navigation_entries)); Action::None } - Message::SelectNextTransaction => { + Message::SelectNextAccount => { self.navigation.update(navigation::Message::SelectNext); Action::None } - Message::SelectPrevTransaction => { + Message::SelectPrevAccount => { self.navigation.update(navigation::Message::SelectPrev); Action::None } diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index e526dc5..0e8d084 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -130,7 +130,7 @@ impl<'a> Component<'a, Message, Action> for MainScreen { } View::Transactions => { self.transactions_view - .update(transactions_view::Message::SelectNextTransaction); + .update(transactions_view::Message::SelectNextAccount); Action::None } }, @@ -147,7 +147,7 @@ impl<'a> Component<'a, Message, Action> for MainScreen { } View::Transactions => { self.transactions_view - .update(transactions_view::Message::SelectPrevTransaction); + .update(transactions_view::Message::SelectPrevAccount); Action::None } }, -- cgit v1.2.3 From b9244f6049c685c2b983632359676521506f8772 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 8 Feb 2026 15:22:50 +0000 Subject: task-085: fetches transactions from database --- schist_desktop_gui/src/gui.rs | 19 +++++++++++++++++-- .../src/gui/components/transactions_view.rs | 10 ++++++++++ .../src/gui/screens/main_screen/main_screen.rs | 9 ++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/schist_desktop_gui/src/gui.rs b/schist_desktop_gui/src/gui.rs index 26f147b..9648ff0 100644 --- a/schist_desktop_gui/src/gui.rs +++ b/schist_desktop_gui/src/gui.rs @@ -7,8 +7,10 @@ use std::{path::PathBuf, str::FromStr}; use diesel::SqliteConnection; use iced::{Element, Task}; -use schist_models::{Account, Bucket}; -use schist_queries::{accounts::get_all_accounts, buckets::get_all_buckets}; +use schist_models::{Account, Bucket, Transaction}; +use schist_queries::{ + accounts::get_all_accounts, buckets::get_all_buckets, transactions::get_all_transactions, +}; use crate::{ cache::{put_to_cache, remove_from_cache, CACHE_KEYS}, @@ -32,6 +34,7 @@ pub enum Message { MainScreenMessage(main_screen::Message), RefetchedAccounts(FetchResult>), RefetchedBuckets(FetchResult>), + RefetchedTransactions(FetchResult>), } pub type FetchResult = std::result::Result; @@ -185,6 +188,16 @@ impl Gui { } iced::Task::none() } + Message::RefetchedTransactions(transactions) => { + match transactions { + Ok(transactions) => { + self.main_screen + .update(main_screen::Message::SetTransactions(transactions)); + } + Err(err) => println!("Failed to get transactions: {:?}", err.message), + }; + Task::none() + } Message::FilesScreenMessage(message) => self.update_files_screen(message), Message::FailedToCreateFile(err) => { self.update_files_screen(files_screen::Message::ReportFailedToCreateFile(err)) @@ -226,6 +239,7 @@ impl Gui { ) -> Task { let buckets = get_all_buckets(&mut connection).map_err(FetchError::new); let accounts = get_all_accounts(&mut connection).map_err(FetchError::new); + let transactions = get_all_transactions(&mut connection).map_err(FetchError::new); self.connection = Some(connection); self.active_screen = Screen::MainScreen; if let Some(path) = path.to_str() { @@ -236,6 +250,7 @@ impl Gui { iced::Task::batch(vec![ self.update(Message::RefetchedBuckets(buckets)), self.update(Message::RefetchedAccounts(accounts)), + self.update(Message::RefetchedTransactions(transactions)), ]) } diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index d28629d..6f2ad44 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -26,6 +26,7 @@ pub enum Message { SelectNextAccount, SelectPrevAccount, SetAccounts(Vec), + SetTransactions(Vec), } pub enum Action { @@ -86,6 +87,7 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { self.navigation.update(message); Action::None } + Message::SetAccounts(accounts) => { let account_navigation_entries: Vec = accounts .into_iter() @@ -95,10 +97,18 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { .update(navigation::Message::SetOptions(account_navigation_entries)); Action::None } + + Message::SetTransactions(transactions) => { + self.transactions_by_account_id = + transactions.into_iter().into_group_map_by(|t| t.account_id); + Action::None + } + Message::SelectNextAccount => { self.navigation.update(navigation::Message::SelectNext); Action::None } + Message::SelectPrevAccount => { self.navigation.update(navigation::Message::SelectPrev); Action::None diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 0e8d084..0a2c355 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -4,7 +4,7 @@ use iced::{ widget::{row, Container}, Element, Length, }; -use schist_models::{Account, Bucket}; +use schist_models::{Account, Bucket, Transaction}; use crate::{ gui::components::{ @@ -36,6 +36,7 @@ pub enum Message { SelectView(View), SetAccounts(Vec), SetBuckets(Vec), + SetTransactions(Vec), ViewNavigationMessage(navigation::Message), } @@ -118,6 +119,12 @@ impl<'a> Component<'a, Message, Action> for MainScreen { Action::None } + Message::SetTransactions(transactions) => { + self.transactions_view + .update(transactions_view::Message::SetTransactions(transactions)); + Action::None + } + Message::NextItem => match self.active_view { View::Balances => { self.balances_view -- cgit v1.2.3 From 170c1a58ebd8b6ff1dceb5f46146f76b601c91ad Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 8 Feb 2026 15:49:01 +0000 Subject: task-085: factor out Viewable impl for TransactionsView --- .../src/gui/components/transactions_view.rs | 40 +++------------------ .../transactions_view/view_transactions_view.rs | 41 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 36 deletions(-) create mode 100644 schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 6f2ad44..f39b522 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -1,17 +1,13 @@ +mod view_transactions_view; + use std::collections::HashMap; -use iced::{ - alignment, - widget::{column, row, Container}, - Element, Length, -}; use itertools::Itertools; use schist_models::{Account, Transaction}; use crate::{ - gui::components::{navigation, AccountNavigationEntry, Navigation, Text}, - style::SPACING_LG, - traits::{Component, Viewable}, + gui::components::{navigation, AccountNavigationEntry, Navigation}, + traits::Component, }; #[derive(Clone, Debug)] @@ -52,34 +48,6 @@ impl TransactionsView { } } -impl<'a> Viewable<'a, Message> for TransactionsView { - fn view(&'a self) -> Element<'a, Message> { - let navigation = self.navigation.view().map(Message::NavigationMessage); - let main_content = column![ - Text::default("Hello, transactions!").as_element(), - Text::default(&format!( - "{} transactions in this account.", - self.navigation.active_option.clone().map_or( - 0, - |AccountNavigationEntry { account, .. }| self - .transactions_by_account_id - .get(&account.id) - .map_or(0, |transactions| transactions.len()) - ) - )) - .as_element(), - ]; - row![ - Container::new(navigation).width(Length::FillPortion(1)), - Container::new(main_content).width(Length::FillPortion(3)), - ] - .align_y(alignment::Vertical::Center) - .height(Length::Fill) - .spacing(SPACING_LG) - .into() - } -} - impl<'a> Component<'a, Message, Action> for TransactionsView { fn update(&mut self, message: Message) -> Action { match message { diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs new file mode 100644 index 0000000..37b6655 --- /dev/null +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -0,0 +1,41 @@ +use iced::{ + alignment, + widget::{column, row, Container}, + Element, Length, +}; + +use crate::{ + gui::components::{AccountNavigationEntry, Text}, + style::SPACING_LG, + traits::Viewable, +}; + +use super::{Message, TransactionsView}; + +impl<'a> Viewable<'a, Message> for TransactionsView { + fn view(&'a self) -> Element<'a, Message> { + let navigation = self.navigation.view().map(Message::NavigationMessage); + let main_content = column![ + Text::default("Hello, transactions!").as_element(), + Text::default(&format!( + "{} transactions in this account.", + self.navigation.active_option.clone().map_or( + 0, + |AccountNavigationEntry { account, .. }| self + .transactions_by_account_id + .get(&account.id) + .map_or(0, |transactions| transactions.len()) + ) + )) + .as_element(), + ]; + row![ + Container::new(navigation).width(Length::FillPortion(1)), + Container::new(main_content).width(Length::FillPortion(3)), + ] + .align_y(alignment::Vertical::Center) + .height(Length::Fill) + .spacing(SPACING_LG) + .into() + } +} -- cgit v1.2.3 From 97b413aa5962bded37dedb380034fa7b97bdc06c Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 8 Feb 2026 20:26:30 +0000 Subject: task-085: display transaction data in tables --- schist_desktop_gui/src/gui/components.rs | 2 + schist_desktop_gui/src/gui/components/table.rs | 42 +++++++++++ .../src/gui/components/table/view_table.rs | 48 ++++++++++++ schist_desktop_gui/src/gui/components/text.rs | 31 ++++++++ .../src/gui/components/transactions_view.rs | 87 +++++++++++++++++----- .../transactions_view/view_transactions_view.rs | 27 ++----- .../src/gui/screens/main_screen/main_screen.rs | 2 +- 7 files changed, 199 insertions(+), 40 deletions(-) create mode 100644 schist_desktop_gui/src/gui/components/table.rs create mode 100644 schist_desktop_gui/src/gui/components/table/view_table.rs diff --git a/schist_desktop_gui/src/gui/components.rs b/schist_desktop_gui/src/gui/components.rs index 606c418..ec91951 100644 --- a/schist_desktop_gui/src/gui/components.rs +++ b/schist_desktop_gui/src/gui/components.rs @@ -5,6 +5,7 @@ pub mod buckets_view; pub mod button; pub mod navigation; pub mod panel; +pub mod table; pub mod text; pub mod transactions_view; @@ -15,5 +16,6 @@ pub use buckets_view::BucketsView; pub use button::{button, panel_button}; pub use navigation::Navigation; pub use panel::Panel; +pub use table::Table; pub use text::Text; pub use transactions_view::TransactionsView; diff --git a/schist_desktop_gui/src/gui/components/table.rs b/schist_desktop_gui/src/gui/components/table.rs new file mode 100644 index 0000000..4c6d810 --- /dev/null +++ b/schist_desktop_gui/src/gui/components/table.rs @@ -0,0 +1,42 @@ +use std::collections::HashMap; + +mod view_table; + +#[derive(Clone, Debug, Default)] +pub struct Table +where + Ix: Clone + std::fmt::Debug, +{ + pub cols: Vec>, + pub rows: Vec>, +} + +#[derive(Clone, Debug)] +pub enum Value { + String(String), + Currency(i32), +} + +#[derive(Clone, Debug)] +pub struct Column +where + Ix: Clone + std::fmt::Debug, +{ + pub index: Ix, + pub name: String, +} + +impl Column +where + Ix: Clone + std::fmt::Debug, +{ + pub fn new(index: Ix, name: &str) -> Self { + Self { + index, + name: name.to_string(), + } + } +} + +#[derive(Clone, Debug)] +pub enum Message {} diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs new file mode 100644 index 0000000..1d5f10b --- /dev/null +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -0,0 +1,48 @@ +use std::{fmt::Debug, hash::Hash}; + +use iced::widget::{column, container, row}; + +use crate::{gui::components::Text, style::SPACING_MD, traits::Viewable}; + +use super::{Message, Table, Value}; + +impl<'a, Ix> Viewable<'a, Message> for Table +where + Ix: Clone + Debug + Eq + Hash, +{ + fn view(&'a self) -> iced::Element<'a, Message> { + let headers = row(self.cols.iter().map(|col| { + container(Text::default(&col.name)) + .width(iced::Length::FillPortion(1)) + .into() + })) + .padding(SPACING_MD); + let rows = column(self.rows.iter().map(|row_data| { + row(self.cols.iter().map(|col| { + container( + row_data + .get(&col.index) + .map(|datum| match datum { + Value::String(text) => Text::default(text).weak(), + Value::Currency(amount) => format_currency(*amount), + }) + .unwrap_or_else(|| Text::default("")), + ) + .width(iced::Length::FillPortion(1)) + .into() + })) + .spacing(SPACING_MD) + .into() + })); + column![headers, rows].into() + } +} + +fn format_currency(amount: i32) -> Text { + let text = if amount >= 0 { + format!(" {} · {} ", amount / 100, amount % 100) + } else { + format!("({} · {})", -amount / 100, -amount % 100) + }; + Text::default(&text).align_right().width(iced::Length::Fill) +} diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index d171043..0d0c8c4 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -5,12 +5,20 @@ use crate::{impl_focusable, style::*}; #[derive(Clone, Debug, PartialEq)] pub struct Text { pub content: String, + align: Alignment, colour: Option, size: Option, strength: Option, + width: iced::Length, is_focused: bool, } +#[derive(Clone, Debug, PartialEq)] +enum Alignment { + Left, + Right, +} + #[derive(Clone, Debug, PartialEq)] enum Colour { Danger, @@ -33,20 +41,24 @@ enum Size { impl Text { pub fn default(content: &str) -> Self { Self { + align: Alignment::Left, content: String::from(content), colour: Some(Colour::Primary), size: Some(Size::Base), strength: Some(Strength::Base), is_focused: false, + width: iced::Length::Shrink, } } pub fn new(content: &str) -> Self { Self { + align: Alignment::Left, content: String::from(content), colour: None, size: None, strength: None, + width: iced::Length::Shrink, is_focused: false, } } @@ -86,6 +98,20 @@ impl Text { self.clone() } } + + pub fn align_right(&self) -> Self { + Self { + align: Alignment::Right, + ..self.clone() + } + } + + pub fn width(&self, width: iced::Length) -> Self { + Self { + width, + ..self.clone() + } + } } impl<'a, Message> From for iced::Element<'a, Message> { @@ -109,6 +135,11 @@ where Some(Size::Small) => TEXT_SIZE_SM, Some(Size::Base) | None => TEXT_SIZE_BASE, }) + .align_x(match &text.borrow().align { + Alignment::Left => iced::alignment::Horizontal::Left, + Alignment::Right => iced::alignment::Horizontal::Right, + }) + .width(text.borrow().width) .style(move |theme: &iced::Theme| iced::widget::text::Style { color: match ( &text.borrow().borrow().colour, diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index f39b522..8e076f1 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -6,13 +6,14 @@ use itertools::Itertools; use schist_models::{Account, Transaction}; use crate::{ - gui::components::{navigation, AccountNavigationEntry, Navigation}, + gui::components::{navigation, table, AccountNavigationEntry, Navigation, Table}, traits::Component, }; #[derive(Clone, Debug)] pub struct TransactionsView { navigation: Navigation, + table: Table, transactions_by_account_id: HashMap>, } @@ -23,6 +24,7 @@ pub enum Message { SelectPrevAccount, SetAccounts(Vec), SetTransactions(Vec), + TableMessage(table::Message), } pub enum Action { @@ -30,57 +32,106 @@ pub enum Action { } impl TransactionsView { - pub fn new(accounts: Vec, transactions: Vec) -> Self { + pub fn new(accounts: &[Account], transactions: &[Transaction]) -> Self { let account_navigation_entries: Vec = accounts - .into_iter() + .iter() + .cloned() .map(AccountNavigationEntry::new) .collect(); let navigation = Navigation::new( account_navigation_entries.first().cloned(), account_navigation_entries, ); - Self { + let mut transactions_view = Self { navigation: navigation, + table: Table::default(), transactions_by_account_id: transactions .into_iter() + .cloned() .into_group_map_by(|t| t.account_id), - } + }; + transactions_view.refresh_table(); + transactions_view + } + + fn refresh_table(&mut self) { + self.table = + Table { + cols: vec![ + table::Column::new(0, "Date"), + table::Column::new(1, "Bucket"), + table::Column::new(2, "Payee"), + table::Column::new(3, "Quantity"), + table::Column::new(4, "Balance"), + ], + rows: self.navigation.active_option.clone().map_or_else( + Vec::new, + |AccountNavigationEntry { account, .. }| { + self.transactions_by_account_id + .get(&account.id) + .cloned() + .unwrap_or_else(Vec::new) + .iter() + .map(|t| { + HashMap::from([ + (0, table::Value::String(t.date.to_string())), + ( + 1, + table::Value::String(t.bucket_id.map_or_else( + || String::from("None"), + |id| id.to_string(), + )), + ), + (2, table::Value::String(t.counterparty.clone())), + (3, table::Value::Currency(t.amount)), + (4, table::Value::String(String::from("TODO"))), + ]) + }) + .collect() + }, + ), + }; } } impl<'a> Component<'a, Message, Action> for TransactionsView { fn update(&mut self, message: Message) -> Action { match message { - Message::NavigationMessage(message) => { - self.navigation.update(message); - Action::None - } + Message::NavigationMessage(message) => self.update_navigation(message), Message::SetAccounts(accounts) => { let account_navigation_entries: Vec = accounts .into_iter() .map(AccountNavigationEntry::new) .collect(); - self.navigation - .update(navigation::Message::SetOptions(account_navigation_entries)); - Action::None + self.update_navigation(navigation::Message::SetOptions(account_navigation_entries)) } Message::SetTransactions(transactions) => { self.transactions_by_account_id = transactions.into_iter().into_group_map_by(|t| t.account_id); + self.refresh_table(); Action::None } - Message::SelectNextAccount => { - self.navigation.update(navigation::Message::SelectNext); - Action::None - } + Message::SelectNextAccount => self.update_navigation(navigation::Message::SelectNext), + + Message::SelectPrevAccount => self.update_navigation(navigation::Message::SelectPrev), + } + } +} - Message::SelectPrevAccount => { - self.navigation.update(navigation::Message::SelectPrev); +impl TransactionsView { + fn update_navigation( + &mut self, + message: navigation::Message, + ) -> Action { + match self.navigation.update(message) { + navigation::Action::ActivateOption(_) | navigation::Action::SelectOption(_) => { + self.refresh_table(); Action::None } + navigation::Action::None => Action::None, } } } diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index 37b6655..d1f6af2 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -1,37 +1,22 @@ use iced::{ alignment, - widget::{column, row, Container}, + widget::{row, Container}, Element, Length, }; -use crate::{ - gui::components::{AccountNavigationEntry, Text}, - style::SPACING_LG, - traits::Viewable, -}; +use crate::{style::SPACING_LG, traits::Viewable}; use super::{Message, TransactionsView}; impl<'a> Viewable<'a, Message> for TransactionsView { fn view(&'a self) -> Element<'a, Message> { let navigation = self.navigation.view().map(Message::NavigationMessage); - let main_content = column![ - Text::default("Hello, transactions!").as_element(), - Text::default(&format!( - "{} transactions in this account.", - self.navigation.active_option.clone().map_or( - 0, - |AccountNavigationEntry { account, .. }| self - .transactions_by_account_id - .get(&account.id) - .map_or(0, |transactions| transactions.len()) - ) - )) - .as_element(), - ]; + + let table = self.table.view().map(Message::TableMessage); + row![ Container::new(navigation).width(Length::FillPortion(1)), - Container::new(main_content).width(Length::FillPortion(3)), + Container::new(table).width(Length::FillPortion(3)), ] .align_y(alignment::Vertical::Center) .height(Length::Fill) diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 0a2c355..9852b53 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -204,7 +204,7 @@ impl MainScreen { balances_view: BalancesView::new(Vec::new()), buckets: Vec::new(), buckets_view: BucketsView::new(Vec::new(), "Hello, buckets!"), - transactions_view: TransactionsView::new(Vec::new(), Vec::new()), + transactions_view: TransactionsView::new(&[], &[]), active_view: View::Balances, view_navigation: Navigation::new(Some(View::Balances), View::views()), } -- cgit v1.2.3 From 921b52d1aa05fd6477bab56ba7dab1ab9d699b42 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 09:32:46 +0000 Subject: task-085: table is scrollable --- .../src/gui/components/table/view_table.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs index 1d5f10b..33fa0ef 100644 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -1,6 +1,8 @@ use std::{fmt::Debug, hash::Hash}; -use iced::widget::{column, container, row}; +use iced::widget::{ + column, container, row, scrollable, scrollable::Direction as ScrollableDirection, +}; use crate::{gui::components::Text, style::SPACING_MD, traits::Viewable}; @@ -13,10 +15,12 @@ where fn view(&'a self) -> iced::Element<'a, Message> { let headers = row(self.cols.iter().map(|col| { container(Text::default(&col.name)) - .width(iced::Length::FillPortion(1)) + .width(iced::Length::Fixed(128.0)) .into() })) + .spacing(SPACING_MD) .padding(SPACING_MD); + let rows = column(self.rows.iter().map(|row_data| { row(self.cols.iter().map(|col| { container( @@ -28,13 +32,19 @@ where }) .unwrap_or_else(|| Text::default("")), ) - .width(iced::Length::FillPortion(1)) + .width(iced::Length::Fixed(128.0)) .into() })) .spacing(SPACING_MD) .into() })); - column![headers, rows].into() + + scrollable(column![headers, rows]) + .direction(ScrollableDirection::Both { + horizontal: Default::default(), + vertical: Default::default(), + }) + .into() } } -- cgit v1.2.3 From 8f57c4a25e6eb109259a082cd4f1e1007ad4044c Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 10:10:27 +0000 Subject: task-085: each column has its own width --- schist_desktop_gui/src/gui/components/table.rs | 13 +++++++++++++ schist_desktop_gui/src/gui/components/table/view_table.rs | 9 ++++----- schist_desktop_gui/src/gui/components/transactions_view.rs | 6 +++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/table.rs b/schist_desktop_gui/src/gui/components/table.rs index 4c6d810..68090c1 100644 --- a/schist_desktop_gui/src/gui/components/table.rs +++ b/schist_desktop_gui/src/gui/components/table.rs @@ -24,6 +24,7 @@ where { pub index: Ix, pub name: String, + pub width: f32, } impl Column @@ -34,8 +35,20 @@ where Self { index, name: name.to_string(), + width: 128.0, } } + + pub fn width(&self, width: f32) -> Self { + Self { + width, + ..self.clone() + } + } + + pub fn mul_width(&self, mul: f32) -> Self { + self.width(self.width * mul) + } } #[derive(Clone, Debug)] diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs index 33fa0ef..81755dc 100644 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -15,11 +15,10 @@ where fn view(&'a self) -> iced::Element<'a, Message> { let headers = row(self.cols.iter().map(|col| { container(Text::default(&col.name)) - .width(iced::Length::Fixed(128.0)) + .width(iced::Length::Fixed(col.width)) .into() })) - .spacing(SPACING_MD) - .padding(SPACING_MD); + .spacing(SPACING_MD); let rows = column(self.rows.iter().map(|row_data| { row(self.cols.iter().map(|col| { @@ -32,14 +31,14 @@ where }) .unwrap_or_else(|| Text::default("")), ) - .width(iced::Length::Fixed(128.0)) + .width(iced::Length::Fixed(col.width)) .into() })) .spacing(SPACING_MD) .into() })); - scrollable(column![headers, rows]) + scrollable(column![headers, rows].spacing(SPACING_MD)) .direction(ScrollableDirection::Both { horizontal: Default::default(), vertical: Default::default(), diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 8e076f1..e78a142 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -60,9 +60,9 @@ impl TransactionsView { cols: vec![ table::Column::new(0, "Date"), table::Column::new(1, "Bucket"), - table::Column::new(2, "Payee"), - table::Column::new(3, "Quantity"), - table::Column::new(4, "Balance"), + table::Column::new(2, "Payee").mul_width(1.5), + table::Column::new(3, "Quantity").mul_width(0.67), + table::Column::new(4, "Balance").mul_width(0.67), ], rows: self.navigation.active_option.clone().map_or_else( Vec::new, -- cgit v1.2.3 From 13f4d97a70cfaeb1e78bbc68ff73bd69de081cb2 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 10:13:03 +0000 Subject: task-085: factor out format_string() --- schist_desktop_gui/src/gui/components/table/view_table.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs index 81755dc..801bbb7 100644 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -26,7 +26,7 @@ where row_data .get(&col.index) .map(|datum| match datum { - Value::String(text) => Text::default(text).weak(), + Value::String(text) => format_string(text), Value::Currency(amount) => format_currency(*amount), }) .unwrap_or_else(|| Text::default("")), @@ -47,11 +47,15 @@ where } } +fn format_string(text: &String) -> Text { + Text::default(text).weak() +} + fn format_currency(amount: i32) -> Text { let text = if amount >= 0 { format!(" {} · {} ", amount / 100, amount % 100) } else { format!("({} · {})", -amount / 100, -amount % 100) }; - Text::default(&text).align_right().width(iced::Length::Fill) + format_string(&text).align_right().width(iced::Length::Fill) } -- cgit v1.2.3 From b1988df5603a427994371d8176bce0c6c1f06fc2 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 10:14:40 +0000 Subject: task-085: rename small -> v_small --- schist_desktop_gui/src/gui/components/panel.rs | 4 ++-- schist_desktop_gui/src/gui/components/text.rs | 8 ++++---- schist_desktop_gui/src/style.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/panel.rs b/schist_desktop_gui/src/gui/components/panel.rs index 364659b..85bfb97 100644 --- a/schist_desktop_gui/src/gui/components/panel.rs +++ b/schist_desktop_gui/src/gui/components/panel.rs @@ -39,7 +39,7 @@ where cols.push( Text::default(err) .highlight_maybe(value.is_focused) - .small() + .v_small() .danger() .into(), ); @@ -48,7 +48,7 @@ where cols.push( Text::default(small) .highlight_maybe(value.is_focused) - .small() + .v_small() .weak() .into(), ); diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index 0d0c8c4..b67a7aa 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -34,7 +34,7 @@ enum Strength { #[derive(Clone, Debug, PartialEq)] enum Size { - Small, + VSmall, Base, } @@ -67,9 +67,9 @@ impl Text { >>::into(self) } - pub fn small(&self) -> Self { + pub fn v_small(&self) -> Self { Self { - size: Some(Size::Small), + size: Some(Size::VSmall), ..self.clone() } } @@ -132,7 +132,7 @@ where { iced::widget::text(text.borrow().content.clone()) .size(match text.borrow().size { - Some(Size::Small) => TEXT_SIZE_SM, + Some(Size::VSmall) => TEXT_SIZE_V_SM, Some(Size::Base) | None => TEXT_SIZE_BASE, }) .align_x(match &text.borrow().align { diff --git a/schist_desktop_gui/src/style.rs b/schist_desktop_gui/src/style.rs index c2ecb02..45a9aeb 100644 --- a/schist_desktop_gui/src/style.rs +++ b/schist_desktop_gui/src/style.rs @@ -1,5 +1,5 @@ pub const SPACING_MD: u16 = 24; pub const SPACING_LG: u16 = 32; -pub const TEXT_SIZE_SM: u16 = 12; +pub const TEXT_SIZE_V_SM: u16 = 12; pub const TEXT_SIZE_BASE: u16 = 16; -- cgit v1.2.3 From 8659e9df22908fb10afb8d949a523d347634e637 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 10:18:42 +0000 Subject: task-085: table contents are small text size --- schist_desktop_gui/src/gui/components/table/view_table.rs | 2 +- schist_desktop_gui/src/gui/components/text.rs | 9 +++++++++ schist_desktop_gui/src/style.rs | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs index 801bbb7..3d4da64 100644 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -48,7 +48,7 @@ where } fn format_string(text: &String) -> Text { - Text::default(text).weak() + Text::default(text).weak().small() } fn format_currency(amount: i32) -> Text { diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index b67a7aa..36a6a13 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -35,6 +35,7 @@ enum Strength { #[derive(Clone, Debug, PartialEq)] enum Size { VSmall, + Small, Base, } @@ -74,6 +75,13 @@ impl Text { } } + pub fn small(&self) -> Self { + Self { + size: Some(Size::Small), + ..self.clone() + } + } + pub fn danger(&self) -> Self { Self { colour: Some(Colour::Danger), @@ -133,6 +141,7 @@ where iced::widget::text(text.borrow().content.clone()) .size(match text.borrow().size { Some(Size::VSmall) => TEXT_SIZE_V_SM, + Some(Size::Small) => TEXT_SIZE_SM, Some(Size::Base) | None => TEXT_SIZE_BASE, }) .align_x(match &text.borrow().align { diff --git a/schist_desktop_gui/src/style.rs b/schist_desktop_gui/src/style.rs index 45a9aeb..fd7c858 100644 --- a/schist_desktop_gui/src/style.rs +++ b/schist_desktop_gui/src/style.rs @@ -2,4 +2,5 @@ pub const SPACING_MD: u16 = 24; pub const SPACING_LG: u16 = 32; pub const TEXT_SIZE_V_SM: u16 = 12; +pub const TEXT_SIZE_SM: u16 = 14; pub const TEXT_SIZE_BASE: u16 = 16; -- cgit v1.2.3 From 3c8a428c195da414171bd6e9064f26c4a66ffe61 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 19:07:31 +0000 Subject: task-085: upgrade iced 0.13.1 -> 0.14.0 --- Cargo.lock | 1551 ++++++++------------ Cargo.toml | 2 +- .../components/balances_view/view_balances_view.rs | 2 +- .../src/gui/components/buckets_view.rs | 2 +- .../src/gui/components/table/view_table.rs | 6 +- .../transactions_view/view_transactions_view.rs | 2 +- .../src/gui/screens/main_screen/main_screen.rs | 2 +- schist_desktop_gui/src/main.rs | 4 +- schist_desktop_gui/src/theme.rs | 11 + 9 files changed, 598 insertions(+), 984 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77f25aa..92590fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,17 +85,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom 0.2.16", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.12" @@ -109,12 +98,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android-activity" version = "0.6.0" @@ -131,11 +114,20 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys 0.6.0+11769913", + "ndk-sys", "num_enum", "thiserror 1.0.69", ] +[[package]] +name = "android-build" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cac4c64175d504608cf239756339c07f6384a476f97f20a7043f92920b0b8fd" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "android-properties" version = "0.2.2" @@ -166,15 +158,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - [[package]] name = "arrayref" version = "0.3.9" @@ -195,11 +178,11 @@ checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] name = "ash" -version = "0.37.3+1.3.251" +version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "libloading 0.7.4", + "libloading", ] [[package]] @@ -213,7 +196,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.2", + "rand", "raw-window-handle", "serde", "serde_repr", @@ -221,7 +204,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-protocols", - "zbus 5.9.0", + "zbus", ] [[package]] @@ -339,7 +322,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -374,7 +357,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -406,18 +389,18 @@ dependencies = [ [[package]] name = "bit-set" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" @@ -437,15 +420,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "block2" version = "0.5.1" @@ -483,12 +457,6 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" -[[package]] -name = "by_address" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" - [[package]] name = "bytemuck" version = "1.23.1" @@ -506,7 +474,7 @@ checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -564,12 +532,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cfg_aliases" version = "0.2.1" @@ -632,45 +594,15 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ + "serde", "termcolor", "unicode-width", ] -[[package]] -name = "com" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "com_macros_support" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "combine" version = "4.6.7" @@ -764,66 +696,39 @@ dependencies = [ "libc", ] +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + [[package]] name = "cosmic-text" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2" +checksum = "173852283a9a57a3cbe365d86e74dc428a09c50421477d5ad6fe9d9509e37737" dependencies = [ "bitflags 2.9.1", "fontdb", + "harfrust", + "linebender_resource_handle", "log", "rangemap", - "rayon", "rustc-hash 1.1.0", - "rustybuzz", "self_cell", + "skrifa", + "smol_str", "swash", "sys-locale", - "ttf-parser 0.21.1", "unicode-bidi", "unicode-linebreak", "unicode-script", "unicode-segmentation", ] -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -837,13 +742,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] -name = "crypto-common" -version = "0.1.6" +name = "cryoglyph" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "08bc795bdbccdbd461736fb163930a009da6597b226d6f6fce33e7a8eb6ec519" dependencies = [ - "generic-array", - "typenum", + "cosmic-text", + "etagere", + "lru", + "rustc-hash 2.1.1", + "wgpu", ] [[package]] @@ -858,33 +766,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" -[[package]] -name = "d3d12" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" -dependencies = [ - "bitflags 2.9.1", - "libloading 0.8.8", - "winapi", -] - -[[package]] -name = "dark-light" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a76fa97167fa740dcdbfe18e8895601e1bc36525f09b044e00916e717c03a3c" -dependencies = [ - "dconf_rs", - "detect-desktop-environment", - "dirs 4.0.0", - "objc", - "rust-ini", - "web-sys", - "winreg", - "zbus 4.4.0", -] - [[package]] name = "darling" version = "0.20.11" @@ -906,7 +787,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.104", + "syn", ] [[package]] @@ -917,15 +798,9 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.104", + "syn", ] -[[package]] -name = "dconf_rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b" - [[package]] name = "deranged" version = "0.4.0" @@ -953,7 +828,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -963,15 +838,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.104", + "syn", ] -[[package]] -name = "detect-desktop-environment" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810" - [[package]] name = "diesel" version = "2.2.12" @@ -993,7 +862,7 @@ dependencies = [ "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1013,26 +882,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.104", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", + "syn", ] [[package]] @@ -1041,18 +891,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys 0.5.0", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users 0.4.6", - "winapi", + "dirs-sys", ] [[package]] @@ -1063,7 +902,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.2", + "redox_users", "windows-sys 0.60.2", ] @@ -1093,7 +932,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1102,14 +941,17 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.8", + "libloading", ] [[package]] -name = "dlv-list" -version = "0.3.0" +name = "document-features" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] [[package]] name = "downcast-rs" @@ -1123,45 +965,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -[[package]] -name = "drm" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1" -dependencies = [ - "bitflags 2.9.1", - "bytemuck", - "drm-ffi", - "drm-fourcc", - "rustix 0.38.44", -] - -[[package]] -name = "drm-ffi" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53" -dependencies = [ - "drm-sys", - "rustix 0.38.44", -] - -[[package]] -name = "drm-fourcc" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" - -[[package]] -name = "drm-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd39dde40b6e196c2e8763f23d119ddb1a8714534bf7d77fa97a65b0feda3986" -dependencies = [ - "libc", - "linux-raw-sys 0.6.5", -] - [[package]] name = "dsl_auto_type" version = "0.1.3" @@ -1173,7 +976,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1206,7 +1009,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1271,12 +1074,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fast-srgb8" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" - [[package]] name = "fastrand" version = "2.3.0" @@ -1284,35 +1081,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "fdeflate" -version = "0.3.7" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "flate2" -version = "1.1.2" +name = "foldhash" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" -dependencies = [ - "crc32fast", - "miniz_oxide", -] +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "fnv" -version = "1.0.7" +name = "foldhash" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "font-types" -version = "0.7.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492" +checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5" dependencies = [ "bytemuck", ] @@ -1328,16 +1118,16 @@ dependencies = [ [[package]] name = "fontdb" -version = "0.16.2" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" dependencies = [ "fontconfig-parser", "log", "memmap2", "slotmap", "tinyvec", - "ttf-parser 0.20.0", + "ttf-parser", ] [[package]] @@ -1358,7 +1148,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1446,7 +1236,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1479,16 +1269,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "gethostname" version = "0.4.3" @@ -1547,9 +1327,9 @@ checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" [[package]] name = "glow" -version = "0.13.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" dependencies = [ "js-sys", "slotmap", @@ -1559,9 +1339,9 @@ dependencies = [ [[package]] name = "glutin_wgl_sys" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" dependencies = [ "gl_generator", ] @@ -1587,33 +1367,32 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" dependencies = [ "log", "presser", "thiserror 1.0.69", - "winapi", - "windows", + "windows 0.58.0", ] [[package]] name = "gpu-descriptor" -version = "0.2.4" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ "bitflags 2.9.1", "gpu-descriptor-types", - "hashbrown 0.14.5", + "hashbrown 0.15.5", ] [[package]] name = "gpu-descriptor-types" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ "bitflags 2.9.1", ] @@ -1636,25 +1415,29 @@ checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", + "num-traits", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "harfrust" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "92c020db12c71d8a12a3fe7607873cade3a01a6287e29d540c8723276221b9d8" dependencies = [ - "ahash 0.7.8", + "bitflags 2.9.1", + "bytemuck", + "core_maths", + "read-fonts", + "smallvec", ] [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "ahash 0.8.12", - "allocator-api2", + "foldhash 0.1.5", ] [[package]] @@ -1662,20 +1445,8 @@ name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "hassle-rs" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" dependencies = [ - "bitflags 2.9.1", - "com", - "libc", - "libloading 0.8.8", - "thiserror 1.0.69", - "widestring", - "winapi", + "foldhash 0.2.0", ] [[package]] @@ -1728,70 +1499,68 @@ dependencies = [ [[package]] name = "iced" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88acfabc84ec077eaf9ede3457ffa3a104626d79022a9bf7f296093b1d60c73f" +checksum = "000e01026c93ba643f8357a3db3ada0e6555265a377f6f9291c472f6dd701fb3" dependencies = [ "iced_core", + "iced_debug", "iced_futures", "iced_renderer", + "iced_runtime", "iced_widget", "iced_winit", - "thiserror 1.0.69", + "thiserror 2.0.14", ] [[package]] name = "iced_core" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0013a238275494641bf8f1732a23a808196540dc67b22ff97099c044ae4c8a1c" +checksum = "91ab1937d699403e7e69252ae743a902bcee9f4ab2052cc4c9a46fcf34729d85" dependencies = [ "bitflags 2.9.1", "bytes", - "dark-light", "glam", + "lilt", "log", "num-traits", - "once_cell", - "palette", "rustc-hash 2.1.1", "smol_str", - "thiserror 1.0.69", + "thiserror 2.0.14", "web-time", ] +[[package]] +name = "iced_debug" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25035ab0215a620e53f4103e36fc4e59a1fb2817e4bfc38a30ad27b4202ea0be" +dependencies = [ + "iced_core", + "iced_futures", + "log", +] + [[package]] name = "iced_futures" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c04a6745ba2e80f32cf01e034fd00d853aa4f4cd8b91888099cb7aaee0d5d7c" +checksum = "8c0c85ccad42dfbec7293c36c018af0ea0dbcc52d137a4a9a0b0f6822a3fdf0a" dependencies = [ "futures", "iced_core", "log", "rustc-hash 2.1.1", "wasm-bindgen-futures", - "wasm-timer", + "wasmtimer", ] [[package]] -name = "iced_glyphon" -version = "0.6.0" +name = "iced_graphics" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c3bb56f1820ca252bc1d0994ece33d233a55657c0c263ea7cb16895adbde82" -dependencies = [ - "cosmic-text", - "etagere", - "lru", - "rustc-hash 2.1.1", - "wgpu", -] - -[[package]] -name = "iced_graphics" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba25a18cfa6d5cc160aca7e1b34f73ccdff21680fa8702168c09739767b6c66f" +checksum = "234ca1c2cec4155055f68fa5fad1b5242c496ac8238d80a259bca382fb44a102" dependencies = [ "bitflags 2.9.1", "bytemuck", @@ -1800,47 +1569,57 @@ dependencies = [ "iced_core", "iced_futures", "log", - "once_cell", "raw-window-handle", "rustc-hash 2.1.1", - "thiserror 1.0.69", + "thiserror 2.0.14", "unicode-segmentation", ] +[[package]] +name = "iced_program" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dfafec2947cda688d8eb00dac337ba11aa60f9ef6335aed343e189d26e4a673" +dependencies = [ + "iced_graphics", + "iced_runtime", +] + [[package]] name = "iced_renderer" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73558208059f9e622df2bf434e044ee2f838ce75201a023cf0ca3e1244f46c2a" +checksum = "250cc0802408e8c077986ec56c7d07c65f423ee658a4b9fd795a1f2aae5dac05" dependencies = [ "iced_graphics", "iced_tiny_skia", "iced_wgpu", "log", - "thiserror 1.0.69", + "thiserror 2.0.14", ] [[package]] name = "iced_runtime" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348b5b2c61c934d88ca3b0ed1ed913291e923d086a66fa288ce9669da9ef62b5" +checksum = "d1889b819ce4c06674183242e336c8d49465665441396914dc07cc86f44fa8d4" dependencies = [ "bytes", "iced_core", "iced_futures", "raw-window-handle", - "thiserror 1.0.69", + "thiserror 2.0.14", ] [[package]] name = "iced_tiny_skia" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c625d368284fcc43b0b36b176f76eff1abebe7959dd58bd8ce6897d641962a50" +checksum = "fe0acf8b75a3bc914aff5f2329fdffc1b36eeaea29dda0e4bd232f1c62e9cc3d" dependencies = [ "bytemuck", "cosmic-text", + "iced_debug", "iced_graphics", "kurbo", "log", @@ -1851,55 +1630,53 @@ dependencies = [ [[package]] name = "iced_wgpu" -version = "0.13.5" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15708887133671d2bcc6c1d01d1f176f43a64d6cdc3b2bf893396c3ee498295f" +checksum = "ff144a999b0ca0f8a10257934500060240825c42e950ec0ebee9c8ae30561c13" dependencies = [ "bitflags 2.9.1", "bytemuck", + "cryoglyph", "futures", "glam", "guillotiere", - "iced_glyphon", + "iced_debug", "iced_graphics", "log", - "once_cell", "rustc-hash 2.1.1", - "thiserror 1.0.69", + "thiserror 2.0.14", "wgpu", ] [[package]] name = "iced_widget" -version = "0.13.4" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81429e1b950b0e4bca65be4c4278fea6678ea782030a411778f26fa9f8983e1d" +checksum = "b1596afa0d3109c2618e8bc12bae6c11d3064df8f95c42dfce570397dbe957ab" dependencies = [ "iced_renderer", - "iced_runtime", + "log", "num-traits", - "once_cell", "rustc-hash 2.1.1", - "thiserror 1.0.69", + "thiserror 2.0.14", "unicode-segmentation", ] [[package]] name = "iced_winit" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44cd4e1c594b6334f409282937bf972ba14d31fedf03c23aa595d982a2fda28" +checksum = "8b7dbedc47562d1de3b9707d939f678b88c382004b7ab5a18f7a7dd723162d75" dependencies = [ - "iced_futures", - "iced_graphics", - "iced_runtime", + "iced_debug", + "iced_program", "log", + "mundy", "rustc-hash 2.1.1", - "thiserror 1.0.69", + "thiserror 2.0.14", "tracing", "wasm-bindgen-futures", "web-sys", - "winapi", "window_clipboard", "winit", ] @@ -2027,15 +1804,6 @@ dependencies = [ "hashbrown 0.16.1", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "itertools" version = "0.13.0" @@ -2100,7 +1868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.8.8", + "libloading", "pkg-config", ] @@ -2126,16 +1894,6 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libloading" version = "0.8.8" @@ -2175,16 +1933,25 @@ dependencies = [ ] [[package]] -name = "linux-raw-sys" -version = "0.4.15" +name = "lilt" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "f67562e5eff6b20553fa9be1c503356768420994e28f67e3eafe6f41910e57ad" +dependencies = [ + "web-time", +] + +[[package]] +name = "linebender_resource_handle" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" [[package]] name = "linux-raw-sys" -version = "0.6.5" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" @@ -2198,6 +1965,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + [[package]] name = "lock_api" version = "0.4.13" @@ -2216,9 +1989,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" -version = "0.12.5" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" [[package]] name = "malloc_buf" @@ -2255,13 +2028,13 @@ dependencies = [ [[package]] name = "metal" -version = "0.27.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ "bitflags 2.9.1", "block", - "core-graphics-types 0.1.3", + "core-graphics-types 0.2.0", "foreign-types", "log", "objc", @@ -2296,27 +2069,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", - "simd-adler32", +] + +[[package]] +name = "mundy" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f507e52285e981a349f7224e0ac7eaf014e1a9cce399471547c8dfbc018b79" +dependencies = [ + "android-build", + "async-io", + "cfg-if", + "dispatch", + "futures-channel", + "futures-lite", + "jni", + "ndk-context", + "objc2 0.6.2", + "objc2-app-kit 0.3.1", + "objc2-foundation 0.3.1", + "pin-project-lite", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows 0.61.3", + "zbus", ] [[package]] name = "naga" -version = "0.19.2" +version = "27.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" +checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" dependencies = [ + "arrayvec", "bit-set", "bitflags 2.9.1", + "cfg-if", + "cfg_aliases", "codespan-reporting", + "half", + "hashbrown 0.16.1", "hexf-parse", "indexmap", + "libm", "log", "num-traits", + "once_cell", "rustc-hash 1.1.0", "spirv", - "termcolor", - "thiserror 1.0.69", - "unicode-xid", + "thiserror 2.0.14", + "unicode-ident", ] [[package]] @@ -2328,7 +2131,7 @@ dependencies = [ "bitflags 2.9.1", "jni-sys", "log", - "ndk-sys 0.6.0+11769913", + "ndk-sys", "num_enum", "raw-window-handle", "thiserror 1.0.69", @@ -2340,15 +2143,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -2358,19 +2152,6 @@ dependencies = [ "jni-sys", ] -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "cfg_aliases 0.2.1", - "libc", - "memoffset", -] - [[package]] name = "nix" version = "0.30.1" @@ -2379,7 +2160,7 @@ checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ "bitflags 2.9.1", "cfg-if", - "cfg_aliases 0.2.1", + "cfg_aliases", "libc", "memoffset", ] @@ -2397,6 +2178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2428,7 +2210,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -2438,7 +2220,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", - "objc_exception", ] [[package]] @@ -2476,10 +2257,10 @@ dependencies = [ "block2 0.5.1", "libc", "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", ] [[package]] @@ -2490,8 +2271,15 @@ checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ "bitflags 2.9.1", "block2 0.6.1", + "libc", "objc2 0.6.2", + "objc2-cloud-kit 0.3.1", + "objc2-core-data 0.3.1", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.1", "objc2-foundation 0.3.1", + "objc2-quartz-core 0.3.1", ] [[package]] @@ -2507,6 +2295,17 @@ dependencies = [ "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.2", + "objc2-foundation 0.3.1", +] + [[package]] name = "objc2-contacts" version = "0.2.2" @@ -2530,6 +2329,17 @@ dependencies = [ "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-data" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.2", + "objc2-foundation 0.3.1", +] + [[package]] name = "objc2-core-foundation" version = "0.3.1" @@ -2541,6 +2351,19 @@ dependencies = [ "objc2 0.6.2", ] +[[package]] +name = "objc2-core-graphics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +dependencies = [ + "bitflags 2.9.1", + "dispatch2", + "objc2 0.6.2", + "objc2-core-foundation", + "objc2-io-surface", +] + [[package]] name = "objc2-core-image" version = "0.2.2" @@ -2553,6 +2376,16 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-core-image" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e" +dependencies = [ + "objc2 0.6.2", + "objc2-foundation 0.3.1", +] + [[package]] name = "objc2-core-location" version = "0.2.2" @@ -2589,6 +2422,19 @@ name = "objc2-foundation" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "bitflags 2.9.1", + "block2 0.6.1", + "libc", + "objc2 0.6.2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" dependencies = [ "bitflags 2.9.1", "objc2 0.6.2", @@ -2632,6 +2478,17 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-quartz-core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.2", + "objc2-foundation 0.3.1", +] + [[package]] name = "objc2-symbols" version = "0.2.2" @@ -2651,13 +2508,13 @@ dependencies = [ "bitflags 2.9.1", "block2 0.5.1", "objc2 0.5.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", + "objc2-cloud-kit 0.2.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-core-location", "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", @@ -2687,15 +2544,6 @@ dependencies = [ "objc2-foundation 0.2.2", ] -[[package]] -name = "objc_exception" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" -dependencies = [ - "cc", -] - [[package]] name = "object" version = "0.36.7" @@ -2727,13 +2575,12 @@ dependencies = [ ] [[package]] -name = "ordered-multimap" -version = "0.4.3" +name = "ordered-float" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ - "dlv-list", - "hashbrown 0.12.3", + "num-traits", ] [[package]] @@ -2752,31 +2599,7 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" dependencies = [ - "ttf-parser 0.25.1", -] - -[[package]] -name = "palette" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" -dependencies = [ - "approx", - "fast-srgb8", - "palette_derive", - "phf", -] - -[[package]] -name = "palette_derive" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" -dependencies = [ - "by_address", - "proc-macro2", - "quote", - "syn 2.0.104", + "ttf-parser", ] [[package]] @@ -2785,17 +2608,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.4" @@ -2803,21 +2615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", - "parking_lot_core 0.9.11", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2845,48 +2643,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] - [[package]] name = "pin-project" version = "1.1.10" @@ -2904,7 +2660,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -2936,19 +2692,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - [[package]] name = "polling" version = "3.9.0" @@ -2969,6 +2712,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +dependencies = [ + "portable-atomic", +] + [[package]] name = "potential_utf" version = "0.1.2" @@ -3047,35 +2805,14 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", ] [[package]] @@ -3085,16 +2822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", + "rand_core", ] [[package]] @@ -3124,45 +2852,17 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "read-fonts" -version = "0.22.7" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f" +checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" dependencies = [ "bytemuck", + "core_maths", "font-types", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -3181,17 +2881,6 @@ dependencies = [ "bitflags 2.9.1", ] -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom 0.2.16", - "libredox", - "thiserror 1.0.69", -] - [[package]] name = "redox_users" version = "0.5.2" @@ -3239,16 +2928,6 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - [[package]] name = "rustc-demangle" version = "0.1.26" @@ -3299,23 +2978,6 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" -[[package]] -name = "rustybuzz" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" -dependencies = [ - "bitflags 2.9.1", - "bytemuck", - "libm", - "smallvec", - "ttf-parser 0.21.1", - "unicode-bidi-mirroring", - "unicode-ccc", - "unicode-properties", - "unicode-script", -] - [[package]] name = "same-file" version = "1.0.6" @@ -3333,7 +2995,7 @@ dependencies = [ "anyhow", "diesel", "diesel_migrations", - "dirs 6.0.0", + "dirs", "iced", "itertools", "libsqlite3-sys", @@ -3454,7 +3116,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3465,7 +3127,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3477,17 +3139,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "shlex" version = "1.3.0" @@ -3503,23 +3154,11 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - [[package]] name = "skrifa" -version = "0.22.3" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe" +checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" dependencies = [ "bytemuck", "read-fonts", @@ -3599,9 +3238,8 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" dependencies = [ "as-raw-xcb-connection", "bytemuck", - "cfg_aliases 0.2.1", + "cfg_aliases", "core-graphics 0.24.0", - "drm", "fastrand", "foreign-types", "js-sys", @@ -3609,7 +3247,7 @@ dependencies = [ "memmap2", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "raw-window-handle", "redox_syscall 0.5.17", "rustix 0.38.44", @@ -3664,24 +3302,13 @@ checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" [[package]] name = "swash" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2" -dependencies = [ - "skrifa", - "yazi", - "zeno", -] - -[[package]] -name = "syn" -version = "1.0.109" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "skrifa", + "yazi", + "zeno", ] [[package]] @@ -3703,7 +3330,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3763,7 +3390,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3774,7 +3401,7 @@ checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3819,7 +3446,6 @@ dependencies = [ "bytemuck", "cfg-if", "log", - "png", "tiny-skia-path", ] @@ -3842,7 +3468,7 @@ checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e" dependencies = [ "as-raw-xcb-connection", "ctor-lite", - "libloading 0.8.8", + "libloading", "pkg-config", "tracing", ] @@ -3947,7 +3573,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3959,29 +3585,14 @@ dependencies = [ "once_cell", ] -[[package]] -name = "ttf-parser" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" - -[[package]] -name = "ttf-parser" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" - [[package]] name = "ttf-parser" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +dependencies = [ + "core_maths", +] [[package]] name = "uds_windows" @@ -4000,18 +3611,6 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" -[[package]] -name = "unicode-bidi-mirroring" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" - -[[package]] -name = "unicode-ccc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" - [[package]] name = "unicode-ident" version = "1.0.18" @@ -4024,12 +3623,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-properties" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" - [[package]] name = "unicode-script" version = "0.5.7" @@ -4048,12 +3641,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "unwrap-infallible" version = "1.0.0" @@ -4143,7 +3730,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.104", + "syn", "wasm-bindgen-shared", ] @@ -4178,7 +3765,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4193,18 +3780,17 @@ dependencies = [ ] [[package]] -name = "wasm-timer" -version = "0.2.5" +name = "wasmtimer" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" dependencies = [ "futures", "js-sys", - "parking_lot 0.11.2", + "parking_lot", "pin-utils", + "slab", "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", ] [[package]] @@ -4338,17 +3924,21 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.19.4" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd7311dbd2abcfebaabf1841a2824ed7c8be443a0f29166e5d3c6a53a762c01" +checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" dependencies = [ "arrayvec", + "bitflags 2.9.1", "cfg-if", - "cfg_aliases 0.1.1", + "cfg_aliases", + "document-features", + "hashbrown 0.16.1", "js-sys", "log", "naga", - "parking_lot 0.12.4", + "parking_lot", + "portable-atomic", "profiling", "raw-window-handle", "smallvec", @@ -4363,35 +3953,68 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.19.4" +version = "27.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a" +checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" dependencies = [ "arrayvec", + "bit-set", "bit-vec", "bitflags 2.9.1", - "cfg_aliases 0.1.1", - "codespan-reporting", + "bytemuck", + "cfg_aliases", + "document-features", + "hashbrown 0.16.1", "indexmap", "log", "naga", "once_cell", - "parking_lot 0.12.4", + "parking_lot", + "portable-atomic", "profiling", "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror 1.0.69", - "web-sys", + "thiserror 2.0.14", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-windows-linux-android", "wgpu-hal", "wgpu-types", ] +[[package]] +name = "wgpu-core-deps-apple" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" +dependencies = [ + "wgpu-hal", +] + [[package]] name = "wgpu-hal" -version = "0.19.5" +version = "27.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfabcfc55fd86611a855816326b2d54c3b2fd7972c27ce414291562650552703" +checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" dependencies = [ "android_system_properties", "arrayvec", @@ -4399,56 +4022,57 @@ dependencies = [ "bit-set", "bitflags 2.9.1", "block", - "cfg_aliases 0.1.1", - "core-graphics-types 0.1.3", - "d3d12", + "bytemuck", + "cfg-if", + "cfg_aliases", + "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hassle-rs", + "hashbrown 0.16.1", "js-sys", "khronos-egl", "libc", - "libloading 0.8.8", + "libloading", "log", "metal", "naga", - "ndk-sys 0.5.0+25.2.9519653", + "ndk-sys", "objc", "once_cell", - "parking_lot 0.12.4", + "ordered-float", + "parking_lot", + "portable-atomic", + "portable-atomic-util", "profiling", "range-alloc", "raw-window-handle", "renderdoc-sys", - "rustc-hash 1.1.0", "smallvec", - "thiserror 1.0.69", + "thiserror 2.0.14", "wasm-bindgen", "web-sys", "wgpu-types", - "winapi", + "windows 0.58.0", + "windows-core 0.58.0", ] [[package]] name = "wgpu-types" -version = "0.19.2" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805" +checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" dependencies = [ "bitflags 2.9.1", + "bytemuck", "js-sys", + "log", + "thiserror 2.0.14", "web-sys", ] -[[package]] -name = "widestring" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" - [[package]] name = "winapi" version = "0.3.9" @@ -4482,34 +4106,60 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d692d46038c433f9daee7ad8757e002a4248c20b0a3fbc991d99521d3bcb6d" +checksum = "d5654226305eaf2dde8853fb482861d28e5dcecbbd40cb88e8393d94bb80d733" dependencies = [ "clipboard-win", "clipboard_macos", "clipboard_wayland", "clipboard_x11", "raw-window-handle", - "thiserror 1.0.69", + "thiserror 2.0.14", ] [[package]] name = "windows" -version = "0.52.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.52.0", + "windows-core 0.58.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + [[package]] name = "windows-core" -version = "0.52.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] @@ -4519,11 +4169,33 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", "windows-link", - "windows-result", - "windows-strings", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4534,7 +4206,18 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4545,7 +4228,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -4554,6 +4237,25 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -4563,6 +4265,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.4.2" @@ -4671,6 +4383,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4857,14 +4578,14 @@ version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ - "ahash 0.8.12", + "ahash", "android-activity", "atomic-waker", "bitflags 2.9.1", "block2 0.5.1", "bytemuck", "calloop", - "cfg_aliases 0.2.1", + "cfg_aliases", "concurrent-queue", "core-foundation 0.9.4", "core-graphics 0.23.2", @@ -4912,15 +4633,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "wit-bindgen-rt" version = "0.39.0" @@ -4956,7 +4668,7 @@ dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "libloading 0.8.8", + "libloading", "once_cell", "rustix 0.38.44", "x11rb-protocol", @@ -4974,16 +4686,6 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" -[[package]] -name = "xdg-home" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "xkbcommon-dl" version = "0.4.2" @@ -5011,9 +4713,9 @@ checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" [[package]] name = "yazi" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yoke" @@ -5035,48 +4737,10 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", "synstructure", ] -[[package]] -name = "zbus" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" -dependencies = [ - "async-broadcast", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix 0.29.0", - "ordered-stream", - "rand 0.8.5", - "serde", - "serde_repr", - "sha1", - "static_assertions", - "tracing", - "uds_windows", - "windows-sys 0.52.0", - "xdg-home", - "zbus_macros 4.4.0", - "zbus_names 3.0.0", - "zvariant 4.2.0", -] - [[package]] name = "zbus" version = "5.9.0" @@ -5097,7 +4761,7 @@ dependencies = [ "futures-core", "futures-lite", "hex", - "nix 0.30.1", + "nix", "ordered-stream", "serde", "serde_repr", @@ -5105,22 +4769,9 @@ dependencies = [ "uds_windows", "windows-sys 0.59.0", "winnow", - "zbus_macros 5.9.0", - "zbus_names 4.2.0", - "zvariant 5.6.0", -] - -[[package]] -name = "zbus_macros" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.104", - "zvariant_utils 2.1.0", + "zbus_macros", + "zbus_names", + "zvariant", ] [[package]] @@ -5132,21 +4783,10 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", - "zbus_names 4.2.0", - "zvariant 5.6.0", - "zvariant_utils 3.2.0", -] - -[[package]] -name = "zbus_names" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" -dependencies = [ - "serde", - "static_assertions", - "zvariant 4.2.0", + "syn", + "zbus_names", + "zvariant", + "zvariant_utils", ] [[package]] @@ -5158,14 +4798,14 @@ dependencies = [ "serde", "static_assertions", "winnow", - "zvariant 5.6.0", + "zvariant", ] [[package]] name = "zeno" -version = "0.2.3" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697" +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" @@ -5184,7 +4824,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -5204,7 +4844,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", "synstructure", ] @@ -5238,20 +4878,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", -] - -[[package]] -name = "zvariant" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" -dependencies = [ - "endi", - "enumflags2", - "serde", - "static_assertions", - "zvariant_derive 4.2.0", + "syn", ] [[package]] @@ -5265,21 +4892,8 @@ dependencies = [ "serde", "url", "winnow", - "zvariant_derive 5.6.0", - "zvariant_utils 3.2.0", -] - -[[package]] -name = "zvariant_derive" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.104", - "zvariant_utils 2.1.0", + "zvariant_derive", + "zvariant_utils", ] [[package]] @@ -5291,19 +4905,8 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", - "zvariant_utils 3.2.0", -] - -[[package]] -name = "zvariant_utils" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", + "syn", + "zvariant_utils", ] [[package]] @@ -5316,6 +4919,6 @@ dependencies = [ "quote", "serde", "static_assertions", - "syn 2.0.104", + "syn", "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index 66cee1d..122c806 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ diesel = { version = "2.2.0" } diesel_migrations = "2.2.0" dirs = "6.0" dotenvy = "0.15.7" -iced = "0.13.1" +iced = "0.14.0" itertools = "0.13.0" libsqlite3-sys = { version = "0.30.1", features = ["bundled"] } rfd = "0.15.4" diff --git a/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs b/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs index 22f22b6..013a6fb 100644 --- a/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs +++ b/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs @@ -24,7 +24,7 @@ impl<'a> Viewable<'a, Message> for BalancesView { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } diff --git a/schist_desktop_gui/src/gui/components/buckets_view.rs b/schist_desktop_gui/src/gui/components/buckets_view.rs index 7f5b218..8f12019 100644 --- a/schist_desktop_gui/src/gui/components/buckets_view.rs +++ b/schist_desktop_gui/src/gui/components/buckets_view.rs @@ -115,7 +115,7 @@ impl<'a> Viewable<'a, Message> for BucketsView { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs index 3d4da64..725c5ff 100644 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -18,7 +18,7 @@ where .width(iced::Length::Fixed(col.width)) .into() })) - .spacing(SPACING_MD); + .spacing(u32::from(SPACING_MD)); let rows = column(self.rows.iter().map(|row_data| { row(self.cols.iter().map(|col| { @@ -34,11 +34,11 @@ where .width(iced::Length::Fixed(col.width)) .into() })) - .spacing(SPACING_MD) + .spacing(u32::from(SPACING_MD)) .into() })); - scrollable(column![headers, rows].spacing(SPACING_MD)) + scrollable(column![headers, rows].spacing(u32::from(SPACING_MD))) .direction(ScrollableDirection::Both { horizontal: Default::default(), vertical: Default::default(), diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index d1f6af2..8102314 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -20,7 +20,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 9852b53..86ce910 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -65,7 +65,7 @@ impl<'a> Viewable<'a, Message> for MainScreen { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } diff --git a/schist_desktop_gui/src/main.rs b/schist_desktop_gui/src/main.rs index a5749d3..3f18452 100644 --- a/schist_desktop_gui/src/main.rs +++ b/schist_desktop_gui/src/main.rs @@ -24,11 +24,11 @@ use crate::{ fn main() -> anyhow::Result<()> { let cache = get_cache().unwrap_or_else(|_| Cache::default()); let config = Config::default(); - iced::application("Schist", Gui::update, Gui::view) + iced::application(move || Gui::new(&cache), Gui::update, Gui::view) .settings(make_settings(&config.clone())) .subscription(gui::subscription) .theme(make_theme) .window(make_window_settings(&config.clone())) - .run_with(move || Gui::new(&cache)) + .run() .context("Failed to run Schist GUI") } diff --git a/schist_desktop_gui/src/theme.rs b/schist_desktop_gui/src/theme.rs index 98df36f..0e71689 100644 --- a/schist_desktop_gui/src/theme.rs +++ b/schist_desktop_gui/src/theme.rs @@ -14,12 +14,18 @@ pub fn make_theme(_state: &Gui) -> Theme { primary: accent_8(), success: accent_8(), danger: red_4(), + warning: red_4(), }, |palette| palette::Extended { background: palette::Background { base: palette::Pair::new(black(), palette.text), + neutral: palette::Pair::new(black(), palette.text), weak: palette::Pair::new(grey_2(), palette.text), + weaker: palette::Pair::new(grey_2(), palette.text), + weakest: palette::Pair::new(grey_2(), palette.text), strong: palette::Pair::new(grey_2(), palette.text), + stronger: palette::Pair::new(grey_2(), palette.text), + strongest: palette::Pair::new(grey_2(), palette.text), }, primary: palette::Primary { base: palette::Pair::new(palette.background, palette.text), @@ -41,6 +47,11 @@ pub fn make_theme(_state: &Gui) -> Theme { weak: palette::Pair::new(palette.background, red_7()), strong: palette::Pair::new(palette.background, red_4()), }, + warning: palette::Warning { + base: palette::Pair::new(palette.background, red_7()), + weak: palette::Pair::new(palette.background, red_7()), + strong: palette::Pair::new(palette.background, red_4()), + }, is_dark: true, }, ) -- cgit v1.2.3 From b3f91aef7c9673c180690f6e22984d50e0dbeecf Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 19:11:22 +0000 Subject: task-085: clips overflowing table cells --- .../src/gui/components/table/view_table.rs | 2 +- schist_desktop_gui/src/gui/components/text.rs | 64 +++++++++++++++++----- .../src/gui/components/transactions_view.rs | 2 +- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs index 725c5ff..f082b83 100644 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ b/schist_desktop_gui/src/gui/components/table/view_table.rs @@ -48,7 +48,7 @@ where } fn format_string(text: &String) -> Text { - Text::default(text).weak().small() + Text::default(text).weak().small().clip() } fn format_currency(amount: i32) -> Text { diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index 36a6a13..7a685c1 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -1,5 +1,7 @@ use std::borrow::Borrow; +use iced::widget::container; + use crate::{impl_focusable, style::*}; #[derive(Clone, Debug, PartialEq)] @@ -7,6 +9,7 @@ pub struct Text { pub content: String, align: Alignment, colour: Option, + overflow_strategy: OverflowStrategy, size: Option, strength: Option, width: iced::Length, @@ -26,6 +29,12 @@ enum Colour { Highlight, } +#[derive(Clone, Debug, PartialEq)] +enum OverflowStrategy { + Grow, + Clip, +} + #[derive(Clone, Debug, PartialEq)] enum Strength { Base, @@ -45,6 +54,7 @@ impl Text { align: Alignment::Left, content: String::from(content), colour: Some(Colour::Primary), + overflow_strategy: OverflowStrategy::Grow, size: Some(Size::Base), strength: Some(Strength::Base), is_focused: false, @@ -57,6 +67,7 @@ impl Text { align: Alignment::Left, content: String::from(content), colour: None, + overflow_strategy: OverflowStrategy::Grow, size: None, strength: None, width: iced::Length::Shrink, @@ -64,7 +75,10 @@ impl Text { } } - pub fn as_element<'a, Message>(self) -> iced::Element<'a, Message> { + pub fn as_element<'a, Message>(self) -> iced::Element<'a, Message> + where + Message: 'a, + { >>::into(self) } @@ -120,15 +134,28 @@ impl Text { ..self.clone() } } + + pub fn clip(&self) -> Self { + Self { + overflow_strategy: OverflowStrategy::Clip, + ..self.clone() + } + } } -impl<'a, Message> From for iced::Element<'a, Message> { +impl<'a, Message> From for iced::Element<'a, Message> +where + Message: 'a, +{ fn from(text: Text) -> Self { text_as_element(text) } } -impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> { +impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> +where + Message: 'a, +{ fn from(text: &'a Text) -> Self { text_as_element(text) } @@ -137,23 +164,27 @@ impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> { fn text_as_element<'a, T, Message>(text: T) -> iced::Element<'a, Message> where T: Borrow + 'a, + Message: 'a, { - iced::widget::text(text.borrow().content.clone()) + let overflow_strategy = &text.borrow().overflow_strategy.clone(); + + let text_elem: iced::widget::Text = iced::widget::text(text.borrow().content.clone()) .size(match text.borrow().size { - Some(Size::VSmall) => TEXT_SIZE_V_SM, - Some(Size::Small) => TEXT_SIZE_SM, - Some(Size::Base) | None => TEXT_SIZE_BASE, + Some(Size::VSmall) => u32::from(TEXT_SIZE_V_SM), + Some(Size::Small) => u32::from(TEXT_SIZE_SM), + Some(Size::Base) | None => u32::from(TEXT_SIZE_BASE), }) .align_x(match &text.borrow().align { Alignment::Left => iced::alignment::Horizontal::Left, Alignment::Right => iced::alignment::Horizontal::Right, }) + .wrapping(match overflow_strategy { + OverflowStrategy::Grow => iced::widget::text::Wrapping::default(), + OverflowStrategy::Clip => iced::widget::text::Wrapping::None, + }) .width(text.borrow().width) .style(move |theme: &iced::Theme| iced::widget::text::Style { - color: match ( - &text.borrow().borrow().colour, - &text.borrow().borrow().strength, - ) { + color: match (&text.borrow().colour, &text.borrow().strength) { (Some(Colour::Danger), Some(Strength::Base) | None) => { Some(theme.extended_palette().danger.base.text) } @@ -174,8 +205,15 @@ where } (None, _) => None, }, - }) - .into() + }); + + match overflow_strategy { + OverflowStrategy::Grow => text_elem.into(), + OverflowStrategy::Clip => container::<'a, Message, _, _>(text_elem) + .height(iced::Length::Shrink) + .clip(true) + .into(), + } } impl_focusable!(Text); diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index e78a142..51877cf 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -60,7 +60,7 @@ impl TransactionsView { cols: vec![ table::Column::new(0, "Date"), table::Column::new(1, "Bucket"), - table::Column::new(2, "Payee").mul_width(1.5), + table::Column::new(2, "Payee").mul_width(2.0), table::Column::new(3, "Quantity").mul_width(0.67), table::Column::new(4, "Balance").mul_width(0.67), ], -- cgit v1.2.3 From 413afad1fdf1d15fefc1b709f2eba1332a110608 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Thu, 12 Feb 2026 20:00:26 +0000 Subject: task-085: uses new iced::widget::Table instead of home-made widget --- schist_desktop_gui/src/gui/components.rs | 2 - schist_desktop_gui/src/gui/components/table.rs | 55 -------------- .../src/gui/components/table/view_table.rs | 61 ---------------- schist_desktop_gui/src/gui/components/text.rs | 9 +++ .../src/gui/components/transactions_view.rs | 52 +------------ .../transactions_view/view_transactions_view.rs | 85 +++++++++++++++++++++- 6 files changed, 93 insertions(+), 171 deletions(-) delete mode 100644 schist_desktop_gui/src/gui/components/table.rs delete mode 100644 schist_desktop_gui/src/gui/components/table/view_table.rs diff --git a/schist_desktop_gui/src/gui/components.rs b/schist_desktop_gui/src/gui/components.rs index ec91951..606c418 100644 --- a/schist_desktop_gui/src/gui/components.rs +++ b/schist_desktop_gui/src/gui/components.rs @@ -5,7 +5,6 @@ pub mod buckets_view; pub mod button; pub mod navigation; pub mod panel; -pub mod table; pub mod text; pub mod transactions_view; @@ -16,6 +15,5 @@ pub use buckets_view::BucketsView; pub use button::{button, panel_button}; pub use navigation::Navigation; pub use panel::Panel; -pub use table::Table; pub use text::Text; pub use transactions_view::TransactionsView; diff --git a/schist_desktop_gui/src/gui/components/table.rs b/schist_desktop_gui/src/gui/components/table.rs deleted file mode 100644 index 68090c1..0000000 --- a/schist_desktop_gui/src/gui/components/table.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::collections::HashMap; - -mod view_table; - -#[derive(Clone, Debug, Default)] -pub struct Table -where - Ix: Clone + std::fmt::Debug, -{ - pub cols: Vec>, - pub rows: Vec>, -} - -#[derive(Clone, Debug)] -pub enum Value { - String(String), - Currency(i32), -} - -#[derive(Clone, Debug)] -pub struct Column -where - Ix: Clone + std::fmt::Debug, -{ - pub index: Ix, - pub name: String, - pub width: f32, -} - -impl Column -where - Ix: Clone + std::fmt::Debug, -{ - pub fn new(index: Ix, name: &str) -> Self { - Self { - index, - name: name.to_string(), - width: 128.0, - } - } - - pub fn width(&self, width: f32) -> Self { - Self { - width, - ..self.clone() - } - } - - pub fn mul_width(&self, mul: f32) -> Self { - self.width(self.width * mul) - } -} - -#[derive(Clone, Debug)] -pub enum Message {} diff --git a/schist_desktop_gui/src/gui/components/table/view_table.rs b/schist_desktop_gui/src/gui/components/table/view_table.rs deleted file mode 100644 index f082b83..0000000 --- a/schist_desktop_gui/src/gui/components/table/view_table.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::{fmt::Debug, hash::Hash}; - -use iced::widget::{ - column, container, row, scrollable, scrollable::Direction as ScrollableDirection, -}; - -use crate::{gui::components::Text, style::SPACING_MD, traits::Viewable}; - -use super::{Message, Table, Value}; - -impl<'a, Ix> Viewable<'a, Message> for Table -where - Ix: Clone + Debug + Eq + Hash, -{ - fn view(&'a self) -> iced::Element<'a, Message> { - let headers = row(self.cols.iter().map(|col| { - container(Text::default(&col.name)) - .width(iced::Length::Fixed(col.width)) - .into() - })) - .spacing(u32::from(SPACING_MD)); - - let rows = column(self.rows.iter().map(|row_data| { - row(self.cols.iter().map(|col| { - container( - row_data - .get(&col.index) - .map(|datum| match datum { - Value::String(text) => format_string(text), - Value::Currency(amount) => format_currency(*amount), - }) - .unwrap_or_else(|| Text::default("")), - ) - .width(iced::Length::Fixed(col.width)) - .into() - })) - .spacing(u32::from(SPACING_MD)) - .into() - })); - - scrollable(column![headers, rows].spacing(u32::from(SPACING_MD))) - .direction(ScrollableDirection::Both { - horizontal: Default::default(), - vertical: Default::default(), - }) - .into() - } -} - -fn format_string(text: &String) -> Text { - Text::default(text).weak().small().clip() -} - -fn format_currency(amount: i32) -> Text { - let text = if amount >= 0 { - format!(" {} · {} ", amount / 100, amount % 100) - } else { - format!("({} · {})", -amount / 100, -amount % 100) - }; - format_string(&text).align_right().width(iced::Length::Fill) -} diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index 7a685c1..1760f4c 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -75,6 +75,15 @@ impl Text { } } + pub fn currency(amount: i32) -> Self { + let formatted_string = if amount < 0 { + format!("({} · {})", -amount / 100, -amount % 100) + } else { + format!(" {} · {} ", amount / 100, amount % 100) + }; + Self::default(&formatted_string) + } + pub fn as_element<'a, Message>(self) -> iced::Element<'a, Message> where Message: 'a, diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 51877cf..491049d 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -6,14 +6,13 @@ use itertools::Itertools; use schist_models::{Account, Transaction}; use crate::{ - gui::components::{navigation, table, AccountNavigationEntry, Navigation, Table}, + gui::components::{navigation, AccountNavigationEntry, Navigation}, traits::Component, }; #[derive(Clone, Debug)] pub struct TransactionsView { navigation: Navigation, - table: Table, transactions_by_account_id: HashMap>, } @@ -24,7 +23,6 @@ pub enum Message { SelectPrevAccount, SetAccounts(Vec), SetTransactions(Vec), - TableMessage(table::Message), } pub enum Action { @@ -42,55 +40,13 @@ impl TransactionsView { account_navigation_entries.first().cloned(), account_navigation_entries, ); - let mut transactions_view = Self { + Self { navigation: navigation, - table: Table::default(), transactions_by_account_id: transactions .into_iter() .cloned() .into_group_map_by(|t| t.account_id), - }; - transactions_view.refresh_table(); - transactions_view - } - - fn refresh_table(&mut self) { - self.table = - Table { - cols: vec![ - table::Column::new(0, "Date"), - table::Column::new(1, "Bucket"), - table::Column::new(2, "Payee").mul_width(2.0), - table::Column::new(3, "Quantity").mul_width(0.67), - table::Column::new(4, "Balance").mul_width(0.67), - ], - rows: self.navigation.active_option.clone().map_or_else( - Vec::new, - |AccountNavigationEntry { account, .. }| { - self.transactions_by_account_id - .get(&account.id) - .cloned() - .unwrap_or_else(Vec::new) - .iter() - .map(|t| { - HashMap::from([ - (0, table::Value::String(t.date.to_string())), - ( - 1, - table::Value::String(t.bucket_id.map_or_else( - || String::from("None"), - |id| id.to_string(), - )), - ), - (2, table::Value::String(t.counterparty.clone())), - (3, table::Value::Currency(t.amount)), - (4, table::Value::String(String::from("TODO"))), - ]) - }) - .collect() - }, - ), - }; + } } } @@ -110,7 +66,6 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { Message::SetTransactions(transactions) => { self.transactions_by_account_id = transactions.into_iter().into_group_map_by(|t| t.account_id); - self.refresh_table(); Action::None } @@ -128,7 +83,6 @@ impl TransactionsView { ) -> Action { match self.navigation.update(message) { navigation::Action::ActivateOption(_) | navigation::Action::SelectOption(_) => { - self.refresh_table(); Action::None } navigation::Action::None => Action::None, diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index 8102314..72f4c8f 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -1,10 +1,17 @@ use iced::{ alignment, - widget::{row, Container}, + widget::{ + row, + scrollable::{self, Scrollbar}, + table, + table::column, + Container, Scrollable, + }, Element, Length, }; +use schist_models::Transaction; -use crate::{style::SPACING_LG, traits::Viewable}; +use crate::{gui::components::Text, style::SPACING_LG, traits::Viewable}; use super::{Message, TransactionsView}; @@ -12,11 +19,81 @@ impl<'a> Viewable<'a, Message> for TransactionsView { fn view(&'a self) -> Element<'a, Message> { let navigation = self.navigation.view().map(Message::NavigationMessage); - let table = self.table.view().map(Message::TableMessage); + let columns = [ + column( + Text::default("Date").width(iced::Length::Fixed(128.0)), + |t: Transaction| { + Text::default(t.date.to_string().as_str()) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() + }, + ), + column( + Text::default("Bucket").width(iced::Length::Fixed(128.0)), + |t: Transaction| { + Text::default( + t.bucket_id + .map(|id| id.to_string()) + .unwrap_or(String::from("None")) + .as_str(), + ) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() + }, + ), + column( + Text::default("Payee").width(iced::Length::Fixed(256.0)), + |t: Transaction| { + Text::default(&t.counterparty) + .width(iced::Length::Fixed(256.0)) + .small() + .clip() + }, + ), + column( + Text::default("Quantity").width(iced::Length::Fixed(96.0)), + |t: Transaction| { + Text::currency(t.amount) + .width(iced::Length::Fixed(96.0)) + .small() + .clip() + .align_right() + }, + ), + column( + Text::default("Balance").width(iced::Length::Fixed(96.0)), + |_t: Transaction| { + Text::default("TODO") + .width(iced::Length::Fixed(96.0)) + .small() + .clip() + }, + ), + ]; + + let rows = self + .navigation + .active_option + .clone() + .map_or_else(Vec::default, |option| { + self.transactions_by_account_id + .get(&option.account.id) + .cloned() + .unwrap_or_else(Vec::default) + }); + + let table = table(columns, rows); row![ Container::new(navigation).width(Length::FillPortion(1)), - Container::new(table).width(Length::FillPortion(3)), + Scrollable::new(table) + .direction(scrollable::Direction::Both { + horizontal: Scrollbar::default(), + vertical: Scrollbar::default(), + }) + .width(Length::FillPortion(3)), ] .align_y(alignment::Vertical::Center) .height(Length::Fill) -- cgit v1.2.3 From d119e7d7ba41ce7ee479336ce5de287ef62a2737 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sat, 21 Feb 2026 14:17:09 +0000 Subject: task-085: table is fixed width --- .../components/transactions_view/view_transactions_view.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index 72f4c8f..d6ca180 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -84,16 +84,14 @@ impl<'a> Viewable<'a, Message> for TransactionsView { .unwrap_or_else(Vec::default) }); - let table = table(columns, rows); + let table = Scrollable::new(table(columns, rows)).direction(scrollable::Direction::Both { + horizontal: Scrollbar::default(), + vertical: Scrollbar::default(), + }); row![ Container::new(navigation).width(Length::FillPortion(1)), - Scrollable::new(table) - .direction(scrollable::Direction::Both { - horizontal: Scrollbar::default(), - vertical: Scrollbar::default(), - }) - .width(Length::FillPortion(3)), + Container::new(table).width(Length::FillPortion(3)), ] .align_y(alignment::Vertical::Center) .height(Length::Fill) -- cgit v1.2.3 From b3d80680c0ac19df7a810ade6f76cabf1005e914 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 08:15:36 +0000 Subject: task-085: format dates --- schist_core/schist_models/src/date_utc.rs | 4 ++++ .../src/gui/components/transactions_view/view_transactions_view.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/schist_core/schist_models/src/date_utc.rs b/schist_core/schist_models/src/date_utc.rs index 927644c..658a8dd 100644 --- a/schist_core/schist_models/src/date_utc.rs +++ b/schist_core/schist_models/src/date_utc.rs @@ -146,6 +146,10 @@ impl DateUtc { } return prev_guess; } + + pub fn format(&self, fmt: &str) -> String { + format!("{}", self.chrono_datetime_utc.format(fmt)) + } } impl Nowlike for DateUtc { diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index d6ca180..eed55ad 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -23,7 +23,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { column( Text::default("Date").width(iced::Length::Fixed(128.0)), |t: Transaction| { - Text::default(t.date.to_string().as_str()) + Text::default(t.date.format("%e %b %Y").as_str()) .width(iced::Length::Fixed(128.0)) .small() .clip() -- cgit v1.2.3 From fe1d4bff956d957a6ad2dcd03b15533ec03bf9d6 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 08:36:01 +0000 Subject: task-085: factor out cell view functions --- .../transactions_view/view_transactions_view.rs | 82 ++++++++++++---------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index eed55ad..7ceadda 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -22,54 +22,23 @@ impl<'a> Viewable<'a, Message> for TransactionsView { let columns = [ column( Text::default("Date").width(iced::Length::Fixed(128.0)), - |t: Transaction| { - Text::default(t.date.format("%e %b %Y").as_str()) - .width(iced::Length::Fixed(128.0)) - .small() - .clip() - }, + view_date_cell, ), column( Text::default("Bucket").width(iced::Length::Fixed(128.0)), - |t: Transaction| { - Text::default( - t.bucket_id - .map(|id| id.to_string()) - .unwrap_or(String::from("None")) - .as_str(), - ) - .width(iced::Length::Fixed(128.0)) - .small() - .clip() - }, + |t: Transaction| view_bucket_cell(t), ), column( Text::default("Payee").width(iced::Length::Fixed(256.0)), - |t: Transaction| { - Text::default(&t.counterparty) - .width(iced::Length::Fixed(256.0)) - .small() - .clip() - }, + view_payee_cell, ), column( Text::default("Quantity").width(iced::Length::Fixed(96.0)), - |t: Transaction| { - Text::currency(t.amount) - .width(iced::Length::Fixed(96.0)) - .small() - .clip() - .align_right() - }, + view_quantity_cell, ), column( Text::default("Balance").width(iced::Length::Fixed(96.0)), - |_t: Transaction| { - Text::default("TODO") - .width(iced::Length::Fixed(96.0)) - .small() - .clip() - }, + |_t: Transaction| view_balance_cell(), ), ]; @@ -99,3 +68,44 @@ impl<'a> Viewable<'a, Message> for TransactionsView { .into() } } + +fn view_date_cell(transaction: Transaction) -> Text { + Text::default(transaction.date.format("%e %b %Y").as_str()) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() +} + +fn view_bucket_cell(t: Transaction) -> Text { + Text::default( + t.bucket_id + .map(|id| id.to_string()) + .unwrap_or(String::from("None")) + .as_str(), + ) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() +} + +fn view_payee_cell(t: Transaction) -> Text { + Text::default(&t.counterparty) + .width(iced::Length::Fixed(256.0)) + .small() + .clip() +} + +fn view_quantity_cell(t: Transaction) -> Text { + Text::currency(t.amount) + .width(iced::Length::Fixed(96.0)) + .small() + .clip() + .align_right() +} + +fn view_balance_cell() -> Text { + Text::default("TODO") + .width(iced::Length::Fixed(96.0)) + .small() + .clip() +} -- cgit v1.2.3 From 376ad725248c9c50596adb8bbebab9d6c5c9dea7 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 08:45:12 +0000 Subject: task-085: can make Text italic --- schist_desktop_gui/src/gui/components/text.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index 1760f4c..0cf9698 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; -use iced::widget::container; +use iced::{font, widget::container, Font}; use crate::{impl_focusable, style::*}; @@ -9,6 +9,7 @@ pub struct Text { pub content: String, align: Alignment, colour: Option, + font_style: font::Style, overflow_strategy: OverflowStrategy, size: Option, strength: Option, @@ -54,6 +55,7 @@ impl Text { align: Alignment::Left, content: String::from(content), colour: Some(Colour::Primary), + font_style: font::Style::Normal, overflow_strategy: OverflowStrategy::Grow, size: Some(Size::Base), strength: Some(Strength::Base), @@ -67,6 +69,7 @@ impl Text { align: Alignment::Left, content: String::from(content), colour: None, + font_style: font::Style::Normal, overflow_strategy: OverflowStrategy::Grow, size: None, strength: None, @@ -150,6 +153,13 @@ impl Text { ..self.clone() } } + + pub fn italic(&self) -> Self { + Self { + font_style: font::Style::Italic, + ..self.clone() + } + } } impl<'a, Message> From for iced::Element<'a, Message> @@ -178,6 +188,10 @@ where let overflow_strategy = &text.borrow().overflow_strategy.clone(); let text_elem: iced::widget::Text = iced::widget::text(text.borrow().content.clone()) + .font(Font { + style: text.borrow().font_style, + ..Default::default() + }) .size(match text.borrow().size { Some(Size::VSmall) => u32::from(TEXT_SIZE_V_SM), Some(Size::Small) => u32::from(TEXT_SIZE_SM), -- cgit v1.2.3 From 6137e4bec5fd7f34c66162b32424343a30b3c5f2 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 08:49:25 +0000 Subject: task-085: formats bucket cells --- .../src/gui/components/transactions_view.rs | 12 ++++++++++-- .../transactions_view/view_transactions_view.rs | 21 ++++++++++++--------- .../src/gui/screens/main_screen/main_screen.rs | 6 ++++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 491049d..11249a1 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -3,7 +3,7 @@ mod view_transactions_view; use std::collections::HashMap; use itertools::Itertools; -use schist_models::{Account, Transaction}; +use schist_models::{Account, Bucket, Transaction}; use crate::{ gui::components::{navigation, AccountNavigationEntry, Navigation}, @@ -12,6 +12,7 @@ use crate::{ #[derive(Clone, Debug)] pub struct TransactionsView { + buckets: Vec, navigation: Navigation, transactions_by_account_id: HashMap>, } @@ -22,6 +23,7 @@ pub enum Message { SelectNextAccount, SelectPrevAccount, SetAccounts(Vec), + SetBuckets(Vec), SetTransactions(Vec), } @@ -30,7 +32,7 @@ pub enum Action { } impl TransactionsView { - pub fn new(accounts: &[Account], transactions: &[Transaction]) -> Self { + pub fn new(accounts: &[Account], buckets: &[Bucket], transactions: &[Transaction]) -> Self { let account_navigation_entries: Vec = accounts .iter() .cloned() @@ -41,6 +43,7 @@ impl TransactionsView { account_navigation_entries, ); Self { + buckets: buckets.to_vec(), navigation: navigation, transactions_by_account_id: transactions .into_iter() @@ -63,6 +66,11 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { self.update_navigation(navigation::Message::SetOptions(account_navigation_entries)) } + Message::SetBuckets(buckets) => { + self.buckets = buckets; + Action::None + } + Message::SetTransactions(transactions) => { self.transactions_by_account_id = transactions.into_iter().into_group_map_by(|t| t.account_id); diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index 7ceadda..f43ee48 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -9,7 +9,7 @@ use iced::{ }, Element, Length, }; -use schist_models::Transaction; +use schist_models::{Bucket, Transaction}; use crate::{gui::components::Text, style::SPACING_LG, traits::Viewable}; @@ -26,7 +26,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { ), column( Text::default("Bucket").width(iced::Length::Fixed(128.0)), - |t: Transaction| view_bucket_cell(t), + |t: Transaction| view_bucket_cell(t, &self.buckets), ), column( Text::default("Payee").width(iced::Length::Fixed(256.0)), @@ -76,13 +76,16 @@ fn view_date_cell(transaction: Transaction) -> Text { .clip() } -fn view_bucket_cell(t: Transaction) -> Text { - Text::default( - t.bucket_id - .map(|id| id.to_string()) - .unwrap_or(String::from("None")) - .as_str(), - ) +fn view_bucket_cell(t: Transaction, buckets: &[Bucket]) -> Text { + (t.bucket_id.map_or_else( + || Text::default("None").italic(), + |id| { + buckets.iter().find(|b| b.id == id).map_or_else( + || Text::default(format!("<{}>", id).as_str()).italic(), + |b| Text::default(&b.name), + ) + }, + )) .width(iced::Length::Fixed(128.0)) .small() .clip() diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 86ce910..038d65f 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -109,7 +109,9 @@ impl<'a> Component<'a, Message, Action> for MainScreen { self.balances_view .update(balances_view::Message::SetBuckets(buckets.clone())); self.buckets_view - .update(buckets_view::Message::SetBuckets(buckets)); + .update(buckets_view::Message::SetBuckets(buckets.clone())); + self.transactions_view + .update(transactions_view::Message::SetBuckets(buckets)); Action::None } @@ -204,7 +206,7 @@ impl MainScreen { balances_view: BalancesView::new(Vec::new()), buckets: Vec::new(), buckets_view: BucketsView::new(Vec::new(), "Hello, buckets!"), - transactions_view: TransactionsView::new(&[], &[]), + transactions_view: TransactionsView::new(&[], &[], &[]), active_view: View::Balances, view_navigation: Navigation::new(Some(View::Balances), View::views()), } -- cgit v1.2.3 From 96e1b8a6158e5ac3b56c03718de5650ff805d41b Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 09:32:21 +0000 Subject: task-085: displays running balances --- .../src/gui/components/transactions_view.rs | 33 ++++++++++++++++------ .../transactions_view/view_transactions_view.rs | 22 +++++++++++---- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 11249a1..27e18cd 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -1,6 +1,6 @@ mod view_transactions_view; -use std::collections::HashMap; +use std::{collections::HashMap, mem::transmute}; use itertools::Itertools; use schist_models::{Account, Bucket, Transaction}; @@ -12,6 +12,7 @@ use crate::{ #[derive(Clone, Debug)] pub struct TransactionsView { + account_balances_by_transaction_id: HashMap, buckets: Vec, navigation: Navigation, transactions_by_account_id: HashMap>, @@ -42,13 +43,30 @@ impl TransactionsView { account_navigation_entries.first().cloned(), account_navigation_entries, ); - Self { + let mut transactions_view = Self { + account_balances_by_transaction_id: HashMap::with_capacity(transactions.len()), buckets: buckets.to_vec(), navigation: navigation, - transactions_by_account_id: transactions - .into_iter() - .cloned() - .into_group_map_by(|t| t.account_id), + transactions_by_account_id: HashMap::with_capacity(accounts.len()), + }; + transactions_view.set_transactions(transactions); + transactions_view + } + + fn set_transactions(&mut self, transactions: &[Transaction]) { + self.transactions_by_account_id = transactions + .into_iter() + .cloned() + .into_group_map_by(|t| t.account_id); + self.account_balances_by_transaction_id = HashMap::new(); + for entry in self.transactions_by_account_id.iter_mut() { + entry.1.sort_by(|t1, t2| t2.date.cmp(&t1.date)); + let mut running_balance = 0; + for transaction in entry.1.iter().rev() { + running_balance += transaction.amount; + self.account_balances_by_transaction_id + .insert(transaction.id, running_balance); + } } } } @@ -72,8 +90,7 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { } Message::SetTransactions(transactions) => { - self.transactions_by_account_id = - transactions.into_iter().into_group_map_by(|t| t.account_id); + self.set_transactions(&transactions); Action::None } diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index f43ee48..4f61493 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use iced::{ alignment, widget::{ @@ -38,7 +40,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { ), column( Text::default("Balance").width(iced::Length::Fixed(96.0)), - |_t: Transaction| view_balance_cell(), + |t: Transaction| view_balance_cell(t, &self.account_balances_by_transaction_id), ), ]; @@ -106,9 +108,17 @@ fn view_quantity_cell(t: Transaction) -> Text { .align_right() } -fn view_balance_cell() -> Text { - Text::default("TODO") - .width(iced::Length::Fixed(96.0)) - .small() - .clip() +fn view_balance_cell( + transaction: Transaction, + account_balances_by_transaction_id: &HashMap, +) -> Text { + (account_balances_by_transaction_id + .get(&transaction.id) + .map_or_else( + || Text::default("Error").danger(), + |&balance| Text::currency(balance), + )) + .width(iced::Length::Fixed(96.0)) + .small() + .clip() } -- cgit v1.2.3 From 4030a63ac6fe61df87dca07e4143a6b84a9e8475 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 21:34:24 +0000 Subject: task-085: include account transfers --- schist_core/schist_models/src/account_transfer.rs | 2 +- schist_core/schist_models/src/date_utc.rs | 1 + schist_core/schist_models/src/transaction.rs | 11 +- schist_desktop_gui/src/gui.rs | 18 +- schist_desktop_gui/src/gui/components/text.rs | 7 + .../src/gui/components/transactions_view.rs | 235 ++++++++++++++++++--- .../transactions_view/view_transactions_view.rs | 61 ++---- .../src/gui/screens/main_screen/main_screen.rs | 13 +- 8 files changed, 275 insertions(+), 73 deletions(-) diff --git a/schist_core/schist_models/src/account_transfer.rs b/schist_core/schist_models/src/account_transfer.rs index ba33dee..11a14a1 100644 --- a/schist_core/schist_models/src/account_transfer.rs +++ b/schist_core/schist_models/src/account_transfer.rs @@ -3,7 +3,7 @@ use diesel::prelude::{Identifiable, Insertable, Queryable, Selectable}; use crate::date_utc::DateUtc; -#[derive(Builder, Queryable, Identifiable, Selectable, Debug, PartialEq, Insertable)] +#[derive(Builder, Clone, Queryable, Identifiable, Selectable, Debug, PartialEq, Eq, Insertable)] #[diesel(table_name = crate::schema::account_transfers)] pub struct AccountTransfer { pub id: i32, diff --git a/schist_core/schist_models/src/date_utc.rs b/schist_core/schist_models/src/date_utc.rs index 658a8dd..e4363a7 100644 --- a/schist_core/schist_models/src/date_utc.rs +++ b/schist_core/schist_models/src/date_utc.rs @@ -26,6 +26,7 @@ use crate::datetime_utc::DatetimeUtc; Clone, Copy, Debug, + Hash, AsExpression, FromSqlRow, )] diff --git a/schist_core/schist_models/src/transaction.rs b/schist_core/schist_models/src/transaction.rs index 7e754be..ef0a0ab 100644 --- a/schist_core/schist_models/src/transaction.rs +++ b/schist_core/schist_models/src/transaction.rs @@ -4,7 +4,16 @@ use diesel::prelude::{Associations, Identifiable, Insertable, Queryable, Selecta use crate::{account::Account, date_utc::DateUtc}; #[derive( - Builder, Clone, Queryable, Identifiable, Selectable, Insertable, Associations, Debug, PartialEq, + Builder, + Clone, + Queryable, + Identifiable, + Selectable, + Insertable, + Associations, + Debug, + PartialEq, + Eq, )] #[diesel(table_name = crate::schema::transactions)] #[diesel(belongs_to(Account))] diff --git a/schist_desktop_gui/src/gui.rs b/schist_desktop_gui/src/gui.rs index 9648ff0..78fea11 100644 --- a/schist_desktop_gui/src/gui.rs +++ b/schist_desktop_gui/src/gui.rs @@ -7,9 +7,10 @@ use std::{path::PathBuf, str::FromStr}; use diesel::SqliteConnection; use iced::{Element, Task}; -use schist_models::{Account, Bucket, Transaction}; +use schist_models::{Account, AccountTransfer, Bucket, Transaction}; use schist_queries::{ - accounts::get_all_accounts, buckets::get_all_buckets, transactions::get_all_transactions, + account_transfers::get_all_account_transfers, accounts::get_all_accounts, + buckets::get_all_buckets, transactions::get_all_transactions, }; use crate::{ @@ -33,6 +34,7 @@ pub enum Message { FilesScreenMessage(files_screen::Message), MainScreenMessage(main_screen::Message), RefetchedAccounts(FetchResult>), + RefetchedAccountTransfers(FetchResult>), RefetchedBuckets(FetchResult>), RefetchedTransactions(FetchResult>), } @@ -188,6 +190,16 @@ impl Gui { } iced::Task::none() } + Message::RefetchedAccountTransfers(account_transfers) => { + match account_transfers { + Ok(account_transfers) => { + self.main_screen + .update(main_screen::Message::SetAccountTransfers(account_transfers)); + } + Err(err) => println!("Failed to get account transfers: {:?}", err.message), + } + iced::Task::none() + } Message::RefetchedTransactions(transactions) => { match transactions { Ok(transactions) => { @@ -239,6 +251,7 @@ impl Gui { ) -> Task { let buckets = get_all_buckets(&mut connection).map_err(FetchError::new); let accounts = get_all_accounts(&mut connection).map_err(FetchError::new); + let account_transfers = get_all_account_transfers(&mut connection).map_err(FetchError::new); let transactions = get_all_transactions(&mut connection).map_err(FetchError::new); self.connection = Some(connection); self.active_screen = Screen::MainScreen; @@ -250,6 +263,7 @@ impl Gui { iced::Task::batch(vec![ self.update(Message::RefetchedBuckets(buckets)), self.update(Message::RefetchedAccounts(accounts)), + self.update(Message::RefetchedAccountTransfers(account_transfers)), self.update(Message::RefetchedTransactions(transactions)), ]) } diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index 0cf9698..068e89a 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -160,6 +160,13 @@ impl Text { ..self.clone() } } + + pub fn style(&self, font_style: font::Style) -> Self { + Self { + font_style, + ..self.clone() + } + } } impl<'a, Message> From for iced::Element<'a, Message> diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 27e18cd..a52c419 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -1,9 +1,10 @@ mod view_transactions_view; -use std::{collections::HashMap, mem::transmute}; +use std::collections::{HashMap, VecDeque}; +use iced::font; use itertools::Itertools; -use schist_models::{Account, Bucket, Transaction}; +use schist_models::{Account, AccountTransfer, Bucket, DateUtc, Transaction}; use crate::{ gui::components::{navigation, AccountNavigationEntry, Navigation}, @@ -12,10 +13,12 @@ use crate::{ #[derive(Clone, Debug)] pub struct TransactionsView { - account_balances_by_transaction_id: HashMap, + accounts: Vec, + account_transfers: Vec, buckets: Vec, navigation: Navigation, - transactions_by_account_id: HashMap>, + transactions: Vec, + transaction_rows_by_account_id: HashMap>, } #[derive(Clone, Debug)] @@ -24,6 +27,7 @@ pub enum Message { SelectNextAccount, SelectPrevAccount, SetAccounts(Vec), + SetAccountTransfers(Vec), SetBuckets(Vec), SetTransactions(Vec), } @@ -32,8 +36,134 @@ pub enum Action { None, } +#[derive(Debug, PartialEq, Eq)] +struct TransactionRowWithoutAggregations { + amount: i32, + bucket: String, + bucket_font_style: font::Style, + date: DateUtc, + payee: String, + payee_font_style: font::Style, +} + +impl TransactionRowWithoutAggregations { + fn from_transaction( + account_id: i32, + transaction: &Transaction, + buckets: &[Bucket], + ) -> Option { + if transaction.account_id == account_id { + let (bucket, bucket_font_style) = match transaction.bucket_id { + Some(bucket_id) => match buckets.iter().find(|b| b.id == bucket_id) { + Some(bucket) => (bucket.name.clone(), font::Style::Normal), + None => (format!("Bucket <{}>", bucket_id), font::Style::Italic), + }, + None => (String::from("None"), font::Style::Italic), + }; + Some(Self { + amount: transaction.amount, + bucket, + bucket_font_style, + date: transaction.date, + payee: transaction.counterparty.clone(), + payee_font_style: font::Style::Normal, + }) + } else { + None + } + } + + fn from_account_transfer( + account_id: i32, + account_transfer: &AccountTransfer, + accounts: &[Account], + ) -> Option { + if account_transfer.from_account_id == account_id { + let (payee, payee_font_style) = if let Some(account) = accounts + .iter() + .find(|a| a.id == account_transfer.to_account_id) + { + (account.name.clone(), font::Style::Normal) + } else { + (format!("<{}>", account_id), font::Style::Italic) + }; + Some(Self { + amount: -account_transfer.amount, + bucket: String::from("Account transfer"), + bucket_font_style: font::Style::Italic, + date: account_transfer.date, + payee, + payee_font_style, + }) + } else if account_transfer.to_account_id == account_id { + let (payee, payee_font_style) = if let Some(account) = accounts + .iter() + .find(|a| a.id == account_transfer.from_account_id) + { + (account.name.clone(), font::Style::Normal) + } else { + (format!("Account <{}>", account_id), font::Style::Italic) + }; + Some(Self { + amount: account_transfer.amount, + bucket: String::from("Account transfer"), + bucket_font_style: font::Style::Italic, + date: account_transfer.date, + payee, + payee_font_style, + }) + } else { + None + } + } + + fn with_aggregations(self, balance: i32) -> TransactionRow { + TransactionRow { + amount: self.amount, + balance, + bucket: self.bucket, + bucket_font_style: self.bucket_font_style, + date: self.date, + payee: self.payee, + payee_font_style: self.payee_font_style, + } + } + + fn compare_date_desc(&self, other: &Self) -> std::cmp::Ordering { + other.date.cmp(&self.date) + } +} + +impl std::cmp::PartialOrd for TransactionRowWithoutAggregations { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.compare_date_desc(other)) + } +} + +impl std::cmp::Ord for TransactionRowWithoutAggregations { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.compare_date_desc(other) + } +} + +#[derive(Clone, Debug, Hash)] +struct TransactionRow { + amount: i32, + balance: i32, + bucket: String, + bucket_font_style: font::Style, + date: DateUtc, + payee: String, + payee_font_style: font::Style, +} + impl TransactionsView { - pub fn new(accounts: &[Account], buckets: &[Bucket], transactions: &[Transaction]) -> Self { + pub fn new( + accounts: &[Account], + account_transfers: &[AccountTransfer], + buckets: &[Bucket], + transactions: &[Transaction], + ) -> Self { let account_navigation_entries: Vec = accounts .iter() .cloned() @@ -43,30 +173,15 @@ impl TransactionsView { account_navigation_entries.first().cloned(), account_navigation_entries, ); - let mut transactions_view = Self { - account_balances_by_transaction_id: HashMap::with_capacity(transactions.len()), + let transaction_rows_by_account_id = + calculate_rows(accounts, account_transfers, buckets, transactions); + Self { + accounts: accounts.to_vec(), + account_transfers: account_transfers.to_vec(), buckets: buckets.to_vec(), navigation: navigation, - transactions_by_account_id: HashMap::with_capacity(accounts.len()), - }; - transactions_view.set_transactions(transactions); - transactions_view - } - - fn set_transactions(&mut self, transactions: &[Transaction]) { - self.transactions_by_account_id = transactions - .into_iter() - .cloned() - .into_group_map_by(|t| t.account_id); - self.account_balances_by_transaction_id = HashMap::new(); - for entry in self.transactions_by_account_id.iter_mut() { - entry.1.sort_by(|t1, t2| t2.date.cmp(&t1.date)); - let mut running_balance = 0; - for transaction in entry.1.iter().rev() { - running_balance += transaction.amount; - self.account_balances_by_transaction_id - .insert(transaction.id, running_balance); - } + transactions: transactions.to_vec(), + transaction_rows_by_account_id, } } } @@ -77,6 +192,13 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { Message::NavigationMessage(message) => self.update_navigation(message), Message::SetAccounts(accounts) => { + self.accounts = accounts.clone(); + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); let account_navigation_entries: Vec = accounts .into_iter() .map(AccountNavigationEntry::new) @@ -84,13 +206,36 @@ impl<'a> Component<'a, Message, Action> for TransactionsView { self.update_navigation(navigation::Message::SetOptions(account_navigation_entries)) } + Message::SetAccountTransfers(account_transfers) => { + self.account_transfers = account_transfers; + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); + Action::None + } + Message::SetBuckets(buckets) => { self.buckets = buckets; + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); Action::None } Message::SetTransactions(transactions) => { - self.set_transactions(&transactions); + self.transactions = transactions; + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); Action::None } @@ -114,3 +259,37 @@ impl TransactionsView { } } } + +fn calculate_rows( + accounts: &[Account], + account_transfers: &[AccountTransfer], + buckets: &[Bucket], + transactions: &[Transaction], +) -> HashMap> { + HashMap::from_iter(accounts.iter().map(|account| { + let transaction_rows_without_aggs = transactions + .iter() + .filter_map(|t| { + TransactionRowWithoutAggregations::from_transaction(account.id, t, buckets) + }) + .chain(account_transfers.iter().filter_map(|at| { + TransactionRowWithoutAggregations::from_account_transfer(account.id, at, accounts) + })) + .sorted(); + + let mut running_balance: i32 = 0; + let mut transaction_rows = VecDeque::with_capacity(transaction_rows_without_aggs.len()); + for row in transaction_rows_without_aggs.rev() { + if running_balance.checked_add(row.amount).is_none() { + panic!( + "can't add {} + {}. row: {:?}", + running_balance, row.amount, row + ); + } + running_balance += row.amount; + transaction_rows.push_front(row.with_aggregations(running_balance)); + } + + (account.id, transaction_rows.into()) + })) +} diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index 4f61493..1427830 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use iced::{ alignment, widget::{ @@ -11,11 +9,10 @@ use iced::{ }, Element, Length, }; -use schist_models::{Bucket, Transaction}; use crate::{gui::components::Text, style::SPACING_LG, traits::Viewable}; -use super::{Message, TransactionsView}; +use super::{Message, TransactionRow, TransactionsView}; impl<'a> Viewable<'a, Message> for TransactionsView { fn view(&'a self) -> Element<'a, Message> { @@ -28,7 +25,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { ), column( Text::default("Bucket").width(iced::Length::Fixed(128.0)), - |t: Transaction| view_bucket_cell(t, &self.buckets), + view_bucket_cell, ), column( Text::default("Payee").width(iced::Length::Fixed(256.0)), @@ -40,7 +37,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { ), column( Text::default("Balance").width(iced::Length::Fixed(96.0)), - |t: Transaction| view_balance_cell(t, &self.account_balances_by_transaction_id), + view_balance_cell, ), ]; @@ -49,7 +46,7 @@ impl<'a> Viewable<'a, Message> for TransactionsView { .active_option .clone() .map_or_else(Vec::default, |option| { - self.transactions_by_account_id + self.transaction_rows_by_account_id .get(&option.account.id) .cloned() .unwrap_or_else(Vec::default) @@ -71,54 +68,40 @@ impl<'a> Viewable<'a, Message> for TransactionsView { } } -fn view_date_cell(transaction: Transaction) -> Text { - Text::default(transaction.date.format("%e %b %Y").as_str()) +fn view_date_cell(row: TransactionRow) -> Text { + Text::default(row.date.format("%e %b %Y").as_str()) .width(iced::Length::Fixed(128.0)) .small() .clip() } -fn view_bucket_cell(t: Transaction, buckets: &[Bucket]) -> Text { - (t.bucket_id.map_or_else( - || Text::default("None").italic(), - |id| { - buckets.iter().find(|b| b.id == id).map_or_else( - || Text::default(format!("<{}>", id).as_str()).italic(), - |b| Text::default(&b.name), - ) - }, - )) - .width(iced::Length::Fixed(128.0)) - .small() - .clip() +fn view_bucket_cell(row: TransactionRow) -> Text { + Text::default(&row.bucket) + .style(row.bucket_font_style) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() } -fn view_payee_cell(t: Transaction) -> Text { - Text::default(&t.counterparty) +fn view_payee_cell(row: TransactionRow) -> Text { + Text::default(&row.payee) + .style(row.payee_font_style) .width(iced::Length::Fixed(256.0)) .small() .clip() } -fn view_quantity_cell(t: Transaction) -> Text { - Text::currency(t.amount) +fn view_quantity_cell(row: TransactionRow) -> Text { + Text::currency(row.amount) .width(iced::Length::Fixed(96.0)) .small() .clip() .align_right() } -fn view_balance_cell( - transaction: Transaction, - account_balances_by_transaction_id: &HashMap, -) -> Text { - (account_balances_by_transaction_id - .get(&transaction.id) - .map_or_else( - || Text::default("Error").danger(), - |&balance| Text::currency(balance), - )) - .width(iced::Length::Fixed(96.0)) - .small() - .clip() +fn view_balance_cell(row: TransactionRow) -> Text { + Text::currency(row.balance) + .width(iced::Length::Fixed(96.0)) + .small() + .clip() } diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 038d65f..6580758 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -4,7 +4,7 @@ use iced::{ widget::{row, Container}, Element, Length, }; -use schist_models::{Account, Bucket, Transaction}; +use schist_models::{Account, AccountTransfer, Bucket, Transaction}; use crate::{ gui::components::{ @@ -35,6 +35,7 @@ pub enum Message { TransactionsViewMessage(transactions_view::Message), SelectView(View), SetAccounts(Vec), + SetAccountTransfers(Vec), SetBuckets(Vec), SetTransactions(Vec), ViewNavigationMessage(navigation::Message), @@ -121,6 +122,14 @@ impl<'a> Component<'a, Message, Action> for MainScreen { Action::None } + Message::SetAccountTransfers(account_transfers) => { + self.transactions_view + .update(transactions_view::Message::SetAccountTransfers( + account_transfers, + )); + Action::None + } + Message::SetTransactions(transactions) => { self.transactions_view .update(transactions_view::Message::SetTransactions(transactions)); @@ -206,7 +215,7 @@ impl MainScreen { balances_view: BalancesView::new(Vec::new()), buckets: Vec::new(), buckets_view: BucketsView::new(Vec::new(), "Hello, buckets!"), - transactions_view: TransactionsView::new(&[], &[], &[]), + transactions_view: TransactionsView::new(&[], &[], &[], &[]), active_view: View::Balances, view_navigation: Navigation::new(Some(View::Balances), View::views()), } -- cgit v1.2.3 From 1bf1819e9e28dec7a1983269377238258286b3c7 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 21:36:54 +0000 Subject: task-085: align balance right --- .../gui/components/transactions_view/view_transactions_view.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs index 1427830..268984b 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -32,11 +32,15 @@ impl<'a> Viewable<'a, Message> for TransactionsView { view_payee_cell, ), column( - Text::default("Quantity").width(iced::Length::Fixed(96.0)), + Text::default("Quantity") + .width(iced::Length::Fixed(96.0)) + .align_right(), view_quantity_cell, ), column( - Text::default("Balance").width(iced::Length::Fixed(96.0)), + Text::default("Balance") + .width(iced::Length::Fixed(96.0)) + .align_right(), view_balance_cell, ), ]; @@ -104,4 +108,5 @@ fn view_balance_cell(row: TransactionRow) -> Text { .width(iced::Length::Fixed(96.0)) .small() .clip() + .align_right() } -- cgit v1.2.3 From c643f80b1763595b19654a9303126801d898d9b6 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 21:37:30 +0000 Subject: mark task-085 done --- requirements/kanban.md | 2 +- requirements/tasks/epic-000.md | 2 +- requirements/tasks/task-085.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/kanban.md b/requirements/kanban.md index 5e09287..0492299 100644 --- a/requirements/kanban.md +++ b/requirements/kanban.md @@ -4,7 +4,7 @@ | -------- | -------- | -------- | | | | epic-000 | | ======== | ======== | ======== | -| | task-001 | task-085 | +| | task-001 | | | | task-064 | | | | task-086 | | | | task-030 | | diff --git a/requirements/tasks/epic-000.md b/requirements/tasks/epic-000.md index 00e3b92..22a08f6 100644 --- a/requirements/tasks/epic-000.md +++ b/requirements/tasks/epic-000.md @@ -13,7 +13,7 @@ Status: in progress - [x] task-072 (import from Actualbudget) - [x] task-089 (keyboard nav in files screen) - [x] task-088 (caching open file) -- [ ] task-085 (view transactions) +- [x] task-085 (view transactions) - [ ] task-001 (inserting transactions) - [ ] task-064 (deleting transactions) - [ ] task-086 (buckets navigation formatting) diff --git a/requirements/tasks/task-085.md b/requirements/tasks/task-085.md index 04267d4..e19b75d 100644 --- a/requirements/tasks/task-085.md +++ b/requirements/tasks/task-085.md @@ -11,7 +11,7 @@ It should have these columns: - Quantity - Balance -Status: doing +Status: done Epic: epic-000 -- cgit v1.2.3 From f3659bd8e9d5e20528aaa1e0e7c1b206fb0eb31c Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Sun, 22 Feb 2026 21:39:43 +0000 Subject: adds task-090 (tech debt) --- requirements/tasks/task-090.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 requirements/tasks/task-090.md diff --git a/requirements/tasks/task-090.md b/requirements/tasks/task-090.md new file mode 100644 index 0000000..cabde69 --- /dev/null +++ b/requirements/tasks/task-090.md @@ -0,0 +1,8 @@ +# task-090 + +Schist's desktop GUI should manage aggregations globally instead of inside the +components. + +Source: tech debt + +Epic: tech debt -- cgit v1.2.3