Skip to content

Commit eab17cc

Browse files
committed
Add AppCtx.
1 parent 9a10b04 commit eab17cc

47 files changed

Lines changed: 658 additions & 387 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 9 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ ui-events = { version = "0.3.0", default-features = false, features = ["kurbo"]
8080
ui-events-winit = { version = "0.3.0", default-features = false }
8181
smallvec = "1.15.1"
8282
hashbrown = { version = "0.17.0", default-features = false, features = ["default-hasher"] }
83+
copypasta = "0.10.2"
8384
dpi = "0.1.2"
8485
image = { version = "0.25.10", default-features = false }
8586
resvg = "0.47.0"

masonry/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ impl AppDriver for Driver {
100100
debug_assert_eq!(window_id, self.window_id, "unknown window");
101101

102102
if action.is::<ButtonPress>() {
103-
let render_root = ctx.render_root(window_id);
103+
let (app_ctx, render_root) = ctx.render_root(window_id);
104104

105-
render_root.edit_widget_with_tag(TEXT_INPUT_TAG, |mut text_input| {
105+
render_root.edit_widget_with_tag(app_ctx, TEXT_INPUT_TAG, |mut text_input| {
106106
let mut text_area = TextInput::text_mut(&mut text_input);
107107
TextArea::reset_text(&mut text_area, "");
108108
});
109-
render_root.edit_widget_with_tag(LIST_TAG, |mut list| {
109+
render_root.edit_widget_with_tag(app_ctx, LIST_TAG, |mut list| {
110110
let child = Label::new(self.next_task.clone()).prepare();
111111
Flex::add_fixed(&mut list, child);
112112
});

masonry/examples/calc_masonry.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ impl AppDriver for CalcState {
155155
) {
156156
debug_assert_eq!(window_id, self.window_id, "unknown window");
157157

158-
let Some(source) = ctx.render_root(window_id).get_widget(widget_id) else {
158+
let (app_ctx, render_root) = ctx.render_root(window_id);
159+
160+
let Some(source) = render_root.get_widget(widget_id) else {
159161
return;
160162
};
161163
let Some(button) = source.downcast::<Button>() else {
@@ -171,7 +173,7 @@ impl AppDriver for CalcState {
171173
CalcAction::None => (),
172174
}
173175

174-
ctx.render_root(window_id).edit_base_layer(|mut root| {
176+
render_root.edit_base_layer(app_ctx, |mut root| {
175177
let mut grid = root.downcast();
176178
let mut flex = Grid::get_mut(&mut grid, 0);
177179
let mut flex = flex.downcast();

masonry/examples/gallery/badge.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2026 the Xilem Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use masonry::app::RenderRoot;
4+
use masonry::app::{AppCtx, RenderRoot};
55
use masonry::core::{
66
ErasedAction, Handled, NewWidget, PropertySet, StyleProperty, Widget, WidgetId, WidgetTag,
77
};
@@ -56,12 +56,12 @@ impl BadgeDemo {
5656
)
5757
}
5858

59-
fn apply_count(&self, render_root: &mut RenderRoot) {
60-
render_root.edit_widget_with_tag(self.count_label, |mut label| {
59+
fn apply_count(&self, app_ctx: &mut AppCtx, render_root: &mut RenderRoot) {
60+
render_root.edit_widget_with_tag(app_ctx, self.count_label, |mut label| {
6161
Label::set_text(&mut label, format!("count: {}", self.count));
6262
});
6363

64-
render_root.edit_widget_with_tag(self.inbox_badged, |mut badged| {
64+
render_root.edit_widget_with_tag(app_ctx, self.inbox_badged, |mut badged| {
6565
if let Some(badge) = Self::make_count_badge(self.count) {
6666
Badged::set_badge(&mut badged, badge);
6767
} else {
@@ -240,12 +240,13 @@ impl DemoPage for BadgeDemo {
240240
wrap_in_shell(self.shell, NewWidget::new(body).erased())
241241
}
242242

243-
fn on_selected(&mut self, render_root: &mut RenderRoot) {
244-
self.apply_count(render_root);
243+
fn on_selected(&mut self, app_ctx: &mut AppCtx, render_root: &mut RenderRoot) {
244+
self.apply_count(app_ctx, render_root);
245245
}
246246

247247
fn on_action(
248248
&mut self,
249+
app_ctx: &mut AppCtx,
249250
render_root: &mut RenderRoot,
250251
action: &ErasedAction,
251252
widget_id: WidgetId,
@@ -265,13 +266,13 @@ impl DemoPage for BadgeDemo {
265266

266267
if widget_id == dec_id {
267268
self.count = self.count.saturating_sub(1);
268-
self.apply_count(render_root);
269+
self.apply_count(app_ctx, render_root);
269270
return Handled::Yes;
270271
}
271272

272273
if widget_id == inc_id {
273274
self.count = self.count.saturating_add(1);
274-
self.apply_count(render_root);
275+
self.apply_count(app_ctx, render_root);
275276
return Handled::Yes;
276277
}
277278

masonry/examples/gallery/checkbox.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2026 the Xilem Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use masonry::app::RenderRoot;
4+
use masonry::app::{AppCtx, RenderRoot};
55
use masonry::core::{ErasedAction, Handled, NewWidget, StyleProperty, Widget, WidgetId, WidgetTag};
66
use masonry::properties::types::CrossAxisAlignment;
77
use masonry::widgets::{Checkbox, CheckboxToggled, Flex, Label};
@@ -52,6 +52,7 @@ impl DemoPage for CheckboxDemo {
5252

5353
fn on_action(
5454
&mut self,
55+
app_ctx: &mut AppCtx,
5556
render_root: &mut RenderRoot,
5657
action: &ErasedAction,
5758
widget_id: WidgetId,
@@ -66,10 +67,10 @@ impl DemoPage for CheckboxDemo {
6667
return Handled::No;
6768
}
6869

69-
render_root.edit_widget_with_tag(self.state_label, |mut label| {
70+
render_root.edit_widget_with_tag(app_ctx, self.state_label, |mut label| {
7071
Label::set_text(&mut label, format!("Checked: {checked}"));
7172
});
72-
render_root.edit_widget_with_tag(self.checkbox, |mut checkbox| {
73+
render_root.edit_widget_with_tag(app_ctx, self.checkbox, |mut checkbox| {
7374
Checkbox::set_checked(&mut checkbox, checked);
7475
});
7576
Handled::Yes

masonry/examples/gallery/demo.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2026 the Xilem Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use masonry::app::RenderRoot;
4+
use masonry::app::{AppCtx, RenderRoot};
55
use masonry::core::{ErasedAction, Handled, NewWidget, Widget, WidgetId, WidgetTag};
66
use masonry::layout::Length;
77
use masonry::properties::types::CrossAxisAlignment;
@@ -21,10 +21,11 @@ pub(crate) trait DemoPage {
2121
fn shell_tags(&self) -> ShellTags;
2222
fn build(&self) -> NewWidget<dyn Widget>;
2323

24-
fn on_selected(&mut self, _render_root: &mut RenderRoot) {}
24+
fn on_selected(&mut self, _app_ctx: &mut AppCtx, _render_root: &mut RenderRoot) {}
2525

2626
fn on_action(
2727
&mut self,
28+
app_ctx: &mut AppCtx,
2829
render_root: &mut RenderRoot,
2930
action: &ErasedAction,
3031
widget_id: WidgetId,

masonry/examples/gallery/main.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ impl Driver {
7373
) {
7474
let shell = self.demos[demo_idx].shell_tags();
7575

76-
let render_root = ctx.render_root(window_id);
77-
render_root.edit_widget_with_tag(shell.disabled_toggle, |mut checkbox| {
76+
let (app_ctx, render_root) = ctx.render_root(window_id);
77+
render_root.edit_widget_with_tag(app_ctx, shell.disabled_toggle, |mut checkbox| {
7878
Checkbox::set_checked(&mut checkbox, disabled);
7979
});
80-
render_root.edit_widget_with_tag(shell.content_wrapper, |mut content| {
80+
render_root.edit_widget_with_tag(app_ctx, shell.content_wrapper, |mut content| {
8181
content.ctx.set_disabled(disabled);
8282
});
8383
}
@@ -91,11 +91,11 @@ impl Driver {
9191

9292
{
9393
let name = self.demos[idx].name();
94-
let render_root = ctx.render_root(window_id);
95-
render_root.edit_widget_with_tag(self.title_tag, |mut label| {
94+
let (app_ctx, render_root) = ctx.render_root(window_id);
95+
render_root.edit_widget_with_tag(app_ctx, self.title_tag, |mut label| {
9696
Label::set_text(&mut label, name);
9797
});
98-
render_root.edit_widget_with_tag(self.stack_tag, |mut stack| {
98+
render_root.edit_widget_with_tag(app_ctx, self.stack_tag, |mut stack| {
9999
IndexedStack::set_active_child(&mut stack, idx);
100100
});
101101
}
@@ -104,8 +104,8 @@ impl Driver {
104104
self.apply_demo_disabled(ctx, window_id, idx, disabled);
105105

106106
{
107-
let render_root = ctx.render_root(window_id);
108-
self.demos[idx].on_selected(render_root);
107+
let (app_ctx, render_root) = ctx.render_root(window_id);
108+
self.demos[idx].on_selected(app_ctx, render_root);
109109
}
110110
}
111111
}
@@ -120,11 +120,12 @@ impl AppDriver for Driver {
120120
) {
121121
debug_assert_eq!(window_id, self.window_id, "unknown window");
122122

123+
let (app_ctx, render_root) = ctx.render_root(window_id);
124+
123125
// Sidebar button pressed: select demo.
124126
if action.is::<ButtonPress>() {
125127
// Sidebar: match by tagged ids.
126128
let selected_idx = {
127-
let render_root = ctx.render_root(window_id);
128129
self.sidebar_buttons
129130
.iter()
130131
.enumerate()
@@ -144,7 +145,6 @@ impl AppDriver for Driver {
144145
if let Some(toggled) = action.downcast_ref::<CheckboxToggled>() {
145146
let toggled = toggled.0;
146147
let disabled_demo = {
147-
let render_root = ctx.render_root(window_id);
148148
self.demos.iter().enumerate().find_map(|(idx, demo)| {
149149
let shell = demo.shell_tags();
150150
let id = render_root
@@ -163,9 +163,11 @@ impl AppDriver for Driver {
163163
}
164164

165165
// Forward everything else to demos.
166-
let render_root = ctx.render_root(window_id);
167166
for demo in &mut self.demos {
168-
if demo.on_action(render_root, &action, widget_id).is_handled() {
167+
if demo
168+
.on_action(app_ctx, render_root, &action, widget_id)
169+
.is_handled()
170+
{
169171
return;
170172
}
171173
}

masonry/examples/gallery/pagination.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2026 the Xilem Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use masonry::app::RenderRoot;
4+
use masonry::app::{AppCtx, RenderRoot};
55
use masonry::core::{Handled, NewWidget, Widget, WidgetId, WidgetTag};
66
use masonry::widgets::{Flex, Label, PageChanged, Pagination, Step, StepInput};
77

@@ -53,6 +53,7 @@ impl DemoPage for PaginationDemo {
5353

5454
fn on_action(
5555
&mut self,
56+
app_ctx: &mut AppCtx,
5657
render_root: &mut RenderRoot,
5758
action: &masonry::core::ErasedAction,
5859
widget_id: WidgetId,
@@ -86,34 +87,34 @@ impl DemoPage for PaginationDemo {
8687
.id();
8788

8889
if widget_id == id_page_count {
89-
render_root.edit_widget_with_tag(self.tag_pagination, |mut widget| {
90+
render_root.edit_widget_with_tag(app_ctx, self.tag_pagination, |mut widget| {
9091
Pagination::set_page_count(&mut widget, value as usize);
9192
});
9293
return Handled::Yes;
9394
}
9495
if widget_id == id_page_active {
95-
render_root.edit_widget_with_tag(self.tag_content, |mut content| {
96+
render_root.edit_widget_with_tag(app_ctx, self.tag_content, |mut content| {
9697
Label::set_text(&mut content, format!("Now on page {}", value));
9798
});
98-
render_root.edit_widget_with_tag(self.tag_pagination, |mut widget| {
99+
render_root.edit_widget_with_tag(app_ctx, self.tag_pagination, |mut widget| {
99100
Pagination::set_active_page(&mut widget, (value - 1) as usize);
100101
});
101102
return Handled::Yes;
102103
}
103104
if widget_id == id_buttons_start {
104-
render_root.edit_widget_with_tag(self.tag_pagination, |mut widget| {
105+
render_root.edit_widget_with_tag(app_ctx, self.tag_pagination, |mut widget| {
105106
Pagination::set_buttons_start(&mut widget, value as u8);
106107
});
107108
return Handled::Yes;
108109
}
109110
if widget_id == id_buttons_end {
110-
render_root.edit_widget_with_tag(self.tag_pagination, |mut widget| {
111+
render_root.edit_widget_with_tag(app_ctx, self.tag_pagination, |mut widget| {
111112
Pagination::set_buttons_end(&mut widget, value as u8);
112113
});
113114
return Handled::Yes;
114115
}
115116
if widget_id == id_buttons_total {
116-
render_root.edit_widget_with_tag(self.tag_pagination, |mut widget| {
117+
render_root.edit_widget_with_tag(app_ctx, self.tag_pagination, |mut widget| {
117118
Pagination::set_buttons_total(&mut widget, value as u8);
118119
});
119120
return Handled::Yes;
@@ -131,10 +132,10 @@ impl DemoPage for PaginationDemo {
131132
return Handled::No;
132133
}
133134

134-
render_root.edit_widget_with_tag(self.tag_content, |mut content| {
135+
render_root.edit_widget_with_tag(app_ctx, self.tag_content, |mut content| {
135136
Label::set_text(&mut content, format!("Now on page {}", page_idx + 1));
136137
});
137-
render_root.edit_widget_with_tag(self.tag_page_active, |mut widget| {
138+
render_root.edit_widget_with_tag(app_ctx, self.tag_page_active, |mut widget| {
138139
StepInput::set_base(&mut widget, (page_idx + 1).cast_signed());
139140
});
140141
return Handled::Yes;

0 commit comments

Comments
 (0)