Skip to content

Commit

Permalink
chore(text_input): add winit example and do some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
wash2 committed Aug 21, 2023
1 parent 878c2dc commit 8afbb03
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 30 deletions.
4 changes: 4 additions & 0 deletions examples/cosmic/src/window/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ impl State {
.size(20)
.id(INPUT_ID.clone())
.into(),
cosmic::widget::text_input("test", &self.entry_value)
.width(Length::Fill)
.on_input(Message::InputChanged)
.into(),
])
.into()
}
Expand Down
4 changes: 2 additions & 2 deletions src/widget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ pub use warning::*;

pub mod cosmic_container;
pub use cosmic_container::*;
#[cfg(feature = "wayland")]
// #[cfg(feature = "wayland")]
pub mod text_input;
#[cfg(feature = "wayland")]
// #[cfg(feature = "wayland")]
pub use text_input::*;

/// An element to distinguish a boundary between two elements.
Expand Down
34 changes: 14 additions & 20 deletions src/widget/text_input/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,27 @@ impl<'a> Editor<'a> {
}

pub fn backspace(&mut self) {
match self.cursor.selection(self.value) {
Some((start, end)) => {
self.cursor.move_left(self.value);
self.value.remove_many(start, end);
}
None => {
let start = self.cursor.start(self.value);
if let Some((start, end)) = self.cursor.selection(self.value) {
self.cursor.move_left(self.value);
self.value.remove_many(start, end);
} else {
let start = self.cursor.start(self.value);

if start > 0 {
self.cursor.move_left(self.value);
self.value.remove(start - 1);
}
if start > 0 {
self.cursor.move_left(self.value);
self.value.remove(start - 1);
}
}
}

pub fn delete(&mut self) {
match self.cursor.selection(self.value) {
Some(_) => {
self.backspace();
}
None => {
let end = self.cursor.end(self.value);
if self.cursor.selection(self.value).is_some() {
self.backspace();
} else {
let end = self.cursor.end(self.value);

if end < self.value.len() {
self.value.remove(end);
}
if end < self.value.len() {
self.value.remove(end);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Display fields that can be filled with text.
//!
//! A [`TextInput`] has some local [`State`].
use crate::app;
use crate::theme::THEME;

use super::cursor;
Expand All @@ -28,12 +27,16 @@ use iced_core::{
Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Shell, Size,
Vector, Widget,
};
#[cfg(feature = "wayland")]
use iced_renderer::core::event::{wayland, PlatformSpecific};
use iced_renderer::core::widget::OperationOutputWrapper;
#[cfg(feature = "wayland")]
use iced_runtime::command::platform_specific;
use iced_runtime::Command;

use iced_runtime::command::platform_specific;
#[cfg(feature = "wayland")]
use iced_runtime::command::platform_specific::wayland::data_device::{DataFromMimeType, DndIcon};
#[cfg(feature = "wayland")]
use sctk::reexports::client::protocol::wl_data_device_manager::DndAction;

/// Creates a new [`TextInput`].
Expand Down Expand Up @@ -140,6 +143,7 @@ where
.padding([spacing, spacing, spacing, spacing])
}

#[cfg(feature = "wayland")]
const SUPPORTED_MIME_TYPES: &[&str; 6] = &[
"text/plain;charset=utf-8",
"text/plain;charset=UTF-8",
Expand All @@ -148,8 +152,11 @@ const SUPPORTED_MIME_TYPES: &[&str; 6] = &[
"text/plain",
"TEXT",
];
#[cfg(feature = "wayland")]
pub type DnDCommand =
Box<dyn Send + Sync + Fn() -> platform_specific::wayland::data_device::ActionInner>;
#[cfg(not(feature = "wayland"))]
pub type DnDCommand = ();

/// A field that can be filled with text.
///
Expand Down Expand Up @@ -356,6 +363,7 @@ where
/// [`Value`] if provided.
///
/// [`Renderer`]: text::Renderer
#[allow(clippy::too_many_arguments)]
pub fn draw(
&self,
tree: &Tree,
Expand Down Expand Up @@ -394,13 +402,15 @@ where
}

/// Sets the start dnd handler of the [`TextInput`].
#[cfg(feature = "wayland")]
pub fn on_start_dnd(mut self, on_start_dnd: impl Fn(State) -> Message + 'a) -> Self {
self.on_create_dnd_source = Some(Box::new(on_start_dnd));
self
}

/// Sets the dnd command produced handler of the [`TextInput`].
/// Commands should be returned in the update function of the application.
#[cfg(feature = "wayland")]
pub fn on_dnd_command_produced(
mut self,
on_dnd_command_produced: impl Fn(
Expand Down Expand Up @@ -958,13 +968,15 @@ where
click.kind(),
state.cursor().state(value),
) {
#[cfg(feature = "wayland")]
(None, click::Kind::Single, cursor::State::Selection { start, end }) => {
// if something is already selected, we can start a drag and drop for a
// single click that is on top of the selected text
// is the click on selected text?
if is_secure {
return event::Status::Ignored;
}

if let (
Some(on_start_dnd),
Some(on_dnd_command_produced),
Expand Down Expand Up @@ -1384,6 +1396,7 @@ where
));
}
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DataSource(
wayland::DataSourceEvent::DndFinished | wayland::DataSourceEvent::Cancelled,
))) => {
Expand All @@ -1393,6 +1406,7 @@ where
return event::Status::Captured;
}
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DataSource(
wayland::DataSourceEvent::Cancelled
| wayland::DataSourceEvent::DndFinished
Expand All @@ -1404,6 +1418,7 @@ where
return event::Status::Captured;
}
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DataSource(
wayland::DataSourceEvent::DndActionAccepted(action),
))) => {
Expand All @@ -1413,7 +1428,7 @@ where
return event::Status::Captured;
}
}
// TODO: handle dnd offer events
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DndOffer(
wayland::DndOfferEvent::Enter { x, y, mime_types },
))) => {
Expand Down Expand Up @@ -1480,6 +1495,7 @@ where
return event::Status::Captured;
}
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DndOffer(
wayland::DndOfferEvent::Motion { x, y },
))) => {
Expand Down Expand Up @@ -1558,6 +1574,7 @@ where
state.cursor.move_to(position.unwrap_or(0));
return event::Status::Captured;
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DndOffer(
wayland::DndOfferEvent::DropPerformed,
))) => {
Expand Down Expand Up @@ -1586,6 +1603,7 @@ where
}
return event::Status::Ignored;
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DndOffer(
wayland::DndOfferEvent::Leave,
))) => {
Expand All @@ -1600,6 +1618,7 @@ where
};
return event::Status::Captured;
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DndOffer(
wayland::DndOfferEvent::DndData { mime_type, data },
))) => {
Expand Down Expand Up @@ -1636,6 +1655,7 @@ where
}
return event::Status::Ignored;
}
#[cfg(feature = "wayland")]
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::DndOffer(
wayland::DndOfferEvent::SourceActions(actions),
))) => {
Expand Down Expand Up @@ -2016,6 +2036,7 @@ pub fn mouse_interaction(
#[derive(Debug, Clone)]
pub struct TextInputString(String);

#[cfg(feature = "wayland")]
impl DataFromMimeType for TextInputString {
fn from_mime_type(&self, mime_type: &str) -> Option<Vec<u8>> {
if SUPPORTED_MIME_TYPES.contains(&mime_type) {
Expand All @@ -2029,9 +2050,11 @@ impl DataFromMimeType for TextInputString {
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum DraggingState {
Selection,
#[cfg(feature = "wayland")]
Dnd(DndAction, String),
}

#[cfg(feature = "wayland")]
#[derive(Debug, Default, Clone)]
pub(crate) enum DndOfferState {
#[default]
Expand All @@ -2040,6 +2063,9 @@ pub(crate) enum DndOfferState {
HandlingOffer(Vec<String>, DndAction),
Dropped,
}
#[derive(Debug, Default, Clone)]
#[cfg(not(feature = "wayland"))]
pub(crate) struct DndOfferState;

/// The state of a [`TextInput`].
#[derive(Debug, Default, Clone)]
Expand Down Expand Up @@ -2081,6 +2107,7 @@ impl State {
}
}

#[cfg(feature = "wayland")]
/// Returns the current value of the dragged text in the [`TextInput`].
#[must_use]
pub fn dragged_text(&self) -> Option<String> {
Expand All @@ -2095,7 +2122,7 @@ impl State {
Self {
is_focused: None,
dragging_state: None,
dnd_offer: DndOfferState::None,
dnd_offer: DndOfferState::default(),
is_pasting: None,
last_click: None,
cursor: Cursor::default(),
Expand Down
9 changes: 5 additions & 4 deletions src/widget/text_input/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//! A text input widget from iced_widgets plus some added details.
//! A text input widget from iced widgets plus some added details.

pub mod cursor;
pub mod editor;
pub mod style;
mod text_input;
mod input;
mod style;
pub mod value;

pub use text_input::*;
pub use input::*;
pub use style::{Appearance as TextInputAppearance, StyleSheet as TextInputStyleSheet};

0 comments on commit 8afbb03

Please sign in to comment.