From 9b74e6ee8564e26f6ef3004e08aff585db0e371e Mon Sep 17 00:00:00 2001 From: Ida Dahl Date: Sun, 4 Jan 2026 00:30:35 +0100 Subject: [PATCH] implemented amounts in gui --- gui/src/lib.rs | 89 ++++++++++++++++++++++++++++++++- gui/ui/app.slint | 119 +++++++++++++++++++++++++++++++++++++++++++-- gui/ui/state.slint | 3 ++ 3 files changed, 206 insertions(+), 5 deletions(-) diff --git a/gui/src/lib.rs b/gui/src/lib.rs index ee4f4e3..e8c0d87 100644 --- a/gui/src/lib.rs +++ b/gui/src/lib.rs @@ -61,6 +61,7 @@ fn update_slint_list(new_list: Vec, list: &VecModel) { .map(|item| SItem { name: item.name.to_shared_string(), checked: item.data.checked, + amount: item.data.amount as i32, }) .for_each(|item| list.push(item)); } @@ -122,13 +123,32 @@ pub fn run() -> Result<(), anyhow::Error> { let conf = conf_shared.clone(); let list = list_shared.clone(); state.on_add_to_list(move |item| { - if list.iter().any(|item2| item2.name == item) { + if let Some(index) = list.iter().position(|item2| item2.name == item) { + let mut item2 = list.row_data(index).unwrap(); + item2.amount = item2.amount + 1; + let item3 = item2.clone(); + list.set_row_data(index, item2); + let conf = conf.clone(); + spawn(async move { + let res = put_list( + &item, + &ItemData { + checked: item3.checked, + amount: item3.amount as i64, + }, + &conf, + ) + .await; + if let Err(err) = res { + eprintln!("{err:?}"); + } + }); return; - // TODO: implement increment when number is added } list.push(SItem { checked: false, name: item.clone(), + amount: 1, }); let conf = conf.clone(); spawn(async move { @@ -204,6 +224,71 @@ pub fn run() -> Result<(), anyhow::Error> { }); }); + let conf = conf_shared.clone(); + let list = list_shared.clone(); + state.on_inc_amount(move |item| { + if let Some(index) = list.iter().position(|item2| item2.name == item) { + let mut item2 = list.row_data(index).unwrap(); + item2.amount = item2.amount + 1; + let item3 = item2.clone(); + list.set_row_data(index, item2); + let conf = conf.clone(); + spawn(async move { + let res = put_list( + &item, + &ItemData { + checked: item3.checked, + amount: item3.amount as i64, + }, + &conf, + ) + .await; + if let Err(err) = res { + eprintln!("{err:?}"); + } + }); + return; + } + }); + + let conf = conf_shared.clone(); + let list = list_shared.clone(); + state.on_dec_amount(move |item| { + if let Some(index) = list.iter().position(|item2| item2.name == item) { + let mut item2 = list.row_data(index).unwrap(); + item2.amount = item2.amount - 1; + let item3 = item2.clone(); + list.set_row_data(index, item2); + let conf = conf.clone(); + if item3.amount < 1 { + list.remove(index); + spawn(async move { + let res = delete_item(&item3.name, &conf).await; + if let Err(err) = res { + eprintln!("{err:?}"); + } + }); + } else { + spawn(async move { + // TODO: add number to increment + let res = put_list( + &item, + &ItemData { + checked: item3.checked, + amount: item3.amount as i64, + }, + &conf, + ) + .await; + if let Err(err) = res { + eprintln!("{err:?}"); + } + }); + return; + } + } + }); + state.on_set_server_address(move |address| { conf_shared.lock().unwrap().address = address.to_string(); #[cfg(target_os = "linux")] diff --git a/gui/ui/app.slint b/gui/ui/app.slint index e15d862..1a72d7d 100644 --- a/gui/ui/app.slint +++ b/gui/ui/app.slint @@ -30,6 +30,13 @@ component GoodListItem inherits Rectangle { } } + Text { + opacity: (root.item.checked ? 0.5 : 1.0); + font-size: 12pt; + text: root.item.amount; + width: 30px; + } + Text { opacity: (root.item.checked ? 0.5 : 1.0); font-size: 12pt; @@ -42,6 +49,94 @@ component GoodListItem inherits Rectangle { //root.item.checked = !root.item.checked; State.check-item(item.name); } + mouse-cursor: pointer; + } +} + +component PlusMinus inherits HorizontalLayout { + in property item; + plus := Rectangle { + Text { + text: "+"; + font-weight: 800; + font-size: 16pt; + } + + background: #ffffff10; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + border-color: #00000070; + border-width: 1px; + width: self.height; + plusta := TouchArea { + clicked => { + State.inc-amount(item.name); + } + mouse-cursor: pointer; + } + } + + minus := Rectangle { + Text { + text: "-"; + font-weight: 800; + font-size: 16pt; + } + + background: #ffffff10; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; + border-color: #00000070; + border-width: 1px; + height: 30px; + width: self.height; + minusta := TouchArea { + clicked => { + State.dec-amount(item.name); + } + mouse-cursor: pointer; + } + } + + states [ + plushov when plusta.has-hover: { + plus.background: #ffffff30; + } + minoshov when minusta.has-hover: { + minus.background: #ffffff30; + } + ] +} + +component GoodListItemAdd inherits Rectangle { + in-out property item; + background: #ffffff10; + border-radius: 8pt; + border-width: 10pt; + HorizontalLayout { + spacing: 8px; + padding: 8px; + alignment: start; + PlusMinus { + item: item; + } + + Rectangle { + height: 30px; + Text { + text: root.item.amount; + font-size: 12pt; + } + } + + Rectangle { + height: 30px; + Text { + opacity: (root.item.checked ? 0.5 : 1.0); + font-size: 12pt; + text: root.item.name; + } + } } } @@ -63,6 +158,24 @@ component GoodsList { } } +component GoodsListAdd { + in property <[SItem]> items; + + ListView { + mouse-drag-pan-enabled: true; + + for item in items: VerticalLayout { + GoodListItemAdd { + item: item; + } + + Rectangle { + height: 4pt; + } + } + } +} + component GoodButtons inherits ScrollView { in property <[string]> favorites: ["Mjölk", "Ost", "Ägg", "Bullens", "Oboy", "Mjöl", "Havregryn", "KrosTom"]; in property button-width: 100; @@ -104,9 +217,9 @@ component AddView inherits VerticalLayout { padding: 8px; spacing: 8px; - RefreshButton {} + RefreshButton { } - goods := GoodsList { + goods := GoodsListAdd { items <=> list; } @@ -148,7 +261,7 @@ component ShopView inherits VerticalLayout { padding: 8px; spacing: 8px; - RefreshButton {} + RefreshButton { } goods := GoodsList { items <=> list; diff --git a/gui/ui/state.slint b/gui/ui/state.slint index 1105745..082ae9d 100644 --- a/gui/ui/state.slint +++ b/gui/ui/state.slint @@ -1,6 +1,7 @@ export struct SItem { name: string, checked: bool, + amount: int, } export global State { @@ -13,6 +14,8 @@ export global State { callback add-to-list(string); callback check-item(string); callback delete-checked(); + callback inc-amount(string); + callback dec-amount(string); in-out property server-address; callback set-server-address(string); set-server-address(address) => {