Wire up events and fix synthetic dragging
Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
04665800c0
commit
0c59937a65
4 changed files with 74 additions and 43 deletions
|
@ -467,14 +467,14 @@ impl MutableAppContext {
|
||||||
pub fn dispatch_action(
|
pub fn dispatch_action(
|
||||||
&mut self,
|
&mut self,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
responder_chain: &[usize],
|
path: &[usize],
|
||||||
name: &str,
|
name: &str,
|
||||||
arg: &dyn Any,
|
arg: &dyn Any,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.pending_flushes += 1;
|
self.pending_flushes += 1;
|
||||||
let mut halted_dispatch = false;
|
let mut halted_dispatch = false;
|
||||||
|
|
||||||
for view_id in responder_chain.iter().rev() {
|
for view_id in path.iter().rev() {
|
||||||
if let Some(mut view) = self
|
if let Some(mut view) = self
|
||||||
.ctx
|
.ctx
|
||||||
.windows
|
.windows
|
||||||
|
@ -635,6 +635,29 @@ impl MutableAppContext {
|
||||||
self,
|
self,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut app = self.upgrade();
|
||||||
|
let presenter = presenter.clone();
|
||||||
|
window.on_event(Box::new(move |event, window| {
|
||||||
|
log::info!("event {:?}", event);
|
||||||
|
app.update(|ctx| {
|
||||||
|
ctx.pending_flushes += 1;
|
||||||
|
let actions = presenter
|
||||||
|
.borrow_mut()
|
||||||
|
.dispatch_event(event, ctx.downgrade());
|
||||||
|
for action in actions {
|
||||||
|
ctx.dispatch_action(
|
||||||
|
window_id,
|
||||||
|
&action.path,
|
||||||
|
action.name,
|
||||||
|
action.arg.as_ref(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ctx.flush_effects();
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut app = self.upgrade();
|
let mut app = self.upgrade();
|
||||||
let presenter = presenter.clone();
|
let presenter = presenter.clone();
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub enum Foreground {
|
||||||
Test(smol::LocalExecutor<'static>),
|
Test(smol::LocalExecutor<'static>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
#[pin_project(project = ForegroundTaskProject)]
|
#[pin_project(project = ForegroundTaskProject)]
|
||||||
pub enum ForegroundTask<T> {
|
pub enum ForegroundTask<T> {
|
||||||
Platform(#[pin] async_task::Task<T>),
|
Platform(#[pin] async_task::Task<T>),
|
||||||
|
|
|
@ -31,8 +31,8 @@ use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
mem, ptr,
|
mem, ptr,
|
||||||
rc::Rc,
|
rc::{Rc, Weak},
|
||||||
time::{Duration, Instant},
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{geometry::RectFExt, renderer::Renderer};
|
use super::{geometry::RectFExt, renderer::Renderer};
|
||||||
|
@ -330,24 +330,33 @@ extern "C" fn dealloc_view(this: &Object, _: Sel) {
|
||||||
|
|
||||||
extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let mut window_state_borrow = window_state.as_ref().borrow_mut();
|
let weak_window_state = Rc::downgrade(&window_state);
|
||||||
|
let mut window_state = window_state.as_ref().borrow_mut();
|
||||||
|
|
||||||
let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
|
let event = unsafe { Event::from_native(native_event, Some(window_state.size().y())) };
|
||||||
|
|
||||||
if let Some(event) = event {
|
if let Some(event) = event {
|
||||||
match event {
|
match event {
|
||||||
Event::LeftMouseDragged { position } => {
|
Event::LeftMouseDragged { position } => {
|
||||||
schedule_synthetic_drag(&&window_state, position)
|
window_state.synthetic_drag_counter += 1;
|
||||||
|
window_state
|
||||||
|
.executor
|
||||||
|
.spawn(synthetic_drag(
|
||||||
|
weak_window_state,
|
||||||
|
window_state.synthetic_drag_counter,
|
||||||
|
position,
|
||||||
|
))
|
||||||
|
.detach();
|
||||||
}
|
}
|
||||||
Event::LeftMouseUp { .. } => {
|
Event::LeftMouseUp { .. } => {
|
||||||
post_inc(&mut window_state_borrow.synthetic_drag_counter);
|
window_state.synthetic_drag_counter += 1;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut callback) = window_state_borrow.event_callback.take() {
|
if let Some(mut callback) = window_state.event_callback.take() {
|
||||||
callback(event, &mut *window_state_borrow);
|
callback(event, &mut *window_state);
|
||||||
window_state_borrow.event_callback = Some(callback);
|
window_state.event_callback = Some(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,30 +459,23 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schedule_synthetic_drag(window_state: &Rc<RefCell<WindowState>>, position: Vector2F) {
|
async fn synthetic_drag(
|
||||||
let weak_window_state = Rc::downgrade(window_state);
|
window_state: Weak<RefCell<WindowState>>,
|
||||||
let mut window_state = window_state.as_ref().borrow_mut();
|
drag_id: usize,
|
||||||
|
position: Vector2F,
|
||||||
let drag_id = post_inc(&mut window_state.synthetic_drag_counter);
|
) {
|
||||||
let instant = Instant::now() + Duration::from_millis(16);
|
loop {
|
||||||
|
Timer::after(Duration::from_millis(16)).await;
|
||||||
window_state
|
if let Some(window_state) = window_state.upgrade() {
|
||||||
.executor
|
let mut window_state = window_state.borrow_mut();
|
||||||
.spawn(async move {
|
if window_state.synthetic_drag_counter == drag_id {
|
||||||
Timer::at(instant).await;
|
if let Some(mut callback) = window_state.event_callback.take() {
|
||||||
if let Some(window_state) = weak_window_state.upgrade() {
|
callback(Event::LeftMouseDragged { position }, &mut *window_state);
|
||||||
let mut window_state_borrow = window_state.as_ref().borrow_mut();
|
window_state.event_callback = Some(callback);
|
||||||
if window_state_borrow.synthetic_drag_counter == drag_id {
|
|
||||||
if let Some(mut callback) = window_state_borrow.event_callback.take() {
|
|
||||||
schedule_synthetic_drag(&window_state, position);
|
|
||||||
callback(
|
|
||||||
Event::LeftMouseDragged { position },
|
|
||||||
&mut *window_state_borrow,
|
|
||||||
);
|
|
||||||
window_state_borrow.event_callback = Some(callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.detach();
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,11 +109,7 @@ impl Presenter {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch_event(
|
pub fn dispatch_event(&self, event: Event, app: &AppContext) -> Vec<ActionToDispatch> {
|
||||||
&self,
|
|
||||||
event: Event,
|
|
||||||
app: &AppContext,
|
|
||||||
) -> Vec<(usize, &'static str, Box<dyn Any>)> {
|
|
||||||
let mut event_ctx = EventContext {
|
let mut event_ctx = EventContext {
|
||||||
rendered_views: &self.rendered_views,
|
rendered_views: &self.rendered_views,
|
||||||
actions: Vec::new(),
|
actions: Vec::new(),
|
||||||
|
@ -128,6 +124,12 @@ impl Presenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ActionToDispatch {
|
||||||
|
pub path: Vec<usize>,
|
||||||
|
pub name: &'static str,
|
||||||
|
pub arg: Box<dyn Any>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct LayoutContext<'a> {
|
pub struct LayoutContext<'a> {
|
||||||
rendered_views: &'a mut HashMap<usize, Box<dyn Element>>,
|
rendered_views: &'a mut HashMap<usize, Box<dyn Element>>,
|
||||||
parents: &'a mut HashMap<usize, usize>,
|
parents: &'a mut HashMap<usize, usize>,
|
||||||
|
@ -184,7 +186,7 @@ impl<'a> PaintContext<'a> {
|
||||||
|
|
||||||
pub struct EventContext<'a> {
|
pub struct EventContext<'a> {
|
||||||
rendered_views: &'a HashMap<usize, Box<dyn Element>>,
|
rendered_views: &'a HashMap<usize, Box<dyn Element>>,
|
||||||
actions: Vec<(usize, &'static str, Box<dyn Any>)>,
|
actions: Vec<ActionToDispatch>,
|
||||||
pub font_cache: &'a FontCache,
|
pub font_cache: &'a FontCache,
|
||||||
pub text_layout_cache: &'a TextLayoutCache,
|
pub text_layout_cache: &'a TextLayoutCache,
|
||||||
view_stack: Vec<usize>,
|
view_stack: Vec<usize>,
|
||||||
|
@ -208,8 +210,11 @@ impl<'a> EventContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch_action<A: 'static + Any>(&mut self, name: &'static str, arg: A) {
|
pub fn dispatch_action<A: 'static + Any>(&mut self, name: &'static str, arg: A) {
|
||||||
self.actions
|
self.actions.push(ActionToDispatch {
|
||||||
.push((*self.view_stack.last().unwrap(), name, Box::new(arg)));
|
path: self.view_stack.clone(),
|
||||||
|
name,
|
||||||
|
arg: Box::new(arg),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue