From a61d26d3589e046aef19488875517cd38341cd38 Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Sat, 3 Oct 2026 15:42:24 +0200 Subject: [PATCH] Add animation when an item is added to the list --- gui/src/lib.rs | 2 ++ gui/ui/app.slint | 63 ++++++++++++++++++++++++++++++---------------- gui/ui/state.slint | 4 +++ 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/gui/src/lib.rs b/gui/src/lib.rs index 639bf29..a199600 100644 --- a/gui/src/lib.rs +++ b/gui/src/lib.rs @@ -93,6 +93,7 @@ fn update_slint_list(new_list: Vec, list: &VecModel) { name: item.name.to_shared_string(), checked: item.data.checked, amount: item.data.amount as i32, + just_added: false, }) .for_each(|item| list.push(item)); } @@ -196,6 +197,7 @@ pub fn run() -> Result<(), anyhow::Error> { checked: false, name: item.clone(), amount: 1, + just_added: true, }); let conf = conf.clone(); io.spawn(async move || { diff --git a/gui/ui/app.slint b/gui/ui/app.slint index d65939b..2226922 100644 --- a/gui/ui/app.slint +++ b/gui/ui/app.slint @@ -113,31 +113,50 @@ component PlusMinus inherits HorizontalLayout { component GoodListItemAdd inherits Rectangle { in-out property item; - background: Palette.alternate-background; - border-radius: 8pt; - border-width: 10pt; - HorizontalLayout { - spacing: 8px; - padding: 8px; - alignment: start; - PlusMinus { - item: item; + Rectangle { + // Animate when this item appears. + transform-scale: item.just-added ? 90% : 100%; + opacity: item.just-added ? 0 : 100%; + init => { + self.transform-scale = 100%; + self.opacity = 100%; + item.just-added = false; + } + animate transform-scale { + duration: 500ms; + easing: ease-out-bounce; + } + animate opacity { + duration: 300ms; + easing: ease-out; } - Rectangle { - height: 30px; - Text { - text: root.item.amount; - font-size: 12pt; + background: Palette.alternate-background; + border-radius: 8pt; + border-width: 10pt; + HorizontalLayout { + spacing: 8px; + padding: 8px; + alignment: start; + PlusMinus { + item: item; } - } - Rectangle { - height: 30px; - Text { - opacity: (root.item.checked ? 0.5 : 1.0); - font-size: 12pt; - text: root.item.name; + 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; + } } } } @@ -169,7 +188,7 @@ component GoodsListAdd { for item in items: VerticalLayout { GoodListItemAdd { - item: item; + item <=> item; } Rectangle { diff --git a/gui/ui/state.slint b/gui/ui/state.slint index c35cffe..901aca9 100644 --- a/gui/ui/state.slint +++ b/gui/ui/state.slint @@ -2,6 +2,10 @@ export struct SItem { name: string, checked: bool, amount: int, + + /// Whether the item was just added by the user. + /// Determines whether the add-animation plays. + just_added: bool, } export struct SButtonItem{