Foundation classes for a basic GUI implementing simple widgets and events
Dependents: TouchScreenGUIDemo
Widgets/Window.cpp@18:d849f3ada858, 2016-05-28 (annotated)
- 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?
User | Revision | Line number | New 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 | } |