1use raui_immediate::*;
2
3macro_rules! impl_imports {
4 () => {
5 #[allow(unused_imports)]
6 use raui_core::widget::component::{
7 containers::{
8 anchor_box::*, area_box::*, content_box::*, context_box::*, flex_box::*,
9 float_box::*, grid_box::*, hidden_box::*, horizontal_box::*, portal_box::*,
10 responsive_box::*, scroll_box::*, size_box::*, switch_box::*, tabs_box::*,
11 tooltip_box::*, variant_box::*, vertical_box::*, wrap_box::*,
12 },
13 interactive::{
14 button::*, float_view::*, input_field::*, navigation::*, options_view::*,
15 scroll_view::*, slider_view::*,
16 },
17 };
18 #[allow(unused_imports)]
19 use raui_core::widget::{
20 component::{image_box::*, space_box::*, text_box::*},
21 none_widget,
22 };
23 #[allow(unused_imports)]
24 use raui_material::component::{
25 containers::{
26 context_paper::*, flex_paper::*, grid_paper::*, horizontal_paper::*,
27 modal_paper::*, paper::*, scroll_paper::*, text_tooltip_paper::*, tooltip_paper::*,
28 vertical_paper::*, window_paper::*, wrap_paper::*,
29 },
30 interactive::{
31 button_paper::*, icon_button_paper::*, slider_paper::*, switch_button_paper::*,
32 text_button_paper::*, text_field_paper::*,
33 },
34 };
35 #[allow(unused_imports)]
36 use raui_material::component::{icon_paper::*, switch_paper::*, text_paper::*};
37 };
38}
39
40macro_rules! impl_slot_components {
41 ($($name:ident),+ $(,)?) => {
42 $(
43 pub fn $name<R>(
44 props: impl Into<raui_core::props::Props>,
45 f: impl FnMut() -> R,
46 ) -> R {
47 impl_imports!();
48 crate::slot_component(raui_core::make_widget!($name), props, f)
49 }
50 )+
51 };
52}
53
54macro_rules! impl_list_components {
55 ($($name:ident),+ $(,)?) => {
56 $(
57 pub fn $name<R>(
58 props: impl Into<raui_core::props::Props>,
59 f: impl FnMut() -> R,
60 ) -> R {
61 impl_imports!();
62 crate::list_component(raui_core::make_widget!($name), props, f)
63 }
64 )+
65 };
66}
67
68macro_rules! impl_content_components {
69 ($content:literal : $($name:ident),+ $(,)?) => {
70 $(
71 pub fn $name<R>(
72 props: impl Into<raui_core::props::Props>,
73 f: impl FnMut() -> R,
74 ) -> R {
75 impl_imports!();
76 crate::content_component(raui_core::make_widget!($name), $content, props, f)
77 }
78 )+
79 };
80}
81
82macro_rules! impl_components {
83 ($($name:ident),+ $(,)?) => {
84 $(
85 pub fn $name(
86 props: impl Into<raui_core::props::Props>,
87 ) {
88 impl_imports!();
89 crate::component(raui_core::make_widget!($name), props)
90 }
91 )+
92 };
93}
94
95pub mod core {
96 impl_components! {
97 image_box,
98 nav_scroll_box_side_scrollbars,
99 none_widget,
100 space_box,
101 text_box,
102 }
103
104 pub mod containers {
105 impl_content_components! {
106 "content":
107 anchor_box,
108 hidden_box,
109 nav_scroll_box_content,
110 pivot_box,
111 portal_box,
112 responsive_props_box,
113 size_box,
114 wrap_box,
115 }
116
117 impl_slot_components! {
118 context_box,
119 nav_scroll_box,
120 portals_context_box,
121 portals_tooltip_box,
122 tooltip_box,
123 variant_box,
124 }
125
126 impl_list_components! {
127 content_box,
128 flex_box,
129 grid_box,
130 horizontal_box,
131 nav_content_box,
132 nav_flex_box,
133 nav_grid_box,
134 nav_horizontal_box,
135 nav_switch_box,
136 nav_tabs_box,
137 nav_vertical_box,
138 responsive_box,
139 switch_box,
140 vertical_box,
141 }
142 }
143
144 pub mod interactive {
145 use raui_core::{
146 make_widget,
147 props::Props,
148 widget::{
149 component::interactive::{
150 button::ButtonProps,
151 input_field::{TextInputProps, TextInputState},
152 navigation::NavTrackingProps,
153 options_view::{OptionsViewProps, OptionsViewProxy},
154 slider_view::{SliderViewProps, SliderViewProxy},
155 },
156 utils::Vec2,
157 },
158 };
159 use raui_immediate::{begin, end, pop, push, use_state};
160 use std::str::FromStr;
161
162 #[derive(Debug, Default, Copy, Clone)]
163 pub struct ImmediateTracking {
164 pub state: NavTrackingProps,
165 pub prev: NavTrackingProps,
166 }
167
168 impl ImmediateTracking {
169 pub fn pointer_delta_factor(&self) -> Vec2 {
170 Vec2 {
171 x: self.state.factor.x - self.prev.factor.x,
172 y: self.state.factor.y - self.prev.factor.y,
173 }
174 }
175
176 pub fn pointer_delta_unscaled(&self) -> Vec2 {
177 Vec2 {
178 x: self.state.unscaled.x - self.prev.unscaled.x,
179 y: self.state.unscaled.y - self.prev.unscaled.y,
180 }
181 }
182
183 pub fn pointer_delta_ui_space(&self) -> Vec2 {
184 Vec2 {
185 x: self.state.ui_space.x - self.prev.ui_space.x,
186 y: self.state.ui_space.y - self.prev.ui_space.y,
187 }
188 }
189
190 pub fn pointer_moved(&self) -> bool {
191 (self.state.factor.x - self.prev.factor.x)
192 + (self.state.factor.y - self.prev.factor.y)
193 > 1.0e-6
194 }
195 }
196
197 #[derive(Debug, Default, Copy, Clone)]
198 pub struct ImmediateButton {
199 pub state: ButtonProps,
200 pub prev: ButtonProps,
201 }
202
203 impl ImmediateButton {
204 pub fn select_start(&self) -> bool {
205 !self.prev.selected && self.state.selected
206 }
207
208 pub fn select_stop(&self) -> bool {
209 self.prev.selected && !self.state.selected
210 }
211
212 pub fn select_changed(&self) -> bool {
213 self.prev.selected != self.state.selected
214 }
215
216 pub fn trigger_start(&self) -> bool {
217 !self.prev.trigger && self.state.trigger
218 }
219
220 pub fn trigger_stop(&self) -> bool {
221 self.prev.trigger && !self.state.trigger
222 }
223
224 pub fn trigger_changed(&self) -> bool {
225 self.prev.trigger != self.state.trigger
226 }
227
228 pub fn context_start(&self) -> bool {
229 !self.prev.context && self.state.context
230 }
231
232 pub fn context_stop(&self) -> bool {
233 self.prev.context && !self.state.context
234 }
235
236 pub fn context_changed(&self) -> bool {
237 self.prev.context != self.state.context
238 }
239 }
240
241 impl_content_components! {
242 "content":
243 navigation_barrier,
244 }
245
246 pub fn tracking(
247 props: impl Into<Props>,
248 mut f: impl FnMut(ImmediateTracking),
249 ) -> ImmediateTracking {
250 use crate::internal::*;
251 let state = use_state(ImmediateTracking::default);
252 let result = state.read().unwrap().to_owned();
253 begin();
254 f(result);
255 let node = end().pop().unwrap_or_default();
256 push(
257 make_widget!(immediate_tracking)
258 .with_props(ImmediateTrackingProps { state: Some(state) })
259 .merge_props(props.into())
260 .named_slot("content", node),
261 );
262 result
263 }
264
265 pub fn self_tracking(
266 props: impl Into<Props>,
267 mut f: impl FnMut(ImmediateTracking),
268 ) -> ImmediateTracking {
269 use crate::internal::*;
270 let state = use_state(ImmediateTracking::default);
271 let result = state.read().unwrap().to_owned();
272 begin();
273 f(result);
274 let node = end().pop().unwrap_or_default();
275 push(
276 make_widget!(immediate_self_tracking)
277 .with_props(ImmediateTrackingProps { state: Some(state) })
278 .merge_props(props.into())
279 .named_slot("content", node),
280 );
281 result
282 }
283
284 pub fn button(
285 props: impl Into<Props>,
286 mut f: impl FnMut(ImmediateButton),
287 ) -> ImmediateButton {
288 use crate::internal::*;
289 let state = use_state(ImmediateButton::default);
290 let result = state.read().unwrap().to_owned();
291 begin();
292 f(result);
293 let node = end().pop().unwrap_or_default();
294 push(
295 make_widget!(immediate_button)
296 .with_props(ImmediateButtonProps { state: Some(state) })
297 .merge_props(props.into())
298 .named_slot("content", node),
299 );
300 result
301 }
302
303 pub fn text_input<T: ToString + FromStr + Send + Sync>(
304 value: &T,
305 props: impl Into<Props>,
306 mut f: impl FnMut(&str, TextInputState),
307 ) -> (Option<T>, TextInputState) {
308 use crate::internal::*;
309 let content = use_state(|| value.to_string());
310 let props = props.into();
311 let TextInputProps { allow_new_line, .. } = props.read_cloned_or_default();
312 let text_state = use_state(TextInputState::default);
313 let text_result = text_state.read().unwrap().to_owned();
314 if !text_result.focused {
315 *content.write().unwrap() = value.to_string();
316 }
317 let result = content.read().unwrap().to_string();
318 begin();
319 f(&result, text_result);
320 let node = end().pop().unwrap_or_default();
321 push(
322 make_widget!(immediate_text_input)
323 .with_props(ImmediateTextInputProps {
324 state: Some(text_state),
325 })
326 .merge_props(props)
327 .with_props(TextInputProps {
328 allow_new_line,
329 text: Some(content.into()),
330 })
331 .named_slot("content", node),
332 );
333 (result.parse().ok(), text_result)
334 }
335
336 pub fn input_field<T: ToString + FromStr + Send + Sync>(
337 value: &T,
338 props: impl Into<Props>,
339 mut f: impl FnMut(&str, TextInputState, ImmediateButton),
340 ) -> (Option<T>, TextInputState, ImmediateButton) {
341 use crate::internal::*;
342 let content = use_state(|| value.to_string());
343 let props = props.into();
344 let TextInputProps { allow_new_line, .. } = props.read_cloned_or_default();
345 let text_state = use_state(TextInputState::default);
346 let text_result = text_state.read().unwrap().to_owned();
347 let button_state = use_state(ImmediateButton::default);
348 let button_result = button_state.read().unwrap().to_owned();
349 if !text_result.focused {
350 *content.write().unwrap() = value.to_string();
351 }
352 let result = content.read().unwrap().to_string();
353 begin();
354 f(&result, text_result, button_result);
355 let node = end().pop().unwrap_or_default();
356 push(
357 make_widget!(immediate_input_field)
358 .with_props(ImmediateTextInputProps {
359 state: Some(text_state),
360 })
361 .with_props(ImmediateButtonProps {
362 state: Some(button_state),
363 })
364 .merge_props(props)
365 .with_props(TextInputProps {
366 allow_new_line,
367 text: Some(content.into()),
368 })
369 .named_slot("content", node),
370 );
371 (result.parse().ok(), text_result, button_result)
372 }
373
374 pub fn slider_view<T: SliderViewProxy + Clone + 'static>(
375 value: T,
376 props: impl Into<Props>,
377 mut f: impl FnMut(&T, ImmediateButton),
378 ) -> (T, ImmediateButton) {
379 use crate::internal::*;
380 let content = use_state(|| value.to_owned());
381 let props = props.into();
382 let SliderViewProps {
383 from,
384 to,
385 direction,
386 ..
387 } = props.read_cloned_or_default();
388 let button_state = use_state(ImmediateButton::default);
389 let button_result = button_state.read().unwrap().to_owned();
390 let result = content.read().unwrap().to_owned();
391 begin();
392 f(&result, button_result);
393 let node = end().pop().unwrap_or_default();
394 push(
395 make_widget!(immediate_slider_view)
396 .with_props(ImmediateButtonProps {
397 state: Some(button_state),
398 })
399 .merge_props(props)
400 .with_props(SliderViewProps {
401 input: Some(content.into()),
402 from,
403 to,
404 direction,
405 })
406 .named_slot("content", node),
407 );
408 (result, button_result)
409 }
410
411 pub fn options_view<T: OptionsViewProxy + Clone + 'static>(
412 value: T,
413 props: impl Into<Props>,
414 mut f_items: impl FnMut(&T),
415 mut f_content: impl FnMut(),
416 ) -> T {
417 let content = use_state(|| value.to_owned());
418 let props = props.into();
419 let result = content.read().unwrap().to_owned();
420 begin();
421 f_items(&result);
422 let nodes = end();
423 begin();
424 f_content();
425 let node = pop();
426 push(
427 make_widget!(raui_core::widget::component::interactive::options_view::options_view)
428 .merge_props(props)
429 .with_props(OptionsViewProps {
430 input: Some(content.into()),
431 })
432 .named_slot("content", node)
433 .listed_slots(nodes),
434 );
435 result
436 }
437 }
438}
439
440pub mod material {
441 impl_components! {
442 icon_paper,
443 scroll_paper_side_scrollbars,
444 switch_paper,
445 text_paper,
446 }
447
448 pub mod containers {
449 impl_slot_components! {
450 context_paper,
451 scroll_paper,
452 tooltip_paper,
453 }
454
455 impl_content_components! {
456 "content":
457 modal_paper,
458 text_tooltip_paper,
459 wrap_paper,
460 }
461
462 impl_list_components! {
463 flex_paper,
464 grid_paper,
465 horizontal_paper,
466 nav_flex_paper,
467 nav_grid_paper,
468 nav_horizontal_paper,
469 nav_vertical_paper,
470 paper,
471 vertical_paper,
472 }
473 }
474
475 pub mod interactive {
476 use crate::core::interactive::ImmediateButton;
477 use raui_core::{
478 make_widget,
479 props::Props,
480 widget::component::interactive::{
481 input_field::{TextInputProps, TextInputState},
482 slider_view::{SliderViewProps, SliderViewProxy},
483 },
484 };
485 use raui_immediate::{begin, end, push, use_state};
486 use std::str::FromStr;
487
488 pub fn button_paper(
489 props: impl Into<Props>,
490 mut f: impl FnMut(ImmediateButton),
491 ) -> ImmediateButton {
492 use crate::internal::*;
493 let state = use_state(ImmediateButton::default);
494 let result = state.read().unwrap().to_owned();
495 begin();
496 f(result);
497 let node = end().pop().unwrap_or_default();
498 push(
499 make_widget!(immediate_button_paper)
500 .with_props(ImmediateButtonProps { state: Some(state) })
501 .merge_props(props.into())
502 .named_slot("content", node),
503 );
504 result
505 }
506
507 pub fn icon_button_paper(props: impl Into<Props>) -> ImmediateButton {
508 use crate::internal::*;
509 let state = use_state(ImmediateButton::default);
510 let result = state.read().unwrap().to_owned();
511 push(
512 make_widget!(immediate_icon_button_paper)
513 .with_props(ImmediateButtonProps { state: Some(state) })
514 .merge_props(props.into()),
515 );
516 result
517 }
518
519 pub fn switch_button_paper(props: impl Into<Props>) -> ImmediateButton {
520 use crate::internal::*;
521 let state = use_state(ImmediateButton::default);
522 let result = state.read().unwrap().to_owned();
523 push(
524 make_widget!(immediate_switch_button_paper)
525 .with_props(ImmediateButtonProps { state: Some(state) })
526 .merge_props(props.into()),
527 );
528 result
529 }
530
531 pub fn text_button_paper(props: impl Into<Props>) -> ImmediateButton {
532 use crate::internal::*;
533 let state = use_state(ImmediateButton::default);
534 let result = state.read().unwrap().to_owned();
535 push(
536 make_widget!(immediate_text_button_paper)
537 .with_props(ImmediateButtonProps { state: Some(state) })
538 .merge_props(props.into()),
539 );
540 result
541 }
542
543 pub fn text_field_paper<T: ToString + FromStr + Send + Sync>(
544 value: &T,
545 props: impl Into<Props>,
546 ) -> (Option<T>, TextInputState, ImmediateButton) {
547 use crate::internal::*;
548 let content = use_state(|| value.to_string());
549 let props = props.into();
550 let TextInputProps { allow_new_line, .. } =
551 props.read_cloned_or_default::<TextInputProps>();
552 let text_state = use_state(TextInputState::default);
553 let text_result = text_state.read().unwrap().to_owned();
554 let button_state = use_state(ImmediateButton::default);
555 let button_result = button_state.read().unwrap().to_owned();
556 if !text_result.focused {
557 *content.write().unwrap() = value.to_string();
558 }
559 let result = content.read().unwrap().to_string();
560 push(
561 make_widget!(immediate_text_field_paper)
562 .with_props(ImmediateTextInputProps {
563 state: Some(text_state),
564 })
565 .with_props(ImmediateButtonProps {
566 state: Some(button_state),
567 })
568 .merge_props(props)
569 .with_props(TextInputProps {
570 allow_new_line,
571 text: Some(content.into()),
572 }),
573 );
574 (result.parse().ok(), text_result, button_result)
575 }
576
577 pub fn slider_paper<T: SliderViewProxy + Clone + 'static>(
578 value: T,
579 props: impl Into<Props>,
580 mut f: impl FnMut(&T, ImmediateButton),
581 ) -> (T, ImmediateButton) {
582 use crate::internal::*;
583 let content = use_state(|| value.to_owned());
584 let props = props.into();
585 let SliderViewProps {
586 from,
587 to,
588 direction,
589 ..
590 } = props.read_cloned_or_default();
591 let button_state = use_state(ImmediateButton::default);
592 let button_result = button_state.read().unwrap().to_owned();
593 let result = content.read().unwrap().to_owned();
594 begin();
595 f(&result, button_result);
596 let node = end().pop().unwrap_or_default();
597 push(
598 make_widget!(immediate_slider_paper)
599 .with_props(ImmediateButtonProps {
600 state: Some(button_state),
601 })
602 .merge_props(props)
603 .with_props(SliderViewProps {
604 input: Some(content.into()),
605 from,
606 to,
607 direction,
608 })
609 .named_slot("content", node),
610 );
611 (result, button_result)
612 }
613
614 pub fn numeric_slider_paper<T: SliderViewProxy + Clone + 'static>(
615 value: T,
616 props: impl Into<Props>,
617 ) -> (T, ImmediateButton) {
618 use crate::internal::*;
619 let content = use_state(|| value.to_owned());
620 let props = props.into();
621 let SliderViewProps {
622 from,
623 to,
624 direction,
625 ..
626 } = props.read_cloned_or_default();
627 let button_state = use_state(ImmediateButton::default);
628 let button_result = button_state.read().unwrap().to_owned();
629 let result = content.read().unwrap().to_owned();
630 push(
631 make_widget!(immediate_numeric_slider_paper)
632 .with_props(ImmediateButtonProps {
633 state: Some(button_state),
634 })
635 .merge_props(props)
636 .with_props(SliderViewProps {
637 input: Some(content.into()),
638 from,
639 to,
640 direction,
641 }),
642 );
643 (result, button_result)
644 }
645 }
646}
647
648mod internal {
649 use crate::core::interactive::{ImmediateButton, ImmediateTracking};
650 use raui_core::{
651 ManagedLazy, Prefab, PropsData, make_widget, pre_hooks,
652 widget::{
653 component::interactive::{
654 button::{ButtonNotifyMessage, ButtonNotifyProps, button},
655 input_field::{TextInputState, input_field, text_input},
656 navigation::{
657 NavTrackingNotifyMessage, NavTrackingNotifyProps, self_tracking, tracking,
658 use_nav_tracking_self,
659 },
660 slider_view::slider_view,
661 },
662 context::WidgetContext,
663 node::WidgetNode,
664 },
665 };
666 use raui_material::component::interactive::{
667 button_paper::button_paper_impl,
668 icon_button_paper::icon_button_paper_impl,
669 slider_paper::{numeric_slider_paper_impl, slider_paper_impl},
670 switch_button_paper::switch_button_paper_impl,
671 text_button_paper::text_button_paper_impl,
672 text_field_paper::text_field_paper_impl,
673 };
674 use serde::{Deserialize, Serialize};
675
676 #[derive(PropsData, Default, Clone, Serialize, Deserialize)]
677 #[props_data(raui_core::props::PropsData)]
678 #[prefab(raui_core::Prefab)]
679 pub struct ImmediateTrackingProps {
680 #[serde(default, skip)]
681 pub state: Option<ManagedLazy<ImmediateTracking>>,
682 }
683
684 impl std::fmt::Debug for ImmediateTrackingProps {
685 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
686 f.debug_struct("ImmediateTrackingProps")
687 .field(
688 "state",
689 &self
690 .state
691 .as_ref()
692 .and_then(|state| state.read())
693 .map(|state| *state),
694 )
695 .finish()
696 }
697 }
698
699 #[derive(PropsData, Default, Clone, Serialize, Deserialize)]
700 #[props_data(raui_core::props::PropsData)]
701 #[prefab(raui_core::Prefab)]
702 pub struct ImmediateButtonProps {
703 #[serde(default, skip)]
704 pub state: Option<ManagedLazy<ImmediateButton>>,
705 }
706
707 impl std::fmt::Debug for ImmediateButtonProps {
708 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
709 f.debug_struct("ImmediateButtonProps")
710 .field(
711 "state",
712 &self
713 .state
714 .as_ref()
715 .and_then(|state| state.read())
716 .map(|state| *state),
717 )
718 .finish()
719 }
720 }
721
722 #[derive(PropsData, Default, Clone, Serialize, Deserialize)]
723 #[props_data(raui_core::props::PropsData)]
724 pub struct ImmediateTextInputProps {
725 #[serde(default, skip)]
726 pub state: Option<ManagedLazy<TextInputState>>,
727 }
728
729 impl std::fmt::Debug for ImmediateTextInputProps {
730 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
731 f.debug_struct("ImmediateTextInputProps")
732 .finish_non_exhaustive()
733 }
734 }
735
736 fn use_immediate_tracking(ctx: &mut WidgetContext) {
737 ctx.props
738 .write(NavTrackingNotifyProps(ctx.id.to_owned().into()));
739
740 if let Ok(props) = ctx.props.read::<ImmediateTrackingProps>() {
741 let state = props.state.as_ref().unwrap();
742 let mut state = state.write().unwrap();
743 state.prev = state.state;
744 }
745
746 ctx.life_cycle.change(|ctx| {
747 if let Ok(props) = ctx.props.read::<ImmediateTrackingProps>()
748 && let Some(state) = props.state.as_ref()
749 && let Some(mut state) = state.write()
750 {
751 for msg in ctx.messenger.messages {
752 if let Some(msg) = msg.as_any().downcast_ref::<NavTrackingNotifyMessage>() {
753 state.state = msg.state;
754 }
755 }
756 }
757 });
758 }
759
760 fn use_immediate_button(ctx: &mut WidgetContext) {
761 ctx.props.write(ButtonNotifyProps(ctx.id.to_owned().into()));
762
763 if let Ok(props) = ctx.props.read::<ImmediateButtonProps>() {
764 let state = props.state.as_ref().unwrap();
765 let mut state = state.write().unwrap();
766 state.prev = state.state;
767 }
768
769 ctx.life_cycle.change(|ctx| {
770 if let Ok(props) = ctx.props.read::<ImmediateButtonProps>()
771 && let Some(state) = props.state.as_ref()
772 && let Some(mut state) = state.write()
773 {
774 for msg in ctx.messenger.messages {
775 if let Some(msg) = msg.as_any().downcast_ref::<ButtonNotifyMessage>() {
776 state.state = msg.state;
777 }
778 }
779 }
780 });
781 }
782
783 fn use_immediate_text_input(ctx: &mut WidgetContext) {
784 if let Ok(data) = ctx.state.read_cloned::<TextInputState>()
785 && let Ok(props) = ctx.props.read::<ImmediateTextInputProps>()
786 {
787 let state = props.state.as_ref().unwrap();
788 let mut state = state.write().unwrap();
789 *state = data;
790 }
791 }
792
793 #[pre_hooks(use_immediate_tracking)]
794 pub(crate) fn immediate_tracking(mut ctx: WidgetContext) -> WidgetNode {
795 tracking(ctx)
796 }
797
798 #[pre_hooks(use_immediate_tracking, use_nav_tracking_self)]
799 pub(crate) fn immediate_self_tracking(mut ctx: WidgetContext) -> WidgetNode {
800 self_tracking(ctx)
801 }
802
803 #[pre_hooks(use_immediate_button)]
804 pub(crate) fn immediate_button(mut ctx: WidgetContext) -> WidgetNode {
805 button(ctx)
806 }
807
808 #[pre_hooks(use_immediate_text_input)]
809 pub(crate) fn immediate_text_input(mut ctx: WidgetContext) -> WidgetNode {
810 text_input(ctx)
811 }
812
813 #[pre_hooks(use_immediate_text_input, use_immediate_button)]
814 pub(crate) fn immediate_input_field(mut ctx: WidgetContext) -> WidgetNode {
815 input_field(ctx)
816 }
817
818 #[pre_hooks(use_immediate_button)]
819 pub(crate) fn immediate_slider_view(mut ctx: WidgetContext) -> WidgetNode {
820 slider_view(ctx)
821 }
822
823 pub(crate) fn immediate_button_paper(ctx: WidgetContext) -> WidgetNode {
824 button_paper_impl(make_widget!(immediate_button), ctx)
825 }
826
827 pub(crate) fn immediate_icon_button_paper(ctx: WidgetContext) -> WidgetNode {
828 icon_button_paper_impl(make_widget!(immediate_button_paper), ctx)
829 }
830
831 pub(crate) fn immediate_switch_button_paper(ctx: WidgetContext) -> WidgetNode {
832 switch_button_paper_impl(make_widget!(immediate_button_paper), ctx)
833 }
834
835 pub(crate) fn immediate_text_button_paper(ctx: WidgetContext) -> WidgetNode {
836 text_button_paper_impl(make_widget!(immediate_button_paper), ctx)
837 }
838
839 pub(crate) fn immediate_text_field_paper(ctx: WidgetContext) -> WidgetNode {
840 text_field_paper_impl(make_widget!(immediate_input_field), ctx)
841 }
842
843 pub(crate) fn immediate_slider_paper(ctx: WidgetContext) -> WidgetNode {
844 slider_paper_impl(make_widget!(immediate_slider_view), ctx)
845 }
846
847 pub(crate) fn immediate_numeric_slider_paper(ctx: WidgetContext) -> WidgetNode {
848 numeric_slider_paper_impl(make_widget!(immediate_slider_paper), ctx)
849 }
850}