Max OS 0.3
Loading...
Searching...
No Matches
widget.cpp
Go to the documentation of this file.
1
9#include <gui/widget.h>
10
11using namespace MaxOS::common;
12using namespace MaxOS::gui;
13using namespace MaxOS::drivers;
14using namespace MaxOS::drivers::peripherals;
15
24
35 m_position(left, top, width, height)
36{
37
38}
39
40Widget::~Widget() = default;
41
51
56
57 // Convert the relative coordinates to absolute coordinates
59
60 // Create a rectangle with the absolute coordinates and the size of the widget
62
63 // Invalidate the area
65
66}
67
74
75 // If the widget has a parent, invalidate the area of the parent
76 if (m_parent != nullptr)
78}
79
86
87 // Parent the child to this widget
88 child->m_parent = this;
89
90}
91
99
100 // Return the parents absolute coordinates
101 if (m_parent != nullptr)
103
104 // If the widget has no m_parent, return the coordinates of the widget
105 return {coordinates.first + m_position.left, coordinates.second + m_position.top};
106
107}
108
117
118 // Check if the coordinates are within the bounds of the widget
119 return m_position.contains(x, y);
120}
121
131
138void Widget::move(int32_t left, int32_t top) {
139
140 // Invalidate the old position
141 invalidate();
142
143 // Set the new position
144 m_position.left = left;
145 m_position.top = top;
146
147 // Re draw the widget in the new position
148 invalidate();
149}
150
159void Widget::resize(int32_t width, int32_t height) {
160
161 // Restrict the width and height to the minimum and maximum values
162 if (width < (int) m_min_width) width = m_min_width;
163 if (height < (int) m_min_height) height = m_min_height;
164 if (width > (int) m_max_width) width = m_max_width;
165 if (height > (int) m_max_height) height = m_max_height;
166
167 // Store the old position, set the new position
169 m_position.width = width;
170 m_position.height = height;
171
172 // Find the areas that need to be redrawn by subtracting the old position from the new position, and vice versa
175
176 // Right and Bottom require to be fully invalidated
179 invalidate();
180 return;
181 }
182
183 //Loop through the areas that need to be redrawn and invalidate them
184 for (auto& area: invalid_areas_old)
186
187 for (auto& area: invalid_areas_new)
189
190}
191
196
197 // Set the focus the widget to this widget
198 set_focus(this);
199}
200
207
208 // Focus the parent to this widget
209 if (m_parent != nullptr)
211}
212
217
218}
219
224
225}
226
231
232 // Bring this widget to the front of the screen
233 bring_to_front(this);
234}
235
242
243 // Bring the parent to the front of the screen
244 if (m_parent != nullptr)
246
247}
248
258
268
280
290
291 // Bring the widget to the front of the screen
293
294 // Focus the widget
295 focus();
296
297 // Return 0 as the event has been handled
298 return nullptr;
299}
300
311
312CompositeWidget::CompositeWidget() = default;
313
322CompositeWidget::CompositeWidget(int32_t left, int32_t top, uint32_t width, uint32_t height)
323: Widget(left, top, width, height) {
324
325}
326
327CompositeWidget::~CompositeWidget() = default;
328
336
337 // Draw the widget with its m_children
338 draw(gc, area, m_children.begin());
339}
340
349
350 // Draw the widget
352
353 // Get the area of the widget
355
356 //Note: has to use iterator as the start is not necessarily the m_first_memory_chunk child
358
359 Rectangle<int32_t> child_area = (*child_widget)->position();
360
361 // Check if the child is in the area that needs to be redrawn
363
364 // Get the area that needs to be redrawn
366
367 // Translate the area so that it is relative to the child
370
371 // Draw the child
372 (*child_widget)->draw(gc, rectangle);
373
374 // Draw what is left of the area that needs to be redrawn
376 for (auto& rest_area_part: rest_draw_area)
378
379 // Return as the entire area has now been drawn
380 return;
381 }
382 }
383
384 // Now draw the widget itself
385 draw_self(gc, area);
386}
387
397
404
405 // Store the child and parent the child to this widget
406 m_children.push_back(child);
408}
409
417
418 for (auto& child_widget: m_children) {
419
420 // Check if the mouse is in the child
423
424 // Get the position of the mouse relative to the child
427
428 // Call the child's on_mouse_enter_widget function
429 child_widget->on_mouse_enter_widget(child_x, child_y);
430
431 // Break as the event has been handled
432 break;
433 }
434 }
435}
436
444
445 for (auto& child_widget: m_children) {
446
447 // Check if the mouse is in the child
450
451 // Get the position of the mouse relative to the child
454
455 // Call the child's on_mouse_leave_widget function
456 child_widget->on_mouse_leave_widget(child_x, child_y);
457
458 // Event has been handled
459 break;
460 }
461 }
462}
463
473
474 Widget* left_child = nullptr;
475 Widget* entered_child = nullptr;
476
477 for (auto& child_widget: m_children) {
478
479 // Check if the mouse is in the child
483
484 // If the mouse started in the child
485 if (mouse_in_from) {
486
487 // The mouse moved out of the child
488 if (!mouse_in_to) {
490 continue;
491 }
492
493 // Mouse still in the child
494 child_widget->on_mouse_move_widget(from_x, from_y, to_x, to_y);
495
496 } else {
497
498 // Mouse moved into the child
499 if (mouse_in_to)
501 }
502
503 // Pass the events to the child
504 if (left_child != nullptr)
505 left_child->on_mouse_leave_widget(from_x, from_y);
506
507 if (entered_child != nullptr)
508 entered_child->on_mouse_enter_widget(to_x, to_y);
509 }
510}
511
521
523
524 for (auto& child_widget: m_children) {
525
526 // Pass the event to the child
527 if (child_widget->contains_coordinate(x, y)) {
528 mouse_event_handler = child_widget->on_mouse_button_pressed(x - child_widget->m_position.left,
529 y - child_widget->m_position.top, button);
530 break;
531 }
532 }
533
534 return mouse_event_handler;
535}
536
545
546 // Loop through the m_children
547 for (auto& child_widget: m_children) {
548
549 // Pass the event to the child
550 if (child_widget->contains_coordinate(x, y)) {
551 child_widget->on_mouse_button_released(x - child_widget->m_position.left, y - child_widget->m_position.top,
552 button);
553 break;
554 }
555 }
556}
Draws pixels to the screen, and handles drawing lines, rectangles and circles.
A pair of two objects.
Definition pair.h:22
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
Type height
The height of the rectangle.
Definition rectangle.h:27
Type top
The top coordinate of the rectangle.
Definition rectangle.h:25
bool intersects(const Rectangle< Type > &)
Definition rectangle.h:88
Rectangle< Type > intersection(const Rectangle< Type > &)
Definition rectangle.h:116
Type left
The left coordinate of the rectangle.
Definition rectangle.h:24
Vector< Rectangle< Type > > subtract(const Rectangle< Type > &)
Definition rectangle.h:142
bool contains(const Rectangle< Type > &)
Definition rectangle.h:192
Type width
The width of the rectangle.
Definition rectangle.h:26
Handles the events that are triggered by the Keyboard Driver.
Definition keyboard.h:274
Handles events that are triggered by the mouse driver.
Definition mouse.h:72
void on_mouse_move_widget(uint32_t from_x, uint32_t from_y, uint32_t to_x, uint32_t to_y) override
Passes the event to the child that the mouse is over, also generates a leave/enter event for children...
Definition widget.cpp:472
void on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button) override
Passes the event to the child that the mouse is over. (Event handling should be done by the derived c...
Definition widget.cpp:544
common::Vector< Widget * > m_children
Widgets contained within this composite widget.
Definition widget.h:92
void on_mouse_leave_widget(uint32_t from_x, uint32_t from_y) override
Passes the event to the child that the mouse is over. (Event handling should be done by the derived c...
Definition widget.cpp:443
virtual void draw_self(common::GraphicsContext *gc, common::Rectangle< int32_t > &area)
Draws the widget itself (should be overridden by the derived class)
Definition widget.cpp:394
void add_child(Widget *child) override
Adds a child to the widget.
Definition widget.cpp:403
drivers::peripherals::MouseEventHandler * on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button) override
Passes the event to the child that the mouse is over.
Definition widget.cpp:520
void draw(common::GraphicsContext *gc, common::Rectangle< int32_t > &area, common::Vector< Widget * >::iterator start)
Draws a section of the widget and the m_children after a specific child.
Definition widget.cpp:348
void on_mouse_enter_widget(uint32_t to_x, uint32_t to_y) override
Passes the event to the child that the mouse is over. (Event handling should be done by the derived c...
Definition widget.cpp:416
A graphical object that can be drawn on the screen.
Definition widget.h:29
uint32_t m_min_width
The smallest m_width the widget can be resized to.
Definition widget.h:40
virtual void bring_to_front(Widget *)
Brings a specific widget to the front of the screen.
Definition widget.cpp:241
virtual void on_focus()
Handles the event when the widget is focussed.
Definition widget.cpp:216
virtual void on_focus_lost()
Handles the event when the widget is unfocused.
Definition widget.cpp:223
uint32_t m_max_width
The largest m_width the widget can be resized to.
Definition widget.h:43
virtual void on_mouse_leave_widget(uint32_t from_x, uint32_t from_y)
Handles the event when the mouse is moved out of the widget.
Definition widget.cpp:265
void focus()
Set the current focused widget to be this widget.
Definition widget.cpp:195
void invalidate()
Invalidates the entire widget. This forces the widget to be redrawn on the next screen update.
Definition widget.cpp:55
virtual bool contains_coordinate(uint32_t x, uint32_t y)
Check if the widget contains a specific coordinate.
Definition widget.cpp:116
virtual void draw(common::GraphicsContext *gc, common::Rectangle< int32_t > &area)
Draw the widget on the screen.
Definition widget.cpp:48
uint32_t m_max_height
The largest m_height the widget can be resized to.
Definition widget.h:44
common::Rectangle< int32_t > position()
Get the position of the widget.
Definition widget.cpp:127
void resize(int32_t width, int32_t height)
Set the size of the widget, and invalidate the old and new positions so they are redrawn.
Definition widget.cpp:159
virtual void on_mouse_enter_widget(uint32_t to_x, uint32_t to_y)
Handles the event when the mouse is moved on to the widget.
Definition widget.cpp:255
virtual void on_mouse_move_widget(uint32_t from_x, uint32_t from_y, uint32_t to_x, uint32_t to_y)
Handles the event when the mouse is moved over the widget.
Definition widget.cpp:277
uint32_t m_min_height
The smallest m_height the widget can be resized to.
Definition widget.h:41
common::Rectangle< int32_t > m_position
The position and size of the widget (relative to its parent)
Definition widget.h:35
void bring_to_front()
Brings this widget to the front of the screen.
Definition widget.cpp:230
virtual drivers::peripherals::MouseEventHandler * on_mouse_button_pressed(uint32_t x, uint32_t y, uint8_t button)
Handles the event when the mouse is pressed on the widget.
Definition widget.cpp:289
Widget()
Construct a new Widget object.
Definition widget.cpp:19
void move(int32_t left, int32_t top)
Set the position of the widget, and invalidate the old and new positions so they are redrawn.
Definition widget.cpp:138
virtual void on_mouse_button_released(uint32_t x, uint32_t y, uint8_t button)
Handles the event when the mouse is released on the widget.
Definition widget.cpp:308
virtual common::Coordinates absolute_coordinates(common::Coordinates coordinates)
Get the absolute coordinates of the widget (relative to the screen)
Definition widget.cpp:98
virtual void add_child(Widget *child)
Set the parent of a widget to this widget, making it into a child.
Definition widget.cpp:85
virtual void set_focus(Widget *)
Sets the widget that is currently focussed.
Definition widget.cpp:206
Widget * m_parent
The widget that owns this widget.
Definition widget.h:37
Defines a base Widget class and CompositeWidget class for creating graphical user interface elements.