summaryrefslogtreecommitdiffstats
path: root/core/src/shell.rs
diff options
context:
space:
mode:
authorLibravatar Héctor <hector@hecrj.dev>2024-11-13 17:08:26 +0100
committerLibravatar GitHub <noreply@github.com>2024-11-13 17:08:26 +0100
commita11fcf8f2dde551335c6f34788393fa2e8f8a362 (patch)
tree1e423c847a6505a2582bec19908866dba94c436d /core/src/shell.rs
parent42a2cb6d4f78343f43d6a68a28e5502d9426ed2c (diff)
parent28ec6df8f0ebf96966bee61caf5a325695314b7a (diff)
downloadiced-a11fcf8f2dde551335c6f34788393fa2e8f8a362.tar.gz
iced-a11fcf8f2dde551335c6f34788393fa2e8f8a362.tar.bz2
iced-a11fcf8f2dde551335c6f34788393fa2e8f8a362.zip
Merge pull request #2662 from iced-rs/reactive-rendering
Reactive Rendering
Diffstat (limited to 'core/src/shell.rs')
-rw-r--r--core/src/shell.rs47
1 files changed, 40 insertions, 7 deletions
diff --git a/core/src/shell.rs b/core/src/shell.rs
index 2952ceff..12ebbaa8 100644
--- a/core/src/shell.rs
+++ b/core/src/shell.rs
@@ -1,3 +1,5 @@
+use crate::event;
+use crate::time::Instant;
use crate::window;
/// A connection to the state of a shell.
@@ -9,6 +11,7 @@ use crate::window;
#[derive(Debug)]
pub struct Shell<'a, Message> {
messages: &'a mut Vec<Message>,
+ event_status: event::Status,
redraw_request: Option<window::RedrawRequest>,
is_layout_invalid: bool,
are_widgets_invalid: bool,
@@ -19,6 +22,7 @@ impl<'a, Message> Shell<'a, Message> {
pub fn new(messages: &'a mut Vec<Message>) -> Self {
Self {
messages,
+ event_status: event::Status::Ignored,
redraw_request: None,
is_layout_invalid: false,
are_widgets_invalid: false,
@@ -35,14 +39,37 @@ impl<'a, Message> Shell<'a, Message> {
self.messages.push(message);
}
- /// Requests a new frame to be drawn.
- pub fn request_redraw(&mut self, request: window::RedrawRequest) {
+ /// Marks the current event as captured. Prevents "event bubbling".
+ ///
+ /// A widget should capture an event when no ancestor should
+ /// handle it.
+ pub fn capture_event(&mut self) {
+ self.event_status = event::Status::Captured;
+ }
+
+ /// Returns the current [`event::Status`] of the [`Shell`].
+ pub fn event_status(&self) -> event::Status {
+ self.event_status
+ }
+
+ /// Returns whether the current event has been captured.
+ pub fn is_event_captured(&self) -> bool {
+ self.event_status == event::Status::Captured
+ }
+
+ /// Requests a new frame to be drawn as soon as possible.
+ pub fn request_redraw(&mut self) {
+ self.redraw_request = Some(window::RedrawRequest::NextFrame);
+ }
+
+ /// Requests a new frame to be drawn at the given [`Instant`].
+ pub fn request_redraw_at(&mut self, at: Instant) {
match self.redraw_request {
None => {
- self.redraw_request = Some(request);
+ self.redraw_request = Some(window::RedrawRequest::At(at));
}
- Some(current) if request < current => {
- self.redraw_request = Some(request);
+ Some(window::RedrawRequest::At(current)) if at < current => {
+ self.redraw_request = Some(window::RedrawRequest::At(at));
}
_ => {}
}
@@ -95,8 +122,12 @@ impl<'a, Message> Shell<'a, Message> {
pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
self.messages.extend(other.messages.drain(..).map(f));
- if let Some(at) = other.redraw_request {
- self.request_redraw(at);
+ if let Some(new) = other.redraw_request {
+ self.redraw_request = Some(
+ self.redraw_request
+ .map(|current| if current < new { current } else { new })
+ .unwrap_or(new),
+ );
}
self.is_layout_invalid =
@@ -104,5 +135,7 @@ impl<'a, Message> Shell<'a, Message> {
self.are_widgets_invalid =
self.are_widgets_invalid || other.are_widgets_invalid;
+
+ self.event_status = self.event_status.merge(other.event_status);
}
}