summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2025-08-25 16:35:45 +0000
committerjoeac <me@joeac.net>2025-08-25 16:35:45 +0000
commitfe85652e4d3e8906824baddaafd05d19105579b8 (patch)
tree31b56e31cbf289a34ec1d6707becf3c60933b56f /schist_desktop_gui/src/gui
parentd082a30de6a0cbd1fbe2ab5a4316db0891004129 (diff)
task-072
Co-authored-by: Joe Carstairs <jcarstairs@scottlogic.com> Reviewed-on: https://git.joeac.net/joeac/schist/pulls/3 Co-authored-by: Joe Carstairs <me@joeac.net> Co-committed-by: Joe Carstairs <me@joeac.net>
Diffstat (limited to 'schist_desktop_gui/src/gui')
-rw-r--r--schist_desktop_gui/src/gui/components.rs2
-rw-r--r--schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs3
-rw-r--r--schist_desktop_gui/src/gui/components/balances_view/view_group_names.rs40
-rw-r--r--schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs11
-rw-r--r--schist_desktop_gui/src/gui/components/buckets_view.rs4
-rw-r--r--schist_desktop_gui/src/gui/components/button.rs21
-rw-r--r--schist_desktop_gui/src/gui/components/text.rs94
-rw-r--r--schist_desktop_gui/src/gui/components/transactions_view.rs4
-rw-r--r--schist_desktop_gui/src/gui/screens.rs5
-rw-r--r--schist_desktop_gui/src/gui/screens/files_screen.rs36
-rw-r--r--schist_desktop_gui/src/gui/screens/files_screen/update_files_screen.rs125
-rw-r--r--schist_desktop_gui/src/gui/screens/files_screen/view_files_screen.rs106
-rw-r--r--schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs10
-rw-r--r--schist_desktop_gui/src/gui/screens/main_screen/view.rs4
14 files changed, 416 insertions, 49 deletions
diff --git a/schist_desktop_gui/src/gui/components.rs b/schist_desktop_gui/src/gui/components.rs
index fc3c838..a242b0b 100644
--- a/schist_desktop_gui/src/gui/components.rs
+++ b/schist_desktop_gui/src/gui/components.rs
@@ -9,7 +9,7 @@ pub mod transactions_view;
pub use balances_view::BalancesView;
pub use bucket_name_and_balance::BucketNameAndBalance;
pub use buckets_view::BucketsView;
-pub use button::{active_button, inactive_button};
+pub use button::{active_button, inactive_button, panel_button};
pub use navigation::Navigation;
pub use text::Text;
pub use transactions_view::TransactionsView;
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 e8a1e46..6a64508 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
@@ -1,6 +1,7 @@
use iced::widget::{column, row, Container};
use iced::{alignment, Element, Length};
+use crate::gui::components::Text;
use crate::gui::components::{balances_view::Message, BalancesView};
use crate::style::SPACING_LG;
use crate::traits::Viewable;
@@ -10,7 +11,7 @@ pub fn view_balances_view<'a>(balances_view: &'a BalancesView) -> Element<'a, Me
.navigation
.view()
.map(Message::NavigationMessage);
- let main_content = column![iced::widget::text(balances_view.greeting.clone())];
+ let main_content = column![Text::default(&balances_view.greeting).as_element()];
row![
Container::new(navigation).width(Length::FillPortion(1)),
Container::new(main_content).width(Length::FillPortion(3)),
diff --git a/schist_desktop_gui/src/gui/components/balances_view/view_group_names.rs b/schist_desktop_gui/src/gui/components/balances_view/view_group_names.rs
index 271e76c..18ddf0b 100644
--- a/schist_desktop_gui/src/gui/components/balances_view/view_group_names.rs
+++ b/schist_desktop_gui/src/gui/components/balances_view/view_group_names.rs
@@ -6,7 +6,7 @@ use crate::gui::components::Text;
pub fn view_group_names(buckets: Vec<Bucket>) -> Vec<Text> {
buckets
.iter()
- .map(|b| b.group.clone())
+ .map(|b| b.group.as_str())
.unique()
.map(Text::new)
.collect()
@@ -96,23 +96,23 @@ mod test {
];
let group_names = view_group_names(buckets);
assert_eq!(17, group_names.len());
- assert_eq!(group_names[0], Text::new(String::from("hydrogen")));
- assert_eq!(group_names[1], Text::new(String::from("helium")));
- assert_eq!(group_names[2], Text::new(String::from("lithium")));
- assert_eq!(group_names[3], Text::new(String::from("beryllium")));
- assert_eq!(group_names[4], Text::new(String::from("boron")));
- assert_eq!(group_names[5], Text::new(String::from("carbon")));
- assert_eq!(group_names[6], Text::new(String::from("nitrogen")));
- assert_eq!(group_names[7], Text::new(String::from("oxygen")));
- assert_eq!(group_names[8], Text::new(String::from("flourine")));
- assert_eq!(group_names[9], Text::new(String::from("neon")));
- assert_eq!(group_names[10], Text::new(String::from("magnesium")));
- assert_eq!(group_names[11], Text::new(String::from("aluminium")));
- assert_eq!(group_names[12], Text::new(String::from("silicon")));
- assert_eq!(group_names[13], Text::new(String::from("phosphorus")));
- assert_eq!(group_names[14], Text::new(String::from("sulphur")));
- assert_eq!(group_names[15], Text::new(String::from("chlorine")));
- assert_eq!(group_names[16], Text::new(String::from("argon")));
+ assert_eq!(group_names[0], Text::new("hydrogen"));
+ assert_eq!(group_names[1], Text::new("helium"));
+ assert_eq!(group_names[2], Text::new("lithium"));
+ assert_eq!(group_names[3], Text::new("beryllium"));
+ assert_eq!(group_names[4], Text::new("boron"));
+ assert_eq!(group_names[5], Text::new("carbon"));
+ assert_eq!(group_names[6], Text::new("nitrogen"));
+ assert_eq!(group_names[7], Text::new("oxygen"));
+ assert_eq!(group_names[8], Text::new("flourine"));
+ assert_eq!(group_names[9], Text::new("neon"));
+ assert_eq!(group_names[10], Text::new("magnesium"));
+ assert_eq!(group_names[11], Text::new("aluminium"));
+ assert_eq!(group_names[12], Text::new("silicon"));
+ assert_eq!(group_names[13], Text::new("phosphorus"));
+ assert_eq!(group_names[14], Text::new("sulphur"));
+ assert_eq!(group_names[15], Text::new("chlorine"));
+ assert_eq!(group_names[16], Text::new("argon"));
}
#[test]
@@ -134,8 +134,8 @@ mod test {
let group_names = view_group_names(buckets);
assert_eq!(
vec![
- Text::new(String::from("hydrogen")),
- Text::new(String::from("helium")),
+ Text::new("hydrogen"),
+ Text::new("helium"),
],
group_names
);
diff --git a/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs b/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs
index db3fc2e..24a3952 100644
--- a/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs
+++ b/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs
@@ -1,10 +1,7 @@
-use iced::{
- widget::{row, text},
- Element,
-};
+use iced::{widget::row, Element};
use schist_models::Bucket;
-use crate::gui::components::navigation;
+use crate::gui::components::{navigation, Text};
#[derive(Clone, Debug, PartialEq)]
pub struct BucketNameAndBalance {
@@ -20,8 +17,8 @@ impl BucketNameAndBalance {
impl<'a> Into<Element<'a, navigation::Message<BucketNameAndBalance>>> for BucketNameAndBalance {
fn into(self) -> Element<'a, navigation::Message<BucketNameAndBalance>> {
row![
- text(self.bucket.name.clone()),
- text(self.bucket.balance.unwrap_or(0))
+ Text::new(&self.bucket.name).as_element(),
+ Text::new(&self.bucket.balance.unwrap_or(0).to_string()).as_element(),
]
.into()
}
diff --git a/schist_desktop_gui/src/gui/components/buckets_view.rs b/schist_desktop_gui/src/gui/components/buckets_view.rs
index bb4dbb4..e513a35 100644
--- a/schist_desktop_gui/src/gui/components/buckets_view.rs
+++ b/schist_desktop_gui/src/gui/components/buckets_view.rs
@@ -6,7 +6,7 @@ use iced::{
use schist_models::Bucket;
use crate::{
- gui::components::{navigation, BucketNameAndBalance, Navigation},
+ gui::components::{navigation, BucketNameAndBalance, Navigation, Text},
style::SPACING_LG,
traits::{Component, Viewable},
};
@@ -53,7 +53,7 @@ impl<'a> Viewable<'a, Message> for BucketsView {
Message: 'a,
{
let navigation = self.navigation.view().map(Message::NavigationMessage);
- let main_content = column![iced::widget::text(self.greeting.clone())];
+ let main_content = column![Text::default(&self.greeting).as_element()];
row![
Container::new(navigation).width(Length::FillPortion(1)),
Container::new(main_content).width(Length::FillPortion(3)),
diff --git a/schist_desktop_gui/src/gui/components/button.rs b/schist_desktop_gui/src/gui/components/button.rs
index bc9e5f9..e071f33 100644
--- a/schist_desktop_gui/src/gui/components/button.rs
+++ b/schist_desktop_gui/src/gui/components/button.rs
@@ -1,5 +1,7 @@
use iced::{widget::Button, Element};
+use crate::style::*;
+
pub fn active_button<'a, Content: Into<Element<'a, Message>>, Message>(
content: Content,
) -> Button<'a, Message> {
@@ -22,3 +24,22 @@ pub fn inactive_button<'a, Content: Into<Element<'a, Message>>, Message>(
.on_press(on_press)
.width(iced::Length::Fill)
}
+
+pub fn panel_button<'a, Content: Into<Element<'a, Message>>, Message>(
+ content: Content,
+ on_press: Message,
+) -> Button<'a, Message> {
+ iced::widget::button(content)
+ .on_press(on_press)
+ .style(|theme: &iced::Theme, _status| iced::widget::button::Style {
+ background: None,
+ border: iced::Border {
+ color: theme.extended_palette().primary.base.text,
+ radius: iced::border::Radius::new(0),
+ width: 2.0,
+ },
+ ..Default::default()
+ })
+ .width(iced::Length::Fill)
+ .padding(iced::Padding::new(SPACING_MD.into()))
+}
diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs
index d334de3..90cd7bc 100644
--- a/schist_desktop_gui/src/gui/components/text.rs
+++ b/schist_desktop_gui/src/gui/components/text.rs
@@ -1,22 +1,100 @@
-use iced::Element;
-
-use crate::gui::components::navigation;
+use crate::style::*;
#[derive(Clone, Debug, PartialEq)]
pub struct Text {
pub content: String,
+ colour: Option<Colour>,
+ size: Option<Size>,
+ strength: Option<Strength>,
+}
+
+#[derive(Clone, Debug, PartialEq)]
+enum Colour {
+ Danger,
+ Primary,
+}
+
+#[derive(Clone, Debug, PartialEq)]
+enum Strength {
+ Base,
+ Weak,
+}
+
+#[derive(Clone, Debug, PartialEq)]
+enum Size {
+ Small,
+ Base,
}
impl Text {
- pub fn new(group_name: String) -> Self {
+ pub fn default(content: &str) -> Self {
+ Self {
+ content: String::from(content),
+ colour: Some(Colour::Primary),
+ size: Some(Size::Base),
+ strength: Some(Strength::Base),
+ }
+ }
+
+ pub fn new(content: &str) -> Self {
+ Self {
+ content: String::from(content),
+ colour: None,
+ size: None,
+ strength: None,
+ }
+ }
+
+ pub fn as_element<'a, Message>(self) -> iced::Element<'a, Message> {
+ <Self as Into<iced::Element<'a, Message>>>::into(self)
+ }
+
+ pub fn small(&self) -> Self {
+ Self {
+ size: Some(Size::Small),
+ ..self.clone()
+ }
+ }
+
+ pub fn danger(&self) -> Self {
+ Self {
+ colour: Some(Colour::Danger),
+ ..self.clone()
+ }
+ }
+
+ pub fn weak(&self) -> Self {
Self {
- content: group_name.clone(),
+ strength: Some(Strength::Weak),
+ ..self.clone()
}
}
}
-impl<'a> Into<Element<'a, navigation::Message<Text>>> for Text {
- fn into(self) -> Element<'a, navigation::Message<Text>> {
- iced::widget::text(self.content.clone()).into()
+impl<'a, Message> Into<iced::Element<'a, Message>> for Text {
+ fn into(self) -> iced::Element<'a, Message> {
+ iced::widget::text(self.content.clone())
+ .size(match self.size {
+ Some(Size::Small) => TEXT_SIZE_SM,
+ Some(Size::Base) | None => TEXT_SIZE_BASE,
+ })
+ .style(move |theme: &iced::Theme| iced::widget::text::Style {
+ color: match (&self.colour, &self.strength) {
+ (Some(Colour::Danger), Some(Strength::Base) | None) => {
+ Some(theme.extended_palette().danger.base.text)
+ }
+ (Some(Colour::Danger), Some(Strength::Weak)) => {
+ Some(theme.extended_palette().danger.weak.text)
+ }
+ (Some(Colour::Primary), Some(Strength::Base) | None) => {
+ Some(theme.extended_palette().primary.base.text)
+ }
+ (Some(Colour::Primary), Some(Strength::Weak)) => {
+ Some(theme.extended_palette().primary.weak.text)
+ }
+ (None, _) => None,
+ },
+ })
+ .into()
}
}
diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs
index 88532a9..1956d38 100644
--- a/schist_desktop_gui/src/gui/components/transactions_view.rs
+++ b/schist_desktop_gui/src/gui/components/transactions_view.rs
@@ -45,7 +45,7 @@ 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![iced::widget::text(self.greeting.clone())];
+ let main_content = column![Text::default(&self.greeting).as_element()];
row![
Container::new(navigation).width(Length::FillPortion(1)),
Container::new(main_content).width(Length::FillPortion(3)),
@@ -113,6 +113,6 @@ fn make_greeting(account_name: Text) -> String {
fn view_account_names(accounts: Vec<Account>) -> Vec<Text> {
accounts
.iter()
- .map(|acc| Text::new(acc.name.clone()))
+ .map(|acc| Text::new(acc.name.as_str()))
.collect()
}
diff --git a/schist_desktop_gui/src/gui/screens.rs b/schist_desktop_gui/src/gui/screens.rs
index 3ae97dd..abca2b6 100644
--- a/schist_desktop_gui/src/gui/screens.rs
+++ b/schist_desktop_gui/src/gui/screens.rs
@@ -1,9 +1,12 @@
+pub mod files_screen;
pub mod main_screen;
+pub use files_screen::FilesScreen;
pub use main_screen::MainScreen;
#[derive(Default)]
pub enum Screen {
#[default]
- Main,
+ FilesScreen,
+ MainScreen,
}
diff --git a/schist_desktop_gui/src/gui/screens/files_screen.rs b/schist_desktop_gui/src/gui/screens/files_screen.rs
new file mode 100644
index 0000000..68a9556
--- /dev/null
+++ b/schist_desktop_gui/src/gui/screens/files_screen.rs
@@ -0,0 +1,36 @@
+mod update_files_screen;
+mod view_files_screen;
+
+use std::{fmt::Debug, path::PathBuf};
+
+use crate::DatabaseConnection;
+
+pub struct FilesScreen {
+ new_file_err: Option<(PathBuf, String)>,
+ file_paths: Vec<PathBuf>,
+ open_file_err: Option<(PathBuf, String)>,
+}
+
+#[derive(Clone, Debug)]
+pub enum Message {
+ ImportFromActualbudget,
+ NewFile,
+ OpenFile(std::path::PathBuf),
+ PickFile,
+}
+
+#[derive(Debug)]
+pub enum Action {
+ None,
+ OpenedFile(DatabaseConnection),
+}
+
+impl<'a> FilesScreen {
+ pub fn new(file_paths: &'a [PathBuf]) -> Self {
+ Self {
+ file_paths: file_paths.to_vec(),
+ new_file_err: None,
+ open_file_err: None,
+ }
+ }
+}
diff --git a/schist_desktop_gui/src/gui/screens/files_screen/update_files_screen.rs b/schist_desktop_gui/src/gui/screens/files_screen/update_files_screen.rs
new file mode 100644
index 0000000..9c45d6e
--- /dev/null
+++ b/schist_desktop_gui/src/gui/screens/files_screen/update_files_screen.rs
@@ -0,0 +1,125 @@
+use actualbudget_to_schist_transformer::schist_state::{export_schist_state, SchistState};
+use itertools::Itertools;
+
+use crate::{
+ database_connection::DatabaseConnectionResult,
+ dialog::{import_from_actualbudget_dialog, new_file_dialog, pick_file_dialog},
+ paths::get_schist_database_directory,
+ traits::Component,
+ DatabaseConnection,
+};
+
+use super::{Action, FilesScreen, Message};
+
+impl<'a> Component<'a, Message, Action> for FilesScreen {
+ fn update(&mut self, message: Message) -> Action {
+ match message {
+ Message::NewFile => match self.new_file() {
+ Some(Ok(file)) => Action::OpenedFile(file),
+ Some(Err(_)) | None => Action::None,
+ },
+
+ Message::OpenFile(file_path) => self
+ .open_file(file_path)
+ .map_or(Action::None, Action::OpenedFile),
+
+ Message::PickFile => match self.pick_file() {
+ Some(Ok(file)) => Action::OpenedFile(file),
+ Some(Err(_)) | None => Action::None,
+ },
+
+ Message::ImportFromActualbudget => match self.import_from_actualbudget() {
+ Some(Ok(file)) => Action::OpenedFile(file),
+ Some(Err(_)) | None => Action::None,
+ },
+ }
+ }
+}
+
+impl FilesScreen {
+ fn pick_file(
+ &mut self,
+ ) -> Option<Result<DatabaseConnection, (std::path::PathBuf, anyhow::Error)>> {
+ pick_file_dialog(get_schist_database_directory().ok()).map(|db_connection_result| {
+ db_connection_result.ok().inspect_err(|(path, err)| {
+ self.open_file_err = Some((path.clone(), err.to_string()));
+ rfd::MessageDialog::new()
+ .set_title("Failed to import from Actualbudget")
+ .set_level(rfd::MessageLevel::Error)
+ .set_description(format!("{}", err.chain().join("\n | ")))
+ .show();
+ })
+ })
+ }
+
+ fn open_file(
+ &mut self,
+ file_path: std::path::PathBuf,
+ ) -> Result<DatabaseConnection, (std::path::PathBuf, anyhow::Error)> {
+ DatabaseConnection::establish(file_path.clone())
+ .ok()
+ .inspect_err(|(_path, err)| {
+ self.open_file_err = Some((file_path, err.to_string()));
+ rfd::MessageDialog::new()
+ .set_title("Failed to import from Actualbudget")
+ .set_level(rfd::MessageLevel::Error)
+ .set_description(format!("{}", err.chain().join("\n | ")))
+ .show();
+ })
+ }
+
+ fn new_file(
+ &mut self,
+ ) -> Option<Result<DatabaseConnection, (std::path::PathBuf, anyhow::Error)>> {
+ new_file_dialog(get_schist_database_directory().ok()).map(|result| {
+ result.ok().inspect_err(|(path, err)| {
+ self.new_file_err = Some((path.clone(), err.to_string()));
+ rfd::MessageDialog::new()
+ .set_title("Failed to import from Actualbudget")
+ .set_level(rfd::MessageLevel::Error)
+ .set_description(format!("{}", err.chain().join("\n | ")))
+ .show();
+ })
+ })
+ }
+
+ fn import_from_actualbudget(&mut self) -> Option<anyhow::Result<DatabaseConnection>> {
+ match import_from_actualbudget_dialog() {
+ Some(Ok(state)) => self.new_file_with_state(&state),
+ Some(Err((path, err))) => Some({
+ self.open_file_err = Some((path, err.to_string()));
+ rfd::MessageDialog::new()
+ .set_title("Failed to import from Actualbudget")
+ .set_level(rfd::MessageLevel::Error)
+ .set_description(format!("{}", err.chain().join("\n | ")))
+ .show();
+ Err(err)
+ }),
+ None => None,
+ }
+ }
+
+ fn new_file_with_state(
+ &mut self,
+ state: &SchistState,
+ ) -> Option<anyhow::Result<DatabaseConnection>> {
+ match new_file_dialog(get_schist_database_directory().ok())
+ .map(DatabaseConnectionResult::ok)
+ {
+ Some(Ok(mut file)) => Some({
+ export_schist_state(state, &mut file.connection).ok()?;
+ Ok(file)
+ }),
+ Some(Err((path, err))) => Some({
+ self.new_file_err = Some((path, err.to_string()));
+ rfd::MessageDialog::new()
+ .set_title("Failed to import from Actualbudget")
+ .set_level(rfd::MessageLevel::Error)
+ .set_description(format!("{}", err.chain().join("\n | ")))
+ .show();
+ Err(err)
+ }),
+ None => None,
+ }
+ }
+}
diff --git a/schist_desktop_gui/src/gui/screens/files_screen/view_files_screen.rs b/schist_desktop_gui/src/gui/screens/files_screen/view_files_screen.rs
new file mode 100644
index 0000000..3cbd939
--- /dev/null
+++ b/schist_desktop_gui/src/gui/screens/files_screen/view_files_screen.rs
@@ -0,0 +1,106 @@
+use std::path::PathBuf;
+
+use iced::widget::column;
+
+use crate::{
+ gui::components::{panel_button, Text},
+ style::*,
+ traits::Viewable,
+};
+
+use super::{FilesScreen, Message};
+
+impl<'a> Viewable<'a, Message> for FilesScreen {
+ fn view(&'a self) -> iced::Element<'a, Message> {
+ let mut cols = Vec::new();
+ if let Some(col) = self.view_new_file_err() {
+ cols.push(col);
+ };
+ if let Some(col) = self.view_open_file_err() {
+ cols.push(col);
+ };
+ cols.push(self.view_new_file_button());
+ cols.push(self.view_open_file_button());
+ cols.push(self.view_import_from_actualbudget_button());
+ cols.append(&mut self.view_files());
+ column(cols).padding(SPACING_LG).spacing(SPACING_MD).into()
+ }
+}
+
+impl<'a> FilesScreen {
+ fn view_new_file_err(&'a self) -> Option<iced::Element<'a, Message>> {
+ self.new_file_err.as_ref().map(|(path, err)| {
+ let msg = format!("Failed to open new file {:#?}: {:#?}", path, err);
+ Text::new(&msg).danger().into()
+ })
+ }
+
+ fn view_open_file_err(&'a self) -> Option<iced::Element<'a, Message>> {
+ self.open_file_err
+ .as_ref()
+ .filter(|(file_path, _err)| !self.file_paths.iter().any(|fp| *fp == *file_path))
+ .map(|(file_path, err)| {
+ let msg = format!("Failed to open new file {:#?}: {:#?}", file_path, err);
+ Text::new(&msg).danger().into()
+ })
+ }
+
+ fn view_files(&'a self) -> Vec<iced::Element<'a, Message>> {
+ self.file_paths
+ .iter()
+ .map(|f| {
+ view_file(
+ f,
+ self.open_file_err
+ .clone()
+ .filter(|(file, _err)| *file == *f)
+ .map(|(_file, err)| err),
+ )
+ })
+ .collect()
+ }
+
+ fn view_new_file_button(&'a self) -> iced::Element<'a, Message> {
+ panel_button::<Text, Message>(Text::default("New file").into(), Message::NewFile).into()
+ }
+
+ fn view_open_file_button(&'a self) -> iced::Element<'a, Message> {
+ panel_button::<Text, Message>(Text::default("Open file").into(), Message::PickFile).into()
+ }
+
+ fn view_import_from_actualbudget_button(&'a self) -> iced::Element<'a, Message> {
+ panel_button::<Text, Message>(
+ Text::default("Import from Actualbudget").into(),
+ Message::ImportFromActualbudget,
+ )
+ .into()
+ }
+}
+
+fn view_file<'a>(file_path: &'a PathBuf, err: Option<String>) -> iced::Element<'a, Message> {
+ let mut cols: Vec<iced::Element<'a, Message>> = err
+ .map(|err| {
+ let msg = format!("Failed to open new file {:#?}: {:#?}", file_path, err);
+ vec![Text::new(&msg).danger().small().into()]
+ })
+ .unwrap_or_else(Vec::new);
+
+ cols.push(
+ Text::default(file_path.to_str().unwrap_or(""))
+ .small()
+ .weak()
+ .into(),
+ );
+
+ cols.push(
+ Text::default(
+ file_path
+ .file_name()
+ .map(|os_str| os_str.to_str().unwrap_or("[invalid Unicode]"))
+ .unwrap_or("[invalid filename]"),
+ )
+ .into(),
+ );
+
+ panel_button(column(cols), Message::OpenFile(file_path.clone())).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 0af3c28..00f4ec3 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
@@ -147,12 +147,12 @@ impl<'a> Component<'a, Message, Action> for MainScreen {
}
impl MainScreen {
- pub fn new(buckets: Vec<Bucket>, accounts: Vec<Account>) -> Self {
+ pub fn new() -> Self {
Self {
- balances_view: BalancesView::new(buckets.clone()),
- buckets: buckets.clone(),
- buckets_view: BucketsView::new(buckets, "Hello, buckets!"),
- transactions_view: TransactionsView::new(accounts, "Hello, transactions!"),
+ 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!"),
active_view: View::Balances,
view_navigation: Navigation::new(Some(View::Balances), View::views()),
}
diff --git a/schist_desktop_gui/src/gui/screens/main_screen/view.rs b/schist_desktop_gui/src/gui/screens/main_screen/view.rs
index eb9c88e..2be427b 100644
--- a/schist_desktop_gui/src/gui/screens/main_screen/view.rs
+++ b/schist_desktop_gui/src/gui/screens/main_screen/view.rs
@@ -1,4 +1,4 @@
-use iced::Element;
+use iced::{widget::Text, Element};
use crate::gui::components::navigation;
@@ -43,6 +43,6 @@ impl View {
impl<'a> Into<Element<'a, navigation::Message<View>>> for View {
fn into(self) -> Element<'a, navigation::Message<View>> {
- iced::widget::text(self.name()).into()
+ Text::new(self.name()).into()
}
}