From f2b375ab245b9e88a61ae510839b1dea292803cb Mon Sep 17 00:00:00 2001 From: Karim Jerbi Date: Sat, 15 Aug 2026 08:56:33 +0100 Subject: [PATCH] feat(read-only): add shared selectable read-only field helper --- src/ui/mod.rs | 1 + src/ui/read_only.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/ui/read_only.rs diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 3db8c005..6a8c7cd2 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -10,6 +10,7 @@ pub mod modal; pub mod overlay; pub mod popup; pub mod properties; +pub mod read_only; pub mod ribbon; pub mod side_toolbar; pub mod statusbar; diff --git a/src/ui/read_only.rs b/src/ui/read_only.rs new file mode 100644 index 00000000..db86824c --- /dev/null +++ b/src/ui/read_only.rs @@ -0,0 +1,38 @@ +use iced::widget::text_input::{self, Status}; +use iced::{Background, Border, Color, Element, Length, Theme}; + +/// A read-only value field: a text input with no `on_input` handler. +/// +/// In the pinned iced fork, an input without `on_input` is treated as +/// disabled, so the caret is never drawn and typing does nothing — but mouse +/// click/drag selection and Ctrl+C / Ctrl+A still work. This gives a field the +/// user can select and copy but never edit or place a blinker in. +#[allow(dead_code)] // consumed by the read-only field unification tasks +pub fn field<'a, Message: Clone + 'a>(value: &'a str, size: f32, width: Length) -> Element<'a, Message> { + iced::widget::text_input("", value) + .size(size) + .style(read_only_style) + .padding([3, 6]) + .width(width) + .into() +} + +/// Muted "disabled input box" look: the same bordered box geometry as the +/// editable fields but with a quieter background and text so it reads as +/// read-only. The selection highlight is kept so copy stays discoverable. +#[allow(dead_code)] // used only via `field`, which the later tasks wire up +fn read_only_style(theme: &Theme, _status: Status) -> text_input::Style { + let palette = theme.palette(); + text_input::Style { + background: Background::Color(palette.background.weakest.color), + border: Border { + color: palette.background.neutral.color, + width: 1.0, + radius: 2.0.into(), + }, + icon: Color::TRANSPARENT, + placeholder: palette.background.base.text.scale_alpha(0.48), + value: palette.background.base.text.scale_alpha(0.72), + selection: palette.primary.base.color.scale_alpha(0.5), + } +}