forked from 1b-agent/opencadstudio-upstream
refactor(ui): finish dialog form helper adoption
This commit is contained in:
1 parent
c80a1d1703
commit
b97e67b533
8 files changed
+110
-149
No files matched your search
@@ -0,0 +1,70 @@
|
||||
use iced::widget::{text, text_input};
|
||||
use iced::{Background, Theme};
|
||||
|
||||
/// Right-hand lane reserved for the scrollbar in editable command tables.
|
||||
pub(crate) const EDITOR_TABLE_GUTTER: f32 = 16.0;
|
||||
|
||||
/// Text style for a value flagged as invalid in an editable command table.
|
||||
pub(crate) fn danger_text_style(theme: &Theme) -> text::Style {
|
||||
text::Style {
|
||||
color: Some(theme.palette().danger.base.color),
|
||||
}
|
||||
}
|
||||
|
||||
/// Invalid-value field style shared by the Shortcuts and Aliases editors.
|
||||
pub(crate) fn danger_input_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||
let danger = theme.palette().danger.base;
|
||||
text_input::Style {
|
||||
background: Background::Color(theme.palette().danger.weak.color),
|
||||
border: iced::border::rounded(4).color(danger.color).width(
|
||||
if matches!(status, text_input::Status::Focused { .. }) {
|
||||
1.5
|
||||
} else {
|
||||
1.0
|
||||
},
|
||||
),
|
||||
icon: danger.color,
|
||||
placeholder: danger.color.scale_alpha(0.7),
|
||||
value: danger.text,
|
||||
selection: danger.color,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{danger_input_style, danger_text_style, EDITOR_TABLE_GUTTER};
|
||||
use iced::widget::text_input;
|
||||
use iced::{Background, Theme};
|
||||
|
||||
#[test]
|
||||
fn invalid_editor_styles_keep_danger_palette_and_focus_border() {
|
||||
let theme = Theme::Dark;
|
||||
let palette = theme.palette();
|
||||
let text_style = danger_text_style(&theme);
|
||||
assert_eq!(text_style.color, Some(palette.danger.base.color));
|
||||
|
||||
let active = danger_input_style(&theme, text_input::Status::Active);
|
||||
assert_eq!(
|
||||
active.background,
|
||||
Background::Color(palette.danger.weak.color)
|
||||
);
|
||||
assert_eq!(active.border.color, palette.danger.base.color);
|
||||
assert_eq!(active.border.width, 1.0);
|
||||
assert_eq!(active.border.radius, 4.0.into());
|
||||
assert_eq!(active.icon, palette.danger.base.color);
|
||||
assert_eq!(
|
||||
active.placeholder,
|
||||
palette.danger.base.color.scale_alpha(0.7)
|
||||
);
|
||||
assert_eq!(active.value, palette.danger.base.text);
|
||||
assert_eq!(active.selection, palette.danger.base.color);
|
||||
|
||||
let focused = danger_input_style(&theme, text_input::Status::Focused { is_hovered: false });
|
||||
assert_eq!(focused.border.width, 1.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn editor_table_gutter_is_sixteen_pixels() {
|
||||
assert_eq!(EDITOR_TABLE_GUTTER, 16.0);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod anno_object_scale;
|
||||
pub mod common;
|
||||
pub mod dimstyle;
|
||||
pub(crate) mod editor_table;
|
||||
pub mod form;
|
||||
pub mod fusion_theme;
|
||||
pub mod mleaderstyle;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
use crate::app::Message;
|
||||
use crate::t;
|
||||
use crate::ui::style::common::muted_style;
|
||||
use crate::ui::style::editor_table::{danger_input_style, danger_text_style, EDITOR_TABLE_GUTTER};
|
||||
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
||||
use iced::{Background, Element, Length, Theme};
|
||||
|
||||
@@ -19,41 +20,6 @@ pub enum AliasField {
|
||||
Command,
|
||||
}
|
||||
|
||||
/// Right-hand lane reserved for the scrollbar so it never overlaps the ✕ column.
|
||||
const GUTTER: f32 = 16.0;
|
||||
|
||||
fn danger_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
iced::widget::text::Style {
|
||||
color: Some(theme.palette().danger.base.color),
|
||||
}
|
||||
}
|
||||
|
||||
/// Text-input variant flagging an invalid value: danger border and value
|
||||
/// color on the theme's danger weak background.
|
||||
fn danger_input_style(
|
||||
theme: &Theme,
|
||||
status: iced::widget::text_input::Status,
|
||||
) -> iced::widget::text_input::Style {
|
||||
let danger = theme.palette().danger.base;
|
||||
iced::widget::text_input::Style {
|
||||
background: Background::Color(theme.palette().danger.weak.color),
|
||||
border: iced::border::rounded(4).color(danger.color).width(
|
||||
if matches!(
|
||||
status,
|
||||
iced::widget::text_input::Status::Focused { is_hovered: _ }
|
||||
) {
|
||||
1.5
|
||||
} else {
|
||||
1.0
|
||||
},
|
||||
),
|
||||
icon: danger.color,
|
||||
placeholder: danger.color.scale_alpha(0.7),
|
||||
value: danger.text,
|
||||
selection: danger.color,
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the alias editor content. `rows` is the live working buffer.
|
||||
pub fn view_window<'a>(
|
||||
rows: &'a [(String, String)],
|
||||
@@ -78,7 +44,7 @@ pub fn view_window<'a>(
|
||||
// scrollable rows so the columns stay aligned.
|
||||
let gutter = iced::Padding {
|
||||
top: 0.0,
|
||||
right: GUTTER,
|
||||
right: EDITOR_TABLE_GUTTER,
|
||||
bottom: 0.0,
|
||||
left: 0.0,
|
||||
};
|
||||
|
||||
@@ -42,16 +42,6 @@ fn muted(theme: &Theme) -> iced::widget::text::Style {
|
||||
}
|
||||
}
|
||||
|
||||
fn button_style(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
move |theme, status| {
|
||||
if accent {
|
||||
button::primary(theme, status)
|
||||
} else {
|
||||
button::secondary(theme, status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn list_style(selected: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
move |theme, status| {
|
||||
if selected {
|
||||
@@ -196,7 +186,10 @@ pub fn view_window<'a>(
|
||||
]
|
||||
.spacing(8),
|
||||
row![
|
||||
text(t!("Current layer")).size(10).style(muted).width(LABEL_WIDTH),
|
||||
text(t!("Current layer"))
|
||||
.size(10)
|
||||
.style(muted)
|
||||
.width(LABEL_WIDTH),
|
||||
text(if state.current_layer.is_empty() {
|
||||
"—".to_string()
|
||||
} else {
|
||||
@@ -224,9 +217,9 @@ pub fn view_window<'a>(
|
||||
let restore = if selected_state.is_some() {
|
||||
button(text(t!("Restore")).size(11))
|
||||
.on_press(Message::LayerStateManagerRestore)
|
||||
.style(button_style(true))
|
||||
.style(button::primary)
|
||||
} else {
|
||||
button(text(t!("Restore")).size(11)).style(button_style(true))
|
||||
button(text(t!("Restore")).size(11)).style(button::primary)
|
||||
};
|
||||
let delete = if selected_state.is_some() {
|
||||
button(text(t!("Delete")).size(11))
|
||||
@@ -238,9 +231,9 @@ pub fn view_window<'a>(
|
||||
let edit = if selected_state.is_some() {
|
||||
button(text(t!("Edit")).size(11))
|
||||
.on_press(Message::LayerStateManagerEdit)
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
} else {
|
||||
button(text(t!("Edit")).size(11)).style(button_style(false))
|
||||
button(text(t!("Edit")).size(11)).style(button::secondary)
|
||||
};
|
||||
|
||||
let right = container(
|
||||
@@ -248,7 +241,7 @@ pub fn view_window<'a>(
|
||||
row![
|
||||
button(text(t!("New")).size(11))
|
||||
.on_press(Message::LayerStateManagerNew)
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
.padding([5, 12]),
|
||||
edit.padding([5, 12]),
|
||||
Space::new().width(sizing.width),
|
||||
@@ -282,7 +275,7 @@ pub fn view_window<'a>(
|
||||
})
|
||||
.size(11))
|
||||
.on_press(Message::LayerStateManagerSave)
|
||||
.style(button_style(true))
|
||||
.style(button::primary)
|
||||
.padding([6, 14]),
|
||||
]
|
||||
.spacing(7)
|
||||
@@ -614,11 +607,11 @@ pub fn view_editor<'a>(
|
||||
Space::new().width(sizing.width),
|
||||
button(text(t!("Cancel")).size(11))
|
||||
.on_press(Message::LayerStateEditorCancel)
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
.padding([5, 12]),
|
||||
button(text(t!("Save Changes")).size(11))
|
||||
.on_press(Message::LayerStateEditorSave)
|
||||
.style(button_style(true))
|
||||
.style(button::primary)
|
||||
.padding([5, 12]),
|
||||
]
|
||||
.spacing(7)
|
||||
|
||||
+6
-37
@@ -4,6 +4,7 @@ use crate::app::Message;
|
||||
use crate::t;
|
||||
use crate::ui::properties::{lw_options, LinetypeItem, LwItem};
|
||||
use crate::ui::style::common::muted_style;
|
||||
use crate::ui::style::form::field_style_with_radius;
|
||||
use crate::ui::style::row_button::{cell_button_style, header_button_style};
|
||||
use crate::ui::ROW_H;
|
||||
use codec::tables::layer::Layer as DocLayer;
|
||||
@@ -53,29 +54,6 @@ const LINETYPE_MENU_W: f32 = 220.0;
|
||||
/// scrolled into view after it is added (#271).
|
||||
pub const LAYER_TABLE_SCROLL_ID: &str = "layer-manager-table-scroll";
|
||||
|
||||
fn table_input_style(
|
||||
theme: &Theme,
|
||||
status: iced::widget::text_input::Status,
|
||||
) -> iced::widget::text_input::Style {
|
||||
let palette = theme.palette();
|
||||
let border = match status {
|
||||
iced::widget::text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||
_ => palette.background.neutral.color,
|
||||
};
|
||||
iced::widget::text_input::Style {
|
||||
background: Background::Color(palette.background.base.color),
|
||||
border: Border {
|
||||
color: border,
|
||||
width: 1.0,
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
icon: palette.background.base.text,
|
||||
placeholder: palette.background.base.text.scale_alpha(0.48),
|
||||
value: palette.background.base.text,
|
||||
selection: palette.primary.base.color.scale_alpha(0.5),
|
||||
}
|
||||
}
|
||||
|
||||
// ── Layer data ────────────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -401,7 +379,7 @@ impl LayerPanel {
|
||||
.size(FONT_SZ)
|
||||
.padding([3, 6])
|
||||
.width(Length::Fixed(180.0))
|
||||
.style(table_input_style),
|
||||
.style(|theme, status| field_style_with_radius(theme, status, 2.0)),
|
||||
]
|
||||
.spacing(2)
|
||||
.align_y(iced::Center),
|
||||
@@ -816,7 +794,7 @@ fn layer_row<'a>(
|
||||
left: 4.0,
|
||||
right: 4.0,
|
||||
})
|
||||
.style(table_input_style)
|
||||
.style(|theme, status| field_style_with_radius(theme, status, 2.0))
|
||||
.width(Length::Fixed(name_col_w))
|
||||
.into()
|
||||
} else {
|
||||
@@ -892,7 +870,7 @@ fn layer_row<'a>(
|
||||
right: 4.0,
|
||||
})
|
||||
.width(Length::Fixed(COL_LT))
|
||||
.input_style(combo_input_style),
|
||||
.input_style(|theme, status| field_style_with_radius(theme, status, 2.0)),
|
||||
LINETYPE_MENU_W,
|
||||
)
|
||||
} else {
|
||||
@@ -920,7 +898,7 @@ fn layer_row<'a>(
|
||||
right: 4.0,
|
||||
})
|
||||
.width(Length::Fixed(COL_LW))
|
||||
.input_style(combo_input_style)
|
||||
.input_style(|theme, status| field_style_with_radius(theme, status, 2.0))
|
||||
.into()
|
||||
} else {
|
||||
text(cur_lw_item.to_string())
|
||||
@@ -943,7 +921,7 @@ fn layer_row<'a>(
|
||||
right: 4.0,
|
||||
})
|
||||
.style(|theme: &Theme, status| {
|
||||
let mut style = table_input_style(theme, status);
|
||||
let mut style = field_style_with_radius(theme, status, 2.0);
|
||||
style.background = iced::Background::Color(Color::TRANSPARENT);
|
||||
style
|
||||
})
|
||||
@@ -1021,15 +999,6 @@ fn layer_row<'a>(
|
||||
.into()
|
||||
}
|
||||
|
||||
// ── Combo style ────────────────────────────────────────────────────────────
|
||||
|
||||
fn combo_input_style(
|
||||
theme: &Theme,
|
||||
status: iced::widget::text_input::Status,
|
||||
) -> iced::widget::text_input::Style {
|
||||
table_input_style(theme, status)
|
||||
}
|
||||
|
||||
// ── Display helpers ───────────────────────────────────────────────────────
|
||||
|
||||
pub fn iced_color_from_acad(c: &AcadColor) -> Color {
|
||||
|
||||
@@ -4,16 +4,6 @@ use crate::ui::style::common::muted_style as muted;
|
||||
use iced::widget::{button, checkbox, column, container, row, scrollable, text, Space};
|
||||
use iced::{Background, Border, Element, Length, Theme};
|
||||
|
||||
fn button_style(primary: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
move |theme, status| {
|
||||
if primary {
|
||||
button::primary(theme, status)
|
||||
} else {
|
||||
button::secondary(theme, status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_window<'a>(
|
||||
layouts: &'a [(String, bool)],
|
||||
printer: Option<&'a str>,
|
||||
@@ -61,10 +51,10 @@ pub fn view_window<'a>(
|
||||
};
|
||||
|
||||
let mut pdf = button(text(t!("PDF")).size(11))
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
.padding([5, 16]);
|
||||
let mut print = button(text(t!("Print")).size(11))
|
||||
.style(button_style(true))
|
||||
.style(button::primary)
|
||||
.padding([5, 18]);
|
||||
if selected > 0 {
|
||||
pdf = pdf.on_press(Message::PrintAllPdf);
|
||||
@@ -94,11 +84,11 @@ pub fn view_window<'a>(
|
||||
row![
|
||||
button(text(t!("Select all")).size(11))
|
||||
.on_press(Message::PrintAllSelectAll)
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
.padding([4, 10]),
|
||||
button(text(t!("Select none")).size(11))
|
||||
.on_press(Message::PrintAllSelectNone)
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
.padding([4, 10]),
|
||||
Space::new().width(Length::Fill),
|
||||
text(summary).size(11).style(muted),
|
||||
@@ -113,7 +103,7 @@ pub fn view_window<'a>(
|
||||
Space::new().width(Length::Fill),
|
||||
button(text(t!("Options…")).size(11))
|
||||
.on_press(Message::PrintAllOptions)
|
||||
.style(button_style(false))
|
||||
.style(button::secondary)
|
||||
.padding([5, 12]),
|
||||
pdf,
|
||||
print,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use crate::app::Message;
|
||||
use crate::t;
|
||||
use crate::ui::style::common::muted_style;
|
||||
use crate::ui::style::editor_table::{danger_input_style, danger_text_style, EDITOR_TABLE_GUTTER};
|
||||
use iced::widget::{button, column, container, row, scrollable, text, text_input, Space};
|
||||
use iced::{Background, Element, Length, Theme};
|
||||
|
||||
@@ -12,40 +13,6 @@ pub enum ShortcutField {
|
||||
Command,
|
||||
}
|
||||
|
||||
const GUTTER: f32 = 16.0;
|
||||
|
||||
fn danger_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
iced::widget::text::Style {
|
||||
color: Some(theme.palette().danger.base.color),
|
||||
}
|
||||
}
|
||||
|
||||
/// Text-input variant flagging an invalid value: danger border and value
|
||||
/// color on the theme's danger weak background.
|
||||
fn danger_input_style(
|
||||
theme: &Theme,
|
||||
status: iced::widget::text_input::Status,
|
||||
) -> iced::widget::text_input::Style {
|
||||
let danger = theme.palette().danger.base;
|
||||
iced::widget::text_input::Style {
|
||||
background: Background::Color(theme.palette().danger.weak.color),
|
||||
border: iced::border::rounded(4).color(danger.color).width(
|
||||
if matches!(
|
||||
status,
|
||||
iced::widget::text_input::Status::Focused { is_hovered: _ }
|
||||
) {
|
||||
1.5
|
||||
} else {
|
||||
1.0
|
||||
},
|
||||
),
|
||||
icon: danger.color,
|
||||
placeholder: danger.color.scale_alpha(0.7),
|
||||
value: danger.text,
|
||||
selection: danger.color,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_window<'a>(
|
||||
rows: &'a [(String, String)],
|
||||
capture_row: Option<usize>,
|
||||
@@ -65,7 +32,7 @@ pub fn view_window<'a>(
|
||||
.style(muted_style);
|
||||
let gutter = iced::Padding {
|
||||
top: 0.0,
|
||||
right: GUTTER,
|
||||
right: EDITOR_TABLE_GUTTER,
|
||||
bottom: 0.0,
|
||||
left: 0.0,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::app::Message;
|
||||
use crate::io::xref_model::Pathtype;
|
||||
use crate::t;
|
||||
use crate::ui::style::common::muted_style;
|
||||
use crate::ui::style::form::{button_style, dialog_button, field_style, form_radio};
|
||||
use crate::ui::style::form::{button_style, dialog_button, field_style, form_radio, LABEL_WIDTH};
|
||||
use crate::ui::window::block_definition::{group, labeled_checkbox};
|
||||
|
||||
/// One edit in the dialog.
|
||||
@@ -366,8 +366,12 @@ pub fn view_window<'a>(
|
||||
group(
|
||||
t!("Location").into_owned(),
|
||||
column![
|
||||
read_only_field(t!("Found in:").into_owned(), &state.found_in, 92.0),
|
||||
read_only_field(t!("Saved path:").into_owned(), &state.saved_path, 92.0),
|
||||
read_only_field(t!("Found in:").into_owned(), &state.found_in, LABEL_WIDTH,),
|
||||
read_only_field(
|
||||
t!("Saved path:").into_owned(),
|
||||
&state.saved_path,
|
||||
LABEL_WIDTH,
|
||||
),
|
||||
]
|
||||
.spacing(5),
|
||||
Length::Shrink,
|
||||
@@ -383,10 +387,11 @@ pub fn view_window<'a>(
|
||||
t!("Show Details")
|
||||
};
|
||||
let footer = row![
|
||||
button(text(details_label).size(12))
|
||||
.on_press(msg(XrefAttachMsg::Details(!state.details)))
|
||||
.style(button::secondary)
|
||||
.padding([6, 18]),
|
||||
dialog_button(
|
||||
details_label,
|
||||
msg(XrefAttachMsg::Details(!state.details)),
|
||||
false,
|
||||
),
|
||||
Space::new().width(Fill),
|
||||
dialog_button(t!("OK"), msg(XrefAttachMsg::Apply), true),
|
||||
dialog_button(t!("Cancel"), Message::CloseModal, false),
|
||||
|
||||
Reference in new issue
Block a user