From 5cd774241308e807dedefd34d353492b3db51848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:18:50 +0200 Subject: [PATCH] chore(about): styling fixes Also reduces code duplication a bit. --- src/widget/about.rs | 162 +++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 86 deletions(-) diff --git a/src/widget/about.rs b/src/widget/about.rs index f1538d8f..9f2276c8 100644 --- a/src/widget/about.rs +++ b/src/widget/about.rs @@ -1,5 +1,5 @@ use crate::{ - Element, fl, + Apply, Element, fl, iced::{Alignment, Length}, widget::{self, horizontal_space}, }; @@ -22,7 +22,7 @@ pub struct About { copyright: Option, /// The license name. license: Option, - /// The license url. If None spdx.org url is used. + /// The license url. license_url: Option, /// Artists who contributed to the application. #[setters(skip)] @@ -51,36 +51,28 @@ fn add_contributors(contributors: Vec<(&str, &str)>) -> Vec<(String, String)> { .collect() } +macro_rules! set_contributors { + ($field:ident, $doc:expr) => { + #[doc = $doc] + pub fn $field(mut self, contributors: impl Into>) -> Self { + self.$field = add_contributors(contributors.into()); + self + } + }; +} + impl<'a> About { - /// Artists who contributed to the application. - pub fn artists(mut self, artists: impl Into>) -> Self { - self.artists = add_contributors(artists.into()); - self - } - - /// Designers who contributed to the application. - pub fn designers(mut self, designers: impl Into>) -> Self { - self.designers = add_contributors(designers.into()); - self - } - - /// Developers who contributed to the application. - pub fn developers(mut self, developers: impl Into>) -> Self { - self.developers = add_contributors(developers.into()); - self - } - - /// Documenters who contributed to the application. - pub fn documenters(mut self, documenters: impl Into>) -> Self { - self.documenters = add_contributors(documenters.into()); - self - } - - /// Translators who contributed to the application. - pub fn translators(mut self, translators: impl Into>) -> Self { - self.translators = add_contributors(translators.into()); - self - } + set_contributors!(artists, "Artists who contributed to the application."); + set_contributors!(designers, "Designers who contributed to the application."); + set_contributors!(developers, "Developers who contributed to the application."); + set_contributors!( + documenters, + "Documenters who contributed to the application." + ); + set_contributors!( + translators, + "Translators who contributed to the application." + ); /// Links associated with the application. pub fn links, V: Into>( @@ -104,88 +96,86 @@ pub fn about<'a, Message: Clone + 'static>( space_xxs, space_m, .. } = crate::theme::spacing(); + let section_button = |name: &'a str, url: &'a str| -> Element<'a, Message> { + widget::row() + .push(widget::text(name)) + .push(horizontal_space()) + .push_maybe( + (!url.is_empty()).then_some(crate::widget::icon::from_name("link-symbolic").icon()), + ) + .align_y(Alignment::Center) + .apply(widget::button::custom) + .class(crate::theme::Button::Link) + .on_press(on_url_press(url)) + .width(Length::Fill) + .into() + }; + let section = |list: &'a Vec<(String, String)>, title: String| { (!list.is_empty()).then_some({ - let items: Vec> = - list.iter() - .map(|(name, url)| { - widget::button::custom( - widget::row() - .push(widget::text(name)) - .push(horizontal_space()) - .push_maybe((!url.is_empty()).then_some( - crate::widget::icon::from_name("link-symbolic").icon(), - )) - .align_y(Alignment::Center), - ) - .class(crate::theme::Button::Link) - .on_press(on_url_press(url)) - .width(Length::Fill) - .into() - }) - .collect(); + let items: Vec> = list + .iter() + .map(|(name, url)| section_button(name, url)) + .collect(); widget::settings::section().title(title).extend(items) }) }; - let application_name = about.name.as_ref().map(widget::text::title3); - let application_icon = about.icon.as_ref().map(|i| { - i.clone() - .icon() - .content_fit(iced::ContentFit::Contain) - .width(Length::Fixed(128.)) - .height(Length::Fixed(128.)) - }); - let author = about.author.as_ref().map(widget::text::body); - let version = about.version.as_ref().map(widget::button::standard); + let header_children: Vec> = [ + about.icon.as_ref().map(|i| { + i.clone() + .icon() + .size(256) + .width(Length::Fixed(128.)) + .height(Length::Fixed(128.)) + .content_fit(iced::ContentFit::Contain) + .into() + }), + about.name.as_ref().map(|n| widget::text::title3(n).into()), + about.author.as_ref().map(|a| widget::text::body(a).into()), + about.version.as_ref().map(|v| { + widget::button::standard(v) + .apply(widget::container) + .padding([space_xxs, 0, 0, 0]) + .into() + }), + ] + .into_iter() + .flatten() + .collect(); + let header = (!header_children.is_empty()) + .then_some(widget::column::with_children(header_children).align_x(Alignment::Center)); + let links_section = section(&about.links, fl!("links")); let developers_section = section(&about.developers, fl!("developers")); let designers_section = section(&about.designers, fl!("designers")); let artists_section = section(&about.artists, fl!("artists")); let translators_section = section(&about.translators, fl!("translators")); let documenters_section = section(&about.documenters, fl!("documenters")); - let license = about.license.as_ref().map(|license| { - let url = about.license_url.as_deref(); - widget::settings::section().title(fl!("license")).add( - widget::button::custom( - widget::row() - .push(widget::text(license)) - .push(horizontal_space()) - .push_maybe( - url.is_some() - .then_some(crate::widget::icon::from_name("link-symbolic").icon()), - ) - .align_y(Alignment::Center), - ) - .class(crate::theme::Button::Link) - .on_press(on_url_press(url.unwrap_or_default())) - .width(Length::Fill), + let license_section = about.license.as_ref().and_then(|license| { + let url = about.license_url.as_deref().unwrap_or_default(); + Some( + widget::settings::section() + .title(fl!("license")) + .add(section_button(license, url)), ) }); let copyright = about.copyright.as_ref().map(widget::text::body); let comments = about.comments.as_ref().map(widget::text::body); widget::column() - .push( - widget::column() - .push_maybe(application_icon) - .push_maybe(application_name) - .push_maybe(author) - .push_maybe(version) - .align_x(Alignment::Center) - .spacing(space_xxs), - ) - .push_maybe(license) + .push_maybe(header) .push_maybe(links_section) .push_maybe(developers_section) .push_maybe(designers_section) .push_maybe(artists_section) .push_maybe(translators_section) .push_maybe(documenters_section) + .push_maybe(license_section) .push_maybe(comments) .push_maybe(copyright) - .align_x(Alignment::Center) .spacing(space_m) .width(Length::Fill) + .align_x(Alignment::Center) .into() }