Graphic Attributes: quieter swatches, Enter in linetype scale, undo names

- Colour swatches carry no *VARIES* or ByBlock text; the L / B / C / V
  button already shows that.
- A separator sits between "Create Layer with active settings" and the
  "Create fills on the current layer" checkbox.
- The linetype scale field is a plain text field like the Properties
  panel: the first click selects its value, Enter applies it (decimal
  comma and expressions accepted) instead of repeating the last command.
  This drops the iced_aw number_input feature again.
- Undo/redo name fill changes "Fill change" and linetype changes
  "Linetype", in all 21 locales.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VgkJN8DEojuPTumAXLHotu
This commit is contained in:
Claude committed 2026-10-07 19:01:25 +00:00
1 parent c21a1e6538
commit 33a105a619
27 files changed
+168 -108

No files matched your search

Generated
-12
View File
@@ -2571,8 +2571,6 @@ dependencies = [
"iced_core",
"iced_fonts_macros",
"iced_widget",
"num-format",
"num-traits",
"web-time",
]
@@ -3770,16 +3768,6 @@ dependencies = [
"syn 2.0.119",
]
[[package]]
name = "num-format"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3"
dependencies = [
"arrayvec",
"itoa",
]
[[package]]
name = "num-integer"
version = "0.1.46"
+1 -1
View File
@@ -26,7 +26,7 @@ url = "2"
iced = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39", features = ["image", "svg", "advanced", "canvas", "smol", "markdown"] }
iced_runtime = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
iced_aw = { git = "https://github.com/HakanSeven12/iced_aw.git", branch = "agent/fix-iced-fonts", features = ["menu", "context_menu", "color_picker", "drop_down", "number_input"] }
iced_aw = { git = "https://github.com/HakanSeven12/iced_aw.git", branch = "agent/fix-iced-fonts", features = ["menu", "context_menu", "color_picker", "drop_down"] }
bytemuck = { version = "1.25", features = ["derive"] }
glam = { version = "0.33", features = ["bytemuck"] }
rfd = "0.17"
+1 -1
View File
@@ -5652,7 +5652,7 @@ graphic-attributes =
.one-unsupported = سمات الرسم: لم يتم تغيير كائن واحد غير مدعوم.
.unsupported-skipped = سمات الرسم: لم يتم تغيير __ocs_fmt_0__ من الكائنات غير المدعومة.
.fill-transparency = شفافية التعبئة
.line-linetype = نوع خط الخطوط
.fill-change = تغيير التعبئة
.line-transparency = شفافية الخطوط
.cylindrical-short = أسطواني
.spherical-short = كروي
+1 -1
View File
@@ -5640,7 +5640,7 @@ graphic-attributes =
.one-unsupported = Графични атрибути: 1 неподдържан обект не беше променен.
.unsupported-skipped = Графични атрибути: __ocs_fmt_0__ неподдържани обекта не бяха променени.
.fill-transparency = Прозрачност на запълването
.line-linetype = Тип линия на линиите
.fill-change = Промяна на запълването
.line-transparency = Прозрачност на линиите
.cylindrical-short = Цил.
.spherical-short = Сфер.
+1 -1
View File
@@ -5637,7 +5637,7 @@ graphic-attributes =
.one-unsupported = Grafické atributy: 1 nepodporovaný objekt nebyl změněn.
.unsupported-skipped = Grafické atributy: nepodporované objekty (__ocs_fmt_0__) nebyly změněny.
.fill-transparency = Průhlednost výplně
.line-linetype = Typ čáry
.fill-change = Změna výplně
.line-transparency = Průhlednost čar
.cylindrical-short = Válc.
.spherical-short = Kul.
+1 -1
View File
@@ -5638,7 +5638,7 @@ graphic-attributes =
.one-unsupported = Grafikattribute: 1 nicht unterstütztes Objekt wurde nicht geändert.
.unsupported-skipped = Grafikattribute: __ocs_fmt_0__ nicht unterstützte Objekte wurden nicht geändert.
.fill-transparency = Füllungstransparenz
.line-linetype = Linientyp der Linien
.fill-change = Füllung ändern
.line-transparency = Linientransparenz
.cylindrical-short = Zyl.
.spherical-short = Kugel
+1 -1
View File
@@ -5640,7 +5640,7 @@ graphic-attributes =
.one-unsupported = Γραφικά χαρακτηριστικά: 1 μη υποστηριζόμενο αντικείμενο δεν άλλαξε.
.unsupported-skipped = Γραφικά χαρακτηριστικά: __ocs_fmt_0__ μη υποστηριζόμενα αντικείμενα δεν άλλαξαν.
.fill-transparency = Διαφάνεια γεμίσματος
.line-linetype = Τύπος γραμμής
.fill-change = Αλλαγή γεμίσματος
.line-transparency = Διαφάνεια γραμμών
.cylindrical-short = Κυλ.
.spherical-short = Σφαιρ.
+1 -1
View File
@@ -5641,7 +5641,7 @@ graphic-attributes =
.one-unsupported = Graphic Attributes: 1 unsupported object was not changed.
.unsupported-skipped = Graphic Attributes: __ocs_fmt_0__ unsupported objects were not changed.
.fill-transparency = Fill transparency
.line-linetype = Line linetype
.fill-change = Fill change
.line-transparency = Line transparency
.cylindrical-short = Cyl.
.spherical-short = Spher.
+1 -1
View File
@@ -5640,7 +5640,7 @@ graphic-attributes =
.one-unsupported = Atributos gráficos: no se modificó 1 objeto no admitido.
.unsupported-skipped = Atributos gráficos: no se modificaron __ocs_fmt_0__ objetos no admitidos.
.fill-transparency = Transparencia del relleno
.line-linetype = Tipo de línea
.fill-change = Cambio de relleno
.line-transparency = Transparencia de línea
.cylindrical-short = Cil.
.spherical-short = Esfér.
+1 -1
View File
@@ -5637,7 +5637,7 @@ graphic-attributes =
.one-unsupported = Grafiikkamääritteet: 1 tukematonta objektia ei muutettu.
.unsupported-skipped = Grafiikkamääritteet: __ocs_fmt_0__ tukematonta objektia jätettiin muuttamatta.
.fill-transparency = Täytön läpinäkyvyys
.line-linetype = Viivojen viivatyyppi
.fill-change = Täytön muutos
.line-transparency = Viivojen läpinäkyvyys
.cylindrical-short = Lieriö
.spherical-short = Pallo
+1 -1
View File
@@ -5639,7 +5639,7 @@ graphic-attributes =
.one-unsupported = Attributs graphiques : 1 objet non pris en charge n'a pas été modifié.
.unsupported-skipped = Attributs graphiques : __ocs_fmt_0__ objets non pris en charge n'ont pas été modifiés.
.fill-transparency = Transparence du remplissage
.line-linetype = Type de ligne
.fill-change = Modification du remplissage
.line-transparency = Transparence des lignes
.cylindrical-short = Cyl.
.spherical-short = Sphér.
+1 -1
View File
@@ -5628,7 +5628,7 @@ graphic-attributes =
.one-unsupported = ग्राफ़िक गुण: 1 असमर्थित ऑब्जेक्ट नहीं बदला गया।
.unsupported-skipped = ग्राफ़िक गुण: __ocs_fmt_0__ असमर्थित ऑब्जेक्ट नहीं बदले गए।
.fill-transparency = भराव पारदर्शिता
.line-linetype = रेखा का लाइनटाइप
.fill-change = भराव परिवर्तन
.line-transparency = रेखा पारदर्शिता
.cylindrical-short = बेलन.
.spherical-short = गोल.
+1 -1
View File
@@ -5639,7 +5639,7 @@ graphic-attributes =
.one-unsupported = Grafikus jellemzők: 1 nem támogatott objektum nem változott.
.unsupported-skipped = Grafikus jellemzők: __ocs_fmt_0__ nem támogatott objektum nem változott.
.fill-transparency = Kitöltés átlátszósága
.line-linetype = Vonaltípus
.fill-change = Kitöltés módosítása
.line-transparency = Vonalak átlátszósága
.cylindrical-short = Henger
.spherical-short = Gömb
+1 -1
View File
@@ -5639,7 +5639,7 @@ graphic-attributes =
.one-unsupported = Attributi grafici: 1 oggetto non supportato non è stato modificato.
.unsupported-skipped = Attributi grafici: __ocs_fmt_0__ oggetti non supportati non sono stati modificati.
.fill-transparency = Trasparenza riempimento
.line-linetype = Tipo di linea
.fill-change = Modifica riempimento
.line-transparency = Trasparenza linee
.cylindrical-short = Cil.
.spherical-short = Sfer.
+1 -1
View File
@@ -5628,7 +5628,7 @@ graphic-attributes =
.one-unsupported = グラフィック属性: サポートされていないオブジェクト 1 個は変更されませんでした。
.unsupported-skipped = グラフィック属性: サポートされていないオブジェクト __ocs_fmt_0__ 個は変更されませんでした。
.fill-transparency = 塗り潰しの透過性
.line-linetype = 線の線種
.fill-change = 塗り潰しの変更
.line-transparency = 線の透過性
.cylindrical-short = 円柱
.spherical-short = 球
+1 -1
View File
@@ -5639,7 +5639,7 @@ graphic-attributes =
.one-unsupported = 그래픽 속성: 지원되지 않는 객체 1개가 변경되지 않았습니다.
.unsupported-skipped = 그래픽 속성: 지원되지 않는 객체 __ocs_fmt_0__개가 변경되지 않았습니다.
.fill-transparency = 채우기 투명도
.line-linetype = 선의 선종류
.fill-change = 채우기 변경
.line-transparency = 선 투명도
.cylindrical-short = 원통
.spherical-short = 구
+1 -1
View File
@@ -5638,7 +5638,7 @@ graphic-attributes =
.one-unsupported = Grafische attributen: 1 niet-ondersteund object is niet gewijzigd.
.unsupported-skipped = Grafische attributen: __ocs_fmt_0__ niet-ondersteunde objecten zijn niet gewijzigd.
.fill-transparency = Transparantie vulling
.line-linetype = Lijntype lijnen
.fill-change = Vulling wijzigen
.line-transparency = Transparantie lijnen
.cylindrical-short = Cil.
.spherical-short = Bol
+1 -1
View File
@@ -5639,7 +5639,7 @@ graphic-attributes =
.one-unsupported = Atrybuty graficzne: 1 nieobsługiwany obiekt nie został zmieniony.
.unsupported-skipped = Atrybuty graficzne: nieobsługiwane obiekty (__ocs_fmt_0__) nie zostały zmienione.
.fill-transparency = Przezroczystość wypełnienia
.line-linetype = Rodzaj linii
.fill-change = Zmiana wypełnienia
.line-transparency = Przezroczystość linii
.cylindrical-short = Walc.
.spherical-short = Sfer.
+1 -1
View File
@@ -5640,7 +5640,7 @@ graphic-attributes =
.one-unsupported = Atributos gráficos: 1 objeto não suportado não foi alterado.
.unsupported-skipped = Atributos gráficos: __ocs_fmt_0__ objetos não suportados não foram alterados.
.fill-transparency = Transparência do preenchimento
.line-linetype = Tipo de linha
.fill-change = Alteração de preenchimento
.line-transparency = Transparência da linha
.cylindrical-short = Cil.
.spherical-short = Esfér.
+1 -1
View File
@@ -5641,7 +5641,7 @@ graphic-attributes =
.one-unsupported = Графические атрибуты: 1 неподдерживаемый объект не изменён.
.unsupported-skipped = Графические атрибуты: неподдерживаемые объекты (__ocs_fmt_0__) не изменены.
.fill-transparency = Прозрачность заливки
.line-linetype = Тип линий
.fill-change = Изменение заливки
.line-transparency = Прозрачность линий
.cylindrical-short = Цил.
.spherical-short = Сфер.
+1 -1
View File
@@ -5563,7 +5563,7 @@ graphic-attributes =
.one-unsupported = Grafik öznitelikleri: desteklenmeyen 1 nesne değiştirilmedi.
.unsupported-skipped = Grafik öznitelikleri: desteklenmeyen __ocs_fmt_0__ nesne değiştirilmedi.
.fill-transparency = Dolgu saydamlığı
.line-linetype = Çizgi tipi
.fill-change = Dolgu değişikliği
.line-transparency = Çizgi saydamlığı
.cylindrical-short = Sil.
.spherical-short = Küre
+1 -1
View File
@@ -5623,7 +5623,7 @@ graphic-attributes =
.one-unsupported = 图形特性: 1 个不支持的对象未更改。
.unsupported-skipped = 图形特性: __ocs_fmt_0__ 个不支持的对象未更改。
.fill-transparency = 填充透明度
.line-linetype = 线的线型
.fill-change = 更改填充
.line-transparency = 线的透明度
.cylindrical-short = 圆柱
.spherical-short = 球形
+1 -1
View File
@@ -5635,7 +5635,7 @@ graphic-attributes =
.one-unsupported = 圖形特性: 1 個不支援的物件未變更。
.unsupported-skipped = 圖形特性: __ocs_fmt_0__ 個不支援的物件未變更。
.fill-transparency = 填充透明度
.line-linetype = 線的線型
.fill-change = 變更填充
.line-transparency = 線的透明度
.cylindrical-short = 圓柱
.spherical-short = 球形
+85 -3
View File
@@ -219,7 +219,11 @@ impl OpenCADStudio {
use GraphicAttributesMsg as M;
if !matches!(
message,
M::ToggleMenu(_) | M::HatchPatternSearch(_) | M::HatchPatternFocus(_) | M::Gradient(_)
M::ToggleMenu(_)
| M::HatchPatternSearch(_)
| M::HatchPatternFocus(_)
| M::LineLinetypeScaleInput(_)
| M::Gradient(_)
) {
self.graphic_attributes.open_menu = None;
}
@@ -253,6 +257,19 @@ impl OpenCADStudio {
M::LineLinetype(linetype) => self.on_line_linetype(linetype),
M::LineLineweight(lineweight) => self.on_line_lineweight(lineweight),
M::LineLinetypeScale(scale) => self.on_line_linetype_scale(scale),
M::LineLinetypeScaleInput(value) => {
self.graphic_attributes.linetype_scale_input = Some(value);
Task::none()
}
M::LineLinetypeScaleSubmit => {
match self.graphic_attributes.linetype_scale_input.take() {
Some(typed) => {
let value = crate::app::expr_eval::eval_number(&typed.replace(',', "."));
value.map_or_else(Task::none, |scale| self.on_line_linetype_scale(scale))
}
None => Task::none(),
}
}
M::LineTransparency(transparency) => self.on_line_transparency(transparency),
M::FillColor(color) => self.on_solid_fill_color(color),
M::FillTransparency(transparency) => self.on_fill_transparency(transparency),
@@ -731,7 +748,7 @@ impl OpenCADStudio {
);
}
let selected = selected.as_slice();
let pending = self.begin_undo(i, crate::t!("Graphic Attributes"), selected.len(), true);
let pending = self.begin_undo(i, crate::t!("Fill change"), selected.len(), true);
let mut changed = false;
for handle in to_close {
let Some(mut entity) = self.tabs[i].scene.document.get_entity(*handle).cloned() else {
@@ -920,7 +937,7 @@ impl OpenCADStudio {
if !self.has_selection() {
return self.on_ribbon_linetype_changed(linetype);
}
self.edit_graphic_part(Part::Line, &crate::t!("Line linetype"), |entity| {
self.edit_graphic_part(Part::Line, &crate::t!("Linetype"), |entity| {
crate::scene::view::dispatch::apply_common_prop(entity, "linetype", &linetype);
});
Task::none()
@@ -1604,4 +1621,69 @@ mod tests {
Some((DockSide::Right, 0))
);
}
fn output_since(app: &OpenCADStudio, start: usize) -> String {
app.command_line.history[start..]
.iter()
.map(|entry| entry.text.as_str())
.collect::<Vec<_>>()
.join("\n")
}
#[test]
fn undo_names_fill_and_linetype_changes() {
let mut app = fresh();
let boundary = add_closed_square(&mut app, 0.0);
select(&mut app, &[boundary]);
let _ = app.update(ga(GraphicAttributesMsg::Fill(GraphicAttribute::Solid)));
let start = app.command_line.history.len();
let _ = app.update(Message::Undo);
assert!(output_since(&app, start).contains("Undo: Fill change"));
let _ = app.update(ga(GraphicAttributesMsg::LineLinetype("Continuous".into())));
let start = app.command_line.history.len();
let _ = app.update(Message::Undo);
assert!(output_since(&app, start).contains("Undo: Linetype"));
}
#[test]
fn typed_linetype_scale_is_applied_on_enter() {
let mut app = fresh();
let i = app.active_tab;
let line = app.tabs[i].scene.add_entity(EntityType::Line(Line::new()));
select(&mut app, &[line]);
// Enter without typing changes nothing.
let _ = app.update(ga(GraphicAttributesMsg::LineLinetypeScaleSubmit));
assert_eq!(common(&app, line).linetype_scale, 1.0);
// Typing alone does not apply; Enter does, with a decimal comma too.
let _ = app.update(ga(GraphicAttributesMsg::LineLinetypeScaleInput("0,35".into())));
assert_eq!(common(&app, line).linetype_scale, 1.0);
let _ = app.update(ga(GraphicAttributesMsg::LineLinetypeScaleSubmit));
assert_eq!(common(&app, line).linetype_scale, 0.35);
assert!(app.graphic_attributes.linetype_scale_input.is_none());
// Invalid or non-positive input is dropped.
for typed in ["abc", "0", "-2"] {
let _ = app.update(ga(GraphicAttributesMsg::LineLinetypeScaleInput(typed.into())));
let _ = app.update(ga(GraphicAttributesMsg::LineLinetypeScaleSubmit));
assert_eq!(common(&app, line).linetype_scale, 0.35);
}
}
#[test]
fn clicking_the_linetype_scale_field_selects_it_once() {
let mut app = fresh();
let field = iced::widget::Id::new(palette::LINETYPE_SCALE_FIELD);
let _ = app.update(Message::PropSyncActive(Some(field.clone())));
assert!(app.graphic_attributes.linetype_scale_focused);
// Focus elsewhere drops unsubmitted text.
app.graphic_attributes.linetype_scale_input = Some("3".into());
let _ = app.update(Message::PropSyncActive(None));
assert!(!app.graphic_attributes.linetype_scale_focused);
assert!(app.graphic_attributes.linetype_scale_input.is_none());
}
}
+16 -1
View File
@@ -6887,13 +6887,28 @@ impl OpenCADStudio {
Message::PropAttrCommit(tag) => self.on_prop_attr_commit(tag),
Message::PropPointerPressed => {
if !self.dock_panel_visible(crate::ui::dock::PanelId::Properties) {
if !self.dock_panel_visible(crate::ui::dock::PanelId::Properties)
&& !self.dock_panel_visible(crate::ui::dock::PanelId::GraphicAttributes)
{
return Task::none();
}
crate::ui::properties::sync_active_field_task()
}
Message::PropSyncActive(focused) => {
// The Graphic Attributes linetype scale field behaves like a
// Properties field: the first click selects its value.
let scale_field = iced::widget::Id::new(
crate::ui::window::graphic_attributes::LINETYPE_SCALE_FIELD,
);
if focused.as_ref() == Some(&scale_field) {
if !std::mem::replace(&mut self.graphic_attributes.linetype_scale_focused, true) {
return iced::widget::operation::select_all(scale_field);
}
return Task::none();
}
self.graphic_attributes.linetype_scale_focused = false;
self.graphic_attributes.linetype_scale_input = None;
let panel = &mut self.tabs[self.active_tab].properties;
if let Some(id) = focused.as_ref() {
if let Some(key) = panel.prop_field_key_for_id(id) {
+1 -1
View File
@@ -5274,7 +5274,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
"Graphic Attributes: 1 unsupported object was not changed." => Some(("graphic-attributes", "one-unsupported")),
"Graphic Attributes: {skipped} unsupported objects were not changed." => Some(("graphic-attributes", "unsupported-skipped")),
"Fill transparency" => Some(("graphic-attributes", "fill-transparency")),
"Line linetype" => Some(("graphic-attributes", "line-linetype")),
"Fill change" => Some(("graphic-attributes", "fill-change")),
"Line transparency" => Some(("graphic-attributes", "line-transparency")),
"Cyl." => Some(("graphic-attributes", "cylindrical-short")),
"Spher." => Some(("graphic-attributes", "spherical-short")),
+44 -69
View File
@@ -21,15 +21,14 @@ type DrawDepth = FxHashMap<u64, [f32; 2]>;
const PALETTE_CONTROL_ICON_SIZE: f32 = 20.0;
const COMPACT_BUTTON_HEIGHT: f32 = 22.0;
const LINETYPE_SCALE_STEP: f64 = 0.1;
const TRANSPARENCY_ICON: &[u8] =
include_bytes!("../../../assets/icons/attributes/transparency.svg");
const LINEWEIGHT_ICON: &[u8] = include_bytes!("../../../assets/icons/attributes/lineweight.svg");
/// A usable object linetype scale (CELTSCALE): any positive finite value.
/// Spinner steps are rounded to six decimals so repeated `±0.1` steps do not
/// accumulate floating-point noise; typed values such as the ISO pen widths
/// 0.13, 0.18, 0.25 and 0.35 are kept as entered.
/// A usable object linetype scale (CELTSCALE): any positive finite value,
/// rounded to six decimals so arithmetic noise does not reach the drawing.
/// Typed values such as the ISO pen widths 0.13, 0.18, 0.25 and 0.35 are
/// kept as entered.
pub(crate) fn normalized_linetype_scale(value: f64) -> Option<f64> {
let value = (value * 1.0e6).round() / 1.0e6;
(value.is_finite() && value > 0.0).then_some(value)
@@ -109,6 +108,9 @@ pub enum GraphicAttributesMsg {
LineLinetype(String),
LineLineweight(LineWeight),
LineLinetypeScale(f64),
/// Text typed in the linetype scale field, applied on Enter.
LineLinetypeScaleInput(String),
LineLinetypeScaleSubmit,
LineTransparency(Transparency),
FillColor(AcadColor),
FillTransparency(Transparency),
@@ -150,6 +152,10 @@ pub struct GraphicAttributesState {
pub pending_fill_close: Option<PendingFillClose>,
/// New fills go to the current layer instead of their object's layer.
pub fill_on_current_layer: bool,
/// Text typed in the linetype scale field, until Enter applies it.
pub linetype_scale_input: Option<String>,
/// Whether the linetype scale field has focus (its value was selected).
pub linetype_scale_focused: bool,
/// View-side caches; `view` runs after every message, so neither the
/// fill lookup nor the gradient preview is rebuilt unless its input changed.
fill_index: RefCell<Option<(u64, FillIndex)>>,
@@ -694,35 +700,16 @@ fn color_control<'a>(
target: ColorPickTarget,
changed: fn(AcadColor) -> GraphicAttributesMsg,
) -> Element<'a, Message> {
let label = if info.varies {
Some("*VARIES*")
} else if info.color == AcadColor::ByBlock {
Some("ByBlock")
} else {
None
};
let label: Element<'a, Message> = match label {
Some(label) => container(text(label).size(10))
.width(Fill)
.align_x(iced::Left)
.align_y(iced::Center)
.padding([0, 6])
.into(),
None => container(Space::new()).width(Fill).height(Fill).into(),
};
// The L / B / C / V button already shows ByLayer, ByBlock and *VARIES*,
// so the swatch carries no text.
let display = info.display;
let swatch = button(label)
let swatch = button(Space::new().width(Fill).height(Fill))
.on_press(Message::OpenColorWindow(target.clone(), info.color))
.width(Fill)
.height(COMPACT_BUTTON_HEIGHT)
.padding(0)
.style(move |theme: &Theme, status| button::Style {
background: Some(Background::Color(display)),
text_color: if display.r * 0.299 + display.g * 0.587 + display.b * 0.114 > 0.55 {
iced::Color::BLACK
} else {
iced::Color::WHITE
},
border: Border {
color: if matches!(status, button::Status::Hovered) {
theme.palette().primary.base.color
@@ -818,6 +805,7 @@ fn header_menu(side: DockSide, open: bool, fill_on_current_layer: bool) -> Eleme
item("Set all attributes ByBlock", GraphicAttributesMsg::SetAllByBlock),
item("Remove ByLayer / ByBlock", GraphicAttributesMsg::RemoveReferences),
item("Create Layer with active settings", GraphicAttributesMsg::CreateLayer),
container(iced::widget::rule::horizontal(1)).padding([2, 4]),
container(
iced::widget::checkbox(fill_on_current_layer)
.label(crate::t!("Create fills on the current layer"))
@@ -1067,28 +1055,26 @@ fn linetype_row<'a>(
.into()
}
fn linetype_scale_field<'a>(scale: f64, varies: bool, continuous: bool) -> Element<'a, Message> {
let field: Element<'a, Message> = if varies {
text_input("*VARIES*", "")
.size(crate::ui::ROW_H * 0.42)
.padding([5, 5])
.style(crate::ui::properties::combo_input_style)
.width(Fill)
.into()
} else {
let value = normalized_linetype_scale(scale).unwrap_or(1.0);
let mut input = iced_aw::number_input(
&value,
(std::ops::Bound::Excluded(0.0), std::ops::Bound::Unbounded),
|value: f64| match normalized_linetype_scale(value) {
Some(value) => msg(GraphicAttributesMsg::LineLinetypeScale(value)),
None => Message::Noop,
},
)
.step(LINETYPE_SCALE_STEP)
.set_size(crate::ui::ROW_H * 0.42)
/// Widget id of the linetype scale field, for select-all on focus.
pub(crate) const LINETYPE_SCALE_FIELD: &str = "graphic-linetype-scale";
/// Like a Properties field: clicking selects the value, Enter applies it.
fn linetype_scale_field<'a>(
scale: f64,
varies: bool,
continuous: bool,
typed: Option<&str>,
) -> Element<'a, Message> {
let shown = match typed {
Some(typed) => typed.to_string(),
None if varies => String::new(),
None => normalized_linetype_scale(scale).unwrap_or(1.0).to_string(),
};
let mut field = text_input(if varies { "*VARIES*" } else { "" }, &shown)
.id(iced::widget::Id::new(LINETYPE_SCALE_FIELD))
.size(crate::ui::ROW_H * 0.42)
.padding([5, 5])
.input_style(move |theme: &Theme, status| {
.style(move |theme: &Theme, status| {
let mut style = crate::ui::properties::combo_input_style(theme, status);
if continuous {
let disabled = theme.palette().background.base.text.scale_alpha(0.42);
@@ -1097,25 +1083,12 @@ fn linetype_scale_field<'a>(scale: f64, varies: bool, continuous: bool) -> Eleme
}
style
})
.style(move |theme: &Theme, status| {
let text = theme.palette().background.base.text;
iced_aw::number_input::number_input::Style {
button_background: None,
icon_color: if continuous || status == iced_aw::style::Status::Disabled {
text.scale_alpha(0.42)
} else {
text
},
}
})
.width(Fill);
if continuous {
input = input.on_input_maybe(None::<fn(f64) -> Message>);
} else {
input = input.on_submit(Message::Noop);
}
input.into()
};
if !continuous {
field = field
.on_input(|value| msg(GraphicAttributesMsg::LineLinetypeScaleInput(value)))
.on_submit(msg(GraphicAttributesMsg::LineLinetypeScaleSubmit));
}
let icon = GraphicAttribute::Solid.icon();
let icon = if continuous {
crate::ui::icons::themed_disabled(icon, PALETTE_CONTROL_ICON_SIZE)
@@ -1193,8 +1166,10 @@ fn line_section<'a>(
no_selection: bool,
draw_depth: &DrawDepth,
side: DockSide,
open_menu: Option<Menu>,
state: &GraphicAttributesState,
) -> Vec<Element<'a, Message>> {
let open_menu = state.open_menu;
let typed_scale = state.linetype_scale_input.as_deref();
let mut rows = Vec::new();
if handles.is_empty() && !no_selection {
return rows;
@@ -1246,7 +1221,7 @@ fn line_section<'a>(
let effective = effective_lineweight(document, handles, draw_depth, lineweight);
rows.push(
row![
linetype_scale_field(scale, scale_varies, continuous),
linetype_scale_field(scale, scale_varies, continuous, typed_scale),
lineweight_field(
properties,
lineweight,
@@ -1296,7 +1271,7 @@ pub fn view<'a>(
selected.is_empty(),
draw_depth,
side,
open_menu,
state,
));
body = body