Add placeholder support to text_editor widget
This commit is contained in:
parent
a5b1a1df54
commit
e9e06c8fe2
5 changed files with 68 additions and 9 deletions
|
|
@ -118,6 +118,10 @@ impl text::Editor for () {
|
|||
|
||||
fn with_text(_text: &str) -> Self {}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn cursor(&self) -> text::editor::Cursor {
|
||||
text::editor::Cursor::Caret(Point::ORIGIN)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ pub trait Editor: Sized + Default {
|
|||
/// Creates a new [`Editor`] laid out with the given text.
|
||||
fn with_text(text: &str) -> Self;
|
||||
|
||||
/// Returns true if the [`Editor`] has no contents.
|
||||
fn is_empty(&self) -> bool;
|
||||
|
||||
/// Returns the current [`Cursor`] of the [`Editor`].
|
||||
fn cursor(&self) -> Cursor;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ impl Markdown {
|
|||
|
||||
fn view(&self) -> Element<Message> {
|
||||
let editor = text_editor(&self.content)
|
||||
.placeholder("Type your Markdown here...")
|
||||
.on_action(Message::Edit)
|
||||
.height(Fill)
|
||||
.padding(10)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,13 @@ impl editor::Editor for Editor {
|
|||
})))
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
let buffer = self.buffer();
|
||||
|
||||
buffer.lines.is_empty()
|
||||
|| (buffer.lines.len() == 1 && buffer.lines[0].text().is_empty())
|
||||
}
|
||||
|
||||
fn line(&self, index: usize) -> Option<&str> {
|
||||
self.buffer()
|
||||
.lines
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//! Display a multi-line text input for text editing.
|
||||
use crate::core::alignment;
|
||||
use crate::core::clipboard::{self, Clipboard};
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
|
|
@ -8,7 +9,7 @@ use crate::core::mouse;
|
|||
use crate::core::renderer;
|
||||
use crate::core::text::editor::{Cursor, Editor as _};
|
||||
use crate::core::text::highlighter::{self, Highlighter};
|
||||
use crate::core::text::{self, LineHeight};
|
||||
use crate::core::text::{self, LineHeight, Text};
|
||||
use crate::core::widget::operation;
|
||||
use crate::core::widget::{self, Widget};
|
||||
use crate::core::{
|
||||
|
|
@ -37,6 +38,7 @@ pub struct TextEditor<
|
|||
Renderer: text::Renderer,
|
||||
{
|
||||
content: &'a Content<Renderer>,
|
||||
placeholder: Option<text::Fragment<'a>>,
|
||||
font: Option<Renderer::Font>,
|
||||
text_size: Option<Pixels>,
|
||||
line_height: LineHeight,
|
||||
|
|
@ -62,6 +64,7 @@ where
|
|||
pub fn new(content: &'a Content<Renderer>) -> Self {
|
||||
Self {
|
||||
content,
|
||||
placeholder: None,
|
||||
font: None,
|
||||
text_size: None,
|
||||
line_height: LineHeight::default(),
|
||||
|
|
@ -85,6 +88,15 @@ where
|
|||
Theme: Catalog,
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
/// Sets the placeholder of the [`PickList`].
|
||||
pub fn placeholder(
|
||||
mut self,
|
||||
placeholder: impl text::IntoFragment<'a>,
|
||||
) -> Self {
|
||||
self.placeholder = Some(placeholder.into_fragment());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the height of the [`TextEditor`].
|
||||
pub fn height(mut self, height: impl Into<Length>) -> Self {
|
||||
self.height = height.into();
|
||||
|
|
@ -144,6 +156,7 @@ where
|
|||
) -> TextEditor<'a, H, Message, Theme, Renderer> {
|
||||
TextEditor {
|
||||
content: self.content,
|
||||
placeholder: self.placeholder,
|
||||
font: self.font,
|
||||
text_size: self.text_size,
|
||||
line_height: self.line_height,
|
||||
|
|
@ -546,8 +559,10 @@ where
|
|||
let mut internal = self.content.0.borrow_mut();
|
||||
let state = tree.state.downcast_ref::<State<Highlighter>>();
|
||||
|
||||
let font = self.font.unwrap_or_else(|| renderer.default_font());
|
||||
|
||||
internal.editor.highlight(
|
||||
self.font.unwrap_or_else(|| renderer.default_font()),
|
||||
font,
|
||||
state.highlighter.borrow_mut().deref_mut(),
|
||||
|highlight| (self.highlighter_format)(highlight, theme),
|
||||
);
|
||||
|
|
@ -576,13 +591,42 @@ where
|
|||
style.background,
|
||||
);
|
||||
|
||||
let position = bounds.position()
|
||||
+ Vector::new(self.padding.left, self.padding.top);
|
||||
|
||||
if internal.editor.is_empty() {
|
||||
if let Some(placeholder) = self.placeholder.clone() {
|
||||
renderer.fill_text(
|
||||
Text {
|
||||
content: placeholder.into_owned(),
|
||||
bounds: bounds.size()
|
||||
- Size::new(
|
||||
self.padding.right,
|
||||
self.padding.bottom,
|
||||
),
|
||||
|
||||
size: self
|
||||
.text_size
|
||||
.unwrap_or_else(|| renderer.default_size()),
|
||||
line_height: self.line_height,
|
||||
font,
|
||||
horizontal_alignment: alignment::Horizontal::Left,
|
||||
vertical_alignment: alignment::Vertical::Top,
|
||||
shaping: text::Shaping::Advanced,
|
||||
},
|
||||
position,
|
||||
style.placeholder,
|
||||
*viewport,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
renderer.fill_editor(
|
||||
&internal.editor,
|
||||
bounds.position()
|
||||
+ Vector::new(self.padding.left, self.padding.top),
|
||||
position,
|
||||
defaults.text_color,
|
||||
*viewport,
|
||||
);
|
||||
}
|
||||
|
||||
let translation = Vector::new(
|
||||
bounds.x + self.padding.left,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue