You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Normally, access keys are only active while holding <kbd>Alt</kbd>. To avoid this requirement we call [`with_alt_bypass`]. Further, we disable <kbd>Tab</kbd> key navigation with [`without_nav_focus`] and ensure that the window can be closed with the <kbd>Esc</kbd> key.
Copy file name to clipboardExpand all lines: src/custom-widget.md
+4-18Lines changed: 4 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -113,7 +113,7 @@ There are two types of child widgets: hidden layout-generated children and expli
113
113
The first of these is a [`Text`] widget, passed `&self.count` as input data. The second is a [`Row`] widget over [`Button`]s over [`AccessLabel`]s. Since we didn't specify a data mapping for this second widget, it is is passed the `Count` widget's input data (`()`).
114
114
115
115
Omitting `#[widget]` on a field which is a child widget is an error; sometimes the outer `#[widget]` attribute-macro will report the issue but not always. For example, if we omit the attribute on `buttons` and run, we get a backtrace like the following:
116
-
```
116
+
```ignore
117
117
thread 'main' (413532) panicked at /path/to/kas/crates/kas-core/src/core/data.rs:123:13:
118
118
WidgetStatus of #INVALID: require Configured, found New
119
119
stack backtrace:
@@ -160,9 +160,8 @@ It is however required to define the associated type [`Widget::Data`]. Since it
160
160
# #[derive(Clone, Debug)]
161
161
# structIncrement(i32);
162
162
# impl_scope! {
163
-
# #[widget{
164
-
# layout ="";
165
-
# }]
163
+
# #[widget]
164
+
# #[layout("")]
166
165
# structCounter {
167
166
# core:widget_core!(),
168
167
# count:i32,
@@ -202,24 +201,11 @@ Don't worry about remembering each step; macro diagnostics should point you in t
202
201
### Aside: the type of child widgets
203
202
204
203
Our `Counter` has two (explicit) child widgets, and we must specify the type of each:
There is no real issue in this case, but widget types can get significantly harder to write than `Row<[Button<AccessLabel>; 2]>`. Worse, some widget types are impossible to write (e.g. the result of [`row!`] or widget generics instantiated with a closure). So what can we do instead?
In the previous example, our top-level `AppData` was `()` and our mutable state was stored in an [`Adapt`] widget. This time, we will store our counter in top-level `AppData`, in a custom type which includes a message handler:
[`AppData::handle_messages`] is more verbose than [`Adapt::on_message`], but does the same job. The method notifies when widgets must be updated by returning [`Action::UPDATE`].
88
+
[`AppData::handle_messages`] is more verbose than [`Adapt::on_message`], but does the same job.
92
89
93
90
To integrate this into our example, we pass a `Count` object into [`kas::runner::Builder::build`] and adjust the prototype of `counter` to:
@@ -122,18 +119,19 @@ Note that our local data includes a *copy* of the top-level data `Count` (along
122
119
We'll skip right over the widget declarations to the new [`Adapt`] node:
123
120
```rust
124
121
# externcrate kas;
125
-
# usekas::widgets::{label_any, Adapt};
122
+
# usekas::widgets::{Adapt, AdaptWidget, Label};
126
123
# #[derive(Clone, Copy, Debug)]
127
124
# structCount(i32);
128
125
# fncounter() ->implkas::Widget<Data=Count> {
129
126
# #[derive(Clone, Debug)]
130
127
# structSetValue(i32);
131
-
# letui=label_any("");
128
+
# letui=Label::new_any("");
132
129
# letinitial= (Count(0), 1);
133
130
letui=ui
134
131
.with_state(initial)
135
132
.on_update(|_, state, count|state.0=*count)
136
133
.on_message(|_, state, SetValue(v)|state.1=v);
134
+
# ui
137
135
# }
138
136
```
139
137
The notable addition here is [`Adapt::on_update`], which takes a closure over the expected mutable reference to local `state` as well as *input* data `count` (i.e. the top-level data), allowing us to update local state with the latest top-level `count`.
@@ -147,16 +145,18 @@ Aside aside: could we not make [`Widget::Data`] into a Generic Associated Type (
147
145
Constructing multiple windows under a UI runner is simple:
0 commit comments