fix(plot): restore dialog layout
This commit is contained in:
parent
bd1b5b4293
commit
6705e65e81
2 changed files with 179 additions and 116 deletions
|
|
@ -240,8 +240,8 @@ impl OpenCADStudio {
|
||||||
super::super::ModalKind::Plot => {
|
super::super::ModalKind::Plot => {
|
||||||
sized_flow(
|
sized_flow(
|
||||||
ex,
|
ex,
|
||||||
820,
|
760,
|
||||||
610,
|
540,
|
||||||
|flow| crate::ui::window::plot::view_window(&self.plot_dialog, flow),
|
|flow| crate::ui::window::plot::view_window(&self.plot_dialog, flow),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,9 +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, row, scrollable, text, text_input, Space,
|
button, checkbox, column, container, mouse_area, row, scrollable, text, text_input,
|
||||||
|
Space,
|
||||||
};
|
};
|
||||||
use iced::{Background, Border, Element, 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";
|
||||||
|
|
@ -278,6 +279,53 @@ 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>(height: Length) -> Element<'a, Message> {
|
||||||
|
container(Space::new().width(1).height(height))
|
||||||
|
.width(1)
|
||||||
|
.height(height)
|
||||||
|
.style(|theme: &Theme| container::Style {
|
||||||
|
background: Some(Background::Color(
|
||||||
|
theme.palette().background.neutral.color
|
||||||
|
)),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_row<'a>(
|
||||||
|
name: &'a str,
|
||||||
|
selected: &str,
|
||||||
|
renaming: Option<&str>,
|
||||||
|
rename_buf: &'a str,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
|
if renaming == Some(name) {
|
||||||
|
return text_input("", rename_buf)
|
||||||
|
.on_input(|value| Message::PlotDlg(PlotDlgMsg::NameInput(value)))
|
||||||
|
.on_submit(Message::PlotDlg(PlotDlgMsg::NameCommit))
|
||||||
|
.style(field_style)
|
||||||
|
.size(11)
|
||||||
|
.padding([4, 8])
|
||||||
|
.width(Fit)
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
let is_selected = name == selected;
|
||||||
|
let cell = container(text(name.to_string()).size(11))
|
||||||
|
.padding([4, 8])
|
||||||
|
.width(Fit)
|
||||||
|
.style(move |theme: &Theme| {
|
||||||
|
let palette = theme.palette();
|
||||||
|
container::Style {
|
||||||
|
background: is_selected.then_some(Background::Color(palette.primary.strong.color)),
|
||||||
|
text_color: is_selected.then_some(palette.primary.strong.text),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mouse_area(cell)
|
||||||
|
.on_press(Message::PlotDlg(PlotDlgMsg::SelectSetup(name.to_string())))
|
||||||
|
.on_double_click(Message::PlotDlg(PlotDlgMsg::RenameStart(name.to_string())))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
/// A `label : dropdown` row. `ctor` turns the picked string into a dialog
|
/// A `label : dropdown` row. `ctor` turns the picked string into a dialog
|
||||||
/// message.
|
/// message.
|
||||||
fn drop_row<'a>(
|
fn drop_row<'a>(
|
||||||
|
|
@ -399,20 +447,7 @@ fn check_static<'a>(label: &'a str, on: bool) -> Element<'a, Message> {
|
||||||
|
|
||||||
fn panel<'a>(content: impl Into<Element<'a, Message>>) -> Element<'a, Message> {
|
fn panel<'a>(content: impl Into<Element<'a, Message>>) -> Element<'a, Message> {
|
||||||
container(content)
|
container(content)
|
||||||
.padding(10)
|
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.style(|theme: &Theme| {
|
|
||||||
let palette = theme.palette();
|
|
||||||
container::Style {
|
|
||||||
background: Some(Background::Color(palette.background.weak.color)),
|
|
||||||
border: Border {
|
|
||||||
color: palette.background.neutral.color,
|
|
||||||
width: 1.0,
|
|
||||||
radius: 4.0.into(),
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,82 +469,105 @@ pub fn view_window(
|
||||||
let can_copy = !s.selected_setup.is_empty() && !is_special;
|
let can_copy = !s.selected_setup.is_empty() && !is_special;
|
||||||
let is_named = can_copy && !sel_is_layout;
|
let is_named = can_copy && !sel_is_layout;
|
||||||
|
|
||||||
// ── Page setup ────────────────────────────────────────────────────────
|
// ── Page setup sidebar ────────────────────────────────────────────────
|
||||||
let setup_selected = (!s.selected_setup.is_empty()).then(|| s.selected_setup.clone());
|
let renaming = if s.name_rename && !s.selected_setup.is_empty() {
|
||||||
let mut setup_actions = row![
|
Some(s.selected_setup.as_str())
|
||||||
text("Name").size(11).style(muted_style).width(56),
|
} else {
|
||||||
iced::widget::pick_list(setup_selected, s.page_setups.clone(), |value| value.to_string())
|
None
|
||||||
.on_select(|value| Message::PlotDlg(PlotDlgMsg::SelectSetup(value)))
|
};
|
||||||
.text_size(12)
|
let rename_buf = s.name_input.as_deref().unwrap_or("");
|
||||||
.padding([3, 6])
|
let rows: Vec<Element<'_, Message>> = s
|
||||||
.width(Length::Fill),
|
.page_setups
|
||||||
button(text("Add…").size(11))
|
.iter()
|
||||||
|
.map(|name| setup_row(name, &s.selected_setup, renaming, rename_buf))
|
||||||
|
.collect();
|
||||||
|
let list_body: Element<'_, Message> = if rows.is_empty() {
|
||||||
|
container(text("(no page setups)").size(11).style(muted_style))
|
||||||
|
.padding([6, 8])
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
scrollable(column(rows).spacing(1)).height(height).into()
|
||||||
|
};
|
||||||
|
let new_name: Element<'_, Message> =
|
||||||
|
if !s.name_rename && s.name_input.is_some() {
|
||||||
|
row![
|
||||||
|
text_input("", rename_buf)
|
||||||
|
.on_input(|value| Message::PlotDlg(PlotDlgMsg::NameInput(value)))
|
||||||
|
.on_submit(Message::PlotDlg(PlotDlgMsg::NameCommit))
|
||||||
|
.style(field_style)
|
||||||
|
.size(11)
|
||||||
|
.padding([4, 8])
|
||||||
|
.width(Length::Fill),
|
||||||
|
button(text("Save").size(11))
|
||||||
|
.on_press(Message::PlotDlg(PlotDlgMsg::NameCommit))
|
||||||
|
.style(btn(true))
|
||||||
|
.padding([4, 8]),
|
||||||
|
button(text("×").size(11))
|
||||||
|
.on_press(Message::PlotDlg(PlotDlgMsg::NameCancel))
|
||||||
|
.style(btn(false))
|
||||||
|
.padding([4, 8]),
|
||||||
|
]
|
||||||
|
.spacing(4)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
Space::new().height(0).into()
|
||||||
|
};
|
||||||
|
let list_panel = container(
|
||||||
|
column![
|
||||||
|
text("Page setups").size(10).style(muted_style),
|
||||||
|
new_name,
|
||||||
|
container(list_body)
|
||||||
|
.style(|theme: &Theme| {
|
||||||
|
let palette = theme.palette();
|
||||||
|
container::Style {
|
||||||
|
background: Some(Background::Color(palette.background.weak.color)),
|
||||||
|
border: Border {
|
||||||
|
color: palette.background.neutral.color,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 3.0.into(),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(height)
|
||||||
|
.padding(2),
|
||||||
|
]
|
||||||
|
.spacing(4)
|
||||||
|
.height(height),
|
||||||
|
)
|
||||||
|
.width(160)
|
||||||
|
.height(height)
|
||||||
|
.padding(iced::Padding {
|
||||||
|
top: 12.0,
|
||||||
|
right: 8.0,
|
||||||
|
bottom: 12.0,
|
||||||
|
left: 12.0,
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut left_bar = row![
|
||||||
|
button(text("New").size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::NewSetup))
|
.on_press(Message::PlotDlg(PlotDlgMsg::NewSetup))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
.padding([4, 10]),
|
.padding([4, 12]),
|
||||||
]
|
]
|
||||||
.spacing(6)
|
.spacing(4);
|
||||||
.align_y(iced::Center);
|
|
||||||
if can_copy {
|
if can_copy {
|
||||||
setup_actions = setup_actions.push(
|
left_bar = left_bar.push(
|
||||||
button(text("Copy").size(11))
|
button(text("Copy").size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::CopySetup))
|
.on_press(Message::PlotDlg(PlotDlgMsg::CopySetup))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
.padding([4, 10]),
|
.padding([4, 12]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if is_named {
|
if is_named {
|
||||||
setup_actions = setup_actions
|
left_bar = left_bar.push(
|
||||||
.push(
|
|
||||||
button(text("Rename").size(11))
|
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::RenameStart(
|
|
||||||
s.selected_setup.clone(),
|
|
||||||
)))
|
|
||||||
.style(btn(false))
|
|
||||||
.padding([4, 10]),
|
|
||||||
)
|
|
||||||
.push(
|
|
||||||
button(text("Delete").size(11))
|
button(text("Delete").size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::DeleteSetup))
|
.on_press(Message::PlotDlg(PlotDlgMsg::DeleteSetup))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
.padding([4, 10]),
|
.padding([4, 12]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let name_editor: Element<'_, Message> = if let Some(value) = s.name_input.as_deref() {
|
|
||||||
row![
|
|
||||||
text(if s.name_rename { "Setup name" } else { "New setup" })
|
|
||||||
.size(11)
|
|
||||||
.style(muted_style)
|
|
||||||
.width(82),
|
|
||||||
text_input("", value)
|
|
||||||
.on_input(|value| Message::PlotDlg(PlotDlgMsg::NameInput(value)))
|
|
||||||
.on_submit(Message::PlotDlg(PlotDlgMsg::NameCommit))
|
|
||||||
.style(field_style)
|
|
||||||
.size(12)
|
|
||||||
.width(Length::Fill),
|
|
||||||
button(text("Save").size(11))
|
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::NameCommit))
|
|
||||||
.style(btn(true))
|
|
||||||
.padding([4, 10]),
|
|
||||||
button(text("Cancel").size(11))
|
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::NameCancel))
|
|
||||||
.style(btn(false))
|
|
||||||
.padding([4, 10]),
|
|
||||||
]
|
|
||||||
.spacing(6)
|
|
||||||
.align_y(iced::Center)
|
|
||||||
.into()
|
|
||||||
} else {
|
|
||||||
Space::new().height(0).into()
|
|
||||||
};
|
|
||||||
let setup_panel = panel(
|
|
||||||
column![
|
|
||||||
section_label("Page setup"),
|
|
||||||
setup_actions,
|
|
||||||
name_editor,
|
|
||||||
]
|
|
||||||
.spacing(7),
|
|
||||||
);
|
|
||||||
|
|
||||||
// ── Printer / plotter ─────────────────────────────────────────────────
|
// ── Printer / plotter ─────────────────────────────────────────────────
|
||||||
let mut printer_opts = vec![OUT_DEFAULT.to_string()];
|
let mut printer_opts = vec![OUT_DEFAULT.to_string()];
|
||||||
|
|
@ -605,6 +663,8 @@ pub fn view_window(
|
||||||
]
|
]
|
||||||
.spacing(7),
|
.spacing(7),
|
||||||
check_enabled("Center the plot", s.center, PlotFlag::Center, common_area),
|
check_enabled("Center the plot", s.center, PlotFlag::Center, common_area),
|
||||||
|
].spacing(7));
|
||||||
|
let scale_panel = panel(column![
|
||||||
section_label("Plot scale"),
|
section_label("Plot scale"),
|
||||||
drop_row_enabled(
|
drop_row_enabled(
|
||||||
"Scale",
|
"Scale",
|
||||||
|
|
@ -735,61 +795,64 @@ pub fn view_window(
|
||||||
check("Plot upside-down", s.upside_down, PlotFlag::UpsideDown),
|
check("Plot upside-down", s.upside_down, PlotFlag::UpsideDown),
|
||||||
].spacing(7));
|
].spacing(7));
|
||||||
|
|
||||||
let left = column![printer_panel, paper_panel, area_panel]
|
let left = column![
|
||||||
.spacing(10)
|
printer_panel,
|
||||||
|
hdivider(width),
|
||||||
|
paper_panel,
|
||||||
|
orientation_panel,
|
||||||
|
hdivider(width),
|
||||||
|
area_panel,
|
||||||
|
]
|
||||||
|
.spacing(9)
|
||||||
.width(width);
|
.width(width);
|
||||||
let right = column![style_panel, shaded_panel, options_panel, orientation_panel]
|
let right = column![
|
||||||
.spacing(10)
|
scale_panel,
|
||||||
|
hdivider(width),
|
||||||
|
style_panel,
|
||||||
|
hdivider(width),
|
||||||
|
shaded_panel,
|
||||||
|
hdivider(width),
|
||||||
|
options_panel,
|
||||||
|
]
|
||||||
|
.spacing(9)
|
||||||
.width(width);
|
.width(width);
|
||||||
let detail = scrollable(
|
let detail = scrollable(
|
||||||
container(column![
|
container(row![left, right].spacing(18).width(width)).padding(14),
|
||||||
setup_panel,
|
|
||||||
row![left, right].spacing(12).width(width),
|
|
||||||
].spacing(10))
|
|
||||||
.padding(12),
|
|
||||||
)
|
)
|
||||||
.width(width)
|
.width(width)
|
||||||
.height(height);
|
.height(height);
|
||||||
|
let body = row![list_panel, vsep(height), detail]
|
||||||
let mut actions = row![
|
.width(width)
|
||||||
button(text("Preview").size(11))
|
.height(height);
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::Preview))
|
let toolbar = container(
|
||||||
.style(btn(false))
|
row![
|
||||||
.padding([5, 14]),
|
left_bar,
|
||||||
Space::new().width(Length::Fill),
|
Space::new().width(width),
|
||||||
]
|
button(text("Set current").size(11))
|
||||||
.spacing(6)
|
|
||||||
.align_y(iced::Center);
|
|
||||||
if s.paper_space {
|
|
||||||
actions = actions.push(
|
|
||||||
button(text("Apply to layout").size(11))
|
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::SetCurrent))
|
.on_press(Message::PlotDlg(PlotDlgMsg::SetCurrent))
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
.padding([5, 12]),
|
.padding([4, 12]),
|
||||||
);
|
Space::new().width(6),
|
||||||
}
|
button(text("Preview").size(11))
|
||||||
actions = actions
|
.on_press(Message::PlotDlg(PlotDlgMsg::Preview))
|
||||||
.push(
|
|
||||||
button(text("Cancel").size(11))
|
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::Close))
|
|
||||||
.style(btn(false))
|
.style(btn(false))
|
||||||
.padding([5, 14]),
|
.padding([4, 12]),
|
||||||
)
|
Space::new().width(6),
|
||||||
.push(
|
|
||||||
button(text(action).size(11))
|
button(text(action).size(11))
|
||||||
.on_press(Message::PlotDlg(PlotDlgMsg::Commit))
|
.on_press(Message::PlotDlg(PlotDlgMsg::Commit))
|
||||||
.style(btn(true))
|
.style(btn(true))
|
||||||
.padding([5, 18]),
|
.padding([4, 18]),
|
||||||
);
|
]
|
||||||
let footer = container(actions)
|
.align_y(iced::Center),
|
||||||
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(theme.palette().background.weak.color)),
|
background: Some(Background::Color(theme.palette().background.weak.color)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.padding([7, 10])
|
.padding([5, 10])
|
||||||
.width(width);
|
.width(width);
|
||||||
|
|
||||||
container(column![detail, hdivider(width), footer].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.palette().background.base.color
|
theme.palette().background.base.color
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue