Foundation classes for a basic GUI implementing simple widgets and events
Dependents: TouchScreenGUIDemo
Widgets/Widget.cpp
- Committer:
- duncanFrance
- Date:
- 2016-05-21
- Revision:
- 13:6714534e7974
- Parent:
- 12:63db16fea709
- Child:
- 15:e69fd74d42e4
File content as of revision 13:6714534e7974:
#include "Widget.h" #include <algorithm> Widget::Widget(GraphicsContext* context) : _context(context), _fg(White), _bg(Black), _offset(0,0), _inner(0,0,0,0), _outer(0,0,0,0), _hidden(false), _padding(0), _borderWidth(0), _borderColour(Black), _adjusting(false), _dirtied(true), _dirtying(false), _damaged(true), _damaging(false) { } void Widget::setParent(Widget* parent) { _parent = parent; } bool Widget::isEventTarget(Event e) { return !_hidden && e.screenX >= _outer.x && e.screenX <= (_outer.x+_outer.width) && e.screenY >= _outer.y && e.screenY <= (_outer.y+_outer.height); } // Location is referred to the offset void Widget::setLocation(int x, int y) { if( (_outer.x != (x+_offset.x())) || (_outer.y != y+_offset.y()) ) { _outer.x = x + _offset.x(); _outer.y = y + _offset.y(); damage(); adjust(); } } void Widget::setSize(int width, int height) { if(_outer.width != width || _outer.height != height) { _outer.width = width; _outer.height = height; damage(); adjust(); } } void Widget::setWidth(int width) { if(_outer.width != width) { _outer.width = width; damage(); adjust(); } } void Widget::setHeight(int height) { if(_outer.height != height) { _outer.height = height; damage(); adjust(); } } int Widget::x() { return _outer.x; } int Widget::y() { return _outer.y; } int Widget::height() { return _outer.height; } int Widget::width() { return _outer.width; } /** const Rectangle &Widget::outer() { return _outer; } const Rectangle &Widget::inner() { return _inner; } **/ void Widget::setOffset(int x, int y) { _outer.x = _outer.x - _offset.x() + x; _outer.y = _outer.y - _offset.y() + y; _offset.x(x); _offset.y(y); damage(); adjust(); } int Widget::offsetX() { return _offset.x(); } int Widget::offsetY() { return _offset.y(); } void Widget::setForeground(uint16_t color) { if(_fg != color) { _fg = color; dirty(); } } void Widget::setBackground(uint16_t color) { if(_bg != color) { _bg = color; dirty(); } } /** * Set the amount of padding between the border and a widget edge **/ void Widget::setPadding(int pixels) { if(_padding != pixels) { _padding = pixels; dirty(); } } void Widget::setBorder(int width, uint16_t colour) { if(_borderWidth != width || _borderColour != colour) { _borderColour = colour; _borderWidth = width; dirty(); } } void Widget::draw() { if(!_hidden && (_dirtied | _damaged)) { _draw(); _dirtied = false; _damaged = false; } } void Widget::clear() { if(!_hidden) _clear(); } void Widget::show() { _hidden = false; draw(); } void Widget::hide() { clear(); _hidden = true; } bool Widget::isHidden() { return _hidden; } void Widget::setEventHandler(EventHandler* handler) { EventListener::setEventHandler(handler); _context->eventDispatcher()->detachListener(this); _context->eventDispatcher()->attachListener(this); } void Widget::unsetEventHandler(EventHandler *handler) { EventListener::unsetEventHandler(handler); } bool Widget::intersects(Widget *w) { return _outer.intersects(w->_outer); } void Widget::dirty() { if(!_dirtying) { _dirtying = true; _dirty(); _dirtying = false; } } bool Widget::isDirty() { return _dirtied; } void Widget::dirtyAll() { _dirtied = true; } void Widget::damage() { if(!_damaging) { _damaging = true; _damage(); _damaging = false; } } bool Widget::isDamaged() { return _damaged; } void Widget::adjust() { if(!_adjusting) { _adjusting = true; _adjust(); _adjusting = false; } } GraphicsDisplay* Widget::display() { return _context->display(); } /********************************************************** * Protected methods **********************************************************/ void Widget::_draw() { GraphicsDisplay *d = display(); // Draw the border // Top d->fillrect(_outer.x, _outer.y, _outer.x+_outer.width, _outer.y+_borderWidth, _borderColour); // Bottom d->fillrect(_outer.x, _outer.y + _outer.height - _borderWidth, _outer.x + _outer.width, _outer.y+_outer.height, _borderColour); // Left d->fillrect(_outer.x, _outer.y, _outer.x+_borderWidth, _outer.y+_outer.height, _borderColour); // Right d->fillrect(_outer.x+_outer.width-_borderWidth, _outer.y, _outer.x+_outer.width, _outer.y+_outer.height, _borderColour); } void Widget::_clear() { display()->fillrect(_outer.x, _outer.y, _outer.x+_outer.width, _outer.y+_outer.height, display()->getBackground()); } void Widget::_dirty() { _dirtied = true; if(_parent != NULL) { _parent->dirty(); } } void Widget::_damage() { _damaged = true; if(_parent != NULL) { _parent->dirty(); } } void Widget::_adjust() { // Recalculate size of inner Rect _inner.resize(_outer, _borderWidth + _padding); }