Skip to content

Commit

Permalink
Add Properties argument to widget methods
Browse files Browse the repository at this point in the history
  • Loading branch information
PoignardAzur committed Feb 18, 2025
1 parent 3746736 commit 0a8a301
Show file tree
Hide file tree
Showing 35 changed files with 724 additions and 330 deletions.
39 changes: 30 additions & 9 deletions masonry/examples/calc_masonry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use accesskit::{Node, Role};
use masonry::app::{AppDriver, DriverCtx};
use masonry::core::{
AccessCtx, AccessEvent, Action, BoxConstraints, EventCtx, LayoutCtx, PaintCtx, PointerEvent,
QueryCtx, RegisterCtx, StyleProperty, TextEvent, Update, UpdateCtx, Widget, WidgetId,
WidgetPod,
Properties, PropertiesMut, QueryCtx, RegisterCtx, StyleProperty, TextEvent, Update, UpdateCtx,
Widget, WidgetId, WidgetPod,
};
use masonry::dpi::LogicalSize;
use masonry::kurbo::{Point, Size};
Expand Down Expand Up @@ -148,7 +148,12 @@ impl CalcButton {
}

impl Widget for CalcButton {
fn on_pointer_event(&mut self, ctx: &mut EventCtx, event: &PointerEvent) {
fn on_pointer_event(
&mut self,
ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
event: &PointerEvent,
) {
match event {
PointerEvent::PointerDown(_, _) => {
if !ctx.is_disabled() {
Expand Down Expand Up @@ -176,9 +181,20 @@ impl Widget for CalcButton {
}
}

fn on_text_event(&mut self, _ctx: &mut EventCtx, _event: &TextEvent) {}
fn on_text_event(
&mut self,
_ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
_event: &TextEvent,
) {
}

fn on_access_event(&mut self, ctx: &mut EventCtx, event: &AccessEvent) {
fn on_access_event(
&mut self,
ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
event: &AccessEvent,
) {
if ctx.target() == ctx.widget_id() {
match event.action {
accesskit::Action::Click => {
Expand All @@ -189,7 +205,7 @@ impl Widget for CalcButton {
}
}

fn update(&mut self, ctx: &mut UpdateCtx, event: &Update) {
fn update(&mut self, ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, event: &Update) {
// Masonry doesn't let us change a widget's attributes directly.
// We use `mutate_later` to get a mutable reference to the inner widget
// and change its border color. This is a simple way to implement a
Expand All @@ -214,20 +230,25 @@ impl Widget for CalcButton {
ctx.register_child(&mut self.inner);
}

fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
fn layout(
&mut self,
ctx: &mut LayoutCtx,
_props: &mut PropertiesMut<'_>,
bc: &BoxConstraints,
) -> Size {
let size = ctx.run_layout(&mut self.inner, bc);
ctx.place_child(&mut self.inner, Point::ORIGIN);

size
}

fn paint(&mut self, _ctx: &mut PaintCtx, _scene: &mut Scene) {}
fn paint(&mut self, _ctx: &mut PaintCtx, _props: &Properties<'_>, _scene: &mut Scene) {}

fn accessibility_role(&self) -> Role {
Role::Button
}

fn accessibility(&mut self, _ctx: &mut AccessCtx, node: &mut Node) {
fn accessibility(&mut self, _ctx: &mut AccessCtx, _props: &Properties<'_>, node: &mut Node) {
let _name = match self.action {
CalcAction::Digit(digit) => digit.to_string(),
CalcAction::Op(op) => op.to_string(),
Expand Down
37 changes: 30 additions & 7 deletions masonry/examples/custom_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use accesskit::{Node, Role};
use masonry::app::{AppDriver, DriverCtx};
use masonry::core::{
AccessCtx, AccessEvent, Action, BoxConstraints, EventCtx, LayoutCtx, ObjectFit, PaintCtx,
PointerEvent, QueryCtx, RegisterCtx, TextEvent, Widget, WidgetId,
PointerEvent, Properties, PropertiesMut, QueryCtx, RegisterCtx, TextEvent, Widget, WidgetId,
};
use masonry::kurbo::{Affine, BezPath, Point, Rect, Size, Stroke};
use masonry::palette;
Expand All @@ -37,15 +37,38 @@ impl AppDriver for Driver {
struct CustomWidget(String);

impl Widget for CustomWidget {
fn on_pointer_event(&mut self, _ctx: &mut EventCtx, _event: &PointerEvent) {}
fn on_pointer_event(
&mut self,
_ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
_event: &PointerEvent,
) {
}

fn on_text_event(&mut self, _ctx: &mut EventCtx, _event: &TextEvent) {}
fn on_text_event(
&mut self,
_ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
_event: &TextEvent,
) {
}

fn on_access_event(&mut self, _ctx: &mut EventCtx, _event: &AccessEvent) {}
fn on_access_event(
&mut self,
_ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
_event: &AccessEvent,
) {
}

fn register_children(&mut self, _ctx: &mut RegisterCtx) {}

fn layout(&mut self, _layout_ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
fn layout(
&mut self,
_layout_ctx: &mut LayoutCtx,
_props: &mut PropertiesMut<'_>,
bc: &BoxConstraints,
) -> Size {
// BoxConstraints are passed by the parent widget.
// This method can return any Size within those constraints:
// bc.constrain(my_size)
Expand All @@ -68,7 +91,7 @@ impl Widget for CustomWidget {
// The paint method gets called last, after an event flow.
// It goes event -> update -> layout -> paint, and each method can influence the next.
// Basically, anything that changes the appearance of a widget causes a paint.
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut Scene) {
fn paint(&mut self, ctx: &mut PaintCtx, _props: &Properties<'_>, scene: &mut Scene) {
// Clear the whole widget with the color of your choice
// (ctx.size() returns the size of the layout rect we're painting in)
// Note: ctx also has a `clear` method, but that clears the whole context,
Expand Down Expand Up @@ -137,7 +160,7 @@ impl Widget for CustomWidget {
Role::Window
}

fn accessibility(&mut self, _ctx: &mut AccessCtx, node: &mut Node) {
fn accessibility(&mut self, _ctx: &mut AccessCtx, _props: &Properties<'_>, node: &mut Node) {
let text = &self.0;
node.set_label(
format!("This is a demo of the Masonry Widget trait. Masonry has accessibility tree support. The demo shows colored shapes with the text '{text}'."),
Expand Down
48 changes: 39 additions & 9 deletions masonry/src/core/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use vello::Scene;

use crate::core::{
AccessCtx, AccessEvent, BoxConstraints, ComposeCtx, EventCtx, LayoutCtx, PaintCtx,
PointerEvent, QueryCtx, RegisterCtx, TextEvent, Update, UpdateCtx, WidgetRef,
PointerEvent, Properties, PropertiesMut, QueryCtx, RegisterCtx, TextEvent, Update, UpdateCtx,
WidgetRef,
};
use crate::kurbo::{Point, Size};
use crate::AsAny;
Expand Down Expand Up @@ -128,19 +129,37 @@ pub trait Widget: AsAny + AsDynWidget {
///
/// Pointer events will target the widget under the pointer, and then the
/// event will bubble to each of its parents.
fn on_pointer_event(&mut self, ctx: &mut EventCtx, event: &PointerEvent) {}
fn on_pointer_event(
&mut self,
ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
event: &PointerEvent,
) {
}

/// Handle a text event.
///
/// Text events will target the [focused widget], then bubble to each parent.
///
/// [focused widget]: crate::doc::doc_06_masonry_concepts#text-focus
fn on_text_event(&mut self, ctx: &mut EventCtx, event: &TextEvent) {}
fn on_text_event(
&mut self,
ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
event: &TextEvent,
) {
}

/// Handle an event from the platform's accessibility API.
///
/// Accessibility events target a specific widget id, then bubble to each parent.
fn on_access_event(&mut self, ctx: &mut EventCtx, event: &AccessEvent) {}
fn on_access_event(
&mut self,
ctx: &mut EventCtx,
_props: &mut PropertiesMut<'_>,
event: &AccessEvent,
) {
}

/// Called at the beginning of a new animation frame.
///
Expand All @@ -161,7 +180,13 @@ pub trait Widget: AsAny + AsDynWidget {
/// For that reason, you should try to avoid doing anything computationally
/// intensive in response to an `AnimFrame` event: it might make the app miss
/// the monitor's refresh, causing lag or jerky animations.
fn on_anim_frame(&mut self, ctx: &mut UpdateCtx, interval: u64) {}
fn on_anim_frame(
&mut self,
ctx: &mut UpdateCtx,
_props: &mut PropertiesMut<'_>,
interval: u64,
) {
}

// TODO - Reorder methods to match 02_implementing_widget.md

Expand All @@ -179,7 +204,7 @@ pub trait Widget: AsAny + AsDynWidget {
/// This method is called to notify your widget of certain special events,
/// (available in the [`Update`] enum) that are generally related to
/// changes in the widget graph or in the state of your specific widget.
fn update(&mut self, ctx: &mut UpdateCtx, event: &Update) {}
fn update(&mut self, ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, event: &Update) {}

/// Compute layout and return the widget's size.
///
Expand All @@ -206,7 +231,12 @@ pub trait Widget: AsAny + AsDynWidget {
/// While each widget should try to return a size that fits the input constraints,
/// **any widget may return a size that doesn't fit its constraints**, and container
/// widgets should handle those cases gracefully.
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size;
fn layout(
&mut self,
ctx: &mut LayoutCtx,
_props: &mut PropertiesMut<'_>,
bc: &BoxConstraints,
) -> Size;

fn compose(&mut self, ctx: &mut ComposeCtx) {}

Expand All @@ -216,11 +246,11 @@ pub trait Widget: AsAny + AsDynWidget {
/// children, or annotations (for example, scrollbars) by painting
/// afterwards. In addition, they can apply masks and transforms on
/// the render context, which is especially useful for scrolling.
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut Scene);
fn paint(&mut self, ctx: &mut PaintCtx, _props: &Properties<'_>, scene: &mut Scene);

fn accessibility_role(&self) -> Role;

fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut Node);
fn accessibility(&mut self, ctx: &mut AccessCtx, _props: &Properties<'_>, node: &mut Node);

/// Return ids of this widget's children.
///
Expand Down
36 changes: 18 additions & 18 deletions masonry/src/doc/02_implementing_widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ Widgets are types which implement the [`Widget`] trait:

```rust,ignore
trait Widget {
fn on_pointer_event(&mut self, ctx: &mut EventCtx, event: &PointerEvent);
fn on_text_event(&mut self, ctx: &mut EventCtx, event: &TextEvent);
fn on_access_event(&mut self, ctx: &mut EventCtx, event: &AccessEvent);
fn on_pointer_event(&mut self, ctx: &mut EventCtx, _props: &mut PropertiesMut<'_>, event: &PointerEvent);
fn on_text_event(&mut self, ctx: &mut EventCtx, _props: &mut PropertiesMut<'_>, event: &TextEvent);
fn on_access_event(&mut self, ctx: &mut EventCtx, _props: &mut PropertiesMut<'_>, event: &AccessEvent);
fn on_anim_frame(&mut self, ctx: &mut UpdateCtx, interval: u64);
fn update(&mut self, ctx: &mut UpdateCtx, event: &Update);
fn on_anim_frame(&mut self, ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, interval: u64);
fn update(&mut self, ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, event: &Update);
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size;
fn layout(&mut self, ctx: &mut LayoutCtx, _props: &mut PropertiesMut<'_>, bc: &BoxConstraints) -> Size;
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut Scene);
fn paint(&mut self, ctx: &mut PaintCtx, _props: &Properties<'_>, scene: &mut Scene);
fn accessibility_role(&self) -> Role;
fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut Node);
fn accessibility(&mut self, ctx: &mut AccessCtx, _props: &Properties<'_>, node: &mut Node);
// ...
}
Expand Down Expand Up @@ -90,7 +90,7 @@ use masonry::core::{
};
impl Widget for ColorRectangle {
fn on_pointer_event(&mut self, ctx: &mut EventCtx, event: &PointerEvent) {
fn on_pointer_event(&mut self, ctx: &mut EventCtx, _props: &mut PropertiesMut<'_>, event: &PointerEvent) {
match event {
PointerEvent::PointerDown(PointerButton::Primary, _) => {
ctx.submit_action(Action::ButtonPressed(PointerButton::Primary));
Expand All @@ -99,9 +99,9 @@ impl Widget for ColorRectangle {
}
}
fn on_text_event(&mut self, _ctx: &mut EventCtx, _event: &TextEvent) {}
fn on_text_event(&mut self, _ctx: &mut EventCtx, _props: &mut PropertiesMut<'_>, _event: &TextEvent) {}
fn on_access_event(&mut self, ctx: &mut EventCtx, event: &AccessEvent) {
fn on_access_event(&mut self, ctx: &mut EventCtx, _props: &mut PropertiesMut<'_>, event: &AccessEvent) {
match event.action {
accesskit::Action::Default => {
ctx.submit_action(Action::ButtonPressed(PointerButton::Primary));
Expand Down Expand Up @@ -136,8 +136,8 @@ use masonry::core::{
impl Widget for ColorRectangle {
// ...
fn on_anim_frame(&mut self, _ctx: &mut UpdateCtx, _interval: u64) {}
fn update(&mut self, _ctx: &mut UpdateCtx, _event: &Update) {}
fn on_anim_frame(&mut self, _ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, _interval: u64) {}
fn update(&mut self, _ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, _event: &Update) {}
// ...
}
Expand All @@ -155,7 +155,7 @@ use masonry::core::{
impl Widget for ColorRectangle {
// ...
fn layout(&mut self, _ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
fn layout(&mut self, _ctx: &mut LayoutCtx, _props: &mut PropertiesMut<'_>, bc: &BoxConstraints) -> Size {
bc.constrain(self.size)
}
Expand All @@ -182,7 +182,7 @@ use accesskit::{Node, Role};
impl Widget for ColorRectangle {
// ...
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut Scene) {
fn paint(&mut self, ctx: &mut PaintCtx, _props: &Properties<'_>, scene: &mut Scene) {
let rect = ctx.size().to_rect();
scene.fill(
Fill::NonZero,
Expand All @@ -197,7 +197,7 @@ impl Widget for ColorRectangle {
Role::Button
}
fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut Node) {
fn accessibility(&mut self, ctx: &mut AccessCtx, _props: &Properties<'_>, node: &mut Node) {
node.set_default_action_verb(DefaultActionVerb::Click);
}
Expand Down Expand Up @@ -302,7 +302,7 @@ First, we update our paint method:
impl Widget for ColorRectangle {
// ...
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut Scene) {
fn paint(&mut self, ctx: &mut PaintCtx, _props: &Properties<'_>, scene: &mut Scene) {
let rect = ctx.size().to_rect();
let color = if ctx.is_hovered() {
Color::WHITE
Expand Down Expand Up @@ -330,7 +330,7 @@ Let's re-implement the `update` method:
impl Widget for ColorRectangle {
// ...
fn update(&mut self, ctx: &mut UpdateCtx, event: &Update) {
fn update(&mut self, ctx: &mut UpdateCtx, _props: &mut PropertiesMut<'_>, event: &Update) {
match event {
Update::HoveredChanged(_) => {
ctx.request_render();
Expand Down
Loading

0 comments on commit 0a8a301

Please sign in to comment.