Struct UiElement

Source
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>

Source

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.

Source

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?
examples/ui_examples/e_messages.rs (lines 226-248)
214    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
215        // Nothing much to do here, except implement the back button functionality.
216
217        let messages = self.gui.manage_messages(ctx, None);
218
219        if messages.contains(&ui::UiMessage::Triggered(1)){
220            // If it is, we end the current scene (and return to the previous one) by popping it off the stack.
221            return Ok(scene_manager::SceneSwitch::pop(1));
222        }
223
224        if messages.contains(&ui::UiMessage::Triggered(13)){
225            // If a certain button is pressed, add a small text element to the gui.
226            self.gui.add_element(100,
227                // using a duration box as a wrapper will remove the element after a set amount of time
228                  ui::containers::DurationBox::new(
229                    Duration::from_secs_f32(1.5),
230                     graphics::Text::new("Just a small reminder that you pressed button 13.")
231                     .set_font("Bahnschrift")
232                     .set_wrap(true)
233                     .set_bounds(glam::Vec2::new(200., 500.))
234                     .set_scale(28.)
235                     .to_owned()
236                     .to_element_builder(0, ctx)
237                     .with_visuals(ui::Visuals::new(
238                        Color::from_rgb(77, 109, 191),
239                        Color::from_rgb(55, 67, 87),
240                        2.,
241                        4.,
242                    ))
243                     .build()
244                    ).to_element_builder(0, ctx)
245                    .with_alignment(ui::Alignment::Center, ui::Alignment::Min)
246                    .with_offset(0., 25.)
247                    .build()
248                    );
249        }
250
251        Ok(scene_manager::SceneSwitch::None)
252    
253    }
Source

pub fn remove_elements(&mut self, id: u32)

Removes all elements with the given ID from this element and (recursively) all its children.

Source

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.

Source

pub fn get_layout(&self) -> Layout

Returns this elements (current) layout.

Source

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.

Source

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?
examples/ui_examples/d_containers.rs (line 157)
154    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
155        // Nothing much to do here, except implement the back button functionality.
156
157        let messages = self.gui.manage_messages(ctx, None);
158
159        if messages.contains(&ui::UiMessage::Triggered(1)) {
160            // If it is, we end the current scene (and return to the previous one) by popping it off the stack.
161            return Ok(scene_manager::SceneSwitch::pop(1));
162        }
163
164        Ok(scene_manager::SceneSwitch::None)
165    }
More examples
Hide additional examples
examples/ui_examples/c_uielement.rs (line 69)
62    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
63
64        // Usually, we would first perform our game logic here, but this scene has no logic.
65
66
67        // You can get messages sent by your UI with the manage_messages function.
68        // 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).
69        let messages = self.gui.manage_messages(ctx, None);
70
71        // 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.
72        if messages.contains(&ui::UiMessage::Triggered(1)){
73            // If it is, we end the current scene (and return to the previous one) by popping it off the stack.
74            return Ok(scene_manager::SceneSwitch::pop(1));
75        }
76
77        // Otherwise, no scene switch is neccessary.
78        Ok(scene_manager::SceneSwitch::None)
79    }
examples/ui_examples/f_sprites.rs (line 148)
119    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
120        // Actually implementing some game state logic.
121
122        // Pressing space changes the variant of the sprite.
123        if ctx
124            .keyboard
125            .is_key_just_pressed(winit::event::VirtualKeyCode::Space)
126        {
127            self.sprite.set_variant(self.sprite.get_variant() + 1);
128        }
129
130        // Move the sprite.
131        self.pos += self.v;
132
133        // Make the sprite bounce off the screen edges.
134        let scaling = 5.;
135
136        if self.pos.x - scaling * 4. < 0. || self.pos.x + scaling * 4. >= ctx.gfx.drawable_size().0
137        {
138            self.v.x *= -1.;
139        }
140
141        if self.pos.y - scaling * 8. < 0. || self.pos.y + scaling * 8. >= ctx.gfx.drawable_size().1
142        {
143            self.v.y *= -1.;
144        }
145
146        // And handle messages as usual
147
148        let messages = self.gui.manage_messages(ctx, None);
149
150        if messages.contains(&ui::UiMessage::Triggered(1)) {
151            return Ok(scene_manager::SceneSwitch::pop(1));
152        }
153
154        Ok(scene_manager::SceneSwitch::None)
155    }
examples/ui_examples/g_selector_scene.rs (line 89)
88    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
89        let messages = self.gui.manage_messages(ctx, None);
90
91        // Scene switches for different scenes
92
93        if messages.contains(&ui::UiMessage::Triggered(1)) {
94            return Ok(scene_manager::SceneSwitch::push(
95                crate::b_scene::BScene::new(ctx),
96            ));
97        }
98
99        if messages.contains(&ui::UiMessage::Triggered(2)) {
100            return Ok(scene_manager::SceneSwitch::push(
101                crate::c_uielement::CScene::new(ctx),
102            ));
103        }
104
105        if messages.contains(&ui::UiMessage::Triggered(3)) {
106            return Ok(scene_manager::SceneSwitch::push(
107                crate::d_containers::DScene::new(ctx)?,
108            ));
109        }
110
111        if messages.contains(&ui::UiMessage::Triggered(4)) {
112            return Ok(scene_manager::SceneSwitch::push(
113                crate::e_messages::EScene::new(ctx)?,
114            ));
115        }
116
117        if messages.contains(&ui::UiMessage::Triggered(5)) {
118            return Ok(scene_manager::SceneSwitch::push(
119                crate::f_sprites::FScene::new(ctx)?,
120            ));
121        }
122
123        // Exit
124
125        if messages.contains(&ui::UiMessage::Triggered(6)) {
126            return Ok(scene_manager::SceneSwitch::pop(1));
127        }
128
129        Ok(scene_manager::SceneSwitch::None)
130    }
examples/ui_examples/e_messages.rs (line 217)
214    fn update(&mut self, ctx: &mut Context) -> Result<scene_manager::SceneSwitch, GameError> {
215        // Nothing much to do here, except implement the back button functionality.
216
217        let messages = self.gui.manage_messages(ctx, None);
218
219        if messages.contains(&ui::UiMessage::Triggered(1)){
220            // If it is, we end the current scene (and return to the previous one) by popping it off the stack.
221            return Ok(scene_manager::SceneSwitch::pop(1));
222        }
223
224        if messages.contains(&ui::UiMessage::Triggered(13)){
225            // If a certain button is pressed, add a small text element to the gui.
226            self.gui.add_element(100,
227                // using a duration box as a wrapper will remove the element after a set amount of time
228                  ui::containers::DurationBox::new(
229                    Duration::from_secs_f32(1.5),
230                     graphics::Text::new("Just a small reminder that you pressed button 13.")
231                     .set_font("Bahnschrift")
232                     .set_wrap(true)
233                     .set_bounds(glam::Vec2::new(200., 500.))
234                     .set_scale(28.)
235                     .to_owned()
236                     .to_element_builder(0, ctx)
237                     .with_visuals(ui::Visuals::new(
238                        Color::from_rgb(77, 109, 191),
239                        Color::from_rgb(55, 67, 87),
240                        2.,
241                        4.,
242                    ))
243                     .build()
244                    ).to_element_builder(0, ctx)
245                    .with_alignment(ui::Alignment::Center, ui::Alignment::Min)
246                    .with_offset(0., 25.)
247                    .build()
248                    );
249        }
250
251        Ok(scene_manager::SceneSwitch::None)
252    
253    }
Source

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.

Source

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.

Source

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.

Source

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?
examples/ui_examples/e_messages.rs (line 262)
255    fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
256
257        // Once again the basic drawing function.
258
259        let mut canvas = graphics::Canvas::from_frame(ctx, None);
260        canvas.set_sampler(graphics::Sampler::nearest_clamp());
261
262        self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
263
264        canvas.finish(ctx)?;
265
266        Ok(())
267    }
More examples
Hide additional examples
examples/ui_examples/g_selector_scene.rs (line 138)
132    fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
133        // business as usual
134        let mut canvas = ggez::graphics::Canvas::from_frame(ctx, Color::from_rgb(100, 100, 150));
135
136        canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
137
138        self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
139
140        canvas.finish(ctx)?;
141
142        Ok(())
143    }
examples/ui_examples/d_containers.rs (line 174)
167    fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
168        // Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.
169
170        let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);
171        // Since we don't set the sampler to 'nearest', our corners will look more round, but the pixel-cow will look blurry.
172        //canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
173
174        self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
175
176        canvas.finish(ctx)?;
177
178        Ok(())
179    }
examples/ui_examples/c_uielement.rs (line 90)
81    fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
82        // Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.
83        let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);        
84        canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
85        
86        // Here, you would draw your gamestate.
87
88        // Drawing a gui is as easy as calling draw_to_screen on the root element.
89        // If you are using a scene, you can simply pass on the mouse_listen parameter. It will be managed by the scene manager.
90        self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
91
92        // Once again, we end drawing by finishing the canvas.
93        canvas.finish(ctx)?;
94
95        Ok(())
96    }
examples/ui_examples/f_sprites.rs (line 195)
157    fn draw(&mut self, ctx: &mut Context, mouse_listen: bool) -> Result<(), GameError> {
158        // Once again, we first create a canvas and set a pixel sampler. Note that this time, we dont clear the background.
159
160        let mut canvas = ggez::graphics::Canvas::from_frame(ctx, None);
161        canvas.set_sampler(ggez::graphics::Sampler::nearest_clamp());
162
163        // Drawing of our (limited) game state.
164
165        // see if we need to mirror our sprite if it moves left
166        let mirroring = if self.v.x > 0. { 1. } else { -1. };
167        let scaling = 5.;
168
169        self.sprite.draw_sprite(
170            ctx,
171            &mut canvas,
172            DrawParam::new().dest_rect(Rect::new(
173                self.pos.x - scaling * 4. * mirroring,
174                self.pos.y - scaling * 8.,
175                scaling * mirroring,
176                scaling,
177            )),
178        );
179
180        let scaling = 2.;
181
182        self.sprite2.draw_sprite(
183            ctx,
184            &mut canvas,
185            DrawParam::new().dest_rect(Rect::new(
186                self.pos.x - scaling * 4. + 32.,
187                self.pos.y - scaling * 8. + 32.,
188                scaling,
189                scaling,
190            )),
191        );
192
193        // And once again drawing the GUI.
194
195        self.gui.draw_to_screen(ctx, &mut canvas, mouse_listen);
196
197        canvas.finish(ctx)?;
198
199        Ok(())
200    }

Trait Implementations§

Source§

impl<T: Copy + Eq + Hash> Debug for UiElement<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Copy + Eq + Hash> From<UiElement<T>> for UiElementBuilder<T>

Source§

fn from(value: UiElement<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: Copy + Eq + Hash> From<UiElementBuilder<T>> for UiElement<T>

Source§

fn from(value: UiElementBuilder<T>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<T> !Freeze for UiElement<T>

§

impl<T> !RefUnwindSafe for UiElement<T>

§

impl<T> !Send for UiElement<T>

§

impl<T> !Sync for UiElement<T>

§

impl<T> Unpin for UiElement<T>

§

impl<T> !UnwindSafe for UiElement<T>

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Has<T> for T

Source§

fn retrieve(&self) -> &T

Method to retrieve the context type.
Source§

impl<T> HasMut<T> for T

Source§

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

Method to retrieve the context type as mutable.
Source§

impl<T, U> Into<U> for T
where 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

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

Source§

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 T
where U: TryFrom<T>,

Source§

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.
Source§

impl<T> Upcast<T> for T

Source§

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

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,