pub struct Ui {
pub frame: u64,
/* private fields */
}
Fields§
§frame: u64
Returns the number of frames that have elapsed since the program started.
Implementations§
Source§impl Ui
impl Ui
Examples found in repository?
4async fn main() {
5 set_pc_assets_folder("examples");
6
7 let sound1 = audio::load_sound("sound.wav").await.unwrap();
8 let sound2 = audio::load_sound("sound2.wav").await.unwrap();
9
10 loop {
11 clear_background(LIGHTGRAY);
12
13 if ui::root_ui().button(None, "Play sound 1") {
14 warn!("play 1!");
15 audio::play_sound_once(&sound1);
16 }
17 if ui::root_ui().button(None, "Play sound 2") {
18 warn!("play 2!");
19 audio::play_sound_once(&sound2);
20 }
21 next_frame().await
22 }
23}
More examples
5async fn main() {
6 prevent_quit();
7
8 let mut show_exit_dialog = false;
9 let mut user_decided_to_exit = false;
10
11 loop {
12 clear_background(GRAY);
13
14 if is_quit_requested() {
15 show_exit_dialog = true;
16 }
17
18 if show_exit_dialog {
19 let dialog_size = vec2(200., 70.);
20 let screen_size = vec2(screen_width(), screen_height());
21 let dialog_position = screen_size / 2. - dialog_size / 2.;
22 Window::new(hash!(), dialog_position, dialog_size).ui(&mut *root_ui(), |ui| {
23 ui.label(None, "Do you really want to quit?");
24 ui.separator();
25 ui.same_line(60.);
26 if ui.button(None, "Yes") {
27 user_decided_to_exit = true;
28 }
29 ui.same_line(120.);
30 if ui.button(None, "No") {
31 show_exit_dialog = false;
32 }
33 });
34 }
35
36 if user_decided_to_exit {
37 break;
38 }
39
40 next_frame().await
41 }
42}
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Source§impl Ui
impl Ui
Sourcepub fn checkbox(&mut self, id: Id, label: &str, data: &mut bool)
pub fn checkbox(&mut self, id: Id, label: &str, data: &mut bool)
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Source§impl Ui
impl Ui
Sourcepub fn combo_box<'a>(
&mut self,
id: Id,
label: &str,
variants: &[&str],
data: impl Into<Option<&'a mut usize>>,
) -> usize
pub fn combo_box<'a>( &mut self, id: Id, label: &str, variants: &[&str], data: impl Into<Option<&'a mut usize>>, ) -> usize
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
More examples
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Source§impl Ui
impl Ui
Sourcepub fn drag<T: Num, T1: Into<Option<(T, T)>>>(
&mut self,
id: Id,
label: &str,
range: T1,
data: &mut T,
)
pub fn drag<T: Num, T1: Into<Option<(T, T)>>>( &mut self, id: Id, label: &str, range: T1, data: &mut T, )
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Source§impl Ui
impl Ui
Sourcepub fn editbox(&mut self, id: Id, size: Vec2, text: &mut String) -> bool
pub fn editbox(&mut self, id: Id, size: Vec2, text: &mut String) -> bool
Examples found in repository?
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
More examples
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Source§impl Ui
impl Ui
Sourcepub fn group<F: FnOnce(&mut Ui)>(&mut self, id: Id, size: Vec2, f: F) -> Drag
pub fn group<F: FnOnce(&mut Ui)>(&mut self, id: Id, size: Vec2, f: F) -> Drag
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Source§impl Ui
impl Ui
Sourcepub fn input_text(&mut self, id: Id, label: &str, data: &mut String)
pub fn input_text(&mut self, id: Id, label: &str, data: &mut String)
Examples found in repository?
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
More examples
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
pub fn input_password(&mut self, id: Id, label: &str, data: &mut String)
Source§impl Ui
impl Ui
Sourcepub fn label<P: Into<Option<Vec2>>>(&mut self, position: P, label: &str)
pub fn label<P: Into<Option<Vec2>>>(&mut self, position: P, label: &str)
Examples found in repository?
5async fn main() {
6 prevent_quit();
7
8 let mut show_exit_dialog = false;
9 let mut user_decided_to_exit = false;
10
11 loop {
12 clear_background(GRAY);
13
14 if is_quit_requested() {
15 show_exit_dialog = true;
16 }
17
18 if show_exit_dialog {
19 let dialog_size = vec2(200., 70.);
20 let screen_size = vec2(screen_width(), screen_height());
21 let dialog_position = screen_size / 2. - dialog_size / 2.;
22 Window::new(hash!(), dialog_position, dialog_size).ui(&mut *root_ui(), |ui| {
23 ui.label(None, "Do you really want to quit?");
24 ui.separator();
25 ui.same_line(60.);
26 if ui.button(None, "Yes") {
27 user_decided_to_exit = true;
28 }
29 ui.same_line(120.);
30 if ui.button(None, "No") {
31 show_exit_dialog = false;
32 }
33 });
34 }
35
36 if user_decided_to_exit {
37 break;
38 }
39
40 next_frame().await
41 }
42}
More examples
6async fn main() {
7 loop {
8 clear_background(WHITE);
9 root_ui().window(hash!(), Vec2::new(20., 20.), Vec2::new(450., 200.), |ui| {
10 let (mouse_x, mouse_y) = mouse_position();
11 ui.label(None, &format!("Mouse position: {mouse_x} {mouse_y}"));
12
13 let (mouse_wheel_x, mouse_wheel_y) = mouse_wheel();
14 ui.label(None, &format!("Mouse wheel x: {mouse_wheel_x}"));
15 ui.label(None, &format!("Mouse wheel y: {mouse_wheel_y}"));
16
17 widgets::Group::new(hash!(), Vec2::new(200., 90.))
18 .position(Vec2::new(240., 0.))
19 .ui(ui, |ui| {
20 ui.label(None, "Pressed kbd keys");
21
22 if let Some(key) = get_last_key_pressed() {
23 ui.label(None, &format!("{key:?}"))
24 }
25 });
26
27 widgets::Group::new(hash!(), Vec2::new(200., 90.))
28 .position(Vec2::new(240., 92.))
29 .ui(ui, |ui| {
30 ui.label(None, "Pressed mouse keys");
31
32 if is_mouse_button_down(MouseButton::Left) {
33 ui.label(None, "Left");
34 }
35 if is_mouse_button_down(MouseButton::Right) {
36 ui.label(None, "Right");
37 }
38 if is_mouse_button_down(MouseButton::Middle) {
39 ui.label(None, "Middle");
40 }
41 });
42 });
43 next_frame().await;
44 }
45}
52 fn slots(&mut self, ui: &mut Ui) {
53 let item_dragging = &mut self.item_dragging;
54
55 let fit_command = &mut self.fit_command;
56 for (label, slot) in self.slots.iter_mut() {
57 Group::new(hash!("grp", slot.id, &label), Vec2::new(210., 55.)).ui(ui, |ui| {
58 let drag = Group::new(slot.id, Vec2::new(50., 50.))
59 // slot without item is not draggable
60 .draggable(slot.item.is_some())
61 // but could be a target of drag
62 .hoverable(*item_dragging)
63 // and is highlighted with other color when some item is dragging
64 .highlight(*item_dragging)
65 .ui(ui, |ui| {
66 if let Some(ref item) = slot.item {
67 ui.label(Vec2::new(5., 10.), &item);
68 }
69 });
70
71 match drag {
72 // there is some item in this slot and it was dragged to another slot
73 Drag::Dropped(_, Some(id)) if slot.item.is_some() => {
74 *fit_command = Some(FittingCommand::Refit {
75 target_slot: id,
76 origin_slot: slot.id,
77 });
78 }
79 // there is some item in this slot and it was dragged out - unfit it
80 Drag::Dropped(_, None) if slot.item.is_some() => {
81 *fit_command = Some(FittingCommand::Unfit {
82 target_slot: slot.id,
83 });
84 }
85 // there is no item in this slot
86 // this is impossible - slots without items are non-draggable
87 Drag::Dropped(_, _) => unreachable!(),
88 Drag::Dragging(pos, id) => {
89 debug!("slots: pos: {:?}, id {:?}", pos, id);
90 *item_dragging = true;
91 }
92 Drag::No => {}
93 }
94 ui.label(Vec2::new(60., 20.), label);
95 });
96 }
97 }
98
99 fn inventory(&mut self, ui: &mut Ui) {
100 let item_dragging = &mut self.item_dragging;
101 for (n, item) in self.inventory.iter().enumerate() {
102 let drag = Group::new(hash!("inventory", n), Vec2::new(50., 50.))
103 .draggable(true)
104 .ui(ui, |ui| {
105 ui.label(Vec2::new(5., 10.), &item);
106 });
107
108 match drag {
109 Drag::Dropped(_, Some(id)) => {
110 self.fit_command = Some(FittingCommand::Fit {
111 target_slot: id,
112 item: item.clone(),
113 });
114 *item_dragging = false;
115 }
116 Drag::Dropped(_, _) => {
117 *item_dragging = false;
118 }
119 Drag::Dragging(pos, id) => {
120 debug!("inventory: pos: {:?}, id {:?}", pos, id);
121 *item_dragging = true;
122 }
123 _ => {}
124 }
125 }
126 }
127
128 fn set_item(&mut self, id: u64, item: Option<String>) {
129 if let Some(slot) = self.slots.iter_mut().find(|(_, slot)| slot.id == id) {
130 slot.1.item = item;
131 }
132 }
133}
134
135#[macroquad::main("UI showcase")]
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
pub fn calc_size(&mut self, label: &str) -> Vec2
Source§impl Ui
impl Ui
Sourcepub fn separator(&mut self)
pub fn separator(&mut self)
Examples found in repository?
5async fn main() {
6 prevent_quit();
7
8 let mut show_exit_dialog = false;
9 let mut user_decided_to_exit = false;
10
11 loop {
12 clear_background(GRAY);
13
14 if is_quit_requested() {
15 show_exit_dialog = true;
16 }
17
18 if show_exit_dialog {
19 let dialog_size = vec2(200., 70.);
20 let screen_size = vec2(screen_width(), screen_height());
21 let dialog_position = screen_size / 2. - dialog_size / 2.;
22 Window::new(hash!(), dialog_position, dialog_size).ui(&mut *root_ui(), |ui| {
23 ui.label(None, "Do you really want to quit?");
24 ui.separator();
25 ui.same_line(60.);
26 if ui.button(None, "Yes") {
27 user_decided_to_exit = true;
28 }
29 ui.same_line(120.);
30 if ui.button(None, "No") {
31 show_exit_dialog = false;
32 }
33 });
34 }
35
36 if user_decided_to_exit {
37 break;
38 }
39
40 next_frame().await
41 }
42}
More examples
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Source§impl Ui
impl Ui
Sourcepub fn slider(&mut self, id: Id, label: &str, range: Range<f32>, data: &mut f32)
pub fn slider(&mut self, id: Id, label: &str, range: Range<f32>, data: &mut f32)
Examples found in repository?
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
Source§impl Ui
impl Ui
Sourcepub fn tree_node<F: FnOnce(&mut Ui)>(
&mut self,
id: Id,
label: &str,
f: F,
) -> bool
pub fn tree_node<F: FnOnce(&mut Ui)>( &mut self, id: Id, label: &str, f: F, ) -> bool
Examples found in repository?
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
More examples
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Source§impl Ui
impl Ui
Sourcepub fn window<F: FnOnce(&mut Ui)>(
&mut self,
id: Id,
position: Vec2,
size: Vec2,
f: F,
) -> bool
pub fn window<F: FnOnce(&mut Ui)>( &mut self, id: Id, position: Vec2, size: Vec2, f: F, ) -> bool
Examples found in repository?
6async fn main() {
7 loop {
8 clear_background(WHITE);
9 root_ui().window(hash!(), Vec2::new(20., 20.), Vec2::new(450., 200.), |ui| {
10 let (mouse_x, mouse_y) = mouse_position();
11 ui.label(None, &format!("Mouse position: {mouse_x} {mouse_y}"));
12
13 let (mouse_wheel_x, mouse_wheel_y) = mouse_wheel();
14 ui.label(None, &format!("Mouse wheel x: {mouse_wheel_x}"));
15 ui.label(None, &format!("Mouse wheel y: {mouse_wheel_y}"));
16
17 widgets::Group::new(hash!(), Vec2::new(200., 90.))
18 .position(Vec2::new(240., 0.))
19 .ui(ui, |ui| {
20 ui.label(None, "Pressed kbd keys");
21
22 if let Some(key) = get_last_key_pressed() {
23 ui.label(None, &format!("{key:?}"))
24 }
25 });
26
27 widgets::Group::new(hash!(), Vec2::new(200., 90.))
28 .position(Vec2::new(240., 92.))
29 .ui(ui, |ui| {
30 ui.label(None, "Pressed mouse keys");
31
32 if is_mouse_button_down(MouseButton::Left) {
33 ui.label(None, "Left");
34 }
35 if is_mouse_button_down(MouseButton::Right) {
36 ui.label(None, "Right");
37 }
38 if is_mouse_button_down(MouseButton::Middle) {
39 ui.label(None, "Middle");
40 }
41 });
42 });
43 next_frame().await;
44 }
45}
More examples
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Source§impl Ui
impl Ui
pub fn new( ctx: &mut dyn RenderingBackend, screen_width: f32, screen_height: f32, ) -> Ui
pub fn set_default_skin(&mut self, _skin: Skin)
Sourcepub fn style_builder(&self) -> StyleBuilder
pub fn style_builder(&self) -> StyleBuilder
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Sourcepub fn default_skin(&self) -> Skin
pub fn default_skin(&self) -> Skin
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Sourcepub fn last_item_clicked(&mut self) -> bool
pub fn last_item_clicked(&mut self) -> bool
Returns true if the last widget which had .ui
called on it is being clicked.
Sourcepub fn last_item_hovered(&mut self) -> bool
pub fn last_item_hovered(&mut self) -> bool
Returns true if the mouse is over the last widget which had .ui
called on it.
Sourcepub fn scroll_here(&mut self)
pub fn scroll_here(&mut self)
Scrolls the middle of the active GUI window to its GUI cursor
Note that this does not work on the first frame of the GUI application.
If you want your widget to start with its scrollbar in a particular location,
consider if ui.frame == 1 { ui.scroll_here() }
.
Sourcepub fn scroll_here_ratio(&mut self, ratio: f32)
pub fn scroll_here_ratio(&mut self, ratio: f32)
Scrolls the active GUI window to its GUI cursor.
1.0 puts the bottom of the window at the GUI cursor, 0.0 puts the top of the window there.
0.5 as the ratio puts the middle of the window at the GUI cursor,
and is equivalent to Ui::scroll_here
.
Sourcepub fn scroll(&mut self) -> Vec2
pub fn scroll(&mut self) -> Vec2
How far the active gui window has been scrolled down on the y axis.
Note that for these purposes, a Group widget is still considered a Window because it can have its own scrollbar.
Sourcepub fn scroll_max(&mut self) -> Vec2
pub fn scroll_max(&mut self) -> Vec2
The farthest down a scrollbar may go given the constraints of its window.
Note that for these purposes, a Group widget is still considered a Window because it can have its own scrollbar.
pub const fn is_mouse_captured(&self) -> bool
pub fn is_mouse_over(&self, mouse_position: Vec2) -> bool
Sourcepub fn active_window_focused(&self) -> bool
pub fn active_window_focused(&self) -> bool
Examples found in repository?
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
pub const fn is_dragging(&self) -> bool
pub fn close_current_window(&mut self)
pub fn new_frame(&mut self, delta: f32)
pub fn render(&mut self, draw_list: &mut Vec<DrawList>)
pub fn focus_window(&mut self, id: Id)
pub fn set_input_focus(&mut self, id: Id)
pub fn clear_input_focus(&mut self)
pub fn move_window(&mut self, id: Id, position: Vec2)
Sourcepub fn same_line(&mut self, x: f32)
pub fn same_line(&mut self, x: f32)
Examples found in repository?
5async fn main() {
6 prevent_quit();
7
8 let mut show_exit_dialog = false;
9 let mut user_decided_to_exit = false;
10
11 loop {
12 clear_background(GRAY);
13
14 if is_quit_requested() {
15 show_exit_dialog = true;
16 }
17
18 if show_exit_dialog {
19 let dialog_size = vec2(200., 70.);
20 let screen_size = vec2(screen_width(), screen_height());
21 let dialog_position = screen_size / 2. - dialog_size / 2.;
22 Window::new(hash!(), dialog_position, dialog_size).ui(&mut *root_ui(), |ui| {
23 ui.label(None, "Do you really want to quit?");
24 ui.separator();
25 ui.same_line(60.);
26 if ui.button(None, "Yes") {
27 user_decided_to_exit = true;
28 }
29 ui.same_line(120.);
30 if ui.button(None, "No") {
31 show_exit_dialog = false;
32 }
33 });
34 }
35
36 if user_decided_to_exit {
37 break;
38 }
39
40 next_frame().await
41 }
42}
More examples
136async fn main() {
137 let mut data = Data::new();
138
139 let mut data0 = String::new();
140 let mut data1 = String::new();
141
142 let mut text0 = String::new();
143 let mut text1 = String::new();
144
145 let mut number0 = 0.;
146 let mut number1 = 0.;
147
148 let texture: Texture2D = load_texture("examples/ferris.png").await.unwrap();
149
150 loop {
151 clear_background(WHITE);
152
153 widgets::Window::new(hash!(), vec2(400., 200.), vec2(320., 400.))
154 .label("Shop")
155 .titlebar(true)
156 .ui(&mut *root_ui(), |ui| {
157 for i in 0..30 {
158 Group::new(hash!("shop", i), Vec2::new(300., 80.)).ui(ui, |ui| {
159 ui.label(Vec2::new(10., 10.), &format!("Item N {i}"));
160 ui.label(Vec2::new(260., 40.), "10/10");
161 ui.label(Vec2::new(200., 58.), &format!("{} kr", 800));
162 if ui.button(Vec2::new(260., 55.), "buy") {
163 data.inventory.push(format!("Item {i}"));
164 }
165 });
166 }
167 });
168
169 widgets::Window::new(hash!(), vec2(100., 220.), vec2(542., 430.))
170 .label("Fitting window")
171 .titlebar(true)
172 .ui(&mut *root_ui(), |ui| {
173 Group::new(hash!(), Vec2::new(230., 400.)).ui(ui, |ui| {
174 data.slots(ui);
175 });
176 Group::new(hash!(), Vec2::new(280., 400.)).ui(ui, |ui| {
177 data.inventory(ui);
178 });
179 });
180
181 widgets::Window::new(hash!(), vec2(470., 50.), vec2(300., 300.))
182 .label("Megaui Showcase Window")
183 .ui(&mut *root_ui(), |ui| {
184 ui.tree_node(hash!(), "input", |ui| {
185 ui.label(None, "Some random text");
186 if ui.button(None, "click me") {
187 println!("hi");
188 }
189
190 ui.separator();
191
192 ui.label(None, "Some other random text");
193 if ui.button(None, "other button") {
194 println!("hi2");
195 }
196
197 ui.separator();
198
199 ui.input_text(hash!(), "<- input text 1", &mut data0);
200 ui.input_text(hash!(), "<- input text 2", &mut data1);
201 ui.label(None, &format!("Text entered: \"{data0}\" and \"{data1}\""));
202
203 ui.separator();
204 });
205 ui.tree_node(hash!(), "buttons", |ui| {
206 widgets::Button::new(texture.clone())
207 .size(vec2(120., 70.))
208 .ui(ui);
209 ui.same_line(0.);
210 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
211 widgets::Button::new("Button").size(vec2(120., 70.)).ui(ui);
212 ui.same_line(0.);
213 widgets::Button::new(texture.clone())
214 .size(vec2(120., 70.))
215 .ui(ui);
216 });
217 ui.tree_node(hash!(), "sliders", |ui| {
218 ui.slider(hash!(), "[-10 .. 10]", -10f32..10f32, &mut number0);
219 ui.slider(hash!(), "[0 .. 100]", 0f32..100f32, &mut number1);
220 });
221 ui.tree_node(hash!(), "editbox 1", |ui| {
222 ui.label(None, "This is editbox!");
223 ui.editbox(hash!(), vec2(285., 165.), &mut text0);
224 });
225 ui.tree_node(hash!(), "editbox 2", |ui| {
226 ui.label(None, "This is editbox!");
227 ui.editbox(hash!(), vec2(285., 165.), &mut text1);
228 });
229 });
230
231 match data.fit_command.take() {
232 Some(FittingCommand::Unfit { target_slot }) => data.set_item(target_slot, None),
233 Some(FittingCommand::Fit { target_slot, item }) => {
234 data.set_item(target_slot, Some(item));
235 }
236 Some(FittingCommand::Refit {
237 target_slot,
238 origin_slot,
239 }) => {
240 let origin_item = data
241 .slots
242 .iter()
243 .find_map(|(_, slot)| {
244 if slot.id == origin_slot {
245 Some(slot.item.clone())
246 } else {
247 None
248 }
249 })
250 .flatten();
251 data.set_item(target_slot, origin_item);
252 data.set_item(origin_slot, None);
253 }
254 None => {}
255 };
256
257 next_frame().await;
258 }
259}
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Sourcepub fn canvas(&mut self) -> DrawCanvas<'_>
pub fn canvas(&mut self) -> DrawCanvas<'_>
Examples found in repository?
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}
Sourcepub fn get_bool(&mut self, id: Id) -> &mut bool
pub fn get_bool(&mut self, id: Id) -> &mut bool
small hack to keep some internal state used like this:
if ui.last_item_clicked() {
*ui.get_bool(hash!("color picker opened")) ^= true;
}
if *ui.get_bool(hash!("color picker opened")) {
}
pub fn get_any<T: Any + Default>(&mut self, id: Id) -> &mut T
Sourcepub fn push_skin(&mut self, skin: &Skin)
pub fn push_skin(&mut self, skin: &Skin)
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}
Sourcepub fn pop_skin(&mut self)
pub fn pop_skin(&mut self)
Examples found in repository?
6async fn main() {
7 let skin1 = {
8 let font = load_ttf_font("examples/ui_assets/HTOWERT.TTF")
9 .await
10 .unwrap();
11 let label_style = root_ui()
12 .style_builder()
13 .with_font(&font)
14 .unwrap()
15 .text_color(Color::from_rgba(180, 180, 120, 255))
16 .font_size(30)
17 .build();
18
19 let window_style = root_ui()
20 .style_builder()
21 .background(
22 Image::from_file_with_format(
23 include_bytes!("../examples/ui_assets/window_background.png"),
24 None,
25 )
26 .unwrap(),
27 )
28 .background_margin(RectOffset::new(20.0, 20.0, 10.0, 10.0))
29 .margin(RectOffset::new(-20.0, -30.0, 0.0, 0.0))
30 .build();
31
32 let button_style = root_ui()
33 .style_builder()
34 .background(
35 Image::from_file_with_format(
36 include_bytes!("../examples/ui_assets/button_background.png"),
37 None,
38 )
39 .unwrap(),
40 )
41 .background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
42 .margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
43 .background_hovered(
44 Image::from_file_with_format(
45 include_bytes!("../examples/ui_assets/button_hovered_background.png"),
46 None,
47 )
48 .unwrap(),
49 )
50 .background_clicked(
51 Image::from_file_with_format(
52 include_bytes!("../examples/ui_assets/button_clicked_background.png"),
53 None,
54 )
55 .unwrap(),
56 )
57 .with_font(&font)
58 .unwrap()
59 .text_color(Color::from_rgba(180, 180, 100, 255))
60 .font_size(40)
61 .build();
62
63 let editbox_style = root_ui()
64 .style_builder()
65 .background_margin(RectOffset::new(0., 0., 0., 0.))
66 .with_font(&font)
67 .unwrap()
68 .text_color(Color::from_rgba(120, 120, 120, 255))
69 .color_selected(Color::from_rgba(190, 190, 190, 255))
70 .font_size(50)
71 .build();
72
73 Skin {
74 editbox_style,
75 window_style,
76 button_style,
77 label_style,
78 ..root_ui().default_skin()
79 }
80 };
81
82 let skin2 = {
83 let font = load_ttf_font("examples/ui_assets/MinimalPixel v2.ttf")
84 .await
85 .unwrap();
86 let label_style = root_ui()
87 .style_builder()
88 .with_font(&font)
89 .unwrap()
90 .text_color(Color::from_rgba(120, 120, 120, 255))
91 .font_size(25)
92 .build();
93
94 let window_style = root_ui()
95 .style_builder()
96 .background(
97 Image::from_file_with_format(
98 include_bytes!("../examples/ui_assets/window_background_2.png"),
99 None,
100 )
101 .unwrap(),
102 )
103 .background_margin(RectOffset::new(52.0, 52.0, 52.0, 52.0))
104 .margin(RectOffset::new(-30.0, 0.0, -30.0, 0.0))
105 .build();
106
107 let button_style = root_ui()
108 .style_builder()
109 .background(
110 Image::from_file_with_format(
111 include_bytes!("../examples/ui_assets/button_background_2.png"),
112 None,
113 )
114 .unwrap(),
115 )
116 .background_margin(RectOffset::new(8.0, 8.0, 8.0, 8.0))
117 .background_hovered(
118 Image::from_file_with_format(
119 include_bytes!("../examples/ui_assets/button_hovered_background_2.png"),
120 None,
121 )
122 .unwrap(),
123 )
124 .background_clicked(
125 Image::from_file_with_format(
126 include_bytes!("../examples/ui_assets/button_clicked_background_2.png"),
127 None,
128 )
129 .unwrap(),
130 )
131 .with_font(&font)
132 .unwrap()
133 .text_color(Color::from_rgba(180, 180, 100, 255))
134 .font_size(40)
135 .build();
136
137 let checkbox_style = root_ui()
138 .style_builder()
139 .background(
140 Image::from_file_with_format(
141 include_bytes!("../examples/ui_assets/checkbox_background.png"),
142 None,
143 )
144 .unwrap(),
145 )
146 .background_hovered(
147 Image::from_file_with_format(
148 include_bytes!("../examples/ui_assets/checkbox_hovered_background.png"),
149 None,
150 )
151 .unwrap(),
152 )
153 .background_clicked(
154 Image::from_file_with_format(
155 include_bytes!("../examples/ui_assets/checkbox_clicked_background.png"),
156 None,
157 )
158 .unwrap(),
159 )
160 .build();
161
162 let editbox_style = root_ui()
163 .style_builder()
164 .background(
165 Image::from_file_with_format(
166 include_bytes!("../examples/ui_assets/editbox_background.png"),
167 None,
168 )
169 .unwrap(),
170 )
171 .background_margin(RectOffset::new(2., 2., 2., 2.))
172 .with_font(&font)
173 .unwrap()
174 .text_color(Color::from_rgba(120, 120, 120, 255))
175 .font_size(25)
176 .build();
177
178 let combobox_style = root_ui()
179 .style_builder()
180 .background(
181 Image::from_file_with_format(
182 include_bytes!("../examples/ui_assets/combobox_background.png"),
183 None,
184 )
185 .unwrap(),
186 )
187 .background_margin(RectOffset::new(4., 25., 6., 6.))
188 .with_font(&font)
189 .unwrap()
190 .text_color(Color::from_rgba(120, 120, 120, 255))
191 .color(Color::from_rgba(210, 210, 210, 255))
192 .font_size(25)
193 .build();
194
195 Skin {
196 window_style,
197 button_style,
198 label_style,
199 checkbox_style,
200 editbox_style,
201 combobox_style,
202 ..root_ui().default_skin()
203 }
204 };
205 let default_skin = root_ui().default_skin().clone();
206
207 let mut window1_skin = skin1.clone();
208 let mut window2_skin = skin2.clone();
209
210 let mut checkbox = false;
211 let mut text = String::new();
212 let mut number = 0.0f32;
213 let mut combobox = 0;
214
215 loop {
216 clear_background(GRAY);
217
218 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
219 ui.label(None, "Window 1");
220
221 if ui.button(None, "Skin 1") {
222 window1_skin = skin1.clone();
223 }
224 if ui.button(None, "Skin 2") {
225 window1_skin = skin2.clone();
226 }
227 if ui.button(None, "No Skin") {
228 window1_skin = default_skin.clone();
229 }
230 });
231 root_ui().same_line(0.);
232 root_ui().group(hash!(), vec2(70.0, 100.0), |ui| {
233 ui.label(None, "Window 2");
234 if ui.button(None, "Skin 1") {
235 window2_skin = skin1.clone();
236 }
237 if ui.button(None, "Skin 2") {
238 window2_skin = skin2.clone();
239 }
240 if ui.button(None, "No Skin") {
241 window2_skin = default_skin.clone();
242 }
243 });
244
245 root_ui().push_skin(&window1_skin);
246
247 root_ui().window(hash!(), vec2(20., 250.), vec2(300., 300.), |ui| {
248 widgets::Button::new("Play")
249 .position(vec2(65.0, 15.0))
250 .ui(ui);
251 widgets::Button::new("Options")
252 .position(vec2(40.0, 75.0))
253 .ui(ui);
254
255 widgets::Button::new("Quit")
256 .position(vec2(65.0, 195.0))
257 .ui(ui);
258 });
259 root_ui().pop_skin();
260
261 root_ui().push_skin(&window2_skin);
262 root_ui().window(hash!(), vec2(250., 20.), vec2(500., 250.), |ui| {
263 ui.checkbox(hash!(), "Checkbox 1", &mut checkbox);
264 ui.combo_box(
265 hash!(),
266 "Combobox",
267 &["First option", "Second option"],
268 &mut combobox,
269 );
270 ui.input_text(hash!(), "Text", &mut text);
271 ui.drag(hash!(), "Drag", None, &mut number);
272
273 widgets::Button::new("Apply")
274 .position(vec2(80.0, 150.0))
275 .ui(ui);
276 widgets::Button::new("Cancel")
277 .position(vec2(280.0, 150.0))
278 .ui(ui);
279 });
280 root_ui().pop_skin();
281
282 next_frame().await;
283 }
284}