Foundation classes for a basic GUI implementing simple widgets and events

Dependents:   TouchScreenGUIDemo

Committer:
duncanFrance
Date:
Sat May 28 14:50:14 2016 +0000
Revision:
18:d849f3ada858
Parent:
17:5184762fda6c
Moved the event queue into the EventDispatcher; Improved event handling across Window/Widget

Who changed what in which revision?

UserRevisionLine numberNew contents of line
duncanFrance 12:63db16fea709 1 #include "Window.h"
duncanFrance 12:63db16fea709 2
duncanFrance 18:d849f3ada858 3 Window::Window(GraphicsContext* context) : Widget(context), _childHandledEvents(0)
duncanFrance 12:63db16fea709 4 {
duncanFrance 17:5184762fda6c 5 setSize(context->display()->width(), context->display()->height());
duncanFrance 12:63db16fea709 6 }
duncanFrance 12:63db16fea709 7
duncanFrance 12:63db16fea709 8 void Window::attach(Widget *widget)
duncanFrance 12:63db16fea709 9 {
duncanFrance 12:63db16fea709 10 _widgets.append(widget);
duncanFrance 12:63db16fea709 11 widget->setParent(this);
duncanFrance 18:d849f3ada858 12 _reenumerateEvents();
duncanFrance 17:5184762fda6c 13 widget->show();
duncanFrance 12:63db16fea709 14 dirtyAll();
duncanFrance 12:63db16fea709 15 damage();
duncanFrance 12:63db16fea709 16 }
duncanFrance 12:63db16fea709 17
duncanFrance 12:63db16fea709 18
duncanFrance 12:63db16fea709 19 void Window::detach(Widget *widget)
duncanFrance 12:63db16fea709 20 {
duncanFrance 17:5184762fda6c 21 widget->hide();
duncanFrance 12:63db16fea709 22 _widgets.remove(widget);
duncanFrance 12:63db16fea709 23 widget->setParent(NULL);
duncanFrance 18:d849f3ada858 24 _reenumerateEvents();
duncanFrance 12:63db16fea709 25 dirty();
duncanFrance 12:63db16fea709 26 }
duncanFrance 12:63db16fea709 27
duncanFrance 12:63db16fea709 28 void Window::dirtyAll() {
duncanFrance 12:63db16fea709 29 if(!_dirtying) {
duncanFrance 12:63db16fea709 30
duncanFrance 12:63db16fea709 31 _dirtying = true;
duncanFrance 12:63db16fea709 32
duncanFrance 12:63db16fea709 33 _dirty();
duncanFrance 12:63db16fea709 34
duncanFrance 12:63db16fea709 35 Widget *w;
duncanFrance 12:63db16fea709 36 _widgets.reset();
duncanFrance 12:63db16fea709 37
duncanFrance 12:63db16fea709 38 while((w = _widgets.next()) != NULL) {
duncanFrance 12:63db16fea709 39 w->dirtyAll();
duncanFrance 12:63db16fea709 40 }
duncanFrance 12:63db16fea709 41
duncanFrance 12:63db16fea709 42 _dirtying = false;
duncanFrance 12:63db16fea709 43 }
duncanFrance 12:63db16fea709 44 }
duncanFrance 12:63db16fea709 45
duncanFrance 12:63db16fea709 46 void Window::_draw()
duncanFrance 12:63db16fea709 47 {
duncanFrance 12:63db16fea709 48 Widget::_draw();
duncanFrance 12:63db16fea709 49
duncanFrance 12:63db16fea709 50 Widget* w;
duncanFrance 12:63db16fea709 51
duncanFrance 12:63db16fea709 52 // Draw only the damaged widgets first
duncanFrance 12:63db16fea709 53 LinkedList<Widget> _damaged;
duncanFrance 12:63db16fea709 54
duncanFrance 12:63db16fea709 55 _widgets.reset();
duncanFrance 12:63db16fea709 56 while((w = _widgets.next()) != NULL) {
duncanFrance 12:63db16fea709 57 if(w->isDamaged()) {
duncanFrance 12:63db16fea709 58 _damaged.appendOnce(w);
duncanFrance 12:63db16fea709 59 w->adjust();
duncanFrance 12:63db16fea709 60 w->draw();
duncanFrance 12:63db16fea709 61 }
duncanFrance 12:63db16fea709 62 }
duncanFrance 12:63db16fea709 63
duncanFrance 12:63db16fea709 64 _damaged.reset();
duncanFrance 12:63db16fea709 65 while((w = _damaged.next()) != NULL) {
duncanFrance 12:63db16fea709 66 _dirtyIntersected(w);
duncanFrance 12:63db16fea709 67 }
duncanFrance 12:63db16fea709 68 _damaged.clear();
duncanFrance 12:63db16fea709 69
duncanFrance 12:63db16fea709 70 _widgets.reset();
duncanFrance 12:63db16fea709 71 while((w = _widgets.next()) != NULL) {
duncanFrance 12:63db16fea709 72 w->draw();
duncanFrance 12:63db16fea709 73 }
duncanFrance 12:63db16fea709 74 }
duncanFrance 12:63db16fea709 75
duncanFrance 12:63db16fea709 76 void Window::_dirtyIntersected(Widget *w)
duncanFrance 12:63db16fea709 77 {
duncanFrance 12:63db16fea709 78 Widget *o;
duncanFrance 18:d849f3ada858 79 LinkedListIterator<Widget> it = _widgets.getIterator();
duncanFrance 18:d849f3ada858 80 while((o = it.next()) != NULL) {
duncanFrance 12:63db16fea709 81 if((o != w) && o->intersects(w)) {
duncanFrance 12:63db16fea709 82 o->dirtyAll();
duncanFrance 12:63db16fea709 83 }
duncanFrance 12:63db16fea709 84 }
duncanFrance 12:63db16fea709 85 }
duncanFrance 12:63db16fea709 86
duncanFrance 18:d849f3ada858 87 void Window::handleEvent(Event e) {
duncanFrance 18:d849f3ada858 88 Widget::handleEvent(e);
duncanFrance 18:d849f3ada858 89 // At this point we can do bubbling, cancelling etc. One day
duncanFrance 18:d849f3ada858 90 if(_childHandledEvents & e.type) {
duncanFrance 18:d849f3ada858 91 LinkedListIterator<Widget> it = _widgets.getIterator();
duncanFrance 18:d849f3ada858 92 Widget *w;
duncanFrance 18:d849f3ada858 93 while((w = it.next()) != NULL) {
duncanFrance 18:d849f3ada858 94 w->handleEvent(e);
duncanFrance 18:d849f3ada858 95 }
duncanFrance 18:d849f3ada858 96 }
duncanFrance 18:d849f3ada858 97 }
duncanFrance 18:d849f3ada858 98
duncanFrance 18:d849f3ada858 99 void Window::_reenumerateHandledEvents() {
duncanFrance 18:d849f3ada858 100
duncanFrance 18:d849f3ada858 101 Widget::_reenumerateHandledEvents();
duncanFrance 18:d849f3ada858 102
duncanFrance 18:d849f3ada858 103 _childHandledEvents = 0;
duncanFrance 18:d849f3ada858 104 Widget *w;
duncanFrance 18:d849f3ada858 105 LinkedListIterator<Widget> wit = _widgets.getIterator();
duncanFrance 18:d849f3ada858 106 while((w = wit.next()) != NULL) {
duncanFrance 18:d849f3ada858 107 _childHandledEvents |= w->_getHandledEvents();
duncanFrance 18:d849f3ada858 108 w = _widgets.next();
duncanFrance 18:d849f3ada858 109 }
duncanFrance 18:d849f3ada858 110 }
duncanFrance 18:d849f3ada858 111
duncanFrance 18:d849f3ada858 112 uint16_t Window::_getHandledEvents() {
duncanFrance 18:d849f3ada858 113 uint16_t m = Widget::_getHandledEvents();
duncanFrance 18:d849f3ada858 114 m |= _childHandledEvents;
duncanFrance 18:d849f3ada858 115 return m;
duncanFrance 18:d849f3ada858 116 }