feat(text_context_menu): always show items, but disable them
This commit is contained in:
parent
a401af8b1c
commit
56a210bb4e
5 changed files with 48 additions and 22 deletions
2
iced
2
iced
|
|
@ -1 +1 @@
|
||||||
Subproject commit ffe1f1dbe3cbfd313f9b5fe8e36a4af462cae5d7
|
Subproject commit 2e12eba5cd9ddf9995e113fbc9fa0ebf8f0f0f97
|
||||||
|
|
@ -355,6 +355,8 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Theme, Renderer> for S
|
||||||
selected_text,
|
selected_text,
|
||||||
false,
|
false,
|
||||||
has_selection,
|
has_selection,
|
||||||
|
self.inner.has_text(&tree.children[0]),
|
||||||
|
self.inner.clipboard_has_text(&tree.children[0]),
|
||||||
&menu_bar_state,
|
&menu_bar_state,
|
||||||
&pending_action,
|
&pending_action,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,12 @@ where
|
||||||
let selected_text = widget.selected_text(tree);
|
let selected_text = widget.selected_text(tree);
|
||||||
let is_editable = widget.is_editable();
|
let is_editable = widget.is_editable();
|
||||||
|
|
||||||
let mut menu_roots = build_menu_roots(is_editable, selected_text.is_some());
|
let mut menu_roots = build_menu_roots(
|
||||||
|
is_editable,
|
||||||
|
selected_text.is_some(),
|
||||||
|
widget.has_text(tree),
|
||||||
|
widget.clipboard_has_text(tree),
|
||||||
|
);
|
||||||
menu_roots.iter_mut().for_each(menu::Tree::set_index);
|
menu_roots.iter_mut().for_each(menu::Tree::set_index);
|
||||||
|
|
||||||
let bounds = Rectangle {
|
let bounds = Rectangle {
|
||||||
|
|
@ -283,28 +288,28 @@ pub(crate) enum TextCtxAction {
|
||||||
SelectAll,
|
SelectAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_menu_roots(is_editable: bool, has_selection: bool) -> Vec<menu::Tree<TextCtxAction>> {
|
fn build_menu_roots(
|
||||||
let mut items = Vec::with_capacity(4);
|
is_editable: bool,
|
||||||
|
has_selection: bool,
|
||||||
|
has_text: bool,
|
||||||
|
clipboard_has_text: bool,
|
||||||
|
) -> Vec<menu::Tree<TextCtxAction>> {
|
||||||
|
let item = |label: &'static str, action: TextCtxAction, enabled: bool| {
|
||||||
|
menu::Tree::from(crate::Element::from(
|
||||||
|
menu::menu_button(vec![widget::text(label).into()])
|
||||||
|
.on_press_maybe(enabled.then_some(action)),
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
if is_editable && has_selection {
|
let mut items = Vec::with_capacity(4);
|
||||||
items.push(menu::Tree::from(crate::Element::from(
|
|
||||||
menu::menu_button(vec![widget::text("Cut").into()]).on_press(TextCtxAction::Cut),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
if has_selection {
|
|
||||||
items.push(menu::Tree::from(crate::Element::from(
|
|
||||||
menu::menu_button(vec![widget::text("Copy").into()]).on_press(TextCtxAction::Copy),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
if is_editable {
|
if is_editable {
|
||||||
items.push(menu::Tree::from(crate::Element::from(
|
items.push(item("Cut", TextCtxAction::Cut, has_selection));
|
||||||
menu::menu_button(vec![widget::text("Paste").into()]).on_press(TextCtxAction::Paste),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
items.push(menu::Tree::from(crate::Element::from(
|
items.push(item("Copy", TextCtxAction::Copy, has_selection));
|
||||||
menu::menu_button(vec![widget::text("Select All").into()])
|
if is_editable {
|
||||||
.on_press(TextCtxAction::SelectAll),
|
items.push(item("Paste", TextCtxAction::Paste, clipboard_has_text));
|
||||||
)));
|
}
|
||||||
|
items.push(item("Select All", TextCtxAction::SelectAll, has_text));
|
||||||
|
|
||||||
vec![menu::Tree::with_children(
|
vec![menu::Tree::with_children(
|
||||||
RcElementWrapper::new(crate::Element::from(widget::Row::new())),
|
RcElementWrapper::new(crate::Element::from(widget::Row::new())),
|
||||||
|
|
@ -486,6 +491,8 @@ pub(crate) fn create_text_context_popup(
|
||||||
selected_text: Option<String>,
|
selected_text: Option<String>,
|
||||||
is_editable: bool,
|
is_editable: bool,
|
||||||
has_selection: bool,
|
has_selection: bool,
|
||||||
|
has_text: bool,
|
||||||
|
clipboard_has_text: bool,
|
||||||
menu_bar_state: &MenuBarState,
|
menu_bar_state: &MenuBarState,
|
||||||
pending_action: &PendingAction,
|
pending_action: &PendingAction,
|
||||||
renderer: &crate::Renderer,
|
renderer: &crate::Renderer,
|
||||||
|
|
@ -499,7 +506,7 @@ pub(crate) fn create_text_context_popup(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut menu_roots = build_menu_roots(is_editable, has_selection);
|
let mut menu_roots = build_menu_roots(is_editable, has_selection, has_text, clipboard_has_text);
|
||||||
menu_roots.iter_mut().for_each(menu::Tree::set_index);
|
menu_roots.iter_mut().for_each(menu::Tree::set_index);
|
||||||
|
|
||||||
let id = menu_bar_state.inner.with_data_mut(|state| {
|
let id = menu_bar_state.inner.with_data_mut(|state| {
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,8 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Theme, crate::Renderer
|
||||||
selected_text,
|
selected_text,
|
||||||
self.inner.is_editable(),
|
self.inner.is_editable(),
|
||||||
has_selection,
|
has_selection,
|
||||||
|
self.inner.has_text(&tree.children[0]),
|
||||||
|
self.inner.clipboard_has_text(&tree.children[0]),
|
||||||
&menu_bar_state,
|
&menu_bar_state,
|
||||||
&pending_action,
|
&pending_action,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
|
||||||
|
|
@ -1054,6 +1054,8 @@ where
|
||||||
.selection(&state.tracked_value)
|
.selection(&state.tracked_value)
|
||||||
.map(|(start, end)| state.tracked_value.select(start, end).to_string());
|
.map(|(start, end)| state.tracked_value.select(start, end).to_string());
|
||||||
let has_selection = selected_text.is_some();
|
let has_selection = selected_text.is_some();
|
||||||
|
let has_text = !state.tracked_value.is_empty();
|
||||||
|
let clipboard_has_text = state.clipboard_has_text;
|
||||||
let click_position = state.context_menu_position.unwrap();
|
let click_position = state.context_menu_position.unwrap();
|
||||||
let menu_bar_state = state.menu_bar_state.clone();
|
let menu_bar_state = state.menu_bar_state.clone();
|
||||||
let pending_action = state.pending_action.clone();
|
let pending_action = state.pending_action.clone();
|
||||||
|
|
@ -1063,6 +1065,8 @@ where
|
||||||
selected_text,
|
selected_text,
|
||||||
true,
|
true,
|
||||||
has_selection,
|
has_selection,
|
||||||
|
has_text,
|
||||||
|
clipboard_has_text,
|
||||||
&menu_bar_state,
|
&menu_bar_state,
|
||||||
&pending_action,
|
&pending_action,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -1617,6 +1621,7 @@ pub fn update<'a, Message: Clone + 'static>(
|
||||||
state.focus();
|
state.focus();
|
||||||
}
|
}
|
||||||
state.context_menu_position = Some(pos);
|
state.context_menu_position = Some(pos);
|
||||||
|
state.clipboard_has_text = iced_core::widget::text::clipboard_has_text(clipboard);
|
||||||
shell.capture_event();
|
shell.capture_event();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3096,6 +3101,7 @@ pub struct State {
|
||||||
keyboard_modifiers: keyboard::Modifiers,
|
keyboard_modifiers: keyboard::Modifiers,
|
||||||
scroll_offset: f32,
|
scroll_offset: f32,
|
||||||
context_menu_position: Option<iced_core::Point>,
|
context_menu_position: Option<iced_core::Point>,
|
||||||
|
clipboard_has_text: bool,
|
||||||
pub(crate) menu_bar_state: crate::widget::menu::MenuBarState,
|
pub(crate) menu_bar_state: crate::widget::menu::MenuBarState,
|
||||||
pub(crate) pending_action: crate::widget::text_context_menu::PendingAction,
|
pub(crate) pending_action: crate::widget::text_context_menu::PendingAction,
|
||||||
}
|
}
|
||||||
|
|
@ -3191,6 +3197,7 @@ impl State {
|
||||||
scroll_offset: 0.0,
|
scroll_offset: 0.0,
|
||||||
dirty: false,
|
dirty: false,
|
||||||
context_menu_position: None,
|
context_menu_position: None,
|
||||||
|
clipboard_has_text: false,
|
||||||
menu_bar_state: crate::widget::menu::MenuBarState::default(),
|
menu_bar_state: crate::widget::menu::MenuBarState::default(),
|
||||||
pending_action: crate::widget::text_context_menu::pending_action(),
|
pending_action: crate::widget::text_context_menu::pending_action(),
|
||||||
}
|
}
|
||||||
|
|
@ -3554,6 +3561,14 @@ impl<Message: Clone + 'static> iced_core::widget::text::HasSelectableText
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_text(&self, tree: &WidgetTree) -> bool {
|
||||||
|
!tree.state.downcast_ref::<State>().tracked_value.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clipboard_has_text(&self, tree: &WidgetTree) -> bool {
|
||||||
|
tree.state.downcast_ref::<State>().clipboard_has_text
|
||||||
|
}
|
||||||
|
|
||||||
fn is_focused(&self, tree: &WidgetTree) -> bool {
|
fn is_focused(&self, tree: &WidgetTree) -> bool {
|
||||||
tree.state.downcast_ref::<State>().is_focused()
|
tree.state.downcast_ref::<State>().is_focused()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue