forked from 1b-agent/opencadstudio-upstream
feat(xref): per-row path actions and right-click row selection
Row menu Select New Path and Find and Replace now act on the right-clicked row via dedicated XrefRowPathPick / XrefRowFindReplacePrompt messages (prefill + command-line focus, XOPEN output included). Rows use a RightClickArea wrapper so right-click selects the row even though ContextMenu captures the press, and opening or acting on the menu resets the Change Path Type flyout state.
This commit is contained in:
1 parent
10758f3e59
commit
be32af38a2
3 files changed
+259
-30
No files matched your search
@@ -2403,6 +2403,10 @@ pub enum Message {
|
|||||||
/// Prefill the command line for Find & Replace across references
|
/// Prefill the command line for Find & Replace across references
|
||||||
/// (`XREF Path Find <old> <new>`); the CLI parses and runs it.
|
/// (`XREF Path Find <old> <new>`); the CLI parses and runs it.
|
||||||
XrefFindReplacePrompt,
|
XrefFindReplacePrompt,
|
||||||
|
/// Pick a new path for a specific row index.
|
||||||
|
XrefRowPathPick(usize),
|
||||||
|
/// Prefill the command line for Find & Replace for a specific row index.
|
||||||
|
XrefRowFindReplacePrompt(usize),
|
||||||
XrefRowChangePathEnter,
|
XrefRowChangePathEnter,
|
||||||
XrefRowChangePathLeave,
|
XrefRowChangePathLeave,
|
||||||
LayerToggleVisible(usize),
|
LayerToggleVisible(usize),
|
||||||
|
|||||||
+39
-5
@@ -2163,6 +2163,7 @@ impl OpenCADStudio {
|
|||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::XrefRowRightClick(index) => {
|
Message::XrefRowRightClick(index) => {
|
||||||
|
self.xref_manager.row_change_path_open = false;
|
||||||
self.xref_manager.right_click_select(index);
|
self.xref_manager.right_click_select(index);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
@@ -2237,6 +2238,7 @@ impl OpenCADStudio {
|
|||||||
self.xref_manager.attach_open = false;
|
self.xref_manager.attach_open = false;
|
||||||
self.xref_manager.refresh_open = false;
|
self.xref_manager.refresh_open = false;
|
||||||
self.xref_manager.path_open = false;
|
self.xref_manager.path_open = false;
|
||||||
|
self.xref_manager.row_change_path_open = false;
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
Message::XrefPathPick => Task::perform(
|
Message::XrefPathPick => Task::perform(
|
||||||
@@ -2307,12 +2309,14 @@ impl OpenCADStudio {
|
|||||||
// Open is not a palette op — it navigates to the file.
|
// Open is not a palette op — it navigates to the file.
|
||||||
if op == crate::ui::window::xref_manager::XrefPaletteOp::Open {
|
if op == crate::ui::window::xref_manager::XrefPaletteOp::Open {
|
||||||
self.xref_manager.right_click_select(index);
|
self.xref_manager.right_click_select(index);
|
||||||
|
self.xref_manager.row_change_path_open = false;
|
||||||
if let Some(entry) = self.xref_manager.entries.get(index) {
|
if let Some(entry) = self.xref_manager.entries.get(index) {
|
||||||
if let Some(found) = entry.found_at.clone() {
|
if let Some(found) = entry.found_at.clone() {
|
||||||
let is_dwg = found.to_ascii_lowercase().ends_with(".dwg")
|
let is_dwg = found.to_ascii_lowercase().ends_with(".dwg")
|
||||||
|| found.to_ascii_lowercase().ends_with(".dxf");
|
|| found.to_ascii_lowercase().ends_with(".dxf");
|
||||||
|
self.command_line.push_output(crate::tf!("XOPEN: opening \"{}\".", found).as_ref());
|
||||||
if is_dwg {
|
if is_dwg {
|
||||||
return Task::done(Message::OpenRecent(std::path::PathBuf::from(found)));
|
return self.update(Message::OpenRecent(std::path::PathBuf::from(found)));
|
||||||
} else {
|
} else {
|
||||||
let _ = open::that_detached(&found);
|
let _ = open::that_detached(&found);
|
||||||
}
|
}
|
||||||
@@ -2324,12 +2328,12 @@ impl OpenCADStudio {
|
|||||||
}
|
}
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
// For XrefPathPick the row menu just sets the anchor; the
|
// Attach prompts the file dialog to pick a drawing to attach.
|
||||||
// picker's result handler does the work. Don't run it through
|
|
||||||
// xref_manager_op.
|
|
||||||
if matches!(op, crate::ui::window::xref_manager::XrefPaletteOp::Attach) {
|
if matches!(op, crate::ui::window::xref_manager::XrefPaletteOp::Attach) {
|
||||||
self.xref_manager.right_click_select(index);
|
self.xref_manager.right_click_select(index);
|
||||||
return Task::done(Message::XAttachPick);
|
self.xref_manager.row_change_path_open = false;
|
||||||
|
self.command_line.push_output(crate::t!("XATTACH").as_ref());
|
||||||
|
return self.update(Message::XAttachPick);
|
||||||
}
|
}
|
||||||
// Row-scoped op: select the row first, then run the op.
|
// Row-scoped op: select the row first, then run the op.
|
||||||
self.xref_manager.right_click_select(index);
|
self.xref_manager.right_click_select(index);
|
||||||
@@ -2337,6 +2341,36 @@ impl OpenCADStudio {
|
|||||||
self.xref_manager_op(op);
|
self.xref_manager_op(op);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
Message::XrefRowPathPick(index) => {
|
||||||
|
self.xref_manager.right_click_select(index);
|
||||||
|
self.xref_manager.row_change_path_open = false;
|
||||||
|
self.update(Message::XrefPathPick)
|
||||||
|
}
|
||||||
|
Message::XrefRowFindReplacePrompt(index) => {
|
||||||
|
self.xref_manager.right_click_select(index);
|
||||||
|
self.xref_manager.row_change_path_open = false;
|
||||||
|
let prefill = if let Some(entry) = self.xref_manager.entries.get(index) {
|
||||||
|
let saved = &entry.saved_path;
|
||||||
|
if let Some(parent) = std::path::Path::new(saved).parent().and_then(|p| p.to_str()) {
|
||||||
|
if !parent.is_empty() {
|
||||||
|
format!("XREF Path Find \"{}\" ", parent)
|
||||||
|
} else {
|
||||||
|
"XREF Path Find ".to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"XREF Path Find ".to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"XREF Path Find ".to_string()
|
||||||
|
};
|
||||||
|
self.command_line.input = prefill;
|
||||||
|
self.command_line.autocomplete_cursor = None;
|
||||||
|
self.command_line.cancel_history_navigation();
|
||||||
|
self.command_line.push_info(
|
||||||
|
crate::t!("Specify replacement path: XREF Path Find <old> <new>").as_ref(),
|
||||||
|
);
|
||||||
|
return self.focus_cmd_input();
|
||||||
|
}
|
||||||
Message::XrefRowChangePathEnter => {
|
Message::XrefRowChangePathEnter => {
|
||||||
self.xref_manager.row_change_path_open = true;
|
self.xref_manager.row_change_path_open = true;
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|||||||
+216
-25
@@ -1478,38 +1478,197 @@ fn menu_item(label: String, msg: Option<Message>, gate: Option<String>) -> Eleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper that publishes a right-click message before delegating to child
|
||||||
|
/// (which may capture right-clicks, e.g. `ContextMenu`).
|
||||||
|
struct RightClickArea<'a> {
|
||||||
|
child: Element<'a, Message>,
|
||||||
|
on_right_press: Message,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RightClickArea<'a> {
|
||||||
|
pub fn new(child: impl Into<Element<'a, Message>>, on_right_press: Message) -> Self {
|
||||||
|
Self {
|
||||||
|
child: child.into(),
|
||||||
|
on_right_press,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> iced_core::Widget<Message, Theme, iced::Renderer> for RightClickArea<'a> {
|
||||||
|
fn diff(&mut self, tree: &mut iced_core::widget::Tree) {
|
||||||
|
tree.diff_children(std::slice::from_mut(&mut self.child));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> iced::Size<Length> {
|
||||||
|
self.child.as_widget().size()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&mut self,
|
||||||
|
tree: &mut iced_core::widget::Tree,
|
||||||
|
renderer: &iced::Renderer,
|
||||||
|
limits: &iced_core::layout::Limits,
|
||||||
|
) -> iced_core::layout::Node {
|
||||||
|
self.child
|
||||||
|
.as_widget_mut()
|
||||||
|
.layout(&mut tree.children[0], renderer, limits)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
tree: &mut iced_core::widget::Tree,
|
||||||
|
event: &iced_core::Event,
|
||||||
|
layout: iced_core::Layout<'_>,
|
||||||
|
cursor: iced_core::mouse::Cursor,
|
||||||
|
renderer: &iced::Renderer,
|
||||||
|
shell: &mut iced_core::Shell<'_, Message>,
|
||||||
|
viewport: &iced::Rectangle,
|
||||||
|
) {
|
||||||
|
if let iced_core::Event::Mouse(iced_core::mouse::Event::ButtonPressed(
|
||||||
|
iced_core::mouse::Button::Right,
|
||||||
|
)) = event
|
||||||
|
{
|
||||||
|
if cursor.is_over(layout.bounds()) {
|
||||||
|
shell.publish(self.on_right_press.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.child.as_widget_mut().update(
|
||||||
|
&mut tree.children[0],
|
||||||
|
event,
|
||||||
|
layout,
|
||||||
|
cursor,
|
||||||
|
renderer,
|
||||||
|
shell,
|
||||||
|
viewport,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
tree: &iced_core::widget::Tree,
|
||||||
|
layout: iced_core::Layout<'_>,
|
||||||
|
cursor: iced_core::mouse::Cursor,
|
||||||
|
viewport: &iced::Rectangle,
|
||||||
|
renderer: &iced::Renderer,
|
||||||
|
) -> iced_core::mouse::Interaction {
|
||||||
|
self.child
|
||||||
|
.as_widget()
|
||||||
|
.mouse_interaction(&tree.children[0], layout, cursor, viewport, renderer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn operate(
|
||||||
|
&mut self,
|
||||||
|
tree: &mut iced_core::widget::Tree,
|
||||||
|
layout: iced_core::Layout<'_>,
|
||||||
|
renderer: &iced::Renderer,
|
||||||
|
operation: &mut dyn iced_core::widget::Operation,
|
||||||
|
) {
|
||||||
|
self.child
|
||||||
|
.as_widget_mut()
|
||||||
|
.operate(&mut tree.children[0], layout, renderer, operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
tree: &iced_core::widget::Tree,
|
||||||
|
renderer: &mut iced::Renderer,
|
||||||
|
theme: &Theme,
|
||||||
|
style: &iced_core::renderer::Style,
|
||||||
|
layout: iced_core::Layout<'_>,
|
||||||
|
cursor: iced_core::mouse::Cursor,
|
||||||
|
viewport: &iced::Rectangle,
|
||||||
|
) {
|
||||||
|
self.child.as_widget().draw(
|
||||||
|
&tree.children[0],
|
||||||
|
renderer,
|
||||||
|
theme,
|
||||||
|
style,
|
||||||
|
layout,
|
||||||
|
cursor,
|
||||||
|
viewport,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlay<'b>(
|
||||||
|
&'b mut self,
|
||||||
|
tree: &'b mut iced_core::widget::Tree,
|
||||||
|
layout: iced_core::Layout<'b>,
|
||||||
|
renderer: &iced::Renderer,
|
||||||
|
viewport: &iced::Rectangle,
|
||||||
|
translation: iced::Vector,
|
||||||
|
) -> Option<iced_core::overlay::Element<'b, Message, Theme, iced::Renderer>> {
|
||||||
|
self.child.as_widget_mut().overlay(
|
||||||
|
&mut tree.children[0],
|
||||||
|
layout,
|
||||||
|
renderer,
|
||||||
|
viewport,
|
||||||
|
translation,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<RightClickArea<'a>> for Element<'a, Message> {
|
||||||
|
fn from(widget: RightClickArea<'a>) -> Self {
|
||||||
|
Element::new(widget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const MENU_ROW_H: f32 = 24.0;
|
||||||
|
const MENU_SEP_H: f32 = 5.0;
|
||||||
|
const MENU_PADDING: f32 = 4.0;
|
||||||
|
const MENU_SPACING: f32 = 1.0;
|
||||||
|
|
||||||
/// One right-click menu row, styled like the model-space context menu:
|
/// One right-click menu row, styled like the model-space context menu:
|
||||||
/// borderless subtle text rows, not toolbar buttons.
|
/// borderless subtle text rows. Hovering a regular row dismisses any open flyout.
|
||||||
fn menu_row(label: String, msg: Message) -> Element<'static, Message> {
|
fn menu_row(label: String, msg: Message) -> Element<'static, Message> {
|
||||||
|
mouse_area(
|
||||||
|
button(text(label).size(12))
|
||||||
|
.on_press(msg)
|
||||||
|
.style(button::subtle)
|
||||||
|
.padding([4, 12])
|
||||||
|
.height(Length::Fixed(MENU_ROW_H))
|
||||||
|
.width(Fill),
|
||||||
|
)
|
||||||
|
.on_enter(Message::XrefRowChangePathLeave)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// One flyout submenu row: does not close the flyout on hover.
|
||||||
|
fn submenu_row(label: String, msg: Message) -> Element<'static, Message> {
|
||||||
button(text(label).size(12))
|
button(text(label).size(12))
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.style(button::subtle)
|
.style(button::subtle)
|
||||||
.padding([4, 12])
|
.padding([4, 12])
|
||||||
|
.height(Length::Fixed(MENU_ROW_H))
|
||||||
.width(Fill)
|
.width(Fill)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn menu_separator() -> Element<'static, Message> {
|
fn menu_separator() -> Element<'static, Message> {
|
||||||
container(iced::widget::Space::new().height(Length::Fixed(1.0)))
|
container(
|
||||||
.style(|theme: &Theme| container::Style {
|
container(iced::widget::Space::new().height(Length::Fixed(1.0)))
|
||||||
background: Some(Background::Color(theme.palette().background.neutral.color)),
|
.style(|theme: &Theme| container::Style {
|
||||||
..Default::default()
|
background: Some(Background::Color(theme.palette().background.neutral.color)),
|
||||||
})
|
..Default::default()
|
||||||
.padding([0, 8])
|
})
|
||||||
.width(Fill)
|
.width(Fill),
|
||||||
.into()
|
)
|
||||||
|
.padding([2, 8])
|
||||||
|
.height(Length::Fixed(MENU_SEP_H))
|
||||||
|
.width(Fill)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Per-row right-click menu. Eight items exactly: universal tools +
|
/// Per-row right-click menu. Eight items exactly: universal tools +
|
||||||
/// path tools. No Bind, no Attach/Overlay — those are DWG-only and
|
/// path tools. No Bind, no Attach/Overlay — those are DWG-only and
|
||||||
/// hidden entirely. Change Path Type shows a right triangle and a
|
/// hidden entirely. Change Path Type shows a right triangle and a
|
||||||
/// second list in front with the 3 sub-options on hover.
|
/// second list adjacent to "Change Path Type" on hover.
|
||||||
fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Message> {
|
fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Message> {
|
||||||
let item = |label: &str, op: XrefPaletteOp| -> Element<'static, Message> {
|
let item = |label: &str, op: XrefPaletteOp| -> Element<'static, Message> {
|
||||||
menu_row(label.to_string(), Message::XrefRowOp(index, op))
|
menu_row(label.to_string(), Message::XrefRowOp(index, op))
|
||||||
};
|
};
|
||||||
let pathtype_item = |label: &str, pt: Pathtype| -> Element<'static, Message> {
|
let pathtype_item = |label: &str, pt: Pathtype| -> Element<'static, Message> {
|
||||||
menu_row(
|
submenu_row(
|
||||||
label.to_string(),
|
label.to_string(),
|
||||||
Message::XrefRowOp(index, XrefPaletteOp::Pathtype(pt)),
|
Message::XrefRowOp(index, XrefPaletteOp::Pathtype(pt)),
|
||||||
)
|
)
|
||||||
@@ -1523,12 +1682,29 @@ fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Messag
|
|||||||
.align_y(iced::Center)
|
.align_y(iced::Center)
|
||||||
.spacing(8),
|
.spacing(8),
|
||||||
)
|
)
|
||||||
|
.style(move |theme: &Theme| {
|
||||||
|
let palette = theme.palette();
|
||||||
|
let bg = if change_path_open {
|
||||||
|
Some(Background::Color(palette.background.weak.color))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
container::Style {
|
||||||
|
background: bg,
|
||||||
|
border: Border {
|
||||||
|
radius: 2.0.into(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
})
|
||||||
.padding([4, 12])
|
.padding([4, 12])
|
||||||
|
.height(Length::Fixed(MENU_ROW_H))
|
||||||
.width(Fill),
|
.width(Fill),
|
||||||
)
|
)
|
||||||
.on_enter(Message::XrefRowChangePathEnter)
|
.on_enter(Message::XrefRowChangePathEnter)
|
||||||
.on_exit(Message::XrefRowChangePathLeave)
|
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let main: Element<'static, Message> = container(
|
let main: Element<'static, Message> = container(
|
||||||
column![
|
column![
|
||||||
item(&crate::t!("Open").into_owned(), XrefPaletteOp::Open),
|
item(&crate::t!("Open").into_owned(), XrefPaletteOp::Open),
|
||||||
@@ -1541,15 +1717,15 @@ fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Messag
|
|||||||
menu_separator(),
|
menu_separator(),
|
||||||
menu_row(
|
menu_row(
|
||||||
crate::t!("Select New Path").into_owned(),
|
crate::t!("Select New Path").into_owned(),
|
||||||
Message::XrefPathPick
|
Message::XrefRowPathPick(index),
|
||||||
),
|
),
|
||||||
menu_row(
|
menu_row(
|
||||||
crate::t!("Find and Replace...").into_owned(),
|
crate::t!("Find and Replace...").into_owned(),
|
||||||
Message::XrefFindReplacePrompt
|
Message::XrefRowFindReplacePrompt(index),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
.spacing(1)
|
.spacing(MENU_SPACING)
|
||||||
.padding(4),
|
.padding(MENU_PADDING),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
@@ -1564,9 +1740,15 @@ fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Messag
|
|||||||
})
|
})
|
||||||
.width(Length::Fixed(220.0))
|
.width(Length::Fixed(220.0))
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
if !change_path_open {
|
if !change_path_open {
|
||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Top offset so the flyout top border aligns directly with the "Change Path Type" row.
|
||||||
|
// 5 items * 24.0 + 5 * 1.0 (spacing) + 5.0 (separator) + 1.0 (spacing) + 4.0 (container padding) = 135.0
|
||||||
|
let flyout_offset = MENU_PADDING + 5.0 * MENU_ROW_H + 5.0 * MENU_SPACING + MENU_SEP_H + MENU_SPACING;
|
||||||
|
|
||||||
let flyout: Element<'static, Message> = mouse_area(
|
let flyout: Element<'static, Message> = mouse_area(
|
||||||
container(
|
container(
|
||||||
column![
|
column![
|
||||||
@@ -1580,8 +1762,8 @@ fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Messag
|
|||||||
),
|
),
|
||||||
pathtype_item(&crate::t!("Remove Path").into_owned(), Pathtype::None),
|
pathtype_item(&crate::t!("Remove Path").into_owned(), Pathtype::None),
|
||||||
]
|
]
|
||||||
.spacing(1)
|
.spacing(MENU_SPACING)
|
||||||
.padding(4),
|
.padding(MENU_PADDING),
|
||||||
)
|
)
|
||||||
.style(|theme: &Theme| container::Style {
|
.style(|theme: &Theme| container::Style {
|
||||||
background: Some(Background::Color(
|
background: Some(Background::Color(
|
||||||
@@ -1599,7 +1781,16 @@ fn row_menu_for(index: usize, change_path_open: bool) -> Element<'static, Messag
|
|||||||
.on_enter(Message::XrefRowChangePathEnter)
|
.on_enter(Message::XrefRowChangePathEnter)
|
||||||
.on_exit(Message::XrefRowChangePathLeave)
|
.on_exit(Message::XrefRowChangePathLeave)
|
||||||
.into();
|
.into();
|
||||||
row![main, flyout].spacing(4).align_y(iced::alignment::Vertical::Top).into()
|
|
||||||
|
let flyout_column = column![
|
||||||
|
iced::widget::Space::new().height(Length::Fixed(flyout_offset)),
|
||||||
|
flyout,
|
||||||
|
];
|
||||||
|
|
||||||
|
row![main, flyout_column]
|
||||||
|
.spacing(0)
|
||||||
|
.align_y(iced::alignment::Vertical::Top)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn xref_row<'a>(
|
fn xref_row<'a>(
|
||||||
@@ -1692,9 +1883,9 @@ fn xref_row<'a>(
|
|||||||
.height(Length::Fixed(ROW_H))
|
.height(Length::Fixed(ROW_H))
|
||||||
.width(Fill),
|
.width(Fill),
|
||||||
)
|
)
|
||||||
.on_press(Message::XrefManagerSelect(index))
|
.on_press(Message::XrefManagerSelect(index));
|
||||||
.on_right_press(Message::XrefRowRightClick(index));
|
let cm = iced_aw::ContextMenu::new(row, move || row_menu_for(index, change_path_open));
|
||||||
iced_aw::ContextMenu::new(row, move || row_menu_for(index, change_path_open)).into()
|
RightClickArea::new(cm, Message::XrefRowRightClick(index)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One tree-mode row: indent + optional expand arrow + file icon + name.
|
/// One tree-mode row: indent + optional expand arrow + file icon + name.
|
||||||
@@ -1753,9 +1944,9 @@ fn tree_row(
|
|||||||
})
|
})
|
||||||
.width(Fill),
|
.width(Fill),
|
||||||
)
|
)
|
||||||
.on_press(Message::XrefManagerSelect(index))
|
.on_press(Message::XrefManagerSelect(index));
|
||||||
.on_right_press(Message::XrefRowRightClick(index));
|
let cm = iced_aw::ContextMenu::new(row, move || row_menu_for(index, change_path_open));
|
||||||
iced_aw::ContextMenu::new(row, move || row_menu_for(index, change_path_open)).into()
|
RightClickArea::new(cm, Message::XrefRowRightClick(index)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tree-mode host root: home icon + name with the current-drawing marker.
|
/// Tree-mode host root: home icon + name with the current-drawing marker.
|
||||||
|
|||||||
Reference in new issue
Block a user