Skip to content

Commit

Permalink
Add .id method and text_editor::focus task
Browse files Browse the repository at this point in the history
  • Loading branch information
sgued committed Oct 29, 2024
1 parent 50340b4 commit 496cb88
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
8 changes: 6 additions & 2 deletions examples/editor/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use iced::highlighter;
use iced::keyboard;
use iced::widget::{
self, button, column, container, horizontal_space, pick_list, row, text,
button, column, container, horizontal_space, pick_list, row, text,
text_editor, toggler, tooltip,
};
use iced::{Center, Element, Fill, Font, Task, Theme};
Expand All @@ -20,6 +20,7 @@ pub fn main() -> iced::Result {
}

struct Editor {
editor_id: text_editor::Id,
file: Option<PathBuf>,
content: text_editor::Content,
theme: highlighter::Theme,
Expand All @@ -42,8 +43,10 @@ enum Message {

impl Editor {
fn new() -> (Self, Task<Message>) {
let id = text_editor::Id::unique();
(
Self {
editor_id: id.clone(),
file: None,
content: text_editor::Content::new(),
theme: highlighter::Theme::SolarizedDark,
Expand All @@ -59,7 +62,7 @@ impl Editor {
)),
Message::FileOpened,
),
widget::focus_next(),
text_editor::focus(id),
]),
)
}
Expand Down Expand Up @@ -188,6 +191,7 @@ impl Editor {
column![
controls,
text_editor(&self.content)
.id(self.editor_id.clone())
.height(Fill)
.on_action(Message::ActionPerformed)
.wrapping(if self.word_wrap {
Expand Down
57 changes: 56 additions & 1 deletion widget/src/text_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ use crate::core::{
Rectangle, Shell, Size, SmolStr, Theme, Vector,
};

use crate::runtime::task::{self, Task};
use crate::runtime::Action as RuntimeAction;

use std::cell::RefCell;
use std::fmt;
use std::ops::DerefMut;
Expand Down Expand Up @@ -103,6 +106,7 @@ pub struct TextEditor<
Theme: Catalog,
Renderer: text::Renderer,
{
id: Option<Id>,
content: &'a Content<Renderer>,
placeholder: Option<text::Fragment<'a>>,
font: Option<Renderer::Font>,
Expand Down Expand Up @@ -131,6 +135,7 @@ where
/// Creates new [`TextEditor`] with the given [`Content`].
pub fn new(content: &'a Content<Renderer>) -> Self {
Self {
id: None,
content,
placeholder: None,
font: None,
Expand All @@ -149,6 +154,12 @@ where
},
}
}

/// Sets the [`Id`] of the [`TextEditor`].
pub fn id(mut self, id: impl Into<Id>) -> Self {
self.id = Some(id.into());
self
}
}

impl<'a, Highlighter, Message, Theme, Renderer>
Expand Down Expand Up @@ -256,6 +267,7 @@ where
) -> highlighter::Format<Renderer::Font>,
) -> TextEditor<'a, H, Message, Theme, Renderer> {
TextEditor {
id: self.id,
content: self.content,
placeholder: self.placeholder,
font: self.font,
Expand Down Expand Up @@ -958,7 +970,7 @@ where
) {
let state = tree.state.downcast_mut::<State<Highlighter>>();

operation.focusable(state, None);
operation.focusable(state, self.id.as_ref().map(|id| &id.0));
}
}

Expand All @@ -978,6 +990,49 @@ where
}
}

/// The identifier of a [`TextEditor`].
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Id(widget::Id);

impl Id {
/// Creates a custom [`Id`].
pub fn new(id: impl Into<std::borrow::Cow<'static, str>>) -> Self {
Self(widget::Id::new(id))
}

/// Creates a unique [`Id`].
///
/// This function produces a different [`Id`] every time it is called.
pub fn unique() -> Self {
Self(widget::Id::unique())
}
}

impl From<Id> for widget::Id {
fn from(id: Id) -> Self {
id.0
}
}

impl From<&'static str> for Id {
fn from(id: &'static str) -> Self {
Self::new(id)
}
}

impl From<String> for Id {
fn from(id: String) -> Self {
Self::new(id)
}
}

/// Produces a [`Task`] that focuses the [`TextEditor`] with the given [`Id`].
pub fn focus<T>(id: impl Into<Id>) -> Task<T> {
task::effect(RuntimeAction::widget(operation::focusable::focus(
id.into().0,
)))
}

/// A binding to an action in the [`TextEditor`].
#[derive(Debug, Clone, PartialEq)]
pub enum Binding<Message> {
Expand Down

0 comments on commit 496cb88

Please sign in to comment.