From dd8f73f9ba7df0770fd6ea0f60d55e4713748ceb Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Sat, 9 Nov 2024 19:56:59 +0100 Subject: [PATCH] improv: about api --- Cargo.toml | 3 +- examples/about/src/main.rs | 19 +++--- iced | 2 +- src/widget/about.rs | 134 +++++++++++++++++-------------------- 4 files changed, 77 insertions(+), 81 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d9265d421d9..57b59b6bde8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ desktop = [ "process", "dep:freedesktop-desktop-entry", "dep:mime", - + "dep:license", "dep:shlex", "tokio?/io-util", "tokio?/net", @@ -98,6 +98,7 @@ fraction = "0.15.3" image = { version = "0.25.1", optional = true } lazy_static = "1.4.0" libc = { version = "0.2.155", optional = true } +license = { version = "3.5.1", optional = true } mime = { version = "0.3.17", optional = true } palette = "0.7.3" rfd = { version = "0.14.0", optional = true } diff --git a/examples/about/src/main.rs b/examples/about/src/main.rs index cf6e3d70037..14a278057d1 100644 --- a/examples/about/src/main.rs +++ b/examples/about/src/main.rs @@ -64,14 +64,17 @@ impl cosmic::Application for App { let nav_model = nav_bar::Model::default(); let about = About::default() - .set_application_name("About Demo") - .set_application_icon(Self::APP_ID) - .set_developer_name("System 76") - .set_license_type("GPL-3.0") - .set_website("https://system76.com/cosmic") - .set_repository_url("https://github.com/pop-os/libcosmic") - .set_support_url("https://github.com/pop-os/libcosmic/issues") - .set_developers([("Michael Murphy".into(), "mmstick@system76.com".into())]); + .name("About Demo") + .icon(Self::APP_ID) + .version("0.1.0") + .author("System 76") + .license("GPL-3.0-only") + .developers([("Michael Murphy", "mmstick@system76.com")]) + .links([ + ("Website", "https://system76.com/cosmic"), + ("Repository", "https://github.com/pop-os/libcosmic)"), + ("Support", "https://github.com/pop-os/libcosmic/issues"), + ]); let mut app = App { core, diff --git a/iced b/iced index a7e035cd852..32972639773 160000 --- a/iced +++ b/iced @@ -1 +1 @@ -Subproject commit a7e035cd852ab13ce0ef04671c1e683fc343aff6 +Subproject commit 3297263977365a5d7e4c4cd9bbc13613b674763b diff --git a/src/widget/about.rs b/src/widget/about.rs index c893ef38513..7a28479fb87 100644 --- a/src/widget/about.rs +++ b/src/widget/about.rs @@ -1,3 +1,5 @@ +use iced_widget::tooltip::Position; +use license::License; #[cfg(feature = "desktop")] use { crate::{ @@ -9,120 +11,108 @@ use { }; #[derive(Debug, Default, Clone, derive_setters::Setters)] -#[setters(prefix = "set_", into, strip_option)] +#[setters(into, strip_option)] /// Information about the application. pub struct About { /// The application's name. - pub application_name: Option, + name: Option, /// The application's icon name. - pub application_icon: Option, - /// Artists who contributed to the application. - #[setters(skip)] - pub artists: BTreeMap, + icon: Option, + /// The application’s version. + version: Option, + /// Name of the application's author. + author: Option, /// Comments about the application. - pub comments: Option, + comments: Option, /// The application's copyright. - pub copyright: Option, + copyright: Option, + /// The license text. + license: Option, + /// Artists who contributed to the application. + #[setters(skip)] + artists: BTreeMap, /// Designers who contributed to the application. #[setters(skip)] - pub designers: BTreeMap, - /// Name of the application's developer. - pub developer_name: Option, + designers: BTreeMap, /// Developers who contributed to the application. #[setters(skip)] - pub developers: BTreeMap, + developers: BTreeMap, /// Documenters who contributed to the application. #[setters(skip)] - pub documenters: BTreeMap, - /// The license text. - pub license: Option, - /// The license from a list of known licenses. - pub license_type: Option, - /// The URL of the application’s support page. - #[setters(skip)] - pub support_url: Option, - /// The URL of the application’s repository. - #[setters(skip)] - pub repository_url: Option, + documenters: BTreeMap, /// Translators who contributed to the application. #[setters(skip)] - pub translators: BTreeMap, + translators: BTreeMap, /// Links associated with the application. #[setters(skip)] - pub links: BTreeMap, - /// The application’s version. - pub version: Option, - /// The application’s website. - #[setters(skip)] - pub website: Option, + links: BTreeMap, } -impl About { - pub fn set_repository_url(mut self, repository_url: impl Into) -> Self { - let repository_url = repository_url.into(); - self.repository_url = Some(repository_url.clone()); - self.links.insert("Repository".into(), repository_url); - self - } - - pub fn set_support_url(mut self, support_url: impl Into) -> Self { - let support_url = support_url.into(); - self.support_url = Some(support_url.clone()); - self.links.insert("Support".into(), support_url); - self - } - - pub fn set_website(mut self, website: impl Into) -> Self { - let website = website.into(); - self.website = Some(website.clone()); - self.links.insert("Website".into(), website); +impl<'a> About { + pub fn links(mut self, links: impl Into>) -> Self { + let links: BTreeMap<&'a str, &'a str> = links.into(); + self.links = links + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); self } - pub fn set_artists(mut self, artists: impl Into>) -> Self { - let artists: BTreeMap = artists.into(); + pub fn artists(mut self, artists: impl Into>) -> Self { + let artists: BTreeMap<&'a str, &'a str> = artists.into(); self.artists = artists .into_iter() - .map(|(k, v)| (k, format!("mailto:{v}"))) + .map(|(k, v)| (k.to_string(), format!("mailto:{v}"))) .collect(); self } - pub fn set_designers(mut self, designers: impl Into>) -> Self { - let designers: BTreeMap = designers.into(); + pub fn designers(mut self, designers: impl Into>) -> Self { + let designers: BTreeMap<&'a str, &'a str> = designers.into(); self.designers = designers .into_iter() - .map(|(k, v)| (k, format!("mailto:{v}"))) + .map(|(k, v)| (k.to_string(), format!("mailto:{v}"))) .collect(); self } - pub fn set_developers(mut self, developers: impl Into>) -> Self { - let developers: BTreeMap = developers.into(); + pub fn developers(mut self, developers: impl Into>) -> Self { + let developers: BTreeMap<&'a str, &'a str> = developers.into(); self.developers = developers .into_iter() - .map(|(k, v)| (k, format!("mailto:{v}"))) + .map(|(k, v)| (k.to_string(), format!("mailto:{v}"))) .collect(); self } - pub fn set_documenters(mut self, documenters: impl Into>) -> Self { - let documenters: BTreeMap = documenters.into(); + pub fn documenters(mut self, documenters: impl Into>) -> Self { + let documenters: BTreeMap<&'a str, &'a str> = documenters.into(); self.documenters = documenters .into_iter() - .map(|(k, v)| (k, format!("mailto:{v}"))) + .map(|(k, v)| (k.to_string(), format!("mailto:{v}"))) .collect(); self } - pub fn set_translators(mut self, translators: impl Into>) -> Self { - let translators: BTreeMap = translators.into(); + pub fn translators(mut self, translators: impl Into>) -> Self { + let translators: BTreeMap<&'a str, &'a str> = translators.into(); self.translators = translators .into_iter() - .map(|(k, v)| (k, format!("mailto:{v}"))) + .map(|(k, v)| (k.to_string(), format!("mailto:{v}"))) .collect(); self } + + fn license_url(&self) -> Option { + let license: &dyn License = match self.license.as_ref() { + Some(license) => license.parse().ok()?, + None => return None, + }; + + self.license + .as_ref() + .map(|_| format!("https://spdx.org/licenses/{}.html", license.id())) + } } /// Constructs the widget for the about section. @@ -137,7 +127,7 @@ pub fn about<'a, Message: Clone + 'static>( None } else { let developers: Vec> = list - .into_iter() + .iter() .map(|(name, url)| { widget::button::custom( widget::row() @@ -148,7 +138,7 @@ pub fn about<'a, Message: Clone + 'static>( .align_y(Vertical::Center), ) .class(crate::theme::Button::Text) - .on_press(on_url_press(url.clone())) + .on_press(on_url_press(url.to_string())) .width(Length::Fill) .into() }) @@ -157,9 +147,9 @@ pub fn about<'a, Message: Clone + 'static>( } }; - let application_name = about.application_name.as_ref().map(widget::text::title3); + let application_name = about.name.as_ref().map(widget::text::title3); let application_icon = about - .application_icon + .icon .as_ref() .map(|icon| crate::desktop::IconSource::Name(icon.clone()).as_cosmic_icon()); @@ -170,9 +160,11 @@ pub fn about<'a, Message: Clone + 'static>( let translators_section = section(&about.translators, "Translators"); let documenters_section = section(&about.documenters, "Documenters"); - let developer_name = about.developer_name.as_ref().map(widget::text); + let author = about.author.as_ref().map(widget::text); let version = about.version.as_ref().map(widget::button::standard); - let license = about.license_type.as_ref().map(widget::button::standard); + let license = about.license.as_ref().map(|license| { + widget::button::standard(license).on_press_maybe(about.license_url().map(on_url_press)) + }); let copyright = about.copyright.as_ref().map(widget::text::body); let comments = about.comments.as_ref().map(widget::text::body); @@ -180,7 +172,7 @@ pub fn about<'a, Message: Clone + 'static>( widget::column() .push_maybe(application_icon) .push_maybe(application_name) - .push_maybe(developer_name) + .push_maybe(author) .push( widget::row() .push_maybe(version)