fix(ui): make modal layouts intrinsic
Pin Iced 0.15 so dialogs can measure content before distributing the resolved frame across child panels. Keep the web plugin notice compact and non-resizable.\n\nCloses #582
This commit is contained in:
parent
284d6ef517
commit
3ab8dc3ca5
59 changed files with 2194 additions and 1649 deletions
854
Cargo.lock
generated
854
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
15
Cargo.toml
15
Cargo.toml
|
|
@ -48,8 +48,11 @@ semver = "1"
|
||||||
# Forcing the `static` feature builds liblzma from the bundled source, making
|
# Forcing the `static` feature builds liblzma from the bundled source, making
|
||||||
# the binary self-contained on every platform.
|
# the binary self-contained on every platform.
|
||||||
lzma-sys = { version = "0.1", features = ["static"], optional = true }
|
lzma-sys = { version = "0.1", features = ["static"], optional = true }
|
||||||
iced = { version = "0.14", features = ["image", "svg", "advanced", "canvas", "smol", "markdown"] }
|
iced = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39", features = ["image", "svg", "advanced", "canvas", "smol", "markdown"] }
|
||||||
iced_aw = { version = "0.14.1", features = ["menu"] }
|
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||||
|
# iced_aw 0.15 compatibility is pending upstream in PR #432. Pin the exact
|
||||||
|
# reviewed pair of commits so Iced and its additional widgets cannot drift.
|
||||||
|
iced_aw = { git = "https://github.com/tsuza/iced_aw.git", rev = "a9301708a4d008dc17f63cbbbb2b2aa06e0e7352", features = ["menu", "context_menu"] }
|
||||||
bytemuck = { version = "1.25", features = ["derive"] }
|
bytemuck = { version = "1.25", features = ["derive"] }
|
||||||
glam = { version = "0.33", features = ["bytemuck"] }
|
glam = { version = "0.33", features = ["bytemuck"] }
|
||||||
truck-modeling = "0.6"
|
truck-modeling = "0.6"
|
||||||
|
|
@ -101,6 +104,10 @@ windows-sys = { version = "0.61", features = ["Win32_UI_Shell", "Win32_UI_Window
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# Track standard DWG object relationships used by the scene integration.
|
# Track standard DWG object relationships used by the scene integration.
|
||||||
acadrust = { git = "https://github.com/OpenAEC-Foundation/acadifc.git", rev = "a7b1e07" }
|
acadrust = { git = "https://github.com/OpenAEC-Foundation/acadifc.git", rev = "a7b1e07" }
|
||||||
|
# iced_aw's 0.15 branch declares the split Iced crates by version. Resolve
|
||||||
|
# those declarations to the same Iced commit as the application dependency.
|
||||||
|
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||||
|
iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
# Native enables the plugin host runtime (out-of-process plugins).
|
# Native enables the plugin host runtime (out-of-process plugins).
|
||||||
|
|
@ -132,7 +139,7 @@ js-sys = "0.3"
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
# window.open (external URLs) + Blob/anchor file downloads (Save) + fetch()
|
# window.open (external URLs) + Blob/anchor file downloads (Save) + fetch()
|
||||||
# (Response) for the lazy per-script web font loader (#141).
|
# (Response) for the lazy per-script web font loader (#141).
|
||||||
web-sys = { version = "0.3", features = [
|
web-sys = { version = "=0.3.85", features = [
|
||||||
"Window",
|
"Window",
|
||||||
"Storage",
|
"Storage",
|
||||||
"StorageManager",
|
"StorageManager",
|
||||||
|
|
@ -176,7 +183,7 @@ web-sys = { version = "0.3", features = [
|
||||||
# `webgl` enables it. `fira-sans` embeds the default UI font — the web has no
|
# `webgl` enables it. `fira-sans` embeds the default UI font — the web has no
|
||||||
# system fonts, so without it all iced text (ribbon labels, command line) is
|
# system fonts, so without it all iced text (ribbon labels, command line) is
|
||||||
# blank. Features merge with the main `iced` dependency.
|
# blank. Features merge with the main `iced` dependency.
|
||||||
iced = { version = "0.14", features = ["webgl", "fira-sans"] }
|
iced = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39", features = ["webgl", "fira-sans"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
strip = true
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ impl OpenCADStudio {
|
||||||
Some(text) => {
|
Some(text) => {
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_info("Copied selected text to clipboard.");
|
.push_info("Copied selected text to clipboard.");
|
||||||
Some(iced::clipboard::write(text))
|
Some(iced::clipboard::write(text).discard())
|
||||||
}
|
}
|
||||||
None => Some(Task::none()),
|
None => Some(Task::none()),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ impl Default for UiThemeConfig {
|
||||||
let theme = iced::Theme::Oxocarbon;
|
let theme = iced::Theme::Oxocarbon;
|
||||||
Self {
|
Self {
|
||||||
name: theme.to_string(),
|
name: theme.to_string(),
|
||||||
palette: UiThemePalette::from_iced(theme.palette()),
|
palette: UiThemePalette::from_iced(theme.seed()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,12 +88,12 @@ pub struct UiThemePalette {
|
||||||
|
|
||||||
impl Default for UiThemePalette {
|
impl Default for UiThemePalette {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::from_iced(iced::Theme::Oxocarbon.palette())
|
Self::from_iced(iced::Theme::Oxocarbon.seed())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiThemePalette {
|
impl UiThemePalette {
|
||||||
pub fn from_iced(palette: iced::theme::Palette) -> Self {
|
pub fn from_iced(palette: iced::theme::palette::Seed) -> Self {
|
||||||
Self {
|
Self {
|
||||||
background: color_to_rgb(palette.background),
|
background: color_to_rgb(palette.background),
|
||||||
text: color_to_rgb(palette.text),
|
text: color_to_rgb(palette.text),
|
||||||
|
|
@ -104,8 +104,8 @@ impl UiThemePalette {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_iced(self) -> iced::theme::Palette {
|
pub fn to_iced(self) -> iced::theme::palette::Seed {
|
||||||
iced::theme::Palette {
|
iced::theme::palette::Seed {
|
||||||
background: rgb_to_color(self.background),
|
background: rgb_to_color(self.background),
|
||||||
text: rgb_to_color(self.text),
|
text: rgb_to_color(self.text),
|
||||||
primary: rgb_to_color(self.primary),
|
primary: rgb_to_color(self.primary),
|
||||||
|
|
|
||||||
|
|
@ -1044,7 +1044,9 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||||
Message::MTextPasteClip,
|
Message::MTextPasteClip,
|
||||||
);
|
);
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
return iced::clipboard::read().map(Message::MTextPasteClip);
|
return iced::clipboard::read_text().map(|result| {
|
||||||
|
Message::MTextPasteClip(result.ok().map(|text| (*text).clone()))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if self.text_inline.is_some() {
|
if self.text_inline.is_some() {
|
||||||
// Web: the iced text_input can't reach the async clipboard,
|
// Web: the iced text_input can't reach the async clipboard,
|
||||||
|
|
|
||||||
|
|
@ -1149,7 +1149,8 @@ impl OpenCADStudio {
|
||||||
});
|
});
|
||||||
self.command_line
|
self.command_line
|
||||||
.push_output(&format!("Copied path: {}", full_path.display()));
|
.push_output(&format!("Copied path: {}", full_path.display()));
|
||||||
return iced::clipboard::write(full_path.to_string_lossy().into_owned());
|
return iced::clipboard::write(full_path.to_string_lossy().into_owned())
|
||||||
|
.discard();
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
|
|
@ -1319,7 +1320,7 @@ impl OpenCADStudio {
|
||||||
if text.is_empty() {
|
if text.is_empty() {
|
||||||
Task::none()
|
Task::none()
|
||||||
} else {
|
} else {
|
||||||
iced::clipboard::write(text)
|
iced::clipboard::write(text).discard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1334,7 +1335,7 @@ impl OpenCADStudio {
|
||||||
if text.is_empty() {
|
if text.is_empty() {
|
||||||
Task::none()
|
Task::none()
|
||||||
} else {
|
} else {
|
||||||
iced::clipboard::write(text)
|
iced::clipboard::write(text).discard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4143,7 +4144,7 @@ impl OpenCADStudio {
|
||||||
Message::SetTheme(theme) => {
|
Message::SetTheme(theme) => {
|
||||||
self.ui_theme.name = theme.to_string();
|
self.ui_theme.name = theme.to_string();
|
||||||
self.ui_theme.palette =
|
self.ui_theme.palette =
|
||||||
crate::app::config::UiThemePalette::from_iced(theme.palette());
|
crate::app::config::UiThemePalette::from_iced(theme.seed());
|
||||||
self.theme_color_inputs = self.ui_theme.palette.hex_values();
|
self.theme_color_inputs = self.ui_theme.palette.hex_values();
|
||||||
self.active_theme = theme;
|
self.active_theme = theme;
|
||||||
self.persist_settings_if_changed();
|
self.persist_settings_if_changed();
|
||||||
|
|
@ -4225,7 +4226,7 @@ impl OpenCADStudio {
|
||||||
crate::app::config::builtin_theme(&self.ui_theme.name)
|
crate::app::config::builtin_theme(&self.ui_theme.name)
|
||||||
{
|
{
|
||||||
self.ui_theme.palette =
|
self.ui_theme.palette =
|
||||||
crate::app::config::UiThemePalette::from_iced(theme.palette());
|
crate::app::config::UiThemePalette::from_iced(theme.seed());
|
||||||
self.theme_color_inputs = self.ui_theme.palette.hex_values();
|
self.theme_color_inputs = self.ui_theme.palette.hex_values();
|
||||||
self.active_theme = theme;
|
self.active_theme = theme;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4441,7 +4442,7 @@ impl OpenCADStudio {
|
||||||
std::env::consts::OS,
|
std::env::consts::OS,
|
||||||
std::env::consts::ARCH,
|
std::env::consts::ARCH,
|
||||||
);
|
);
|
||||||
iced::clipboard::write(info)
|
iced::clipboard::write(info).discard()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Plugin Manager window ─────────────────────────────────────
|
// ── Plugin Manager window ─────────────────────────────────────
|
||||||
|
|
@ -4652,7 +4653,8 @@ impl OpenCADStudio {
|
||||||
std::env::consts::ARCH,
|
std::env::consts::ARCH,
|
||||||
crate::plugin::marketplace::REGISTRY_URL,
|
crate::plugin::marketplace::REGISTRY_URL,
|
||||||
error,
|
error,
|
||||||
));
|
))
|
||||||
|
.discard();
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ pub(super) fn viewport_controls<'a>(
|
||||||
| iced::widget::button::Status::Pressed
|
| iced::widget::button::Status::Pressed
|
||||||
)
|
)
|
||||||
.then_some(Background::Color(
|
.then_some(Background::Color(
|
||||||
theme.extended_palette().danger.weak.color
|
theme.palette().danger.weak.color
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
text_color: theme.extended_palette().danger.base.color,
|
text_color: theme.palette().danger.base.color,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -56,7 +56,7 @@ pub(super) fn viewport_controls<'a>(
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.padding([4, 6])
|
.padding([4, 6])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (active, status) {
|
let pair = match (active, status) {
|
||||||
(_, iced::widget::button::Status::Hovered) => {
|
(_, iced::widget::button::Status::Hovered) => {
|
||||||
Some(palette.background.strong)
|
Some(palette.background.strong)
|
||||||
|
|
@ -79,7 +79,7 @@ pub(super) fn viewport_controls<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Render-mode picker, restyled borderless so the outer chip frames it.
|
// Render-mode picker, restyled borderless so the outer chip frames it.
|
||||||
let picker = iced::widget::pick_list(
|
let picker = crate::ui::pick_list(
|
||||||
render_modes,
|
render_modes,
|
||||||
Some(RenderModeChoice(render_mode)),
|
Some(RenderModeChoice(render_mode)),
|
||||||
|c| Message::SetRenderMode(c.0),
|
|c| Message::SetRenderMode(c.0),
|
||||||
|
|
@ -87,7 +87,7 @@ pub(super) fn viewport_controls<'a>(
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
.padding([4, 6])
|
.padding([4, 6])
|
||||||
.style(move |theme: &Theme, _| {
|
.style(move |theme: &Theme, _| {
|
||||||
let text = theme.extended_palette().background.base.text;
|
let text = theme.palette().background.base.text;
|
||||||
iced::widget::pick_list::Style {
|
iced::widget::pick_list::Style {
|
||||||
background: Background::Color(iced::Color::TRANSPARENT),
|
background: Background::Color(iced::Color::TRANSPARENT),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -105,7 +105,7 @@ pub(super) fn viewport_controls<'a>(
|
||||||
container(iced::widget::Space::new().width(1.0).height(16.0)).style(|theme: &Theme| {
|
container(iced::widget::Space::new().width(1.0).height(16.0)).style(|theme: &Theme| {
|
||||||
iced::widget::container::Style {
|
iced::widget::container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color.scale_alpha(0.7)
|
theme.palette().background.neutral.color.scale_alpha(0.7)
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ pub(super) fn viewport_controls<'a>(
|
||||||
container(bar)
|
container(bar)
|
||||||
.padding(2)
|
.padding(2)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
iced::widget::container::Style {
|
iced::widget::container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
palette.background.weak.color.scale_alpha(0.92)
|
palette.background.weak.color.scale_alpha(0.92)
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ impl OpenCADStudio {
|
||||||
pub fn view_main(&self) -> Element<'_, Message> {
|
pub fn view_main(&self) -> Element<'_, Message> {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let tab = &self.tabs[i];
|
let tab = &self.tabs[i];
|
||||||
let theme_text = self.active_theme.extended_palette().background.base.text;
|
let theme_text = self.active_theme.palette().background.base.text;
|
||||||
let viewcube_text_color = [
|
let viewcube_text_color = [
|
||||||
theme_text.r,
|
theme_text.r,
|
||||||
theme_text.g,
|
theme_text.g,
|
||||||
|
|
@ -197,7 +197,7 @@ impl OpenCADStudio {
|
||||||
sel.vp_size = (size.width, size.height);
|
sel.vp_size = (size.width, size.height);
|
||||||
}
|
}
|
||||||
scene.sync_tiles_from_panes(size.width, size.height);
|
scene.sync_tiles_from_panes(size.width, size.height);
|
||||||
Space::new().width(Fill).height(Fill).into()
|
Space::new().width(Fill).height(Fill)
|
||||||
})
|
})
|
||||||
.into();
|
.into();
|
||||||
let shaders = pane_grid::PaneGrid::new(
|
let shaders = pane_grid::PaneGrid::new(
|
||||||
|
|
@ -978,7 +978,7 @@ impl OpenCADStudio {
|
||||||
.padding([3, 10])
|
.padding([3, 10])
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (is_sel, status) {
|
let pair = match (is_sel, status) {
|
||||||
(true, _) => Some(palette.primary.strong),
|
(true, _) => Some(palette.primary.strong),
|
||||||
(_, iced::widget::button::Status::Hovered) => {
|
(_, iced::widget::button::Status::Hovered) => {
|
||||||
|
|
@ -1004,7 +1004,7 @@ impl OpenCADStudio {
|
||||||
let menu_panel = container(col)
|
let menu_panel = container(col)
|
||||||
.padding(2)
|
.padding(2)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -1055,7 +1055,7 @@ impl OpenCADStudio {
|
||||||
.padding([3, 10])
|
.padding([3, 10])
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
iced::widget::button::Style {
|
iced::widget::button::Style {
|
||||||
background: matches!(
|
background: matches!(
|
||||||
status,
|
status,
|
||||||
|
|
@ -1074,10 +1074,10 @@ impl OpenCADStudio {
|
||||||
col = col.push(btn);
|
col = col.push(btn);
|
||||||
}
|
}
|
||||||
let panel = container(iced::widget::scrollable(col).height(iced::Length::Shrink))
|
let panel = container(iced::widget::scrollable(col).height(iced::Length::Shrink))
|
||||||
.max_height(360.0)
|
.height(iced::Length::Fit.max(360.0))
|
||||||
.padding(2)
|
.padding(2)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -1154,7 +1154,7 @@ impl OpenCADStudio {
|
||||||
trace
|
trace
|
||||||
};
|
};
|
||||||
let perf_button_style = |theme: &Theme, status: button::Status| {
|
let perf_button_style = |theme: &Theme, status: button::Status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if matches!(status, button::Status::Hovered) {
|
let pair = if matches!(status, button::Status::Hovered) {
|
||||||
palette.background.strong
|
palette.background.strong
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1195,7 +1195,7 @@ impl OpenCADStudio {
|
||||||
.padding([2, 6]);
|
.padding([2, 6]);
|
||||||
let header = row![
|
let header = row![
|
||||||
text("PERF").size(12).style(|theme: &Theme| iced::widget::text::Style {
|
text("PERF").size(12).style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().success.base.color),
|
color: Some(theme.palette().success.base.color),
|
||||||
}),
|
}),
|
||||||
Space::new().width(iced::Length::Fill),
|
Space::new().width(iced::Length::Fill),
|
||||||
copy_btn,
|
copy_btn,
|
||||||
|
|
@ -1210,7 +1210,7 @@ impl OpenCADStudio {
|
||||||
column![
|
column![
|
||||||
header,
|
header,
|
||||||
text(summary).size(11).style(|theme: &Theme| iced::widget::text::Style {
|
text(summary).size(11).style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().success.base.color),
|
color: Some(theme.palette().success.base.color),
|
||||||
}),
|
}),
|
||||||
log,
|
log,
|
||||||
]
|
]
|
||||||
|
|
@ -1486,7 +1486,7 @@ impl OpenCADStudio {
|
||||||
})
|
})
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -1536,15 +1536,20 @@ impl OpenCADStudio {
|
||||||
// the native (single main window) and web builds.
|
// the native (single main window) and web builds.
|
||||||
let base: Element<'_, Message> = match self.modal_content() {
|
let base: Element<'_, Message> = match self.modal_content() {
|
||||||
Some(content) => {
|
Some(content) => {
|
||||||
|
let modal_options = if cfg!(target_arch = "wasm32")
|
||||||
|
&& matches!(self.active_modal, Some(super::ModalKind::PluginManager))
|
||||||
|
{
|
||||||
|
crate::ui::modal::ModalOptions::NOTICE
|
||||||
|
} else {
|
||||||
|
crate::ui::modal::ModalOptions::STANDARD
|
||||||
|
};
|
||||||
crate::ui::modal::modal(
|
crate::ui::modal::modal(
|
||||||
composed,
|
composed,
|
||||||
self.modal_title(),
|
self.modal_title(),
|
||||||
// Content width — outer size minus the frame padding.
|
|
||||||
self.modal_outer_size().map(|s| s.0 - 20.0).unwrap_or(420.0),
|
|
||||||
content,
|
content,
|
||||||
Message::CloseModal,
|
Message::CloseModal,
|
||||||
self.modal_offset,
|
self.modal_offset,
|
||||||
true,
|
modal_options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
None => composed.into(),
|
None => composed.into(),
|
||||||
|
|
@ -1555,25 +1560,24 @@ impl OpenCADStudio {
|
||||||
crate::ui::modal::modal(
|
crate::ui::modal::modal(
|
||||||
base,
|
base,
|
||||||
"Select Color",
|
"Select Color",
|
||||||
420.0,
|
|
||||||
iced::widget::container(crate::ui::color_select::color_grid_window(
|
iced::widget::container(crate::ui::color_select::color_grid_window(
|
||||||
Message::ColorWindowPick,
|
Message::ColorWindowPick,
|
||||||
))
|
))
|
||||||
.width(iced::Length::Fixed(420.0))
|
.width(iced::Length::Fit.max(420.0))
|
||||||
.height(iced::Length::Fixed(470.0)),
|
.height(iced::Length::Fit.max(470.0)),
|
||||||
Message::CloseColorPicker,
|
Message::CloseColorPicker,
|
||||||
iced::Vector::ZERO,
|
iced::Vector::ZERO,
|
||||||
false,
|
crate::ui::modal::ModalOptions::MOVABLE_FIXED,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
base
|
base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Outer pixel size (content + title-bar/padding chrome) of the active
|
/// Conservative outer pixel bounds for the active modal, used to clamp drag
|
||||||
/// modal, used to clamp drag so it cannot be pushed off-screen. Mirrors the
|
/// so it cannot be pushed off-screen. Mirrors the maximum dimensions in
|
||||||
/// `sized(..)` dimensions in [`Self::modal_content`]; keep the two in sync.
|
/// [`Self::modal_content`]; content-sized dialogs may render smaller.
|
||||||
/// `None` has no active modal. About (content-sized) uses a safe estimate.
|
/// `None` has no active modal. About uses a safe estimate.
|
||||||
pub(crate) fn modal_outer_size(&self) -> Option<(f32, f32)> {
|
pub(crate) fn modal_outer_size(&self) -> Option<(f32, f32)> {
|
||||||
use super::ModalKind::*;
|
use super::ModalKind::*;
|
||||||
// Title bar (~26) + spacing (6) + frame padding (10·2) → ~52 vertical;
|
// Title bar (~26) + spacing (6) + frame padding (10·2) → ~52 vertical;
|
||||||
|
|
@ -1583,8 +1587,17 @@ impl OpenCADStudio {
|
||||||
let (w, h) = match self.active_modal? {
|
let (w, h) = match self.active_modal? {
|
||||||
About => (440, 360),
|
About => (440, 360),
|
||||||
Shortcuts => (720, 520),
|
Shortcuts => (720, 520),
|
||||||
Options => (480, 190),
|
Options => (520, 500),
|
||||||
PluginManager => (940, 600),
|
PluginManager => {
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
{
|
||||||
|
(self.web_plugin_notice_width(), 230)
|
||||||
|
}
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
{
|
||||||
|
(940, 600)
|
||||||
|
}
|
||||||
|
}
|
||||||
UpdateNotice => (560, 460),
|
UpdateNotice => (560, 460),
|
||||||
Layers => (900, 360),
|
Layers => (900, 360),
|
||||||
LayerStateManager => (720, 420),
|
LayerStateManager => (720, 420),
|
||||||
|
|
@ -2005,7 +2018,7 @@ pub(super) fn doc_tab_bar<'a>(tabs: &'a [DocumentTab], active_tab: usize) -> Ele
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
.padding([4, 12])
|
.padding([4, 12])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let background = match (is_active, status) {
|
let background = match (is_active, status) {
|
||||||
(false, button::Status::Hovered) => {
|
(false, button::Status::Hovered) => {
|
||||||
Some(Background::Color(palette.background.weak.color))
|
Some(Background::Color(palette.background.weak.color))
|
||||||
|
|
@ -2053,7 +2066,7 @@ pub(super) fn doc_tab_bar<'a>(tabs: &'a [DocumentTab], active_tab: usize) -> Ele
|
||||||
let tab_container = container(row_inner)
|
let tab_container = container(row_inner)
|
||||||
.height(iced::Length::Fixed(23.0))
|
.height(iced::Length::Fixed(23.0))
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(if is_active {
|
background: Some(Background::Color(if is_active {
|
||||||
palette.primary.weak.color
|
palette.primary.weak.color
|
||||||
|
|
@ -2112,10 +2125,10 @@ pub(super) fn doc_tab_bar<'a>(tabs: &'a [DocumentTab], active_tab: usize) -> Ele
|
||||||
container(WrapFlow::new(items).spacing_x(0.0).row_h(30.0))
|
container(WrapFlow::new(items).spacing_x(0.0).row_h(30.0))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -2146,13 +2159,13 @@ pub(super) fn doc_tab_bar<'a>(tabs: &'a [DocumentTab], active_tab: usize) -> Ele
|
||||||
//
|
//
|
||||||
fn start_muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn start_muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn start_primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2196,7 +2209,7 @@ impl canvas::Program<Message> for VBarLabel {
|
||||||
frame.fill_text(canvas::Text {
|
frame.fill_text(canvas::Text {
|
||||||
content: self.text.clone(),
|
content: self.text.clone(),
|
||||||
position: iced::Point::ORIGIN,
|
position: iced::Point::ORIGIN,
|
||||||
color: theme.extended_palette().background.base.text.scale_alpha(0.72),
|
color: theme.palette().background.base.text.scale_alpha(0.72),
|
||||||
size: iced::Pixels(13.0),
|
size: iced::Pixels(13.0),
|
||||||
align_x: iced::advanced::text::Alignment::Center,
|
align_x: iced::advanced::text::Alignment::Center,
|
||||||
align_y: iced::alignment::Vertical::Center,
|
align_y: iced::alignment::Vertical::Center,
|
||||||
|
|
@ -2223,10 +2236,10 @@ pub(super) fn collapse_bar<'a>(name: &str, on_press: Message) -> Element<'a, Mes
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -2264,7 +2277,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.padding([10, 22])
|
.padding([10, 22])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered => palette.background.strong,
|
button::Status::Hovered => palette.background.strong,
|
||||||
_ => palette.background.weak,
|
_ => palette.background.weak,
|
||||||
|
|
@ -2354,8 +2367,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.height(iced::Length::Fixed(120.0))
|
.height(iced::Length::Fixed(120.0))
|
||||||
.content_fit(iced::ContentFit::Contain),
|
.content_fit(iced::ContentFit::Contain),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(Fill.max(300.0)),
|
||||||
.max_width(300.0),
|
|
||||||
)
|
)
|
||||||
.interaction(iced::mouse::Interaction::Pointer)
|
.interaction(iced::mouse::Interaction::Pointer)
|
||||||
.on_press(Message::OpenUrl("https://open-aec.com/".to_string())),
|
.on_press(Message::OpenUrl("https://open-aec.com/".to_string())),
|
||||||
|
|
@ -2469,7 +2481,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.height(iced::Length::Fixed(thumb_h))
|
.height(iced::Length::Fixed(thumb_h))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 6.0.into(),
|
radius: 6.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -2499,7 +2511,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.center_x(Fill)
|
.center_x(Fill)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let pair = theme.extended_palette().danger.base;
|
let pair = theme.palette().danger.base;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(pair.color)),
|
background: Some(Background::Color(pair.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -2529,7 +2541,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
.padding(VIDEO_PANEL_PADDING)
|
.padding(VIDEO_PANEL_PADDING)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -2582,7 +2594,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.padding([8, 10])
|
.padding([8, 10])
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
palette.background.base.color.scale_alpha(0.42),
|
palette.background.base.color.scale_alpha(0.42),
|
||||||
|
|
@ -2615,7 +2627,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.center_x(Fill)
|
.center_x(Fill)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let pair = theme.extended_palette().primary.base;
|
let pair = theme.palette().primary.base;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(pair.color)),
|
background: Some(Background::Color(pair.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -2648,7 +2660,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
.padding(16)
|
.padding(16)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -2697,7 +2709,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.center_x(Fill)
|
.center_x(Fill)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let pair = theme.extended_palette().danger.base;
|
let pair = theme.palette().danger.base;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(pair.color)),
|
background: Some(Background::Color(pair.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -2731,7 +2743,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
.padding(20)
|
.padding(20)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -2779,7 +2791,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
.on_press(Message::StartSectionSelect(section))
|
.on_press(Message::StartSectionSelect(section))
|
||||||
.padding([8, 18])
|
.padding([8, 18])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (is_active, status) {
|
let pair = match (is_active, status) {
|
||||||
(true, _) => Some(palette.primary.weak),
|
(true, _) => Some(palette.primary.weak),
|
||||||
(false, button::Status::Hovered) => {
|
(false, button::Status::Hovered) => {
|
||||||
|
|
@ -2851,7 +2863,7 @@ pub(super) fn start_page_view<'a>(
|
||||||
container(body)
|
container(body)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -2956,7 +2968,7 @@ pub(super) fn recent_files_panel<'a>(
|
||||||
.padding([6, 12])
|
.padding([6, 12])
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
button::Style {
|
button::Style {
|
||||||
background: matches!(status, button::Status::Hovered).then_some(
|
background: matches!(status, button::Status::Hovered).then_some(
|
||||||
Background::Color(palette.background.strong.color)
|
Background::Color(palette.background.strong.color)
|
||||||
|
|
@ -2979,7 +2991,7 @@ pub(super) fn recent_files_panel<'a>(
|
||||||
.on_press(Message::RecentRemove(path_for_remove))
|
.on_press(Message::RecentRemove(path_for_remove))
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.style(|theme: &Theme, status| {
|
.style(|theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
button::Style {
|
button::Style {
|
||||||
background: matches!(status, button::Status::Hovered)
|
background: matches!(status, button::Status::Hovered)
|
||||||
.then_some(Background::Color(palette.danger.weak.color)),
|
.then_some(Background::Color(palette.danger.weak.color)),
|
||||||
|
|
@ -3004,7 +3016,7 @@ pub(super) fn recent_files_panel<'a>(
|
||||||
// so an over-max entry snaps to the max.
|
// so an over-max entry snaps to the max.
|
||||||
const STEP: usize = 5;
|
const STEP: usize = 5;
|
||||||
let step_style = |theme: &Theme, status: button::Status| {
|
let step_style = |theme: &Theme, status: button::Status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
button::Style {
|
button::Style {
|
||||||
background: matches!(status, button::Status::Hovered).then_some(
|
background: matches!(status, button::Status::Hovered).then_some(
|
||||||
Background::Color(palette.background.strong.color)
|
Background::Color(palette.background.strong.color)
|
||||||
|
|
@ -3058,7 +3070,7 @@ pub(super) fn recent_files_panel<'a>(
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
.padding(20)
|
.padding(20)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,15 @@
|
||||||
use super::super::{Message, OpenCADStudio};
|
use super::super::{Message, OpenCADStudio};
|
||||||
use iced::widget::{button, column, container, pick_list, row, text, Space};
|
use iced::widget::{button, column, container, row, text, Space};
|
||||||
use iced::{Background, Element, Fill, Theme};
|
use iced::{Background, Element, Fit, Theme};
|
||||||
|
|
||||||
impl OpenCADStudio {
|
impl OpenCADStudio {
|
||||||
/// Title shown in the active modal's title bar, left of the move/close
|
#[cfg(target_arch = "wasm32")]
|
||||||
/// buttons. Keep in sync with the [`Self::modal_content`] dispatch.
|
pub(super) fn web_plugin_notice_width(&self) -> u16 {
|
||||||
|
(self.win_size.0 - 48.0).clamp(280.0, 460.0) as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Title shown in the active modal's title bar. Keep in sync with the
|
||||||
|
/// [`Self::modal_content`] dispatch.
|
||||||
pub(super) fn modal_title(&self) -> &'static str {
|
pub(super) fn modal_title(&self) -> &'static str {
|
||||||
use super::super::ModalKind as K;
|
use super::super::ModalKind as K;
|
||||||
match self.active_modal {
|
match self.active_modal {
|
||||||
|
|
@ -43,96 +48,138 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the currently-open modal dialog's content (Plan B), or `None`.
|
/// Build the currently-open modal dialog's content (Plan B), or `None`.
|
||||||
/// Each former pop-up window is constructed here and given a bounded size
|
/// Each former pop-up window is constructed here and given a maximum size.
|
||||||
/// (About shrinks to its content). Rendered as an overlay by `view_main`.
|
/// Iced 0.15 measures the content first, so smaller dialogs stop at their
|
||||||
|
/// intrinsic size while overflowing regions become scrollable at the cap.
|
||||||
pub(super) fn modal_content<'s>(&'s self) -> Option<Element<'s, Message>> {
|
pub(super) fn modal_content<'s>(&'s self) -> Option<Element<'s, Message>> {
|
||||||
// Grow every dialog by the shared corner-resize delta (grow-only, so the
|
|
||||||
// natural size is the floor). The delta resets to zero whenever a modal
|
|
||||||
// opens/closes, so each dialog starts at its own size.
|
|
||||||
let ex = self.modal_resize;
|
let ex = self.modal_resize;
|
||||||
let sized = |e: Element<'s, Message>, w: u16, h: u16| -> Element<'s, Message> {
|
let sized = |e: Element<'s, Message>, w: u16, h: u16| -> Element<'s, Message> {
|
||||||
iced::widget::container(e)
|
container(e)
|
||||||
.width(iced::Length::Fixed(w as f32 + ex.x))
|
.width(Fit.max(w as f32 + ex.x))
|
||||||
.height(iced::Length::Fixed(h as f32 + ex.y))
|
.height(Fit.max(h as f32 + ex.y))
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
Some(match self.active_modal? {
|
Some(match self.active_modal? {
|
||||||
super::super::ModalKind::About => crate::ui::window::about::view_window(),
|
super::super::ModalKind::About => {
|
||||||
|
sized(crate::ui::window::about::view_window(), 440, 360)
|
||||||
|
}
|
||||||
super::super::ModalKind::Shortcuts => {
|
super::super::ModalKind::Shortcuts => {
|
||||||
sized(crate::ui::window::shortcuts::view_window(&self.shortcut_overrides), 720, 520)
|
sized_flow(
|
||||||
|
ex,
|
||||||
|
720,
|
||||||
|
520,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::shortcuts::view_window(
|
||||||
|
&self.shortcut_overrides,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::Aliases => {
|
super::super::ModalKind::Aliases => {
|
||||||
sized(crate::ui::window::alias_editor::view_window(&self.alias_editor_rows), 480, 520)
|
sized_flow(
|
||||||
|
ex,
|
||||||
|
480,
|
||||||
|
520,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::alias_editor::view_window(
|
||||||
|
&self.alias_editor_rows,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::Options => sized(
|
super::super::ModalKind::Options => sized_flow(
|
||||||
crate::ui::window::options::view_window(
|
ex,
|
||||||
&self.default_save_format,
|
|
||||||
&self.ui_theme,
|
|
||||||
&self.theme_color_inputs,
|
|
||||||
),
|
|
||||||
520,
|
520,
|
||||||
500,
|
500,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::options::view_window(
|
||||||
|
&self.default_save_format,
|
||||||
|
&self.ui_theme,
|
||||||
|
&self.theme_color_inputs,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
super::super::ModalKind::PluginManager => {
|
super::super::ModalKind::PluginManager => {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
{
|
{
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::window::plugin_manager::view_window(
|
ex,
|
||||||
&self.disabled_plugins,
|
|
||||||
&self.external_plugins,
|
|
||||||
&self.loaded_plugin_ids,
|
|
||||||
crate::ui::window::plugin_manager::MarketView {
|
|
||||||
registry: &self.plugin_registry,
|
|
||||||
registry_loading: self.plugin_registry_loading,
|
|
||||||
registry_error: self.plugin_registry_error.as_deref(),
|
|
||||||
registry_error_details_open: self
|
|
||||||
.plugin_registry_error_details_open,
|
|
||||||
input: &self.plugin_repo_input,
|
|
||||||
search: &self.plugin_search_input,
|
|
||||||
repos: &self.plugin_repos,
|
|
||||||
release_tags: &self.repo_release_tags,
|
|
||||||
selected_tag: &self.repo_selected_tag,
|
|
||||||
selected_repo: self.selected_plugin_repo.as_deref(),
|
|
||||||
readmes: &self.plugin_readmes,
|
|
||||||
readme_loading: &self.plugin_readme_loading,
|
|
||||||
status: &self.marketplace_status,
|
|
||||||
},
|
|
||||||
&self.active_theme,
|
|
||||||
),
|
|
||||||
940,
|
940,
|
||||||
600,
|
600,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::plugin_manager::view_window(
|
||||||
|
&self.disabled_plugins,
|
||||||
|
&self.external_plugins,
|
||||||
|
&self.loaded_plugin_ids,
|
||||||
|
crate::ui::window::plugin_manager::MarketView {
|
||||||
|
registry: &self.plugin_registry,
|
||||||
|
registry_loading: self.plugin_registry_loading,
|
||||||
|
registry_error: self.plugin_registry_error.as_deref(),
|
||||||
|
registry_error_details_open: self
|
||||||
|
.plugin_registry_error_details_open,
|
||||||
|
input: &self.plugin_repo_input,
|
||||||
|
search: &self.plugin_search_input,
|
||||||
|
repos: &self.plugin_repos,
|
||||||
|
release_tags: &self.repo_release_tags,
|
||||||
|
selected_tag: &self.repo_selected_tag,
|
||||||
|
selected_repo: self.selected_plugin_repo.as_deref(),
|
||||||
|
readmes: &self.plugin_readmes,
|
||||||
|
readme_loading: &self.plugin_readme_loading,
|
||||||
|
status: &self.marketplace_status,
|
||||||
|
},
|
||||||
|
&self.active_theme,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
sized(
|
sized(
|
||||||
crate::ui::window::plugin_manager::view_web_notice(),
|
crate::ui::window::plugin_manager::view_web_notice(),
|
||||||
520,
|
self.web_plugin_notice_width(),
|
||||||
260,
|
230,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::super::ModalKind::UpdateNotice => {
|
super::super::ModalKind::UpdateNotice => {
|
||||||
let latest = self.update_notice_version.as_deref().unwrap_or("?");
|
let latest = self.update_notice_version.as_deref().unwrap_or("?");
|
||||||
let body = self.update_notice_body.as_deref().unwrap_or("");
|
let body = self.update_notice_body.as_deref().unwrap_or("");
|
||||||
sized(crate::ui::window::update_notice::view_window(latest, body), 560, 460)
|
sized_flow(
|
||||||
|
ex,
|
||||||
|
560,
|
||||||
|
460,
|
||||||
|
|flow| crate::ui::window::update_notice::view_window(latest, body, flow),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::Layers => {
|
super::super::ModalKind::Layers => {
|
||||||
let tab = &self.tabs[self.active_tab];
|
let tab = &self.tabs[self.active_tab];
|
||||||
sized(tab.layers.view_window(self.layer_name_col_w), 900, 360)
|
sized_flow(
|
||||||
|
ex,
|
||||||
|
900,
|
||||||
|
360,
|
||||||
|
|flow| tab.layers.view_window(self.layer_name_col_w, flow),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::LayerStateManager => {
|
super::super::ModalKind::LayerStateManager => {
|
||||||
let states = self.tabs[self.active_tab].scene.document.layer_states();
|
let states = self.tabs[self.active_tab].scene.document.layer_states();
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::window::layer_state_manager::view_window(
|
ex,
|
||||||
states,
|
|
||||||
self.layer_state_selected.as_deref(),
|
|
||||||
&self.layer_state_name_buf,
|
|
||||||
&self.layer_state_description_buf,
|
|
||||||
&self.layer_state_filter,
|
|
||||||
),
|
|
||||||
720,
|
720,
|
||||||
420,
|
420,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::layer_state_manager::view_window(
|
||||||
|
states.clone(),
|
||||||
|
self.layer_state_selected.as_deref(),
|
||||||
|
&self.layer_state_name_buf,
|
||||||
|
&self.layer_state_description_buf,
|
||||||
|
&self.layer_state_filter,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::LayerStateEditor => {
|
super::super::ModalKind::LayerStateEditor => {
|
||||||
|
|
@ -155,15 +202,19 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
linetypes.sort_by_key(|name| name.to_lowercase());
|
linetypes.sort_by_key(|name| name.to_lowercase());
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::window::layer_state_manager::view_editor(
|
ex,
|
||||||
state,
|
|
||||||
&self.layer_state_edit_filter,
|
|
||||||
self.layer_state_edit_color_open,
|
|
||||||
linetypes,
|
|
||||||
),
|
|
||||||
1180,
|
1180,
|
||||||
560,
|
560,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::layer_state_manager::view_editor(
|
||||||
|
state,
|
||||||
|
&self.layer_state_edit_filter,
|
||||||
|
self.layer_state_edit_color_open,
|
||||||
|
linetypes.clone(),
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
sized(
|
sized(
|
||||||
|
|
@ -176,21 +227,30 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::super::ModalKind::Plot => {
|
super::super::ModalKind::Plot => {
|
||||||
sized(crate::ui::window::plot::view_window(&self.plot_dialog), 760, 540)
|
sized_flow(
|
||||||
|
ex,
|
||||||
|
760,
|
||||||
|
540,
|
||||||
|
|flow| crate::ui::window::plot::view_window(&self.plot_dialog, flow),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::LayoutManager => {
|
super::super::ModalKind::LayoutManager => {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let layouts = self.tabs[i].scene.layout_names();
|
let layouts = self.tabs[i].scene.layout_names();
|
||||||
let current = self.tabs[i].scene.current_layout.clone();
|
let current = self.tabs[i].scene.current_layout.clone();
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::window::layout_manager::view_window(
|
ex,
|
||||||
layouts,
|
|
||||||
&self.layout_manager_selected,
|
|
||||||
&self.layout_manager_rename_buf,
|
|
||||||
current,
|
|
||||||
),
|
|
||||||
640,
|
640,
|
||||||
320,
|
320,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::layout_manager::view_window(
|
||||||
|
layouts.clone(),
|
||||||
|
&self.layout_manager_selected,
|
||||||
|
&self.layout_manager_rename_buf,
|
||||||
|
current.clone(),
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::ScaleManager => {
|
super::super::ModalKind::ScaleManager => {
|
||||||
|
|
@ -206,21 +266,25 @@ impl OpenCADStudio {
|
||||||
.map(|(p, d)| format!("{p}:{d}"))
|
.map(|(p, d)| format!("{p}:{d}"))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
(name, ratio)
|
(name, ratio)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let current = tab.scene.document.header.current_annotation_scale.clone();
|
let current = tab.scene.document.header.current_annotation_scale.clone();
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::style::scale_manager::view_window(
|
ex,
|
||||||
&scales,
|
|
||||||
&self.scale_manager_selected,
|
|
||||||
¤t,
|
|
||||||
self.scale_rename.as_deref(),
|
|
||||||
&self.scale_rename_buf,
|
|
||||||
&self.scale_manager_paper_buf,
|
|
||||||
&self.scale_manager_drawing_buf,
|
|
||||||
),
|
|
||||||
520,
|
520,
|
||||||
360,
|
360,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::scale_manager::view_window(
|
||||||
|
&scales,
|
||||||
|
&self.scale_manager_selected,
|
||||||
|
¤t,
|
||||||
|
self.scale_rename.as_deref(),
|
||||||
|
&self.scale_rename_buf,
|
||||||
|
&self.scale_manager_paper_buf,
|
||||||
|
&self.scale_manager_drawing_buf,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::AnnoObjectScale => {
|
super::super::ModalKind::AnnoObjectScale => {
|
||||||
|
|
@ -263,22 +327,33 @@ impl OpenCADStudio {
|
||||||
(name, ratio, is_member)
|
(name, ratio, is_member)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::style::anno_object_scale::view_window(&label, &scales),
|
ex,
|
||||||
360,
|
360,
|
||||||
420,
|
420,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::anno_object_scale::view_window(
|
||||||
|
&label,
|
||||||
|
&scales,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::Plotstyle => sized(
|
super::super::ModalKind::Plotstyle => sized_flow(
|
||||||
crate::ui::style::plotstyle::view_window(
|
ex,
|
||||||
self.active_plot_style.as_ref(),
|
|
||||||
self.plotstyle_panel_aci,
|
|
||||||
&self.ps_color_buf,
|
|
||||||
&self.ps_lineweight_buf,
|
|
||||||
&self.ps_screening_buf,
|
|
||||||
),
|
|
||||||
780,
|
780,
|
||||||
540,
|
540,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::plotstyle::view_window(
|
||||||
|
self.active_plot_style.as_ref(),
|
||||||
|
self.plotstyle_panel_aci,
|
||||||
|
&self.ps_color_buf,
|
||||||
|
&self.ps_lineweight_buf,
|
||||||
|
&self.ps_screening_buf,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
super::super::ModalKind::TextStyle => {
|
super::super::ModalKind::TextStyle => {
|
||||||
let tab = &self.tabs[self.active_tab];
|
let tab = &self.tabs[self.active_tab];
|
||||||
|
|
@ -296,27 +371,31 @@ impl OpenCADStudio {
|
||||||
.get(&self.textstyle_selected)
|
.get(&self.textstyle_selected)
|
||||||
.map(|s| (s.flags.backward, s.flags.upside_down, s.annotative))
|
.map(|s| (s.flags.backward, s.flags.upside_down, s.annotative))
|
||||||
.unwrap_or((false, false, false));
|
.unwrap_or((false, false, false));
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::style::textstyle::view_window(crate::ui::style::textstyle::TextStyleView {
|
ex,
|
||||||
styles,
|
|
||||||
selected: &self.textstyle_selected,
|
|
||||||
current: &tab.scene.document.header.current_text_style_name,
|
|
||||||
font_buf: &self.textstyle_font,
|
|
||||||
width_buf: &self.textstyle_width,
|
|
||||||
oblique_buf: &self.textstyle_oblique,
|
|
||||||
height_buf: &self.textstyle_height,
|
|
||||||
bigfont_buf: &self.textstyle_bigfont,
|
|
||||||
ttf_buf: &self.textstyle_ttf,
|
|
||||||
backward,
|
|
||||||
upside_down,
|
|
||||||
annotative,
|
|
||||||
rename_active: self.style_rename.as_deref(),
|
|
||||||
rename_buf: &self.style_rename_buf,
|
|
||||||
}),
|
|
||||||
// Wider than the old 620 window: the TTF system-font panel
|
|
||||||
// (Plan B / web fonts) added a column.
|
|
||||||
860,
|
860,
|
||||||
480,
|
480,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::textstyle::view_window(
|
||||||
|
crate::ui::style::textstyle::TextStyleView {
|
||||||
|
styles: styles.clone(),
|
||||||
|
selected: &self.textstyle_selected,
|
||||||
|
current: &tab.scene.document.header.current_text_style_name,
|
||||||
|
font_buf: &self.textstyle_font,
|
||||||
|
width_buf: &self.textstyle_width,
|
||||||
|
oblique_buf: &self.textstyle_oblique,
|
||||||
|
height_buf: &self.textstyle_height,
|
||||||
|
bigfont_buf: &self.textstyle_bigfont,
|
||||||
|
ttf_buf: &self.textstyle_ttf,
|
||||||
|
backward,
|
||||||
|
upside_down,
|
||||||
|
annotative,
|
||||||
|
rename_active: self.style_rename.as_deref(),
|
||||||
|
rename_buf: &self.style_rename_buf,
|
||||||
|
},
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::MlStyle => {
|
super::super::ModalKind::MlStyle => {
|
||||||
|
|
@ -336,17 +415,21 @@ impl OpenCADStudio {
|
||||||
ObjectType::MLineStyle(s) if s.name == self.mlstyle_selected => Some(s),
|
ObjectType::MLineStyle(s) if s.name == self.mlstyle_selected => Some(s),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::style::mlstyle::view_window(
|
ex,
|
||||||
styles,
|
|
||||||
&self.mlstyle_selected,
|
|
||||||
selected_style,
|
|
||||||
tab.scene.document.header.multiline_style.clone(),
|
|
||||||
self.style_rename.as_deref(),
|
|
||||||
&self.style_rename_buf,
|
|
||||||
),
|
|
||||||
620,
|
620,
|
||||||
420,
|
420,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::mlstyle::view_window(
|
||||||
|
styles.clone(),
|
||||||
|
&self.mlstyle_selected,
|
||||||
|
selected_style,
|
||||||
|
tab.scene.document.header.multiline_style.clone(),
|
||||||
|
self.style_rename.as_deref(),
|
||||||
|
&self.style_rename_buf,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::TableStyle => {
|
super::super::ModalKind::TableStyle => {
|
||||||
|
|
@ -366,31 +449,35 @@ impl OpenCADStudio {
|
||||||
ObjectType::TableStyle(s) if s.name == self.tablestyle_selected => Some(s),
|
ObjectType::TableStyle(s) if s.name == self.tablestyle_selected => Some(s),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::style::tablestyle::view_window(
|
ex,
|
||||||
styles,
|
|
||||||
&self.tablestyle_selected,
|
|
||||||
&self.ribbon.active_table_style,
|
|
||||||
selected_style,
|
|
||||||
&self.ts_hmargin,
|
|
||||||
&self.ts_vmargin,
|
|
||||||
&self.ts_description,
|
|
||||||
&self.ts_cell_textstyle,
|
|
||||||
&self.ts_cell_height,
|
|
||||||
&self.ts_cell_textcolor,
|
|
||||||
&self.ts_cell_fillcolor,
|
|
||||||
&self.ts_cell_datatype,
|
|
||||||
&self.ts_cell_unittype,
|
|
||||||
&self.ts_cell_format,
|
|
||||||
&self.ts_border_lw,
|
|
||||||
&self.ts_border_color,
|
|
||||||
&self.ts_border_spacing,
|
|
||||||
self.style_rename.as_deref(),
|
|
||||||
&self.style_rename_buf,
|
|
||||||
self.ts_color_open,
|
|
||||||
),
|
|
||||||
620,
|
620,
|
||||||
420,
|
420,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::tablestyle::view_window(
|
||||||
|
styles.clone(),
|
||||||
|
&self.tablestyle_selected,
|
||||||
|
&self.ribbon.active_table_style,
|
||||||
|
selected_style,
|
||||||
|
&self.ts_hmargin,
|
||||||
|
&self.ts_vmargin,
|
||||||
|
&self.ts_description,
|
||||||
|
&self.ts_cell_textstyle,
|
||||||
|
&self.ts_cell_height,
|
||||||
|
&self.ts_cell_textcolor,
|
||||||
|
&self.ts_cell_fillcolor,
|
||||||
|
&self.ts_cell_datatype,
|
||||||
|
&self.ts_cell_unittype,
|
||||||
|
&self.ts_cell_format,
|
||||||
|
&self.ts_border_lw,
|
||||||
|
&self.ts_border_color,
|
||||||
|
&self.ts_border_spacing,
|
||||||
|
self.style_rename.as_deref(),
|
||||||
|
&self.style_rename_buf,
|
||||||
|
self.ts_color_open,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::MLeaderStyle => {
|
super::super::ModalKind::MLeaderStyle => {
|
||||||
|
|
@ -462,44 +549,50 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
None => Default::default(),
|
None => Default::default(),
|
||||||
};
|
};
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::style::mleaderstyle::view_window(crate::ui::style::mleaderstyle::MLeaderStyleView {
|
ex,
|
||||||
styles,
|
|
||||||
selected: &self.mleaderstyle_selected,
|
|
||||||
style: selected_style,
|
|
||||||
current: tab.active_mleader_style.clone(),
|
|
||||||
landing_distance: &self.mls_landing_distance,
|
|
||||||
landing_gap: &self.mls_landing_gap,
|
|
||||||
arrowhead_size: &self.mls_arrowhead_size,
|
|
||||||
text_height: &self.mls_text_height,
|
|
||||||
scale_factor: &self.mls_scale_factor,
|
|
||||||
break_gap: &self.mls_break_gap,
|
|
||||||
first_seg_angle: &self.mls_first_seg_angle,
|
|
||||||
second_seg_angle: &self.mls_second_seg_angle,
|
|
||||||
max_points: &self.mls_max_points,
|
|
||||||
default_text: &self.mls_default_text,
|
|
||||||
line_color: &self.mls_line_color,
|
|
||||||
text_color: &self.mls_text_color,
|
|
||||||
description: &self.mls_description,
|
|
||||||
align_space: &self.mls_align_space,
|
|
||||||
block_color: &self.mls_block_color,
|
|
||||||
block_rotation: &self.mls_block_rotation,
|
|
||||||
block_scale_x: &self.mls_block_scale_x,
|
|
||||||
block_scale_y: &self.mls_block_scale_y,
|
|
||||||
block_scale_z: &self.mls_block_scale_z,
|
|
||||||
block_opts,
|
|
||||||
lt_opts,
|
|
||||||
textstyle_opts,
|
|
||||||
line_type_name,
|
|
||||||
arrowhead_name,
|
|
||||||
text_style_name,
|
|
||||||
block_content_name,
|
|
||||||
rename_active: self.style_rename.as_deref(),
|
|
||||||
rename_buf: &self.style_rename_buf,
|
|
||||||
color_open: self.mls_color_open,
|
|
||||||
}),
|
|
||||||
560,
|
560,
|
||||||
560,
|
560,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::mleaderstyle::view_window(
|
||||||
|
crate::ui::style::mleaderstyle::MLeaderStyleView {
|
||||||
|
styles: styles.clone(),
|
||||||
|
selected: &self.mleaderstyle_selected,
|
||||||
|
style: selected_style,
|
||||||
|
current: tab.active_mleader_style.clone(),
|
||||||
|
landing_distance: &self.mls_landing_distance,
|
||||||
|
landing_gap: &self.mls_landing_gap,
|
||||||
|
arrowhead_size: &self.mls_arrowhead_size,
|
||||||
|
text_height: &self.mls_text_height,
|
||||||
|
scale_factor: &self.mls_scale_factor,
|
||||||
|
break_gap: &self.mls_break_gap,
|
||||||
|
first_seg_angle: &self.mls_first_seg_angle,
|
||||||
|
second_seg_angle: &self.mls_second_seg_angle,
|
||||||
|
max_points: &self.mls_max_points,
|
||||||
|
default_text: &self.mls_default_text,
|
||||||
|
line_color: &self.mls_line_color,
|
||||||
|
text_color: &self.mls_text_color,
|
||||||
|
description: &self.mls_description,
|
||||||
|
align_space: &self.mls_align_space,
|
||||||
|
block_color: &self.mls_block_color,
|
||||||
|
block_rotation: &self.mls_block_rotation,
|
||||||
|
block_scale_x: &self.mls_block_scale_x,
|
||||||
|
block_scale_y: &self.mls_block_scale_y,
|
||||||
|
block_scale_z: &self.mls_block_scale_z,
|
||||||
|
block_opts: block_opts.clone(),
|
||||||
|
lt_opts: lt_opts.clone(),
|
||||||
|
textstyle_opts: textstyle_opts.clone(),
|
||||||
|
line_type_name: line_type_name.clone(),
|
||||||
|
arrowhead_name: arrowhead_name.clone(),
|
||||||
|
text_style_name: text_style_name.clone(),
|
||||||
|
block_content_name: block_content_name.clone(),
|
||||||
|
rename_active: self.style_rename.as_deref(),
|
||||||
|
rename_buf: &self.style_rename_buf,
|
||||||
|
color_open: self.mls_color_open,
|
||||||
|
},
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::DimStyle => {
|
super::super::ModalKind::DimStyle => {
|
||||||
|
|
@ -562,8 +655,9 @@ impl OpenCADStudio {
|
||||||
),
|
),
|
||||||
None => Default::default(),
|
None => Default::default(),
|
||||||
};
|
};
|
||||||
sized(crate::ui::style::dimstyle::view_window(
|
sized_flow(ex, 720, 560, |flow| {
|
||||||
styles,
|
crate::ui::style::dimstyle::view_window(
|
||||||
|
styles.clone(),
|
||||||
&self.dimstyle_selected,
|
&self.dimstyle_selected,
|
||||||
&self.tabs[self.active_tab]
|
&self.tabs[self.active_tab]
|
||||||
.scene
|
.scene
|
||||||
|
|
@ -642,20 +736,22 @@ impl OpenCADStudio {
|
||||||
dimalttz: &self.ds_dimalttz,
|
dimalttz: &self.ds_dimalttz,
|
||||||
dimtolj: &self.ds_dimtolj,
|
dimtolj: &self.ds_dimtolj,
|
||||||
dimtzin: &self.ds_dimtzin,
|
dimtzin: &self.ds_dimtzin,
|
||||||
dimblk_name,
|
dimblk_name: dimblk_name.clone(),
|
||||||
dimblk1_name,
|
dimblk1_name: dimblk1_name.clone(),
|
||||||
dimblk2_name,
|
dimblk2_name: dimblk2_name.clone(),
|
||||||
dimldrblk_name,
|
dimldrblk_name: dimldrblk_name.clone(),
|
||||||
dimltex_name,
|
dimltex_name: dimltex_name.clone(),
|
||||||
dimltex1_name,
|
dimltex1_name: dimltex1_name.clone(),
|
||||||
dimltex2_name,
|
dimltex2_name: dimltex2_name.clone(),
|
||||||
block_opts,
|
block_opts: block_opts.clone(),
|
||||||
lt_opts,
|
lt_opts: lt_opts.clone(),
|
||||||
color_open: self.ds_color_open.clone(),
|
color_open: self.ds_color_open.clone(),
|
||||||
},
|
},
|
||||||
self.style_rename.as_deref(),
|
self.style_rename.as_deref(),
|
||||||
&self.style_rename_buf,
|
&self.style_rename_buf,
|
||||||
), 720, 560)
|
flow,
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
super::super::ModalKind::AssocPrompt => sized(default_assoc_dialog_window(), 440, 210),
|
super::super::ModalKind::AssocPrompt => sized(default_assoc_dialog_window(), 440, 210),
|
||||||
super::super::ModalKind::AecDropWarning => {
|
super::super::ModalKind::AecDropWarning => {
|
||||||
|
|
@ -738,14 +834,22 @@ impl OpenCADStudio {
|
||||||
};
|
};
|
||||||
sized(unsaved_changes_dialog_window(&tab_name), 420, 160)
|
sized(unsaved_changes_dialog_window(&tab_name), 420, 160)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::PointStyle => sized(
|
super::super::ModalKind::PointStyle => sized_flow(
|
||||||
crate::ui::style::point_style::view_window(
|
ex,
|
||||||
self.tabs[self.active_tab].scene.document.header.point_display_mode,
|
|
||||||
self.point_size_relative,
|
|
||||||
&self.point_size_buf,
|
|
||||||
),
|
|
||||||
360,
|
360,
|
||||||
470,
|
470,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::style::point_style::view_window(
|
||||||
|
self.tabs[self.active_tab]
|
||||||
|
.scene
|
||||||
|
.document
|
||||||
|
.header
|
||||||
|
.point_display_mode,
|
||||||
|
self.point_size_relative,
|
||||||
|
&self.point_size_buf,
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
super::super::ModalKind::AttributeEditor => {
|
super::super::ModalKind::AttributeEditor => {
|
||||||
let doc = &self.tabs[self.active_tab].scene.document;
|
let doc = &self.tabs[self.active_tab].scene.document;
|
||||||
|
|
@ -763,18 +867,22 @@ impl OpenCADStudio {
|
||||||
.map(|s| s.name.trim().to_string())
|
.map(|s| s.name.trim().to_string())
|
||||||
.filter(|n| !n.is_empty())
|
.filter(|n| !n.is_empty())
|
||||||
.collect();
|
.collect();
|
||||||
sized(
|
sized_flow(
|
||||||
crate::ui::window::attribute_editor::view_window(
|
ex,
|
||||||
&self.attr_editor_block,
|
|
||||||
&self.attr_editor_rows,
|
|
||||||
self.attr_editor_selected,
|
|
||||||
self.attr_editor_tab,
|
|
||||||
layers,
|
|
||||||
linetypes,
|
|
||||||
styles,
|
|
||||||
),
|
|
||||||
640,
|
640,
|
||||||
500,
|
500,
|
||||||
|
|flow| {
|
||||||
|
crate::ui::window::attribute_editor::view_window(
|
||||||
|
&self.attr_editor_block,
|
||||||
|
&self.attr_editor_rows,
|
||||||
|
self.attr_editor_selected,
|
||||||
|
self.attr_editor_tab,
|
||||||
|
layers.clone(),
|
||||||
|
linetypes.clone(),
|
||||||
|
styles.clone(),
|
||||||
|
flow,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super::super::ModalKind::SaveDialog => {
|
super::super::ModalKind::SaveDialog => {
|
||||||
|
|
@ -794,6 +902,20 @@ impl OpenCADStudio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sized_flow<'a>(
|
||||||
|
extra: iced::Vector,
|
||||||
|
max_width: u16,
|
||||||
|
max_height: u16,
|
||||||
|
mut build: impl FnMut(crate::ui::modal::ModalSizing) -> Element<'a, Message>,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
|
crate::ui::modal::intrinsic(
|
||||||
|
build(crate::ui::modal::ModalSizing::INTRINSIC),
|
||||||
|
build(crate::ui::modal::ModalSizing::FILL),
|
||||||
|
iced::Size::new(max_width as f32, max_height as f32),
|
||||||
|
extra,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn dialog_button(
|
fn dialog_button(
|
||||||
label: &'static str,
|
label: &'static str,
|
||||||
message: Message,
|
message: Message,
|
||||||
|
|
@ -807,7 +929,7 @@ fn dialog_button(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dialog_body_style(theme: &Theme) -> container::Style {
|
fn dialog_body_style(theme: &Theme) -> container::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
text_color: Some(palette.background.base.text),
|
text_color: Some(palette.background.base.text),
|
||||||
|
|
@ -817,7 +939,7 @@ fn dialog_body_style(theme: &Theme) -> container::Style {
|
||||||
|
|
||||||
fn dialog_muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
fn dialog_muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -846,7 +968,7 @@ fn save_as_dialog_window<'a>(filename: &'a str, format: &'a str) -> Element<'a,
|
||||||
.on_input(Message::SaveDialogFilenameChanged)
|
.on_input(Message::SaveDialogFilenameChanged)
|
||||||
.size(13)
|
.size(13)
|
||||||
.padding([5, 8])
|
.padding([5, 8])
|
||||||
.width(Fill),
|
.width(Fit),
|
||||||
]
|
]
|
||||||
.align_y(iced::Alignment::Center)
|
.align_y(iced::Alignment::Center)
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
|
|
@ -860,10 +982,10 @@ fn save_as_dialog_window<'a>(filename: &'a str, format: &'a str) -> Element<'a,
|
||||||
items.push(
|
items.push(
|
||||||
row![
|
row![
|
||||||
label("Format:").width(70),
|
label("Format:").width(70),
|
||||||
pick_list(crate::io::SAVE_FORMAT_OPTIONS, sel_fmt, |s: &str| {
|
crate::ui::pick_list(crate::io::SAVE_FORMAT_OPTIONS, sel_fmt, |s: &str| {
|
||||||
Message::SaveDialogFormatChanged(s.to_string())
|
Message::SaveDialogFormatChanged(s.to_string())
|
||||||
})
|
})
|
||||||
.width(Fill),
|
.width(Fit),
|
||||||
]
|
]
|
||||||
.align_y(iced::Alignment::Center)
|
.align_y(iced::Alignment::Center)
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
|
|
@ -872,7 +994,7 @@ fn save_as_dialog_window<'a>(filename: &'a str, format: &'a str) -> Element<'a,
|
||||||
items.push(Space::new().height(16).into());
|
items.push(Space::new().height(16).into());
|
||||||
items.push(
|
items.push(
|
||||||
row![
|
row![
|
||||||
Space::new().width(Fill),
|
Space::new().width(Fit),
|
||||||
dialog_button("Save as...", Message::SaveDialogConfirm, button::primary),
|
dialog_button("Save as...", Message::SaveDialogConfirm, button::primary),
|
||||||
Space::new().width(8),
|
Space::new().width(8),
|
||||||
dialog_button("Cancel", Message::SaveDialogCancel, button::secondary),
|
dialog_button("Cancel", Message::SaveDialogCancel, button::secondary),
|
||||||
|
|
@ -885,8 +1007,8 @@ fn save_as_dialog_window<'a>(filename: &'a str, format: &'a str) -> Element<'a,
|
||||||
container(body)
|
container(body)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.padding([14, 16])
|
.padding([14, 16])
|
||||||
.width(Fill)
|
.width(Fit)
|
||||||
.height(Fill)
|
.height(Fit)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -908,7 +1030,7 @@ fn unsaved_changes_dialog_window(name: &str) -> Element<'static, Message> {
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
)
|
)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.center(Fill)
|
.center(Fit)
|
||||||
.padding([24, 28])
|
.padding([24, 28])
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -932,11 +1054,11 @@ fn file_in_use_dialog_window(path: &str, error: &str) -> Element<'static, Messag
|
||||||
Close it there and retry, or save this drawing under a different name."
|
Close it there and retry, or save this drawing under a different name."
|
||||||
)
|
)
|
||||||
.size(13)
|
.size(13)
|
||||||
.width(Fill),
|
.width(Fit),
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
text(path_line).size(11).style(dialog_muted_text_style).width(Fill),
|
text(path_line).size(11).style(dialog_muted_text_style).width(Fit),
|
||||||
Space::new().height(4),
|
Space::new().height(4),
|
||||||
text(details).size(11).style(dialog_muted_text_style).width(Fill),
|
text(details).size(11).style(dialog_muted_text_style).width(Fit),
|
||||||
Space::new().height(18),
|
Space::new().height(18),
|
||||||
row![
|
row![
|
||||||
dialog_button(
|
dialog_button(
|
||||||
|
|
@ -962,8 +1084,8 @@ fn file_in_use_dialog_window(path: &str, error: &str) -> Element<'static, Messag
|
||||||
)
|
)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.padding([18, 20])
|
.padding([18, 20])
|
||||||
.width(Fill)
|
.width(Fit)
|
||||||
.height(Fill)
|
.height(Fit)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -985,9 +1107,9 @@ fn external_change_dialog_window(path: &str) -> Element<'static, Message> {
|
||||||
save your local work elsewhere, or explicitly overwrite it."
|
save your local work elsewhere, or explicitly overwrite it."
|
||||||
)
|
)
|
||||||
.size(13)
|
.size(13)
|
||||||
.width(Fill),
|
.width(Fit),
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
text(path_line).size(11).style(dialog_muted_text_style).width(Fill),
|
text(path_line).size(11).style(dialog_muted_text_style).width(Fit),
|
||||||
Space::new().height(18),
|
Space::new().height(18),
|
||||||
row![
|
row![
|
||||||
dialog_button(
|
dialog_button(
|
||||||
|
|
@ -1019,8 +1141,8 @@ fn external_change_dialog_window(path: &str) -> Element<'static, Message> {
|
||||||
)
|
)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.padding([18, 20])
|
.padding([18, 20])
|
||||||
.width(Fill)
|
.width(Fit)
|
||||||
.height(Fill)
|
.height(Fit)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1054,7 +1176,7 @@ fn aec_drop_dialog_window(count: usize, target: &str, src_version: &str) -> Elem
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
)
|
)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.center(Fill)
|
.center(Fit)
|
||||||
.padding([24, 28])
|
.padding([24, 28])
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -1093,7 +1215,7 @@ fn layer_delete_warning_window(names: &[String], count: usize) -> Element<'stati
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
)
|
)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.center(Fill)
|
.center(Fit)
|
||||||
.padding([24, 28])
|
.padding([24, 28])
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -1113,7 +1235,7 @@ fn default_assoc_dialog_window() -> Element<'static, Message> {
|
||||||
.style(dialog_muted_text_style),
|
.style(dialog_muted_text_style),
|
||||||
iced::widget::Space::new().height(22),
|
iced::widget::Space::new().height(22),
|
||||||
row![
|
row![
|
||||||
iced::widget::Space::new().width(Fill),
|
iced::widget::Space::new().width(Fit),
|
||||||
dialog_button("Not now", Message::AssocPromptNo, button::secondary),
|
dialog_button("Not now", Message::AssocPromptNo, button::secondary),
|
||||||
iced::widget::Space::new().width(8),
|
iced::widget::Space::new().width(8),
|
||||||
dialog_button(
|
dialog_button(
|
||||||
|
|
@ -1127,7 +1249,7 @@ fn default_assoc_dialog_window() -> Element<'static, Message> {
|
||||||
.spacing(0),
|
.spacing(0),
|
||||||
)
|
)
|
||||||
.style(dialog_body_style)
|
.style(dialog_body_style)
|
||||||
.center(Fill)
|
.center(Fit)
|
||||||
.padding([24, 28])
|
.padding([24, 28])
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::super::Message;
|
use super::super::Message;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, column, container, mouse_area, pick_list, row, stack, text, text_input,
|
button, column, container, mouse_area, row, stack, text, text_input,
|
||||||
Space,
|
Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Color, Element, Fill, Theme};
|
use iced::{Background, Border, Color, Element, Fill, Theme};
|
||||||
|
|
@ -36,7 +36,7 @@ pub(super) fn text_inline_overlay(
|
||||||
|
|
||||||
let panel = container(field)
|
let panel = container(field)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -211,7 +211,7 @@ impl iced::widget::canvas::Program<Message> for MTextPreview {
|
||||||
);
|
);
|
||||||
frame.fill(
|
frame.fill(
|
||||||
&rect,
|
&rect,
|
||||||
theme.extended_palette().primary.base.color.scale_alpha(0.45),
|
theme.palette().primary.base.color.scale_alpha(0.45),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +247,7 @@ impl iced::widget::canvas::Program<Message> for MTextPreview {
|
||||||
frame.stroke(
|
frame.stroke(
|
||||||
&path,
|
&path,
|
||||||
Stroke::default()
|
Stroke::default()
|
||||||
.with_color(theme.extended_palette().warning.base.color)
|
.with_color(theme.palette().warning.base.color)
|
||||||
.with_width(1.5),
|
.with_width(1.5),
|
||||||
);
|
);
|
||||||
} else if collapsed {
|
} else if collapsed {
|
||||||
|
|
@ -271,7 +271,7 @@ impl iced::widget::canvas::Program<Message> for MTextPreview {
|
||||||
frame.stroke(
|
frame.stroke(
|
||||||
&path,
|
&path,
|
||||||
Stroke::default()
|
Stroke::default()
|
||||||
.with_color(theme.extended_palette().warning.base.color)
|
.with_color(theme.palette().warning.base.color)
|
||||||
.with_width(1.5),
|
.with_width(1.5),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -318,11 +318,14 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
modal_offset: iced::Vector,
|
modal_offset: iced::Vector,
|
||||||
modal_resize: iced::Vector,
|
modal_resize: iced::Vector,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
|
let sizing = crate::ui::modal::ModalSizing::from_resize(modal_resize);
|
||||||
|
let width = sizing.width;
|
||||||
|
let height = sizing.height;
|
||||||
use super::super::mtext_editor::{JustifyChoice, MTextFmt, ParaAlign};
|
use super::super::mtext_editor::{JustifyChoice, MTextFmt, ParaAlign};
|
||||||
use iced::widget::canvas;
|
use iced::widget::canvas;
|
||||||
|
|
||||||
let btn_style = |theme: &Theme, status: button::Status| {
|
let btn_style = |theme: &Theme, status: button::Status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => palette.background.strong,
|
button::Status::Hovered | button::Status::Pressed => palette.background.strong,
|
||||||
_ => palette.background.weak,
|
_ => palette.background.weak,
|
||||||
|
|
@ -366,7 +369,7 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
} else {
|
} else {
|
||||||
styles
|
styles
|
||||||
};
|
};
|
||||||
let style_pl = pick_list(style_opts, Some(ed.style.clone()), Message::MTextStyle)
|
let style_pl = crate::ui::pick_list(style_opts, Some(ed.style.clone()), Message::MTextStyle)
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
.width(iced::Length::Fixed(96.0));
|
.width(iced::Length::Fixed(96.0));
|
||||||
let font_sel = if ed.font.trim().is_empty() {
|
let font_sel = if ed.font.trim().is_empty() {
|
||||||
|
|
@ -374,7 +377,7 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
} else {
|
} else {
|
||||||
ed.font.clone()
|
ed.font.clone()
|
||||||
};
|
};
|
||||||
let font_pl = pick_list(
|
let font_pl = crate::ui::pick_list(
|
||||||
MTEXT_FONTS
|
MTEXT_FONTS
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
|
|
@ -432,14 +435,15 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
include_bytes!("../../../assets/icons/mt_lower.svg"),
|
include_bytes!("../../../assets/icons/mt_lower.svg"),
|
||||||
Message::MTextFmt(MTextFmt::Lowercase)
|
Message::MTextFmt(MTextFmt::Lowercase)
|
||||||
),
|
),
|
||||||
iced::widget::Space::new().width(Fill),
|
iced::widget::Space::new().width(width),
|
||||||
color_pl,
|
color_pl,
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Alignment::Center);
|
.align_y(iced::Alignment::Center)
|
||||||
|
.width(width);
|
||||||
|
|
||||||
// ── Row 2: oblique / width / char-spacing · align · line spacing · OK ─
|
// ── Row 2: oblique / width / char-spacing · align · line spacing · OK ─
|
||||||
let justify = pick_list(
|
let justify = crate::ui::pick_list(
|
||||||
JustifyChoice::ALL,
|
JustifyChoice::ALL,
|
||||||
Some(JustifyChoice(ed.attachment)),
|
Some(JustifyChoice(ed.attachment)),
|
||||||
|c| Message::MTextJustify(c.0),
|
|c| Message::MTextJustify(c.0),
|
||||||
|
|
@ -487,7 +491,8 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
.style(btn_style),
|
.style(btn_style),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Alignment::Center);
|
.align_y(iced::Alignment::Center)
|
||||||
|
.width(width);
|
||||||
|
|
||||||
// ── Body: the rendered preview (the editor is preview-only). It fills the
|
// ── Body: the rendered preview (the editor is preview-only). It fills the
|
||||||
// space left by the toolbars, so the resizable modal's extra height flows
|
// space left by the toolbars, so the resizable modal's extra height flows
|
||||||
|
|
@ -587,11 +592,11 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
vertical: Scrollbar::default(),
|
vertical: Scrollbar::default(),
|
||||||
horizontal: Scrollbar::default(),
|
horizontal: Scrollbar::default(),
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill),
|
.height(height),
|
||||||
)
|
)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -603,8 +608,8 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding(2)
|
.padding(2)
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -613,32 +618,31 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
// buffer, so there is no separate Cancel.
|
// buffer, so there is no separate Cancel.
|
||||||
let action_bar = container(
|
let action_bar = container(
|
||||||
row![
|
row![
|
||||||
iced::widget::Space::new().width(Fill),
|
iced::widget::Space::new().width(width),
|
||||||
crate::ui::style::style_manager::tb_button("Apply", Message::MTextApply, true),
|
crate::ui::style::style_manager::tb_button("Apply", Message::MTextApply, true),
|
||||||
]
|
]
|
||||||
.align_y(iced::Alignment::Center),
|
.align_y(iced::Alignment::Center),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
// The shared modal frame supplies the panel background, drag title bar,
|
// The shared modal frame supplies the panel background, drag title bar,
|
||||||
// ✕ (which also cancels) and the resize grip. The content is a Fill column
|
// ✕ (which also cancels) and the resize grip. Iced 0.15 measures this
|
||||||
// wrapped here in a fixed box (natural 660×480, grown by the shared resize
|
// content first and clamps it to the user-growable maximum.
|
||||||
// delta) so the modal frame shrinks to it and the corner grip can drag it.
|
|
||||||
let content = container(
|
let content = container(
|
||||||
column![action_bar, row1, row2, body]
|
column![action_bar, row1, row2, body]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill),
|
.height(height),
|
||||||
)
|
)
|
||||||
.width(iced::Length::Fixed(660.0 + modal_resize.x))
|
.width(iced::Length::Fit.max(660.0 + modal_resize.x))
|
||||||
.height(iced::Length::Fixed(480.0 + modal_resize.y));
|
.height(iced::Length::Fit.max(480.0 + modal_resize.y));
|
||||||
|
|
||||||
let _ = canvas_size; // positioned & sized by the modal frame now
|
let _ = canvas_size; // positioned & sized by the modal frame now
|
||||||
// `modal` sizes its stack from the base layer, so the base must fill the
|
// `modal` sizes its stack from the base layer, so the base must fill the
|
||||||
|
|
@ -647,11 +651,10 @@ pub(super) fn mtext_editor_overlay<'a>(
|
||||||
crate::ui::modal::modal(
|
crate::ui::modal::modal(
|
||||||
iced::widget::Space::new().width(Fill).height(Fill),
|
iced::widget::Space::new().width(Fill).height(Fill),
|
||||||
"Text Editor",
|
"Text Editor",
|
||||||
660.0 + modal_resize.x,
|
|
||||||
content,
|
content,
|
||||||
Message::MTextCancel,
|
Message::MTextCancel,
|
||||||
modal_offset,
|
modal_offset,
|
||||||
true,
|
crate::ui::modal::ModalOptions::STANDARD,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,7 +681,7 @@ pub(super) fn viewport_context_menu_overlay(
|
||||||
container(iced::widget::Space::new().width(Fill).height(1))
|
container(iced::widget::Space::new().width(Fill).height(1))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color,
|
theme.palette().background.weak.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -838,10 +841,10 @@ pub(super) fn snap_override_overlay(pos: iced::Point) -> Element<'static, Messag
|
||||||
button::Status::Hovered | button::Status::Pressed
|
button::Status::Hovered | button::Status::Pressed
|
||||||
)
|
)
|
||||||
.then_some(Background::Color(
|
.then_some(Background::Color(
|
||||||
theme.extended_palette().primary.weak.color
|
theme.palette().primary.weak.color
|
||||||
)),
|
)),
|
||||||
border: Border::default(),
|
border: Border::default(),
|
||||||
text_color: theme.extended_palette().background.base.text,
|
text_color: theme.palette().background.base.text,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.padding(2);
|
.padding(2);
|
||||||
|
|
@ -849,7 +852,7 @@ pub(super) fn snap_override_overlay(pos: iced::Point) -> Element<'static, Messag
|
||||||
btn,
|
btn,
|
||||||
container(text(label).size(11))
|
container(text(label).size(11))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.strong.color)),
|
background: Some(Background::Color(palette.background.strong.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -878,7 +881,7 @@ pub(super) fn snap_override_overlay(pos: iced::Point) -> Element<'static, Messag
|
||||||
|
|
||||||
let panel = container(grid)
|
let panel = container(grid)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -919,7 +922,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
types: &[String],
|
types: &[String],
|
||||||
properties: &[(String, String)],
|
properties: &[(String, String)],
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
use iced::widget::{checkbox, pick_list};
|
use iced::widget::{checkbox};
|
||||||
let mut type_options: Vec<String> = vec![QSELECT_ANY_TYPE.to_string()];
|
let mut type_options: Vec<String> = vec![QSELECT_ANY_TYPE.to_string()];
|
||||||
type_options.extend(types.iter().cloned());
|
type_options.extend(types.iter().cloned());
|
||||||
|
|
||||||
|
|
@ -971,7 +974,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
button(text(lbl).size(12))
|
button(text(lbl).size(12))
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.style(move |theme: &Theme, st| {
|
.style(move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (
|
let pair = match (
|
||||||
primary,
|
primary,
|
||||||
matches!(st, button::Status::Hovered | button::Status::Pressed),
|
matches!(st, button::Status::Hovered | button::Status::Pressed),
|
||||||
|
|
@ -1005,7 +1008,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
Space::new().height(10),
|
Space::new().height(10),
|
||||||
row![
|
row![
|
||||||
label("Object type:"),
|
label("Object type:"),
|
||||||
pick_list(type_options, Some(type_sel), |s: String| {
|
crate::ui::pick_list(type_options, Some(type_sel), |s: String| {
|
||||||
if s == QSELECT_ANY_TYPE {
|
if s == QSELECT_ANY_TYPE {
|
||||||
Message::QSelectSetType(None)
|
Message::QSelectSetType(None)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1019,7 +1022,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
row![
|
row![
|
||||||
label("Property:"),
|
label("Property:"),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
prop_options,
|
prop_options,
|
||||||
Some(prop_sel),
|
Some(prop_sel),
|
||||||
|p: crate::app::QSelectPropertyChoice| {
|
|p: crate::app::QSelectPropertyChoice| {
|
||||||
|
|
@ -1037,7 +1040,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
row![
|
row![
|
||||||
label("Operator:"),
|
label("Operator:"),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
op_options,
|
op_options,
|
||||||
Some(state.operator),
|
Some(state.operator),
|
||||||
Message::QSelectSetOperator
|
Message::QSelectSetOperator
|
||||||
|
|
@ -1074,7 +1077,7 @@ pub(super) fn qselect_overlay<'a>(
|
||||||
.padding(16)
|
.padding(16)
|
||||||
.width(iced::Length::Fixed(400.0))
|
.width(iced::Length::Fixed(400.0))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use super::super::Message;
|
use super::super::Message;
|
||||||
use crate::scene::{VIEWCUBE_PX, VIEWCUBE_REGION_PX};
|
use crate::scene::{VIEWCUBE_PX, VIEWCUBE_REGION_PX};
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, container, mouse_area, pick_list, stack, Space,
|
button, container, mouse_area, stack, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
|
|
@ -36,13 +36,13 @@ fn vc_btn<'a>(content: Element<'a, Message>, size: f32, msg: Message) -> Element
|
||||||
iced::widget::button::Status::Hovered | iced::widget::button::Status::Pressed
|
iced::widget::button::Status::Hovered | iced::widget::button::Status::Pressed
|
||||||
)
|
)
|
||||||
.then_some(Background::Color(
|
.then_some(Background::Color(
|
||||||
theme.extended_palette().primary.weak.color
|
theme.palette().primary.weak.color
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
text_color: theme.extended_palette().background.base.text,
|
text_color: theme.palette().background.base.text,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
|
|
@ -155,14 +155,14 @@ pub(super) fn viewcube_ucs_picker<'a>(current: String, names: Vec<String>) -> El
|
||||||
} else {
|
} else {
|
||||||
current
|
current
|
||||||
};
|
};
|
||||||
pick_list(options, Some(selected), Message::SetViewcubeUcs)
|
crate::ui::pick_list(options, Some(selected), Message::SetViewcubeUcs)
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
.padding([2, 6])
|
.padding([2, 6])
|
||||||
// Fixed width so the caller can centre it under the cube centre with a
|
// Fixed width so the caller can centre it under the cube centre with a
|
||||||
// simple half-width offset (content-sized width would drift off-centre).
|
// simple half-width offset (content-sized width would drift off-centre).
|
||||||
.width(iced::Length::Fixed(UCS_PICKER_W))
|
.width(iced::Length::Fixed(UCS_PICKER_W))
|
||||||
.style(move |theme: &Theme, _| {
|
.style(move |theme: &Theme, _| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
iced::widget::pick_list::Style {
|
iced::widget::pick_list::Style {
|
||||||
background: Background::Color(palette.background.weak.color),
|
background: Background::Color(palette.background.weak.color),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ impl DeviceCapabilities {
|
||||||
fn from_limits(limits: &wgpu::Limits) -> Self {
|
fn from_limits(limits: &wgpu::Limits) -> Self {
|
||||||
Self {
|
Self {
|
||||||
max_storage_buffers_per_shader_stage: limits.max_storage_buffers_per_shader_stage,
|
max_storage_buffers_per_shader_stage: limits.max_storage_buffers_per_shader_stage,
|
||||||
max_inter_stage_shader_components: limits.max_inter_stage_shader_components,
|
max_inter_stage_shader_components: limits.max_inter_stage_shader_variables,
|
||||||
max_vertex_attributes: limits.max_vertex_attributes,
|
max_vertex_attributes: limits.max_vertex_attributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ impl HatchGpu {
|
||||||
};
|
};
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("hatch.pipeline_layout"),
|
label: Some("hatch.pipeline_layout"),
|
||||||
bind_group_layouts: &[frame_bind_group_layout, &bind_group_layout],
|
bind_group_layouts: &[frame_bind_group_layout, &bind_group_layout].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some(if uses_storage {
|
label: Some(if uses_storage {
|
||||||
|
|
@ -108,8 +108,8 @@ impl HatchGpu {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState {
|
bias: wgpu::DepthBiasState {
|
||||||
constant: 1,
|
constant: 1,
|
||||||
|
|
@ -132,7 +132,7 @@ impl HatchGpu {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
let backend = match backend_kind {
|
let backend = match backend_kind {
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ impl ImageGpu {
|
||||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
mag_filter: wgpu::FilterMode::Linear,
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
min_filter: wgpu::FilterMode::Linear,
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
mipmap_filter: wgpu::MipmapFilterMode::Nearest,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,7 @@ pub fn create_material_bind_group(
|
||||||
address_mode_w: address,
|
address_mode_w: address,
|
||||||
mag_filter: wgpu::FilterMode::Linear,
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
min_filter: wgpu::FilterMode::Linear,
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
mipmap_filter: wgpu::FilterMode::Linear,
|
mipmap_filter: wgpu::MipmapFilterMode::Linear,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -380,14 +380,14 @@ impl Pipeline {
|
||||||
let wire_const_bgl = wire_mode
|
let wire_const_bgl = wire_mode
|
||||||
.uses_storage()
|
.uses_storage()
|
||||||
.then(|| wire_gpu::WireConst::bind_group_layout(device));
|
.then(|| wire_gpu::WireConst::bind_group_layout(device));
|
||||||
let mut wire_bgls: Vec<&wgpu::BindGroupLayout> = vec![&frame_bgl];
|
let mut wire_bgls: Vec<Option<&wgpu::BindGroupLayout>> = vec![Some(&frame_bgl)];
|
||||||
if let Some(bgl) = &wire_const_bgl {
|
if let Some(bgl) = &wire_const_bgl {
|
||||||
wire_bgls.push(bgl);
|
wire_bgls.push(Some(bgl));
|
||||||
}
|
}
|
||||||
let wire_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let wire_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("wire.pipeline_layout"),
|
label: Some("wire.pipeline_layout"),
|
||||||
bind_group_layouts: &wire_bgls,
|
bind_group_layouts: &wire_bgls,
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let depth_tex = create_depth_texture(device, Size::new(1, 1));
|
let depth_tex = create_depth_texture(device, Size::new(1, 1));
|
||||||
|
|
@ -438,8 +438,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -458,7 +458,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -476,7 +476,7 @@ impl Pipeline {
|
||||||
let clip_mask_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let clip_mask_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("clip_mask.pipeline_layout"),
|
label: Some("clip_mask.pipeline_layout"),
|
||||||
bind_group_layouts: &[],
|
bind_group_layouts: &[],
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
let clip_mask_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
let clip_mask_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
label: Some("clip_mask.pipeline"),
|
label: Some("clip_mask.pipeline"),
|
||||||
|
|
@ -502,8 +502,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: false,
|
depth_write_enabled: Some(false),
|
||||||
depth_compare: wgpu::CompareFunction::Always,
|
depth_compare: Some(wgpu::CompareFunction::Always),
|
||||||
stencil: wgpu::StencilState {
|
stencil: wgpu::StencilState {
|
||||||
front: wgpu::StencilFaceState {
|
front: wgpu::StencilFaceState {
|
||||||
compare: wgpu::CompareFunction::Always,
|
compare: wgpu::CompareFunction::Always,
|
||||||
|
|
@ -537,7 +537,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -559,8 +559,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -579,7 +579,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -602,8 +602,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: false,
|
depth_write_enabled: Some(false),
|
||||||
depth_compare: wgpu::CompareFunction::Always,
|
depth_compare: Some(wgpu::CompareFunction::Always),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -622,7 +622,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -654,8 +654,8 @@ impl Pipeline {
|
||||||
|
|
||||||
let wipeout_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let wipeout_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("wipeout.pipeline_layout"),
|
label: Some("wipeout.pipeline_layout"),
|
||||||
bind_group_layouts: &[&frame_bgl, &wipeout_bgl1],
|
bind_group_layouts: &[&frame_bgl, &wipeout_bgl1].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let wipeout_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let wipeout_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
|
@ -681,8 +681,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
// Bias TOWARD the camera: a wipeout must win against geometry at
|
// Bias TOWARD the camera: a wipeout must win against geometry at
|
||||||
// its own depth (a block's wipeout + shapes are coincident at
|
// its own depth (a block's wipeout + shapes are coincident at
|
||||||
|
|
@ -710,7 +710,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -850,8 +850,8 @@ impl Pipeline {
|
||||||
let layout =
|
let layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("mesh.cull.layout"),
|
label: Some("mesh.cull.layout"),
|
||||||
bind_group_layouts: &[&bgl],
|
bind_group_layouts: &[&bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
let pipeline =
|
let pipeline =
|
||||||
device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
|
device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
|
||||||
|
|
@ -1027,8 +1027,8 @@ impl Pipeline {
|
||||||
|
|
||||||
let mesh_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let mesh_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("mesh.pipeline_layout"),
|
label: Some("mesh.pipeline_layout"),
|
||||||
bind_group_layouts: &[&frame_bgl, &mesh_material_bgl],
|
bind_group_layouts: &[&frame_bgl, &mesh_material_bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mesh_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
let mesh_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
|
@ -1047,8 +1047,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState {
|
bias: wgpu::DepthBiasState {
|
||||||
constant: 1,
|
constant: 1,
|
||||||
|
|
@ -1071,7 +1071,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1096,8 +1096,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: false,
|
depth_write_enabled: Some(false),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState {
|
bias: wgpu::DepthBiasState {
|
||||||
constant: 1,
|
constant: 1,
|
||||||
|
|
@ -1120,7 +1120,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1144,8 +1144,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: false,
|
depth_write_enabled: Some(false),
|
||||||
depth_compare: wgpu::CompareFunction::Always,
|
depth_compare: Some(wgpu::CompareFunction::Always),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -1164,7 +1164,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -1199,8 +1199,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -1219,7 +1219,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -1246,8 +1246,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState {
|
bias: wgpu::DepthBiasState {
|
||||||
constant: 1,
|
constant: 1,
|
||||||
|
|
@ -1270,7 +1270,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1284,8 +1284,8 @@ impl Pipeline {
|
||||||
|
|
||||||
let face3d_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let face3d_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("face3d.pipeline_layout"),
|
label: Some("face3d.pipeline_layout"),
|
||||||
bind_group_layouts: &[&frame_bgl],
|
bind_group_layouts: &[&frame_bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let face3d_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
let face3d_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
|
@ -1304,8 +1304,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState {
|
bias: wgpu::DepthBiasState {
|
||||||
constant: 1,
|
constant: 1,
|
||||||
|
|
@ -1328,7 +1328,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1351,8 +1351,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState {
|
bias: wgpu::DepthBiasState {
|
||||||
constant: 1,
|
constant: 1,
|
||||||
|
|
@ -1375,7 +1375,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1418,8 +1418,8 @@ impl Pipeline {
|
||||||
|
|
||||||
let image_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let image_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("image.pipeline_layout"),
|
label: Some("image.pipeline_layout"),
|
||||||
bind_group_layouts: &[&frame_bgl, &image_bgl1],
|
bind_group_layouts: &[&frame_bgl, &image_bgl1].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let image_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let image_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
|
@ -1445,8 +1445,8 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
depth_compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
stencil: content_stencil.clone(),
|
stencil: content_stencil.clone(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -1465,7 +1465,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1533,8 +1533,8 @@ impl Pipeline {
|
||||||
|
|
||||||
let blit_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let blit_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("blit.pipeline_layout"),
|
label: Some("blit.pipeline_layout"),
|
||||||
bind_group_layouts: &[&blit_bgl],
|
bind_group_layouts: &[&blit_bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let blit_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
let blit_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
|
@ -1572,7 +1572,7 @@ impl Pipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -2874,6 +2874,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
// MSAA texture is clip-bounds-sized, so viewport starts at (0, 0).
|
// MSAA texture is clip-bounds-sized, so viewport starts at (0, 0).
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
|
|
@ -2918,6 +2919,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_pipeline(&self.image_pipeline);
|
pass.set_pipeline(&self.image_pipeline);
|
||||||
|
|
@ -2968,6 +2970,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||||
|
|
@ -3373,6 +3376,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||||
|
|
@ -3423,6 +3427,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_pipeline(&self.wire_pipeline);
|
pass.set_pipeline(&self.wire_pipeline);
|
||||||
|
|
@ -3465,6 +3470,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_pipeline(&self.wire_pipeline);
|
pass.set_pipeline(&self.wire_pipeline);
|
||||||
|
|
@ -3559,6 +3565,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_pipeline(&self.text_pipeline);
|
pass.set_pipeline(&self.text_pipeline);
|
||||||
|
|
@ -3604,6 +3611,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_pipeline(&self.wipeout_pipeline);
|
pass.set_pipeline(&self.wipeout_pipeline);
|
||||||
|
|
@ -3646,6 +3654,7 @@ impl Pipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
pass.set_viewport(0.0, 0.0, vp.width as f32, vp.height as f32, 0.0, 1.0);
|
||||||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||||
|
|
@ -3697,6 +3706,7 @@ impl Pipeline {
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
// No draw calls — the pass itself triggers the MSAA resolve.
|
// No draw calls — the pass itself triggers the MSAA resolve.
|
||||||
}
|
}
|
||||||
|
|
@ -3722,6 +3732,7 @@ impl Pipeline {
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(
|
pass.set_viewport(
|
||||||
surface_dest.x as f32,
|
surface_dest.x as f32,
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ impl TextAtlasGpu {
|
||||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
mag_filter: wgpu::FilterMode::Linear,
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
min_filter: wgpu::FilterMode::Linear,
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
mipmap_filter: wgpu::MipmapFilterMode::Nearest,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
|
@ -267,8 +267,8 @@ pub fn create_pipelines(
|
||||||
});
|
});
|
||||||
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("text.pipeline.layout"),
|
label: Some("text.pipeline.layout"),
|
||||||
bind_group_layouts: &[frame_bgl, atlas_bgl],
|
bind_group_layouts: &[frame_bgl, atlas_bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
let create = |label, depth_write_enabled, depth_compare| {
|
let create = |label, depth_write_enabled, depth_compare| {
|
||||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
|
@ -306,16 +306,20 @@ pub fn create_pipelines(
|
||||||
mask: !0,
|
mask: !0,
|
||||||
alpha_to_coverage_enabled: false,
|
alpha_to_coverage_enabled: false,
|
||||||
},
|
},
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
create("text.pipeline", true, wgpu::CompareFunction::LessEqual),
|
create(
|
||||||
|
"text.pipeline",
|
||||||
|
Some(true),
|
||||||
|
Some(wgpu::CompareFunction::LessEqual),
|
||||||
|
),
|
||||||
create(
|
create(
|
||||||
"text.highlight.pipeline",
|
"text.highlight.pipeline",
|
||||||
false,
|
Some(false),
|
||||||
wgpu::CompareFunction::Always,
|
Some(wgpu::CompareFunction::Always),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -510,8 +510,8 @@ impl ViewCubeText {
|
||||||
});
|
});
|
||||||
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("vc.text_layout"),
|
label: Some("vc.text_layout"),
|
||||||
bind_group_layouts: &[&bgl],
|
bind_group_layouts: &[&bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("vc.text_shader"),
|
label: Some("vc.text_shader"),
|
||||||
|
|
@ -545,7 +545,7 @@ impl ViewCubeText {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
let vertex_capacity = MAX_VERTS as u32;
|
let vertex_capacity = MAX_VERTS as u32;
|
||||||
|
|
@ -782,6 +782,7 @@ impl ViewCubeText {
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(
|
pass.set_viewport(
|
||||||
clip.x as f32,
|
clip.x as f32,
|
||||||
|
|
@ -1172,8 +1173,8 @@ impl ViewCubePipeline {
|
||||||
});
|
});
|
||||||
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("vc.layout"),
|
label: Some("vc.layout"),
|
||||||
bind_group_layouts: &[&bgl],
|
bind_group_layouts: &[&bgl].map(Some),
|
||||||
push_constant_ranges: &[],
|
immediate_size: 0,
|
||||||
});
|
});
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("vc.shader"),
|
label: Some("vc.shader"),
|
||||||
|
|
@ -1199,8 +1200,8 @@ impl ViewCubePipeline {
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
format: wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: Some(true),
|
||||||
depth_compare: wgpu::CompareFunction::Less,
|
depth_compare: Some(wgpu::CompareFunction::Less),
|
||||||
stencil: wgpu::StencilState::default(),
|
stencil: wgpu::StencilState::default(),
|
||||||
bias: wgpu::DepthBiasState::default(),
|
bias: wgpu::DepthBiasState::default(),
|
||||||
}),
|
}),
|
||||||
|
|
@ -1215,7 +1216,7 @@ impl ViewCubePipeline {
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview_mask: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
let text = ViewCubeText::new(device, queue, format);
|
let text = ViewCubeText::new(device, queue, format);
|
||||||
|
|
@ -1303,6 +1304,7 @@ impl ViewCubePipeline {
|
||||||
}),
|
}),
|
||||||
timestamp_writes: None,
|
timestamp_writes: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
multiview_mask: None,
|
||||||
});
|
});
|
||||||
pass.set_viewport(
|
pass.set_viewport(
|
||||||
clip.x as f32,
|
clip.x as f32,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,9 @@ fn instance_buffer_mapped<T: bytemuck::Pod>(
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
let mut view = buf.slice(..).get_mapped_range_mut();
|
let mut view = buf.slice(..).get_mapped_range_mut();
|
||||||
view[..bytes.len()].copy_from_slice(bytes);
|
if !bytes.is_empty() {
|
||||||
|
view.slice(..bytes.len()).copy_from_slice(bytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.unmap();
|
buf.unmap();
|
||||||
buf
|
buf
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::ui::properties::acad_color_display;
|
||||||
use acadrust::types::Color as AcadColor;
|
use acadrust::types::Color as AcadColor;
|
||||||
use iced::advanced::layout::{self, Layout};
|
use iced::advanced::layout::{self, Layout};
|
||||||
use iced::advanced::widget::{self, Widget};
|
use iced::advanced::widget::{self, Widget};
|
||||||
use iced::advanced::{mouse, overlay, renderer, Clipboard, Shell};
|
use iced::advanced::{mouse, overlay, renderer, Shell};
|
||||||
use iced::widget::{button, column, container, row, scrollable, text};
|
use iced::widget::{button, column, container, row, scrollable, text};
|
||||||
use iced::{Background, Border, Color, Element, Event, Length, Point, Rectangle, Renderer, Size, Theme, Vector};
|
use iced::{Background, Border, Color, Element, Event, Length, Point, Rectangle, Renderer, Size, Theme, Vector};
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ fn swatch<'a>(bg: Color) -> Element<'a, Message> {
|
||||||
.style(move |theme: &Theme| container::Style {
|
.style(move |theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(bg)),
|
background: Some(Background::Color(bg)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 2.0.into(),
|
radius: 2.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -118,7 +118,7 @@ pub fn color_selector<'a>(
|
||||||
|
|
||||||
let popup = container(color_list(extras, on_select, on_more))
|
let popup = container(color_list(extras, on_select, on_more))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -141,7 +141,7 @@ pub fn color_selector<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_row_style(theme: &Theme, status: button::Status) -> button::Style {
|
fn list_row_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let hovered = matches!(status, button::Status::Hovered);
|
let hovered = matches!(status, button::Status::Hovered);
|
||||||
let text_color = if hovered {
|
let text_color = if hovered {
|
||||||
palette.background.strong.text
|
palette.background.strong.text
|
||||||
|
|
@ -230,9 +230,9 @@ pub fn color_grid_window(on_pick: impl Fn(AcadColor) -> Message) -> Element<'sta
|
||||||
background: Some(Background::Color(bg)),
|
background: Some(Background::Color(bg)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: if matches!(status, button::Status::Hovered) {
|
color: if matches!(status, button::Status::Hovered) {
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
} else {
|
} else {
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
},
|
},
|
||||||
width: if matches!(status, button::Status::Hovered) {
|
width: if matches!(status, button::Status::Hovered) {
|
||||||
1.5
|
1.5
|
||||||
|
|
@ -241,7 +241,7 @@ pub fn color_grid_window(on_pick: impl Fn(AcadColor) -> Message) -> Element<'sta
|
||||||
},
|
},
|
||||||
radius: 1.0.into(),
|
radius: 1.0.into(),
|
||||||
},
|
},
|
||||||
text_color: theme.extended_palette().background.base.text,
|
text_color: theme.palette().background.base.text,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.padding(0),
|
.padding(0),
|
||||||
|
|
@ -255,19 +255,19 @@ pub fn color_grid_window(on_pick: impl Fn(AcadColor) -> Message) -> Element<'sta
|
||||||
column![
|
column![
|
||||||
text("Select Color").size(13),
|
text("Select Color").size(13),
|
||||||
row![chip(AcadColor::ByLayer, "ByLayer"), chip(AcadColor::ByBlock, "ByBlock")].spacing(6),
|
row![chip(AcadColor::ByLayer, "ByLayer"), chip(AcadColor::ByBlock, "ByBlock")].spacing(6),
|
||||||
scrollable(grid).height(Length::Fill),
|
scrollable(grid).height(Length::Fit),
|
||||||
]
|
]
|
||||||
.spacing(8),
|
.spacing(8),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.width(Length::Fill)
|
.width(Length::Fit)
|
||||||
.height(Length::Fill)
|
.height(Length::Fit)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,22 +289,14 @@ struct Floating<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget<Message, Theme, Renderer> for Floating<'a> {
|
impl<'a> Widget<Message, Theme, Renderer> for Floating<'a> {
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
vec![widget::Tree::new(&self.base), widget::Tree::new(&self.popup)]
|
tree.diff_children(&mut [&mut self.base, &mut self.popup]);
|
||||||
}
|
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
tree.diff_children(&[self.base.as_widget(), self.popup.as_widget()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
self.base.as_widget().size()
|
self.base.as_widget().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> Size<Length> {
|
|
||||||
self.base.as_widget().size_hint()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut widget::Tree,
|
tree: &mut widget::Tree,
|
||||||
|
|
@ -323,7 +315,6 @@ impl<'a> Widget<Message, Theme, Renderer> for Floating<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -333,7 +324,6 @@ impl<'a> Widget<Message, Theme, Renderer> for Floating<'a> {
|
||||||
layout,
|
layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -469,13 +459,12 @@ impl overlay::Overlay<Message, Theme, Renderer> for FloatingOverlay<'_, '_> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) {
|
) {
|
||||||
let child = layout.children().next().unwrap();
|
let child = layout.children().next().unwrap();
|
||||||
let vp = child.bounds();
|
let vp = child.bounds();
|
||||||
self.popup.as_widget_mut().update(
|
self.popup.as_widget_mut().update(
|
||||||
self.tree, event, child, cursor, renderer, clipboard, shell, &vp,
|
self.tree, event, child, cursor, renderer, shell, &vp,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ impl CommandLine {
|
||||||
.on_press(Message::CommandOptionPick(opt.keyword.clone()))
|
.on_press(Message::CommandOptionPick(opt.keyword.clone()))
|
||||||
.padding([1, 6])
|
.padding([1, 6])
|
||||||
.style(|theme: &Theme, status| {
|
.style(|theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if matches!(
|
let pair = if matches!(
|
||||||
status,
|
status,
|
||||||
button::Status::Hovered | button::Status::Pressed
|
button::Status::Hovered | button::Status::Pressed
|
||||||
|
|
@ -431,7 +431,7 @@ impl CommandLine {
|
||||||
});
|
});
|
||||||
let prompt = container(
|
let prompt = container(
|
||||||
text("Command:").size(11).style(|theme: &Theme| iced::widget::text::Style {
|
text("Command:").size(11).style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().success.base.color),
|
color: Some(theme.palette().success.base.color),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
@ -445,7 +445,7 @@ impl CommandLine {
|
||||||
.on_press(Message::CommandLiteralToggle)
|
.on_press(Message::CommandLiteralToggle)
|
||||||
.padding([2, 6])
|
.padding([2, 6])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if literal_active {
|
let pair = if literal_active {
|
||||||
palette.primary.weak
|
palette.primary.weak
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
|
|
@ -508,7 +508,7 @@ impl CommandLine {
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.padding([2, 8])
|
.padding([2, 8])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if is_selected {
|
let pair = if is_selected {
|
||||||
palette.primary.weak
|
palette.primary.weak
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
|
|
@ -567,9 +567,9 @@ impl CommandLine {
|
||||||
.on_action(Message::CommandHistoryEdit)
|
.on_action(Message::CommandHistoryEdit)
|
||||||
.size(11)
|
.size(11)
|
||||||
.padding([2, 8])
|
.padding([2, 8])
|
||||||
.max_height(180.0)
|
.height(Length::Fit.max(180.0))
|
||||||
.style(|theme: &Theme, _status| {
|
.style(|theme: &Theme, _status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
text_editor::Style {
|
text_editor::Style {
|
||||||
background: Background::Color(palette.background.base.color),
|
background: Background::Color(palette.background.base.color),
|
||||||
border: Border::default(),
|
border: Border::default(),
|
||||||
|
|
@ -625,7 +625,7 @@ impl CommandLine {
|
||||||
container(history_rows)
|
container(history_rows)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -646,7 +646,7 @@ impl CommandLine {
|
||||||
history_divider,
|
history_divider,
|
||||||
container(input_row)
|
container(input_row)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weakest.color)),
|
background: Some(Background::Color(palette.background.weakest.color)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -658,7 +658,7 @@ impl CommandLine {
|
||||||
.center_y(Length::Fixed(30.0)),
|
.center_y(Length::Fixed(30.0)),
|
||||||
])
|
])
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -669,8 +669,7 @@ impl CommandLine {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Length::Fill)
|
.width(Length::Fill.max(720.0))
|
||||||
.max_width(720.0)
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -733,7 +732,7 @@ pub fn ranked_matches(
|
||||||
/// Flat button style for the history dropdown's Copy / Clear strip: a subtle
|
/// Flat button style for the history dropdown's Copy / Clear strip: a subtle
|
||||||
/// filled pill that brightens on hover.
|
/// filled pill that brightens on hover.
|
||||||
fn header_btn_style(theme: &Theme, status: button::Status) -> button::Style {
|
fn header_btn_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
let pair = if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
||||||
palette.background.weak
|
palette.background.weak
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -752,7 +751,7 @@ fn header_btn_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn history_color(theme: &Theme, kind: &EntryKind) -> Color {
|
fn history_color(theme: &Theme, kind: &EntryKind) -> Color {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
match kind {
|
match kind {
|
||||||
EntryKind::Command => palette.background.base.text,
|
EntryKind::Command => palette.background.base.text,
|
||||||
EntryKind::Output => palette.background.base.text.scale_alpha(0.72),
|
EntryKind::Output => palette.background.base.text.scale_alpha(0.72),
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ pub const SAVE: &[u8] = include_bytes!("../../assets/icons/ui/save.svg");
|
||||||
pub const FILE_EXPORT: &[u8] = include_bytes!("../../assets/icons/ui/file_export.svg");
|
pub const FILE_EXPORT: &[u8] = include_bytes!("../../assets/icons/ui/file_export.svg");
|
||||||
pub const PRINT: &[u8] = include_bytes!("../../assets/icons/ui/print.svg");
|
pub const PRINT: &[u8] = include_bytes!("../../assets/icons/ui/print.svg");
|
||||||
pub const HEART: &[u8] = include_bytes!("../../assets/icons/ui/heart.svg");
|
pub const HEART: &[u8] = include_bytes!("../../assets/icons/ui/heart.svg");
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
pub const GEAR: &[u8] = include_bytes!("../../assets/icons/ui/gear.svg");
|
||||||
pub const DOT: &[u8] = include_bytes!("../../assets/icons/ui/dot.svg");
|
pub const DOT: &[u8] = include_bytes!("../../assets/icons/ui/dot.svg");
|
||||||
pub const DIRTY_DOT: &[u8] = include_bytes!("../../assets/icons/ui/dirty_dot.svg");
|
pub const DIRTY_DOT: &[u8] = include_bytes!("../../assets/icons/ui/dirty_dot.svg");
|
||||||
pub const ARROW_LONG_RIGHT: &[u8] = include_bytes!("../../assets/icons/ui/arrow_long_right.svg");
|
pub const ARROW_LONG_RIGHT: &[u8] = include_bytes!("../../assets/icons/ui/arrow_long_right.svg");
|
||||||
|
|
@ -130,7 +132,7 @@ struct SemanticColors {
|
||||||
|
|
||||||
impl SemanticColors {
|
impl SemanticColors {
|
||||||
fn from_theme(theme: &Theme) -> Self {
|
fn from_theme(theme: &Theme) -> Self {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
Self {
|
Self {
|
||||||
background: color_hex(palette.background.strong.color),
|
background: color_hex(palette.background.strong.color),
|
||||||
text: color_hex(palette.background.base.text),
|
text: color_hex(palette.background.base.text),
|
||||||
|
|
@ -257,12 +259,12 @@ fn semantic_handle(bytes: &'static [u8], theme: &Theme) -> svg::Handle {
|
||||||
fn palette_key(theme: &Theme) -> [[u8; 4]; 6] {
|
fn palette_key(theme: &Theme) -> [[u8; 4]; 6] {
|
||||||
let palette = theme.palette();
|
let palette = theme.palette();
|
||||||
[
|
[
|
||||||
palette.background.into_rgba8(),
|
palette.background.base.color.into_rgba8(),
|
||||||
palette.text.into_rgba8(),
|
palette.background.base.text.into_rgba8(),
|
||||||
palette.primary.into_rgba8(),
|
palette.primary.base.color.into_rgba8(),
|
||||||
palette.success.into_rgba8(),
|
palette.success.base.color.into_rgba8(),
|
||||||
palette.warning.into_rgba8(),
|
palette.warning.base.color.into_rgba8(),
|
||||||
palette.danger.into_rgba8(),
|
palette.danger.base.color.into_rgba8(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -395,7 +397,7 @@ pub fn themed<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'a, M> {
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text),
|
color: Some(theme.palette().background.base.text),
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -408,7 +410,7 @@ pub fn themed_secondary<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(
|
color: Some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -426,7 +428,7 @@ pub fn themed_disabled<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'a
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(
|
color: Some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -442,7 +444,7 @@ pub fn themed_primary<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'a,
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -453,7 +455,7 @@ pub fn themed_success<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'a,
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(theme.extended_palette().success.base.color),
|
color: Some(theme.palette().success.base.color),
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -464,7 +466,7 @@ pub fn themed_warning<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'a,
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(theme.extended_palette().warning.base.color),
|
color: Some(theme.palette().warning.base.color),
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -475,7 +477,7 @@ pub fn themed_danger<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element<'a,
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(theme.extended_palette().danger.base.color),
|
color: Some(theme.palette().danger.base.color),
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -486,7 +488,7 @@ pub fn themed_danger_text<'a, M: 'a>(bytes: &'static [u8], size: f32) -> Element
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)
|
.height(size)
|
||||||
.style(|theme: &Theme, _| svg::Style {
|
.style(|theme: &Theme, _| svg::Style {
|
||||||
color: Some(theme.extended_palette().danger.base.text),
|
color: Some(theme.palette().danger.base.text),
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,23 @@
|
||||||
/// Change this to scale the ribbon, layer manager rows, and property panel rows uniformly.
|
/// Change this to scale the ribbon, layer manager rows, and property panel rows uniformly.
|
||||||
pub const ROW_H: f32 = 26.0;
|
pub const ROW_H: f32 = 26.0;
|
||||||
|
|
||||||
|
/// Iced 0.15 separates pick-list construction from the selection callback.
|
||||||
|
/// Keep the application's established call shape while the rest of the UI
|
||||||
|
/// migrates independently.
|
||||||
|
pub fn pick_list<'a, T, L, V, Message>(
|
||||||
|
options: L,
|
||||||
|
selected: Option<V>,
|
||||||
|
on_select: impl Fn(T) -> Message + 'a,
|
||||||
|
) -> iced::widget::PickList<'a, T, L, V, Message>
|
||||||
|
where
|
||||||
|
T: PartialEq + Clone + ToString + 'a,
|
||||||
|
L: std::borrow::Borrow<[T]> + 'a,
|
||||||
|
V: std::borrow::Borrow<T> + 'a,
|
||||||
|
Message: Clone + 'a,
|
||||||
|
{
|
||||||
|
iced::widget::pick_list(selected, options, |value| value.to_string()).on_select(on_select)
|
||||||
|
}
|
||||||
|
|
||||||
/// Place `content` at fixed top-left coordinates inside a fill-sized layer.
|
/// Place `content` at fixed top-left coordinates inside a fill-sized layer.
|
||||||
/// Negative coordinates clamp to the layer edge.
|
/// Negative coordinates clamp to the layer edge.
|
||||||
pub fn pin_at<'a, Message: 'a>(
|
pub fn pin_at<'a, Message: 'a>(
|
||||||
|
|
|
||||||
371
src/ui/modal.rs
371
src/ui/modal.rs
|
|
@ -6,106 +6,324 @@
|
||||||
//! so both stack dialogs here — one code path for every platform.
|
//! so both stack dialogs here — one code path for every platform.
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{button, column, container, mouse_area, opaque, row, stack};
|
use iced::advanced::layout::{self, Layout};
|
||||||
use iced::{Background, Border, Element, Length, Padding, Theme, Vector};
|
use iced::advanced::widget::{self, Widget};
|
||||||
|
use iced::advanced::{mouse, overlay, renderer, Shell};
|
||||||
|
use iced::widget::{button, column, container, mouse_area, opaque, row, stack, Space};
|
||||||
|
use iced::{
|
||||||
|
Background, Border, Element, Event, Length, Padding, Rectangle, Renderer, Size, Theme, Vector,
|
||||||
|
};
|
||||||
|
|
||||||
/// Stack `content` over `base` behind a dimmed backdrop, framed with a
|
#[derive(Debug, Clone, Copy)]
|
||||||
/// draggable title bar (the ✕ close button at its right end). The backdrop only
|
pub struct ModalOptions {
|
||||||
/// dims and blocks clicks from reaching the view beneath — it does **not**
|
movable: bool,
|
||||||
/// dismiss the dialog; closing is the ✕ button alone (`on_close`).
|
resizable: bool,
|
||||||
|
neutral_close: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sizing used inside an intrinsically measured modal.
|
||||||
|
///
|
||||||
|
/// [`INTRINSIC`](Self::INTRINSIC) lets each widget report the most space it can
|
||||||
|
/// use, while [`FILL`](Self::FILL) distributes the resulting shared frame to
|
||||||
|
/// sibling toolbars, panes and scroll areas.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct ModalSizing {
|
||||||
|
pub width: Length,
|
||||||
|
pub height: Length,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModalSizing {
|
||||||
|
pub const INTRINSIC: Self = Self {
|
||||||
|
width: Length::Fluid(iced_core::length::Constraint::Max),
|
||||||
|
height: Length::Fluid(iced_core::length::Constraint::Max),
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const FILL: Self = Self {
|
||||||
|
width: Length::Fill,
|
||||||
|
height: Length::Fill,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn from_resize(_resize: Vector) -> Self {
|
||||||
|
Self::FILL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Measure an intrinsic copy of `content`, then lay the fill copy out in the
|
||||||
|
/// resulting shared frame. `extra` grows that frame when the resize handle is
|
||||||
|
/// dragged; `max` only caps the initial intrinsic pass.
|
||||||
|
pub fn intrinsic<'a>(
|
||||||
|
measurement: impl Into<Element<'a, Message>>,
|
||||||
|
content: impl Into<Element<'a, Message>>,
|
||||||
|
max: Size,
|
||||||
|
extra: Vector,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
|
Element::new(Intrinsic {
|
||||||
|
children: [measurement.into(), content.into()],
|
||||||
|
max,
|
||||||
|
extra,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Intrinsic<'a> {
|
||||||
|
children: [Element<'a, Message>; 2],
|
||||||
|
max: Size,
|
||||||
|
extra: Vector,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Widget<Message, Theme, Renderer> for Intrinsic<'_> {
|
||||||
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
|
tree.diff_children(&mut self.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> Size<Length> {
|
||||||
|
Size::new(
|
||||||
|
Length::Fit.max(self.max.width + self.extra.x),
|
||||||
|
Length::Fit.max(self.max.height + self.extra.y),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&mut self,
|
||||||
|
tree: &mut widget::Tree,
|
||||||
|
renderer: &Renderer,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> layout::Node {
|
||||||
|
let measure_max = Size::new(
|
||||||
|
self.max.width.min(limits.max().width),
|
||||||
|
self.max.height.min(limits.max().height),
|
||||||
|
);
|
||||||
|
let measure_limits = layout::Limits::new(Size::ZERO, measure_max);
|
||||||
|
let measured = self.children[0]
|
||||||
|
.as_widget_mut()
|
||||||
|
.layout(&mut tree.children[0], renderer, &measure_limits);
|
||||||
|
let size = Size::new(
|
||||||
|
(measured.size().width + self.extra.x).min(limits.max().width),
|
||||||
|
(measured.size().height + self.extra.y).min(limits.max().height),
|
||||||
|
);
|
||||||
|
let final_limits = layout::Limits::new(size, size);
|
||||||
|
let content = self.children[1]
|
||||||
|
.as_widget_mut()
|
||||||
|
.layout(&mut tree.children[1], renderer, &final_limits);
|
||||||
|
|
||||||
|
layout::Node::with_children(size, vec![measured, content])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn operate(
|
||||||
|
&mut self,
|
||||||
|
tree: &mut widget::Tree,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
renderer: &Renderer,
|
||||||
|
operation: &mut dyn widget::Operation,
|
||||||
|
) {
|
||||||
|
self.children[1]
|
||||||
|
.as_widget_mut()
|
||||||
|
.operate(&mut tree.children[1], layout.child(1), renderer, operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
tree: &mut widget::Tree,
|
||||||
|
event: &Event,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
renderer: &Renderer,
|
||||||
|
shell: &mut Shell<'_, Message>,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
) {
|
||||||
|
self.children[1].as_widget_mut().update(
|
||||||
|
&mut tree.children[1],
|
||||||
|
event,
|
||||||
|
layout.child(1),
|
||||||
|
cursor,
|
||||||
|
renderer,
|
||||||
|
shell,
|
||||||
|
viewport,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
tree: &widget::Tree,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
renderer: &Renderer,
|
||||||
|
) -> mouse::Interaction {
|
||||||
|
self.children[1]
|
||||||
|
.as_widget()
|
||||||
|
.mouse_interaction(
|
||||||
|
&tree.children[1],
|
||||||
|
layout.child(1),
|
||||||
|
cursor,
|
||||||
|
viewport,
|
||||||
|
renderer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
tree: &widget::Tree,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
theme: &Theme,
|
||||||
|
style: &renderer::Style,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
) {
|
||||||
|
self.children[1]
|
||||||
|
.as_widget()
|
||||||
|
.draw(
|
||||||
|
&tree.children[1],
|
||||||
|
renderer,
|
||||||
|
theme,
|
||||||
|
style,
|
||||||
|
layout.child(1),
|
||||||
|
cursor,
|
||||||
|
viewport,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlay<'b>(
|
||||||
|
&'b mut self,
|
||||||
|
tree: &'b mut widget::Tree,
|
||||||
|
layout: Layout<'b>,
|
||||||
|
renderer: &Renderer,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
translation: Vector,
|
||||||
|
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||||
|
self.children[1]
|
||||||
|
.as_widget_mut()
|
||||||
|
.overlay(
|
||||||
|
&mut tree.children[1],
|
||||||
|
layout.child(1),
|
||||||
|
renderer,
|
||||||
|
viewport,
|
||||||
|
translation,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModalOptions {
|
||||||
|
pub const STANDARD: Self = Self {
|
||||||
|
movable: true,
|
||||||
|
resizable: true,
|
||||||
|
neutral_close: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MOVABLE_FIXED: Self = Self {
|
||||||
|
movable: true,
|
||||||
|
resizable: false,
|
||||||
|
neutral_close: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const NOTICE: Self = Self {
|
||||||
|
movable: true,
|
||||||
|
resizable: false,
|
||||||
|
neutral_close: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stack `content` over `base` behind a dimmed backdrop, framed with a title bar
|
||||||
|
/// (the ✕ close button at its right end). The backdrop only dims and blocks
|
||||||
|
/// clicks from reaching the view beneath — it does **not** dismiss the dialog;
|
||||||
|
/// closing is the ✕ button alone (`on_close`).
|
||||||
///
|
///
|
||||||
/// `offset` shifts the dialog from screen-centre so it can be dragged by its
|
/// `offset` shifts the dialog from screen-centre so it can be dragged by its
|
||||||
/// title bar; pass `Vector::ZERO` to keep it centred.
|
/// title bar; pass `Vector::ZERO` to keep it centred.
|
||||||
pub fn modal<'a>(
|
pub fn modal<'a>(
|
||||||
base: impl Into<Element<'a, Message>>,
|
base: impl Into<Element<'a, Message>>,
|
||||||
title: &'a str,
|
title: &'a str,
|
||||||
title_width: f32,
|
|
||||||
content: impl Into<Element<'a, Message>>,
|
content: impl Into<Element<'a, Message>>,
|
||||||
on_close: Message,
|
on_close: Message,
|
||||||
offset: Vector,
|
offset: Vector,
|
||||||
resizable: bool,
|
options: ModalOptions,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let close = button(crate::ui::icons::themed_danger(
|
let close = if options.neutral_close {
|
||||||
crate::ui::icons::CLOSE,
|
button(crate::ui::icons::themed_secondary(
|
||||||
13.0,
|
crate::ui::icons::CLOSE,
|
||||||
))
|
13.0,
|
||||||
.on_press(on_close)
|
))
|
||||||
.padding([1, 7])
|
.on_press(on_close)
|
||||||
.style(close_style);
|
.padding([1, 7])
|
||||||
|
.style(neutral_close_style)
|
||||||
|
} else {
|
||||||
|
button(crate::ui::icons::themed_danger(
|
||||||
|
crate::ui::icons::CLOSE,
|
||||||
|
13.0,
|
||||||
|
))
|
||||||
|
.on_press(on_close)
|
||||||
|
.padding([1, 7])
|
||||||
|
.style(close_style)
|
||||||
|
};
|
||||||
|
|
||||||
// Draggable title bar: a grip handle next to the ✕. Kept `Shrink` (no
|
// The dialog name is centred across the content width with the ✕ overlaid
|
||||||
// `Fill`) so a single Fill child can't blow the dialog out to the full
|
// at the right edge. The title bar is itself an overlay: the content layer
|
||||||
// screen width — the dialog stays sized to its content. Pressing the grip
|
// below determines the intrinsic modal width before `Fill` is resolved.
|
||||||
// starts a drag (handled in `update`).
|
|
||||||
let grip = mouse_area(
|
|
||||||
container(crate::ui::icons::themed_primary(crate::ui::icons::MOVE, 14.0))
|
|
||||||
.padding([1, 7])
|
|
||||||
.style(|theme: &Theme| container::Style {
|
|
||||||
background: Some(Background::Color(
|
|
||||||
theme.extended_palette().background.weakest.color,
|
|
||||||
)),
|
|
||||||
border: Border {
|
|
||||||
radius: 4.0.into(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.on_press(Message::ModalGrab)
|
|
||||||
.interaction(iced::mouse::Interaction::Grab);
|
|
||||||
|
|
||||||
// The dialog name is centred across the dialog width with the grip + ✕
|
|
||||||
// overlaid at the right edge. The bar takes an explicit `title_width`
|
|
||||||
// (the caller's content width) instead of `Fill` — a Fill child inside
|
|
||||||
// the Shrink frame would blow the dialog out to the full screen.
|
|
||||||
let title_text = iced::widget::text(title).size(15);
|
let title_text = iced::widget::text(title).size(15);
|
||||||
|
let title_surface: Element<'a, Message> = container(title_text)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fixed(24.0))
|
||||||
|
.align_x(iced::alignment::Horizontal::Center)
|
||||||
|
.align_y(iced::alignment::Vertical::Center)
|
||||||
|
.into();
|
||||||
|
let title_surface: Element<'a, Message> = if options.movable {
|
||||||
|
mouse_area(title_surface)
|
||||||
|
.on_press(Message::ModalGrab)
|
||||||
|
.interaction(iced::mouse::Interaction::Grab)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
title_surface
|
||||||
|
};
|
||||||
|
let controls: Element<'a, Message> = row![close].align_y(iced::Center).into();
|
||||||
let title_bar = stack![
|
let title_bar = stack![
|
||||||
container(title_text)
|
title_surface,
|
||||||
.width(Length::Fixed(title_width))
|
container(controls)
|
||||||
.height(Length::Fixed(24.0))
|
.width(Length::Fill)
|
||||||
.align_x(iced::alignment::Horizontal::Center)
|
|
||||||
.align_y(iced::alignment::Vertical::Center),
|
|
||||||
container(row![grip, close].spacing(6).align_y(iced::Center))
|
|
||||||
.width(Length::Fixed(title_width))
|
|
||||||
.height(Length::Fixed(24.0))
|
.height(Length::Fixed(24.0))
|
||||||
.align_x(iced::alignment::Horizontal::Right)
|
.align_x(iced::alignment::Horizontal::Right)
|
||||||
.align_y(iced::alignment::Vertical::Center),
|
.align_y(iced::alignment::Vertical::Center),
|
||||||
];
|
]
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fixed(24.0));
|
||||||
|
|
||||||
let panel_style = |theme: &Theme| container::Style {
|
let panel_style = |theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 6.0.into(),
|
radius: 6.0.into(),
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
// The dialog is always sized to its content (the caller fixes the content's
|
// The first stack layer dictates its intrinsic size. Its top spacer reserves
|
||||||
// width/height, growing it by the shared resize delta). When `resizable`, a
|
// room for the title, while the actual title bar and resize grip overlay it
|
||||||
// corner grip is appended bottom-right; dragging it drives `ModalResizeGrab`
|
// without influencing the modal dimensions.
|
||||||
// + the shared drag move/release, which bumps that delta. The title bar sits
|
let body_base = column![
|
||||||
// top-right above the content either way (`align_x(Right)`).
|
Space::new().height(Length::Fixed(24.0)),
|
||||||
let body = if resizable {
|
content.into(),
|
||||||
|
]
|
||||||
|
.spacing(6);
|
||||||
|
let mut body = stack![body_base, title_bar];
|
||||||
|
if options.resizable {
|
||||||
let resize = mouse_area(
|
let resize = mouse_area(
|
||||||
container(crate::ui::icons::themed_primary(crate::ui::icons::RESIZE, 15.0))
|
container(crate::ui::icons::themed_primary(crate::ui::icons::RESIZE, 15.0))
|
||||||
.padding([0, 2]),
|
.padding([0, 2]),
|
||||||
)
|
)
|
||||||
.on_press(Message::ModalResizeGrab)
|
.on_press(Message::ModalResizeGrab)
|
||||||
.interaction(iced::mouse::Interaction::Grab);
|
.interaction(iced::mouse::Interaction::Grab);
|
||||||
column![title_bar, content.into(), resize]
|
body = body.push(
|
||||||
} else {
|
container(resize)
|
||||||
column![title_bar, content.into()]
|
.width(Length::Fill)
|
||||||
};
|
.height(Length::Fill)
|
||||||
let framed: Element<'a, Message> = container(
|
.align_x(iced::alignment::Horizontal::Right)
|
||||||
body.spacing(6).align_x(iced::alignment::Horizontal::Right),
|
.align_y(iced::alignment::Vertical::Bottom),
|
||||||
)
|
);
|
||||||
.padding(10)
|
}
|
||||||
.style(panel_style)
|
let framed: Element<'a, Message> =
|
||||||
.into();
|
container(body).padding(10).style(panel_style).into();
|
||||||
|
|
||||||
// Position via asymmetric padding (padding is non-negative): shifting a
|
// Position via asymmetric padding (padding is non-negative): shifting a
|
||||||
// centred box by `d` on an axis needs (near − far) padding = 2·d there.
|
// centred box by `d` on an axis needs (near − far) padding = 2·d there.
|
||||||
|
|
@ -126,7 +344,7 @@ pub fn modal<'a>(
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.strongest
|
.strongest
|
||||||
.color
|
.color
|
||||||
|
|
@ -148,7 +366,7 @@ pub fn modal<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_style(theme: &Theme, status: button::Status) -> button::Style {
|
fn close_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => palette.danger.strong,
|
button::Status::Hovered | button::Status::Pressed => palette.danger.strong,
|
||||||
_ => palette.background.weakest,
|
_ => palette.background.weakest,
|
||||||
|
|
@ -163,3 +381,20 @@ fn close_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn neutral_close_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
|
let palette = theme.palette();
|
||||||
|
let pair = match status {
|
||||||
|
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
||||||
|
_ => palette.background.weakest,
|
||||||
|
};
|
||||||
|
button::Style {
|
||||||
|
background: Some(Background::Color(pair.color)),
|
||||||
|
text_color: pair.text,
|
||||||
|
border: Border {
|
||||||
|
radius: 4.0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -332,9 +332,9 @@ fn draw_grip_marker(frame: &mut canvas::Frame, grip: &GripMarker, theme: &Theme)
|
||||||
};
|
};
|
||||||
|
|
||||||
if grip.is_hot {
|
if grip.is_hot {
|
||||||
frame.fill(&path, theme.extended_palette().danger.base.color);
|
frame.fill(&path, theme.palette().danger.base.color);
|
||||||
} else {
|
} else {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let color = palette.primary.base.color;
|
let color = palette.primary.base.color;
|
||||||
frame.fill(
|
frame.fill(
|
||||||
&path,
|
&path,
|
||||||
|
|
@ -435,7 +435,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
// Filled bars in the pane_grid spacing gaps, so adjacent panes read as
|
// Filled bars in the pane_grid spacing gaps, so adjacent panes read as
|
||||||
// distinct viewports. Drawn first so all other overlays sit on top.
|
// distinct viewports. Drawn first so all other overlays sit on top.
|
||||||
if !self.dividers.is_empty() {
|
if !self.dividers.is_empty() {
|
||||||
let divider = theme.extended_palette().background.neutral.color;
|
let divider = theme.palette().background.neutral.color;
|
||||||
for d in &self.dividers {
|
for d in &self.dividers {
|
||||||
let bar = canvas::Path::rectangle(
|
let bar = canvas::Path::rectangle(
|
||||||
Point::new(d.x, d.y),
|
Point::new(d.x, d.y),
|
||||||
|
|
@ -450,13 +450,13 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
// under the cursor, and drag a translucent ghost card along the cursor
|
// under the cursor, and drag a translucent ghost card along the cursor
|
||||||
// so the pane is visibly "moving".
|
// so the pane is visibly "moving".
|
||||||
if let Some(src) = self.pane_move_rect {
|
if let Some(src) = self.pane_move_rect {
|
||||||
let accent = theme.extended_palette().primary.base.color;
|
let accent = theme.palette().primary.base.color;
|
||||||
// Source pane: dimmed + dashed-feel outline (it has been lifted).
|
// Source pane: dimmed + dashed-feel outline (it has been lifted).
|
||||||
let src_path =
|
let src_path =
|
||||||
canvas::Path::rectangle(Point::new(src.x, src.y), iced::Size::new(src.width, src.height));
|
canvas::Path::rectangle(Point::new(src.x, src.y), iced::Size::new(src.width, src.height));
|
||||||
frame.fill(
|
frame.fill(
|
||||||
&src_path,
|
&src_path,
|
||||||
theme.extended_palette().background.strong.color.scale_alpha(0.28),
|
theme.palette().background.strong.color.scale_alpha(0.28),
|
||||||
);
|
);
|
||||||
frame.stroke(
|
frame.stroke(
|
||||||
&src_path,
|
&src_path,
|
||||||
|
|
@ -515,9 +515,9 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
) {
|
) {
|
||||||
let base = if crossing {
|
let base = if crossing {
|
||||||
theme.extended_palette().success.base.color
|
theme.palette().success.base.color
|
||||||
} else {
|
} else {
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
};
|
};
|
||||||
let fill = base.scale_alpha(0.12);
|
let fill = base.scale_alpha(0.12);
|
||||||
let stroke = base.scale_alpha(0.9);
|
let stroke = base.scale_alpha(0.9);
|
||||||
|
|
@ -547,9 +547,9 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
|
|
||||||
if self.selection.poly_active && self.selection.poly_points.len() > 1 {
|
if self.selection.poly_active && self.selection.poly_points.len() > 1 {
|
||||||
let base = if self.selection.poly_crossing {
|
let base = if self.selection.poly_crossing {
|
||||||
theme.extended_palette().success.base.color
|
theme.palette().success.base.color
|
||||||
} else {
|
} else {
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
};
|
};
|
||||||
let fill = base.scale_alpha(0.12);
|
let fill = base.scale_alpha(0.12);
|
||||||
let stroke = base.scale_alpha(0.9);
|
let stroke = base.scale_alpha(0.9);
|
||||||
|
|
@ -909,7 +909,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
if !over_viewcube && !over_divider && !self.pan_mode && !self.suppressed {
|
if !over_viewcube && !over_divider && !self.pan_mode && !self.suppressed {
|
||||||
if let Some(cp) = self.selection.last_move_pos {
|
if let Some(cp) = self.selection.last_move_pos {
|
||||||
let color = theme
|
let color = theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -956,7 +956,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
// the hovered object sits on a locked layer (issue: locked
|
// the hovered object sits on a locked layer (issue: locked
|
||||||
// objects are visible + snappable but not selectable/editable).
|
// objects are visible + snappable but not selectable/editable).
|
||||||
if self.hover_locked {
|
if self.hover_locked {
|
||||||
let warning = theme.extended_palette().warning.base;
|
let warning = theme.palette().warning.base;
|
||||||
let amber = warning.color.scale_alpha(0.98);
|
let amber = warning.color.scale_alpha(0.98);
|
||||||
let dark = warning.text;
|
let dark = warning.text;
|
||||||
let bx = cp.x + sq + 7.0;
|
let bx = cp.x + sq + 7.0;
|
||||||
|
|
@ -1005,7 +1005,7 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Object Snap Tracking ─────────────────────────────────────────────
|
// ── Object Snap Tracking ─────────────────────────────────────────────
|
||||||
let track_color = theme.extended_palette().primary.base.color.scale_alpha(0.7);
|
let track_color = theme.palette().primary.base.color.scale_alpha(0.7);
|
||||||
// The alignment line the cursor is currently locked to — drawn at its
|
// The alignment line the cursor is currently locked to — drawn at its
|
||||||
// real angle from the acquired point through the lock and a little
|
// real angle from the acquired point through the lock and a little
|
||||||
// beyond, dashed so it reads as a construction guide. This covers the
|
// beyond, dashed so it reads as a construction guide. This covers the
|
||||||
|
|
@ -2110,7 +2110,7 @@ impl DynInputCanvas {
|
||||||
canvas::Stroke {
|
canvas::Stroke {
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
style: canvas::Style::Solid(
|
style: canvas::Style::Solid(
|
||||||
theme.extended_palette().background.neutral.color.scale_alpha(0.9)
|
theme.palette().background.neutral.color.scale_alpha(0.9)
|
||||||
),
|
),
|
||||||
line_dash: canvas::LineDash { segments: &[2.0, 3.0], offset: 0 },
|
line_dash: canvas::LineDash { segments: &[2.0, 3.0], offset: 0 },
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -2161,7 +2161,7 @@ impl DynInputCanvas {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn box_colors(b: &DynBox, theme: &Theme) -> (Color, Color, Color) {
|
fn box_colors(b: &DynBox, theme: &Theme) -> (Color, Color, Color) {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
if b.active {
|
if b.active {
|
||||||
(
|
(
|
||||||
palette.primary.weak.color,
|
palette.primary.weak.color,
|
||||||
|
|
@ -2188,7 +2188,7 @@ impl DynInputCanvas {
|
||||||
if self.prompt.is_empty() {
|
if self.prompt.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pw = (self.prompt.len() as f32 * DYN_CHAR_W) + DYN_PAD * 2.0;
|
let pw = (self.prompt.len() as f32 * DYN_CHAR_W) + DYN_PAD * 2.0;
|
||||||
let rect = canvas::Path::rectangle(pos, Size { width: pw, height: DYN_BOX_H });
|
let rect = canvas::Path::rectangle(pos, Size { width: pw, height: DYN_BOX_H });
|
||||||
frame.fill(&rect, palette.background.strong.color);
|
frame.fill(&rect, palette.background.strong.color);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ pub fn menu_entries(
|
||||||
let divider = container(iced::widget::Space::new().height(1))
|
let divider = container(iced::widget::Space::new().height(1))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color,
|
theme.palette().background.weak.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -83,7 +83,7 @@ fn empty_row() -> Element<'static, Message> {
|
||||||
text("No objects").size(11).style(|theme: &Theme| text::Style {
|
text("No objects").size(11).style(|theme: &Theme| text::Style {
|
||||||
color: Some(
|
color: Some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub fn menu_entries<'a>(snapper: &'a Snapper) -> Vec<Entry<'a>> {
|
||||||
let divider = container(iced::widget::Space::new().height(1))
|
let divider = container(iced::widget::Space::new().height(1))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color,
|
theme.palette().background.weak.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ impl canvas::Program<Message> for HatchPatternPreview {
|
||||||
use crate::scene::model::hatch_model::{HatchModel, HatchPattern};
|
use crate::scene::model::hatch_model::{HatchModel, HatchPattern};
|
||||||
|
|
||||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pad = 4.0;
|
let pad = 4.0;
|
||||||
let sample = canvas::Path::rectangle(
|
let sample = canvas::Path::rectangle(
|
||||||
Point::new(pad, pad),
|
Point::new(pad, pad),
|
||||||
|
|
@ -342,7 +342,7 @@ impl PropertiesPanel {
|
||||||
let header = container(text("Properties").size(12))
|
let header = container(text("Properties").size(12))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color,
|
theme.palette().background.weak.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -372,7 +372,7 @@ impl PropertiesPanel {
|
||||||
|
|
||||||
let title_bar = container(title_content)
|
let title_bar = container(title_content)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weakest.color)),
|
background: Some(Background::Color(palette.background.weakest.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -405,7 +405,7 @@ impl PropertiesPanel {
|
||||||
|
|
||||||
container(column![header, title_bar, content])
|
container(column![header, title_bar, content])
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -434,7 +434,7 @@ impl PropertiesPanel {
|
||||||
.style(muted_text_style),
|
.style(muted_text_style),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weakest.color)),
|
background: Some(Background::Color(palette.background.weakest.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -456,7 +456,7 @@ impl PropertiesPanel {
|
||||||
Some(
|
Some(
|
||||||
container(col)
|
container(col)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -478,7 +478,7 @@ impl PropertiesPanel {
|
||||||
// Section header
|
// Section header
|
||||||
let hdr = container(text(§ion.title).size(10))
|
let hdr = container(text(§ion.title).size(10))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -665,7 +665,7 @@ impl PropertiesPanel {
|
||||||
row![
|
row![
|
||||||
container(text("?").size(10))
|
container(text("?").size(10))
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.strong.color)),
|
background: Some(Background::Color(palette.background.strong.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -896,7 +896,7 @@ impl PropertiesPanel {
|
||||||
)
|
)
|
||||||
.on_press(Message::PropEditChoiceToggle)
|
.on_press(Message::PropEditChoiceToggle)
|
||||||
.style(|theme: &Theme, status| {
|
.style(|theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
||||||
_ => palette.background.base,
|
_ => palette.background.base,
|
||||||
|
|
@ -917,7 +917,7 @@ impl PropertiesPanel {
|
||||||
.height(Length::Fixed(ROW_H - 6.0));
|
.height(Length::Fixed(ROW_H - 6.0));
|
||||||
let head = container(row![input, caret].align_y(iced::Center))
|
let head = container(row![input, caret].align_y(iced::Center))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -956,7 +956,7 @@ impl PropertiesPanel {
|
||||||
.style(container::bordered_box)
|
.style(container::bordered_box)
|
||||||
.padding(2)
|
.padding(2)
|
||||||
.width(200)
|
.width(200)
|
||||||
.max_height(220.0);
|
.height(Length::Fit.max(220.0));
|
||||||
|
|
||||||
prop_row_widget(
|
prop_row_widget(
|
||||||
label,
|
label,
|
||||||
|
|
@ -1011,7 +1011,7 @@ impl PropertiesPanel {
|
||||||
)
|
)
|
||||||
.on_press(Message::PropHatchPatternPickerToggle(current.to_string()))
|
.on_press(Message::PropHatchPatternPickerToggle(current.to_string()))
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let hovered = matches!(status, button::Status::Hovered | button::Status::Pressed);
|
let hovered = matches!(status, button::Status::Hovered | button::Status::Pressed);
|
||||||
button::Style {
|
button::Style {
|
||||||
background: Some(Background::Color(if hovered {
|
background: Some(Background::Color(if hovered {
|
||||||
|
|
@ -1072,7 +1072,7 @@ impl PropertiesPanel {
|
||||||
)
|
)
|
||||||
.on_press(Message::PropHatchPatternChanged(name))
|
.on_press(Message::PropHatchPatternChanged(name))
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let hovered =
|
let hovered =
|
||||||
matches!(status, button::Status::Hovered | button::Status::Pressed);
|
matches!(status, button::Status::Hovered | button::Status::Pressed);
|
||||||
let pair = if selected {
|
let pair = if selected {
|
||||||
|
|
@ -1126,7 +1126,7 @@ impl PropertiesPanel {
|
||||||
.style(container::bordered_box)
|
.style(container::bordered_box)
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.width(348)
|
.width(348)
|
||||||
.max_height(360.0);
|
.height(Length::Fit.max(360.0));
|
||||||
|
|
||||||
prop_row_widget(
|
prop_row_widget(
|
||||||
label,
|
label,
|
||||||
|
|
@ -1175,9 +1175,9 @@ pub fn color_picker_dropdown<'a>(
|
||||||
background: Some(Background::Color(bg)),
|
background: Some(Background::Color(bg)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: if matches!(status, button::Status::Hovered) {
|
color: if matches!(status, button::Status::Hovered) {
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
} else {
|
} else {
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
},
|
},
|
||||||
width: if matches!(status, button::Status::Hovered) {
|
width: if matches!(status, button::Status::Hovered) {
|
||||||
1.5
|
1.5
|
||||||
|
|
@ -1186,7 +1186,7 @@ pub fn color_picker_dropdown<'a>(
|
||||||
},
|
},
|
||||||
radius: 2.0.into(),
|
radius: 2.0.into(),
|
||||||
},
|
},
|
||||||
text_color: theme.extended_palette().background.base.text,
|
text_color: theme.palette().background.base.text,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.padding(0),
|
.padding(0),
|
||||||
|
|
@ -1222,7 +1222,7 @@ pub fn color_picker_dropdown<'a>(
|
||||||
|
|
||||||
let mut col = column![container(inner)
|
let mut col = column![container(inner)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -1258,9 +1258,9 @@ pub fn color_picker_dropdown<'a>(
|
||||||
background: Some(Background::Color(bg)),
|
background: Some(Background::Color(bg)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: if matches!(status, button::Status::Hovered) {
|
color: if matches!(status, button::Status::Hovered) {
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
} else {
|
} else {
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
},
|
},
|
||||||
width: if matches!(status, button::Status::Hovered) {
|
width: if matches!(status, button::Status::Hovered) {
|
||||||
1.5
|
1.5
|
||||||
|
|
@ -1269,7 +1269,7 @@ pub fn color_picker_dropdown<'a>(
|
||||||
},
|
},
|
||||||
radius: 1.0.into(),
|
radius: 1.0.into(),
|
||||||
},
|
},
|
||||||
text_color: theme.extended_palette().background.base.text,
|
text_color: theme.palette().background.base.text,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.padding(0),
|
.padding(0),
|
||||||
|
|
@ -1281,7 +1281,7 @@ pub fn color_picker_dropdown<'a>(
|
||||||
col = col.push(
|
col = col.push(
|
||||||
container(scrollable(rows).height(160))
|
container(scrollable(rows).height(160))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -1309,7 +1309,7 @@ fn render_stepper_row<'a>(label: &'a str, display: &'a str) -> Element<'a, Messa
|
||||||
.on_press(Message::PropVertexStep(delta))
|
.on_press(Message::PropVertexStep(delta))
|
||||||
.padding([0, 6])
|
.padding([0, 6])
|
||||||
.style(|theme: &Theme, status| {
|
.style(|theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
||||||
_ => palette.background.base,
|
_ => palette.background.base,
|
||||||
|
|
@ -1346,12 +1346,12 @@ fn render_bool_row<'a>(label: &'a str, field: &'static str, value: bool) -> Elem
|
||||||
text(btn_label)
|
text(btn_label)
|
||||||
.size(FONT_SZ)
|
.size(FONT_SZ)
|
||||||
.style(move |theme: &Theme| iced::widget::text::Style {
|
.style(move |theme: &Theme| iced::widget::text::Style {
|
||||||
color: value.then_some(theme.extended_palette().warning.base.color),
|
color: value.then_some(theme.palette().warning.base.color),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.on_press(Message::PropBoolToggle(field))
|
.on_press(Message::PropBoolToggle(field))
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
||||||
_ => palette.background.base,
|
_ => palette.background.base,
|
||||||
|
|
@ -1480,7 +1480,7 @@ fn render_group_row(
|
||||||
let label_col = container(label_btn)
|
let label_col = container(label_btn)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weakest.color,
|
theme.palette().background.weakest.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -1498,7 +1498,7 @@ fn render_group_row(
|
||||||
let value_col = container(value_field)
|
let value_col = container(value_field)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -1516,7 +1516,7 @@ fn render_group_row(
|
||||||
.height(Length::Fixed(ROW_H))
|
.height(Length::Fixed(ROW_H))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -1548,7 +1548,7 @@ fn prop_row_widget<'a>(label: &'a str, widget: Element<'a, Message>) -> Element<
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weakest.color,
|
theme.palette().background.weakest.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -1564,7 +1564,7 @@ fn prop_row_widget<'a>(label: &'a str, widget: Element<'a, Message>) -> Element<
|
||||||
let value_col = container(widget)
|
let value_col = container(widget)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -1581,7 +1581,7 @@ fn prop_row_widget<'a>(label: &'a str, widget: Element<'a, Message>) -> Element<
|
||||||
.height(Length::Fixed(ROW_H))
|
.height(Length::Fixed(ROW_H))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -1655,7 +1655,7 @@ fn aci_label(idx: u8) -> &'static str {
|
||||||
// ── Widget style helpers ──────────────────────────────────────────────────
|
// ── Widget style helpers ──────────────────────────────────────────────────
|
||||||
|
|
||||||
fn combo_btn_style(theme: &Theme, status: button::Status) -> button::Style {
|
fn combo_btn_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
button::Status::Hovered | button::Status::Pressed => palette.background.weak,
|
||||||
_ => palette.background.base,
|
_ => palette.background.base,
|
||||||
|
|
@ -1673,7 +1673,7 @@ fn combo_btn_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_input_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn text_input_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border_color = match status {
|
let border_color = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -1700,7 +1700,7 @@ fn combo_input_style(theme: &Theme, status: text_input::Status) -> text_input::S
|
||||||
/// focus highlight, so it reads as plain text, unlike the bordered editable
|
/// focus highlight, so it reads as plain text, unlike the bordered editable
|
||||||
/// fields) yet with a visible selection colour so Ctrl+C copy is discoverable.
|
/// fields) yet with a visible selection colour so Ctrl+C copy is discoverable.
|
||||||
fn ro_input_style(theme: &Theme, _status: text_input::Status) -> text_input::Style {
|
fn ro_input_style(theme: &Theme, _status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
text_input::Style {
|
text_input::Style {
|
||||||
background: Background::Color(palette.background.base.color),
|
background: Background::Color(palette.background.base.color),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -1717,13 +1717,13 @@ fn ro_input_style(theme: &Theme, _status: text_input::Status) -> text_input::Sty
|
||||||
|
|
||||||
fn muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.72)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.72)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hint_text_style(theme: &Theme) -> iced::widget::text::Style {
|
fn hint_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.48)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.48)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use iced::advanced::layout::{self, Layout};
|
use iced::advanced::layout::{self, Layout};
|
||||||
use iced::advanced::widget::{self, Widget};
|
use iced::advanced::widget::{self, Widget};
|
||||||
use iced::advanced::{mouse, overlay, renderer, Clipboard, Renderer as _, Shell};
|
use iced::advanced::{mouse, overlay, renderer, Renderer as _, Shell};
|
||||||
use iced::{
|
use iced::{
|
||||||
Background, Border, Element, Event, Length, Point, Rectangle, Renderer, Shadow, Size,
|
Background, Border, Element, Event, Length, Point, Rectangle, Renderer, Shadow, Size,
|
||||||
Theme, Vector,
|
Theme, Vector,
|
||||||
|
|
@ -184,28 +184,16 @@ impl<'a> CollapsePanels<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget<Message, Theme, Renderer> for CollapsePanels<'a> {
|
impl<'a> Widget<Message, Theme, Renderer> for CollapsePanels<'a> {
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
let mut v = Vec::with_capacity(self.panels.len() * SLOTS);
|
let mut refs = Vec::with_capacity(self.panels.len() * SLOTS);
|
||||||
for p in &self.panels {
|
for p in &mut self.panels {
|
||||||
v.push(widget::Tree::new(&p.full));
|
refs.push(&mut p.full);
|
||||||
v.push(widget::Tree::new(&p.compact));
|
refs.push(&mut p.compact);
|
||||||
v.push(widget::Tree::new(&p.button));
|
refs.push(&mut p.button);
|
||||||
v.push(widget::Tree::new(&p.tight));
|
refs.push(&mut p.tight);
|
||||||
v.push(widget::Tree::new(&p.flyout));
|
refs.push(&mut p.flyout);
|
||||||
}
|
}
|
||||||
v
|
tree.diff_children(&mut refs);
|
||||||
}
|
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
let mut refs: Vec<&dyn Widget<Message, Theme, Renderer>> = Vec::new();
|
|
||||||
for p in &self.panels {
|
|
||||||
refs.push(p.full.as_widget());
|
|
||||||
refs.push(p.compact.as_widget());
|
|
||||||
refs.push(p.button.as_widget());
|
|
||||||
refs.push(p.tight.as_widget());
|
|
||||||
refs.push(p.flyout.as_widget());
|
|
||||||
}
|
|
||||||
tree.diff_children(&refs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
|
|
@ -362,7 +350,6 @@ impl<'a> Widget<Message, Theme, Renderer> for CollapsePanels<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -376,7 +363,6 @@ impl<'a> Widget<Message, Theme, Renderer> for CollapsePanels<'a> {
|
||||||
child_layout,
|
child_layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -477,7 +463,7 @@ impl<'a> Widget<Message, Theme, Renderer> for CollapsePanels<'a> {
|
||||||
shadow: Shadow::default(),
|
shadow: Shadow::default(),
|
||||||
snap: true,
|
snap: true,
|
||||||
},
|
},
|
||||||
Background::Color(theme.extended_palette().background.neutral.color),
|
Background::Color(theme.palette().background.neutral.color),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -611,7 +597,6 @@ impl overlay::Overlay<Message, Theme, Renderer> for FlyoutOverlay<'_, '_> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) {
|
) {
|
||||||
let child = layout.children().next().unwrap();
|
let child = layout.children().next().unwrap();
|
||||||
|
|
@ -627,7 +612,7 @@ impl overlay::Overlay<Message, Theme, Renderer> for FlyoutOverlay<'_, '_> {
|
||||||
|
|
||||||
self.flyout
|
self.flyout
|
||||||
.as_widget_mut()
|
.as_widget_mut()
|
||||||
.update(self.tree, event, child, cursor, renderer, clipboard, shell, &vp);
|
.update(self.tree, event, child, cursor, renderer, shell, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(
|
fn operate(
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ impl Ribbon {
|
||||||
button(text(module.title()).size(12))
|
button(text(module.title()).size(12))
|
||||||
.on_press(Message::RibbonSelectTab(i))
|
.on_press(Message::RibbonSelectTab(i))
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let accent = if is_contextual {
|
let accent = if is_contextual {
|
||||||
palette.warning.base
|
palette.warning.base
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -470,9 +470,9 @@ impl Ribbon {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: if is_active {
|
color: if is_active {
|
||||||
if is_contextual {
|
if is_contextual {
|
||||||
theme.extended_palette().warning.base.color
|
theme.palette().warning.base.color
|
||||||
} else {
|
} else {
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Color::TRANSPARENT
|
Color::TRANSPARENT
|
||||||
|
|
@ -526,7 +526,7 @@ impl Ribbon {
|
||||||
let tab_bar = container(tab_row)
|
let tab_bar = container(tab_row)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -647,10 +647,10 @@ impl Ribbon {
|
||||||
))
|
))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weakest.color,
|
theme.palette().background.weakest.color,
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -672,10 +672,10 @@ impl Ribbon {
|
||||||
let tool_bar = container(tool_area)
|
let tool_bar = container(tool_area)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weakest.color,
|
theme.palette().background.weakest.color,
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -827,7 +827,7 @@ impl Ribbon {
|
||||||
.style(move |theme: &Theme| iced::widget::text::Style {
|
.style(move |theme: &Theme| iced::widget::text::Style {
|
||||||
color: (!is_current).then_some(
|
color: (!is_current).then_some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -895,7 +895,7 @@ impl Ribbon {
|
||||||
.style(move |theme: &Theme| container::Style {
|
.style(move |theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(lc)),
|
background: Some(Background::Color(lc)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.strong.color,
|
color: theme.palette().background.strong.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 1.0.into(),
|
radius: 1.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -924,7 +924,7 @@ impl Ribbon {
|
||||||
.style(move |theme: &Theme| iced::widget::text::Style {
|
.style(move |theme: &Theme| iced::widget::text::Style {
|
||||||
color: (!is_active).then_some(
|
color: (!is_active).then_some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -981,7 +981,7 @@ impl Ribbon {
|
||||||
.padding([3, 4])
|
.padding([3, 4])
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -1055,7 +1055,7 @@ impl Ribbon {
|
||||||
.style(move |theme: &Theme| iced::widget::text::Style {
|
.style(move |theme: &Theme| iced::widget::text::Style {
|
||||||
color: (!is_sel).then_some(
|
color: (!is_sel).then_some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -1154,7 +1154,7 @@ impl Ribbon {
|
||||||
.style(move |theme: &Theme| iced::widget::text::Style {
|
.style(move |theme: &Theme| iced::widget::text::Style {
|
||||||
color: (!is_cur).then_some(
|
color: (!is_cur).then_some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -1207,7 +1207,7 @@ impl Ribbon {
|
||||||
.style(move |theme: &Theme| iced::widget::text::Style {
|
.style(move |theme: &Theme| iced::widget::text::Style {
|
||||||
color: (!is_cur).then_some(
|
color: (!is_cur).then_some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ pub(super) fn make_icon_dim(icon: IconKind, size: f32, dim: bool) -> Element<'st
|
||||||
IconKind::Glyph(s) => text(s)
|
IconKind::Glyph(s) => text(s)
|
||||||
.size(size * 0.7)
|
.size(size * 0.7)
|
||||||
.style(|theme: &Theme| iced::widget::text::Style {
|
.style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.42)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.42)),
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
IconKind::Svg(bytes) => icons::semantic_disabled(bytes, size),
|
IconKind::Svg(bytes) => icons::semantic_disabled(bytes, size),
|
||||||
|
|
@ -179,7 +179,7 @@ pub(super) fn tool_btn_style(
|
||||||
is_active: bool,
|
is_active: bool,
|
||||||
status: button::Status,
|
status: button::Status,
|
||||||
) -> button::Style {
|
) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (is_active, status) {
|
let pair = match (is_active, status) {
|
||||||
(true, _) => palette.primary.weak,
|
(true, _) => palette.primary.weak,
|
||||||
(_, button::Status::Hovered) => palette.background.weak,
|
(_, button::Status::Hovered) => palette.background.weak,
|
||||||
|
|
@ -208,7 +208,7 @@ pub(super) fn combo_btn_style(
|
||||||
status: button::Status,
|
status: button::Status,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
) -> button::Style {
|
) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if is_open {
|
let pair = if is_open {
|
||||||
palette.primary.weak
|
palette.primary.weak
|
||||||
} else if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
} else if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
||||||
|
|
@ -233,7 +233,7 @@ pub(super) fn combo_btn_style(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn popup_row_style(theme: &Theme, status: button::Status) -> button::Style {
|
pub(super) fn popup_row_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
let pair = if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
||||||
palette.background.weak
|
palette.background.weak
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -247,7 +247,7 @@ pub(super) fn popup_row_style(theme: &Theme, status: button::Status) -> button::
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn popup_panel_style(theme: &Theme) -> container::Style {
|
pub(super) fn popup_panel_style(theme: &Theme) -> container::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -261,14 +261,14 @@ pub(super) fn popup_panel_style(theme: &Theme) -> container::Style {
|
||||||
|
|
||||||
pub(super) fn muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
pub(super) fn muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.72)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.72)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn tool_label_style(theme: &Theme, dim: bool) -> iced::widget::text::Style {
|
pub(super) fn tool_label_style(theme: &Theme, dim: bool) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: dim.then_some(
|
color: dim.then_some(
|
||||||
theme.extended_palette().background.base.text.scale_alpha(0.42),
|
theme.palette().background.base.text.scale_alpha(0.42),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -280,7 +280,7 @@ pub(super) fn make_tip(tip: String) -> Element<'static, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn tip_style(theme: &Theme) -> container::Style {
|
pub(super) fn tip_style(theme: &Theme) -> container::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.strong.color)),
|
background: Some(Background::Color(palette.background.strong.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -632,7 +632,7 @@ pub(super) fn render_large<'a>(
|
||||||
.style(move |theme: &Theme| container::Style {
|
.style(move |theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(lc)),
|
background: Some(Background::Color(lc)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.strong.color,
|
color: theme.palette().background.strong.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 1.0.into(),
|
radius: 1.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -778,7 +778,7 @@ pub(super) fn render_large<'a>(
|
||||||
.style(move |theme: &Theme| container::Style {
|
.style(move |theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(c)),
|
background: Some(Background::Color(c)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.strong.color,
|
color: theme.palette().background.strong.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 1.0.into(),
|
radius: 1.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -1088,7 +1088,7 @@ pub(super) fn top_hist_btn_style(
|
||||||
open: bool,
|
open: bool,
|
||||||
status: button::Status,
|
status: button::Status,
|
||||||
) -> button::Style {
|
) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (active, open, status) {
|
let pair = match (active, open, status) {
|
||||||
(false, _, _) => palette.background.weakest,
|
(false, _, _) => palette.background.weakest,
|
||||||
(_, true, _) => palette.primary.weak,
|
(_, true, _) => palette.primary.weak,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ fn tip_panel(label: &'static str) -> Element<'static, Message> {
|
||||||
container(text(label).size(11))
|
container(text(label).size(11))
|
||||||
.padding([2, 6])
|
.padding([2, 6])
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.strong.color)),
|
background: Some(Background::Color(palette.background.strong.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -62,7 +62,7 @@ pub fn view(tools: &[ToolDef]) -> Option<Element<'static, Message>> {
|
||||||
.width(Length::Fixed(BTN_SIZE))
|
.width(Length::Fixed(BTN_SIZE))
|
||||||
.height(Length::Fixed(BTN_SIZE))
|
.height(Length::Fixed(BTN_SIZE))
|
||||||
.style(|theme: &Theme, status| {
|
.style(|theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let hovered = matches!(
|
let hovered = matches!(
|
||||||
status,
|
status,
|
||||||
button::Status::Hovered | button::Status::Pressed
|
button::Status::Hovered | button::Status::Pressed
|
||||||
|
|
@ -85,7 +85,7 @@ pub fn view(tools: &[ToolDef]) -> Option<Element<'static, Message>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let panel = container(col).padding(4).style(|theme: &Theme| {
|
let panel = container(col).padding(4).style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
|
||||||
|
|
@ -470,7 +470,7 @@ impl StatusBar {
|
||||||
|
|
||||||
container(wrap)
|
container(wrap)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -581,7 +581,7 @@ fn toggle_pill(icon: &'static [u8], active: bool, msg: Message) -> Element<'stat
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let mut style = button::subtle(theme, status);
|
let mut style = button::subtle(theme, status);
|
||||||
if active {
|
if active {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
style.background = Some(Background::Color(match status {
|
style.background = Some(Background::Color(match status {
|
||||||
button::Status::Hovered => palette.primary.base.color,
|
button::Status::Hovered => palette.primary.base.color,
|
||||||
_ => palette.primary.weak.color,
|
_ => palette.primary.weak.color,
|
||||||
|
|
@ -612,7 +612,7 @@ fn split_pill<'a>(
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
container(row![main, caret].spacing(3).align_y(iced::Center))
|
container(row![main, caret].spacing(3).align_y(iced::Center))
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(if active {
|
background: Some(Background::Color(if active {
|
||||||
palette.primary.weak.color
|
palette.primary.weak.color
|
||||||
|
|
@ -667,7 +667,7 @@ fn polar_pill<'a>(
|
||||||
row![
|
row![
|
||||||
polar_icon,
|
polar_icon,
|
||||||
text(angle).size(11).style(move |theme: &Theme| {
|
text(angle).size(11).style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
text::Style {
|
text::Style {
|
||||||
color: Some(if active {
|
color: Some(if active {
|
||||||
palette.primary.base.color
|
palette.primary.base.color
|
||||||
|
|
@ -796,7 +796,7 @@ fn space_tab<'a>(
|
||||||
report_key_prefix: &'static str,
|
report_key_prefix: &'static str,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let tab_style = move |theme: &Theme| {
|
let tab_style = move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let text_color = if !enabled {
|
let text_color = if !enabled {
|
||||||
palette.background.base.text.scale_alpha(0.42)
|
palette.background.base.text.scale_alpha(0.42)
|
||||||
} else if is_active {
|
} else if is_active {
|
||||||
|
|
@ -912,7 +912,7 @@ fn space_mode_btn(current_layout: &str, in_mspace: bool) -> Element<'static, Mes
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let mut style = button::subtle(theme, status);
|
let mut style = button::subtle(theme, status);
|
||||||
if active {
|
if active {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
style.background = Some(Background::Color(match status {
|
style.background = Some(Background::Color(match status {
|
||||||
button::Status::Hovered if clickable => palette.primary.base.color,
|
button::Status::Hovered if clickable => palette.primary.base.color,
|
||||||
_ => palette.primary.weak.color,
|
_ => palette.primary.weak.color,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ pub fn menu_bar<'a>(
|
||||||
.close_on_background_click_global(true)
|
.close_on_background_click_global(true)
|
||||||
.draw_path(DrawPath::Backdrop)
|
.draw_path(DrawPath::Backdrop)
|
||||||
.style(|theme: &Theme, _| {
|
.style(|theme: &Theme, _| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
iced_aw::style::menu_bar::Style {
|
iced_aw::style::menu_bar::Style {
|
||||||
bar_background: Background::Color(Color::TRANSPARENT),
|
bar_background: Background::Color(Color::TRANSPARENT),
|
||||||
bar_border: Border::default(),
|
bar_border: Border::default(),
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ fn layout_row<'a>(name: String, is_current: bool) -> Element<'a, Message> {
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let mut style = button::subtle(theme, status);
|
let mut style = button::subtle(theme, status);
|
||||||
if is_current && status == button::Status::Active {
|
if is_current && status == button::Status::Active {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
style.background = Some(Background::Color(palette.primary.weak.color));
|
style.background = Some(Background::Color(palette.primary.weak.color));
|
||||||
style.text_color = palette.primary.weak.text;
|
style.text_color = palette.primary.weak.text;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,19 @@
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use crate::ui::style::style_manager::{hdivider, muted_text_style, tb_button};
|
use crate::ui::style::style_manager::{hdivider, muted_text_style, tb_button};
|
||||||
use iced::widget::{column, container, mouse_area, row, scrollable, text, Space};
|
use iced::widget::{column, container, mouse_area, row, scrollable, text, Space};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
/// `scales` is `(name, "paper:drawing" ratio, is_member)`. Every label is cloned
|
/// `scales` is `(name, "paper:drawing" ratio, is_member)`. Every label is cloned
|
||||||
/// into the widget tree, so the returned element borrows nothing from the args.
|
/// into the widget tree, so the returned element borrows nothing from the args.
|
||||||
pub fn view_window(
|
pub fn view_window(
|
||||||
object_label: &str,
|
object_label: &str,
|
||||||
scales: &[(String, String, bool)],
|
scales: &[(String, String, bool)],
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'static, Message> {
|
) -> Element<'static, Message> {
|
||||||
let toolbar = container(
|
let toolbar = container(
|
||||||
row![
|
row![
|
||||||
text(format!("Object: {object_label}")).size(11),
|
text(format!("Object: {object_label}")).size(11),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
tb_button("Close", Message::CloseModal, true),
|
tb_button("Close", Message::CloseModal, true),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
|
|
@ -28,11 +29,11 @@ pub fn view_window(
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
let rows: Vec<Element<'_, Message>> = scales
|
let rows: Vec<Element<'_, Message>> = scales
|
||||||
|
|
@ -41,23 +42,23 @@ pub fn view_window(
|
||||||
let check = crate::ui::icons::themed_check_cell(*member);
|
let check = crate::ui::icons::themed_check_cell(*member);
|
||||||
let label = row![
|
let label = row![
|
||||||
check,
|
check,
|
||||||
text(name.clone()).size(11).width(Fill),
|
text(name.clone()).size(11).width(sizing.width),
|
||||||
text(ratio.clone()).size(10).style(muted_text_style),
|
text(ratio.clone()).size(10).style(muted_text_style),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Center);
|
.align_y(iced::Center);
|
||||||
let cell = container(label)
|
let cell = container(label)
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill);
|
.width(sizing.width);
|
||||||
mouse_area(cell)
|
mouse_area(cell)
|
||||||
.on_press(Message::AnnoObjectScaleToggle(name.clone()))
|
.on_press(Message::AnnoObjectScaleToggle(name.clone()))
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let list = container(scrollable(column(rows).spacing(1)).height(Fill))
|
let list = container(scrollable(column(rows).spacing(1)).height(sizing.height))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -68,8 +69,8 @@ pub fn view_window(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(2);
|
.padding(2);
|
||||||
|
|
||||||
let body = container(
|
let body = container(
|
||||||
|
|
@ -80,20 +81,20 @@ pub fn view_window(
|
||||||
list,
|
list,
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(12);
|
.padding(12);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), body])
|
container(column![toolbar, hdivider(sizing.width), body])
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
use crate::app::{ColorPickTarget, DsField, Message};
|
use crate::app::{ColorPickTarget, DsField, Message};
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, checkbox, column, container, pick_list, row, scrollable, text, text_input, Space,
|
button, checkbox, column, container, row, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
/// All DimStyle field values needed by the view.
|
/// All DimStyle field values needed by the view.
|
||||||
pub struct DimStyleValues<'a> {
|
pub struct DimStyleValues<'a> {
|
||||||
|
|
@ -95,7 +95,7 @@ pub struct DimStyleValues<'a> {
|
||||||
|
|
||||||
fn tab_btn_style(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn tab_btn_style(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (active, st) {
|
let pair = match (active, st) {
|
||||||
(true, _) => palette.primary.strong,
|
(true, _) => palette.primary.strong,
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -117,7 +117,7 @@ fn tab_btn_style(active: bool) -> impl Fn(&Theme, button::Status) -> button::Sty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -138,23 +138,23 @@ fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hdivider<'a>() -> Element<'a, Message> {
|
fn hdivider<'a>(width: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -169,6 +169,7 @@ pub fn view_window<'a>(
|
||||||
vals: DimStyleValues<'a>,
|
vals: DimStyleValues<'a>,
|
||||||
rename_active: Option<&'a str>,
|
rename_active: Option<&'a str>,
|
||||||
rename_buf: &'a str,
|
rename_buf: &'a str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
// ── Tab bar ───────────────────────────────────────────────────────────
|
// ── Tab bar ───────────────────────────────────────────────────────────
|
||||||
let tabs = row![
|
let tabs = row![
|
||||||
|
|
@ -234,7 +235,7 @@ pub fn view_window<'a>(
|
||||||
.unwrap_or_else(|| val.to_string());
|
.unwrap_or_else(|| val.to_string());
|
||||||
row![
|
row![
|
||||||
lbl(label),
|
lbl(label),
|
||||||
pick_list(labels, Some(cur), move |chosen| {
|
crate::ui::pick_list(labels, Some(cur), move |chosen| {
|
||||||
let code = opts
|
let code = opts
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, l)| *l == chosen.as_str())
|
.find(|(_, l)| *l == chosen.as_str())
|
||||||
|
|
@ -288,7 +289,7 @@ pub fn view_window<'a>(
|
||||||
Message::DsColorMore(fld.clone()),
|
Message::DsColorMore(fld.clone()),
|
||||||
Message::OpenColorWindow(ColorPickTarget::DimStyle(fld.clone())),
|
Message::OpenColorWindow(ColorPickTarget::DimStyle(fld.clone())),
|
||||||
);
|
);
|
||||||
row![lbl(label), selector]
|
row![lbl(label), container(selector).width(150)]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
.into()
|
.into()
|
||||||
|
|
@ -303,7 +304,7 @@ pub fn view_window<'a>(
|
||||||
-> Element<'a, Message> {
|
-> Element<'a, Message> {
|
||||||
row![
|
row![
|
||||||
lbl(label),
|
lbl(label),
|
||||||
pick_list(options, Some(selected), move |value| {
|
crate::ui::pick_list(options, Some(selected), move |value| {
|
||||||
Message::DsSetHandle { field, value }
|
Message::DsSetHandle { field, value }
|
||||||
})
|
})
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
|
|
@ -753,16 +754,16 @@ pub fn view_window<'a>(
|
||||||
column![
|
column![
|
||||||
text(format!("Editing: {selected}")).size(11).style(muted_style),
|
text(format!("Editing: {selected}")).size(11).style(muted_style),
|
||||||
tabs,
|
tabs,
|
||||||
hdivider(),
|
hdivider(sizing.width),
|
||||||
scrollable(container(tab_content).padding([12, 12]).width(Fill))
|
scrollable(container(tab_content).padding([12, 12]).width(sizing.width))
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 0.0,
|
right: 0.0,
|
||||||
|
|
@ -771,6 +772,7 @@ pub fn view_window<'a>(
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||||
|
sizing,
|
||||||
kind: crate::app::StyleKind::Dim,
|
kind: crate::app::StyleKind::Dim,
|
||||||
styles: &styles,
|
styles: &styles,
|
||||||
selected,
|
selected,
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, checkbox, column, container, pick_list, row, scrollable, text, text_input,
|
button, checkbox, column, container, row, scrollable, text, text_input,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (accent, st) {
|
let pair = match (accent, st) {
|
||||||
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -32,13 +32,13 @@ fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,7 +142,7 @@ fn enum_row<'a>(
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
row![
|
row![
|
||||||
text(label).size(11).style(muted_style).width(150),
|
text(label).size(11).style(muted_style).width(150),
|
||||||
pick_list(options, Some(selected), move |value| {
|
crate::ui::pick_list(options, Some(selected), move |value| {
|
||||||
Message::MLeaderStyleSetEnum { field, value }
|
Message::MLeaderStyleSetEnum { field, value }
|
||||||
})
|
})
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
|
|
@ -157,7 +157,7 @@ fn lineweight_row<'a>(selected: acadrust::types::LineWeight) -> Element<'a, Mess
|
||||||
let selected = crate::ui::properties::LwItem(selected);
|
let selected = crate::ui::properties::LwItem(selected);
|
||||||
row![
|
row![
|
||||||
text("Line weight:").size(11).style(muted_style).width(150),
|
text("Line weight:").size(11).style(muted_style).width(150),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
crate::ui::properties::lw_options(),
|
crate::ui::properties::lw_options(),
|
||||||
Some(selected),
|
Some(selected),
|
||||||
|item| Message::MLeaderStyleLineWeightChanged(item.0)
|
|item| Message::MLeaderStyleLineWeightChanged(item.0)
|
||||||
|
|
@ -199,7 +199,7 @@ fn handle_row<'a>(
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
row![
|
row![
|
||||||
text(label).size(11).style(muted_style).width(150),
|
text(label).size(11).style(muted_style).width(150),
|
||||||
pick_list(options, Some(selected), move |value| {
|
crate::ui::pick_list(options, Some(selected), move |value| {
|
||||||
Message::MLeaderStyleSetHandle { field, value }
|
Message::MLeaderStyleSetHandle { field, value }
|
||||||
})
|
})
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
|
|
@ -219,7 +219,10 @@ fn chk<'a>(label: &'static str, val: bool, field: &'static str) -> Element<'a, M
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_window<'a>(v: MLeaderStyleView<'a>) -> Element<'a, Message> {
|
pub fn view_window<'a>(
|
||||||
|
v: MLeaderStyleView<'a>,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
// ── Right: Details panel ──────────────────────────────────────────────
|
// ── Right: Details panel ──────────────────────────────────────────────
|
||||||
let details: Element<'_, Message> = if let Some(s) = v.style {
|
let details: Element<'_, Message> = if let Some(s) = v.style {
|
||||||
scrollable(
|
scrollable(
|
||||||
|
|
@ -396,8 +399,8 @@ pub fn view_window<'a>(v: MLeaderStyleView<'a>) -> Element<'a, Message> {
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.padding([12, 12]),
|
.padding([12, 12]),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
container(text("Select a style to view details.").size(11).style(muted_style))
|
container(text("Select a style to view details.").size(11).style(muted_style))
|
||||||
|
|
@ -405,9 +408,12 @@ pub fn view_window<'a>(v: MLeaderStyleView<'a>) -> Element<'a, Message> {
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let right_panel = container(details).width(Fill).height(Fill);
|
let right_panel = container(details)
|
||||||
|
.width(sizing.width)
|
||||||
|
.height(sizing.height);
|
||||||
|
|
||||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||||
|
sizing,
|
||||||
kind: crate::app::StyleKind::MLeader,
|
kind: crate::app::StyleKind::MLeader,
|
||||||
styles: &v.styles,
|
styles: &v.styles,
|
||||||
selected: v.selected,
|
selected: v.selected,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{column, container, row, scrollable, text};
|
use iced::widget::{column, container, row, scrollable, text};
|
||||||
use iced::{Element, Fill, Theme};
|
use iced::{Element, Theme};
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -17,6 +17,7 @@ pub fn view_window<'a>(
|
||||||
current_style: String,
|
current_style: String,
|
||||||
rename_active: Option<&'a str>,
|
rename_active: Option<&'a str>,
|
||||||
rename_buf: &'a str,
|
rename_buf: &'a str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
// ── Right: Details panel ──────────────────────────────────────────────
|
// ── Right: Details panel ──────────────────────────────────────────────
|
||||||
let info_row = |label: &'static str, val: String| -> Element<'_, Message> {
|
let info_row = |label: &'static str, val: String| -> Element<'_, Message> {
|
||||||
|
|
@ -69,7 +70,7 @@ pub fn view_window<'a>(
|
||||||
];
|
];
|
||||||
col_items.extend(elem_rows);
|
col_items.extend(elem_rows);
|
||||||
scrollable(column(col_items).spacing(6).padding([12, 12]))
|
scrollable(column(col_items).spacing(6).padding([12, 12]))
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
container(text("Select a style to view details.").size(11).style(muted_style))
|
container(text("Select a style to view details.").size(11).style(muted_style))
|
||||||
|
|
@ -77,9 +78,12 @@ pub fn view_window<'a>(
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let right_panel = container(details).width(Fill).height(Fill);
|
let right_panel = container(details)
|
||||||
|
.width(sizing.width)
|
||||||
|
.height(sizing.height);
|
||||||
|
|
||||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||||
|
sizing,
|
||||||
kind: crate::app::StyleKind::MLine,
|
kind: crate::app::StyleKind::MLine,
|
||||||
styles: &styles,
|
styles: &styles,
|
||||||
selected,
|
selected,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (accent, st) {
|
let pair = match (accent, st) {
|
||||||
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -29,7 +29,7 @@ fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -50,30 +50,30 @@ fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hdivider<'a>() -> Element<'a, Message> {
|
fn hdivider<'a>(width: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vsep<'a>() -> Element<'a, Message> {
|
fn vsep<'a>(height: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(1).height(Fill))
|
container(Space::new().width(1).height(height))
|
||||||
.width(1)
|
.width(1)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -86,6 +86,7 @@ pub fn view_window<'a>(
|
||||||
color_buf: &'a str,
|
color_buf: &'a str,
|
||||||
lw_buf: &'a str,
|
lw_buf: &'a str,
|
||||||
screen_buf: &'a str,
|
screen_buf: &'a str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let table_name = table
|
let table_name = table
|
||||||
.map(|t| t.name.as_str())
|
.map(|t| t.name.as_str())
|
||||||
|
|
@ -106,7 +107,7 @@ pub fn view_window<'a>(
|
||||||
.on_press(Message::PlotStyleClear)
|
.on_press(Message::PlotStyleClear)
|
||||||
.style(btn_s(false))
|
.style(btn_s(false))
|
||||||
.padding([4, 10]),
|
.padding([4, 10]),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
text(table_name).size(10).style(muted_style),
|
text(table_name).size(10).style(muted_style),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
|
|
@ -114,11 +115,11 @@ pub fn view_window<'a>(
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
// ── Left: ACI list ────────────────────────────────────────────────────
|
// ── Left: ACI list ────────────────────────────────────────────────────
|
||||||
|
|
@ -153,7 +154,7 @@ pub fn view_window<'a>(
|
||||||
button(text(label).size(10).font(iced::Font::MONOSPACE))
|
button(text(label).size(10).font(iced::Font::MONOSPACE))
|
||||||
.on_press(Message::PlotStylePanelSelectAci(aci))
|
.on_press(Message::PlotStylePanelSelectAci(aci))
|
||||||
.style(move |theme: &Theme, st| {
|
.style(move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (is_sel, st) {
|
let pair = match (is_sel, st) {
|
||||||
(true, _) => Some(palette.primary.strong),
|
(true, _) => Some(palette.primary.strong),
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -170,7 +171,7 @@ pub fn view_window<'a>(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding([2, 8])
|
.padding([2, 8])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -178,9 +179,9 @@ pub fn view_window<'a>(
|
||||||
let aci_list = container(
|
let aci_list = container(
|
||||||
column![
|
column![
|
||||||
text("ACI Color Index").size(10).style(muted_style),
|
text("ACI Color Index").size(10).style(muted_style),
|
||||||
container(scrollable(column(aci_items).spacing(1)).height(Fill))
|
container(scrollable(column(aci_items).spacing(1)).height(sizing.height))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -191,15 +192,15 @@ pub fn view_window<'a>(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(280)
|
.width(280)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 8.0,
|
right: 8.0,
|
||||||
|
|
@ -261,29 +262,29 @@ pub fn view_window<'a>(
|
||||||
text(format!(" Color: {cur_color}")).size(10),
|
text(format!(" Color: {cur_color}")).size(10),
|
||||||
text(format!(" Lineweight: {cur_lw}")).size(10),
|
text(format!(" Lineweight: {cur_lw}")).size(10),
|
||||||
text(format!(" Screening: {cur_scr}")).size(10),
|
text(format!(" Screening: {cur_scr}")).size(10),
|
||||||
Space::new().height(Fill),
|
Space::new().height(sizing.height),
|
||||||
button(text("Apply to ACI").size(11))
|
button(text("Apply to ACI").size(11))
|
||||||
.on_press(Message::PlotStylePanelApply)
|
.on_press(Message::PlotStylePanelApply)
|
||||||
.style(btn_s(true))
|
.style(btn_s(true))
|
||||||
.padding([5, 10]),
|
.padding([5, 10]),
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding([12, 12]);
|
.padding([12, 12]);
|
||||||
|
|
||||||
let body = row![aci_list, vsep(), edit_panel].height(Fill);
|
let body = row![aci_list, vsep(sizing.height), edit_panel].height(sizing.height);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), body].spacing(0))
|
container(column![toolbar, hdivider(sizing.width), body].spacing(0))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ impl canvas::Program<Message> for GlyphCanvas {
|
||||||
_cursor: mouse::Cursor,
|
_cursor: mouse::Cursor,
|
||||||
) -> Vec<canvas::Geometry> {
|
) -> Vec<canvas::Geometry> {
|
||||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||||
let glyph = theme.extended_palette().background.base.text;
|
let glyph = theme.palette().background.base.text;
|
||||||
let (cx, cy) = (bounds.width * 0.5, bounds.height * 0.5);
|
let (cx, cy) = (bounds.width * 0.5, bounds.height * 0.5);
|
||||||
let r = bounds.width.min(bounds.height) * 0.30;
|
let r = bounds.width.min(bounds.height) * 0.30;
|
||||||
let stroke = canvas::Stroke {
|
let stroke = canvas::Stroke {
|
||||||
|
|
@ -83,7 +83,7 @@ fn cell<'a>(value: i16, selected: bool) -> Element<'a, Message> {
|
||||||
.padding(0)
|
.padding(0)
|
||||||
.on_press(Message::PointStyleSetMode(value))
|
.on_press(Message::PointStyleSetMode(value))
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if selected {
|
let pair = if selected {
|
||||||
palette.primary.strong
|
palette.primary.strong
|
||||||
} else if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
} else if matches!(status, button::Status::Hovered | button::Status::Pressed) {
|
||||||
|
|
@ -106,7 +106,7 @@ fn cell<'a>(value: i16, selected: bool) -> Element<'a, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -127,11 +127,18 @@ fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_window<'a>(pdmode: i16, relative: bool, size_buf: &str) -> Element<'a, Message> {
|
pub fn view_window<'a>(
|
||||||
|
pdmode: i16,
|
||||||
|
relative: bool,
|
||||||
|
size_buf: &str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
|
let width = sizing.width;
|
||||||
|
let height = sizing.height;
|
||||||
// Glyph grid: a row per enclosure, a cell per shape.
|
// Glyph grid: a row per enclosure, a cell per shape.
|
||||||
let mut grid = column![].spacing(6);
|
let mut grid = column![].spacing(6);
|
||||||
for enc in ENCLOSURES {
|
for enc in ENCLOSURES {
|
||||||
|
|
@ -192,16 +199,20 @@ pub fn view_window<'a>(pdmode: i16, relative: bool, size_buf: &str) -> Element<'
|
||||||
Space::new().height(8),
|
Space::new().height(8),
|
||||||
radios,
|
radios,
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
row![Space::new().width(Length::Fill), ok],
|
row![Space::new().width(width), ok].width(width),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.padding(20),
|
.padding(20)
|
||||||
|
.width(width)
|
||||||
|
.height(height),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::ui::style::style_manager::{
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
column, container, mouse_area, row, scrollable, text, text_input, Space,
|
column, container, mouse_area, row, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
/// Inline-rename text-input id, so the rename-start handler can focus it.
|
/// Inline-rename text-input id, so the rename-start handler can focus it.
|
||||||
pub fn rename_input_id() -> iced::widget::Id {
|
pub fn rename_input_id() -> iced::widget::Id {
|
||||||
|
|
@ -20,7 +20,7 @@ pub fn rename_input_id() -> iced::widget::Id {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -49,6 +49,7 @@ pub fn view_window<'a, 'b>(
|
||||||
rename_buf: &'a str,
|
rename_buf: &'a str,
|
||||||
paper_buf: &'a str,
|
paper_buf: &'a str,
|
||||||
drawing_buf: &'a str,
|
drawing_buf: &'a str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
// ── Toolbar: New / Delete | Set Current / Apply ───────────────────────
|
// ── Toolbar: New / Delete | Set Current / Apply ───────────────────────
|
||||||
let toolbar = container(
|
let toolbar = container(
|
||||||
|
|
@ -56,7 +57,7 @@ pub fn view_window<'a, 'b>(
|
||||||
tb_button("New", Message::ScaleManagerNew, false),
|
tb_button("New", Message::ScaleManagerNew, false),
|
||||||
tb_button("Copy", Message::ScaleManagerCopy, false),
|
tb_button("Copy", Message::ScaleManagerCopy, false),
|
||||||
tb_button("Delete", Message::ScaleManagerDelete, false),
|
tb_button("Delete", Message::ScaleManagerDelete, false),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
tb_button("Set Current", Message::ScaleManagerSetCurrent, false),
|
tb_button("Set Current", Message::ScaleManagerSetCurrent, false),
|
||||||
tb_button("Apply", Message::ScaleManagerApply, true),
|
tb_button("Apply", Message::ScaleManagerApply, true),
|
||||||
]
|
]
|
||||||
|
|
@ -65,11 +66,11 @@ pub fn view_window<'a, 'b>(
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
// ── Left: scale list ──────────────────────────────────────────────────
|
// ── Left: scale list ──────────────────────────────────────────────────
|
||||||
|
|
@ -85,7 +86,7 @@ pub fn view_window<'a, 'b>(
|
||||||
.on_submit(Message::ScaleRenameCommit)
|
.on_submit(Message::ScaleRenameCommit)
|
||||||
.size(11)
|
.size(11)
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
let is_sel = name.as_str() == selected;
|
let is_sel = name.as_str() == selected;
|
||||||
|
|
@ -93,16 +94,16 @@ pub fn view_window<'a, 'b>(
|
||||||
let check = crate::ui::icons::themed_check_cell(is_cur);
|
let check = crate::ui::icons::themed_check_cell(is_cur);
|
||||||
let label = row![
|
let label = row![
|
||||||
check,
|
check,
|
||||||
text(name.clone()).size(11).width(Fill),
|
text(name.clone()).size(11).width(sizing.width),
|
||||||
text(ratio.clone()).size(10).style(muted_text_style),
|
text(ratio.clone()).size(10).style(muted_text_style),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_y(iced::Center);
|
.align_y(iced::Center);
|
||||||
let cell = container(label)
|
let cell = container(label)
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let pair = theme.extended_palette().primary.strong;
|
let pair = theme.palette().primary.strong;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: is_sel.then_some(Background::Color(pair.color)),
|
background: is_sel.then_some(Background::Color(pair.color)),
|
||||||
text_color: is_sel.then_some(pair.text),
|
text_color: is_sel.then_some(pair.text),
|
||||||
|
|
@ -119,9 +120,9 @@ pub fn view_window<'a, 'b>(
|
||||||
let list_panel = container(
|
let list_panel = container(
|
||||||
column![
|
column![
|
||||||
text("Scales").size(10).style(muted_text_style),
|
text("Scales").size(10).style(muted_text_style),
|
||||||
container(scrollable(column(rows).spacing(1)).height(Fill))
|
container(scrollable(column(rows).spacing(1)).height(sizing.height))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -132,15 +133,15 @@ pub fn view_window<'a, 'b>(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(190)
|
.width(190)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 8.0,
|
right: 8.0,
|
||||||
|
|
@ -158,7 +159,7 @@ pub fn view_window<'a, 'b>(
|
||||||
.style(field_style)
|
.style(field_style)
|
||||||
.size(12)
|
.size(12)
|
||||||
.padding([5, 8])
|
.padding([5, 8])
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
|
|
@ -176,20 +177,20 @@ pub fn view_window<'a, 'b>(
|
||||||
]
|
]
|
||||||
.spacing(8),
|
.spacing(8),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(12);
|
.padding(12);
|
||||||
|
|
||||||
let body = row![list_panel, vsep(), editor].height(Fill);
|
let body = row![list_panel, vsep(sizing.height), editor].height(sizing.height);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), body])
|
container(column![toolbar, hdivider(sizing.width), body])
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ pub fn item<'a>(
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let pair = theme.extended_palette().primary.strong;
|
let pair = theme.palette().primary.strong;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: is_selected.then_some(Background::Color(pair.color)),
|
background: is_selected.then_some(Background::Color(pair.color)),
|
||||||
text_color: is_selected.then_some(pair.text),
|
text_color: is_selected.then_some(pair.text),
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
use crate::app::{Message, StyleKind};
|
use crate::app::{Message, StyleKind};
|
||||||
use iced::widget::button::{Status, Style};
|
use iced::widget::button::{Status, Style};
|
||||||
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
/// Everything the shared frame needs. The per-manager `editor` element is the
|
/// Everything the shared frame needs. The per-manager `editor` element is the
|
||||||
/// only bespoke part.
|
/// only bespoke part.
|
||||||
|
|
@ -24,6 +24,7 @@ use iced::{Background, Border, Element, Fill, Theme};
|
||||||
/// list data (`styles`, `selected`, …) that the frame only reads while building
|
/// list data (`styles`, `selected`, …) that the frame only reads while building
|
||||||
/// rows, so callers may pass a locally-built `Vec`.
|
/// rows, so callers may pass a locally-built `Vec`.
|
||||||
pub struct Scaffold<'a, 'b> {
|
pub struct Scaffold<'a, 'b> {
|
||||||
|
pub sizing: crate::ui::modal::ModalSizing,
|
||||||
pub kind: StyleKind,
|
pub kind: StyleKind,
|
||||||
pub styles: &'b [String],
|
pub styles: &'b [String],
|
||||||
pub selected: &'b str,
|
pub selected: &'b str,
|
||||||
|
|
@ -46,12 +47,14 @@ pub struct Scaffold<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
||||||
|
let width = s.sizing.width;
|
||||||
|
let height = s.sizing.height;
|
||||||
// ── Toolbar: New / Copy / Delete | … | Set Current / Apply ────────────
|
// ── Toolbar: New / Copy / Delete | … | Set Current / Apply ────────────
|
||||||
let bar = row![
|
let bar = row![
|
||||||
tb_button("New", s.on_new, false),
|
tb_button("New", s.on_new, false),
|
||||||
tb_button("Copy", s.on_copy, false),
|
tb_button("Copy", s.on_copy, false),
|
||||||
tb_button("Delete", s.on_delete, false),
|
tb_button("Delete", s.on_delete, false),
|
||||||
Space::new().width(Fill),
|
Space::new().width(width),
|
||||||
tb_button("Set Current", s.on_set_current, false),
|
tb_button("Set Current", s.on_set_current, false),
|
||||||
tb_button("Apply", s.on_apply, true),
|
tb_button("Apply", s.on_apply, true),
|
||||||
]
|
]
|
||||||
|
|
@ -60,11 +63,11 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
||||||
let toolbar = container(bar)
|
let toolbar = container(bar)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
// ── Left: style list (single click selects, double click renames) ─────
|
// ── Left: style list (single click selects, double click renames) ─────
|
||||||
|
|
@ -89,9 +92,9 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
||||||
let list_panel = container(
|
let list_panel = container(
|
||||||
column![
|
column![
|
||||||
text("Styles").size(10).style(muted_text_style),
|
text("Styles").size(10).style(muted_text_style),
|
||||||
container(scrollable(column(rows).spacing(1)).height(Fill))
|
container(scrollable(column(rows).spacing(1)).height(height))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -102,15 +105,15 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.height(Fill),
|
.height(height),
|
||||||
)
|
)
|
||||||
.width(170)
|
.width(170)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 8.0,
|
right: 8.0,
|
||||||
|
|
@ -118,17 +121,17 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
||||||
left: 12.0,
|
left: 12.0,
|
||||||
});
|
});
|
||||||
|
|
||||||
let body = row![list_panel, vsep(), s.editor].height(Fill);
|
let body = row![list_panel, vsep(height), s.editor].height(height);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), body])
|
container(column![toolbar, hdivider(width), body])
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +148,7 @@ pub(crate) fn tb_button<'a>(label: &'a str, msg: Message, accent: bool) -> Eleme
|
||||||
|
|
||||||
fn btn_s(accent: bool) -> impl Fn(&Theme, Status) -> Style {
|
fn btn_s(accent: bool) -> impl Fn(&Theme, Status) -> Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (accent, st) {
|
let pair = match (accent, st) {
|
||||||
(true, Status::Hovered | Status::Pressed) => palette.primary.strong,
|
(true, Status::Hovered | Status::Pressed) => palette.primary.strong,
|
||||||
(false, Status::Hovered | Status::Pressed) => palette.background.strong,
|
(false, Status::Hovered | Status::Pressed) => palette.background.strong,
|
||||||
|
|
@ -167,30 +170,30 @@ fn btn_s(accent: bool) -> impl Fn(&Theme, Status) -> Style {
|
||||||
|
|
||||||
pub(crate) fn muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
pub(crate) fn muted_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn hdivider<'a>() -> Element<'a, Message> {
|
pub(crate) fn hdivider<'a>(width: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn vsep<'a>() -> Element<'a, Message> {
|
pub(crate) fn vsep<'a>(height: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(1).height(Fill))
|
container(Space::new().width(1).height(height))
|
||||||
.width(1)
|
.width(1)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, checkbox, column, container, pick_list, row, scrollable, text, text_input, Column,
|
button, checkbox, column, container, row, scrollable, text, text_input, Column,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (accent, st) {
|
let pair = match (accent, st) {
|
||||||
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -32,13 +32,13 @@ fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,6 +63,7 @@ pub fn view_window<'a>(
|
||||||
rename_active: Option<&'a str>,
|
rename_active: Option<&'a str>,
|
||||||
rename_buf: &'a str,
|
rename_buf: &'a str,
|
||||||
color_open: Option<(u8, &'static str)>,
|
color_open: Option<(u8, &'static str)>,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
// ── Right: Details panel ──────────────────────────────────────────────
|
// ── Right: Details panel ──────────────────────────────────────────────
|
||||||
let info_row = |label: &'static str, val: String| -> Element<'_, Message> {
|
let info_row = |label: &'static str, val: String| -> Element<'_, Message> {
|
||||||
|
|
@ -140,7 +141,7 @@ pub fn view_window<'a>(
|
||||||
.push(
|
.push(
|
||||||
row![
|
row![
|
||||||
text(" Alignment:").size(11).style(muted_style).width(150),
|
text(" Alignment:").size(11).style(muted_style).width(150),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
[
|
[
|
||||||
"TopLeft",
|
"TopLeft",
|
||||||
"TopCenter",
|
"TopCenter",
|
||||||
|
|
@ -193,7 +194,7 @@ pub fn view_window<'a>(
|
||||||
col = col.push(
|
col = col.push(
|
||||||
row![
|
row![
|
||||||
text(format!(" {bname}")).size(11).style(muted_style).width(28),
|
text(format!(" {bname}")).size(11).style(muted_style).width(28),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
["Single", "Double"]
|
["Single", "Double"]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
|
|
@ -273,7 +274,7 @@ pub fn view_window<'a>(
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
row![
|
row![
|
||||||
text("Flow direction:").size(11).style(muted_style).width(160),
|
text("Flow direction:").size(11).style(muted_style).width(160),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
["Down", "Up"]
|
["Down", "Up"]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
|
|
@ -336,8 +337,8 @@ pub fn view_window<'a>(
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.padding([12, 12]),
|
.padding([12, 12]),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
container(text("Select a style to view details.").size(11).style(muted_style))
|
container(text("Select a style to view details.").size(11).style(muted_style))
|
||||||
|
|
@ -345,9 +346,12 @@ pub fn view_window<'a>(
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let right_panel = container(details).width(Fill).height(Fill);
|
let right_panel = container(details)
|
||||||
|
.width(sizing.width)
|
||||||
|
.height(sizing.height);
|
||||||
|
|
||||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||||
|
sizing,
|
||||||
kind: crate::app::StyleKind::Table,
|
kind: crate::app::StyleKind::Table,
|
||||||
styles: &styles,
|
styles: &styles,
|
||||||
selected,
|
selected,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::app::StyleKind;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, canvas, checkbox, column, container, row, scrollable, text, text_input, Space,
|
button, canvas, checkbox, column, container, row, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{mouse, Background, Border, Element, Fill, Length, Point, Rectangle, Theme};
|
use iced::{mouse, Background, Border, Element, Length, Point, Rectangle, Theme};
|
||||||
|
|
||||||
/// View-model for the Text Style editor window.
|
/// View-model for the Text Style editor window.
|
||||||
pub struct TextStyleView<'a> {
|
pub struct TextStyleView<'a> {
|
||||||
|
|
@ -36,7 +36,7 @@ const BUILTIN_FONTS: &[&str] = &[
|
||||||
|
|
||||||
fn list_item(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn list_item(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (active, st) {
|
let pair = match (active, st) {
|
||||||
(true, _) => Some(palette.primary.strong),
|
(true, _) => Some(palette.primary.strong),
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -53,7 +53,7 @@ fn list_item(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -74,23 +74,23 @@ fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vsep<'a>() -> Element<'a, Message> {
|
fn vsep<'a>(height: Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(1).height(Fill))
|
container(Space::new().width(1).height(height))
|
||||||
.width(1)
|
.width(1)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -162,7 +162,7 @@ impl canvas::Program<Message> for TextPreviewCanvas {
|
||||||
};
|
};
|
||||||
let stroke = canvas::Stroke {
|
let stroke = canvas::Stroke {
|
||||||
width: 1.4,
|
width: 1.4,
|
||||||
style: canvas::Style::Solid(theme.extended_palette().background.base.text),
|
style: canvas::Style::Solid(theme.palette().background.base.text),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
for s in &strokes {
|
for s in &strokes {
|
||||||
|
|
@ -181,7 +181,10 @@ impl canvas::Program<Message> for TextPreviewCanvas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
pub fn view_window<'a>(
|
||||||
|
v: TextStyleView<'a>,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
let TextStyleView {
|
let TextStyleView {
|
||||||
styles,
|
styles,
|
||||||
selected,
|
selected,
|
||||||
|
|
@ -207,7 +210,7 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
.on_press(Message::TextStyleFontPick(f.to_string()))
|
.on_press(Message::TextStyleFontPick(f.to_string()))
|
||||||
.style(list_item(is_sel))
|
.style(list_item(is_sel))
|
||||||
.padding([3, 8])
|
.padding([3, 8])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -215,9 +218,9 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
let font_panel = container(
|
let font_panel = container(
|
||||||
column![
|
column![
|
||||||
text("Font File").size(10).style(muted_style),
|
text("Font File").size(10).style(muted_style),
|
||||||
container(scrollable(column(font_items).spacing(1)).height(Fill))
|
container(scrollable(column(font_items).spacing(1)).height(sizing.height))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -228,8 +231,8 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
text_input("font file…", font_buf)
|
text_input("font file…", font_buf)
|
||||||
.on_input(|v| Message::TextStyleEdit {
|
.on_input(|v| Message::TextStyleEdit {
|
||||||
|
|
@ -238,13 +241,13 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
})
|
})
|
||||||
.style(field_style)
|
.style(field_style)
|
||||||
.size(11)
|
.size(11)
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(190)
|
.width(190)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding([12, 8]);
|
.padding([12, 8]);
|
||||||
|
|
||||||
// Labeled numeric/text field row → TextStyleEdit { field, value }.
|
// Labeled numeric/text field row → TextStyleEdit { field, value }.
|
||||||
|
|
@ -286,7 +289,7 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
oblique: oblique_buf.trim().parse::<f32>().unwrap_or(0.0).to_radians(),
|
oblique: oblique_buf.trim().parse::<f32>().unwrap_or(0.0).to_radians(),
|
||||||
rotation: if upside_down { std::f32::consts::PI } else { 0.0 },
|
rotation: if upside_down { std::f32::consts::PI } else { 0.0 },
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Length::Fixed(56.0));
|
.height(Length::Fixed(56.0));
|
||||||
|
|
||||||
// ── Right: Properties ─────────────────────────────────────────────────
|
// ── Right: Properties ─────────────────────────────────────────────────
|
||||||
|
|
@ -320,7 +323,7 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
text("Preview").size(10).style(muted_style),
|
text("Preview").size(10).style(muted_style),
|
||||||
container(preview)
|
container(preview)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -332,13 +335,13 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 12.0,
|
right: 12.0,
|
||||||
|
|
@ -358,7 +361,7 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
})
|
})
|
||||||
.style(list_item(is_sel))
|
.style(list_item(is_sel))
|
||||||
.padding([3, 8])
|
.padding([3, 8])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -366,9 +369,9 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
let ttf_panel = container(
|
let ttf_panel = container(
|
||||||
column![
|
column![
|
||||||
text("TrueType (system)").size(10).style(muted_style),
|
text("TrueType (system)").size(10).style(muted_style),
|
||||||
container(scrollable(column(ttf_items).spacing(1)).height(Fill))
|
container(scrollable(column(ttf_items).spacing(1)).height(sizing.height))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -379,8 +382,8 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
text_input("TrueType font…", ttf_buf)
|
text_input("TrueType font…", ttf_buf)
|
||||||
.on_input(|v| Message::TextStyleEdit {
|
.on_input(|v| Message::TextStyleEdit {
|
||||||
|
|
@ -389,18 +392,26 @@ pub fn view_window<'a>(v: TextStyleView<'a>) -> Element<'a, Message> {
|
||||||
})
|
})
|
||||||
.style(field_style)
|
.style(field_style)
|
||||||
.size(11)
|
.size(11)
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(190)
|
.width(190)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding([12, 8]);
|
.padding([12, 8]);
|
||||||
|
|
||||||
let editor = row![font_panel, vsep(), ttf_panel, vsep(), props_panel].height(Fill);
|
let editor = row![
|
||||||
|
font_panel,
|
||||||
|
vsep(sizing.height),
|
||||||
|
ttf_panel,
|
||||||
|
vsep(sizing.height),
|
||||||
|
props_panel
|
||||||
|
]
|
||||||
|
.height(sizing.height);
|
||||||
|
|
||||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||||
|
sizing,
|
||||||
kind: StyleKind::Text,
|
kind: StyleKind::Text,
|
||||||
styles: &styles,
|
styles: &styles,
|
||||||
selected,
|
selected,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ fn info_row<'a>(label: &'static str, value: String) -> Element<'a, Message> {
|
||||||
text(label)
|
text(label)
|
||||||
.size(11)
|
.size(11)
|
||||||
.style(|theme: &Theme| iced::widget::text::Style {
|
.style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
})
|
})
|
||||||
.width(100),
|
.width(100),
|
||||||
text(value).size(11),
|
text(value).size(11),
|
||||||
|
|
@ -28,12 +28,12 @@ pub fn view_window<'a>() -> Element<'a, Message> {
|
||||||
text("Open CAD Studio")
|
text("Open CAD Studio")
|
||||||
.size(32)
|
.size(32)
|
||||||
.style(|theme: &Theme| iced::widget::text::Style {
|
.style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}),
|
}),
|
||||||
text("CAD application for Architecture & Engineering")
|
text("CAD application for Architecture & Engineering")
|
||||||
.size(11)
|
.size(11)
|
||||||
.style(|theme: &Theme| iced::widget::text::Style {
|
.style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
|
|
@ -84,7 +84,7 @@ pub fn view_window<'a>() -> Element<'a, Message> {
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
||||||
use iced::{Background, Element, Fill, Length, Theme};
|
use iced::{Background, Element, Length, Theme};
|
||||||
|
|
||||||
/// Which column of an alias row a text edit targets.
|
/// Which column of an alias row a text edit targets.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
|
@ -20,12 +20,15 @@ const GUTTER: f32 = 16.0;
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the alias editor content. `rows` is the live working buffer.
|
/// Build the alias editor content. `rows` is the live working buffer.
|
||||||
pub fn view_window(rows: &[(String, String)]) -> Element<'_, Message> {
|
pub fn view_window(
|
||||||
|
rows: &[(String, String)],
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'_, Message> {
|
||||||
let title = text("Command Aliases").size(15);
|
let title = text("Command Aliases").size(15);
|
||||||
let hint = text(
|
let hint = text(
|
||||||
"Type an alias and the command it runs (e.g. L → LINE). \
|
"Type an alias and the command it runs (e.g. L → LINE). \
|
||||||
|
|
@ -42,7 +45,7 @@ pub fn view_window(rows: &[(String, String)]) -> Element<'_, Message> {
|
||||||
let head = container(
|
let head = container(
|
||||||
row![
|
row![
|
||||||
container(text("Alias").size(11).style(muted_style)).width(Length::Fixed(120.0)),
|
container(text("Alias").size(11).style(muted_style)).width(Length::Fixed(120.0)),
|
||||||
container(text("Command").size(11).style(muted_style)).width(Fill),
|
container(text("Command").size(11).style(muted_style)).width(sizing.width),
|
||||||
Space::new().width(Length::Fixed(30.0)),
|
Space::new().width(Length::Fixed(30.0)),
|
||||||
]
|
]
|
||||||
.spacing(8),
|
.spacing(8),
|
||||||
|
|
@ -60,7 +63,7 @@ pub fn view_window(rows: &[(String, String)]) -> Element<'_, Message> {
|
||||||
.on_input(move |v| Message::AliasEditorInput { idx, field: AliasField::Command, value: v })
|
.on_input(move |v| Message::AliasEditorInput { idx, field: AliasField::Command, value: v })
|
||||||
.size(13)
|
.size(13)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Fill);
|
.width(sizing.width);
|
||||||
let del = button(crate::ui::icons::themed_danger(crate::ui::icons::CLOSE, 12.0))
|
let del = button(crate::ui::icons::themed_danger(crate::ui::icons::CLOSE, 12.0))
|
||||||
.on_press(Message::AliasEditorRemove(idx))
|
.on_press(Message::AliasEditorRemove(idx))
|
||||||
.padding([2, 6])
|
.padding([2, 6])
|
||||||
|
|
@ -89,20 +92,20 @@ pub fn view_window(rows: &[(String, String)]) -> Element<'_, Message> {
|
||||||
hint,
|
hint,
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
head,
|
head,
|
||||||
scrollable(container(list).padding(gutter)).height(Fill),
|
scrollable(container(list).padding(gutter)).height(sizing.height),
|
||||||
Space::new().height(6),
|
Space::new().height(6),
|
||||||
row![add, Space::new().width(Fill), apply].align_y(iced::Center),
|
row![add, Space::new().width(sizing.width), apply].align_y(iced::Center),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.padding(12)
|
.padding(12)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::app::Message;
|
||||||
use acadrust::entities::{HorizontalAlignment, VerticalAlignment};
|
use acadrust::entities::{HorizontalAlignment, VerticalAlignment};
|
||||||
use acadrust::types::{Color as AcadColor, LineWeight};
|
use acadrust::types::{Color as AcadColor, LineWeight};
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, checkbox, column, container, pick_list, row, scrollable, text, text_input, Space,
|
button, checkbox, column, container, row, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Length, Theme};
|
use iced::{Background, Border, Element, Length, Theme};
|
||||||
|
|
||||||
|
|
@ -135,12 +135,12 @@ pub fn color_from_label(label: &str) -> Option<AcadColor> {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -156,13 +156,13 @@ fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Horizontal 1px divider in the shared border colour (matches style windows).
|
/// Horizontal 1px divider in the shared border colour (matches style windows).
|
||||||
fn hdivider<'a>() -> Element<'a, Message> {
|
fn hdivider<'a>(width: Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Length::Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -170,13 +170,18 @@ fn hdivider<'a>() -> Element<'a, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One `label : widget` row with a fixed-width label column.
|
/// One `label : widget` row with a fixed-width label column.
|
||||||
fn field_row<'a>(label: &'a str, widget: Element<'a, Message>) -> Element<'a, Message> {
|
fn field_row<'a>(
|
||||||
|
label: &'a str,
|
||||||
|
widget: Element<'a, Message>,
|
||||||
|
width: Length,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
row![
|
row![
|
||||||
container(text(label).size(12).style(muted_style)).width(LABEL_W),
|
container(text(label).size(12).style(muted_style)).width(LABEL_W),
|
||||||
widget,
|
widget,
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
|
.width(width)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,6 +190,7 @@ fn edit_field<'a>(
|
||||||
label: &'a str,
|
label: &'a str,
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
on_input: impl Fn(String) -> Message + 'a,
|
on_input: impl Fn(String) -> Message + 'a,
|
||||||
|
width: Length,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let ti = text_input("", value)
|
let ti = text_input("", value)
|
||||||
.on_input(on_input)
|
.on_input(on_input)
|
||||||
|
|
@ -192,8 +198,8 @@ fn edit_field<'a>(
|
||||||
.style(field_style)
|
.style(field_style)
|
||||||
.size(13)
|
.size(13)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Length::Fill);
|
.width(width);
|
||||||
field_row(label, ti.into())
|
field_row(label, ti.into(), width)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A labelled pick_list of owned string options.
|
/// A labelled pick_list of owned string options.
|
||||||
|
|
@ -202,12 +208,13 @@ fn pick_field<'a>(
|
||||||
options: Vec<String>,
|
options: Vec<String>,
|
||||||
selected: Option<String>,
|
selected: Option<String>,
|
||||||
on_select: impl Fn(String) -> Message + 'a,
|
on_select: impl Fn(String) -> Message + 'a,
|
||||||
|
width: Length,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let pl = pick_list(options, selected, on_select)
|
let pl = crate::ui::pick_list(options, selected, on_select)
|
||||||
.text_size(13)
|
.text_size(13)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Length::Fill);
|
.width(width);
|
||||||
field_row(label, pl.into())
|
field_row(label, pl.into(), width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_button<'a>(label: &'a str, this: AttrTab, active: AttrTab) -> Element<'a, Message> {
|
fn tab_button<'a>(label: &'a str, this: AttrTab, active: AttrTab) -> Element<'a, Message> {
|
||||||
|
|
@ -216,7 +223,7 @@ fn tab_button<'a>(label: &'a str, this: AttrTab, active: AttrTab) -> Element<'a,
|
||||||
.padding([4, 12])
|
.padding([4, 12])
|
||||||
.on_press(Message::AttrEditorTab(this))
|
.on_press(Message::AttrEditorTab(this))
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (is_active, status) {
|
let pair = match (is_active, status) {
|
||||||
(true, _) => palette.primary.strong,
|
(true, _) => palette.primary.strong,
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -250,7 +257,10 @@ pub fn view_window<'a>(
|
||||||
layers: Vec<String>,
|
layers: Vec<String>,
|
||||||
linetypes: Vec<String>,
|
linetypes: Vec<String>,
|
||||||
styles: Vec<String>,
|
styles: Vec<String>,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
|
let width = sizing.width;
|
||||||
|
let height = sizing.height;
|
||||||
// ── Top toolbar: block name on the left, Apply on the right ───────────
|
// ── Top toolbar: block name on the left, Apply on the right ───────────
|
||||||
// Mirrors the style-manager windows (actions left, primary action right).
|
// Mirrors the style-manager windows (actions left, primary action right).
|
||||||
let apply = button(text("Apply").size(11))
|
let apply = button(text("Apply").size(11))
|
||||||
|
|
@ -260,18 +270,18 @@ pub fn view_window<'a>(
|
||||||
let toolbar = container(
|
let toolbar = container(
|
||||||
row![
|
row![
|
||||||
text(format!("Block: {block}")).size(12).style(muted_style),
|
text(format!("Block: {block}")).size(12).style(muted_style),
|
||||||
Space::new().width(Length::Fill),
|
Space::new().width(width),
|
||||||
apply,
|
apply,
|
||||||
]
|
]
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
let tabs = row![
|
let tabs = row![
|
||||||
|
|
@ -285,36 +295,49 @@ pub fn view_window<'a>(
|
||||||
text("This block has no attributes.").size(13).style(muted_style).into()
|
text("This block has no attributes.").size(13).style(muted_style).into()
|
||||||
} else {
|
} else {
|
||||||
match tab {
|
match tab {
|
||||||
AttrTab::Attribute => attribute_tab(rows, selected),
|
AttrTab::Attribute => attribute_tab(rows, selected, width, height),
|
||||||
AttrTab::TextOptions => text_options_tab(&rows[selected.min(rows.len() - 1)], styles),
|
AttrTab::TextOptions => {
|
||||||
|
text_options_tab(&rows[selected.min(rows.len() - 1)], styles, width, height)
|
||||||
|
}
|
||||||
AttrTab::Properties => {
|
AttrTab::Properties => {
|
||||||
properties_tab(&rows[selected.min(rows.len() - 1)], layers, linetypes)
|
properties_tab(
|
||||||
|
&rows[selected.min(rows.len() - 1)],
|
||||||
|
layers,
|
||||||
|
linetypes,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let content = container(column![tabs, body].spacing(8))
|
let content = container(column![tabs, body].spacing(8))
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
.height(Length::Fill)
|
.height(height)
|
||||||
.padding(12);
|
.padding(12);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), content])
|
container(column![toolbar, hdivider(width), content])
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
.height(Length::Fill)
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attribute tab: tag / prompt / value list with row-select, plus a value box.
|
/// Attribute tab: tag / prompt / value list with row-select, plus a value box.
|
||||||
fn attribute_tab<'a>(rows: &'a [AttrRow], selected: usize) -> Element<'a, Message> {
|
fn attribute_tab<'a>(
|
||||||
|
rows: &'a [AttrRow],
|
||||||
|
selected: usize,
|
||||||
|
width: Length,
|
||||||
|
height: Length,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
let head = row![
|
let head = row![
|
||||||
container(text("Tag").size(11).style(muted_style)).width(130),
|
container(text("Tag").size(11).style(muted_style)).width(130),
|
||||||
container(text("Prompt").size(11).style(muted_style)).width(Length::Fill),
|
container(text("Prompt").size(11).style(muted_style)).width(width),
|
||||||
container(text("Value").size(11).style(muted_style)).width(140),
|
container(text("Value").size(11).style(muted_style)).width(140),
|
||||||
]
|
]
|
||||||
.spacing(6);
|
.spacing(6);
|
||||||
|
|
@ -324,16 +347,16 @@ fn attribute_tab<'a>(rows: &'a [AttrRow], selected: usize) -> Element<'a, Messag
|
||||||
let is_sel = idx == selected;
|
let is_sel = idx == selected;
|
||||||
let line = row![
|
let line = row![
|
||||||
container(text(r.tag.as_str()).size(12)).width(130),
|
container(text(r.tag.as_str()).size(12)).width(130),
|
||||||
container(text(r.prompt.as_str()).size(12).style(muted_style)).width(Length::Fill),
|
container(text(r.prompt.as_str()).size(12).style(muted_style)).width(width),
|
||||||
container(text(r.value.as_str()).size(12)).width(140),
|
container(text(r.value.as_str()).size(12)).width(140),
|
||||||
]
|
]
|
||||||
.spacing(6);
|
.spacing(6);
|
||||||
let btn = button(line)
|
let btn = button(line)
|
||||||
.on_press(Message::AttrEditorSelect(idx))
|
.on_press(Message::AttrEditorSelect(idx))
|
||||||
.padding([3, 4])
|
.padding([3, 4])
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let hovered = matches!(status, button::Status::Hovered);
|
let hovered = matches!(status, button::Status::Hovered);
|
||||||
let pair = if is_sel {
|
let pair = if is_sel {
|
||||||
palette.primary.strong
|
palette.primary.strong
|
||||||
|
|
@ -359,20 +382,27 @@ fn attribute_tab<'a>(rows: &'a [AttrRow], selected: usize) -> Element<'a, Messag
|
||||||
.style(field_style)
|
.style(field_style)
|
||||||
.size(13)
|
.size(13)
|
||||||
.padding([4, 6])
|
.padding([4, 6])
|
||||||
.width(Length::Fill);
|
.width(width);
|
||||||
|
|
||||||
column![
|
column![
|
||||||
head,
|
head,
|
||||||
scrollable(list).height(Length::Fill),
|
scrollable(list).width(width).height(height),
|
||||||
Space::new().height(8),
|
Space::new().height(8),
|
||||||
field_row("Value:", value_box.into()),
|
field_row("Value:", value_box.into(), width),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Text Options tab: the selected attribute's text formatting.
|
/// Text Options tab: the selected attribute's text formatting.
|
||||||
fn text_options_tab<'a>(r: &'a AttrRow, styles: Vec<String>) -> Element<'a, Message> {
|
fn text_options_tab<'a>(
|
||||||
|
r: &'a AttrRow,
|
||||||
|
styles: Vec<String>,
|
||||||
|
width: Length,
|
||||||
|
height: Length,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
let style_sel = if r.text_style.is_empty() {
|
let style_sel = if r.text_style.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -384,14 +414,14 @@ fn text_options_tab<'a>(r: &'a AttrRow, styles: Vec<String>) -> Element<'a, Mess
|
||||||
column![
|
column![
|
||||||
pick_field("Text Style", styles, style_sel, |s| {
|
pick_field("Text Style", styles, style_sel, |s| {
|
||||||
Message::AttrEditorTextStyle(s)
|
Message::AttrEditorTextStyle(s)
|
||||||
}),
|
}, width),
|
||||||
pick_field("Justification", justify_opts, justify_sel, |s| {
|
pick_field("Justification", justify_opts, justify_sel, |s| {
|
||||||
Message::AttrEditorJustify(s)
|
Message::AttrEditorJustify(s)
|
||||||
}),
|
}, width),
|
||||||
edit_field("Height", &r.height, Message::AttrEditorHeight),
|
edit_field("Height", &r.height, Message::AttrEditorHeight, width),
|
||||||
edit_field("Rotation", &r.rotation, Message::AttrEditorRotation),
|
edit_field("Rotation", &r.rotation, Message::AttrEditorRotation, width),
|
||||||
edit_field("Width Factor", &r.width_factor, Message::AttrEditorWidth),
|
edit_field("Width Factor", &r.width_factor, Message::AttrEditorWidth, width),
|
||||||
edit_field("Oblique Angle", &r.oblique, Message::AttrEditorOblique),
|
edit_field("Oblique Angle", &r.oblique, Message::AttrEditorOblique, width),
|
||||||
field_row(
|
field_row(
|
||||||
"",
|
"",
|
||||||
checkbox(r.backwards)
|
checkbox(r.backwards)
|
||||||
|
|
@ -400,6 +430,7 @@ fn text_options_tab<'a>(r: &'a AttrRow, styles: Vec<String>) -> Element<'a, Mess
|
||||||
.size(15)
|
.size(15)
|
||||||
.text_size(12)
|
.text_size(12)
|
||||||
.into(),
|
.into(),
|
||||||
|
width,
|
||||||
),
|
),
|
||||||
field_row(
|
field_row(
|
||||||
"",
|
"",
|
||||||
|
|
@ -409,9 +440,12 @@ fn text_options_tab<'a>(r: &'a AttrRow, styles: Vec<String>) -> Element<'a, Mess
|
||||||
.size(15)
|
.size(15)
|
||||||
.text_size(12)
|
.text_size(12)
|
||||||
.into(),
|
.into(),
|
||||||
|
width,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -420,6 +454,8 @@ fn properties_tab<'a>(
|
||||||
r: &'a AttrRow,
|
r: &'a AttrRow,
|
||||||
layers: Vec<String>,
|
layers: Vec<String>,
|
||||||
linetypes: Vec<String>,
|
linetypes: Vec<String>,
|
||||||
|
width: Length,
|
||||||
|
height: Length,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let layer_sel = Some(r.layer.clone());
|
let layer_sel = Some(r.layer.clone());
|
||||||
let lt_sel = Some(if r.linetype.is_empty() {
|
let lt_sel = Some(if r.linetype.is_empty() {
|
||||||
|
|
@ -439,21 +475,23 @@ fn properties_tab<'a>(
|
||||||
|
|
||||||
let lw_opts = lw_options();
|
let lw_opts = lw_options();
|
||||||
let lw_sel = LwItem(r.line_weight);
|
let lw_sel = LwItem(r.line_weight);
|
||||||
let lw = pick_list(lw_opts, Some(lw_sel), |it: LwItem| {
|
let lw = crate::ui::pick_list(lw_opts, Some(lw_sel), |it: LwItem| {
|
||||||
Message::AttrEditorLineweight(it.0)
|
Message::AttrEditorLineweight(it.0)
|
||||||
})
|
})
|
||||||
.text_size(13)
|
.text_size(13)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Length::Fill);
|
.width(width);
|
||||||
|
|
||||||
column![
|
column![
|
||||||
pick_field("Layer", layers, layer_sel, Message::AttrEditorLayer),
|
pick_field("Layer", layers, layer_sel, Message::AttrEditorLayer, width),
|
||||||
pick_field("Linetype", linetypes, lt_sel, Message::AttrEditorLinetype),
|
pick_field("Linetype", linetypes, lt_sel, Message::AttrEditorLinetype, width),
|
||||||
pick_field("Color", color_opts, color_sel, |s| {
|
pick_field("Color", color_opts, color_sel, |s| {
|
||||||
Message::AttrEditorColor(s)
|
Message::AttrEditorColor(s)
|
||||||
}),
|
}, width),
|
||||||
field_row("Lineweight", lw.into()),
|
field_row("Lineweight", lw.into(), width),
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::app::{LayerStateLayerFlag, LayerStateProperty, Message};
|
||||||
use crate::ui::properties::{lw_options, LwItem};
|
use crate::ui::properties::{lw_options, LwItem};
|
||||||
use acadrust::{LayerState, LayerStateMask};
|
use acadrust::{LayerState, LayerStateMask};
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, checkbox, column, container, pick_list, row, scrollable, text, text_input, Space,
|
button, checkbox, column, container, row, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Length, Theme};
|
use iced::{Background, Border, Element, Fill, Length, Theme};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
@ -39,7 +39,7 @@ fn muted(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(
|
color: Some(
|
||||||
theme
|
theme
|
||||||
.extended_palette()
|
.palette()
|
||||||
.background
|
.background
|
||||||
.base
|
.base
|
||||||
.text
|
.text
|
||||||
|
|
@ -68,13 +68,13 @@ fn list_style(selected: bool) -> impl Fn(&Theme, button::Status) -> button::Styl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn divider<'a>() -> Element<'a, Message> {
|
fn divider<'a>(width: Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color,
|
theme.palette().background.neutral.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -107,6 +107,7 @@ pub fn view_window<'a>(
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
description: &'a str,
|
description: &'a str,
|
||||||
filter: &'a str,
|
filter: &'a str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let selected_state = selected.and_then(|selected| {
|
let selected_state = selected.and_then(|selected| {
|
||||||
states
|
states
|
||||||
|
|
@ -139,7 +140,7 @@ pub fn view_window<'a>(
|
||||||
.on_press(Message::LayerStateManagerSelect(state.name.clone()))
|
.on_press(Message::LayerStateManagerSelect(state.name.clone()))
|
||||||
.style(list_style(is_selected))
|
.style(list_style(is_selected))
|
||||||
.padding([6, 9])
|
.padding([6, 9])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -165,7 +166,9 @@ pub fn view_window<'a>(
|
||||||
let state_list: Element<'_, Message> = if rows.is_empty() {
|
let state_list: Element<'_, Message> = if rows.is_empty() {
|
||||||
empty
|
empty
|
||||||
} else {
|
} else {
|
||||||
scrollable(column(rows).spacing(2)).height(Fill).into()
|
scrollable(column(rows).spacing(2))
|
||||||
|
.height(sizing.height)
|
||||||
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let left = container(
|
let left = container(
|
||||||
|
|
@ -175,12 +178,12 @@ pub fn view_window<'a>(
|
||||||
.size(11)
|
.size(11)
|
||||||
.padding([5, 8]),
|
.padding([5, 8]),
|
||||||
container(state_list)
|
container(state_list)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(3)
|
.padding(3)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -188,10 +191,10 @@ pub fn view_window<'a>(
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(280)
|
.width(280)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 8.0,
|
right: 8.0,
|
||||||
|
|
@ -261,13 +264,13 @@ pub fn view_window<'a>(
|
||||||
.style(button_style(false))
|
.style(button_style(false))
|
||||||
.padding([5, 12]),
|
.padding([5, 12]),
|
||||||
edit.padding([5, 12]),
|
edit.padding([5, 12]),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
restore.padding([5, 12]),
|
restore.padding([5, 12]),
|
||||||
delete.padding([5, 12]),
|
delete.padding([5, 12]),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
divider(),
|
divider(sizing.width),
|
||||||
text("Name").size(10).style(muted),
|
text("Name").size(10).style(muted),
|
||||||
text_input("Layer state name", name)
|
text_input("Layer state name", name)
|
||||||
.on_input(Message::LayerStateManagerName)
|
.on_input(Message::LayerStateManagerName)
|
||||||
|
|
@ -281,7 +284,7 @@ pub fn view_window<'a>(
|
||||||
.padding([5, 8]),
|
.padding([5, 8]),
|
||||||
Space::new().height(8),
|
Space::new().height(8),
|
||||||
details,
|
details,
|
||||||
Space::new().height(Fill),
|
Space::new().height(sizing.height),
|
||||||
text("Layer states are stored inside the drawing and remain available after reopening it.")
|
text("Layer states are stored inside the drawing and remain available after reopening it.")
|
||||||
.size(10)
|
.size(10)
|
||||||
.style(muted),
|
.style(muted),
|
||||||
|
|
@ -296,15 +299,15 @@ pub fn view_window<'a>(
|
||||||
.padding([6, 14]),
|
.padding([6, 14]),
|
||||||
]
|
]
|
||||||
.spacing(7)
|
.spacing(7)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding([12, 12]);
|
.padding([12, 12]);
|
||||||
|
|
||||||
container(row![left, right].height(Fill))
|
container(row![left, right].height(sizing.height))
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,10 +383,10 @@ fn editor_header<'a>() -> Element<'a, Message> {
|
||||||
.padding([5, 8])
|
.padding([5, 8])
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color,
|
theme.palette().background.weak.color,
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 0.0.into(),
|
radius: 0.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -429,13 +432,13 @@ fn editor_layer_row<'a>(
|
||||||
54.0
|
54.0
|
||||||
),
|
),
|
||||||
container(color).width(Length::Fixed(135.0)),
|
container(color).width(Length::Fixed(135.0)),
|
||||||
pick_list(linetypes, current_linetype, move |value| {
|
crate::ui::pick_list(linetypes, current_linetype, move |value| {
|
||||||
Message::LayerStateEditorLayerLinetype(index, value)
|
Message::LayerStateEditorLayerLinetype(index, value)
|
||||||
})
|
})
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
.padding([3, 5])
|
.padding([3, 5])
|
||||||
.width(Length::Fixed(150.0)),
|
.width(Length::Fixed(150.0)),
|
||||||
pick_list(lw_options(), current_lineweight, move |item: LwItem| {
|
crate::ui::pick_list(lw_options(), current_lineweight, move |item: LwItem| {
|
||||||
Message::LayerStateEditorLayerLineweight(index, item.0)
|
Message::LayerStateEditorLayerLineweight(index, item.0)
|
||||||
})
|
})
|
||||||
.text_size(11)
|
.text_size(11)
|
||||||
|
|
@ -446,7 +449,7 @@ fn editor_layer_row<'a>(
|
||||||
.size(11)
|
.size(11)
|
||||||
.padding([3, 5])
|
.padding([3, 5])
|
||||||
.width(Length::Fixed(135.0)),
|
.width(Length::Fixed(135.0)),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
transparency_options(layer.transparency),
|
transparency_options(layer.transparency),
|
||||||
Some(TransparencyItem(layer.transparency)),
|
Some(TransparencyItem(layer.transparency)),
|
||||||
move |item| Message::LayerStateEditorLayerTransparency(index, item.0),
|
move |item| Message::LayerStateEditorLayerTransparency(index, item.0),
|
||||||
|
|
@ -461,7 +464,7 @@ fn editor_layer_row<'a>(
|
||||||
.padding([3, 8])
|
.padding([3, 8])
|
||||||
.style(move |theme: &Theme| container::Style {
|
.style(move |theme: &Theme| container::Style {
|
||||||
background: (index % 2 == 1).then_some(Background::Color(
|
background: (index % 2 == 1).then_some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color,
|
theme.palette().background.weak.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -474,6 +477,7 @@ pub fn view_editor<'a>(
|
||||||
filter: &'a str,
|
filter: &'a str,
|
||||||
color_open: Option<usize>,
|
color_open: Option<usize>,
|
||||||
linetypes: Vec<String>,
|
linetypes: Vec<String>,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let properties = [
|
let properties = [
|
||||||
("On / Off", LayerStateProperty::On),
|
("On / Off", LayerStateProperty::On),
|
||||||
|
|
@ -529,7 +533,7 @@ pub fn view_editor<'a>(
|
||||||
.on_input(Message::LayerStateEditorDescription)
|
.on_input(Message::LayerStateEditorDescription)
|
||||||
.size(11)
|
.size(11)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
|
|
@ -537,9 +541,9 @@ pub fn view_editor<'a>(
|
||||||
text(format!("{} saved layers", state.layers.len()))
|
text(format!("{} saved layers", state.layers.len()))
|
||||||
.size(10)
|
.size(10)
|
||||||
.style(muted),
|
.style(muted),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
text("Current layer").size(10).style(muted),
|
text("Current layer").size(10).style(muted),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
layer_names,
|
layer_names,
|
||||||
Some(state.current_layer.clone()),
|
Some(state.current_layer.clone()),
|
||||||
Message::LayerStateEditorCurrentLayer,
|
Message::LayerStateEditorCurrentLayer,
|
||||||
|
|
@ -550,12 +554,12 @@ pub fn view_editor<'a>(
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
divider(),
|
divider(sizing.width),
|
||||||
text("Properties restored by this state").size(10).style(muted),
|
text("Properties restored by this state").size(10).style(muted),
|
||||||
mask_controls,
|
mask_controls,
|
||||||
row![
|
row![
|
||||||
text("Saved layer values").size(12),
|
text("Saved layer values").size(12),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
text_input("Search layers…", filter)
|
text_input("Search layers…", filter)
|
||||||
.on_input(Message::LayerStateEditorFilter)
|
.on_input(Message::LayerStateEditorFilter)
|
||||||
.size(11)
|
.size(11)
|
||||||
|
|
@ -564,14 +568,14 @@ pub fn view_editor<'a>(
|
||||||
]
|
]
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
container(
|
container(
|
||||||
column![editor_header(), scrollable(rows).height(Fill)]
|
column![editor_header(), scrollable(rows).height(sizing.height)]
|
||||||
.spacing(0)
|
.spacing(0)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.neutral.color,
|
color: theme.palette().background.neutral.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -581,7 +585,7 @@ pub fn view_editor<'a>(
|
||||||
text("Changes affect the saved state only; the drawing is unchanged until Restore.")
|
text("Changes affect the saved state only; the drawing is unchanged until Restore.")
|
||||||
.size(10)
|
.size(10)
|
||||||
.style(muted),
|
.style(muted),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
button(text("Cancel").size(11))
|
button(text("Cancel").size(11))
|
||||||
.on_press(Message::LayerStateEditorCancel)
|
.on_press(Message::LayerStateEditorCancel)
|
||||||
.style(button_style(false))
|
.style(button_style(false))
|
||||||
|
|
@ -595,10 +599,10 @@ pub fn view_editor<'a>(
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.padding(12)
|
.padding(12)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ pub const LAYER_TABLE_SCROLL_ID: &str = "layer-manager-table-scroll";
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ fn table_input_style(
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
status: iced::widget::text_input::Status,
|
status: iced::widget::text_input::Status,
|
||||||
) -> iced::widget::text_input::Style {
|
) -> iced::widget::text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
iced::widget::text_input::Status::Focused { .. } => palette.primary.base.color,
|
iced::widget::text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -308,11 +308,19 @@ impl LayerPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the layer panel as the full content of its own OS window.
|
/// Render the layer panel as the full content of its own OS window.
|
||||||
pub fn view_window(&self, name_col_w: f32) -> Element<'_, Message> {
|
pub fn view_window(
|
||||||
self.view_content(name_col_w)
|
&self,
|
||||||
|
name_col_w: f32,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'_, Message> {
|
||||||
|
self.view_content(name_col_w, sizing)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_content(&self, name_col_w: f32) -> Element<'_, Message> {
|
fn view_content(
|
||||||
|
&self,
|
||||||
|
name_col_w: f32,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'_, Message> {
|
||||||
let has_sel = self.selected.is_some();
|
let has_sel = self.selected.is_some();
|
||||||
let sel_is_zero = self
|
let sel_is_zero = self
|
||||||
.selected
|
.selected
|
||||||
|
|
@ -335,7 +343,7 @@ impl LayerPanel {
|
||||||
Message::LayerSetCurrent,
|
Message::LayerSetCurrent,
|
||||||
has_sel,
|
has_sel,
|
||||||
),
|
),
|
||||||
iced::widget::Space::new().width(Fill),
|
iced::widget::Space::new().width(sizing.width),
|
||||||
// Search box: filters rows by name as the user types (#343).
|
// Search box: filters rows by name as the user types (#343).
|
||||||
text_input("Search…", &self.filter)
|
text_input("Search…", &self.filter)
|
||||||
.on_input(Message::LayerManagerFilterChanged)
|
.on_input(Message::LayerManagerFilterChanged)
|
||||||
|
|
@ -349,11 +357,11 @@ impl LayerPanel {
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([4, 8]);
|
.padding([4, 8]);
|
||||||
|
|
||||||
// ── Column header ─────────────────────────────────────────────────
|
// ── Column header ─────────────────────────────────────────────────
|
||||||
|
|
@ -367,7 +375,7 @@ impl LayerPanel {
|
||||||
container(iced::widget::Space::new().width(2).height(14)).style(
|
container(iced::widget::Space::new().width(2).height(14)).style(
|
||||||
|theme: &Theme| container::Style {
|
|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
@ -390,7 +398,7 @@ impl LayerPanel {
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.align_y(iced::Center);
|
.align_y(iced::Center);
|
||||||
|
|
||||||
for vp in &self.vp_cols {
|
for vp in &self.vp_cols {
|
||||||
|
|
@ -404,7 +412,7 @@ impl LayerPanel {
|
||||||
|
|
||||||
let col_header = container(header_row)
|
let col_header = container(header_row)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -416,7 +424,7 @@ impl LayerPanel {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill);
|
.width(sizing.width);
|
||||||
|
|
||||||
// ── Layer rows ────────────────────────────────────────────────────
|
// ── Layer rows ────────────────────────────────────────────────────
|
||||||
let mut rows_col = column![].spacing(0);
|
let mut rows_col = column![].spacing(0);
|
||||||
|
|
@ -457,18 +465,18 @@ impl LayerPanel {
|
||||||
|
|
||||||
let table = scrollable(rows_col)
|
let table = scrollable(rows_col)
|
||||||
.id(iced::advanced::widget::Id::new(LAYER_TABLE_SCROLL_ID))
|
.id(iced::advanced::widget::Id::new(LAYER_TABLE_SCROLL_ID))
|
||||||
.height(Fill);
|
.height(sizing.height.min(240.0));
|
||||||
|
|
||||||
// ── Full-window frame ─────────────────────────────────────────────
|
// ── Full-window frame ─────────────────────────────────────────────
|
||||||
container(column![toolbar, col_header, table].spacing(0))
|
container(column![toolbar, col_header, table].spacing(0))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -481,7 +489,7 @@ fn layer_cell_button_style(
|
||||||
is_selected: bool,
|
is_selected: bool,
|
||||||
index: usize,
|
index: usize,
|
||||||
) -> button::Style {
|
) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let highlighted = matches!(status, button::Status::Hovered);
|
let highlighted = matches!(status, button::Status::Hovered);
|
||||||
let pair = if highlighted {
|
let pair = if highlighted {
|
||||||
palette.background.strong
|
palette.background.strong
|
||||||
|
|
@ -500,7 +508,7 @@ fn layer_cell_button_style(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layer_header_button_style(theme: &Theme, status: button::Status) -> button::Style {
|
fn layer_header_button_style(theme: &Theme, status: button::Status) -> button::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let highlighted = matches!(
|
let highlighted = matches!(
|
||||||
status,
|
status,
|
||||||
button::Status::Hovered | button::Status::Pressed
|
button::Status::Hovered | button::Status::Pressed
|
||||||
|
|
@ -568,7 +576,7 @@ fn toolbar_btn<'a>(icon: &'static [u8], label: &'a str, msg: Message) -> Element
|
||||||
)
|
)
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.style(|theme: &Theme, status| {
|
.style(|theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered | button::Status::Pressed => {
|
button::Status::Hovered | button::Status::Pressed => {
|
||||||
palette.background.strong
|
palette.background.strong
|
||||||
|
|
@ -608,7 +616,7 @@ fn toolbar_btn_cond<'a>(
|
||||||
} else {
|
} else {
|
||||||
text(label).size(11).style(|theme: &Theme| iced::widget::text::Style {
|
text(label).size(11).style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(
|
color: Some(
|
||||||
theme.extended_palette().background.base.text.scale_alpha(0.42)
|
theme.palette().background.base.text.scale_alpha(0.42)
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -617,7 +625,7 @@ fn toolbar_btn_cond<'a>(
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
)
|
)
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match status {
|
let pair = match status {
|
||||||
button::Status::Hovered if enabled => palette.background.strong,
|
button::Status::Hovered if enabled => palette.background.strong,
|
||||||
_ => palette.background.weak,
|
_ => palette.background.weak,
|
||||||
|
|
@ -657,7 +665,7 @@ fn name_tip<'a>(name: &'a str) -> Element<'a, Message> {
|
||||||
right: 7.0,
|
right: 7.0,
|
||||||
})
|
})
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.strong.color)),
|
background: Some(Background::Color(palette.background.strong.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -891,7 +899,7 @@ fn layer_row<'a>(
|
||||||
mouse_area(
|
mouse_area(
|
||||||
container(row_content)
|
container(row_content)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if is_selected {
|
let pair = if is_selected {
|
||||||
palette.primary.weak
|
palette.primary.weak
|
||||||
} else if index % 2 == 0 {
|
} else if index % 2 == 0 {
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
||||||
use iced::{Background, Element, Fill, Theme};
|
use iced::{Background, Element, Theme};
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,26 +36,26 @@ fn list_item(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hdivider<'a>() -> Element<'a, Message> {
|
fn hdivider<'a>(width: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color,
|
theme.palette().background.neutral.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vsep<'a>() -> Element<'a, Message> {
|
fn vsep<'a>(height: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(1).height(Fill))
|
container(Space::new().width(1).height(height))
|
||||||
.width(1)
|
.width(1)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color,
|
theme.palette().background.neutral.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -67,6 +67,7 @@ pub fn view_window<'a>(
|
||||||
selected: &'a str,
|
selected: &'a str,
|
||||||
rename_buf: &'a str,
|
rename_buf: &'a str,
|
||||||
current: String,
|
current: String,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let is_model = selected == "Model";
|
let is_model = selected == "Model";
|
||||||
|
|
||||||
|
|
@ -87,7 +88,7 @@ pub fn view_window<'a>(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding([4, 10]),
|
.padding([4, 10]),
|
||||||
Space::new().width(Fill),
|
Space::new().width(sizing.width),
|
||||||
button(
|
button(
|
||||||
row![
|
row![
|
||||||
crate::ui::icons::themed_arrow_left(9.0),
|
crate::ui::icons::themed_arrow_left(9.0),
|
||||||
|
|
@ -120,11 +121,11 @@ pub fn view_window<'a>(
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weakest.color,
|
theme.palette().background.weakest.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([5, 8]);
|
.padding([5, 8]);
|
||||||
|
|
||||||
// ── Left: Layout list ─────────────────────────────────────────────────
|
// ── Left: Layout list ─────────────────────────────────────────────────
|
||||||
|
|
@ -143,7 +144,7 @@ pub fn view_window<'a>(
|
||||||
.on_press(Message::LayoutManagerSelect(name.clone()))
|
.on_press(Message::LayoutManagerSelect(name.clone()))
|
||||||
.style(list_item(is_sel))
|
.style(list_item(is_sel))
|
||||||
.padding([5, 10])
|
.padding([5, 10])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -151,17 +152,17 @@ pub fn view_window<'a>(
|
||||||
let layout_list = container(
|
let layout_list = container(
|
||||||
column![
|
column![
|
||||||
text("Layouts").size(10).style(muted_style),
|
text("Layouts").size(10).style(muted_style),
|
||||||
container(scrollable(column(list_items).spacing(2)).height(Fill))
|
container(scrollable(column(list_items).spacing(2)).height(sizing.height))
|
||||||
.style(container::bordered_box)
|
.style(container::bordered_box)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.height(Fill),
|
.height(sizing.height),
|
||||||
)
|
)
|
||||||
.width(220)
|
.width(220)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 8.0,
|
right: 8.0,
|
||||||
|
|
@ -221,19 +222,19 @@ pub fn view_window<'a>(
|
||||||
]
|
]
|
||||||
.spacing(8),
|
.spacing(8),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([12, 12]);
|
.padding([12, 12]);
|
||||||
|
|
||||||
let body = row![layout_list, vsep(), details].height(Fill);
|
let body = row![layout_list, vsep(sizing.height), details].height(sizing.height);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), body].spacing(0))
|
container(column![toolbar, hdivider(sizing.width), body].spacing(0))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Messag
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().primary.base.color
|
theme.palette().primary.base.color
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
|
|
@ -85,7 +85,7 @@ pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Messag
|
||||||
container(Space::new().width(Length::Fixed(BAR_TRACK_WIDTH)).height(Length::Fixed(BAR_TRACK_HEIGHT)))
|
container(Space::new().width(Length::Fixed(BAR_TRACK_WIDTH)).height(Length::Fixed(BAR_TRACK_HEIGHT)))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.strong.color
|
theme.palette().background.strong.color
|
||||||
)),
|
)),
|
||||||
border: Border {
|
border: Border {
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
|
|
@ -110,7 +110,7 @@ pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Messag
|
||||||
))
|
))
|
||||||
.size(13)
|
.size(13)
|
||||||
.style(|theme: &Theme| iced::widget::text::Style {
|
.style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.82)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.82)),
|
||||||
});
|
});
|
||||||
|
|
||||||
let phase_line = text(format!(
|
let phase_line = text(format!(
|
||||||
|
|
@ -120,7 +120,7 @@ pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Messag
|
||||||
))
|
))
|
||||||
.size(12)
|
.size(12)
|
||||||
.style(|theme: &Theme| iced::widget::text::Style {
|
.style(|theme: &Theme| iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
});
|
});
|
||||||
|
|
||||||
let cancel_btn: Element<'_, Message> = button(text("Cancel").size(12))
|
let cancel_btn: Element<'_, Message> = button(text("Cancel").size(12))
|
||||||
|
|
@ -138,7 +138,7 @@ pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Messag
|
||||||
)
|
)
|
||||||
.padding([18, 22])
|
.padding([18, 22])
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -154,7 +154,7 @@ pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Messag
|
||||||
let backdrop: Element<'_, Message> = container(Space::new().width(Fill).height(Fill))
|
let backdrop: Element<'_, Message> = container(Space::new().width(Fill).height(Fill))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.strong.color.scale_alpha(0.72)
|
theme.palette().background.strong.color.scale_alpha(0.72)
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
use crate::app::config::UiThemeConfig;
|
use crate::app::config::UiThemeConfig;
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, column, container, pick_list, row, scrollable, text, text_input, Space,
|
button, column, container, row, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
pub fn view_window<'a>(
|
pub fn view_window<'a>(
|
||||||
default_save_format: &'a str,
|
default_save_format: &'a str,
|
||||||
ui_theme: &'a UiThemeConfig,
|
ui_theme: &'a UiThemeConfig,
|
||||||
theme_color_inputs: &'a [String; 6],
|
theme_color_inputs: &'a [String; 6],
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let selected_format = crate::io::SAVE_FORMAT_OPTIONS
|
let selected_format = crate::io::SAVE_FORMAT_OPTIONS
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -40,7 +41,7 @@ pub fn view_window<'a>(
|
||||||
.style(move |theme: &Theme| container::Style {
|
.style(move |theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(color)),
|
background: Some(Background::Color(color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
color: theme.extended_palette().background.strong.color,
|
color: theme.palette().background.strong.color,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
},
|
},
|
||||||
|
|
@ -69,12 +70,12 @@ pub fn view_window<'a>(
|
||||||
Space::new().height(10),
|
Space::new().height(10),
|
||||||
row![
|
row![
|
||||||
text("Default save format:").size(12).width(150),
|
text("Default save format:").size(12).width(150),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
crate::io::SAVE_FORMAT_OPTIONS,
|
crate::io::SAVE_FORMAT_OPTIONS,
|
||||||
selected_format,
|
selected_format,
|
||||||
|format: &str| Message::DefaultSaveFormatChanged(format.to_string())
|
|format: &str| Message::DefaultSaveFormatChanged(format.to_string())
|
||||||
)
|
)
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.spacing(12)
|
.spacing(12)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
|
|
@ -82,18 +83,19 @@ pub fn view_window<'a>(
|
||||||
text(
|
text(
|
||||||
"Used for the first save of a new drawing. Existing drawings keep their file type and version."
|
"Used for the first save of a new drawing. Existing drawings keep their file type and version."
|
||||||
)
|
)
|
||||||
.size(11),
|
.size(11)
|
||||||
|
.width(sizing.width),
|
||||||
Space::new().height(22),
|
Space::new().height(22),
|
||||||
text("Theme").size(15),
|
text("Theme").size(15),
|
||||||
Space::new().height(10),
|
Space::new().height(10),
|
||||||
row![
|
row![
|
||||||
text("Iced theme:").size(12).width(150),
|
text("Iced theme:").size(12).width(150),
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
theme_options,
|
theme_options,
|
||||||
selected_theme,
|
selected_theme,
|
||||||
Message::OptionsThemeChanged,
|
Message::OptionsThemeChanged,
|
||||||
)
|
)
|
||||||
.width(Fill),
|
.width(sizing.width),
|
||||||
]
|
]
|
||||||
.spacing(12)
|
.spacing(12)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
|
|
@ -101,25 +103,26 @@ pub fn view_window<'a>(
|
||||||
text(
|
text(
|
||||||
"Changing a base colour switches to Custom. Iced generates every component shade from these six colours."
|
"Changing a base colour switches to Custom. Iced generates every component shade from these six colours."
|
||||||
)
|
)
|
||||||
.size(11),
|
.size(11)
|
||||||
|
.width(sizing.width),
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
color_controls,
|
color_controls,
|
||||||
]
|
]
|
||||||
.spacing(0)
|
.spacing(0)
|
||||||
.width(Fill);
|
.width(sizing.width);
|
||||||
|
|
||||||
let body = column![
|
let body = column![
|
||||||
scrollable(content).height(Fill),
|
scrollable(content).height(sizing.height),
|
||||||
Space::new().height(12),
|
Space::new().height(12),
|
||||||
row![Space::new().width(Fill), close],
|
row![Space::new().width(sizing.width), close],
|
||||||
]
|
]
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill);
|
.height(sizing.height);
|
||||||
|
|
||||||
container(body)
|
container(body)
|
||||||
.style(container::rounded_box)
|
.style(container::rounded_box)
|
||||||
.padding([16, 18])
|
.padding([16, 18])
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use crate::io::paper_sizes::PaperSize;
|
use crate::io::paper_sizes::PaperSize;
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, checkbox, column, container, mouse_area, pick_list, row, scrollable, text, text_input,
|
button, checkbox, column, container, mouse_area, row, scrollable, text, text_input,
|
||||||
Space,
|
Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Length, Theme};
|
use iced::{Background, Border, Element, Fit, Length, Theme};
|
||||||
|
|
||||||
/// Sentinel entries in the printer dropdown (not real printer names).
|
/// Sentinel entries in the printer dropdown (not real printer names).
|
||||||
pub const OUT_DEFAULT: &str = "System default printer";
|
pub const OUT_DEFAULT: &str = "System default printer";
|
||||||
|
|
@ -212,7 +212,7 @@ impl PlotDialogState {
|
||||||
|
|
||||||
fn btn(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn btn(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
move |theme: &Theme, st| {
|
move |theme: &Theme, st| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match (accent, st) {
|
let pair = match (accent, st) {
|
||||||
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
||||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||||
|
|
@ -236,7 +236,7 @@ fn btn(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let border = match status {
|
let border = match status {
|
||||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||||
_ => palette.background.neutral.color,
|
_ => palette.background.neutral.color,
|
||||||
|
|
@ -253,17 +253,17 @@ fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hdivider<'a>() -> Element<'a, Message> {
|
fn hdivider<'a>(width: Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -274,13 +274,13 @@ fn section_label<'a>(s: &'static str) -> Element<'a, Message> {
|
||||||
text(s).size(11).style(muted_style).into()
|
text(s).size(11).style(muted_style).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vsep<'a>() -> Element<'a, Message> {
|
fn vsep<'a>(height: Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(1).height(Fill))
|
container(Space::new().width(1).height(height))
|
||||||
.width(1)
|
.width(1)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color
|
theme.palette().background.neutral.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -302,15 +302,15 @@ fn setup_row<'a>(
|
||||||
.style(field_style)
|
.style(field_style)
|
||||||
.size(11)
|
.size(11)
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill)
|
.width(Fit)
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
let is_sel = name == selected;
|
let is_sel = name == selected;
|
||||||
let cell = container(text(name.to_string()).size(11))
|
let cell = container(text(name.to_string()).size(11))
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill)
|
.width(Fit)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: is_sel.then_some(Background::Color(palette.primary.strong.color)),
|
background: is_sel.then_some(Background::Color(palette.primary.strong.color)),
|
||||||
text_color: is_sel.then_some(palette.primary.strong.text),
|
text_color: is_sel.then_some(palette.primary.strong.text),
|
||||||
|
|
@ -330,11 +330,12 @@ fn drop_row<'a>(
|
||||||
options: Vec<String>,
|
options: Vec<String>,
|
||||||
selected: Option<String>,
|
selected: Option<String>,
|
||||||
ctor: fn(String) -> PlotDlgMsg,
|
ctor: fn(String) -> PlotDlgMsg,
|
||||||
|
width: Length,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let pl = pick_list(options, selected, move |s| Message::PlotDlg(ctor(s)))
|
let pl = crate::ui::pick_list(options, selected, move |s| Message::PlotDlg(ctor(s)))
|
||||||
.text_size(12)
|
.text_size(12)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Length::Fill);
|
.width(width);
|
||||||
row![text(label).size(11).style(muted_style).width(92), pl]
|
row![text(label).size(11).style(muted_style).width(92), pl]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
|
|
@ -375,7 +376,12 @@ fn strs(items: &[&str]) -> Vec<String> {
|
||||||
items.iter().map(|s| s.to_string()).collect()
|
items.iter().map(|s| s.to_string()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
pub fn view_window(
|
||||||
|
s: &PlotDialogState,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'_, Message> {
|
||||||
|
let width = sizing.width;
|
||||||
|
let height = sizing.height;
|
||||||
// ── Toolbar: Cancel … Preview Print/Export ──────────────────────────
|
// ── Toolbar: Cancel … Preview Print/Export ──────────────────────────
|
||||||
let action = if s.to_file { "Export PDF" } else { "Print" };
|
let action = if s.to_file { "Export PDF" } else { "Print" };
|
||||||
// `<none>` / `<previous>` are pseudo-entries; layout rows are `*name*`.
|
// `<none>` / `<previous>` are pseudo-entries; layout rows are `*name*`.
|
||||||
|
|
@ -409,7 +415,7 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
let toolbar = container(
|
let toolbar = container(
|
||||||
row![
|
row![
|
||||||
left_bar,
|
left_bar,
|
||||||
Space::new().width(Fill),
|
Space::new().width(width),
|
||||||
button(text("Set current").size(11))
|
button(text("Set current").size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::SetCurrent))
|
.on_press(Message::PlotDlg(PlotDlgMsg::SetCurrent))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
|
|
@ -429,11 +435,11 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weak.color
|
theme.palette().background.weak.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.padding([5, 10]);
|
.padding([5, 10]);
|
||||||
|
|
||||||
// ── Printer dropdown: default + discovered printers + PDF sentinel ────
|
// ── Printer dropdown: default + discovered printers + PDF sentinel ────
|
||||||
|
|
@ -465,14 +471,14 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
.padding([6, 8])
|
.padding([6, 8])
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
scrollable(column(rows).spacing(1)).height(Fill).into()
|
scrollable(column(rows).spacing(1)).height(height).into()
|
||||||
};
|
};
|
||||||
let list_panel = container(
|
let list_panel = container(
|
||||||
column![
|
column![
|
||||||
text("Page setups").size(10).style(muted_style),
|
text("Page setups").size(10).style(muted_style),
|
||||||
container(list_body)
|
container(list_body)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -483,15 +489,15 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(Length::Fill)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.padding(2),
|
.padding(2),
|
||||||
]
|
]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.height(Fill),
|
.height(height),
|
||||||
)
|
)
|
||||||
.width(160)
|
.width(160)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 12.0,
|
top: 12.0,
|
||||||
right: 8.0,
|
right: 8.0,
|
||||||
|
|
@ -507,37 +513,39 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
};
|
};
|
||||||
let left = column![
|
let left = column![
|
||||||
section_label("Printer / plotter"),
|
section_label("Printer / plotter"),
|
||||||
drop_row("Output", printer_opts, printer_sel, PlotDlgMsg::Printer),
|
drop_row("Output", printer_opts, printer_sel, PlotDlgMsg::Printer, width),
|
||||||
field_row("Copies", &s.copies, PlotDlgMsg::Copies, 60),
|
field_row("Copies", &s.copies, PlotDlgMsg::Copies, 60),
|
||||||
hdivider(),
|
hdivider(width),
|
||||||
section_label("Paper"),
|
section_label("Paper"),
|
||||||
drop_row("Size", paper_opts, Some(s.paper.clone()), PlotDlgMsg::Paper),
|
drop_row("Size", paper_opts, Some(s.paper.clone()), PlotDlgMsg::Paper, width),
|
||||||
drop_row(
|
drop_row(
|
||||||
"Orientation",
|
"Orientation",
|
||||||
strs(&["Portrait", "Landscape"]),
|
strs(&["Portrait", "Landscape"]),
|
||||||
Some(s.orientation.clone()),
|
Some(s.orientation.clone()),
|
||||||
PlotDlgMsg::Orientation,
|
PlotDlgMsg::Orientation,
|
||||||
|
width,
|
||||||
),
|
),
|
||||||
drop_row(
|
drop_row(
|
||||||
"Rotation",
|
"Rotation",
|
||||||
strs(&["0°", "90°", "180°", "270°"]),
|
strs(&["0°", "90°", "180°", "270°"]),
|
||||||
Some(s.rotation.clone()),
|
Some(s.rotation.clone()),
|
||||||
PlotDlgMsg::Rotation,
|
PlotDlgMsg::Rotation,
|
||||||
|
width,
|
||||||
),
|
),
|
||||||
hdivider(),
|
hdivider(width),
|
||||||
section_label("Plot area"),
|
section_label("Plot area"),
|
||||||
row![
|
row![
|
||||||
container(
|
container(
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
strs(&["Layout", "Extents", "Display", "Window"]),
|
strs(&["Layout", "Extents", "Display", "Window"]),
|
||||||
Some(s.area.clone()),
|
Some(s.area.clone()),
|
||||||
move |v| Message::PlotDlg(PlotDlgMsg::Area(v)),
|
move |v| Message::PlotDlg(PlotDlgMsg::Area(v)),
|
||||||
)
|
)
|
||||||
.text_size(12)
|
.text_size(12)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
)
|
)
|
||||||
.width(Fill),
|
.width(width),
|
||||||
button(text("Pick…").size(11))
|
button(text("Pick…").size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::PickWindow))
|
.on_press(Message::PlotDlg(PlotDlgMsg::PickWindow))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
|
|
@ -554,7 +562,7 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
check("Center the plot", s.center, PlotFlag::Center),
|
check("Center the plot", s.center, PlotFlag::Center),
|
||||||
]
|
]
|
||||||
.spacing(9)
|
.spacing(9)
|
||||||
.width(Fill);
|
.width(width);
|
||||||
|
|
||||||
// ── Right column ─────────────────────────────────────────────────────
|
// ── Right column ─────────────────────────────────────────────────────
|
||||||
let right = column![
|
let right = column![
|
||||||
|
|
@ -564,14 +572,15 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
strs(&["Fit", "1:1", "1:2", "1:5", "1:10", "1:20", "1:50", "1:100", "2:1"]),
|
strs(&["Fit", "1:1", "1:2", "1:5", "1:10", "1:20", "1:50", "1:100", "2:1"]),
|
||||||
Some(s.scale.clone()),
|
Some(s.scale.clone()),
|
||||||
PlotDlgMsg::Scale,
|
PlotDlgMsg::Scale,
|
||||||
|
width,
|
||||||
),
|
),
|
||||||
check("Scale lineweights", s.scale_lw, PlotFlag::ScaleLw),
|
check("Scale lineweights", s.scale_lw, PlotFlag::ScaleLw),
|
||||||
hdivider(),
|
hdivider(width),
|
||||||
section_label("Plot style table (pen assignments)"),
|
section_label("Plot style table (pen assignments)"),
|
||||||
row![
|
row![
|
||||||
container(text(style_label).size(12))
|
container(text(style_label).size(12))
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(palette.background.base.color)),
|
background: Some(Background::Color(palette.background.base.color)),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -583,7 +592,7 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.padding([4, 8])
|
.padding([4, 8])
|
||||||
.width(Fill),
|
.width(width),
|
||||||
button(text("Load…").size(11))
|
button(text("Load…").size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::LoadStyle))
|
.on_press(Message::PlotDlg(PlotDlgMsg::LoadStyle))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
|
|
@ -595,20 +604,20 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.align_y(iced::Center),
|
.align_y(iced::Center),
|
||||||
hdivider(),
|
hdivider(width),
|
||||||
section_label("Quality"),
|
section_label("Quality"),
|
||||||
row![
|
row![
|
||||||
container(
|
container(
|
||||||
pick_list(
|
crate::ui::pick_list(
|
||||||
strs(&["Draft", "Normal", "High", "Maximum"]),
|
strs(&["Draft", "Normal", "High", "Maximum"]),
|
||||||
Some(s.quality.clone()),
|
Some(s.quality.clone()),
|
||||||
move |v| Message::PlotDlg(PlotDlgMsg::Quality(v)),
|
move |v| Message::PlotDlg(PlotDlgMsg::Quality(v)),
|
||||||
)
|
)
|
||||||
.text_size(12)
|
.text_size(12)
|
||||||
.padding([3, 6])
|
.padding([3, 6])
|
||||||
.width(Length::Fill)
|
.width(width)
|
||||||
)
|
)
|
||||||
.width(Fill),
|
.width(width),
|
||||||
text("DPI").size(11).style(muted_style),
|
text("DPI").size(11).style(muted_style),
|
||||||
text_input("", &s.dpi)
|
text_input("", &s.dpi)
|
||||||
.on_input(move |v| Message::PlotDlg(PlotDlgMsg::Dpi(v)))
|
.on_input(move |v| Message::PlotDlg(PlotDlgMsg::Dpi(v)))
|
||||||
|
|
@ -623,8 +632,9 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
strs(&["As displayed", "Wireframe", "Hidden", "Rendered"]),
|
strs(&["As displayed", "Wireframe", "Hidden", "Rendered"]),
|
||||||
Some(s.shade.clone()),
|
Some(s.shade.clone()),
|
||||||
PlotDlgMsg::Shade,
|
PlotDlgMsg::Shade,
|
||||||
|
width,
|
||||||
),
|
),
|
||||||
hdivider(),
|
hdivider(width),
|
||||||
section_label("Plot options"),
|
section_label("Plot options"),
|
||||||
row![
|
row![
|
||||||
column![
|
column![
|
||||||
|
|
@ -634,7 +644,7 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
check("Plot transparency", s.transparency, PlotFlag::Transparency),
|
check("Plot transparency", s.transparency, PlotFlag::Transparency),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.width(Fill),
|
.width(width),
|
||||||
column![
|
column![
|
||||||
check("Paperspace last", s.paperspace_last, PlotFlag::PaperspaceLast),
|
check("Paperspace last", s.paperspace_last, PlotFlag::PaperspaceLast),
|
||||||
check("Hide paperspace", s.hide_paperspace, PlotFlag::HidePaperspace),
|
check("Hide paperspace", s.hide_paperspace, PlotFlag::HidePaperspace),
|
||||||
|
|
@ -642,28 +652,30 @@ pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
||||||
check("Save to layout", s.save_layout, PlotFlag::SaveLayout),
|
check("Save to layout", s.save_layout, PlotFlag::SaveLayout),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(6)
|
||||||
.width(Fill),
|
.width(width),
|
||||||
]
|
]
|
||||||
.spacing(10),
|
.spacing(10),
|
||||||
]
|
]
|
||||||
.spacing(9)
|
.spacing(9)
|
||||||
.width(Fill);
|
.width(width);
|
||||||
|
|
||||||
let detail = scrollable(
|
let detail = scrollable(
|
||||||
container(row![left, right].spacing(18).width(Fill)).padding(14),
|
container(row![left, right].spacing(18).width(width)).padding(14),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill);
|
.height(height);
|
||||||
let body = row![list_panel, vsep(), detail].height(Fill);
|
let body = row![list_panel, vsep(height), detail]
|
||||||
|
.width(width)
|
||||||
|
.height(height);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), body].spacing(0))
|
container(column![toolbar, hdivider(width), body].spacing(0))
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color
|
theme.palette().background.base.color
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use crate::plugin::external::{ExternalPlugin, RegistryEntry};
|
use crate::plugin::external::{ExternalPlugin, RegistryEntry};
|
||||||
use iced::widget::{
|
use iced::widget::{
|
||||||
button, column, container, markdown, pick_list, row, rule, scrollable, text, text_input, Space,
|
button, column, container, markdown, row, rule, scrollable, text, text_input, Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, Fill, Length, Theme};
|
use iced::{Background, Border, Element, Fill, Length, Theme};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
@ -48,13 +48,13 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ fn badge<'a>(label: String) -> Element<'a, Message> {
|
||||||
container(text(label).size(11))
|
container(text(label).size(11))
|
||||||
.padding([2, 8])
|
.padding([2, 8])
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let pair = theme.extended_palette().primary.weak;
|
let pair = theme.palette().primary.weak;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(pair.color)),
|
background: Some(Background::Color(pair.color)),
|
||||||
text_color: Some(pair.text),
|
text_color: Some(pair.text),
|
||||||
|
|
@ -105,7 +105,7 @@ fn status_badge<'a>(label: &str, kind: StatusKind) -> Element<'a, Message> {
|
||||||
container(text(label.to_string()).size(11))
|
container(text(label.to_string()).size(11))
|
||||||
.padding([2, 8])
|
.padding([2, 8])
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = match kind {
|
let pair = match kind {
|
||||||
StatusKind::Muted => palette.background.weak,
|
StatusKind::Muted => palette.background.weak,
|
||||||
StatusKind::Success => palette.success.weak,
|
StatusKind::Success => palette.success.weak,
|
||||||
|
|
@ -126,7 +126,7 @@ fn status_badge<'a>(label: &str, kind: StatusKind) -> Element<'a, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn card_style(theme: &Theme, selected: bool) -> container::Style {
|
fn card_style(theme: &Theme, selected: bool) -> container::Style {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
container::Style {
|
container::Style {
|
||||||
background: selected
|
background: selected
|
||||||
.then(|| Background::Color(palette.primary.weak.color.scale_alpha(0.18))),
|
.then(|| Background::Color(palette.primary.weak.color.scale_alpha(0.18))),
|
||||||
|
|
@ -325,7 +325,7 @@ fn install_controls<'a>(
|
||||||
text("no releases").size(11).style(muted_style).into()
|
text("no releases").size(11).style(muted_style).into()
|
||||||
} else {
|
} else {
|
||||||
let r = repo_s.clone();
|
let r = repo_s.clone();
|
||||||
pick_list(tags, selected, move |tag| {
|
crate::ui::pick_list(tags, selected, move |tag| {
|
||||||
Message::PluginReleaseSelect(r.clone(), tag)
|
Message::PluginReleaseSelect(r.clone(), tag)
|
||||||
})
|
})
|
||||||
.text_size(12)
|
.text_size(12)
|
||||||
|
|
@ -490,7 +490,7 @@ fn registry_notice<'a>(m: &MarketView) -> Option<Element<'a, Message>> {
|
||||||
container(body.padding([10, 12]))
|
container(body.padding([10, 12]))
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.style(|theme: &Theme| {
|
.style(|theme: &Theme| {
|
||||||
let pair = theme.extended_palette().warning.weak;
|
let pair = theme.palette().warning.weak;
|
||||||
container::Style {
|
container::Style {
|
||||||
background: Some(Background::Color(pair.color.scale_alpha(0.16))),
|
background: Some(Background::Color(pair.color.scale_alpha(0.16))),
|
||||||
border: Border {
|
border: Border {
|
||||||
|
|
@ -638,7 +638,12 @@ fn resolve_readme_link(repo: &str, uri: &str) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readme_panel<'a>(market: &MarketView<'a>, theme: &Theme) -> Element<'a, Message> {
|
fn readme_panel<'a>(
|
||||||
|
market: &MarketView<'a>,
|
||||||
|
theme: &Theme,
|
||||||
|
width: Length,
|
||||||
|
height: Length,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
let Some(repo) = market.selected_repo else {
|
let Some(repo) = market.selected_repo else {
|
||||||
return container(
|
return container(
|
||||||
column![
|
column![
|
||||||
|
|
@ -649,9 +654,10 @@ fn readme_panel<'a>(market: &MarketView<'a>, theme: &Theme) -> Element<'a, Messa
|
||||||
]
|
]
|
||||||
.spacing(8),
|
.spacing(8),
|
||||||
)
|
)
|
||||||
.center(Fill)
|
.center_x(width)
|
||||||
.width(Fill)
|
.center_y(height)
|
||||||
.height(Fill)
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.style(container::bordered_box)
|
.style(container::bordered_box)
|
||||||
.into();
|
.into();
|
||||||
};
|
};
|
||||||
|
|
@ -667,7 +673,7 @@ fn readme_panel<'a>(market: &MarketView<'a>, theme: &Theme) -> Element<'a, Messa
|
||||||
text(repo.to_string()).size(11).style(primary_style),
|
text(repo.to_string()).size(11).style(primary_style),
|
||||||
]
|
]
|
||||||
.spacing(3)
|
.spacing(3)
|
||||||
.width(Fill),
|
.width(width),
|
||||||
pill_button(
|
pill_button(
|
||||||
"View on GitHub",
|
"View on GitHub",
|
||||||
Message::OpenUrl(format!("https://github.com/{repo}")),
|
Message::OpenUrl(format!("https://github.com/{repo}")),
|
||||||
|
|
@ -686,9 +692,10 @@ fn readme_panel<'a>(market: &MarketView<'a>, theme: &Theme) -> Element<'a, Messa
|
||||||
]
|
]
|
||||||
.spacing(6),
|
.spacing(6),
|
||||||
)
|
)
|
||||||
.center(Fill)
|
.center_x(width)
|
||||||
.width(Fill)
|
.center_y(height)
|
||||||
.height(Fill)
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
match market.readmes.get(repo) {
|
match market.readmes.get(repo) {
|
||||||
|
|
@ -715,18 +722,20 @@ fn readme_panel<'a>(market: &MarketView<'a>, theme: &Theme) -> Element<'a, Messa
|
||||||
]
|
]
|
||||||
.spacing(6),
|
.spacing(6),
|
||||||
)
|
)
|
||||||
.center(Fill)
|
.center_x(width)
|
||||||
.width(Fill)
|
.center_y(height)
|
||||||
.height(Fill)
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into(),
|
.into(),
|
||||||
None => container(
|
None => container(
|
||||||
text("Select the plugin again to load its README.")
|
text("Select the plugin again to load its README.")
|
||||||
.size(12)
|
.size(12)
|
||||||
.style(muted_style),
|
.style(muted_style),
|
||||||
)
|
)
|
||||||
.center(Fill)
|
.center_x(width)
|
||||||
.width(Fill)
|
.center_y(height)
|
||||||
.height(Fill)
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -738,18 +747,18 @@ fn readme_panel<'a>(market: &MarketView<'a>, theme: &Theme) -> Element<'a, Messa
|
||||||
left: 0.0,
|
left: 0.0,
|
||||||
};
|
};
|
||||||
let readme = scrollable(container(content).padding(gutter))
|
let readme = scrollable(container(content).padding(gutter))
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.width(Fill);
|
.width(width);
|
||||||
|
|
||||||
container(
|
container(
|
||||||
column![header, rule::horizontal(1), readme]
|
column![header, rule::horizontal(1), readme]
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.padding([12, 14])
|
.padding([12, 14])
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill),
|
.height(height),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.style(container::bordered_box)
|
.style(container::bordered_box)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -760,7 +769,10 @@ pub fn view_window<'a>(
|
||||||
loaded: &FxHashSet<String>,
|
loaded: &FxHashSet<String>,
|
||||||
market: MarketView<'a>,
|
market: MarketView<'a>,
|
||||||
theme: &'a Theme,
|
theme: &'a Theme,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
|
let width = sizing.width;
|
||||||
|
let height = sizing.height;
|
||||||
let title = text("Plugins").size(20);
|
let title = text("Plugins").size(20);
|
||||||
let subtitle = text("Browse, install, and manage add-ons. Select one to view its README.")
|
let subtitle = text("Browse, install, and manage add-ons. Select one to view its README.")
|
||||||
.size(12)
|
.size(12)
|
||||||
|
|
@ -813,40 +825,43 @@ pub fn view_window<'a>(
|
||||||
left: 0.0,
|
left: 0.0,
|
||||||
};
|
};
|
||||||
let catalog = scrollable(container(list.width(Fill)).padding(gutter))
|
let catalog = scrollable(container(list.width(Fill)).padding(gutter))
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.width(Fill);
|
.width(Fill);
|
||||||
let search = text_input("Search plugins…", market.search)
|
let search = text_input("Search plugins…", market.search)
|
||||||
.on_input(Message::PluginSearchInput)
|
.on_input(Message::PluginSearchInput)
|
||||||
.size(13)
|
.size(13)
|
||||||
.padding([7, 10])
|
.padding([7, 10])
|
||||||
.width(Fill);
|
.width(Fill);
|
||||||
let catalog_pane = column![search, catalog].spacing(10).width(Fill).height(Fill);
|
let catalog_pane = column![search, catalog]
|
||||||
let details = readme_panel(&market, theme);
|
.spacing(10)
|
||||||
|
.width(Fill)
|
||||||
|
.height(height);
|
||||||
|
let details = readme_panel(&market, theme, width, height);
|
||||||
let body = row![
|
let body = row![
|
||||||
container(catalog_pane)
|
container(catalog_pane)
|
||||||
.width(Length::Fixed(410.0))
|
.width(Length::Fixed(410.0))
|
||||||
.height(Fill),
|
.height(height),
|
||||||
details,
|
details,
|
||||||
]
|
]
|
||||||
.spacing(14)
|
.spacing(14)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.width(Fill);
|
.width(width);
|
||||||
|
|
||||||
container(
|
container(
|
||||||
column![title, subtitle, Space::new().height(12), body]
|
column![title, subtitle, Space::new().height(12), body]
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.padding(18)
|
.padding(18)
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill),
|
.height(height),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(Fill)
|
.height(height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -855,28 +870,58 @@ pub fn view_window<'a>(
|
||||||
pub fn view_web_notice<'a>() -> Element<'a, Message> {
|
pub fn view_web_notice<'a>() -> Element<'a, Message> {
|
||||||
let download = button(text("Download desktop app").size(13))
|
let download = button(text("Download desktop app").size(13))
|
||||||
.on_press(Message::OpenUrl(DESKTOP_DOWNLOAD_URL.to_string()))
|
.on_press(Message::OpenUrl(DESKTOP_DOWNLOAD_URL.to_string()))
|
||||||
.padding([8, 16])
|
.padding([9, 18])
|
||||||
.style(button::primary);
|
.style(|theme: &Theme, status| {
|
||||||
|
let mut style = button::primary(theme, status);
|
||||||
|
style.text_color = iced::Color::WHITE;
|
||||||
|
style
|
||||||
|
});
|
||||||
|
|
||||||
container(
|
let icon = container(crate::ui::icons::themed_primary(
|
||||||
|
crate::ui::icons::GEAR,
|
||||||
|
26.0,
|
||||||
|
))
|
||||||
|
.center(Length::Fixed(44.0))
|
||||||
|
.style(|theme: &Theme| container::Style {
|
||||||
|
background: Some(Background::Color(
|
||||||
|
theme.palette().primary.weak.color,
|
||||||
|
)),
|
||||||
|
border: Border {
|
||||||
|
radius: 12.0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
let notice = container(
|
||||||
column![
|
column![
|
||||||
text("Plugins require the desktop app").size(20),
|
icon,
|
||||||
|
text("Plugins are available in the desktop app")
|
||||||
|
.size(20)
|
||||||
|
.width(Length::Fit)
|
||||||
|
.align_x(iced::alignment::Horizontal::Center),
|
||||||
text(
|
text(
|
||||||
"Open CAD Studio plugins are native packages and cannot run inside a browser. \
|
"Open CAD Studio plugins are native packages and cannot run inside a browser. \
|
||||||
Install the desktop app to browse, install, and use plugins.",
|
Download the desktop app to browse, install, and use plugins.",
|
||||||
)
|
)
|
||||||
.size(13)
|
.size(13)
|
||||||
|
.width(Length::Fit)
|
||||||
|
.align_x(iced::alignment::Horizontal::Center)
|
||||||
.style(muted_style),
|
.style(muted_style),
|
||||||
Space::new().height(8),
|
Space::new().height(4),
|
||||||
download,
|
download,
|
||||||
]
|
]
|
||||||
.spacing(8)
|
.spacing(10)
|
||||||
.padding(24)
|
.align_x(iced::alignment::Horizontal::Center)
|
||||||
.width(Fill),
|
.width(Length::Fit),
|
||||||
)
|
)
|
||||||
.center(Fill)
|
.width(Length::Fit.max(380.0));
|
||||||
.width(Fill)
|
|
||||||
.height(Fill)
|
container(notice)
|
||||||
|
.center_x(Length::Fit)
|
||||||
|
.padding([16, 20])
|
||||||
|
.width(Length::Fit)
|
||||||
|
.height(Length::Fit)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{column, container, row, scrollable, text, Space};
|
use iced::widget::{column, container, row, scrollable, text, Space};
|
||||||
use iced::{Background, Element, Fill, Theme};
|
use iced::{Background, Element, Theme};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// Display name of the primary accelerator modifier on this platform.
|
/// Display name of the primary accelerator modifier on this platform.
|
||||||
|
|
@ -16,23 +16,23 @@ const MOD: &str = "Ctrl";
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hdivider<'a>() -> Element<'a, Message> {
|
fn hdivider<'a>(width: iced::Length) -> Element<'a, Message> {
|
||||||
container(Space::new().width(Fill).height(1))
|
container(Space::new().width(width).height(1))
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.height(1)
|
.height(1)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.neutral.color,
|
theme.palette().background.neutral.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
@ -70,6 +70,7 @@ fn section<'a>(title: impl Into<Cow<'static, str>>) -> Element<'a, Message> {
|
||||||
|
|
||||||
pub fn view_window<'a>(
|
pub fn view_window<'a>(
|
||||||
overrides: &'a rustc_hash::FxHashMap<String, String>,
|
overrides: &'a rustc_hash::FxHashMap<String, String>,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
// ── Toolbar ───────────────────────────────────────────────────────────
|
// ── Toolbar ───────────────────────────────────────────────────────────
|
||||||
let toolbar = container(
|
let toolbar = container(
|
||||||
|
|
@ -82,11 +83,11 @@ pub fn view_window<'a>(
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.weakest.color,
|
theme.palette().background.weakest.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding([5, 10]);
|
.padding([5, 10]);
|
||||||
|
|
||||||
// ── Shortcut entries ──────────────────────────────────────────────────
|
// ── Shortcut entries ──────────────────────────────────────────────────
|
||||||
|
|
@ -152,8 +153,8 @@ pub fn view_window<'a>(
|
||||||
|
|
||||||
// ── Section headers styled separately ────────────────────────────────
|
// ── Section headers styled separately ────────────────────────────────
|
||||||
let content = scrollable(column(rows).spacing(3).padding([12, 16]))
|
let content = scrollable(column(rows).spacing(3).padding([12, 16]))
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill);
|
.height(sizing.height);
|
||||||
|
|
||||||
// ── Header row with accent ────────────────────────────────────────────
|
// ── Header row with accent ────────────────────────────────────────────
|
||||||
let header = container(
|
let header = container(
|
||||||
|
|
@ -166,20 +167,29 @@ pub fn view_window<'a>(
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().primary.weak.color,
|
theme.palette().primary.weak.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill);
|
.width(sizing.width);
|
||||||
|
|
||||||
container(column![toolbar, hdivider(), header, hdivider(), content].spacing(0))
|
container(
|
||||||
|
column![
|
||||||
|
toolbar,
|
||||||
|
hdivider(sizing.width),
|
||||||
|
header,
|
||||||
|
hdivider(sizing.width),
|
||||||
|
content
|
||||||
|
]
|
||||||
|
.spacing(0),
|
||||||
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,28 @@
|
||||||
use crate::app::Message;
|
use crate::app::Message;
|
||||||
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
||||||
use iced::{Background, Border, Element, Fill, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
|
||||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().background.base.text.scale_alpha(0.68)),
|
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||||
iced::widget::text::Style {
|
iced::widget::text::Style {
|
||||||
color: Some(theme.extended_palette().primary.base.color),
|
color: Some(theme.palette().primary.base.color),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders one of the two "Installed" / "Latest" cards. The `highlight`
|
/// Renders one of the two "Installed" / "Latest" cards. The `highlight`
|
||||||
/// flag tints the border + label with the accent colour, making the new
|
/// flag tints the border + label with the accent colour, making the new
|
||||||
/// version the visual anchor of the row.
|
/// version the visual anchor of the row.
|
||||||
fn version_card<'a>(label: &'static str, value: String, highlight: bool) -> Element<'a, Message> {
|
fn version_card<'a>(
|
||||||
|
label: &'static str,
|
||||||
|
value: String,
|
||||||
|
highlight: bool,
|
||||||
|
width: iced::Length,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
text(label)
|
text(label)
|
||||||
|
|
@ -32,7 +37,7 @@ fn version_card<'a>(label: &'static str, value: String, highlight: bool) -> Elem
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_x(iced::Center),
|
.align_x(iced::Center),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(width)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 14.0,
|
top: 14.0,
|
||||||
right: 12.0,
|
right: 12.0,
|
||||||
|
|
@ -41,7 +46,7 @@ fn version_card<'a>(label: &'static str, value: String, highlight: bool) -> Elem
|
||||||
})
|
})
|
||||||
.align_x(iced::Center)
|
.align_x(iced::Center)
|
||||||
.style(move |theme: &Theme| {
|
.style(move |theme: &Theme| {
|
||||||
let palette = theme.extended_palette();
|
let palette = theme.palette();
|
||||||
let pair = if highlight {
|
let pair = if highlight {
|
||||||
palette.primary.weak
|
palette.primary.weak
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -120,7 +125,11 @@ fn strip_inline_md(s: &str) -> String {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_window<'a>(latest: &'a str, body: &'a str) -> Element<'a, Message> {
|
pub fn view_window<'a>(
|
||||||
|
latest: &'a str,
|
||||||
|
body: &'a str,
|
||||||
|
sizing: crate::ui::modal::ModalSizing,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
let header = container(
|
let header = container(
|
||||||
column![
|
column![
|
||||||
text("New Release Available").size(20).style(primary_style),
|
text("New Release Available").size(20).style(primary_style),
|
||||||
|
|
@ -131,7 +140,7 @@ pub fn view_window<'a>(latest: &'a str, body: &'a str) -> Element<'a, Message> {
|
||||||
.spacing(4)
|
.spacing(4)
|
||||||
.align_x(iced::Center),
|
.align_x(iced::Center),
|
||||||
)
|
)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 14.0,
|
top: 14.0,
|
||||||
right: 0.0,
|
right: 0.0,
|
||||||
|
|
@ -147,20 +156,21 @@ pub fn view_window<'a>(latest: &'a str, body: &'a str) -> Element<'a, Message> {
|
||||||
"Installed",
|
"Installed",
|
||||||
format!("v{}", env!("CARGO_PKG_VERSION")),
|
format!("v{}", env!("CARGO_PKG_VERSION")),
|
||||||
false,
|
false,
|
||||||
|
sizing.width,
|
||||||
);
|
);
|
||||||
let latest_card = version_card("Latest", format!("v{}", latest), true);
|
let latest_card = version_card("Latest", format!("v{}", latest), true, sizing.width);
|
||||||
let arrow = container(crate::ui::icons::themed_secondary(
|
let arrow = container(crate::ui::icons::themed_secondary(
|
||||||
crate::ui::icons::ARROW_LONG_RIGHT,
|
crate::ui::icons::ARROW_LONG_RIGHT,
|
||||||
20.0,
|
20.0,
|
||||||
))
|
))
|
||||||
.width(iced::Length::Fixed(32.0))
|
.width(iced::Length::Fixed(32.0))
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.align_x(iced::Center)
|
.align_x(iced::Center)
|
||||||
.align_y(iced::Center);
|
.align_y(iced::Center);
|
||||||
let info_block = row![installed, arrow, latest_card]
|
let info_block = row![installed, arrow, latest_card]
|
||||||
.spacing(0)
|
.spacing(0)
|
||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
.width(Fill);
|
.width(sizing.width);
|
||||||
|
|
||||||
let later_btn = button(text("Later").size(11))
|
let later_btn = button(text("Later").size(11))
|
||||||
.on_press(Message::UpdateNoticeClose)
|
.on_press(Message::UpdateNoticeClose)
|
||||||
|
|
@ -172,7 +182,7 @@ pub fn view_window<'a>(latest: &'a str, body: &'a str) -> Element<'a, Message> {
|
||||||
.style(button::primary)
|
.style(button::primary)
|
||||||
.padding([6, 16]);
|
.padding([6, 16]);
|
||||||
|
|
||||||
let footer = row![Space::new().width(Fill), later_btn, open_btn]
|
let footer = row![Space::new().width(sizing.width), later_btn, open_btn]
|
||||||
.spacing(8)
|
.spacing(8)
|
||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
|
|
@ -203,27 +213,26 @@ pub fn view_window<'a>(latest: &'a str, body: &'a str) -> Element<'a, Message> {
|
||||||
for line in body.lines() {
|
for line in body.lines() {
|
||||||
col = col.push(render_notes_line(line));
|
col = col.push(render_notes_line(line));
|
||||||
}
|
}
|
||||||
scrollable(container(col).padding([10, 14])).height(Fill).into()
|
scrollable(container(col).padding([10, 14]))
|
||||||
|
.height(sizing.height)
|
||||||
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let notes_block = container(notes_body)
|
let notes_block = container(notes_body)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.style(container::bordered_box);
|
.style(container::bordered_box);
|
||||||
|
|
||||||
// Wrap notes_block in a Fill-height container outside the column so it
|
// Keep the notes panel content-sized. The outer modal supplies the maximum
|
||||||
// greedily claims every pixel left over after the fixed-height rows
|
// height, so long release notes scroll instead of stretching the dialog.
|
||||||
// (header, version cards, heading, footer). Without this iced lets the
|
|
||||||
// notes panel shrink to its content height, leaving a gap above the
|
|
||||||
// footer.
|
|
||||||
let notes_fill = container(notes_block)
|
let notes_fill = container(notes_block)
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill);
|
.height(sizing.height);
|
||||||
|
|
||||||
container(
|
container(
|
||||||
column![header, info_block, notes_heading, notes_fill, footer]
|
column![header, info_block, notes_heading, notes_fill, footer]
|
||||||
.spacing(0)
|
.spacing(0)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.padding(iced::Padding {
|
.padding(iced::Padding {
|
||||||
top: 0.0,
|
top: 0.0,
|
||||||
right: 20.0,
|
right: 20.0,
|
||||||
|
|
@ -233,11 +242,11 @@ pub fn view_window<'a>(latest: &'a str, body: &'a str) -> Element<'a, Message> {
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
theme.extended_palette().background.base.color,
|
theme.palette().background.base.color,
|
||||||
)),
|
)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.width(Fill)
|
.width(sizing.width)
|
||||||
.height(Fill)
|
.height(sizing.height)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use iced::advanced::layout::{self, Layout};
|
use iced::advanced::layout::{self, Layout};
|
||||||
use iced::advanced::widget::{self, tree, Widget};
|
use iced::advanced::widget::{self, tree, Widget};
|
||||||
use iced::advanced::{mouse, overlay, renderer, Clipboard, Renderer as _, Shell};
|
use iced::advanced::{mouse, overlay, renderer, Renderer as _, Shell};
|
||||||
use iced::{
|
use iced::{
|
||||||
Background, Border, Element, Event, Length, Point, Rectangle, Renderer, Shadow, Size,
|
Background, Border, Element, Event, Length, Point, Rectangle, Renderer, Shadow, Size,
|
||||||
Theme, Vector,
|
Theme, Vector,
|
||||||
|
|
@ -121,13 +121,9 @@ impl<'a> WrapBar<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget<Message, Theme, Renderer> for WrapBar<'a> {
|
impl<'a> Widget<Message, Theme, Renderer> for WrapBar<'a> {
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
self.refs().iter().map(|e| widget::Tree::new(*e)).collect()
|
let mut refs = self.refs_mut();
|
||||||
}
|
tree.diff_children(&mut refs);
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
let refs: Vec<_> = self.refs().iter().map(|e| e.as_widget()).collect();
|
|
||||||
tree.diff_children(&refs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
|
|
@ -300,7 +296,6 @@ impl<'a> Widget<Message, Theme, Renderer> for WrapBar<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -316,7 +311,6 @@ impl<'a> Widget<Message, Theme, Renderer> for WrapBar<'a> {
|
||||||
child_layout,
|
child_layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -529,13 +523,8 @@ impl<'a> WrapFlow<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget<Message, Theme, Renderer> for WrapFlow<'a> {
|
impl<'a> Widget<Message, Theme, Renderer> for WrapFlow<'a> {
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
self.items.iter().map(widget::Tree::new).collect()
|
tree.diff_children(&mut self.items);
|
||||||
}
|
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
let refs: Vec<_> = self.items.iter().map(|e| e.as_widget()).collect();
|
|
||||||
tree.diff_children(&refs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
|
|
@ -633,7 +622,6 @@ impl<'a> Widget<Message, Theme, Renderer> for WrapFlow<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -649,7 +637,6 @@ impl<'a> Widget<Message, Theme, Renderer> for WrapFlow<'a> {
|
||||||
child_layout,
|
child_layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -789,13 +776,8 @@ impl<'a> DensitySwap<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
self.variants.iter().map(widget::Tree::new).collect()
|
tree.diff_children(&mut self.variants);
|
||||||
}
|
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
let refs: Vec<_> = self.variants.iter().map(|e| e.as_widget()).collect();
|
|
||||||
tree.diff_children(&refs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
|
|
@ -847,7 +829,6 @@ impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -859,7 +840,6 @@ impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||||
child_layout,
|
child_layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -980,22 +960,14 @@ impl<'a> PosReport<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget<Message, Theme, Renderer> for PosReport<'a> {
|
impl<'a> Widget<Message, Theme, Renderer> for PosReport<'a> {
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
vec![widget::Tree::new(&self.child)]
|
tree.diff_children(std::slice::from_mut(&mut self.child));
|
||||||
}
|
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
tree.diff_children(&[self.child.as_widget()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
self.child.as_widget().size()
|
self.child.as_widget().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> Size<Length> {
|
|
||||||
self.child.as_widget().size_hint()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut widget::Tree,
|
tree: &mut widget::Tree,
|
||||||
|
|
@ -1014,7 +986,6 @@ impl<'a> Widget<Message, Theme, Renderer> for PosReport<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -1024,7 +995,6 @@ impl<'a> Widget<Message, Theme, Renderer> for PosReport<'a> {
|
||||||
layout,
|
layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -1211,22 +1181,14 @@ impl<'a> Widget<Message, Theme, Renderer> for ReorderTab<'a> {
|
||||||
tree::State::new(ReorderState::default())
|
tree::State::new(ReorderState::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn children(&self) -> Vec<widget::Tree> {
|
fn diff(&mut self, tree: &mut widget::Tree) {
|
||||||
vec![widget::Tree::new(&self.child)]
|
tree.diff_children(std::slice::from_mut(&mut self.child));
|
||||||
}
|
|
||||||
|
|
||||||
fn diff(&self, tree: &mut widget::Tree) {
|
|
||||||
tree.diff_children(&[self.child.as_widget()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> Size<Length> {
|
fn size(&self) -> Size<Length> {
|
||||||
self.child.as_widget().size()
|
self.child.as_widget().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> Size<Length> {
|
|
||||||
self.child.as_widget().size_hint()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &mut widget::Tree,
|
tree: &mut widget::Tree,
|
||||||
|
|
@ -1245,7 +1207,6 @@ impl<'a> Widget<Message, Theme, Renderer> for ReorderTab<'a> {
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
|
|
@ -1295,7 +1256,6 @@ impl<'a> Widget<Message, Theme, Renderer> for ReorderTab<'a> {
|
||||||
layout,
|
layout,
|
||||||
cursor,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
|
||||||
shell,
|
shell,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
|
|
@ -1374,7 +1334,7 @@ impl<'a> Widget<Message, Theme, Renderer> for ReorderTab<'a> {
|
||||||
shadow: Shadow::default(),
|
shadow: Shadow::default(),
|
||||||
snap: true,
|
snap: true,
|
||||||
},
|
},
|
||||||
Background::Color(theme.extended_palette().primary.base.color),
|
Background::Color(theme.palette().primary.base.color),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue