feat(ui): refine about dialog

Use intrinsic modal sizing and present platform details in a balanced layout.\n\nRefs #450
This commit is contained in:
Hakan Seven committed 2026-08-04 15:53:34 +03:00
1 parent 2f86bfde8e
commit 429d2eb06b
3 files changed
+125 -74

No files matched your search

+2 -2
View File
@@ -5006,8 +5006,8 @@ impl OpenCADStudio {
let info = format!( let info = format!(
"Open CAD Studio v{}\nOS: {}\nArch: {}", "Open CAD Studio v{}\nOS: {}\nArch: {}",
env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_VERSION"),
std::env::consts::OS, crate::ui::window::about::platform_name(),
std::env::consts::ARCH, crate::ui::window::about::architecture_name(),
); );
iced::clipboard::write(info).discard() iced::clipboard::write(info).discard()
} }
+3 -6
View File
@@ -54,12 +54,9 @@ impl OpenCADStudio {
pub(super) fn modal_content<'s>(&'s self) -> Option<Element<'s, Message>> { pub(super) fn modal_content<'s>(&'s self) -> Option<Element<'s, Message>> {
let ex = self.modal_resize; let ex = self.modal_resize;
Some(match self.active_modal? { Some(match self.active_modal? {
super::super::ModalKind::About => automatic_flow(ex, |flow| { super::super::ModalKind::About => {
container(crate::ui::window::about::view_window()) automatic_flow(ex, crate::ui::window::about::view_window)
.width(flow.width) }
.height(flow.height)
.into()
}),
super::super::ModalKind::Shortcuts => { super::super::ModalKind::Shortcuts => {
sized_flow( sized_flow(
ex, ex,
+120 -66
View File
@@ -1,91 +1,145 @@
use crate::app::Message; use crate::app::Message;
use iced::widget::{button, column, container, row, text};
use iced::{Background, Element, Theme};
use crate::t; 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 {
label: std::borrow::Cow<'static, str>, iced::widget::text::Style {
value: String,
) -> 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)), color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
}) }
.width(100), }
text(value).size(11),
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: impl iced::widget::text::IntoFragment<'a>,
width: Length,
) -> Element<'a, Message> {
container(
column![
text(label).size(10).style(muted_style),
text(value).size(14),
] ]
.spacing(8) .spacing(5),
.align_y(iced::Center) )
.padding([3, 0]) .padding([10, 12])
.width(width)
.height(Length::Fixed(62.0))
.style(surface_style)
.into() .into()
} }
pub fn view_window<'a>() -> Element<'a, Message> { pub(crate) fn platform_name() -> &'static str {
let version = env!("CARGO_PKG_VERSION"); #[cfg(target_arch = "wasm32")]
let os = std::env::consts::OS; {
let arch = std::env::consts::ARCH; "Web"
}
#[cfg(not(target_arch = "wasm32"))]
{
match std::env::consts::OS {
"linux" => "Linux",
"windows" => "Windows",
"macos" => "macOS",
other => other,
}
}
}
let logo = container( 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![ column![
text("Open CAD Studio") text("Open CAD Studio").size(28).style(primary_style),
.size(32)
.style(|theme: &Theme| iced::widget::text::Style {
color: Some(theme.palette().primary.base.color),
}),
text(t!("CAD application for Architecture & Engineering")) text(t!("CAD application for Architecture & Engineering"))
.size(11) .size(11)
.style(|theme: &Theme| iced::widget::text::Style { .style(muted_style),
color: Some(theme.palette().background.base.text.scale_alpha(0.68)), text(version.clone()).size(13),
}),
] ]
.spacing(4) .spacing(5),
.align_x(iced::Center),
)
.padding(iced::Padding {
top: 20.0,
right: 0.0,
bottom: 16.0,
left: 0.0,
})
.align_x(iced::Center);
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) .spacing(18)
.padding([12, 16]), .align_y(iced::Center),
) )
.style(container::bordered_box); .padding([14, 16])
.width(content_width)
.style(surface_style);
let copy_btn = button(text(t!("Copy Info")).size(11)) 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 = button(text(t!("Copy Info")).size(11))
.on_press(Message::AboutCopyInfo) .on_press(Message::AboutCopyInfo)
.style(button::primary) .style(button::primary)
.padding([6, 16]); .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( container(
column![logo, info_block, footer] column![
.spacing(0) hero,
.padding(iced::Padding { metadata,
top: 0.0, row![Space::new().width(content_width), copy]
right: 20.0, .width(sizing.width)
bottom: 20.0, .align_y(iced::Center),
left: 20.0, ]
}), .spacing(12)
.padding(16)
.width(sizing.width)
.height(sizing.height),
) )
.width(sizing.width)
.height(sizing.height)
.style(|theme: &Theme| container::Style { .style(|theme: &Theme| container::Style {
background: Some(Background::Color( background: Some(Background::Color(
theme.palette().background.base.color, theme.palette().background.base.color,