feat(properties): copy read-only property values to the clipboard
A read-only value cell is now click-to-copy: clicking writes the full,
un-elided value to the system clipboard (copy cursor on hover). One
change in render_ro_row, so it covers every read-only row for every
entity. Adds Message::PropCopyValue routed through iced:📋:write.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4d2471cafd
commit
c59a584d14
3 changed files with 20 additions and 3 deletions
|
|
@ -1431,6 +1431,9 @@ pub enum Message {
|
||||||
},
|
},
|
||||||
/// User committed a geometry/common field edit (Enter pressed).
|
/// User committed a geometry/common field edit (Enter pressed).
|
||||||
PropGeomCommit(&'static str),
|
PropGeomCommit(&'static str),
|
||||||
|
/// Copy a read-only property value to the system clipboard (click on a
|
||||||
|
/// read-only value cell). Carries the full, un-elided value.
|
||||||
|
PropCopyValue(String),
|
||||||
/// User is typing in a block-attribute value field (live buffer update),
|
/// User is typing in a block-attribute value field (live buffer update),
|
||||||
/// keyed by the attribute tag.
|
/// keyed by the attribute tag.
|
||||||
PropAttrInput { tag: String, value: String },
|
PropAttrInput { tag: String, value: String },
|
||||||
|
|
|
||||||
|
|
@ -2107,6 +2107,8 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
Message::PropGeomCommit(field) => self.on_prop_geom_commit(field),
|
Message::PropGeomCommit(field) => self.on_prop_geom_commit(field),
|
||||||
|
|
||||||
|
Message::PropCopyValue(value) => iced::clipboard::write(value),
|
||||||
|
|
||||||
Message::PropAttrInput { tag, value } => {
|
Message::PropAttrInput { tag, value } => {
|
||||||
self.tabs[self.active_tab]
|
self.tabs[self.active_tab]
|
||||||
.properties
|
.properties
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@ use std::fmt;
|
||||||
use crate::ui::ROW_H;
|
use crate::ui::ROW_H;
|
||||||
use acadrust::types::{Color as AcadColor, LineWeight};
|
use acadrust::types::{Color as AcadColor, LineWeight};
|
||||||
use acadrust::Handle;
|
use acadrust::Handle;
|
||||||
use iced::widget::{button, column, combo_box, container, row, scrollable, text, text_input};
|
use iced::widget::{
|
||||||
|
button, column, combo_box, container, mouse_area, row, scrollable, text, text_input,
|
||||||
|
};
|
||||||
use iced::{Background, Border, Color, Element, Length, Padding, Theme};
|
use iced::{Background, Border, Color, Element, Length, Padding, Theme};
|
||||||
|
|
||||||
// ── Row-height-derived constants ─────────────────────────────────────────
|
// ── Row-height-derived constants ─────────────────────────────────────────
|
||||||
|
|
@ -865,7 +867,7 @@ fn render_bool_row<'a>(label: &'a str, field: &'static str, value: bool) -> Elem
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_ro_row<'a>(label: &'a str, value: &'a str) -> Element<'a, Message> {
|
fn render_ro_row<'a>(label: &'a str, value: &'a str) -> Element<'a, Message> {
|
||||||
let value = crate::ui::text_util::elide(value, 22);
|
let display = crate::ui::text_util::elide(value, 22);
|
||||||
let label_col = container(text(crate::ui::text_util::elide(label, 18)).size(FONT_SZ).color(LABEL_COLOR))
|
let label_col = container(text(crate::ui::text_util::elide(label, 18)).size(FONT_SZ).color(LABEL_COLOR))
|
||||||
.style(|_: &Theme| container::Style {
|
.style(|_: &Theme| container::Style {
|
||||||
background: Some(Background::Color(LABEL_BG)),
|
background: Some(Background::Color(LABEL_BG)),
|
||||||
|
|
@ -880,7 +882,7 @@ fn render_ro_row<'a>(label: &'a str, value: &'a str) -> Element<'a, Message> {
|
||||||
left: 6.0,
|
left: 6.0,
|
||||||
right: 6.0,
|
right: 6.0,
|
||||||
});
|
});
|
||||||
let value_col = container(text(value).size(FONT_SZ).color(VALUE_COLOR))
|
let value_inner = container(text(display).size(FONT_SZ).color(VALUE_COLOR))
|
||||||
.style(|_: &Theme| container::Style {
|
.style(|_: &Theme| container::Style {
|
||||||
background: Some(Background::Color(VALUE_BG)),
|
background: Some(Background::Color(VALUE_BG)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -894,6 +896,16 @@ fn render_ro_row<'a>(label: &'a str, value: &'a str) -> Element<'a, Message> {
|
||||||
left: 6.0,
|
left: 6.0,
|
||||||
right: 6.0,
|
right: 6.0,
|
||||||
});
|
});
|
||||||
|
// A read-only value is still copyable: click the value cell to copy the
|
||||||
|
// full (un-elided) text to the clipboard.
|
||||||
|
let value_col: Element<'a, Message> = if value.is_empty() {
|
||||||
|
value_inner.into()
|
||||||
|
} else {
|
||||||
|
mouse_area(value_inner)
|
||||||
|
.on_press(Message::PropCopyValue(value.to_string()))
|
||||||
|
.interaction(iced::mouse::Interaction::Copy)
|
||||||
|
.into()
|
||||||
|
};
|
||||||
container(row![label_col, value_col])
|
container(row![label_col, value_col])
|
||||||
.height(Length::Fixed(ROW_H))
|
.height(Length::Fixed(ROW_H))
|
||||||
.style(|_: &Theme| container::Style {
|
.style(|_: &Theme| container::Style {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue