Continued implementation work on CloseWindowCommand and Commands in general.
This commit is contained in:
parent
fe598d84e4
commit
79142cf332
|
@ -58,6 +58,37 @@ macro_rules! command {
|
|||
pub fn notify(self, events: &mut $crate::event::Events, parameter: Option<std::rc::Rc<dyn std::any::Any>>) {
|
||||
<Self as $crate::event::Event>::notify(self, events, $crate::command::CommandArgs::now(parameter));
|
||||
}
|
||||
|
||||
/// Gets a read-only variable that indicates if the command has at least one enabled handler.
|
||||
///
|
||||
/// When this is `false` but [`has_handlers`](Self::has_handlers) is `true` the command can be considered
|
||||
/// *relevant* in the current app state but not enabled, associated command trigger widgets should be
|
||||
/// visible but disabled.
|
||||
#[inline]
|
||||
#[allow(unused)]
|
||||
pub fn enabled(self) -> $crate::var::ReadOnlyVar<bool, $crate::var::RcVar<bool>> {
|
||||
<Self as $crate::command::Command>::enabled(self)
|
||||
}
|
||||
|
||||
/// Gets a read-only variable that indicates if the command has at least one handler.
|
||||
///
|
||||
/// When this is `false` the command can be considered *not relevant* in the current app state
|
||||
/// and associated command trigger widgets can be hidden.
|
||||
#[inline]
|
||||
#[allow(unused)]
|
||||
pub fn has_handlers(self) -> $crate::var::ReadOnlyVar<bool, $crate::var::RcVar<bool>> {
|
||||
<Self as $crate::command::Command>::has_handlers(self)
|
||||
}
|
||||
|
||||
/// Create a new handle to this command.
|
||||
///
|
||||
/// A handle indicates that there is an active *handler* for the event, the handle can also
|
||||
/// be used to set the [`enabled`](Self::enabled) state.
|
||||
#[inline]
|
||||
#[allow(unused)]
|
||||
pub fn new_handle<Evs: $crate::event::WithEvents>(self, events: &mut Evs) -> $crate::command::CommandHandle {
|
||||
<Self as $crate::command::Command>::new_handle(self, events)
|
||||
}
|
||||
}
|
||||
impl $crate::event::Event for $Command {
|
||||
type Args = $crate::command::CommandArgs;
|
||||
|
@ -99,7 +130,7 @@ macro_rules! command {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn new_handle(self, events: &mut $crate::event::Events) -> $crate::command::CommandHandle {
|
||||
fn new_handle<Evs: $crate::event::WithEvents>(self, events: &mut Evs) -> $crate::command::CommandHandle {
|
||||
Self::COMMAND.with(|c| c.new_handle(events, &Self::COMMAND))
|
||||
}
|
||||
|
||||
|
@ -145,7 +176,7 @@ pub trait Command: Event<Args = CommandArgs> {
|
|||
///
|
||||
/// A handle indicates that there is an active *handler* for the event, the handle can also
|
||||
/// be used to set the [`enabled`](Self::enabled) state.
|
||||
fn new_handle(self, events: &mut Events) -> CommandHandle;
|
||||
fn new_handle<Evs: WithEvents>(self, events: &mut Evs) -> CommandHandle;
|
||||
|
||||
/// Gets a [`AnyCommand`] that represents this command.
|
||||
fn as_any(self) -> AnyCommand;
|
||||
|
@ -185,8 +216,8 @@ impl AnyCommand {
|
|||
|
||||
/// Schedule an event update for the command represented by `self`.
|
||||
#[inline]
|
||||
pub fn notify(self, events: &mut Events, args: CommandArgs) {
|
||||
Event::notify(self, events, args)
|
||||
pub fn notify(self, events: &mut Events, parameter: Option<Rc<dyn Any>>) {
|
||||
Event::notify(self, events, CommandArgs::now(parameter))
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for AnyCommand {
|
||||
|
@ -233,7 +264,7 @@ impl Command for AnyCommand {
|
|||
self.0.with(|c| c.has_handlers_value())
|
||||
}
|
||||
|
||||
fn new_handle(self, events: &mut Events) -> CommandHandle {
|
||||
fn new_handle<Evs: WithEvents>(self, events: &mut Evs) -> CommandHandle {
|
||||
self.0.with(|c| c.new_handle(events, self.0))
|
||||
}
|
||||
|
||||
|
@ -321,6 +352,14 @@ impl CommandHandle {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a dummy [`CommandHandle`] that is not connected to any command.
|
||||
pub fn dummy() -> Self {
|
||||
CommandHandle {
|
||||
handle: Handle::dummy(AtomicUsize::new(0)),
|
||||
local_enabled: Cell::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Drop for CommandHandle {
|
||||
fn drop(&mut self) {
|
||||
|
@ -361,10 +400,10 @@ impl CommandValue {
|
|||
self.enabled.set_ne(vars, self.enabled_value());
|
||||
}
|
||||
|
||||
pub fn new_handle(&self, events: &mut Events, key: &'static LocalKey<CommandValue>) -> CommandHandle {
|
||||
if self.registered.get() {
|
||||
pub fn new_handle<Evs: WithEvents>(&self, events: &mut Evs, key: &'static LocalKey<CommandValue>) -> CommandHandle {
|
||||
if !self.registered.get() {
|
||||
self.registered.set(true);
|
||||
events.register_command(AnyCommand(key));
|
||||
events.with_events(|e| e.register_command(AnyCommand(key)));
|
||||
}
|
||||
CommandHandle {
|
||||
handle: self.handle.reanimate(),
|
||||
|
|
|
@ -994,6 +994,14 @@ impl Events {
|
|||
retain
|
||||
});
|
||||
}
|
||||
|
||||
/// Commands that had handles generated in this app.
|
||||
///
|
||||
/// When [`Command::new_handle`] is called for the first time in an app, the command gets regitered here.
|
||||
#[inline]
|
||||
pub fn commands(&self) -> impl Iterator<Item = AnyCommand> + '_ {
|
||||
self.commands.values().copied()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a type that can provide access to a [`Events`] inside the window of function call.
|
||||
|
|
|
@ -804,6 +804,15 @@ impl AppExtension for GestureManager {
|
|||
args.target.clone(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
let command = ctx
|
||||
.events
|
||||
.commands()
|
||||
.find(|c| c.enabled_value() && c.shortcut().get(ctx.vars).0.contains(&args.shortcut));
|
||||
if let Some(command) = command {
|
||||
command.notify(ctx.events, None);
|
||||
args.stop_propagation()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -717,8 +717,8 @@ where
|
|||
/// the input is the same syntax.
|
||||
///
|
||||
/// The handler generates a future for each event, the future is polled immediately if it does not finish it is scheduled
|
||||
/// to update in [`on_pre_update`](crate::context::Updates::on_pre_update). Note that this means
|
||||
/// [`stop_propagation`](crate::event::EventArgs::stop_propagation) can only be meaningfully called before the first `.await`,
|
||||
/// to update in [`on_pre_update`](crate::context::Updates::on_pre_update). Note that this means
|
||||
/// [`stop_propagation`](crate::event::EventArgs::stop_propagation) can only be meaningfully called before the first `.await`,
|
||||
/// after the event has already propagated.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
//!
|
||||
//! # Handlers
|
||||
//!
|
||||
//! A property event handler is any type that implements [`WidgetHandler`](crate::core::handler::WidgetHandler), usually they are a
|
||||
//! closure declared with the assistance of a macro, the widget handler macros are [`hn!`](crate::core::handler::hn!),
|
||||
//! [`hn_once!`](crate::core::handler::hn_once!), [`async_hn!`](crate::core::handler::async_hn!) and
|
||||
//! A property event handler is any type that implements [`WidgetHandler`](crate::core::handler::WidgetHandler), usually they are a
|
||||
//! closure declared with the assistance of a macro, the widget handler macros are [`hn!`](crate::core::handler::hn!),
|
||||
//! [`hn_once!`](crate::core::handler::hn_once!), [`async_hn!`](crate::core::handler::async_hn!) and
|
||||
//! [`async_hn_once!`](crate::core::handler::async_hn_once!).
|
||||
//!
|
||||
//! ```
|
||||
|
|
|
@ -24,6 +24,11 @@ use crate::properties::events::window::*;
|
|||
/// See [`run_window`](crate::core::window::AppRunWindow::run_window) for more details.
|
||||
#[widget($crate::widgets::window)]
|
||||
pub mod window {
|
||||
use zero_ui_core::window::WindowsExt;
|
||||
|
||||
use crate::core::command::CommandHandle;
|
||||
use crate::properties::commands::CloseWindowCommand;
|
||||
|
||||
use super::*;
|
||||
|
||||
inherit!(container);
|
||||
|
@ -259,6 +264,27 @@ pub mod window {
|
|||
on_pre_redraw: impl FnMut(&mut RedrawArgs) + 'static,
|
||||
on_redraw: impl FnMut(&mut RedrawArgs) + 'static,
|
||||
) -> Window {
|
||||
struct OnCloseWindowNode<C: UiNode> {
|
||||
child: C,
|
||||
handle: CommandHandle,
|
||||
}
|
||||
#[impl_ui_node(child)]
|
||||
impl<C: UiNode> UiNode for OnCloseWindowNode<C> {
|
||||
fn init(&mut self, ctx: &mut WidgetContext) {
|
||||
self.handle = CloseWindowCommand.new_handle(ctx);
|
||||
self.handle.set_enabled(true);
|
||||
self.child.init(ctx)
|
||||
}
|
||||
fn event<A: EventUpdateArgs>(&mut self, ctx: &mut WidgetContext, args: &A) {
|
||||
if let Some(args) = CloseWindowCommand.update(args) {
|
||||
let _ = ctx.services.windows().close(ctx.path.window_id());
|
||||
self.child.event(ctx, args)
|
||||
} else {
|
||||
self.child.event(ctx, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
let child = OnCloseWindowNode{child, handle: CommandHandle::dummy()};
|
||||
Window::new(
|
||||
root_id,
|
||||
start_position,
|
||||
|
|
Loading…
Reference in New Issue