feat(text): expose has_text and clipboard_has_text for context menus
This commit is contained in:
parent
ffe1f1dbe3
commit
d0f221c48b
2 changed files with 47 additions and 1 deletions
|
|
@ -224,6 +224,7 @@ pub struct State<P: Paragraph> {
|
||||||
focused: bool,
|
focused: bool,
|
||||||
keyboard_focused: bool,
|
keyboard_focused: bool,
|
||||||
context_menu_position: Option<Point>,
|
context_menu_position: Option<Point>,
|
||||||
|
clipboard_has_text: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Paragraph> Default for State<P> {
|
impl<P: Paragraph> Default for State<P> {
|
||||||
|
|
@ -234,6 +235,7 @@ impl<P: Paragraph> Default for State<P> {
|
||||||
focused: false,
|
focused: false,
|
||||||
keyboard_focused: false,
|
keyboard_focused: false,
|
||||||
context_menu_position: None,
|
context_menu_position: None,
|
||||||
|
clipboard_has_text: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -529,6 +531,7 @@ where
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) => {
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) => {
|
||||||
if let Some(pos) = cursor.position_over(bounds) {
|
if let Some(pos) = cursor.position_over(bounds) {
|
||||||
state.context_menu_position = Some(pos);
|
state.context_menu_position = Some(pos);
|
||||||
|
state.clipboard_has_text = clipboard_has_text(clipboard);
|
||||||
state.focused = true;
|
state.focused = true;
|
||||||
state.keyboard_focused = false;
|
state.keyboard_focused = false;
|
||||||
shell.capture_event();
|
shell.capture_event();
|
||||||
|
|
@ -1023,6 +1026,13 @@ pub fn danger(theme: &Theme) -> Style {
|
||||||
|
|
||||||
use crate::widget::tree::Tree as WidgetTree;
|
use crate::widget::tree::Tree as WidgetTree;
|
||||||
|
|
||||||
|
/// Returns `true` if the clipboard currently holds non-empty text.
|
||||||
|
pub fn clipboard_has_text(clipboard: &dyn Clipboard) -> bool {
|
||||||
|
clipboard
|
||||||
|
.read(crate::clipboard::Kind::Standard)
|
||||||
|
.is_some_and(|s| !s.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
/// Implement this on a **widget** to enable context menu support for
|
/// Implement this on a **widget** to enable context menu support for
|
||||||
/// text selection (Copy, Select All, and optionally Cut / Paste) in libcosmic
|
/// text selection (Copy, Select All, and optionally Cut / Paste) in libcosmic
|
||||||
pub trait HasSelectableText {
|
pub trait HasSelectableText {
|
||||||
|
|
@ -1032,11 +1042,23 @@ pub trait HasSelectableText {
|
||||||
/// Selects all text.
|
/// Selects all text.
|
||||||
fn select_all(&self, tree: &mut WidgetTree);
|
fn select_all(&self, tree: &mut WidgetTree);
|
||||||
|
|
||||||
/// Returns `true` if the widget is editable (enables Cut / Paste).
|
/// Returns `true` if the widget is editable (shows Cut / Paste).
|
||||||
fn is_editable(&self) -> bool {
|
fn is_editable(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the widget has any text (enables Select All).
|
||||||
|
fn has_text(&self, _tree: &WidgetTree) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the clipboard held text when the context menu was
|
||||||
|
/// requested (enables Paste). Widgets cache this on right-click because
|
||||||
|
/// overlays have no clipboard access.
|
||||||
|
fn clipboard_has_text(&self, _tree: &WidgetTree) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the widget is currently focused.
|
/// Returns `true` if the widget is currently focused.
|
||||||
fn is_focused(&self, tree: &WidgetTree) -> bool;
|
fn is_focused(&self, tree: &WidgetTree) -> bool;
|
||||||
|
|
||||||
|
|
@ -1106,6 +1128,16 @@ impl<Theme: Catalog, Renderer: text::Renderer> HasSelectableText
|
||||||
sel.end = count;
|
sel.end = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_text(&self, tree: &WidgetTree) -> bool {
|
||||||
|
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();
|
||||||
|
!state.paragraph.content().is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clipboard_has_text(&self, tree: &WidgetTree) -> bool {
|
||||||
|
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();
|
||||||
|
state.clipboard_has_text
|
||||||
|
}
|
||||||
|
|
||||||
fn is_focused(&self, tree: &WidgetTree) -> bool {
|
fn is_focused(&self, tree: &WidgetTree) -> bool {
|
||||||
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();
|
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();
|
||||||
state.is_focused()
|
state.is_focused()
|
||||||
|
|
|
||||||
|
|
@ -545,6 +545,7 @@ pub struct State<Highlighter: text::Highlighter> {
|
||||||
highlighter_settings: Highlighter::Settings,
|
highlighter_settings: Highlighter::Settings,
|
||||||
highlighter_format_address: usize,
|
highlighter_format_address: usize,
|
||||||
context_menu_position: Option<Point>,
|
context_menu_position: Option<Point>,
|
||||||
|
clipboard_has_text: bool,
|
||||||
pending_edit: Option<Action>,
|
pending_edit: Option<Action>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -632,6 +633,7 @@ where
|
||||||
highlighter_settings: self.highlighter_settings.clone(),
|
highlighter_settings: self.highlighter_settings.clone(),
|
||||||
highlighter_format_address: self.highlighter_format as usize,
|
highlighter_format_address: self.highlighter_format as usize,
|
||||||
context_menu_position: None,
|
context_menu_position: None,
|
||||||
|
clipboard_has_text: false,
|
||||||
pending_edit: None,
|
pending_edit: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -736,6 +738,8 @@ where
|
||||||
state.focus = Some(Focus::now());
|
state.focus = Some(Focus::now());
|
||||||
}
|
}
|
||||||
state.context_menu_position = Some(pos);
|
state.context_menu_position = Some(pos);
|
||||||
|
state.clipboard_has_text =
|
||||||
|
widget::text::clipboard_has_text(clipboard);
|
||||||
shell.capture_event();
|
shell.capture_event();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1649,6 +1653,16 @@ where
|
||||||
self.on_edit.is_some()
|
self.on_edit.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_text(&self, _tree: &widget::Tree) -> bool {
|
||||||
|
!self.content.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clipboard_has_text(&self, tree: &widget::Tree) -> bool {
|
||||||
|
tree.state
|
||||||
|
.downcast_ref::<State<Highlighter>>()
|
||||||
|
.clipboard_has_text
|
||||||
|
}
|
||||||
|
|
||||||
fn is_focused(&self, tree: &widget::Tree) -> bool {
|
fn is_focused(&self, tree: &widget::Tree) -> bool {
|
||||||
tree.state.downcast_ref::<State<Highlighter>>().is_focused()
|
tree.state.downcast_ref::<State<Highlighter>>().is_focused()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue