Skip to content

Commit

Permalink
exec_after return TimerToken
Browse files Browse the repository at this point in the history
  • Loading branch information
dzhou121 committed Aug 19, 2023
1 parent 3c74df6 commit de4713b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 25 deletions.
21 changes: 14 additions & 7 deletions src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use std::time::Duration;

use glazier::{
kurbo::{Point, Vec2},
FileDialogOptions, FileInfo,
FileDialogOptions, FileInfo, TimerToken,
};

use crate::{
app_handle::{get_current_view, UpdateMessage, UPDATE_MESSAGES},
app_handle::{get_current_view, get_current_window_handle, UpdateMessage, UPDATE_MESSAGES},
menu::Menu,
};

Expand Down Expand Up @@ -35,11 +35,18 @@ pub fn update_window_scale(window_scale: f64) {
add_update_message(UpdateMessage::WindowScale(window_scale));
}

pub fn exec_after(deadline: Duration, action: impl FnOnce() + 'static) {
add_update_message(UpdateMessage::RequestTimer {
deadline,
action: Box::new(action),
});
pub fn exec_after(deadline: Duration, action: impl FnOnce(TimerToken) + 'static) -> TimerToken {
let handle = get_current_window_handle();
if let Some(handle) = handle {
let token = handle.request_timer(deadline);
add_update_message(UpdateMessage::RequestTimer {
token,
action: Box::new(action),
});
token
} else {
TimerToken::INVALID
}
}

pub fn open_file(
Expand Down
29 changes: 22 additions & 7 deletions src/app_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use floem_reactive::{with_scope, Scope};
use floem_renderer::Renderer;
use glazier::kurbo::{Affine, Point, Rect, Size, Vec2};
use glazier::{
FileDialogOptions, FileDialogToken, FileInfo, Scale, TimerToken, WinHandler, WindowState,
FileDialogOptions, FileDialogToken, FileInfo, Scale, TimerToken, WinHandler, WindowHandle,
WindowState,
};

use crate::menu::Menu;
Expand All @@ -39,6 +40,7 @@ thread_local! {
/// It stores the active view handle, so that when you dispatch an action, it knows
/// which view handle it submitted to
pub(crate) static CURRENT_RUNNING_VIEW_HANDLE: RefCell<Id> = RefCell::new(Id::next());
pub(crate) static WINDOW_HANDLES: RefCell<HashMap<Id, WindowHandle>> = Default::default();
}

pub type FileDialogs = HashMap<FileDialogToken, Box<dyn Fn(Option<FileInfo>)>>;
Expand Down Expand Up @@ -185,8 +187,8 @@ pub enum UpdateMessage {
file_info_action: Box<dyn Fn(Option<FileInfo>)>,
},
RequestTimer {
deadline: std::time::Duration,
action: Box<dyn FnOnce()>,
token: TimerToken,
action: Box<dyn FnOnce(TimerToken)>,
},
Animation {
id: Id,
Expand Down Expand Up @@ -272,7 +274,7 @@ impl<V: View> AppHandle<V> {
let id = self.app_state.ids_with_anim_in_progress().get(0).cloned();

if let Some(id) = id {
exec_after(Duration::from_millis(1), move || {
exec_after(Duration::from_millis(1), move |_| {
id.request_layout();
});
}
Expand Down Expand Up @@ -601,8 +603,8 @@ impl<V: View> AppHandle<V> {
self.file_dialogs.insert(token, file_info_action);
}
}
UpdateMessage::RequestTimer { deadline, action } => {
cx.app_state.request_timer(deadline, action);
UpdateMessage::RequestTimer { token, action } => {
cx.app_state.request_timer(token, action);
}
UpdateMessage::Animation { id, animation } => {
cx.app_state.animated.insert(id);
Expand Down Expand Up @@ -914,11 +916,21 @@ pub(crate) fn set_current_view(id: Id) {
});
}

pub(crate) fn get_current_window_handle() -> Option<WindowHandle> {
let view_id = get_current_view();
WINDOW_HANDLES.with(|window_handles| window_handles.borrow().get(&view_id).cloned())
}

impl<V: View> WinHandler for AppHandle<V> {
fn connect(&mut self, handle: &glazier::WindowHandle) {
WINDOWS.with(|windows| {
windows.borrow_mut().insert(self.window_id, handle.clone());
});
WINDOW_HANDLES.with(|window_handles| {
window_handles
.borrow_mut()
.insert(self.view.id(), handle.clone());
});
self.app_state.handle = handle.clone();
self.paint_state.connect(handle);
self.handle = handle.clone();
Expand Down Expand Up @@ -1035,7 +1047,7 @@ impl<V: View> WinHandler for AppHandle<V> {
fn timer(&mut self, token: TimerToken) {
set_current_view(self.view.id());
if let Some(action) = self.app_state.timers.remove(&token) {
action();
action(token);
}
self.process_update();
}
Expand Down Expand Up @@ -1063,6 +1075,9 @@ impl<V: View> WinHandler for AppHandle<V> {
windows.remove(&self.window_id);
windows.len()
});
WINDOW_HANDLES.with(|window_handles| {
window_handles.borrow_mut().remove(&self.view.id());
});
self.scope.dispose();
EXT_EVENT_HANDLER.handle.lock().remove(&self.view.id());
EXT_EVENT_HANDLER.queue.lock().remove(&self.view.id());
Expand Down
5 changes: 2 additions & 3 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ pub struct AppState {
pub(crate) last_cursor: glazier::Cursor,
pub(crate) keyboard_navigation: bool,
pub(crate) context_menu: HashMap<u32, Box<dyn Fn()>>,
pub(crate) timers: HashMap<TimerToken, Box<dyn FnOnce()>>,
pub(crate) timers: HashMap<TimerToken, Box<dyn FnOnce(TimerToken)>>,
}

impl Default for AppState {
Expand Down Expand Up @@ -444,8 +444,7 @@ impl AppState {
}
}

pub(crate) fn request_timer(&mut self, deadline: Duration, action: Box<dyn FnOnce()>) {
let token = self.handle.request_timer(deadline);
pub(crate) fn request_timer(&mut self, token: TimerToken, action: Box<dyn FnOnce(TimerToken)>) {
self.timers.insert(token, action);
}

Expand Down
11 changes: 4 additions & 7 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ use glazier::kurbo::{Affine, Circle, Line, Point, Rect, Size};
use taffy::prelude::Node;

use crate::{
action::show_context_menu,
action::{exec_after, show_context_menu},
context::{AppState, DragState, EventCx, LayoutCx, PaintCx, UpdateCx},
event::{Event, EventListener},
id::Id,
Expand Down Expand Up @@ -669,12 +669,9 @@ pub trait View {
let elapsed = released_at.elapsed().as_millis() as f64;
if elapsed < LIMIT {
offset_scale = Some(1.0 - elapsed / LIMIT);
cx.app_state.request_timer(
std::time::Duration::from_millis(8),
Box::new(move || {
id.request_paint();
}),
);
exec_after(std::time::Duration::from_millis(8), move |_| {
id.request_paint();
});
} else {
drag_set_to_none = true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/views/text_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ impl View for TextInput {
let id = self.id();
exec_after(
Duration::from_millis(CURSOR_BLINK_INTERVAL_MS),
Box::new(move || {
Box::new(move |_| {
id.request_paint();
}),
);
Expand Down

0 comments on commit de4713b

Please sign in to comment.