Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add defaults for View trait methods #147

Merged
merged 1 commit into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 87 additions & 12 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@
pub trait View {
fn id(&self) -> Id;

/// This method walk over children and must be implemented if the view has any children.
/// It should return children back to front and should stop if `_for_each` returns `true`.
fn for_each_child<'a>(&'a self, _for_each: &mut dyn FnMut(&'a dyn View) -> bool) {}

Check warning on line 116 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L116

Added line #L116 was not covered by tests

/// This method walk over children and must be implemented if the view has any children.
/// It should return children back to front and should stop if `_for_each` returns `true`.
fn for_each_child_mut<'a>(&'a mut self, _for_each: &mut dyn FnMut(&'a mut dyn View) -> bool) {}

Check warning on line 120 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L120

Added line #L120 was not covered by tests

fn view_style(&self) -> Option<Style> {
None
}
Expand All @@ -119,14 +127,50 @@
None
}

fn child(&self, id: Id) -> Option<&dyn View>;
fn child(&self, id: Id) -> Option<&dyn View> {
let mut result = None;
self.for_each_child(&mut |view| {
if view.id() == id {
result = Some(view);
true

Check warning on line 135 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L130-L135

Added lines #L130 - L135 were not covered by tests
} else {
false

Check warning on line 137 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L137

Added line #L137 was not covered by tests
}
});
result
}

Check warning on line 141 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L139-L141

Added lines #L139 - L141 were not covered by tests

fn child_mut(&mut self, id: Id) -> Option<&mut dyn View>;
fn child_mut(&mut self, id: Id) -> Option<&mut dyn View> {
let mut result = None;
self.for_each_child_mut(&mut |view| {
if view.id() == id {
result = Some(view);
true

Check warning on line 148 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L143-L148

Added lines #L143 - L148 were not covered by tests
} else {
false

Check warning on line 150 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L150

Added line #L150 was not covered by tests
}
});
result
}

Check warning on line 154 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L152-L154

Added lines #L152 - L154 were not covered by tests

fn children(&self) -> Vec<&dyn View>;
fn children(&self) -> Vec<&dyn View> {
let mut result = Vec::new();
self.for_each_child(&mut |view| {
result.push(view);
false
});
result
}

Check warning on line 163 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L156-L163

Added lines #L156 - L163 were not covered by tests

/// At the moment, this is used only to build the debug tree.
fn children_mut(&mut self) -> Vec<&mut dyn View>;
fn children_mut(&mut self) -> Vec<&mut dyn View> {
let mut result = Vec::new();
self.for_each_child_mut(&mut |view| {
result.push(view);
false
});
result
}

Check warning on line 173 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L166-L173

Added lines #L166 - L173 were not covered by tests

fn debug_name(&self) -> std::borrow::Cow<'static, str> {
core::any::type_name::<Self>().into()
Expand All @@ -141,7 +185,9 @@
///
/// You are in charge of downcasting the state to the expected type and you're required to return
/// indicating if you'd like a layout or paint pass to be scheduled.
fn update(&mut self, cx: &mut UpdateCx, state: Box<dyn Any>) -> ChangeFlags;
fn update(&mut self, _cx: &mut UpdateCx, _state: Box<dyn Any>) -> ChangeFlags {
ChangeFlags::empty()
}

Check warning on line 190 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L188-L190

Added lines #L188 - L190 were not covered by tests

/// Use this method to style the view's children.
fn style(&mut self, cx: &mut StyleCx<'_>) {
Expand All @@ -152,23 +198,52 @@

/// Use this method to layout the view's children.
/// Usually you'll do this by calling `LayoutCx::layout_node`
fn layout(&mut self, cx: &mut LayoutCx) -> Node;
fn layout(&mut self, cx: &mut LayoutCx) -> Node {
cx.layout_node(self.id(), true, |cx| {
let mut nodes = Vec::new();
self.for_each_child_mut(&mut |child| {
nodes.push(cx.layout_view(child));
false
});
nodes
})
}

Check warning on line 210 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L201-L210

Added lines #L201 - L210 were not covered by tests

/// You must implement this if your view has children.
///
/// Responsible for computing the layout of the view's children.
fn compute_layout(&mut self, _cx: &mut LayoutCx) -> Option<Rect> {
None
fn compute_layout(&mut self, cx: &mut LayoutCx) -> Option<Rect> {
let mut layout_rect: Option<Rect> = None;
self.for_each_child_mut(&mut |child| {
let child_layout = cx.compute_view_layout(child);
if let Some(rect) = layout_rect {
layout_rect = Some(rect.union(child_layout));
} else {
layout_rect = Some(child_layout);
}
false
});
layout_rect

Check warning on line 224 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L213-L224

Added lines #L213 - L224 were not covered by tests
}

/// Implement this to handle events and to pass them down to children
///
/// Return true to stop the event from propagating to other views
fn event(&mut self, cx: &mut EventCx, id_path: Option<&[Id]>, event: Event) -> bool;
fn event(&mut self, cx: &mut EventCx, id_path: Option<&[Id]>, event: Event) -> bool {
let mut handled = false;
self.for_each_child_mut(&mut |child| {
handled |= cx.view_event(child, id_path, event.clone());
Copy link
Contributor

@dzhou121 dzhou121 Nov 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably need to break out if the event is handled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning true breaks the loop here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right

handled
});
handled
}

Check warning on line 237 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L230-L237

Added lines #L230 - L237 were not covered by tests

/// `View`-specific implementation. Will be called in the [`View::paint_main`] entry point method.
/// Usually you'll call the child `View::paint_main` method. But you might also draw text, adjust the offset, clip or draw text.
fn paint(&mut self, cx: &mut PaintCx);
fn paint(&mut self, cx: &mut PaintCx) {
self.for_each_child_mut(&mut |child| {
cx.paint_view(child);
false
});
}

Check warning on line 246 in src/view.rs

View check run for this annotation

Codecov / codecov/patch

src/view.rs#L241-L246

Added lines #L241 - L246 were not covered by tests
}

pub(crate) fn paint_bg(
Expand Down
46 changes: 5 additions & 41 deletions src/views/clip.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use kurbo::{Rect, Size};

use crate::{
id::Id,
view::{ChangeFlags, View},
};
use crate::{id::Id, view::View};

pub struct Clip {
id: Id,
Expand All @@ -22,42 +19,18 @@
self.id
}

fn child(&self, id: Id) -> Option<&dyn View> {
if self.child.id() == id {
Some(&self.child)
} else {
None
}
}

fn child_mut(&mut self, id: Id) -> Option<&mut dyn View> {
if self.child.id() == id {
Some(&mut self.child)
} else {
None
}
fn for_each_child<'a>(&'a self, for_each: &mut dyn FnMut(&'a dyn View) -> bool) {
for_each(&self.child);

Check warning on line 23 in src/views/clip.rs

View check run for this annotation

Codecov / codecov/patch

src/views/clip.rs#L22-L23

Added lines #L22 - L23 were not covered by tests
}

fn children(&self) -> Vec<&dyn View> {
vec![&self.child]
}

fn children_mut(&mut self) -> Vec<&mut dyn View> {
vec![&mut self.child]
fn for_each_child_mut<'a>(&'a mut self, for_each: &mut dyn FnMut(&'a mut dyn View) -> bool) {
for_each(&mut self.child);

Check warning on line 27 in src/views/clip.rs

View check run for this annotation

Codecov / codecov/patch

src/views/clip.rs#L26-L27

Added lines #L26 - L27 were not covered by tests
}

fn debug_name(&self) -> std::borrow::Cow<'static, str> {
"Clip".into()
}

fn update(
&mut self,
_cx: &mut crate::context::UpdateCx,
_state: Box<dyn std::any::Any>,
) -> crate::view::ChangeFlags {
ChangeFlags::empty()
}

fn layout(&mut self, cx: &mut crate::context::LayoutCx) -> taffy::prelude::Node {
cx.layout_node(self.id, true, |cx| vec![cx.layout_view(&mut self.child)])
}
Expand All @@ -66,15 +39,6 @@
Some(cx.compute_view_layout(&mut self.child))
}

fn event(
&mut self,
cx: &mut crate::context::EventCx,
id_path: Option<&[Id]>,
event: crate::event::Event,
) -> bool {
cx.view_event(&mut self.child, id_path, event)
}

fn paint(&mut self, cx: &mut crate::context::PaintCx) {
cx.save();
let style = cx.get_builtin_style(self.id);
Expand Down
60 changes: 5 additions & 55 deletions src/views/container.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
use kurbo::Rect;

use crate::{
id::Id,
view::{ChangeFlags, View},
};
use crate::{id::Id, view::View};

/// A simple wrapper around another View. See [`container`]
pub struct Container {
Expand All @@ -27,60 +22,15 @@
self.id
}

fn child(&self, id: Id) -> Option<&dyn View> {
if self.child.id() == id {
Some(&self.child)
} else {
None
}
}

fn child_mut(&mut self, id: Id) -> Option<&mut dyn View> {
if self.child.id() == id {
Some(&mut self.child)
} else {
None
}
}

fn children(&self) -> Vec<&dyn View> {
vec![&self.child]
fn for_each_child<'a>(&'a self, for_each: &mut dyn FnMut(&'a dyn View) -> bool) {
for_each(&self.child);

Check warning on line 26 in src/views/container.rs

View check run for this annotation

Codecov / codecov/patch

src/views/container.rs#L25-L26

Added lines #L25 - L26 were not covered by tests
}

fn children_mut(&mut self) -> Vec<&mut dyn View> {
vec![&mut self.child]
fn for_each_child_mut<'a>(&'a mut self, for_each: &mut dyn FnMut(&'a mut dyn View) -> bool) {
for_each(&mut self.child);

Check warning on line 30 in src/views/container.rs

View check run for this annotation

Codecov / codecov/patch

src/views/container.rs#L29-L30

Added lines #L29 - L30 were not covered by tests
}

fn debug_name(&self) -> std::borrow::Cow<'static, str> {
"Container".into()
}

fn update(
&mut self,
_cx: &mut crate::context::UpdateCx,
_state: Box<dyn std::any::Any>,
) -> crate::view::ChangeFlags {
ChangeFlags::empty()
}

fn layout(&mut self, cx: &mut crate::context::LayoutCx) -> taffy::prelude::Node {
cx.layout_node(self.id, true, |cx| vec![cx.layout_view(&mut self.child)])
}

fn compute_layout(&mut self, cx: &mut crate::context::LayoutCx) -> Option<Rect> {
Some(cx.compute_view_layout(&mut self.child))
}

fn event(
&mut self,
cx: &mut crate::context::EventCx,
id_path: Option<&[Id]>,
event: crate::event::Event,
) -> bool {
cx.view_event(&mut self.child, id_path, event)
}

fn paint(&mut self, cx: &mut crate::context::PaintCx) {
cx.paint_view(&mut self.child);
}
}
24 changes: 4 additions & 20 deletions src/views/container_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,12 @@
self.id
}

fn child(&self, id: Id) -> Option<&dyn View> {
if self.child.id() == id {
Some(&*self.child)
} else {
None
}
fn for_each_child<'a>(&'a self, for_each: &mut dyn FnMut(&'a dyn View) -> bool) {
for_each(&self.child);

Check warning on line 61 in src/views/container_box.rs

View check run for this annotation

Codecov / codecov/patch

src/views/container_box.rs#L60-L61

Added lines #L60 - L61 were not covered by tests
}

fn child_mut(&mut self, id: Id) -> Option<&mut dyn View> {
if self.child.id() == id {
Some(&mut *self.child)
} else {
None
}
}

fn children(&self) -> Vec<&dyn View> {
vec![&*self.child]
}

fn children_mut(&mut self) -> Vec<&mut dyn View> {
vec![&mut *self.child]
fn for_each_child_mut<'a>(&'a mut self, for_each: &mut dyn FnMut(&'a mut dyn View) -> bool) {
for_each(&mut self.child);

Check warning on line 65 in src/views/container_box.rs

View check run for this annotation

Codecov / codecov/patch

src/views/container_box.rs#L64-L65

Added lines #L64 - L65 were not covered by tests
}

fn debug_name(&self) -> std::borrow::Cow<'static, str> {
Expand Down
60 changes: 5 additions & 55 deletions src/views/drag_resize_window_area.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
use kurbo::Rect;
use winit::window::ResizeDirection;

use crate::{
action::drag_resize_window,
event::{Event, EventListener},
id::Id,
style::CursorStyle,
view::View,
action::drag_resize_window, event::EventListener, id::Id, style::CursorStyle, view::View,
};

use super::Decorators;
Expand Down Expand Up @@ -49,56 +44,11 @@
self.id
}

fn child(&self, id: Id) -> Option<&dyn View> {
if self.child.id() == id {
Some(&self.child)
} else {
None
}
fn for_each_child<'a>(&'a self, for_each: &mut dyn FnMut(&'a dyn View) -> bool) {
for_each(&self.child);

Check warning on line 48 in src/views/drag_resize_window_area.rs

View check run for this annotation

Codecov / codecov/patch

src/views/drag_resize_window_area.rs#L47-L48

Added lines #L47 - L48 were not covered by tests
}

fn child_mut(&mut self, id: Id) -> Option<&mut dyn View> {
if self.child.id() == id {
Some(&mut self.child)
} else {
None
}
}

fn children(&self) -> Vec<&dyn View> {
vec![&self.child]
}

fn children_mut(&mut self) -> Vec<&mut dyn View> {
vec![&mut self.child]
}

fn update(
&mut self,
_cx: &mut crate::context::UpdateCx,
_state: Box<dyn std::any::Any>,
) -> crate::view::ChangeFlags {
crate::view::ChangeFlags::empty()
}

fn layout(&mut self, cx: &mut crate::context::LayoutCx) -> taffy::prelude::Node {
cx.layout_node(self.id, true, |cx| vec![cx.layout_view(&mut self.child)])
}

fn compute_layout(&mut self, cx: &mut crate::context::LayoutCx) -> Option<Rect> {
Some(cx.compute_view_layout(&mut self.child))
}

fn event(
&mut self,
cx: &mut crate::context::EventCx,
id_path: Option<&[Id]>,
event: Event,
) -> bool {
cx.view_event(&mut self.child, id_path, event)
}

fn paint(&mut self, cx: &mut crate::context::PaintCx) {
cx.paint_view(&mut self.child);
fn for_each_child_mut<'a>(&'a mut self, for_each: &mut dyn FnMut(&'a mut dyn View) -> bool) {
for_each(&mut self.child);

Check warning on line 52 in src/views/drag_resize_window_area.rs

View check run for this annotation

Codecov / codecov/patch

src/views/drag_resize_window_area.rs#L51-L52

Added lines #L51 - L52 were not covered by tests
}
}
Loading