From 744a40823731bc673f0edf3d1a56c8825e6dc4c8 Mon Sep 17 00:00:00 2001 From: Kaur Kuut Date: Sun, 17 May 2020 16:03:44 +0300 Subject: [PATCH 1/2] Add the request_timer method to LifeCycleCtx. --- CHANGELOG.md | 2 ++ druid/src/contexts.rs | 13 +++++++++++++ druid/src/core.rs | 12 +++++++++++- druid/src/window.rs | 30 ++++++++++++++++++++---------- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0ad27a4e6..f069f8add5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i - `MouseButtons` to `MouseEvent` to track which buttons are being held down during an event. ([#843] by [@xStrom]) - `Env` and `Key` gained methods for inspecting an `Env` at runtime ([#880] by [@Zarenor]) - `UpdateCtx::request_timer` and `UpdateCtx::request_anim_frame`. ([#898] by [@finnerale]) +- `LifeCycleCtx::request_timer`. ([#954] by [@xStrom]) - `UpdateCtx::size` and `LifeCycleCtx::size`. ([#917] by [@jneem]) - `WidgetExt::debug_widget_id`, for displaying widget ids on hover. ([#876] by [@cmyr]) - `im` feature, with `Data` support for the [`im` crate](https://docs.rs/im/) collections. ([#924] by [@cmyr]) @@ -196,6 +197,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i [#943]: https://github.com/xi-editor/druid/pull/943 [#951]: https://github.com/xi-editor/druid/pull/951 [#953]: https://github.com/xi-editor/druid/pull/953 +[#954]: https://github.com/xi-editor/druid/pull/954 ## [0.5.0] - 2020-04-01 diff --git a/druid/src/contexts.rs b/druid/src/contexts.rs index 6cf23df7e6..af217f9d79 100644 --- a/druid/src/contexts.rs +++ b/druid/src/contexts.rs @@ -62,6 +62,7 @@ pub struct LifeCycleCtx<'a> { pub(crate) command_queue: &'a mut CommandQueue, pub(crate) base_state: &'a mut BaseState, pub(crate) window_id: WindowId, + pub(crate) window: &'a WindowHandle, } /// A mutable context provided to data update methods of widgets. @@ -91,6 +92,7 @@ pub struct LayoutCtx<'a, 'b: 'a> { pub(crate) base_state: &'a mut BaseState, pub(crate) text_factory: &'a mut Text<'b>, pub(crate) window_id: WindowId, + pub(crate) window: &'a WindowHandle, pub(crate) mouse_pos: Option, } @@ -548,6 +550,17 @@ impl<'a> LifeCycleCtx<'a> { self.request_paint(); } + /// Request a timer event. + /// + /// The return value is a token, which can be used to associate the + /// request with the event. + pub fn request_timer(&mut self, deadline: Duration) -> TimerToken { + self.base_state.request_timer = true; + let timer_token = self.window.request_timer(deadline); + self.base_state.add_timer(timer_token); + timer_token + } + /// The layout size. /// /// This is the layout size as ultimately determined by the parent diff --git a/druid/src/core.rs b/druid/src/core.rs index 2c56950d54..e22318de3e 100644 --- a/druid/src/core.rs +++ b/druid/src/core.rs @@ -24,7 +24,7 @@ use crate::piet::{ use crate::{ BoxConstraints, Color, Command, Data, Env, Event, EventCtx, InternalEvent, InternalLifeCycle, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx, Region, Target, TimerToken, UpdateCtx, Widget, - WidgetId, WindowId, + WidgetId, WindowHandle, WindowId, }; /// Our queue type @@ -224,6 +224,7 @@ impl> WidgetPod { ctx.command_queue, &mut self.state, ctx.window_id, + ctx.window, layout_rect, ctx.mouse_pos, data, @@ -334,6 +335,7 @@ impl> WidgetPod { command_queue: &mut CommandQueue, child_state: &mut BaseState, window_id: WindowId, + window: &WindowHandle, rect: Rect, mouse_pos: Option, data: &T, @@ -350,6 +352,7 @@ impl> WidgetPod { command_queue, base_state: child_state, window_id, + window, }; child.lifecycle(&mut child_ctx, &hot_changed_event, data, env); // if hot changes and we're showing widget ids, always repaint @@ -515,6 +518,7 @@ impl> WidgetPod { command_queue: ctx.command_queue, base_state: &mut self.state, window_id: ctx.window_id, + window: ctx.window, text_factory: ctx.text_factory, mouse_pos: child_mouse_pos, }; @@ -600,6 +604,7 @@ impl> WidgetPod { child_ctx.command_queue, child_ctx.base_state, child_ctx.window_id, + child_ctx.window, rect, None, data, @@ -647,6 +652,7 @@ impl> WidgetPod { child_ctx.command_queue, child_ctx.base_state, child_ctx.window_id, + child_ctx.window, rect, Some(mouse_event.pos), data, @@ -663,6 +669,7 @@ impl> WidgetPod { child_ctx.command_queue, child_ctx.base_state, child_ctx.window_id, + child_ctx.window, rect, Some(mouse_event.pos), data, @@ -679,6 +686,7 @@ impl> WidgetPod { child_ctx.command_queue, child_ctx.base_state, child_ctx.window_id, + child_ctx.window, rect, Some(mouse_event.pos), data, @@ -839,6 +847,7 @@ impl> WidgetPod { command_queue: ctx.command_queue, base_state: &mut self.state, window_id: ctx.window_id, + window: ctx.window, }; if recurse { @@ -1005,6 +1014,7 @@ mod tests { command_queue: &mut command_queue, base_state: &mut state, window_id: WindowId::next(), + window: &WindowHandle::default(), }; let env = Env::default(); diff --git a/druid/src/window.rs b/druid/src/window.rs index 92cd4c894b..4db972a544 100644 --- a/druid/src/window.rs +++ b/druid/src/window.rs @@ -250,16 +250,17 @@ impl Window { env: &Env, process_commands: bool, ) { - let mut base_state = BaseState::new(self.root.id()); - let mut ctx = LifeCycleCtx { - command_queue: queue, - window_id: self.id, - base_state: &mut base_state, - }; - if let LifeCycle::AnimFrame(_) = event { - self.do_anim_frame(&mut ctx, data, env) + self.do_anim_frame(queue, data, env) } else { + let mut base_state = BaseState::new(self.root.id()); + let mut ctx = LifeCycleCtx { + command_queue: queue, + window_id: self.id, + window: &self.handle, + base_state: &mut base_state, + }; + self.root.lifecycle(&mut ctx, event, data, env); } @@ -267,7 +268,15 @@ impl Window { } /// AnimFrame has special logic, so we implement it separately. - fn do_anim_frame(&mut self, ctx: &mut LifeCycleCtx, data: &T, env: &Env) { + fn do_anim_frame(&mut self, queue: &mut CommandQueue, data: &T, env: &Env) { + let mut base_state = BaseState::new(self.root.id()); + let mut ctx = LifeCycleCtx { + command_queue: queue, + window_id: self.id, + window: &self.handle, + base_state: &mut base_state, + }; + // TODO: this calculation uses wall-clock time of the paint call, which // potentially has jitter. // @@ -277,7 +286,7 @@ impl Window { let elapsed_ns = last.map(|t| now.duration_since(t).as_nanos()).unwrap_or(0) as u64; let event = LifeCycle::AnimFrame(elapsed_ns); - self.root.lifecycle(ctx, &event, data, env); + self.root.lifecycle(&mut ctx, &event, data, env); if ctx.base_state.request_anim { self.last_anim = Some(now); } @@ -340,6 +349,7 @@ impl Window { base_state: &mut base_state, text_factory: piet.text(), window_id: self.id, + window: &self.handle, mouse_pos: self.last_mouse_pos, }; let bc = BoxConstraints::tight(self.size); From 40e6832e044e89430844a4f484d72da6f740a9b7 Mon Sep 17 00:00:00 2001 From: Kaur Kuut Date: Sun, 17 May 2020 16:59:34 +0300 Subject: [PATCH 2/2] Fix merge mistake. --- druid/src/core.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/druid/src/core.rs b/druid/src/core.rs index e22318de3e..6322adf91f 100644 --- a/druid/src/core.rs +++ b/druid/src/core.rs @@ -213,6 +213,7 @@ impl> WidgetPod { command_queue: ctx.command_queue, base_state: &mut self.state, window_id: ctx.window_id, + window: ctx.window, }; let size_event = LifeCycle::Size(new_size); self.inner.lifecycle(&mut child_ctx, &size_event, data, env); @@ -703,6 +704,7 @@ impl> WidgetPod { child_ctx.command_queue, child_ctx.base_state, child_ctx.window_id, + child_ctx.window, rect, Some(mouse_event.pos), data,