From 5e6ba7d42261cae4d5069054bf1a6523ac722997 Mon Sep 17 00:00:00 2001 From: Cleboost Date: Sun, 29 Jun 2025 11:15:36 +0200 Subject: [PATCH 1/5] Add icons to sidebar menu links Updated the sidebar menu to display icons next to each link (Home, Tracks, Albums, Podcasts) by modifying the sidebar_link_widget to accept and render an optional icon. --- psst-gui/src/ui/mod.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/psst-gui/src/ui/mod.rs b/psst-gui/src/ui/mod.rs index ac248b10..ac9f6e20 100644 --- a/psst-gui/src/ui/mod.rs +++ b/psst-gui/src/ui/mod.rs @@ -393,15 +393,20 @@ fn route_widget() -> impl Widget { fn sidebar_menu_widget() -> impl Widget { Flex::column() .with_default_spacer() - .with_child(sidebar_link_widget("Home", Nav::Home)) - .with_child(sidebar_link_widget("Tracks", Nav::SavedTracks)) - .with_child(sidebar_link_widget("Albums", Nav::SavedAlbums)) - .with_child(sidebar_link_widget("Podcasts", Nav::Shows)) + .with_child(sidebar_link_widget("Home", Some(&icons::HOME), Nav::Home)) + .with_child(sidebar_link_widget("Tracks", Some(&icons::MUSIC_NOTE), Nav::SavedTracks)) + .with_child(sidebar_link_widget("Albums", Some(&icons::ALBUM), Nav::SavedAlbums)) + .with_child(sidebar_link_widget("Podcasts", Some(&icons::PODCAST), Nav::Shows)) .with_child(search::input_widget().padding((theme::grid(1.0), theme::grid(1.0)))) } -fn sidebar_link_widget(title: &str, link_nav: Nav) -> impl Widget { - Label::new(title) +fn sidebar_link_widget(title: &str, icon: Option<&icons::SvgIcon>, link_nav: Nav) -> impl Widget { + let mut row = Flex::row(); + if let Some(icon) = icon { + row.add_child(icon.scale((20.0, 20.0)).padding((0.0, 0.0, 8.0, 0.0))); + } + row.add_child(Label::new(title)); + row .padding((theme::grid(2.0), theme::grid(1.0))) .expand_width() .link() From cfca47aaf6f67aadfe6880f3f65793f90e9edb31 Mon Sep 17 00:00:00 2001 From: Cleboost Date: Sun, 29 Jun 2025 15:28:05 +0200 Subject: [PATCH 2/5] Enhance search input with icon and custom styling Refactored the search input widget to include a search icon and improved padding, background, and border styling for better UI consistency. Utilized a Container and Flex layout to align the icon and input field, and applied theme-based color adjustments. --- psst-gui/src/ui/search.rs | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/psst-gui/src/ui/search.rs b/psst-gui/src/ui/search.rs index b5245db6..1d14f63d 100644 --- a/psst-gui/src/ui/search.rs +++ b/psst-gui/src/ui/search.rs @@ -2,8 +2,8 @@ use std::sync::Arc; use druid::{ im::Vector, - widget::{CrossAxisAlignment, Either, Flex, Label, LabelText, List, TextBox}, - Data, LensExt, Selector, Widget, WidgetExt, + widget::{CrossAxisAlignment, Either, Flex, Label, LabelText, List, TextBox, Container}, + Data, LensExt, Selector, Widget, WidgetExt, Color, Env, }; use crate::{ @@ -15,7 +15,7 @@ use crate::{ }, ui::show, webapi::WebApi, - widget::{Async, Empty, MyWidgetExt}, + widget::{icons, Async, Empty, MyWidgetExt, Overlay}, }; use super::{album, artist, playable, playlist, theme, track, utils}; @@ -26,7 +26,7 @@ pub const LOAD_RESULTS: Selector> = Selector::new("app.search.load-resu pub const OPEN_LINK: Selector = Selector::new("app.search.open-link"); pub fn input_widget() -> impl Widget { - TextBox::new() + let search_field = TextBox::new() .with_placeholder("Search") .controller(InputController::new().on_submit(|ctx, query, _| { if query.trim().is_empty() { @@ -36,7 +36,33 @@ pub fn input_widget() -> impl Widget { })) .with_id(cmd::WIDGET_SEARCH_INPUT) .expand_width() - .lens(AppState::search.then(Search::input)) + .padding((theme::grid(0.8), theme::grid(0.15), theme::grid(0.2), theme::grid(0.15))) + .env_scope(|env, _| { + let bg_color = env.get(theme::GREY_700); + env.set(theme::BACKGROUND_LIGHT, bg_color); + env.set(theme::BACKGROUND_DARK, bg_color); + env.set(theme::BORDER_DARK, Color::TRANSPARENT); + env.set(theme::BORDER_LIGHT, Color::TRANSPARENT); + env.set(theme::SELECTION_COLOR, env.get(theme::SELECTION_COLOR)); + env.set(theme::CURSOR_COLOR, env.get(theme::CURSOR_COLOR)); + env.set(theme::PRIMARY_LIGHT, Color::TRANSPARENT); + env.set(theme::PRIMARY_DARK, Color::TRANSPARENT); + }) + .lens(AppState::search.then(Search::input)); + + let icon_overlay = icons::SEARCH + .scale((20.0, 20.0)) + .with_color(theme::PLACEHOLDER_COLOR) + .padding((theme::grid(0.5), theme::grid(0.5), theme::grid(0.2), theme::grid(0.5))); + + Container::new( + Flex::row() + .cross_axis_alignment(CrossAxisAlignment::Center) + .with_child(icon_overlay) + .with_flex_child(search_field, 1.0) + ) + .background(theme::GREY_700) + .rounded(theme::grid(1.0)) } pub fn results_widget() -> impl Widget { From 0952c2b3dfe572694260cf9fe445062df269f681 Mon Sep 17 00:00:00 2001 From: Cleboost Date: Sun, 29 Jun 2025 15:33:30 +0200 Subject: [PATCH 3/5] Update theme color usage in search input widget Replaces usage of SELECTION_COLOR with SELECTED_TEXT_BACKGROUND_COLOR in the search input widget. Also removes unused imports for Overlay and Env to clean up the code. --- psst-gui/src/ui/search.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/psst-gui/src/ui/search.rs b/psst-gui/src/ui/search.rs index 1d14f63d..9d651ecb 100644 --- a/psst-gui/src/ui/search.rs +++ b/psst-gui/src/ui/search.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use druid::{ im::Vector, widget::{CrossAxisAlignment, Either, Flex, Label, LabelText, List, TextBox, Container}, - Data, LensExt, Selector, Widget, WidgetExt, Color, Env, + Data, LensExt, Selector, Widget, WidgetExt, Color, }; use crate::{ @@ -15,7 +15,7 @@ use crate::{ }, ui::show, webapi::WebApi, - widget::{icons, Async, Empty, MyWidgetExt, Overlay}, + widget::{icons, Async, Empty, MyWidgetExt}, }; use super::{album, artist, playable, playlist, theme, track, utils}; @@ -43,7 +43,7 @@ pub fn input_widget() -> impl Widget { env.set(theme::BACKGROUND_DARK, bg_color); env.set(theme::BORDER_DARK, Color::TRANSPARENT); env.set(theme::BORDER_LIGHT, Color::TRANSPARENT); - env.set(theme::SELECTION_COLOR, env.get(theme::SELECTION_COLOR)); + env.set(theme::SELECTED_TEXT_BACKGROUND_COLOR, env.get(theme::SELECTED_TEXT_BACKGROUND_COLOR)); env.set(theme::CURSOR_COLOR, env.get(theme::CURSOR_COLOR)); env.set(theme::PRIMARY_LIGHT, Color::TRANSPARENT); env.set(theme::PRIMARY_DARK, Color::TRANSPARENT); From 525fdc6b765a1b9bf602c30bc9e6c48efc4d93fe Mon Sep 17 00:00:00 2001 From: Cleboost Date: Mon, 30 Jun 2025 21:14:06 +0200 Subject: [PATCH 4/5] Revert "Enhance search input with icon and custom styling" This reverts commit cfca47aaf6f67aadfe6880f3f65793f90e9edb31. This reverts commit 0952c2b3dfe572694260cf9fe445062df269f681. --- psst-gui/src/ui/search.rs | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/psst-gui/src/ui/search.rs b/psst-gui/src/ui/search.rs index 9d651ecb..b5245db6 100644 --- a/psst-gui/src/ui/search.rs +++ b/psst-gui/src/ui/search.rs @@ -2,8 +2,8 @@ use std::sync::Arc; use druid::{ im::Vector, - widget::{CrossAxisAlignment, Either, Flex, Label, LabelText, List, TextBox, Container}, - Data, LensExt, Selector, Widget, WidgetExt, Color, + widget::{CrossAxisAlignment, Either, Flex, Label, LabelText, List, TextBox}, + Data, LensExt, Selector, Widget, WidgetExt, }; use crate::{ @@ -15,7 +15,7 @@ use crate::{ }, ui::show, webapi::WebApi, - widget::{icons, Async, Empty, MyWidgetExt}, + widget::{Async, Empty, MyWidgetExt}, }; use super::{album, artist, playable, playlist, theme, track, utils}; @@ -26,7 +26,7 @@ pub const LOAD_RESULTS: Selector> = Selector::new("app.search.load-resu pub const OPEN_LINK: Selector = Selector::new("app.search.open-link"); pub fn input_widget() -> impl Widget { - let search_field = TextBox::new() + TextBox::new() .with_placeholder("Search") .controller(InputController::new().on_submit(|ctx, query, _| { if query.trim().is_empty() { @@ -36,33 +36,7 @@ pub fn input_widget() -> impl Widget { })) .with_id(cmd::WIDGET_SEARCH_INPUT) .expand_width() - .padding((theme::grid(0.8), theme::grid(0.15), theme::grid(0.2), theme::grid(0.15))) - .env_scope(|env, _| { - let bg_color = env.get(theme::GREY_700); - env.set(theme::BACKGROUND_LIGHT, bg_color); - env.set(theme::BACKGROUND_DARK, bg_color); - env.set(theme::BORDER_DARK, Color::TRANSPARENT); - env.set(theme::BORDER_LIGHT, Color::TRANSPARENT); - env.set(theme::SELECTED_TEXT_BACKGROUND_COLOR, env.get(theme::SELECTED_TEXT_BACKGROUND_COLOR)); - env.set(theme::CURSOR_COLOR, env.get(theme::CURSOR_COLOR)); - env.set(theme::PRIMARY_LIGHT, Color::TRANSPARENT); - env.set(theme::PRIMARY_DARK, Color::TRANSPARENT); - }) - .lens(AppState::search.then(Search::input)); - - let icon_overlay = icons::SEARCH - .scale((20.0, 20.0)) - .with_color(theme::PLACEHOLDER_COLOR) - .padding((theme::grid(0.5), theme::grid(0.5), theme::grid(0.2), theme::grid(0.5))); - - Container::new( - Flex::row() - .cross_axis_alignment(CrossAxisAlignment::Center) - .with_child(icon_overlay) - .with_flex_child(search_field, 1.0) - ) - .background(theme::GREY_700) - .rounded(theme::grid(1.0)) + .lens(AppState::search.then(Search::input)) } pub fn results_widget() -> impl Widget { From 91179be90c25f153a0ea6f719edcda4c64354bc4 Mon Sep 17 00:00:00 2001 From: Jackson Goode <54308792+jacksongoode@users.noreply.github.com> Date: Wed, 26 Nov 2025 02:24:02 +0900 Subject: [PATCH 5/5] Cleanup and use size 18.0 --- psst-gui/src/ui/mod.rs | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/psst-gui/src/ui/mod.rs b/psst-gui/src/ui/mod.rs index ac9f6e20..61effda4 100644 --- a/psst-gui/src/ui/mod.rs +++ b/psst-gui/src/ui/mod.rs @@ -394,19 +394,40 @@ fn sidebar_menu_widget() -> impl Widget { Flex::column() .with_default_spacer() .with_child(sidebar_link_widget("Home", Some(&icons::HOME), Nav::Home)) - .with_child(sidebar_link_widget("Tracks", Some(&icons::MUSIC_NOTE), Nav::SavedTracks)) - .with_child(sidebar_link_widget("Albums", Some(&icons::ALBUM), Nav::SavedAlbums)) - .with_child(sidebar_link_widget("Podcasts", Some(&icons::PODCAST), Nav::Shows)) + .with_child(sidebar_link_widget( + "Tracks", + Some(&icons::MUSIC_NOTE), + Nav::SavedTracks, + )) + .with_child(sidebar_link_widget( + "Albums", + Some(&icons::ALBUM), + Nav::SavedAlbums, + )) + .with_child(sidebar_link_widget( + "Podcasts", + Some(&icons::PODCAST), + Nav::Shows, + )) .with_child(search::input_widget().padding((theme::grid(1.0), theme::grid(1.0)))) } -fn sidebar_link_widget(title: &str, icon: Option<&icons::SvgIcon>, link_nav: Nav) -> impl Widget { - let mut row = Flex::row(); - if let Some(icon) = icon { - row.add_child(icon.scale((20.0, 20.0)).padding((0.0, 0.0, 8.0, 0.0))); - } - row.add_child(Label::new(title)); - row +fn sidebar_link_widget( + title: &str, + icon: Option<&icons::SvgIcon>, + link_nav: Nav, +) -> impl Widget { + Flex::row() + .with_child( + icon.map(|i| { + i.scale((18.0, 18.0)) + .padding_right(theme::grid(1.0)) + .boxed() + }) + .unwrap_or_else(|| Empty.boxed()), + ) + .with_child(Label::new(title)) + .with_flex_spacer(1.0) .padding((theme::grid(2.0), theme::grid(1.0))) .expand_width() .link()