Skip to content

Commit

Permalink
Merge pull request #5 from cryptowatch/port/widget-operations
Browse files Browse the repository at this point in the history
Port widget operations to impure widgets
  • Loading branch information
hecrj authored Oct 28, 2022
2 parents c5b9e76 + ab0e99e commit 0ac98fd
Show file tree
Hide file tree
Showing 30 changed files with 1,053 additions and 59 deletions.
48 changes: 27 additions & 21 deletions glutin/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use iced_winit::futures;
use iced_winit::futures::channel::mpsc;
use iced_winit::renderer;
use iced_winit::user_interface;
use iced_winit::{Clipboard, Debug, Proxy, Settings};
use iced_winit::{Clipboard, Command, Debug, Proxy, Settings};

use glutin::window::Window;
use std::mem::ManuallyDrop;
Expand All @@ -39,9 +39,9 @@ where
debug.startup_started();

let mut event_loop = EventLoop::with_user_event();
let mut proxy = event_loop.create_proxy();
let proxy = event_loop.create_proxy();

let mut runtime = {
let runtime = {
let executor = E::new().map_err(Error::ExecutorCreationFailed)?;
let proxy = Proxy::new(event_loop.create_proxy());

Expand All @@ -54,8 +54,6 @@ where
runtime.enter(|| A::new(flags))
};

let subscription = application.subscription();

let context = {
let builder = settings.window.into_builder(
&application.title(),
Expand Down Expand Up @@ -125,30 +123,18 @@ where
})?
};

let mut clipboard = Clipboard::connect(context.window());

application::run_command(
init_command,
&mut runtime,
&mut clipboard,
&mut proxy,
context.window(),
|| compositor.fetch_information(),
);
runtime.track(subscription);

let (mut sender, receiver) = mpsc::unbounded();

let mut instance = Box::pin(run_instance::<A, E, C>(
application,
compositor,
renderer,
runtime,
clipboard,
proxy,
debug,
receiver,
context,
init_command,
settings.exit_on_close_request,
));

Expand Down Expand Up @@ -196,11 +182,11 @@ async fn run_instance<A, E, C>(
mut compositor: C,
mut renderer: A::Renderer,
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
mut clipboard: Clipboard,
mut proxy: glutin::event_loop::EventLoopProxy<A::Message>,
mut debug: Debug,
mut receiver: mpsc::UnboundedReceiver<glutin::event::Event<'_, A::Message>>,
mut context: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,
init_command: Command<A::Message>,
exit_on_close_request: bool,
) where
A: Application + 'static,
Expand All @@ -211,13 +197,30 @@ async fn run_instance<A, E, C>(
use glutin::event;
use iced_winit::futures::stream::StreamExt;

let mut clipboard = Clipboard::connect(context.window());
let mut cache = user_interface::Cache::default();
let mut state = application::State::new(&application, context.window());
let mut viewport_version = state.viewport_version();

application::run_command(
&mut application,
&mut cache,
&state,
&mut renderer,
init_command,
&mut runtime,
&mut clipboard,
&mut proxy,
&mut debug,
context.window(),
|| compositor.fetch_information(),
);
runtime.track(application.subscription());

let mut user_interface =
ManuallyDrop::new(application::build_user_interface(
&mut application,
user_interface::Cache::default(),
cache,
&mut renderer,
state.logical_size(),
&mut debug,
Expand Down Expand Up @@ -258,12 +261,15 @@ async fn run_instance<A, E, C>(
user_interface::State::Outdated
)
{
let cache =
let mut cache =
ManuallyDrop::into_inner(user_interface).into_cache();

// Update application
application::update(
&mut application,
&mut cache,
&state,
&mut renderer,
&mut runtime,
&mut clipboard,
&mut proxy,
Expand Down
10 changes: 10 additions & 0 deletions native/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod action;

pub use action::Action;

use crate::widget;

use iced_futures::MaybeSend;

use std::fmt;
Expand All @@ -24,6 +26,13 @@ impl<T> Command<T> {
Self(iced_futures::Command::single(action))
}

/// Creates a [`Command`] that performs a [`widget::Operation`].
pub fn widget(operation: impl widget::Operation<T> + 'static) -> Self {
Self(iced_futures::Command::single(Action::Widget(
widget::Action::new(operation),
)))
}

/// Creates a [`Command`] that performs the action of the given future.
pub fn perform<A>(
future: impl Future<Output = T> + 'static + MaybeSend,
Expand Down Expand Up @@ -51,6 +60,7 @@ impl<T> Command<T> {
) -> Command<A>
where
T: 'static,
A: 'static,
{
let Command(command) = self;

Expand Down
7 changes: 7 additions & 0 deletions native/src/command/action.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::clipboard;
use crate::system;
use crate::widget;
use crate::window;

use iced_futures::MaybeSend;
Expand All @@ -23,6 +24,9 @@ pub enum Action<T> {

/// Run a system action.
System(system::Action<T>),

/// Run a widget action.
Widget(widget::Action<T>),
}

impl<T> Action<T> {
Expand All @@ -35,6 +39,7 @@ impl<T> Action<T> {
) -> Action<A>
where
T: 'static,
A: 'static,
{
use iced_futures::futures::FutureExt;

Expand All @@ -43,6 +48,7 @@ impl<T> Action<T> {
Self::Clipboard(action) => Action::Clipboard(action.map(f)),
Self::Window(window) => Action::Window(window),
Self::System(system) => Action::System(system.map(f)),
Self::Widget(widget) => Action::Widget(widget.map(f)),
}
}
}
Expand All @@ -56,6 +62,7 @@ impl<T> fmt::Debug for Action<T> {
}
Self::Window(action) => write!(f, "Action::Window({:?})", action),
Self::System(action) => write!(f, "Action::System({:?})", action),
Self::Widget(_action) => write!(f, "Action::Widget"),
}
}
}
44 changes: 44 additions & 0 deletions native/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::layout;
use crate::mouse;
use crate::overlay;
use crate::renderer;
use crate::widget;
use crate::{
Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Widget,
};
Expand Down Expand Up @@ -220,6 +221,15 @@ where
self.widget.layout(renderer, limits)
}

/// Applies an [`Operation`] to the [`Element`].
pub fn operate(
&mut self,
layout: Layout<'_>,
operation: &mut dyn widget::Operation<Message>,
) {
self.widget.operate(layout, operation);
}

/// Processes a runtime [`Event`].
pub fn on_event(
&mut self,
Expand Down Expand Up @@ -328,6 +338,40 @@ where
self.widget.layout(renderer, limits)
}

fn operate(
&mut self,
layout: Layout<'_>,
operation: &mut dyn widget::Operation<B>,
) {
struct MapOperation<'a, B> {
operation: &'a mut dyn widget::Operation<B>,
}

impl<'a, T, B> widget::Operation<T> for MapOperation<'a, B> {
fn container(
&mut self,
id: Option<&widget::Id>,
operate_on_children: &mut dyn FnMut(
&mut dyn widget::Operation<T>,
),
) {
self.operation.container(id, &mut |operation| {
operate_on_children(&mut MapOperation { operation });
});
}

fn focusable(
&mut self,
state: &mut dyn widget::operation::Focusable,
id: Option<&widget::Id>,
) {
self.operation.focusable(state, id);
}
}

self.widget.operate(layout, &mut MapOperation { operation });
}

fn on_event(
&mut self,
event: Event,
Expand Down
9 changes: 9 additions & 0 deletions native/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
use crate::renderer;
use crate::widget;
use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size};

/// An interactive component that can be displayed on top of other widgets.
Expand Down Expand Up @@ -40,6 +41,14 @@ where
cursor_position: Point,
);

/// Applies an [`Operation`] to the [`Widget`].
fn operate(
&self,
_layout: Layout<'_>,
_operation: &mut dyn widget::Operation<Message>,
) {
}

/// Processes a runtime [`Event`].
///
/// It receives:
Expand Down
10 changes: 10 additions & 0 deletions native/src/overlay/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
use crate::renderer;
use crate::widget;
use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size, Vector};

/// A generic [`Overlay`].
Expand Down Expand Up @@ -102,6 +103,15 @@ where
self.overlay
.draw(renderer, theme, style, layout, cursor_position)
}

/// Applies an [`Operation`] to the [`Element`].
pub fn operate(
&self,
layout: Layout<'_>,
operation: &mut dyn widget::Operation<Message>,
) {
self.overlay.operate(layout, operation);
}
}

struct Map<'a, A, B, Renderer> {
Expand Down
18 changes: 18 additions & 0 deletions native/src/user_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
use crate::renderer;
use crate::widget;
use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};

/// A set of interactive graphical elements with a specific [`Layout`].
Expand Down Expand Up @@ -460,6 +461,23 @@ where
.unwrap_or(base_interaction)
}

/// Applies a [`widget::Operation`] to the [`UserInterface`].
pub fn operate(
&mut self,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
) {
self.root.operate(Layout::new(&self.base), operation);

if let Some(layout) = self.overlay.as_ref() {
if let Some(overlay) =
self.root.overlay(Layout::new(&self.base), renderer)
{
overlay.operate(Layout::new(layout), operation);
}
}
}

/// Relayouts and returns a new [`UserInterface`] using the provided
/// bounds.
pub fn relayout(self, bounds: Size, renderer: &mut Renderer) -> Self {
Expand Down
16 changes: 16 additions & 0 deletions native/src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod checkbox;
pub mod column;
pub mod container;
pub mod image;
pub mod operation;
pub mod pane_grid;
pub mod pick_list;
pub mod progress_bar;
Expand All @@ -31,6 +32,9 @@ pub mod text_input;
pub mod toggler;
pub mod tooltip;

mod action;
mod id;

#[doc(no_inline)]
pub use button::Button;
#[doc(no_inline)]
Expand Down Expand Up @@ -70,6 +74,10 @@ pub use toggler::Toggler;
#[doc(no_inline)]
pub use tooltip::Tooltip;

pub use action::Action;
pub use id::Id;
pub use operation::Operation;

use crate::event::{self, Event};
use crate::layout;
use crate::mouse;
Expand Down Expand Up @@ -132,6 +140,14 @@ where
viewport: &Rectangle,
);

/// Applies an [`Operation`] to the [`Widget`].
fn operate(
&mut self,
_layout: Layout<'_>,
_operation: &mut dyn Operation<Message>,
) {
}

/// Processes a runtime [`Event`].
///
/// It receives:
Expand Down
Loading

0 comments on commit 0ac98fd

Please sign in to comment.