Merge pull request #1131 from iced-rs/component-trait
`iced_lazy` and `Component` trait
This commit is contained in:
commit
26d053ab38
31 changed files with 605 additions and 121 deletions
|
|
@ -57,6 +57,7 @@ members = [
|
||||||
"graphics",
|
"graphics",
|
||||||
"glow",
|
"glow",
|
||||||
"glutin",
|
"glutin",
|
||||||
|
"lazy",
|
||||||
"native",
|
"native",
|
||||||
"style",
|
"style",
|
||||||
"web",
|
"web",
|
||||||
|
|
@ -65,6 +66,7 @@ members = [
|
||||||
"examples/bezier_tool",
|
"examples/bezier_tool",
|
||||||
"examples/clock",
|
"examples/clock",
|
||||||
"examples/color_palette",
|
"examples/color_palette",
|
||||||
|
"examples/component",
|
||||||
"examples/counter",
|
"examples/counter",
|
||||||
"examples/custom_widget",
|
"examples/custom_widget",
|
||||||
"examples/download_progress",
|
"examples/download_progress",
|
||||||
|
|
|
||||||
11
examples/component/Cargo.toml
Normal file
11
examples/component/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "component"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
iced = { path = "../..", features = ["debug"] }
|
||||||
|
iced_native = { path = "../../native" }
|
||||||
|
iced_lazy = { path = "../../lazy" }
|
||||||
180
examples/component/src/main.rs
Normal file
180
examples/component/src/main.rs
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
use iced::{Container, Element, Length, Sandbox, Settings};
|
||||||
|
use numeric_input::NumericInput;
|
||||||
|
|
||||||
|
pub fn main() -> iced::Result {
|
||||||
|
Component::run(Settings::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Component {
|
||||||
|
numeric_input: numeric_input::State,
|
||||||
|
value: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Message {
|
||||||
|
NumericInputChanged(Option<u32>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sandbox for Component {
|
||||||
|
type Message = Message;
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn title(&self) -> String {
|
||||||
|
String::from("Component - Iced")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Message) {
|
||||||
|
match message {
|
||||||
|
Message::NumericInputChanged(value) => {
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view(&mut self) -> Element<Message> {
|
||||||
|
Container::new(NumericInput::new(
|
||||||
|
&mut self.numeric_input,
|
||||||
|
self.value,
|
||||||
|
Message::NumericInputChanged,
|
||||||
|
))
|
||||||
|
.padding(20)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.center_y()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod numeric_input {
|
||||||
|
use iced_lazy::component::{self, Component};
|
||||||
|
use iced_native::alignment::{self, Alignment};
|
||||||
|
use iced_native::text;
|
||||||
|
use iced_native::widget::button::{self, Button};
|
||||||
|
use iced_native::widget::text_input::{self, TextInput};
|
||||||
|
use iced_native::widget::{Row, Text};
|
||||||
|
use iced_native::{Element, Length};
|
||||||
|
|
||||||
|
pub struct NumericInput<'a, Message> {
|
||||||
|
state: &'a mut State,
|
||||||
|
value: Option<u32>,
|
||||||
|
on_change: Box<dyn Fn(Option<u32>) -> Message>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct State {
|
||||||
|
input: text_input::State,
|
||||||
|
decrement_button: button::State,
|
||||||
|
increment_button: button::State,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Event {
|
||||||
|
InputChanged(String),
|
||||||
|
IncrementPressed,
|
||||||
|
DecrementPressed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message> NumericInput<'a, Message> {
|
||||||
|
pub fn new(
|
||||||
|
state: &'a mut State,
|
||||||
|
value: Option<u32>,
|
||||||
|
on_change: impl Fn(Option<u32>) -> Message + 'static,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
state,
|
||||||
|
value,
|
||||||
|
on_change: Box::new(on_change),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Renderer> Component<Message, Renderer>
|
||||||
|
for NumericInput<'a, Message>
|
||||||
|
where
|
||||||
|
Renderer: 'a + text::Renderer,
|
||||||
|
{
|
||||||
|
type Event = Event;
|
||||||
|
|
||||||
|
fn update(&mut self, event: Event) -> Option<Message> {
|
||||||
|
match event {
|
||||||
|
Event::IncrementPressed => Some((self.on_change)(Some(
|
||||||
|
self.value.unwrap_or_default().saturating_add(1),
|
||||||
|
))),
|
||||||
|
Event::DecrementPressed => Some((self.on_change)(Some(
|
||||||
|
self.value.unwrap_or_default().saturating_sub(1),
|
||||||
|
))),
|
||||||
|
Event::InputChanged(value) => {
|
||||||
|
if value.is_empty() {
|
||||||
|
Some((self.on_change)(None))
|
||||||
|
} else {
|
||||||
|
value
|
||||||
|
.parse()
|
||||||
|
.ok()
|
||||||
|
.map(Some)
|
||||||
|
.map(self.on_change.as_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view(&mut self) -> Element<Event, Renderer> {
|
||||||
|
let button = |state, label, on_press| {
|
||||||
|
Button::new(
|
||||||
|
state,
|
||||||
|
Text::new(label)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.horizontal_alignment(alignment::Horizontal::Center)
|
||||||
|
.vertical_alignment(alignment::Vertical::Center),
|
||||||
|
)
|
||||||
|
.width(Length::Units(50))
|
||||||
|
.on_press(on_press)
|
||||||
|
};
|
||||||
|
|
||||||
|
Row::with_children(vec![
|
||||||
|
button(
|
||||||
|
&mut self.state.decrement_button,
|
||||||
|
"-",
|
||||||
|
Event::DecrementPressed,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
TextInput::new(
|
||||||
|
&mut self.state.input,
|
||||||
|
"Type a number",
|
||||||
|
self.value
|
||||||
|
.as_ref()
|
||||||
|
.map(u32::to_string)
|
||||||
|
.as_ref()
|
||||||
|
.map(String::as_str)
|
||||||
|
.unwrap_or(""),
|
||||||
|
Event::InputChanged,
|
||||||
|
)
|
||||||
|
.padding(10)
|
||||||
|
.into(),
|
||||||
|
button(
|
||||||
|
&mut self.state.increment_button,
|
||||||
|
"+",
|
||||||
|
Event::IncrementPressed,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
|
.align_items(Alignment::Fill)
|
||||||
|
.spacing(10)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Renderer> From<NumericInput<'a, Message>>
|
||||||
|
for Element<'a, Message, Renderer>
|
||||||
|
where
|
||||||
|
Message: 'a,
|
||||||
|
Renderer: text::Renderer + 'a,
|
||||||
|
{
|
||||||
|
fn from(numeric_input: NumericInput<'a, Message>) -> Self {
|
||||||
|
component::view(numeric_input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,8 +9,8 @@ use crate::{Backend, Primitive};
|
||||||
use iced_native::layout;
|
use iced_native::layout;
|
||||||
use iced_native::mouse;
|
use iced_native::mouse;
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector,
|
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Shell, Size,
|
||||||
Widget,
|
Vector, Widget,
|
||||||
};
|
};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
@ -158,7 +158,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
_renderer: &Renderer<B>,
|
_renderer: &Renderer<B>,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ where
|
||||||
self.program.update(canvas_event, bounds, cursor);
|
self.program.update(canvas_event, bounds, cursor);
|
||||||
|
|
||||||
if let Some(message) = message {
|
if let Some(message) = message {
|
||||||
messages.push(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return event_status;
|
return event_status;
|
||||||
|
|
|
||||||
11
lazy/Cargo.toml
Normal file
11
lazy/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "iced_lazy"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ouroboros = "0.13"
|
||||||
|
|
||||||
|
[dependencies.iced_native]
|
||||||
|
version = "0.4"
|
||||||
|
path = "../native"
|
||||||
186
lazy/src/component.rs
Normal file
186
lazy/src/component.rs
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
use iced_native::event;
|
||||||
|
use iced_native::layout::{self, Layout};
|
||||||
|
use iced_native::mouse;
|
||||||
|
use iced_native::overlay;
|
||||||
|
use iced_native::renderer;
|
||||||
|
use iced_native::{
|
||||||
|
Clipboard, Element, Hasher, Length, Point, Rectangle, Shell, Widget,
|
||||||
|
};
|
||||||
|
|
||||||
|
use ouroboros::self_referencing;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
pub fn view<'a, C, Message, Renderer>(
|
||||||
|
component: C,
|
||||||
|
) -> Element<'a, Message, Renderer>
|
||||||
|
where
|
||||||
|
C: Component<Message, Renderer> + 'a,
|
||||||
|
Message: 'a,
|
||||||
|
Renderer: iced_native::Renderer + 'a,
|
||||||
|
{
|
||||||
|
Element::new(Instance {
|
||||||
|
state: Some(
|
||||||
|
StateBuilder {
|
||||||
|
component: Box::new(component),
|
||||||
|
cache_builder: |state| Cache {
|
||||||
|
element: state.view(),
|
||||||
|
message: PhantomData,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Component<Message, Renderer> {
|
||||||
|
type Event;
|
||||||
|
|
||||||
|
fn update(&mut self, event: Self::Event) -> Option<Message>;
|
||||||
|
|
||||||
|
fn view(&mut self) -> Element<Self::Event, Renderer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Instance<'a, Message, Renderer, Event> {
|
||||||
|
state: Option<State<'a, Message, Renderer, Event>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[self_referencing]
|
||||||
|
struct State<'a, Message: 'a, Renderer: 'a, Event: 'a> {
|
||||||
|
component: Box<dyn Component<Message, Renderer, Event = Event> + 'a>,
|
||||||
|
|
||||||
|
#[borrows(mut component)]
|
||||||
|
#[covariant]
|
||||||
|
cache: Cache<'this, Message, Renderer, Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Cache<'a, Message, Renderer, Event> {
|
||||||
|
element: Element<'a, Event, Renderer>,
|
||||||
|
message: PhantomData<Message>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Renderer, Event> Widget<Message, Renderer>
|
||||||
|
for Instance<'a, Message, Renderer, Event>
|
||||||
|
where
|
||||||
|
Renderer: iced_native::Renderer,
|
||||||
|
{
|
||||||
|
fn width(&self) -> Length {
|
||||||
|
self.state.as_ref().unwrap().borrow_cache().element.width()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn height(&self) -> Length {
|
||||||
|
self.state.as_ref().unwrap().borrow_cache().element.width()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&self,
|
||||||
|
renderer: &Renderer,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> layout::Node {
|
||||||
|
self.state
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_cache()
|
||||||
|
.element
|
||||||
|
.layout(renderer, limits)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(
|
||||||
|
&mut self,
|
||||||
|
event: iced_native::Event,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor_position: Point,
|
||||||
|
renderer: &Renderer,
|
||||||
|
clipboard: &mut dyn Clipboard,
|
||||||
|
shell: &mut Shell<'_, Message>,
|
||||||
|
) -> event::Status {
|
||||||
|
let mut local_messages = Vec::new();
|
||||||
|
let mut local_shell = Shell::new(&mut local_messages);
|
||||||
|
|
||||||
|
let event_status =
|
||||||
|
self.state.as_mut().unwrap().with_cache_mut(|cache| {
|
||||||
|
cache.element.on_event(
|
||||||
|
event,
|
||||||
|
layout,
|
||||||
|
cursor_position,
|
||||||
|
renderer,
|
||||||
|
clipboard,
|
||||||
|
&mut local_shell,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
if !local_messages.is_empty() {
|
||||||
|
let mut component =
|
||||||
|
self.state.take().unwrap().into_heads().component;
|
||||||
|
|
||||||
|
for message in local_messages
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|message| component.update(message))
|
||||||
|
{
|
||||||
|
shell.publish(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state = Some(
|
||||||
|
StateBuilder {
|
||||||
|
component,
|
||||||
|
cache_builder: |state| Cache {
|
||||||
|
element: state.view(),
|
||||||
|
message: PhantomData,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
shell.invalidate_layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
event_status
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
style: &renderer::Style,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor_position: Point,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
) {
|
||||||
|
self.state.as_ref().unwrap().borrow_cache().element.draw(
|
||||||
|
renderer,
|
||||||
|
style,
|
||||||
|
layout,
|
||||||
|
cursor_position,
|
||||||
|
viewport,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash_layout(&self, state: &mut Hasher) {
|
||||||
|
self.state
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_cache()
|
||||||
|
.element
|
||||||
|
.hash_layout(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor_position: Point,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
) -> mouse::Interaction {
|
||||||
|
self.state
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_cache()
|
||||||
|
.element
|
||||||
|
.mouse_interaction(layout, cursor_position, viewport)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlay(
|
||||||
|
&mut self,
|
||||||
|
_layout: Layout<'_>,
|
||||||
|
) -> Option<overlay::Element<'_, Message, Renderer>> {
|
||||||
|
// TODO: Rethink overlay composability
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
3
lazy/src/lib.rs
Normal file
3
lazy/src/lib.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod component;
|
||||||
|
|
||||||
|
pub use component::Component;
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::mouse;
|
||||||
use crate::overlay;
|
use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Color, Hasher, Layout, Length, Point, Rectangle, Widget,
|
Clipboard, Color, Hasher, Layout, Length, Point, Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A generic [`Widget`].
|
/// A generic [`Widget`].
|
||||||
|
|
@ -228,7 +228,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.widget.on_event(
|
self.widget.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -236,7 +236,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -327,9 +327,10 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<B>,
|
shell: &mut Shell<'_, B>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let mut original_messages = Vec::new();
|
let mut local_messages = Vec::new();
|
||||||
|
let mut local_shell = Shell::new(&mut local_messages);
|
||||||
|
|
||||||
let status = self.widget.on_event(
|
let status = self.widget.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -337,12 +338,10 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
&mut original_messages,
|
&mut local_shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
original_messages
|
shell.merge(local_shell, &self.mapper);
|
||||||
.drain(..)
|
|
||||||
.for_each(|message| messages.push((self.mapper)(message)));
|
|
||||||
|
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
|
|
@ -427,7 +426,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.element.widget.on_event(
|
self.element.widget.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -435,7 +434,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ pub mod window;
|
||||||
mod element;
|
mod element;
|
||||||
mod hasher;
|
mod hasher;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
|
mod shell;
|
||||||
mod user_interface;
|
mod user_interface;
|
||||||
|
|
||||||
// We disable debug capabilities on release builds unless the `debug` feature
|
// We disable debug capabilities on release builds unless the `debug` feature
|
||||||
|
|
@ -85,6 +86,7 @@ pub use overlay::Overlay;
|
||||||
pub use program::Program;
|
pub use program::Program;
|
||||||
pub use renderer::Renderer;
|
pub use renderer::Renderer;
|
||||||
pub use runtime::Runtime;
|
pub use runtime::Runtime;
|
||||||
|
pub use shell::Shell;
|
||||||
pub use subscription::Subscription;
|
pub use subscription::Subscription;
|
||||||
pub use user_interface::{Cache, UserInterface};
|
pub use user_interface::{Cache, UserInterface};
|
||||||
pub use widget::Widget;
|
pub use widget::Widget;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use crate::event::{self, Event};
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{Clipboard, Hasher, Layout, Point, Rectangle, Size};
|
use crate::{Clipboard, Hasher, Layout, Point, Rectangle, Shell, Size};
|
||||||
|
|
||||||
/// An interactive component that can be displayed on top of other widgets.
|
/// An interactive component that can be displayed on top of other widgets.
|
||||||
pub trait Overlay<Message, Renderer>
|
pub trait Overlay<Message, Renderer>
|
||||||
|
|
@ -71,7 +71,7 @@ where
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
_messages: &mut Vec<Message>,
|
_shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
event::Status::Ignored
|
event::Status::Ignored
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::event::{self, Event};
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{Clipboard, Hasher, Layout, Point, Rectangle, Size, Vector};
|
use crate::{Clipboard, Hasher, Layout, Point, Rectangle, Shell, Size, Vector};
|
||||||
|
|
||||||
/// A generic [`Overlay`].
|
/// A generic [`Overlay`].
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
|
|
@ -25,6 +25,11 @@ where
|
||||||
Self { position, overlay }
|
Self { position, overlay }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the position of the [`Element`].
|
||||||
|
pub fn position(&self) -> Point {
|
||||||
|
self.position
|
||||||
|
}
|
||||||
|
|
||||||
/// Translates the [`Element`].
|
/// Translates the [`Element`].
|
||||||
pub fn translate(mut self, translation: Vector) -> Self {
|
pub fn translate(mut self, translation: Vector) -> Self {
|
||||||
self.position = self.position + translation;
|
self.position = self.position + translation;
|
||||||
|
|
@ -57,7 +62,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.overlay.on_event(
|
self.overlay.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -65,7 +70,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,9 +136,10 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<B>,
|
shell: &mut Shell<'_, B>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let mut original_messages = Vec::new();
|
let mut local_messages = Vec::new();
|
||||||
|
let mut local_shell = Shell::new(&mut local_messages);
|
||||||
|
|
||||||
let event_status = self.content.on_event(
|
let event_status = self.content.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -141,12 +147,10 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
&mut original_messages,
|
&mut local_shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
original_messages
|
shell.merge(local_shell, self.mapper);
|
||||||
.drain(..)
|
|
||||||
.for_each(|message| messages.push((self.mapper)(message)));
|
|
||||||
|
|
||||||
event_status
|
event_status
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::widget::scrollable::{self, Scrollable};
|
||||||
use crate::widget::Container;
|
use crate::widget::Container;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Color, Element, Hasher, Layout, Length, Padding, Point,
|
Clipboard, Color, Element, Hasher, Layout, Length, Padding, Point,
|
||||||
Rectangle, Size, Vector, Widget,
|
Rectangle, Shell, Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_style::menu::Style;
|
pub use iced_style::menu::Style;
|
||||||
|
|
@ -222,7 +222,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.container.on_event(
|
self.container.on_event(
|
||||||
event.clone(),
|
event.clone(),
|
||||||
|
|
@ -230,7 +230,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,7 +333,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
_messages: &mut Vec<Message>,
|
_shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
|
||||||
|
|
|
||||||
54
native/src/shell.rs
Normal file
54
native/src/shell.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/// A connection to the state of a shell.
|
||||||
|
///
|
||||||
|
/// A [`Widget`] can leverage a [`Shell`] to trigger changes in an application,
|
||||||
|
/// like publishing messages or invalidating the current layout.
|
||||||
|
///
|
||||||
|
/// [`Widget`]: crate::Widget
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Shell<'a, Message> {
|
||||||
|
messages: &'a mut Vec<Message>,
|
||||||
|
is_layout_invalid: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message> Shell<'a, Message> {
|
||||||
|
/// Creates a new [`Shell`] with the provided buffer of messages.
|
||||||
|
pub fn new(messages: &'a mut Vec<Message>) -> Self {
|
||||||
|
Self {
|
||||||
|
messages,
|
||||||
|
is_layout_invalid: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Triggers the given function if the layout is invalid, cleaning it in the
|
||||||
|
/// process.
|
||||||
|
pub fn with_invalid_layout(&mut self, f: impl FnOnce()) {
|
||||||
|
if self.is_layout_invalid {
|
||||||
|
self.is_layout_invalid = false;
|
||||||
|
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Publish the given `Message` for an application to process it.
|
||||||
|
pub fn publish(&mut self, message: Message) {
|
||||||
|
self.messages.push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invalidates the current application layout.
|
||||||
|
///
|
||||||
|
/// The shell will relayout the application widgets.
|
||||||
|
pub fn invalidate_layout(&mut self) {
|
||||||
|
self.is_layout_invalid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merges the current [`Shell`] with another one by applying the given
|
||||||
|
/// function to the messages of the latter.
|
||||||
|
///
|
||||||
|
/// This method is useful for composition.
|
||||||
|
pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
|
||||||
|
self.messages.extend(other.messages.drain(..).map(f));
|
||||||
|
|
||||||
|
self.is_layout_invalid =
|
||||||
|
self.is_layout_invalid || other.is_layout_invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::overlay;
|
use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{Clipboard, Element, Layout, Point, Rectangle, Size};
|
use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
||||||
|
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ where
|
||||||
/// let event_statuses = user_interface.update(
|
/// let event_statuses = user_interface.update(
|
||||||
/// &events,
|
/// &events,
|
||||||
/// cursor_position,
|
/// cursor_position,
|
||||||
/// &renderer,
|
/// &mut renderer,
|
||||||
/// &mut clipboard,
|
/// &mut clipboard,
|
||||||
/// &mut messages
|
/// &mut messages
|
||||||
/// );
|
/// );
|
||||||
|
|
@ -196,16 +196,18 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
events: &[Event],
|
events: &[Event],
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &mut Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
) -> Vec<event::Status> {
|
) -> Vec<event::Status> {
|
||||||
let (base_cursor, overlay_statuses) = if let Some(mut overlay) =
|
let (base_cursor, overlay_statuses) = if let Some(mut overlay) =
|
||||||
self.root.overlay(Layout::new(&self.base.layout))
|
self.root.overlay(Layout::new(&self.base.layout))
|
||||||
{
|
{
|
||||||
let layer = Self::overlay_layer(
|
let bounds = self.bounds;
|
||||||
|
|
||||||
|
let mut layer = Self::overlay_layer(
|
||||||
self.overlay.take(),
|
self.overlay.take(),
|
||||||
self.bounds,
|
bounds,
|
||||||
&mut overlay,
|
&mut overlay,
|
||||||
renderer,
|
renderer,
|
||||||
);
|
);
|
||||||
|
|
@ -214,14 +216,27 @@ where
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|event| {
|
.map(|event| {
|
||||||
overlay.on_event(
|
let mut shell = Shell::new(messages);
|
||||||
|
|
||||||
|
let event_status = overlay.on_event(
|
||||||
event,
|
event,
|
||||||
Layout::new(&layer.layout),
|
Layout::new(&layer.layout),
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
&mut shell,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
shell.with_invalid_layout(|| {
|
||||||
|
layer = Self::overlay_layer(
|
||||||
|
None,
|
||||||
|
bounds,
|
||||||
|
&mut overlay,
|
||||||
|
renderer,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
event_status
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
@ -245,15 +260,34 @@ where
|
||||||
.cloned()
|
.cloned()
|
||||||
.zip(overlay_statuses.into_iter())
|
.zip(overlay_statuses.into_iter())
|
||||||
.map(|(event, overlay_status)| {
|
.map(|(event, overlay_status)| {
|
||||||
|
let mut shell = Shell::new(messages);
|
||||||
|
|
||||||
let event_status = self.root.widget.on_event(
|
let event_status = self.root.widget.on_event(
|
||||||
event,
|
event,
|
||||||
Layout::new(&self.base.layout),
|
Layout::new(&self.base.layout),
|
||||||
base_cursor,
|
base_cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
&mut shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
shell.with_invalid_layout(|| {
|
||||||
|
let hash = {
|
||||||
|
let hasher = &mut crate::Hasher::default();
|
||||||
|
self.root.hash_layout(hasher);
|
||||||
|
|
||||||
|
hasher.finish()
|
||||||
|
};
|
||||||
|
|
||||||
|
let layout = renderer.layout(
|
||||||
|
&self.root,
|
||||||
|
&layout::Limits::new(Size::ZERO, self.bounds),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.base = Layer { layout, hash };
|
||||||
|
self.overlay = None;
|
||||||
|
});
|
||||||
|
|
||||||
event_status.merge(overlay_status)
|
event_status.merge(overlay_status)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
@ -313,7 +347,7 @@ where
|
||||||
/// let event_statuses = user_interface.update(
|
/// let event_statuses = user_interface.update(
|
||||||
/// &events,
|
/// &events,
|
||||||
/// cursor_position,
|
/// cursor_position,
|
||||||
/// &renderer,
|
/// &mut renderer,
|
||||||
/// &mut clipboard,
|
/// &mut clipboard,
|
||||||
/// &mut messages
|
/// &mut messages
|
||||||
/// );
|
/// );
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::overlay;
|
use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{Clipboard, Hasher, Layout, Length, Point, Rectangle};
|
use crate::{Clipboard, Hasher, Layout, Length, Point, Rectangle, Shell};
|
||||||
|
|
||||||
/// A component that displays information and allows interaction.
|
/// A component that displays information and allows interaction.
|
||||||
///
|
///
|
||||||
|
|
@ -163,7 +163,7 @@ where
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
_messages: &mut Vec<Message>,
|
_shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
event::Status::Ignored
|
event::Status::Ignored
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::renderer;
|
||||||
use crate::touch;
|
use crate::touch;
|
||||||
use crate::{
|
use crate::{
|
||||||
Background, Clipboard, Color, Element, Hasher, Layout, Length, Padding,
|
Background, Clipboard, Color, Element, Hasher, Layout, Length, Padding,
|
||||||
Point, Rectangle, Vector, Widget,
|
Point, Rectangle, Shell, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
@ -197,7 +197,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
if let event::Status::Captured = self.content.on_event(
|
if let event::Status::Captured = self.content.on_event(
|
||||||
event.clone(),
|
event.clone(),
|
||||||
|
|
@ -205,7 +205,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
) {
|
) {
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +232,7 @@ where
|
||||||
self.state.is_pressed = false;
|
self.state.is_pressed = false;
|
||||||
|
|
||||||
if bounds.contains(cursor_position) {
|
if bounds.contains(cursor_position) {
|
||||||
messages.push(on_press);
|
shell.publish(on_press);
|
||||||
}
|
}
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::touch;
|
||||||
use crate::widget::{self, Row, Text};
|
use crate::widget::{self, Row, Text};
|
||||||
use crate::{
|
use crate::{
|
||||||
Alignment, Clipboard, Color, Element, Hasher, Layout, Length, Point,
|
Alignment, Clipboard, Color, Element, Hasher, Layout, Length, Point,
|
||||||
Rectangle, Widget,
|
Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_style::checkbox::{Style, StyleSheet};
|
pub use iced_style::checkbox::{Style, StyleSheet};
|
||||||
|
|
@ -171,7 +171,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
|
|
@ -179,7 +179,7 @@ where
|
||||||
let mouse_over = layout.bounds().contains(cursor_position);
|
let mouse_over = layout.bounds().contains(cursor_position);
|
||||||
|
|
||||||
if mouse_over {
|
if mouse_over {
|
||||||
messages.push((self.on_toggle)(!self.is_checked));
|
shell.publish((self.on_toggle)(!self.is_checked));
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
Alignment, Clipboard, Element, Hasher, Layout, Length, Padding, Point,
|
Alignment, Clipboard, Element, Hasher, Layout, Length, Padding, Point,
|
||||||
Rectangle, Widget,
|
Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
@ -146,7 +146,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.children
|
self.children
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
|
@ -158,7 +158,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.fold(event::Status::Ignored, event::Status::merge)
|
.fold(event::Status::Ignored, event::Status::merge)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
Background, Clipboard, Color, Element, Hasher, Layout, Length, Padding,
|
Background, Clipboard, Color, Element, Hasher, Layout, Length, Padding,
|
||||||
Point, Rectangle, Widget,
|
Point, Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
@ -167,7 +167,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.content.widget.on_event(
|
self.content.widget.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -175,7 +175,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Size, Vector,
|
Clipboard, Element, Hasher, Layout, Length, Point, Rectangle, Shell, Size,
|
||||||
Widget,
|
Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
@ -169,7 +169,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
_messages: &mut Vec<Message>,
|
_shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::touch;
|
use crate::touch;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Color, Element, Hasher, Layout, Length, Point, Rectangle, Size,
|
Clipboard, Color, Element, Hasher, Layout, Length, Point, Rectangle, Shell,
|
||||||
Vector, Widget,
|
Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_style::pane_grid::{Line, StyleSheet};
|
pub use iced_style::pane_grid::{Line, StyleSheet};
|
||||||
|
|
@ -205,7 +205,7 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) {
|
) {
|
||||||
let mut clicked_region =
|
let mut clicked_region =
|
||||||
self.elements.iter().zip(layout.children()).filter(
|
self.elements.iter().zip(layout.children()).filter(
|
||||||
|
|
@ -214,7 +214,7 @@ where
|
||||||
|
|
||||||
if let Some(((pane, content), layout)) = clicked_region.next() {
|
if let Some(((pane, content), layout)) = clicked_region.next() {
|
||||||
if let Some(on_click) = &self.on_click {
|
if let Some(on_click) = &self.on_click {
|
||||||
messages.push(on_click(*pane));
|
shell.publish(on_click(*pane));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(on_drag) = &self.on_drag {
|
if let Some(on_drag) = &self.on_drag {
|
||||||
|
|
@ -226,7 +226,7 @@ where
|
||||||
|
|
||||||
self.state.pick_pane(pane, origin);
|
self.state.pick_pane(pane, origin);
|
||||||
|
|
||||||
messages.push(on_drag(DragEvent::Picked { pane: *pane }));
|
shell.publish(on_drag(DragEvent::Picked { pane: *pane }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +236,7 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
if let Some((_, on_resize)) = &self.on_resize {
|
if let Some((_, on_resize)) = &self.on_resize {
|
||||||
if let Some((split, _)) = self.state.picked_split() {
|
if let Some((split, _)) = self.state.picked_split() {
|
||||||
|
|
@ -263,7 +263,7 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
messages.push(on_resize(ResizeEvent { split, ratio }));
|
shell.publish(on_resize(ResizeEvent { split, ratio }));
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -362,7 +362,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let mut event_status = event::Status::Ignored;
|
let mut event_status = event::Status::Ignored;
|
||||||
|
|
||||||
|
|
@ -395,15 +395,11 @@ where
|
||||||
if let Some((split, axis, _)) = clicked_split {
|
if let Some((split, axis, _)) = clicked_split {
|
||||||
self.state.pick_split(&split, axis);
|
self.state.pick_split(&split, axis);
|
||||||
} else {
|
} else {
|
||||||
self.click_pane(
|
self.click_pane(layout, cursor_position, shell);
|
||||||
layout,
|
|
||||||
cursor_position,
|
|
||||||
messages,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.click_pane(layout, cursor_position, messages);
|
self.click_pane(layout, cursor_position, shell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -430,7 +426,7 @@ where
|
||||||
_ => DragEvent::Canceled { pane },
|
_ => DragEvent::Canceled { pane },
|
||||||
};
|
};
|
||||||
|
|
||||||
messages.push(on_drag(event));
|
shell.publish(on_drag(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state.idle();
|
self.state.idle();
|
||||||
|
|
@ -445,7 +441,7 @@ where
|
||||||
Event::Mouse(mouse::Event::CursorMoved { .. })
|
Event::Mouse(mouse::Event::CursorMoved { .. })
|
||||||
| Event::Touch(touch::Event::FingerMoved { .. }) => {
|
| Event::Touch(touch::Event::FingerMoved { .. }) => {
|
||||||
event_status =
|
event_status =
|
||||||
self.trigger_resize(layout, cursor_position, messages);
|
self.trigger_resize(layout, cursor_position, shell);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -464,7 +460,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
is_picked,
|
is_picked,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::widget::container;
|
use crate::widget::container;
|
||||||
use crate::widget::pane_grid::TitleBar;
|
use crate::widget::pane_grid::TitleBar;
|
||||||
use crate::{Clipboard, Element, Hasher, Layout, Point, Rectangle, Size};
|
use crate::{
|
||||||
|
Clipboard, Element, Hasher, Layout, Point, Rectangle, Shell, Size,
|
||||||
|
};
|
||||||
|
|
||||||
/// The content of a [`Pane`].
|
/// The content of a [`Pane`].
|
||||||
///
|
///
|
||||||
|
|
@ -160,7 +162,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
is_picked: bool,
|
is_picked: bool,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let mut event_status = event::Status::Ignored;
|
let mut event_status = event::Status::Ignored;
|
||||||
|
|
@ -174,7 +176,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
children.next().unwrap()
|
children.next().unwrap()
|
||||||
|
|
@ -191,7 +193,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::widget::container;
|
use crate::widget::container;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Element, Hasher, Layout, Padding, Point, Rectangle, Size,
|
Clipboard, Element, Hasher, Layout, Padding, Point, Rectangle, Shell, Size,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The title bar of a [`Pane`].
|
/// The title bar of a [`Pane`].
|
||||||
|
|
@ -218,7 +218,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let mut children = layout.children();
|
let mut children = layout.children();
|
||||||
let padded = children.next().unwrap();
|
let padded = children.next().unwrap();
|
||||||
|
|
@ -235,7 +235,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
event::Status::Ignored
|
event::Status::Ignored
|
||||||
|
|
@ -247,7 +247,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
control_status.merge(title_status)
|
control_status.merge(title_status)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::text::{self, Text};
|
||||||
use crate::touch;
|
use crate::touch;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Element, Hasher, Layout, Length, Padding, Point, Rectangle,
|
Clipboard, Element, Hasher, Layout, Length, Padding, Point, Rectangle,
|
||||||
Size, Widget,
|
Shell, Size, Widget,
|
||||||
};
|
};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
|
@ -245,7 +245,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
|
|
@ -271,7 +271,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(last_selection) = self.last_selection.take() {
|
if let Some(last_selection) = self.last_selection.take() {
|
||||||
messages.push((self.on_selected)(last_selection));
|
shell.publish((self.on_selected)(last_selection));
|
||||||
|
|
||||||
*self.is_open = false;
|
*self.is_open = false;
|
||||||
|
|
||||||
|
|
@ -312,7 +312,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(next_option) = next_option {
|
if let Some(next_option) = next_option {
|
||||||
messages.push((self.on_selected)(next_option.clone()));
|
shell.publish((self.on_selected)(next_option.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
event::Status::Captured
|
event::Status::Captured
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::touch;
|
||||||
use crate::widget::{self, Row, Text};
|
use crate::widget::{self, Row, Text};
|
||||||
use crate::{
|
use crate::{
|
||||||
Alignment, Clipboard, Color, Element, Hasher, Layout, Length, Point,
|
Alignment, Clipboard, Color, Element, Hasher, Layout, Length, Point,
|
||||||
Rectangle, Widget,
|
Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_style::radio::{Style, StyleSheet};
|
pub use iced_style::radio::{Style, StyleSheet};
|
||||||
|
|
@ -187,13 +187,13 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
| Event::Touch(touch::Event::FingerPressed { .. }) => {
|
| Event::Touch(touch::Event::FingerPressed { .. }) => {
|
||||||
if layout.bounds().contains(cursor_position) {
|
if layout.bounds().contains(cursor_position) {
|
||||||
messages.push(self.on_click.clone());
|
shell.publish(self.on_click.clone());
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::overlay;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
Alignment, Clipboard, Element, Hasher, Layout, Length, Padding, Point,
|
Alignment, Clipboard, Element, Hasher, Layout, Length, Padding, Point,
|
||||||
Rectangle, Widget,
|
Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
@ -145,7 +145,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.children
|
self.children
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
|
@ -157,7 +157,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.fold(event::Status::Ignored, event::Status::merge)
|
.fold(event::Status::Ignored, event::Status::merge)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::touch;
|
||||||
use crate::widget::Column;
|
use crate::widget::Column;
|
||||||
use crate::{
|
use crate::{
|
||||||
Alignment, Background, Clipboard, Color, Element, Hasher, Layout, Length,
|
Alignment, Background, Clipboard, Color, Element, Hasher, Layout, Length,
|
||||||
Padding, Point, Rectangle, Size, Vector, Widget,
|
Padding, Point, Rectangle, Shell, Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{f32, hash::Hash, u32};
|
use std::{f32, hash::Hash, u32};
|
||||||
|
|
@ -144,14 +144,14 @@ impl<'a, Message, Renderer: crate::Renderer> Scrollable<'a, Message, Renderer> {
|
||||||
&self,
|
&self,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
content_bounds: Rectangle,
|
content_bounds: Rectangle,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) {
|
) {
|
||||||
if content_bounds.height <= bounds.height {
|
if content_bounds.height <= bounds.height {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(on_scroll) = &self.on_scroll {
|
if let Some(on_scroll) = &self.on_scroll {
|
||||||
messages.push(on_scroll(
|
shell.publish(on_scroll(
|
||||||
self.state.offset.absolute(bounds, content_bounds)
|
self.state.offset.absolute(bounds, content_bounds)
|
||||||
/ (content_bounds.height - bounds.height),
|
/ (content_bounds.height - bounds.height),
|
||||||
));
|
));
|
||||||
|
|
@ -251,7 +251,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
@ -286,7 +286,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -307,7 +307,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.notify_on_scroll(bounds, content_bounds, messages);
|
self.notify_on_scroll(bounds, content_bounds, shell);
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +336,7 @@ where
|
||||||
self.notify_on_scroll(
|
self.notify_on_scroll(
|
||||||
bounds,
|
bounds,
|
||||||
content_bounds,
|
content_bounds,
|
||||||
messages,
|
shell,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -377,7 +377,7 @@ where
|
||||||
content_bounds,
|
content_bounds,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.notify_on_scroll(bounds, content_bounds, messages);
|
self.notify_on_scroll(bounds, content_bounds, shell);
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +409,7 @@ where
|
||||||
self.notify_on_scroll(
|
self.notify_on_scroll(
|
||||||
bounds,
|
bounds,
|
||||||
content_bounds,
|
content_bounds,
|
||||||
messages,
|
shell,
|
||||||
);
|
);
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::renderer;
|
||||||
use crate::touch;
|
use crate::touch;
|
||||||
use crate::{
|
use crate::{
|
||||||
Background, Clipboard, Color, Element, Hasher, Layout, Length, Point,
|
Background, Clipboard, Color, Element, Hasher, Layout, Length, Point,
|
||||||
Rectangle, Size, Widget,
|
Rectangle, Shell, Size, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
@ -191,7 +191,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let is_dragging = self.state.is_dragging;
|
let is_dragging = self.state.is_dragging;
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self.value.into() - new_value.into()).abs() > f64::EPSILON {
|
if (self.value.into() - new_value.into()).abs() > f64::EPSILON {
|
||||||
messages.push((self.on_change)(new_value));
|
shell.publish((self.on_change)(new_value));
|
||||||
|
|
||||||
self.value = new_value;
|
self.value = new_value;
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +241,7 @@ where
|
||||||
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
||||||
if is_dragging {
|
if is_dragging {
|
||||||
if let Some(on_release) = self.on_release.clone() {
|
if let Some(on_release) = self.on_release.clone() {
|
||||||
messages.push(on_release);
|
shell.publish(on_release);
|
||||||
}
|
}
|
||||||
self.state.is_dragging = false;
|
self.state.is_dragging = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::text::{self, Text};
|
||||||
use crate::touch;
|
use crate::touch;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Color, Element, Hasher, Layout, Length, Padding, Point,
|
Clipboard, Color, Element, Hasher, Layout, Length, Padding, Point,
|
||||||
Rectangle, Size, Vector, Widget,
|
Rectangle, Shell, Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
@ -384,7 +384,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
|
|
@ -509,7 +509,7 @@ where
|
||||||
editor.insert(c);
|
editor.insert(c);
|
||||||
|
|
||||||
let message = (self.on_change)(editor.contents());
|
let message = (self.on_change)(editor.contents());
|
||||||
messages.push(message);
|
shell.publish(message);
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +521,7 @@ where
|
||||||
match key_code {
|
match key_code {
|
||||||
keyboard::KeyCode::Enter => {
|
keyboard::KeyCode::Enter => {
|
||||||
if let Some(on_submit) = self.on_submit.clone() {
|
if let Some(on_submit) = self.on_submit.clone() {
|
||||||
messages.push(on_submit);
|
shell.publish(on_submit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Backspace => {
|
keyboard::KeyCode::Backspace => {
|
||||||
|
|
@ -551,7 +551,7 @@ where
|
||||||
editor.backspace();
|
editor.backspace();
|
||||||
|
|
||||||
let message = (self.on_change)(editor.contents());
|
let message = (self.on_change)(editor.contents());
|
||||||
messages.push(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Delete => {
|
keyboard::KeyCode::Delete => {
|
||||||
if platform::is_jump_modifier_pressed(modifiers)
|
if platform::is_jump_modifier_pressed(modifiers)
|
||||||
|
|
@ -582,7 +582,7 @@ where
|
||||||
editor.delete();
|
editor.delete();
|
||||||
|
|
||||||
let message = (self.on_change)(editor.contents());
|
let message = (self.on_change)(editor.contents());
|
||||||
messages.push(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Left => {
|
keyboard::KeyCode::Left => {
|
||||||
if platform::is_jump_modifier_pressed(modifiers)
|
if platform::is_jump_modifier_pressed(modifiers)
|
||||||
|
|
@ -674,7 +674,7 @@ where
|
||||||
editor.delete();
|
editor.delete();
|
||||||
|
|
||||||
let message = (self.on_change)(editor.contents());
|
let message = (self.on_change)(editor.contents());
|
||||||
messages.push(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::V => {
|
keyboard::KeyCode::V => {
|
||||||
if self.state.keyboard_modifiers.command() {
|
if self.state.keyboard_modifiers.command() {
|
||||||
|
|
@ -700,7 +700,7 @@ where
|
||||||
editor.paste(content.clone());
|
editor.paste(content.clone());
|
||||||
|
|
||||||
let message = (self.on_change)(editor.contents());
|
let message = (self.on_change)(editor.contents());
|
||||||
messages.push(message);
|
shell.publish(message);
|
||||||
|
|
||||||
self.state.is_pasting = Some(content);
|
self.state.is_pasting = Some(content);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use crate::text;
|
||||||
use crate::widget::{Row, Text};
|
use crate::widget::{Row, Text};
|
||||||
use crate::{
|
use crate::{
|
||||||
Alignment, Clipboard, Element, Event, Hasher, Layout, Length, Point,
|
Alignment, Clipboard, Element, Event, Hasher, Layout, Length, Point,
|
||||||
Rectangle, Widget,
|
Rectangle, Shell, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use iced_style::toggler::{Style, StyleSheet};
|
pub use iced_style::toggler::{Style, StyleSheet};
|
||||||
|
|
@ -173,14 +173,14 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
_clipboard: &mut dyn Clipboard,
|
_clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
|
||||||
let mouse_over = layout.bounds().contains(cursor_position);
|
let mouse_over = layout.bounds().contains(cursor_position);
|
||||||
|
|
||||||
if mouse_over {
|
if mouse_over {
|
||||||
messages.push((self.on_toggle)(!self.is_active));
|
shell.publish((self.on_toggle)(!self.is_active));
|
||||||
|
|
||||||
event::Status::Captured
|
event::Status::Captured
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ use crate::text;
|
||||||
use crate::widget::container;
|
use crate::widget::container;
|
||||||
use crate::widget::text::Text;
|
use crate::widget::text::Text;
|
||||||
use crate::{
|
use crate::{
|
||||||
Clipboard, Element, Event, Hasher, Layout, Length, Padding, Point, Size,
|
Clipboard, Element, Event, Hasher, Layout, Length, Padding, Point, Shell,
|
||||||
Vector, Widget,
|
Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An element to display a widget over another.
|
/// An element to display a widget over another.
|
||||||
|
|
@ -130,7 +130,7 @@ where
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.content.widget.on_event(
|
self.content.widget.on_event(
|
||||||
event,
|
event,
|
||||||
|
|
@ -138,7 +138,7 @@ where
|
||||||
cursor_position,
|
cursor_position,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
messages,
|
shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue