summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'schist_desktop_gui/src/gui')
-rw-r--r--schist_desktop_gui/src/gui/components/balances_view.rs26
-rw-r--r--schist_desktop_gui/src/gui/components/balances_view/update_balances_view.rs60
-rw-r--r--schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs47
-rw-r--r--schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs25
-rw-r--r--schist_desktop_gui/src/gui/components/button.rs7
-rw-r--r--schist_desktop_gui/src/gui/components/navigation.rs86
-rw-r--r--schist_desktop_gui/src/gui/components/navigation/new_navigation.rs72
-rw-r--r--schist_desktop_gui/src/gui/components/navigation/update_navigation.rs225
-rw-r--r--schist_desktop_gui/src/gui/components/navigation/view_navigation.rs37
-rw-r--r--schist_desktop_gui/src/gui/components/navigation/view_navigation_button.rs32
-rw-r--r--schist_desktop_gui/src/gui/components/text.rs68
-rw-r--r--schist_desktop_gui/src/gui/screens/main_screen/view.rs6
12 files changed, 339 insertions, 352 deletions
diff --git a/schist_desktop_gui/src/gui/components/balances_view.rs b/schist_desktop_gui/src/gui/components/balances_view.rs
index 3ca37be..a1c8db3 100644
--- a/schist_desktop_gui/src/gui/components/balances_view.rs
+++ b/schist_desktop_gui/src/gui/components/balances_view.rs
@@ -3,19 +3,13 @@ mod update_balances_view;
mod view_balances_view;
mod view_group_names;
-use self::{
- update_balances_view::update_balances_view, view_balances_view::view_balances_view,
- view_group_names::view_group_names,
-};
+use self::view_group_names::view_group_names;
use schist_models::Bucket;
-use crate::{
- gui::components::{
- balances_view::make_balances_view_greeting::make_balances_view_greeting, navigation,
- Navigation, Text,
- },
- traits::{Component, Viewable},
+use crate::gui::components::{
+ balances_view::make_balances_view_greeting::make_balances_view_greeting, navigation,
+ Navigation, Text,
};
#[derive(Clone, Debug)]
@@ -49,15 +43,3 @@ impl BalancesView {
}
}
}
-
-impl<'a> Viewable<'a, Message> for BalancesView {
- fn view(&'a self) -> iced::Element<'a, Message> {
- view_balances_view(self)
- }
-}
-
-impl<'a> Component<'a, Message, Action> for BalancesView {
- fn update(&mut self, message: Message) -> Action {
- update_balances_view(self, message)
- }
-}
diff --git a/schist_desktop_gui/src/gui/components/balances_view/update_balances_view.rs b/schist_desktop_gui/src/gui/components/balances_view/update_balances_view.rs
index e7b32c3..1dd5c6f 100644
--- a/schist_desktop_gui/src/gui/components/balances_view/update_balances_view.rs
+++ b/schist_desktop_gui/src/gui/components/balances_view/update_balances_view.rs
@@ -7,42 +7,57 @@ use crate::{
traits::Component,
};
-pub fn update_balances_view(balances_view: &mut BalancesView, message: Message) -> Action {
- match message {
- Message::NavigationMessage(message) => update_navigation(balances_view, message),
- Message::SetBuckets(buckets) => set_buckets(balances_view, buckets),
- Message::SelectNextBucket => select_next_bucket(balances_view),
- Message::SelectPrevBucket => select_prev_bucket(balances_view),
+impl<'a> Component<'a, Message, Action> for BalancesView {
+ fn update(&mut self, message: Message) -> Action {
+ match message {
+ Message::NavigationMessage(message) => {
+ update_navigation(self, message);
+ Action::None
+ }
+
+ Message::SetBuckets(buckets) => {
+ set_buckets(self, buckets);
+ Action::None
+ }
+
+ Message::SelectNextBucket => {
+ select_next_bucket(self);
+ Action::None
+ }
+
+ Message::SelectPrevBucket => {
+ select_prev_bucket(self);
+ Action::None
+ }
+ }
}
}
-fn select_prev_bucket(balances_view: &mut BalancesView) -> Action {
+fn select_prev_bucket(balances_view: &mut BalancesView) -> () {
match balances_view
.navigation
.update(navigation::Message::SelectPrev)
{
navigation::Action::SelectOption(option) => {
balances_view.greeting = make_balances_view_greeting(Some(option));
- Action::None
}
- navigation::Action::None => Action::None,
- }
+ navigation::Action::None => {}
+ };
}
-fn select_next_bucket(balances_view: &mut BalancesView) -> Action {
+fn select_next_bucket(balances_view: &mut BalancesView) -> () {
match balances_view
.navigation
.update(navigation::Message::SelectNext)
{
navigation::Action::SelectOption(option) => {
balances_view.greeting = make_balances_view_greeting(Some(option));
- Action::None
}
- navigation::Action::None => Action::None,
- }
+ navigation::Action::None => {}
+ };
}
-fn set_buckets(balances_view: &mut BalancesView, buckets: Vec<schist_models::Bucket>) -> Action {
+fn set_buckets(balances_view: &mut BalancesView, buckets: Vec<schist_models::Bucket>) -> () {
balances_view.buckets = buckets.clone();
match balances_view
.navigation
@@ -50,23 +65,18 @@ fn set_buckets(balances_view: &mut BalancesView, buckets: Vec<schist_models::Buc
{
navigation::Action::SelectOption(option) => {
balances_view.greeting = make_balances_view_greeting(Some(option));
- Action::None
}
- navigation::Action::None => Action::None,
- }
+ navigation::Action::None => {}
+ };
}
-fn update_navigation(
- balances_view: &mut BalancesView,
- message: navigation::Message<Text>,
-) -> Action {
+fn update_navigation(balances_view: &mut BalancesView, message: navigation::Message<Text>) -> () {
match balances_view.navigation.update(message) {
navigation::Action::SelectOption(group_name) => {
balances_view.greeting = make_balances_view_greeting(Some(group_name));
- Action::None
}
- navigation::Action::None => Action::None,
- }
+ navigation::Action::None => {}
+ };
}
#[cfg(test)]
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 6a64508..22f22b6 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,23 +1,30 @@
-use iced::widget::{column, row, Container};
-use iced::{alignment, Element, Length};
+use iced::{
+ alignment,
+ widget::{column, row, Container},
+ Length,
+};
-use crate::gui::components::Text;
-use crate::gui::components::{balances_view::Message, BalancesView};
-use crate::style::SPACING_LG;
-use crate::traits::Viewable;
+use crate::{
+ gui::components::{balances_view::Message, BalancesView, Text},
+ style::SPACING_LG,
+ traits::Viewable,
+};
-pub fn view_balances_view<'a>(balances_view: &'a BalancesView) -> Element<'a, Message> {
- let navigation = balances_view
- .navigation
- .view()
- .map(Message::NavigationMessage);
- 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)),
- ]
- .align_y(alignment::Vertical::Center)
- .height(Length::Fill)
- .spacing(SPACING_LG)
- .into()
+impl<'a> Viewable<'a, Message> for BalancesView {
+ fn view(&'a self) -> iced::Element<'a, Message> {
+ let balances_view: &'a BalancesView = self;
+ let navigation = balances_view
+ .navigation
+ .view()
+ .map(Message::NavigationMessage);
+ 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)),
+ ]
+ .align_y(alignment::Vertical::Center)
+ .height(Length::Fill)
+ .spacing(SPACING_LG)
+ .into()
+ }
}
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 24a3952..8a5a16e 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,7 +1,10 @@
-use iced::{widget::row, Element};
+use iced::{
+ widget::{row, text},
+ Element, Length,
+};
use schist_models::Bucket;
-use crate::gui::components::{navigation, Text};
+use crate::gui::components::navigation;
#[derive(Clone, Debug, PartialEq)]
pub struct BucketNameAndBalance {
@@ -14,11 +17,21 @@ impl BucketNameAndBalance {
}
}
-impl<'a> Into<Element<'a, navigation::Message<BucketNameAndBalance>>> for BucketNameAndBalance {
- fn into(self) -> Element<'a, navigation::Message<BucketNameAndBalance>> {
+impl<'a> From<&'a BucketNameAndBalance> for Element<'a, navigation::Message<BucketNameAndBalance>> {
+ fn from(bucket_name_and_balance: &'a BucketNameAndBalance) -> Self {
+ let balance_style = if bucket_name_and_balance
+ .bucket
+ .balance
+ .is_none_or(|balance| balance >= 0)
+ {
+ text::default
+ } else {
+ text::danger
+ };
+
row![
- Text::new(&self.bucket.name).as_element(),
- Text::new(&self.bucket.balance.unwrap_or(0).to_string()).as_element(),
+ text(bucket_name_and_balance.bucket.name.clone()).width(Length::Fill),
+ text(bucket_name_and_balance.bucket.pretty_balance_per_100()).style(balance_style),
]
.into()
}
diff --git a/schist_desktop_gui/src/gui/components/button.rs b/schist_desktop_gui/src/gui/components/button.rs
index e071f33..6882273 100644
--- a/schist_desktop_gui/src/gui/components/button.rs
+++ b/schist_desktop_gui/src/gui/components/button.rs
@@ -2,9 +2,10 @@ use iced::{widget::Button, Element};
use crate::style::*;
-pub fn active_button<'a, Content: Into<Element<'a, Message>>, Message>(
- content: Content,
-) -> Button<'a, Message> {
+pub fn active_button<'a, Content, Message>(content: &'a Content) -> Button<'a, Message>
+where
+ Element<'a, Message>: From<&'a Content>,
+{
iced::widget::button(content)
.style(|theme: &iced::Theme, _status| iced::widget::button::Style {
background: Some(iced::Background::Color(
diff --git a/schist_desktop_gui/src/gui/components/navigation.rs b/schist_desktop_gui/src/gui/components/navigation.rs
index bed3221..6dbe622 100644
--- a/schist_desktop_gui/src/gui/components/navigation.rs
+++ b/schist_desktop_gui/src/gui/components/navigation.rs
@@ -1,19 +1,9 @@
-mod new_navigation;
mod update_navigation;
mod view_navigation;
mod view_navigation_button;
-use new_navigation::new_navigation;
-use update_navigation::update_navigation;
-use view_navigation::view_navigation;
-use view_navigation_button::view_navigation_button;
-
use std::fmt::Debug;
-use iced::Element;
-
-use crate::traits::{Component, Viewable};
-
#[derive(Clone, Debug)]
pub struct Navigation<TOption> {
options_before_active: Vec<TOption>,
@@ -36,33 +26,67 @@ pub enum Action<TOption> {
impl<TOption: Clone + Debug + PartialEq> Navigation<TOption> {
pub fn new(active_option: Option<TOption>, options: Vec<TOption>) -> Self {
- new_navigation(active_option, options)
+ let active_option_index = active_option.clone().map_or(Option::None, |active_option| {
+ options.iter().position(|option| option.eq(&active_option))
+ });
+ if let Some(active_option_index) = active_option_index {
+ let split = options.split_at(active_option_index);
+ Navigation {
+ options_before_active: split.0.to_vec(),
+ active_option: active_option,
+ options_after_active: split.1.split_at(1).1.to_vec(),
+ }
+ } else {
+ Navigation {
+ options_before_active: options,
+ active_option: active_option,
+ options_after_active: vec![],
+ }
+ }
}
}
-impl<'a, TOption> Navigation<TOption>
-where
- TOption: Clone + PartialEq + Into<Element<'a, Message<TOption>>>,
-{
- pub fn button(&'a self, option: &'a TOption) -> Element<'a, Message<TOption>> {
- view_navigation_button(self, option)
+#[cfg(test)]
+mod test {
+ use super::Navigation;
+
+ #[test]
+ fn when_active_option_at_start_of_options_then_finds_active_option() {
+ let navigation = Navigation::new(Some(1), vec![1, 2, 3, 4, 5]);
+ assert_eq!(Vec::<i32>::new(), navigation.options_before_active);
+ assert_eq!(Some(1), navigation.active_option);
+ assert_eq!(vec![2, 3, 4, 5], navigation.options_after_active);
}
-}
-impl<'a, TOption> Viewable<'a, Message<TOption>> for Navigation<TOption>
-where
- TOption: Clone + PartialEq + Into<Element<'a, Message<TOption>>>,
-{
- fn view(&'a self) -> iced::Element<'a, Message<TOption>> {
- view_navigation(self)
+ #[test]
+ fn when_active_option_in_middle_of_options_then_finds_active_option() {
+ let navigation = Navigation::new(Some(3), vec![1, 2, 3, 4, 5]);
+ assert_eq!(vec![1, 2], navigation.options_before_active);
+ assert_eq!(Some(3), navigation.active_option);
+ assert_eq!(vec![4, 5], navigation.options_after_active);
+ }
+
+ #[test]
+ fn when_active_option_at_end_of_options_then_finds_active_option() {
+ let navigation = Navigation::new(Some(5), vec![1, 2, 3, 4, 5]);
+ assert_eq!(vec![1, 2, 3, 4], navigation.options_before_active);
+ assert_eq!(Some(5), navigation.active_option);
+ assert_eq!(Vec::<i32>::new(), navigation.options_after_active);
+ }
+
+ #[test]
+ fn when_active_option_not_in_options_then_appends_active_option() {
+ let navigation = Navigation::new(Some(6), vec![1, 2, 3, 4, 5]);
+ assert_eq!(vec![1, 2, 3, 4, 5], navigation.options_before_active);
+ assert_eq!(Some(6), navigation.active_option);
+ assert_eq!(Vec::<i32>::new(), navigation.options_after_active);
}
-}
-impl<'a, TOption> Component<'a, Message<TOption>, Action<TOption>> for Navigation<TOption>
-where
- TOption: Clone + PartialEq + Into<Element<'a, Message<TOption>>>,
-{
- fn update(&mut self, message: Message<TOption>) -> Action<TOption> {
- update_navigation(self, message)
+ #[test]
+ fn when_no_active_option_then_all_options_are_before_active_option() {
+ let navigation = Navigation::new(None, vec![1, 2, 3, 4, 5]);
+ assert_eq!(vec![1, 2, 3, 4, 5], navigation.options_before_active);
+ assert_eq!(None, navigation.active_option);
+ assert_eq!(Vec::<i32>::new(), navigation.options_after_active);
}
}
diff --git a/schist_desktop_gui/src/gui/components/navigation/new_navigation.rs b/schist_desktop_gui/src/gui/components/navigation/new_navigation.rs
deleted file mode 100644
index b5c0c19..0000000
--- a/schist_desktop_gui/src/gui/components/navigation/new_navigation.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-use super::Navigation;
-
-pub fn new_navigation<TOption>(
- active_option: Option<TOption>,
- options: Vec<TOption>,
-) -> Navigation<TOption>
-where
- TOption: Clone + PartialEq,
-{
- let active_option_index = active_option.clone().map_or(Option::None, |active_option| {
- options.iter().position(|option| option.eq(&active_option))
- });
- if let Some(active_option_index) = active_option_index {
- let split = options.split_at(active_option_index);
- Navigation {
- options_before_active: split.0.to_vec(),
- active_option,
- options_after_active: split.1.split_at(1).1.to_vec(),
- }
- } else {
- Navigation {
- options_before_active: options,
- active_option,
- options_after_active: vec![],
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::Navigation;
-
- #[test]
- fn when_active_option_at_start_of_options_then_finds_active_option() {
- let navigation = Navigation::new(Some(1), vec![1, 2, 3, 4, 5]);
- assert_eq!(Vec::<i32>::new(), navigation.options_before_active);
- assert_eq!(Some(1), navigation.active_option);
- assert_eq!(vec![2, 3, 4, 5], navigation.options_after_active);
- }
-
- #[test]
- fn when_active_option_in_middle_of_options_then_finds_active_option() {
- let navigation = Navigation::new(Some(3), vec![1, 2, 3, 4, 5]);
- assert_eq!(vec![1, 2], navigation.options_before_active);
- assert_eq!(Some(3), navigation.active_option);
- assert_eq!(vec![4, 5], navigation.options_after_active);
- }
-
- #[test]
- fn when_active_option_at_end_of_options_then_finds_active_option() {
- let navigation = Navigation::new(Some(5), vec![1, 2, 3, 4, 5]);
- assert_eq!(vec![1, 2, 3, 4], navigation.options_before_active);
- assert_eq!(Some(5), navigation.active_option);
- assert_eq!(Vec::<i32>::new(), navigation.options_after_active);
- }
-
- #[test]
- fn when_active_option_not_in_options_then_appends_active_option() {
- let navigation = Navigation::new(Some(6), vec![1, 2, 3, 4, 5]);
- assert_eq!(vec![1, 2, 3, 4, 5], navigation.options_before_active);
- assert_eq!(Some(6), navigation.active_option);
- assert_eq!(Vec::<i32>::new(), navigation.options_after_active);
- }
-
- #[test]
- fn when_no_active_option_then_all_options_are_before_active_option() {
- let navigation = Navigation::new(None, vec![1, 2, 3, 4, 5]);
- assert_eq!(vec![1, 2, 3, 4, 5], navigation.options_before_active);
- assert_eq!(None, navigation.active_option);
- assert_eq!(Vec::<i32>::new(), navigation.options_after_active);
- }
-}
diff --git a/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs b/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs
index f86867f..c44ddd8 100644
--- a/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs
+++ b/schist_desktop_gui/src/gui/components/navigation/update_navigation.rs
@@ -1,127 +1,130 @@
use iced::Element;
+use crate::traits::Component;
+
use super::{Action, Message, Navigation};
-pub fn update_navigation<'a, TOption>(
- navigation: &mut Navigation<TOption>,
- message: Message<TOption>,
-) -> Action<TOption>
+impl<'a, TOption> Component<'a, Message<TOption>, Action<TOption>> for Navigation<TOption>
where
- TOption: Clone + PartialEq + Into<Element<'a, Message<TOption>>>,
+ TOption: Clone + PartialEq + 'a,
+ Element<'a, Message<TOption>>: From<&'a TOption>,
{
- match message {
- Message::SelectOption(option) => {
- if navigation
- .active_option
- .as_ref()
- .is_some_and(|active_option| active_option.clone() == option)
- {
- Action::None
- } else if let Some(index) = navigation
- .options_before_active
- .iter()
- .position(|o| o.clone() == option)
- {
- let split = navigation.options_before_active.split_at(index);
- navigation.options_after_active = vec![
+ fn update(&mut self, message: Message<TOption>) -> Action<TOption> {
+ let navigation: &mut Navigation<TOption> = self;
+ match message {
+ Message::SelectOption(option) => {
+ if navigation
+ .active_option
+ .as_ref()
+ .is_some_and(|active_option| TOption::eq(active_option, &option))
+ {
+ Action::None
+ } else if let Some(index) = navigation
+ .options_before_active
+ .iter()
+ .position(|o| TOption::eq(o, &option))
+ {
+ let split = navigation.options_before_active.split_at(index);
+ navigation.options_after_active = vec![
+ navigation
+ .active_option
+ .clone()
+ .map_or(vec![], |active_option| vec![active_option]),
+ split.1.split_at(1).1.to_vec(),
+ navigation.options_after_active.clone(),
+ ]
+ .concat();
+ navigation.options_before_active = split.0.to_vec();
+ navigation.active_option = Some(option.clone());
+ Action::SelectOption(option)
+ } else if let Some(index) = navigation
+ .options_after_active
+ .iter()
+ .position(|o| TOption::eq(o, &option))
+ {
+ let split = navigation.options_after_active.split_at(index);
+ navigation.options_before_active = vec![
+ navigation.options_before_active.clone(),
+ split.0.to_vec(),
+ navigation
+ .active_option
+ .clone()
+ .map_or(vec![], |active_option| vec![active_option]),
+ ]
+ .concat();
+ navigation.active_option = Some(option.clone());
+ navigation.options_after_active = split.1.split_at(1).1.to_vec();
+ Action::SelectOption(option)
+ } else {
+ if let Some(active_option) = &navigation.active_option {
+ navigation.options_before_active.push(active_option.clone());
+ }
navigation
- .active_option
- .clone()
- .map_or(vec![], |active_option| vec![active_option]),
- split.1.split_at(1).1.to_vec(),
- navigation.options_after_active.clone(),
- ]
- .concat();
- navigation.options_before_active = split.0.to_vec();
- navigation.active_option = Some(option.clone());
- Action::SelectOption(option)
- } else if let Some(index) = navigation
- .options_after_active
- .iter()
- .position(|o| o.clone() == option)
- {
- let split = navigation.options_after_active.split_at(index);
- navigation.options_before_active = vec![
- navigation.options_before_active.clone(),
- split.0.to_vec(),
+ .options_before_active
+ .append(&mut navigation.options_after_active);
+ navigation.active_option = Some(option.clone());
+ navigation.options_after_active = vec![];
+ Action::SelectOption(option)
+ }
+ }
+ Message::SetOptions(options) => {
+ let active_option_index =
navigation
.active_option
.clone()
- .map_or(vec![], |active_option| vec![active_option]),
- ]
- .concat();
- navigation.active_option = Some(option.clone());
- navigation.options_after_active = split.1.split_at(1).1.to_vec();
- Action::SelectOption(option)
- } else {
- if let Some(active_option) = &navigation.active_option {
- navigation.options_before_active.push(active_option.clone());
+ .map_or(Option::None, |active_option| {
+ options
+ .iter()
+ .position(|option| active_option == option.clone())
+ });
+ if let Some(active_option_index) = active_option_index {
+ let split = options.split_at(active_option_index);
+ navigation.options_before_active = split.0.to_vec();
+ navigation.options_after_active = split.1.split_at(1).1.to_vec();
+ Action::None
+ } else {
+ navigation.options_before_active = options
+ .split_last()
+ .map_or_else(Vec::new, |(_last, rest)| rest.to_vec());
+ navigation.active_option = options.last().cloned();
+ options
+ .last()
+ .cloned()
+ .map_or(Action::None, Action::SelectOption)
}
- navigation
- .options_before_active
- .append(&mut navigation.options_after_active);
- navigation.active_option = Some(option.clone());
- navigation.options_after_active = vec![];
- Action::SelectOption(option)
}
- }
- Message::SetOptions(options) => {
- let active_option_index =
- navigation
- .active_option
- .clone()
- .map_or(Option::None, |active_option| {
- options
- .iter()
- .position(|option| active_option == option.clone())
- });
- if let Some(active_option_index) = active_option_index {
- let split = options.split_at(active_option_index);
- navigation.options_before_active = split.0.to_vec();
- navigation.options_after_active = split.1.split_at(1).1.to_vec();
- Action::None
- } else {
- navigation.options_before_active = options
- .split_last()
- .map_or_else(Vec::new, |(_last, rest)| rest.to_vec());
- navigation.active_option = options.last().cloned();
- options
- .last()
- .cloned()
- .map_or(Action::None, Action::SelectOption)
- }
- }
- Message::SelectNext => {
- if let Some(next) = navigation.options_after_active.clone().first() {
- navigation.options_before_active = vec![
- navigation.options_before_active.clone(),
- navigation.active_option.clone().map_or(vec![], |o| vec![o]),
- ]
- .concat();
- navigation.active_option = Some(next.clone());
- navigation.options_after_active =
- navigation.options_after_active.split_at(1).1.to_vec();
- Action::SelectOption(next.clone())
- } else {
- Action::None
+ Message::SelectNext => {
+ if let Some(next) = navigation.options_after_active.clone().first() {
+ navigation.options_before_active = vec![
+ navigation.options_before_active.clone(),
+ navigation.active_option.clone().map_or(vec![], |o| vec![o]),
+ ]
+ .concat();
+ navigation.active_option = Some(next.clone());
+ navigation.options_after_active =
+ navigation.options_after_active.split_at(1).1.to_vec();
+ Action::SelectOption(next.clone())
+ } else {
+ Action::None
+ }
}
- }
- Message::SelectPrev => {
- if let Some(prev) = navigation.options_before_active.clone().last() {
- navigation.options_after_active = vec![
- navigation.active_option.clone().map_or(vec![], |o| vec![o]),
- navigation.options_after_active.clone(),
- ]
- .concat();
- navigation.active_option = Some(prev.clone());
- navigation.options_before_active = navigation
- .options_before_active
- .split_last()
- .map(|split| split.1.to_vec())
- .unwrap_or_else(Vec::new);
- Action::SelectOption(prev.clone())
- } else {
- Action::None
+ Message::SelectPrev => {
+ if let Some(prev) = navigation.options_before_active.clone().last() {
+ navigation.options_after_active = vec![
+ navigation.active_option.clone().map_or(vec![], |o| vec![o]),
+ navigation.options_after_active.clone(),
+ ]
+ .concat();
+ navigation.active_option = Some(prev.clone());
+ navigation.options_before_active = navigation
+ .options_before_active
+ .split_last()
+ .map(|split| split.1.to_vec())
+ .unwrap_or_else(Vec::new);
+ Action::SelectOption(prev.clone())
+ } else {
+ Action::None
+ }
}
}
}
diff --git a/schist_desktop_gui/src/gui/components/navigation/view_navigation.rs b/schist_desktop_gui/src/gui/components/navigation/view_navigation.rs
index beec818..3f1da18 100644
--- a/schist_desktop_gui/src/gui/components/navigation/view_navigation.rs
+++ b/schist_desktop_gui/src/gui/components/navigation/view_navigation.rs
@@ -1,26 +1,27 @@
use iced::{widget::column, Element};
+use crate::traits::Viewable;
+
use super::{Message, Navigation};
-pub fn view_navigation<'a, TOption>(
- navigation: &'a Navigation<TOption>,
-) -> Element<'a, Message<TOption>>
+impl<'a, TOption> Viewable<'a, Message<TOption>> for Navigation<TOption>
where
- TOption: Clone + PartialEq + Into<Element<'a, Message<TOption>>>,
+ TOption: Clone + PartialEq + 'a,
+ Element<'a, Message<TOption>>: From<&'a TOption>,
{
- let mut options = Vec::new();
- navigation
- .options_before_active
- .iter()
- .map(|option| navigation.button(&option))
- .for_each(|option| options.push(option));
- if let Some(active_option) = navigation.active_option.as_ref() {
- options.push(navigation.button(&active_option));
+ fn view(&'a self) -> iced::Element<'a, Message<TOption>> {
+ let mut options = Vec::new();
+ self.options_before_active
+ .iter()
+ .map(|option| self.view_navigation_button(&option))
+ .for_each(|option| options.push(option));
+ if let Some(active_option) = self.active_option.as_ref() {
+ options.push(self.view_navigation_button(&active_option));
+ }
+ self.options_after_active
+ .iter()
+ .map(|option| self.view_navigation_button(&option))
+ .for_each(|option| options.push(option));
+ column(options).into()
}
- navigation
- .options_after_active
- .iter()
- .map(|option| navigation.button(&option))
- .for_each(|option| options.push(option));
- column(options).into()
}
diff --git a/schist_desktop_gui/src/gui/components/navigation/view_navigation_button.rs b/schist_desktop_gui/src/gui/components/navigation/view_navigation_button.rs
index 3132bf1..d65328c 100644
--- a/schist_desktop_gui/src/gui/components/navigation/view_navigation_button.rs
+++ b/schist_desktop_gui/src/gui/components/navigation/view_navigation_button.rs
@@ -4,24 +4,24 @@ use crate::gui::components::{active_button, inactive_button};
use super::{Message, Navigation};
-pub fn view_navigation_button<'a, TOption>(
- navigation: &'a Navigation<TOption>,
- option: &'a TOption,
-) -> Element<'a, Message<TOption>>
+impl<'a, TOption> Navigation<TOption>
where
- TOption: Clone + PartialEq + Into<Element<'a, Message<TOption>>>,
+ TOption: Clone + PartialEq + 'a,
+ Element<'a, Message<TOption>>: From<&'a TOption>,
{
- if navigation
- .active_option
- .as_ref()
- .is_some_and(|o| *o == *option)
- {
- active_button(Into::<Element<'a, Message<TOption>>>::into(option.clone())).into()
- } else {
- inactive_button(
- Into::<Element<'a, Message<TOption>>>::into(option.clone()),
- Message::SelectOption(option.clone()),
- )
+ pub(super) fn view_navigation_button(
+ &'a self,
+ option: &'a TOption,
+ ) -> Element<'a, Message<TOption>> {
+ if self
+ .active_option
+ .as_ref()
+ .is_some_and(|o| TOption::eq(o, option))
+ {
+ active_button(option)
+ } else {
+ inactive_button(option, Message::SelectOption(option.clone()))
+ }
.into()
}
}
diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs
index 90cd7bc..a3093ac 100644
--- a/schist_desktop_gui/src/gui/components/text.rs
+++ b/schist_desktop_gui/src/gui/components/text.rs
@@ -1,3 +1,5 @@
+use std::borrow::Borrow;
+
use crate::style::*;
#[derive(Clone, Debug, PartialEq)]
@@ -71,30 +73,46 @@ impl Text {
}
}
-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()
+impl<'a, Message> From<Text> for iced::Element<'a, Message> {
+ fn from(text: Text) -> Self {
+ text_as_element(text)
+ }
+}
+
+impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> {
+ fn from(text: &'a Text) -> Self {
+ text_as_element(text)
}
}
+
+fn text_as_element<'a, T, Message>(text: T) -> iced::Element<'a, Message>
+where
+ T: Borrow<Text> + 'a,
+{
+ iced::widget::text(text.borrow().content.clone())
+ .size(match text.borrow().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 (
+ &text.borrow().borrow().colour,
+ &text.borrow().borrow().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/screens/main_screen/view.rs b/schist_desktop_gui/src/gui/screens/main_screen/view.rs
index 2be427b..5f2df4e 100644
--- a/schist_desktop_gui/src/gui/screens/main_screen/view.rs
+++ b/schist_desktop_gui/src/gui/screens/main_screen/view.rs
@@ -41,8 +41,8 @@ impl View {
}
}
-impl<'a> Into<Element<'a, navigation::Message<View>>> for View {
- fn into(self) -> Element<'a, navigation::Message<View>> {
- Text::new(self.name()).into()
+impl<'a> From<&'a View> for Element<'a, navigation::Message<View>> {
+ fn from(val: &'a View) -> Self {
+ Text::new(val.name()).into()
}
}