diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index 364d9d82a..8c647591d 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -5006,8 +5006,8 @@ impl OpenCADStudio { let info = format!( "Open CAD Studio v{}\nOS: {}\nArch: {}", env!("CARGO_PKG_VERSION"), - std::env::consts::OS, - std::env::consts::ARCH, + crate::ui::window::about::platform_name(), + crate::ui::window::about::architecture_name(), ); iced::clipboard::write(info).discard() } diff --git a/src/app/view/modal.rs b/src/app/view/modal.rs index aa99d37e0..6a2c5c7ae 100644 --- a/src/app/view/modal.rs +++ b/src/app/view/modal.rs @@ -54,12 +54,9 @@ impl OpenCADStudio { pub(super) fn modal_content<'s>(&'s self) -> Option> { let ex = self.modal_resize; Some(match self.active_modal? { - super::super::ModalKind::About => automatic_flow(ex, |flow| { - container(crate::ui::window::about::view_window()) - .width(flow.width) - .height(flow.height) - .into() - }), + super::super::ModalKind::About => { + automatic_flow(ex, crate::ui::window::about::view_window) + } super::super::ModalKind::Shortcuts => { sized_flow( ex, diff --git a/src/ui/window/about.rs b/src/ui/window/about.rs index 0c6984cca..6b7c8e87e 100644 --- a/src/ui/window/about.rs +++ b/src/ui/window/about.rs @@ -1,91 +1,145 @@ use crate::app::Message; -use iced::widget::{button, column, container, row, text}; -use iced::{Background, Element, Theme}; use crate::t; +use iced::widget::{button, column, container, row, svg, text, Space}; +use iced::{Background, Border, Element, Fill, Length, Shrink, Theme}; -fn info_row<'a>( +fn muted_style(theme: &Theme) -> iced::widget::text::Style { + iced::widget::text::Style { + color: Some(theme.palette().background.base.text.scale_alpha(0.68)), + } +} + +fn primary_style(theme: &Theme) -> iced::widget::text::Style { + iced::widget::text::Style { + color: Some(theme.palette().primary.base.color), + } +} + +fn surface_style(theme: &Theme) -> container::Style { + container::Style { + background: Some(Background::Color( + theme.palette().background.weakest.color, + )), + border: Border { + color: theme.palette().background.neutral.color, + width: 1.0, + radius: 8.0.into(), + }, + ..Default::default() + } +} + +fn info_card<'a>( label: std::borrow::Cow<'static, str>, - value: String, + value: impl iced::widget::text::IntoFragment<'a>, + width: Length, ) -> Element<'a, Message> { - row![ - text(label) - .size(11) - .style(|theme: &Theme| iced::widget::text::Style { - color: Some(theme.palette().background.base.text.scale_alpha(0.68)), - }) - .width(100), - text(value).size(11), - ] - .spacing(8) - .align_y(iced::Center) - .padding([3, 0]) + container( + column![ + text(label).size(10).style(muted_style), + text(value).size(14), + ] + .spacing(5), + ) + .padding([10, 12]) + .width(width) + .height(Length::Fixed(62.0)) + .style(surface_style) .into() } -pub fn view_window<'a>() -> Element<'a, Message> { - let version = env!("CARGO_PKG_VERSION"); - let os = std::env::consts::OS; - let arch = std::env::consts::ARCH; +pub(crate) fn platform_name() -> &'static str { + #[cfg(target_arch = "wasm32")] + { + "Web" + } + #[cfg(not(target_arch = "wasm32"))] + { + match std::env::consts::OS { + "linux" => "Linux", + "windows" => "Windows", + "macos" => "macOS", + other => other, + } + } +} - let logo = container( - column![ - text("Open CAD Studio") - .size(32) - .style(|theme: &Theme| iced::widget::text::Style { - color: Some(theme.palette().primary.base.color), - }), - text(t!("CAD application for Architecture & Engineering")) - .size(11) - .style(|theme: &Theme| iced::widget::text::Style { - color: Some(theme.palette().background.base.text.scale_alpha(0.68)), - }), +pub(crate) fn architecture_name() -> &'static str { + match std::env::consts::ARCH { + "x86_64" => "x86-64", + "aarch64" => "ARM64", + "wasm32" => "WebAssembly 32-bit", + other => other, + } +} + +pub fn view_window( + sizing: crate::ui::modal::ModalSizing, +) -> Element<'static, Message> { + let version = format!("v{}", env!("CARGO_PKG_VERSION")); + let content_width = if matches!(sizing.width, Length::Fill) { + Fill + } else { + Shrink + }; + let card_width = if matches!(sizing.width, Length::Fill) { + Length::FillPortion(1) + } else { + Length::Fixed(148.0) + }; + let logo = svg(svg::Handle::from_memory(include_bytes!( + "../../../assets/logo.svg" + ))) + .width(Length::Fixed(72.0)) + .height(Length::Fixed(72.0)); + + let hero = container( + row![ + logo, + column![ + text("Open CAD Studio").size(28).style(primary_style), + text(t!("CAD application for Architecture & Engineering")) + .size(11) + .style(muted_style), + text(version.clone()).size(13), + ] + .spacing(5), ] - .spacing(4) - .align_x(iced::Center), + .spacing(18) + .align_y(iced::Center), ) - .padding(iced::Padding { - top: 20.0, - right: 0.0, - bottom: 16.0, - left: 0.0, - }) - .align_x(iced::Center); + .padding([14, 16]) + .width(content_width) + .style(surface_style); - let info_block = container( - column![ - info_row(t!("Version"), format!("v{}", version)), - info_row(t!("Platform"), os.to_string()), - info_row(t!("Arch"), arch.to_string()), - ] - .spacing(2) - .padding([12, 16]), - ) - .style(container::bordered_box); + let metadata = row![ + info_card(t!("Version"), version, card_width), + info_card(t!("Platform"), platform_name(), card_width), + info_card(t!("Arch"), architecture_name(), card_width), + ] + .spacing(8) + .width(content_width); - let copy_btn = button(text(t!("Copy Info")).size(11)) + let copy = button(text(t!("Copy Info")).size(11)) .on_press(Message::AboutCopyInfo) .style(button::primary) .padding([6, 16]); - let footer = row![copy_btn] - .align_y(iced::Center) - .padding(iced::Padding { - top: 12.0, - right: 0.0, - bottom: 0.0, - left: 0.0, - }); - container( - column![logo, info_block, footer] - .spacing(0) - .padding(iced::Padding { - top: 0.0, - right: 20.0, - bottom: 20.0, - left: 20.0, - }), + column![ + hero, + metadata, + row![Space::new().width(content_width), copy] + .width(sizing.width) + .align_y(iced::Center), + ] + .spacing(12) + .padding(16) + .width(sizing.width) + .height(sizing.height), ) + .width(sizing.width) + .height(sizing.height) .style(|theme: &Theme| container::Style { background: Some(Background::Color( theme.palette().background.base.color,