forked from 1b-agent/opencadstudio-upstream
fix(styles): make double-click inline rename actually fire
The list row wrapped a `button` inside the `mouse_area`. The button captured the press, so the parent `mouse_area` never saw the second click and `on_double_click` never fired — double-clicking a style name did nothing. Drop the inner button: the row is now a plain `mouse_area` carrying both `on_press` (select) and `on_double_click` (start rename), with selection shown via the container background. Focus the rename field on start so the user can type immediately. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
f2dfd01795
commit
65a25033bc
3 files changed
+47
-42
No files matched your search
+3
-1
@@ -6170,7 +6170,9 @@ impl OpenCADStudio {
|
||||
// ── Shared inline rename (all style managers) ─────────────────
|
||||
Message::StyleRenameStart(kind, name) => {
|
||||
self.style_rename_start(kind, name);
|
||||
Task::none()
|
||||
// Focus the freshly-shown rename field so the user can type
|
||||
// immediately after the double click.
|
||||
iced::widget::operation::focus(crate::ui::style_list::rename_input_id())
|
||||
}
|
||||
Message::StyleRenameEdit(s) => {
|
||||
self.style_rename_buf = s;
|
||||
|
||||
+43
-17
@@ -1,28 +1,51 @@
|
||||
//! Shared style-manager list row.
|
||||
//!
|
||||
//! Every style manager renders the same left-hand list of style names where a
|
||||
//! single click selects and a double click renames inline. Only the row's
|
||||
//! button style differs per manager, so it is passed in.
|
||||
//! single click selects and a double click renames inline.
|
||||
//!
|
||||
//! The whole row is a `mouse_area` (not a `button`): an inner interactive
|
||||
//! widget would capture the press and the parent `mouse_area` would never see
|
||||
//! the second click, so `on_double_click` would never fire. `mouse_area`
|
||||
//! carries both `on_press` (select) and `on_double_click` (rename) itself.
|
||||
|
||||
use crate::app::{Message, StyleKind};
|
||||
use iced::widget::button::{Status, Style};
|
||||
use iced::widget::{button, mouse_area, text, text_input};
|
||||
use iced::{Element, Fill, Theme};
|
||||
use iced::widget::{container, mouse_area, text, text_input};
|
||||
use iced::{Background, Color, Element, Fill, Theme};
|
||||
|
||||
/// Shared id for the inline rename field, so the rename-start handler can focus
|
||||
/// it the moment the row turns editable.
|
||||
pub fn rename_input_id() -> iced::widget::Id {
|
||||
iced::widget::Id::new("style-rename-input")
|
||||
}
|
||||
|
||||
const TEXT: Color = Color {
|
||||
r: 0.88,
|
||||
g: 0.88,
|
||||
b: 0.88,
|
||||
a: 1.0,
|
||||
};
|
||||
const ACTIVE: Color = Color {
|
||||
r: 0.20,
|
||||
g: 0.40,
|
||||
b: 0.70,
|
||||
a: 1.0,
|
||||
};
|
||||
|
||||
/// One row of the style list. Renders an editable `text_input` when `name` is
|
||||
/// the style being renamed (`rename_active`), otherwise a selectable button
|
||||
/// wrapped in a `mouse_area` whose double click starts the rename.
|
||||
/// the style being renamed (`rename_active`), otherwise a selectable row whose
|
||||
/// double click starts the rename.
|
||||
pub fn item<'a>(
|
||||
name: &str,
|
||||
label: String,
|
||||
is_selected: bool,
|
||||
kind: StyleKind,
|
||||
on_select: Message,
|
||||
rename_active: Option<&str>,
|
||||
rename_buf: &'a str,
|
||||
style: impl Fn(&Theme, Status) -> Style + 'a,
|
||||
) -> Element<'a, Message> {
|
||||
if rename_active == Some(name) {
|
||||
text_input("", rename_buf)
|
||||
.id(iced::widget::Id::new("style-rename-input"))
|
||||
.on_input(Message::StyleRenameEdit)
|
||||
.on_submit(Message::StyleRenameCommit(kind))
|
||||
.size(11)
|
||||
@@ -30,14 +53,17 @@ pub fn item<'a>(
|
||||
.width(Fill)
|
||||
.into()
|
||||
} else {
|
||||
mouse_area(
|
||||
button(text(label).size(11))
|
||||
.on_press(on_select)
|
||||
.style(style)
|
||||
.padding([4, 8])
|
||||
.width(Fill),
|
||||
)
|
||||
.on_double_click(Message::StyleRenameStart(kind, name.to_string()))
|
||||
.into()
|
||||
let row = container(text(label).size(11).color(TEXT))
|
||||
.padding([4, 8])
|
||||
.width(Fill)
|
||||
.style(move |_: &Theme| container::Style {
|
||||
background: is_selected.then_some(Background::Color(ACTIVE)),
|
||||
text_color: Some(TEXT),
|
||||
..Default::default()
|
||||
});
|
||||
mouse_area(row)
|
||||
.on_press(on_select)
|
||||
.on_double_click(Message::StyleRenameStart(kind, name.to_string()))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
+1
-24
@@ -48,12 +48,6 @@ const ACCENT: Color = Color {
|
||||
b: 0.85,
|
||||
a: 1.0,
|
||||
};
|
||||
const ACTIVE: Color = Color {
|
||||
r: 0.20,
|
||||
g: 0.40,
|
||||
b: 0.70,
|
||||
a: 1.0,
|
||||
};
|
||||
const LIST: Color = Color {
|
||||
r: 0.12,
|
||||
g: 0.12,
|
||||
@@ -128,11 +122,11 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
||||
crate::ui::style_list::item(
|
||||
name,
|
||||
label,
|
||||
is_sel,
|
||||
s.kind,
|
||||
(s.on_select)(name.clone()),
|
||||
s.rename_active,
|
||||
s.rename_buf,
|
||||
list_item(is_sel),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -222,23 +216,6 @@ fn btn_s(accent: bool) -> impl Fn(&Theme, Status) -> Style {
|
||||
}
|
||||
}
|
||||
|
||||
fn list_item(active: bool) -> impl Fn(&Theme, Status) -> Style {
|
||||
move |_: &Theme, st| Style {
|
||||
background: Some(Background::Color(match (active, st) {
|
||||
(true, _) => ACTIVE,
|
||||
(false, Status::Hovered | Status::Pressed) => Color {
|
||||
r: 0.26,
|
||||
g: 0.26,
|
||||
b: 0.26,
|
||||
a: 1.0,
|
||||
},
|
||||
_ => Color::TRANSPARENT,
|
||||
})),
|
||||
text_color: TEXT,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn hdivider<'a>() -> Element<'a, Message> {
|
||||
container(Space::new().width(Fill).height(1))
|
||||
.width(Fill)
|
||||
|
||||
Reference in new issue
Block a user