Struct mooeye::ui::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
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)
    
    }
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
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
Hide additional examples
examples/ui_examples/c_uielement.rs (line 69)
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)
    }
examples/ui_examples/f_sprites.rs (line 148)
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)
    }
examples/ui_examples/g_selector_scene.rs (line 89)
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)
    }
examples/ui_examples/e_messages.rs (line 217)
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)
    
    }
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
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
Hide additional examples
examples/ui_examples/g_selector_scene.rs (line 138)
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(())
    }
examples/ui_examples/d_containers.rs (line 174)
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(())
    }
examples/ui_examples/c_uielement.rs (line 90)
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(())
    }
examples/ui_examples/f_sprites.rs (line 195)
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(())
    }

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> !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 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.

§

impl<S> FromSample<S> for S

§

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

§

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

§

fn into_sample(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

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

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

§

fn to_sample_(self) -> U

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>

§

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

§

fn vzip(self) -> V

§

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