Struct thyme::WidgetBuilder

source ·
pub struct WidgetBuilder<'a> { /* private fields */ }
Expand description

A WidgetBuilder is used to customize widgets within your UI tree, following a builder pattern.

Although there are several convenience methods on Frame for simple buttons, labels, etc, widgets with more complex behavior will usually be created via Frame.start and then customized using the methods here. Note also that many methods here have an equivalent in the widget’s theme definition.

Each method here takes the WidgetBuilder by value, modifies it, and then returns it, allowing you to use a builder pattern. The window method will transform this into a WindowBuilder, while the finish and children methods will complete the widget and add it to the frame’s widget tree.

Implementations§

source§

impl<'a> WidgetBuilder<'a>

source

pub fn parent(&self) -> &Widget

Returns the parent widget for this WidgetBuilder, which can be used to directly query the attributes of the parent

source

pub fn widget(&self) -> &Widget

Returns the current Widget for this WidgetBuilder. This can be used to query directly the various attributes of the widget. Further methods on this WidgetBuilder will modify the widget.

source

pub fn frame(&self) -> &Frame

Returns a reference to the current frame, (the ui object), which is currently stored by this builder

source

pub fn always_top(self) -> WidgetBuilder<'a>

Specifies that this widget and its children should be part of a new Render Group that is always shown on top of other groups. See new_render_group

source

pub fn always_bottom(self) -> WidgetBuilder<'a>

Specifies that this widget and its children should be part of a new Render Group that is always shown below other groups. See new_render_group

source

pub fn new_render_group(self) -> WidgetBuilder<'a>

Specifies that this widget and its children should be part of a new Render Group. Render groups are used to handle cases where widgets may overlap, and determine input routing and draw order in those cases. If your UI doesn’t have moveable elements such as windows, you should generally be ok to draw your entire UI in one render group, with the exception of modal popups. Windows make use of render groups. Render groups allow a widget that is created later in your UI code to pick up input instead of a widget that is created earlier, even if those widgets overlap. Note that the system internally relies on the render group ordering. In particular, having your layout create a new render group earlier in the UI code as a result of an action on a later render group will cause that later render group to lose input focus.

source

pub fn wants_mouse(self, wants_mouse: bool) -> WidgetBuilder<'a>

Sets whether this widget will interact with the mouse. By default, widgets will not interact with the mouse, so this is set to true for buttons and similar. This may also be specified in the widget’s theme.

source

pub fn wants_scroll(self, wants_scroll: bool) -> WidgetBuilder<'a>

Sets whether this widget will receive mouse scrollwheel events. By default, widgets will not receive scroll wheel events, so this is set to true for scrollpanes. This may also be specified in the widget’s theme.

source

pub fn id<T: Into<String>>(self, id: T) -> WidgetBuilder<'a>

Sets an id for this widget. This id is used internally to associate the widget with its PersistentState. You will need to specify an id if you want to make changes to the PersistentState. Otherwise, Thyme can usually generate a unique internal ID for most elements.

source

pub fn initially_open(self, open: bool) -> WidgetBuilder<'a>

Specify whether this widget is initially open, or visible. By default, widgets are initially open. If set to false, the widget will not be shown until it is set to open using one of the methods on Frame to modify its PersistentState.

source

pub fn text_color(self, color: Color) -> WidgetBuilder<'a>

Specify a Color for the text of this widget to display. The default color is white. This may also be specified in the widget’s theme.

source

pub fn text_align(self, align: Align) -> WidgetBuilder<'a>

Specify the alignment of the widget’s text within the widget’s inner area, as defined by its overall size and border. This may also be specified in the widget’s theme.

source

pub fn text_indent(self, indent: f32) -> WidgetBuilder<'a>

Specify the indent of the first line of text rendered by this widget, in logical pixels. Useful for multi-line (or potentially multi-line) text where the starting position is indented.

source

pub fn text<T: Into<String>>(self, text: T) -> WidgetBuilder<'a>

Specify text to display for this widget. The widget must have a font specified to render text. This may also be specified in the widget’s theme.

Examples found in repository?
examples/demo.rs (line 301)
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
fn party_members_panel(ui: &mut Frame, party: &mut Party) {
    for (index, member) in party.members.iter_mut().enumerate() {
        let clicked = ui.start("filled_slot_button")
        .text(&member.name)
        .active(Some(index) == party.editing_index)
        .finish().clicked;

        if clicked {
            set_active_character(ui, member);
            party.editing_index = Some(index);
        }
    }

    if ui.start("add_character_button").finish().clicked {
        let new_member = Character::generate(party.members.len());
        set_active_character(ui, &new_member);
        party.members.push(new_member);
        party.editing_index = Some(party.members.len() - 1);
    }
}
source

pub fn tooltip_text<T: Into<String>>(self, tooltip: T) -> WidgetBuilder<'a>

Specify tooltip to display as a simple tooltip if this widget is hovered with the mouse. The tooltip will use the “tooltip” theme which must be present in the theme. This may also be specified in the widget’s theme.

source

pub fn font(self, font: &str) -> WidgetBuilder<'a>

Specify a font for any text rendered by this widget. A widget must have a font specified to render text. The font must be registered in the theme’s font definitions. This may also be specified in the widget’s theme.

source

pub fn image_color(self, color: Color) -> WidgetBuilder<'a>

Specify a Color for the images of this widget to display. The default color is white. This multiplies the color of the background and foreground images. This may also be specified in the widget’s theme.

source

pub fn foreground(self, fg: &str) -> WidgetBuilder<'a>

Specify a foreground image for this widget. The image ID, fg must be registered in the theme’s image definitions. The ID consists of “{image_set_id}/{image_id}”. Foreground images are drawn below text but above the background. This may also be specified in the widget’s theme.

source

pub fn background(self, bg: &str) -> WidgetBuilder<'a>

Specify a background image for this widget. The image ID, bg must be registered in the theme’s image definitions. The ID consists of “{image_set_id}/{image_id}”. Background images are drawn below text and any children. This may also be specified in the widget’s theme.

source

pub fn child_align(self, align: Align) -> WidgetBuilder<'a>

Specifies the default alignment of children added to this widget. See Align. This may be overridden by the child, either in the theme or by calling align. This may also be specified in the widget’s theme.

source

pub fn layout_spacing(self, spacing: Point) -> WidgetBuilder<'a>

Specifies the spacing, in logical pixels, to use between children that are laid out in this widget. This may also be specified in the widget’s theme.

source

pub fn layout_horizontal(self) -> WidgetBuilder<'a>

Specifies that the children of this widget should be laid out vertically. See Layout. This may also be specified in the widget’s theme.

source

pub fn layout_vertical(self) -> WidgetBuilder<'a>

Specifies that the children of this widget should be laid out vertically. See Layout. This may also be specified in the widget’s theme.

source

pub fn layout(self, layout: Layout) -> WidgetBuilder<'a>

Specifies the layout for children of this widget. See Layout. This may also be specified in the widget’s theme.

source

pub fn screen_pos(self, x: f32, y: f32) -> WidgetBuilder<'a>

Manually specify a position for this widget, basedon the specified x and y logical pixel positions. This position ignores alignment or any other considerations. This may also be specified in the widget’s theme.

Examples found in repository?
examples/demo.rs (line 291)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}
source

pub fn render_as_tooltip(self) -> WidgetBuilder<'a>

Helper to treat this widget as a tooltip. The widget will be placed on top of other widgets in its own render group. Positioning will be based on the mouse cursor position. See new_render_group.

source

pub fn pos(self, x: f32, y: f32) -> WidgetBuilder<'a>

Specify the position of the widget, with respect to its alignment within the parent. The x and `` values are in logical pixels. See align. This may also be specified in the widget’s theme.

source

pub fn align(self, align: Align) -> WidgetBuilder<'a>

Specify the alignment of this widget with respect to its parent. See Align. This may also be specified in the widget’s theme.

source

pub fn border(self, border: Border) -> WidgetBuilder<'a>

Specify the widget’s border size, which determines the inner size of the widget relative to its size. See Border. This may also be specified in the widget’s theme.

source

pub fn size(self, x: f32, y: f32) -> WidgetBuilder<'a>

Specify the widget’s size in logical pixels. This may or may not be an absolute size, depending on WidthRelative and HeightRelative This may also be specified in the widget’s theme.

Examples found in repository?
examples/demo.rs (line 290)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}
source

pub fn width(self, x: f32) -> WidgetBuilder<'a>

Specify the widget’s width in logical pixels. See size. This may also be specified in the widget’s theme.

source

pub fn height(self, y: f32) -> WidgetBuilder<'a>

Specify the widget’s height in logical pixels. See size. This may also be specified in the widget’s theme.

source

pub fn width_from(self, from: WidthRelative) -> WidgetBuilder<'a>

Specify how to compute the widget’s width from its size. See WidthRelative. This may also be specified in the widget’s theme. You may also specify this using size_from.

source

pub fn height_from(self, from: HeightRelative) -> WidgetBuilder<'a>

Specify how to compute the widget’s height from its size. See HeightRelative This may also be specified in the widget’s theme. You may also specify this using size_from.

source

pub fn size_from( self, width_from: WidthRelative, height_from: HeightRelative ) -> WidgetBuilder<'a>

Specify how to compute the widget’s height and width from its size. See WidthRelative and HeightRelative. This may also be specified in the widget’s theme. You may also specify this using width_from and height_from

source

pub fn clip(self, clip: Rect) -> WidgetBuilder<'a>

Sets the widget’s clip Rectangle. By default, a widget will have a clip rectangle set from its size and position, calculated based on the theme and the various methods such as size, pos, width_from, height_from, etc. You can override that behavior with this method. This is useful to display part of an image, such as in a progress bar, or to limit the size of child content, such as in a scrollpane. Widgets always inherit their clip as the minimum extent of their parent’s clip and their own clip. See Rect.min.

source

pub fn unclip(self) -> WidgetBuilder<'a>

Removes all constraints from the widget’s clip Rectangle. This will allow the widget to render outside of its parent’s area. See clip.

Examples found in repository?
examples/demo.rs (line 288)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}
source

pub fn unparent(self) -> WidgetBuilder<'a>

If called, the current parent widget will not treat this widget as a child for the purposes of computing its child bounds. This is useful for popups and similar which are not neccesarily children of the widgets that create them. You usually will also want unclip and new_render_group.

Examples found in repository?
examples/demo.rs (line 289)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}
source

pub fn force_hover(self, hover: bool) -> WidgetBuilder<'a>

Forces this widget’s AnimState to have the specified value for its hover AnimStateKey

source

pub fn force_pressed(self, pressed: bool) -> WidgetBuilder<'a>

Forces this widget’s AnimState to have the specified value for its pressed AnimStateKey

source

pub fn active(self, active: bool) -> WidgetBuilder<'a>

Sets whether the widget’s AnimState will include the active AnimStateKey.

Examples found in repository?
examples/demo.rs (line 208)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}

fn party_members_panel(ui: &mut Frame, party: &mut Party) {
    for (index, member) in party.members.iter_mut().enumerate() {
        let clicked = ui.start("filled_slot_button")
        .text(&member.name)
        .active(Some(index) == party.editing_index)
        .finish().clicked;

        if clicked {
            set_active_character(ui, member);
            party.editing_index = Some(index);
        }
    }

    if ui.start("add_character_button").finish().clicked {
        let new_member = Character::generate(party.members.len());
        set_active_character(ui, &new_member);
        party.members.push(new_member);
        party.editing_index = Some(party.members.len() - 1);
    }
}
source

pub fn visible(self, visible: bool) -> WidgetBuilder<'a>

Sets whether this widget will be visible. If the widget is not visible, it will not be shown and any child closures (such as passed in children) will not be run.

source

pub fn enabled(self, enabled: bool) -> WidgetBuilder<'a>

Sets whether this widget will be enabled. If the widget is not enabled, it will not interact with any user input.

Examples found in repository?
examples/demo.rs (line 333)
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
fn stats_panel(ui: &mut Frame, character: &mut Character) {
    let points_used: u32 = character.stats.values().sum();
    let points_available: u32 = STAT_POINTS - points_used;
    let frac = ((ui.cur_time_millis() - ui.base_time_millis("stat_roll")) as f32 / 1000.0).min(1.0);

    let roll = ui.start("roll_button")
    .enabled(frac > 0.99)
    .children(|ui| {
        ui.progress_bar("progress_bar", frac);
    });

    if roll.clicked {
        ui.set_base_time_now("stat_roll");
    }

    for stat in Stat::iter() {
        let value = character.stats.entry(stat).or_insert(10);

        ui.tree(
        "stat_panel",
        &format!("stat_panel_{:?}", stat),
        false,
        |ui| {
            ui.label("label", format!("{:?}", stat));

            match ui.spinner("spinner", *value, MIN_STAT, if points_available == 0 { *value } else { MAX_STAT }) {
                1 => *value += 1,
                -1 => *value -= 1,
                _ => (),
            }
        }, |ui| {
            ui.child("description");
        });
    }

    ui.label("points_available", format!("Points Remaining: {}", points_available));
}

fn item_picker(ui: &mut Frame, character: &mut Character) {
    for item in ITEMS.iter() {
        let clicked = ui.start("item_button")
        .enabled(character.gp >= item.price)
        .children(|ui| {
            ui.label("name", item.name);
            // TODO icon image
            ui.child("icon");
            ui.label("price", format!("{} Gold", item.price));
        }).clicked;

        if clicked {
            character.gp -= item.price;
            character.items.push(item.clone());
            ui.close("item_picker");
        }
    }
}
source

pub fn trigger_layout(self, rect: &mut Rect) -> WidgetBuilder<'a>

Force the widget to layout its size and position immediately. Assuming these attributes are not changed after this method is called, these attributes will have their final values after this method returns. The size and position are written to the passed in Rect.

source

pub fn trigger_layout_inner(self, rect: &mut Rect) -> WidgetBuilder<'a>

Force the widget to layout its size and position immediately. Assuming these attributes are not changed after this is method is called, they will have their final values after this method returns. The inner size and position (size and position adjusted by the Border) are written to the passed in Rect

source

pub fn trigger_text_layout(self, cursor: &mut Point) -> WidgetBuilder<'a>

Causes this widget to layout its current text. The final position of the text cursor is written into cursor. If this widget does not have a font or has no text, nothing is written into cursor.

source

pub fn window(self, id: &str) -> WindowBuilder<'a>

Turns this builder into a WindowBuilder. You should use all WidgetBuilder methods you need before calling this method. The window must still be completed with one of the WindowBuilder methods. You must pass a unique id for each window created by your application.

Examples found in repository?
examples/demo.rs (line 220)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}
source

pub fn scrollpane(self, content_id: &str) -> ScrollpaneBuilder<'a>

Turns this builder into a ScrollpaneBuilder. You should use all WidgetBuilder methods you need before calling this method. The scrollpane must still be completed with one of the methods on ScrollpaneBuilder. You must pass a unique content_id for the scrollpane’s content.

Examples found in repository?
examples/demo.rs (line 395)
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
fn inventory_panel(ui: &mut Frame, character: &mut Character) {
    ui.start("top_panel")
    .children(|ui| {
        if ui.child("buy").clicked {
            ui.open_modal("item_picker");
        }

        ui.label("gold", format!("{} Gold", character.gp));
    });
    
    ui.start("items_panel")
    .scrollpane("items_content")
    .show_vertical_scrollbar(ShowElement::Always)
    .children(|ui| {
        items_panel(ui, character);
    });
}
source

pub fn edit<F: FnOnce(WidgetBuilder<'_>) -> WidgetBuilder<'_>>( self, f: F ) -> WidgetBuilder<'a>

Executes the passed in closure on this WidgetBuilder, returning the resulting value. This allows you to insert arbitrary control flow while continuing to chain the WidgetBuilder methods. Without this method, you might need to save the builder in a variable, check some condition (possibly calling another WidgetBuilder method), and then continue on with the usual method chaining.

Example
fn hover_button(ui: &mut Frame, force_hover: bool) -> WidgetState {
    ui.start("hover_button")
    .edit(|builder| {
        if force_hover {
            builder.force_hover(true)
        } else {
            builder
        }
    }).finish()
}
source

pub fn finish(self) -> WidgetState

Consumes the builder and adds a widget to the current frame. The returned data includes information about the animation state and mouse interactions of the created element. If you wish this widget to have one or more child widgets, you should call children instead.

Examples found in repository?
examples/demo.rs (line 208)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}

fn party_members_panel(ui: &mut Frame, party: &mut Party) {
    for (index, member) in party.members.iter_mut().enumerate() {
        let clicked = ui.start("filled_slot_button")
        .text(&member.name)
        .active(Some(index) == party.editing_index)
        .finish().clicked;

        if clicked {
            set_active_character(ui, member);
            party.editing_index = Some(index);
        }
    }

    if ui.start("add_character_button").finish().clicked {
        let new_member = Character::generate(party.members.len());
        set_active_character(ui, &new_member);
        party.members.push(new_member);
        party.editing_index = Some(party.members.len() - 1);
    }
}
source

pub fn children<F: FnOnce(&mut Frame)>(self, f: F) -> WidgetState

Consumes the builder and adds a widget to the current frame. The returned data includes information about the animation state and mouse interactions of the created element. The provided closure is called to enable adding children to this widget. If you don’t want to add children, you can just call finish instead.

Examples found in repository?
examples/demo.rs (lines 207-217)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
pub fn build_ui(ui: &mut Frame, party: &mut Party) {
    match party.theme_choice {
        ThemeChoice::Pixels | ThemeChoice::Fantasy | ThemeChoice::Transparent | ThemeChoice::Golden => {
            // show a custom cursor.  it automatically inherits mouse presses in its state
            ui.set_mouse_cursor("gui/cursor", thyme::Align::TopLeft);
        },
        ThemeChoice::NoImage => {
            // don't show a custom cursor
        }
    }

    ui.label("bench", format!(
        "{}\n{}\n{}",
        bench::short_report("thyme"),
        bench::short_report("frame"),
        bench::short_report("draw"),
    ));

    ui.start("theme_panel").children(|ui| {
        if ui.start("live_reload").active(!party.live_reload_disabled).finish().clicked {
            party.live_reload_disabled = !party.live_reload_disabled;
        }

        if let Some(choice) = ui.combo_box("theme_choice", "theme_choice", &party.theme_choice, &THEME_CHOICES) {
            party.old_theme_choice = Some(party.theme_choice);
            party.theme_choice = *choice;
            party.reload_assets = true;
        }
    });

    ui.start("party_window")
    .window("party_window")
    .with_close_button(false)
    .moveable(false)
    .resizable(false)
    .children(|ui| {
        ui.scrollpane("members_panel", "party_content", |ui| {
            party_members_panel(ui, party);
        });
    });

    if let Some(index) = party.editing_index {
        let character = &mut party.members[index];

        ui.window("character_window", |ui| {
            ui.scrollpane("pane", "character_content", |ui| {
                ui.start("name_panel")
                .children(|ui| {
                    if let Some(new_name) = ui.input_field("name_input", "name_input", None) {
                        character.name = new_name;
                    }
                });

                ui.gap(10.0);
                ui.label("age_label", format!("Age: {}", character.age.round() as u32));
                if let Some(age) = ui.horizontal_slider("age_slider", MIN_AGE, MAX_AGE, character.age) {
                    character.age = age;
                }

                for stat in Stat::iter() {
                    let value = format!("{}", character.stats.get(&stat).unwrap_or(&10));
                    let key = format!("{:?}", stat);
                    ui.set_variable(key, value);
                }

                ui.scrollpane("description_panel", "description_pane", |ui| {
                    ui.text_area("description_box");
                });

                ui.gap(10.0);

                if let Some(race) = ui.combo_box("race_selector", "race_selector", &character.race, Race::all()) {
                    character.race = *race;
                }
    
                ui.gap(10.0);
    
                ui.tree("stats_panel", "stats_panel", true,
                |ui| {
                    ui.child("title");
                },|ui| {
                    stats_panel(ui, character);
                });
                
                ui.gap(10.0);
    
                ui.tree("inventory_panel", "inventory_panel", true,
                |ui| {
                    ui.child("title");
                }, |ui| {
                    inventory_panel(ui, character);
                });
            });
        });

        ui.window("item_picker", |ui| {
            let display_size = ui.display_size();

            ui.start("greyed_out")
            .unclip()
            .unparent()
            .size(display_size.x, display_size.y)
            .screen_pos(0.0, 0.0).finish();

            item_picker(ui, character);
        });
    }
}

fn party_members_panel(ui: &mut Frame, party: &mut Party) {
    for (index, member) in party.members.iter_mut().enumerate() {
        let clicked = ui.start("filled_slot_button")
        .text(&member.name)
        .active(Some(index) == party.editing_index)
        .finish().clicked;

        if clicked {
            set_active_character(ui, member);
            party.editing_index = Some(index);
        }
    }

    if ui.start("add_character_button").finish().clicked {
        let new_member = Character::generate(party.members.len());
        set_active_character(ui, &new_member);
        party.members.push(new_member);
        party.editing_index = Some(party.members.len() - 1);
    }
}

fn set_active_character(ui: &mut Frame, character: &Character) {
    ui.open("character_window");
    ui.modify("name_input", |state| {
        state.text = Some(character.name.clone());
    });
    ui.close("item_picker");
}

fn stats_panel(ui: &mut Frame, character: &mut Character) {
    let points_used: u32 = character.stats.values().sum();
    let points_available: u32 = STAT_POINTS - points_used;
    let frac = ((ui.cur_time_millis() - ui.base_time_millis("stat_roll")) as f32 / 1000.0).min(1.0);

    let roll = ui.start("roll_button")
    .enabled(frac > 0.99)
    .children(|ui| {
        ui.progress_bar("progress_bar", frac);
    });

    if roll.clicked {
        ui.set_base_time_now("stat_roll");
    }

    for stat in Stat::iter() {
        let value = character.stats.entry(stat).or_insert(10);

        ui.tree(
        "stat_panel",
        &format!("stat_panel_{:?}", stat),
        false,
        |ui| {
            ui.label("label", format!("{:?}", stat));

            match ui.spinner("spinner", *value, MIN_STAT, if points_available == 0 { *value } else { MAX_STAT }) {
                1 => *value += 1,
                -1 => *value -= 1,
                _ => (),
            }
        }, |ui| {
            ui.child("description");
        });
    }

    ui.label("points_available", format!("Points Remaining: {}", points_available));
}

fn item_picker(ui: &mut Frame, character: &mut Character) {
    for item in ITEMS.iter() {
        let clicked = ui.start("item_button")
        .enabled(character.gp >= item.price)
        .children(|ui| {
            ui.label("name", item.name);
            // TODO icon image
            ui.child("icon");
            ui.label("price", format!("{} Gold", item.price));
        }).clicked;

        if clicked {
            character.gp -= item.price;
            character.items.push(item.clone());
            ui.close("item_picker");
        }
    }
}

fn inventory_panel(ui: &mut Frame, character: &mut Character) {
    ui.start("top_panel")
    .children(|ui| {
        if ui.child("buy").clicked {
            ui.open_modal("item_picker");
        }

        ui.label("gold", format!("{} Gold", character.gp));
    });
    
    ui.start("items_panel")
    .scrollpane("items_content")
    .show_vertical_scrollbar(ShowElement::Always)
    .children(|ui| {
        items_panel(ui, character);
    });
}
source

pub fn custom_int(&self, key: &str, default_value: i32) -> i32

Queries the theme for the specified custom int, in the custom field for the theme with the specified key. Returns the default_value if the theme or key cannot be found, or if the key is specified but is not a float

source

pub fn custom_float(&self, key: &str, default_value: f32) -> f32

Queries the theme for the specified custom float, in the custom field for the theme with the specified key. Returns the default_value if the theme or key cannot be found, or if the key is specified but is not a float

source

pub fn custom_string(&self, key: &str, default_value: String) -> String

Queries the theme for the specified custom String, in the custom field for the theme with the specified key. Returns the default_value if the theme or key cannot be found, or if the key is specified but is not a String

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for WidgetBuilder<'a>

§

impl<'a> !Send for WidgetBuilder<'a>

§

impl<'a> !Sync for WidgetBuilder<'a>

§

impl<'a> Unpin for WidgetBuilder<'a>

§

impl<'a> !UnwindSafe for WidgetBuilder<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>