pub struct UiElement<T: Copy + Eq + Hash> {
pub content: Box<dyn UiContent<T>>,
/* private fields */
}
Expand description
A UI element. The entire UI tree of mooeye is built out of these elements. This wrapper struct contains all information about look, layout, tooltip, message handling, etc. of the element, while also containing one UiContent field that contains the actual content.
Fields§
§content: Box<dyn UiContent<T>>
The conent managed & displayed by this element
Implementations§
source§impl<T: Copy + Eq + Hash> UiElement<T>
impl<T: Copy + Eq + Hash> UiElement<T>
sourcepub fn new<E: UiContent<T> + 'static>(id: u32, content: E) -> Self
pub fn new<E: UiContent<T> + 'static>(id: u32, content: E) -> Self
Creates a new UiElement containig the specified content and the specified ID. The element will be treated as a leaf node, even if its implements UiContainer. ID should be as unique as you require it. Layout and visuals will be set to default values, hover_visuals is initialized as None.
sourcepub fn add_element(
&mut self,
id: u32,
element: UiElement<T>
) -> Option<UiElement<T>>
pub fn add_element( &mut self, id: u32, element: UiElement<T> ) -> Option<UiElement<T>>
Adds an element to this element (or its children), recursively searching until an element with a fitting ID is found. The element is discarded there is no container child with fitting ID.
Examples found in repository?
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
fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
// Nothing much to do here, except implement the back button functionality.
let messages = self.gui.manage_messages(ctx, None);
if messages.contains(&ui::UiMessage::Triggered(1)){
// If it is, we end the current scene (and return to the previous one) by popping it off the stack.
return Ok(scene_manager::SceneSwitch::pop(1));
}
if messages.contains(&ui::UiMessage::Triggered(13)){
// If a certain button is pressed, add a small text element to the gui.
self.gui.add_element(100,
// using a duration box as a wrapper will remove the element after a set amount of time
ui::containers::DurationBox::new(
Duration::from_secs_f32(1.5),
graphics::Text::new("Just a small reminder that you pressed button 13.")
.set_font("Bahnschrift")
.set_wrap(true)
.set_bounds(glam::Vec2::new(200., 500.))
.set_scale(28.)
.to_owned()
.to_element_builder(0, ctx)
.with_visuals(ui::Visuals::new(
Color::from_rgb(77, 109, 191),
Color::from_rgb(55, 67, 87),
2.,
4.,
))
.build()
).to_element_builder(0, ctx)
.with_alignment(ui::Alignment::Center, ui::Alignment::Min)
.with_offset(0., 25.)
.build()
);
}
Ok(scene_manager::SceneSwitch::None)
}
sourcepub fn remove_elements(&mut self, id: u32)
pub fn remove_elements(&mut self, id: u32)
Removes all elements with the given ID from this element and (recursively) all its children.
sourcepub fn get_id(&self) -> u32
pub fn get_id(&self) -> u32
Returns this elements (not neccessarily unique) ID within this UI. This ID is used to indentify the source of intern messages.
sourcepub fn get_layout(&self) -> Layout
pub fn get_layout(&self) -> Layout
Returns this elements (current) layout.
sourcepub fn update(
&mut self,
ctx: &Context,
extern_messages: impl Into<Option<HashSet<UiMessage<T>>>>
) -> HashSet<UiMessage<T>>
pub fn update( &mut self, ctx: &Context, extern_messages: impl Into<Option<HashSet<UiMessage<T>>>> ) -> HashSet<UiMessage<T>>
Receives a data structure containing all messages triggered by your game_state this frame (or None if there were no messages). It then collects all messages sent by this element and its children and redistributes all of those messages to this element and all children. Returns all internal messages to act on them. In addition, if this element has children, all children whose UiContent::expired function returns true are removed from the container.
sourcepub fn manage_messages(
&mut self,
ctx: &Context,
extern_messages: impl Into<Option<HashSet<UiMessage<T>>>>
) -> HashSet<UiMessage<T>>
pub fn manage_messages( &mut self, ctx: &Context, extern_messages: impl Into<Option<HashSet<UiMessage<T>>>> ) -> HashSet<UiMessage<T>>
Deprecated version of UiElement::update.
Examples found in repository?
154 155 156 157 158 159 160 161 162 163 164 165
fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
// Nothing much to do here, except implement the back button functionality.
let messages = self.gui.manage_messages(ctx, None);
if messages.contains(&ui::UiMessage::Triggered(1)) {
// If it is, we end the current scene (and return to the previous one) by popping it off the stack.
return Ok(scene_manager::SceneSwitch::pop(1));
}
Ok(scene_manager::SceneSwitch::None)
}
More examples
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
// Usually, we would first perform our game logic here, but this scene has no logic.
// You can get messages sent by your UI with the manage_messages function.
// Usually, you also pass in extern messages created by your game state to bring the UI up to date. Since we don't have a game state, we can pass None (this is useful for menu scenes and similar).
let messages = self.gui.manage_messages(ctx, None);
// We then check if our button has been clicked by creating a Clicked event with the correct ID and checking if it is contained in the messages set.
if messages.contains(&ui::UiMessage::Triggered(1)){
// If it is, we end the current scene (and return to the previous one) by popping it off the stack.
return Ok(scene_manager::SceneSwitch::pop(1));
}
// Otherwise, no scene switch is neccessary.
Ok(scene_manager::SceneSwitch::None)
}
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
// Actually implementing some game state logic.
// Pressing space changes the variant of the sprite.
if ctx
.keyboard
.is_key_just_pressed(winit::event::VirtualKeyCode::Space)
{
self.sprite.set_variant(self.sprite.get_variant() + 1);
}
// Move the sprite.
self.pos += self.v;
// Make the sprite bounce off the screen edges.
let scaling = 5.;
if self.pos.x - scaling * 4. < 0. || self.pos.x + scaling * 4. >= ctx.gfx.drawable_size().0
{
self.v.x *= -1.;
}
if self.pos.y - scaling * 8. < 0. || self.pos.y + scaling * 8. >= ctx.gfx.drawable_size().1
{
self.v.y *= -1.;
}
// And handle messages as usual
let messages = self.gui.manage_messages(ctx, None);
if messages.contains(&ui::UiMessage::Triggered(1)) {
return Ok(scene_manager::SceneSwitch::pop(1));
}
Ok(scene_manager::SceneSwitch::None)
}
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
let messages = self.gui.manage_messages(ctx, None);
// Scene switches for different scenes
if messages.contains(&ui::UiMessage::Triggered(1)) {
return Ok(scene_manager::SceneSwitch::push(
crate::b_scene::BScene::new(ctx),
));
}
if messages.contains(&ui::UiMessage::Triggered(2)) {
return Ok(scene_manager::SceneSwitch::push(
crate::c_uielement::CScene::new(ctx),
));
}
if messages.contains(&ui::UiMessage::Triggered(3)) {
return Ok(scene_manager::SceneSwitch::push(
crate::d_containers::DScene::new(ctx)?,
));
}
if messages.contains(&ui::UiMessage::Triggered(4)) {
return Ok(scene_manager::SceneSwitch::push(
crate::e_messages::EScene::new(ctx)?,
));
}
if messages.contains(&ui::UiMessage::Triggered(5)) {
return Ok(scene_manager::SceneSwitch::push(
crate::f_sprites::FScene::new(ctx)?,
));
}
// Exit
if messages.contains(&ui::UiMessage::Triggered(6)) {
return Ok(scene_manager::SceneSwitch::pop(1));
}
Ok(scene_manager::SceneSwitch::None)
}
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
fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
// Nothing much to do here, except implement the back button functionality.
let messages = self.gui.manage_messages(ctx, None);
if messages.contains(&ui::UiMessage::Triggered(1)){
// If it is, we end the current scene (and return to the previous one) by popping it off the stack.
return Ok(scene_manager::SceneSwitch::pop(1));
}
if messages.contains(&ui::UiMessage::Triggered(13)){
// If a certain button is pressed, add a small text element to the gui.
self.gui.add_element(100,
// using a duration box as a wrapper will remove the element after a set amount of time
ui::containers::DurationBox::new(
Duration::from_secs_f32(1.5),
graphics::Text::new("Just a small reminder that you pressed button 13.")
.set_font("Bahnschrift")
.set_wrap(true)
.set_bounds(glam::Vec2::new(200., 500.))
.set_scale(28.)
.to_owned()
.to_element_builder(0, ctx)
.with_visuals(ui::Visuals::new(
Color::from_rgb(77, 109, 191),
Color::from_rgb(55, 67, 87),
2.,
4.,
))
.build()
).to_element_builder(0, ctx)
.with_alignment(ui::Alignment::Center, ui::Alignment::Min)
.with_offset(0., 25.)
.build()
);
}
Ok(scene_manager::SceneSwitch::None)
}
sourcepub fn add_transition(&mut self, transition: Transition<T>)
pub fn add_transition(&mut self, transition: Transition<T>)
Adds a transition to the end of the transition queue. It will be executed as soon as all transitions added beforehand have run their course.
sourcepub fn width_range(&self) -> (f32, f32)
pub fn width_range(&self) -> (f32, f32)
Returns the minimum and maximum width this element this element can have. Calculated from adding left and right padding to the size-data.
sourcepub fn height_range(&self) -> (f32, f32)
pub fn height_range(&self) -> (f32, f32)
Returns the minimum and maximum height this element this element can have. Calculated from adding top and bottom padding to the size-data.
sourcepub fn draw_to_screen(
&mut self,
ctx: &mut Context,
canvas: &mut Canvas,
mouse_listen: bool
)
pub fn draw_to_screen( &mut self, ctx: &mut Context, canvas: &mut Canvas, mouse_listen: bool )
Draws this UiElement to the current screen. Call this on your root element every frame.
Examples found in repository?
255 256 257 258 259 260 261 262 263 264 265 266 267
fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
// Once again the basic drawing function.
let mut canvas = graphics::Canvas::from_frame(ctx, None);
canvas.set_sampler(graphics::Sampler::nearest_clamp());
self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
canvas.finish(ctx)?;
Ok(())
}
More examples
132 133 134 135 136 137 138 139 140 141 142 143
fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
// business as usual
let mut canvas = ggez::graphics::Canvas::from_frame(ctx, Color::from_rgb(100, 100, 150));
canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
canvas.finish(ctx)?;
Ok(())
}
167 168 169 170 171 172 173 174 175 176 177 178 179
fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
// Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.
let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);
// Since we don't set the sampler to 'nearest', our corners will look more round, but the pixel-cow will look blurry.
//canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
canvas.finish(ctx)?;
Ok(())
}
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
// Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.
let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);
canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
// Here, you would draw your gamestate.
// Drawing a gui is as easy as calling draw_to_screen on the root element.
// If you are using a scene, you can simply pass on the mouse_listen parameter. It will be managed by the scene manager.
self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
// Once again, we end drawing by finishing the canvas.
canvas.finish(ctx)?;
Ok(())
}
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
// Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.
let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);
canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
// Drawing of our (limited) game state.
// see if we need to mirror our sprite if it moves left
let mirroring = if self.v.x > 0. { 1. } else { -1. };
let scaling = 5.;
self.sprite.draw_sprite(
ctx,
&mut canvas,
DrawParam::new().dest_rect(Rect::new(
self.pos.x - scaling * 4. * mirroring,
self.pos.y - scaling * 8.,
scaling * mirroring,
scaling,
)),
);
let scaling = 2.;
self.sprite2.draw_sprite(
ctx,
&mut canvas,
DrawParam::new().dest_rect(Rect::new(
self.pos.x - scaling * 4. + 32.,
self.pos.y - scaling * 8. + 32.,
scaling,
scaling,
)),
);
// And once again drawing the GUI.
self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
canvas.finish(ctx)?;
Ok(())
}