1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Make sure you have seen `context_box` code example first, because this is an evolution of that.
use raui_app::app::declarative::DeclarativeApp;
use raui_core::{
make_widget, pre_hooks,
widget::{
WidgetRef,
component::{
containers::{
anchor_box::PivotBoxProps,
content_box::content_box,
horizontal_box::{HorizontalBoxProps, horizontal_box},
portal_box::PortalsContainer,
tooltip_box::portals_tooltip_box,
},
image_box::{ImageBoxProps, image_box},
interactive::{
button::button,
navigation::{NavItemActive, use_nav_container_active},
},
},
context::WidgetContext,
node::WidgetNode,
unit::{
flex::FlexBoxItemLayout,
image::{ImageBoxColor, ImageBoxMaterial, ImageBoxSizeValue},
},
utils::{Color, Vec2},
},
};
// we mark app as an active navigable container to let all buttons down the tree register to the
// navigation system so they can react on mouse hovering for example.
#[pre_hooks(use_nav_container_active)]
fn app(mut ctx: WidgetContext) -> WidgetNode {
let idref = WidgetRef::default();
make_widget!(content_box)
.idref(idref.clone())
.with_shared_props(PortalsContainer(idref))
.listed_slot(
make_widget!(horizontal_box)
.with_props(HorizontalBoxProps {
separation: 25.0,
override_slots_layout: Some(FlexBoxItemLayout::cleared()),
..Default::default()
})
.listed_slot(make_widget!(icon).with_props(Color {
r: 1.0,
g: 0.25,
b: 0.25,
a: 1.0,
}))
.listed_slot(
make_widget!(icon)
.with_props(Color {
r: 0.25,
g: 1.0,
b: 0.25,
a: 1.0,
})
.with_props(PivotBoxProps {
pivot: Vec2 { x: 0.5, y: 1.0 },
align: Vec2 { x: 0.5, y: 0.0 },
}),
)
.listed_slot(
make_widget!(icon)
.with_props(Color {
r: 0.25,
g: 0.25,
b: 1.0,
a: 1.0,
})
.with_props(PivotBoxProps {
pivot: Vec2 { x: 1.0, y: 1.0 },
align: Vec2 { x: 1.0, y: 0.0 },
}),
),
)
.into()
}
fn icon(ctx: WidgetContext) -> WidgetNode {
// tooltip box is basically an evolution of context box - what changes is tooltip box is shown
// only if this its content gets selected by navigation system (and since buttons can be
// selected for example by mouse hover, this tooltip is shown whenever mouse gets over the
// widget it wraps).
make_widget!(portals_tooltip_box)
.with_props(ctx.props.read_cloned_or_default::<PivotBoxProps>())
// put colored image box as content widget.
.named_slot(
"content",
// we wrap content with button to allow automated widget selection that will show tooltip,
make_widget!(button)
// remember that buttons has to be activated to make them receive selection
// navigation messages - they are inactive by default.
.with_props(NavItemActive)
.named_slot(
"content",
make_widget!(image_box).with_props(ImageBoxProps {
material: ImageBoxMaterial::Color(ImageBoxColor {
color: ctx.props.read_cloned_or_default::<Color>(),
..Default::default()
}),
width: ImageBoxSizeValue::Exact(100.0),
height: ImageBoxSizeValue::Exact(100.0),
..Default::default()
}),
),
)
// put gray image box as tooltip widget.
.named_slot(
"tooltip",
make_widget!(image_box).with_props(ImageBoxProps {
material: ImageBoxMaterial::Color(ImageBoxColor {
color: Color {
r: 0.25,
g: 0.25,
b: 0.25,
a: 1.0,
},
..Default::default()
}),
width: ImageBoxSizeValue::Exact(150.0),
height: ImageBoxSizeValue::Exact(50.0),
..Default::default()
}),
)
.into()
}
fn main() {
DeclarativeApp::simple("Tooltip Box", make_widget!(app));
}