Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SimpleGUI by
Widget.cpp
00001 #include "Widget.h" 00002 #include <algorithm> 00003 Widget::Widget(GraphicsContext* context) 00004 : _handledEvents(0), 00005 _parent(NULL), _context(context), 00006 _fg(White), _bg(Black), 00007 _offset(0,0), _outer(0,0,0,0), _inner(0,0,0,0), 00008 _hidden(false), 00009 _padding(0), _borderWidth(0), _borderColour(Black), 00010 _adjusting(false), 00011 _dirtied(true), _dirtying(false), 00012 _damaged(true), _damaging(false) 00013 { 00014 } 00015 00016 void Widget::setParent(Widget* parent) { 00017 _parent = parent; 00018 } 00019 00020 Widget *Widget::getParent() { 00021 return _parent; 00022 } 00023 00024 // Location is referred to the offset 00025 void Widget::setLocation(int x, int y) 00026 { 00027 if( (_outer.x != (x+_offset.x())) || (_outer.y != y+_offset.y()) ) { 00028 _outer.x = x + _offset.x(); 00029 _outer.y = y + _offset.y(); 00030 damage(); 00031 adjust(); 00032 } 00033 } 00034 00035 void Widget::setSize(int width, int height) 00036 { 00037 if(_outer.width != width || _outer.height != height) { 00038 _outer.width = width; 00039 _outer.height = height; 00040 damage(); 00041 adjust(); 00042 } 00043 } 00044 00045 void Widget::setWidth(int width) { 00046 if(_outer.width != width) { 00047 _outer.width = width; 00048 damage(); 00049 adjust(); 00050 } 00051 } 00052 00053 void Widget::setHeight(int height) { 00054 if(_outer.height != height) { 00055 _outer.height = height; 00056 damage(); 00057 adjust(); 00058 } 00059 } 00060 00061 int Widget::x() 00062 { 00063 return _outer.x; 00064 } 00065 00066 int Widget::y() 00067 { 00068 return _outer.y; 00069 } 00070 00071 int Widget::height() 00072 { 00073 return _outer.height; 00074 } 00075 00076 int Widget::width() 00077 { 00078 return _outer.width; 00079 } 00080 /** 00081 const Rectangle &Widget::outer() { 00082 return _outer; 00083 } 00084 00085 const Rectangle &Widget::inner() { 00086 return _inner; 00087 } 00088 **/ 00089 void Widget::setOffset(int x, int y) { 00090 _outer.x = _outer.x - _offset.x() + x; 00091 _outer.y = _outer.y - _offset.y() + y; 00092 _offset.x(x); 00093 _offset.y(y); 00094 damage(); 00095 adjust(); 00096 } 00097 00098 int Widget::offsetX() { 00099 return _offset.x(); 00100 } 00101 00102 int Widget::offsetY() { 00103 return _offset.y(); 00104 } 00105 00106 00107 void Widget::setForeground(uint16_t color) 00108 { 00109 if(_fg != color) { 00110 _fg = color; 00111 dirty(); 00112 } 00113 } 00114 00115 void Widget::setBackground(uint16_t color) 00116 { 00117 if(_bg != color) { 00118 _bg = color; 00119 dirty(); 00120 } 00121 } 00122 00123 00124 /** 00125 * Set the amount of padding between the border and a widget edge 00126 **/ 00127 void Widget::setPadding(int pixels) 00128 { 00129 if(_padding != pixels) { 00130 _padding = pixels; 00131 dirty(); 00132 } 00133 } 00134 00135 void Widget::setBorder(int width, uint16_t colour) 00136 { 00137 if(_borderWidth != width || _borderColour != colour) { 00138 _borderColour = colour; 00139 _borderWidth = width; 00140 dirty(); 00141 } 00142 } 00143 00144 void Widget::draw() 00145 { 00146 if(!_hidden && (_dirtied | _damaged)) { 00147 _draw(); 00148 _dirtied = false; 00149 _damaged = false; 00150 } 00151 } 00152 00153 void Widget::clear() 00154 { 00155 if(!_hidden) _clear(); 00156 } 00157 00158 void Widget::show() 00159 { 00160 _hidden = false; 00161 dirty(); 00162 damage(); 00163 } 00164 00165 void Widget::hide() 00166 { 00167 _clear(); 00168 _hidden = true; 00169 } 00170 00171 bool Widget::isHidden() 00172 { 00173 return _hidden; 00174 } 00175 00176 void Widget::setEventHandler(EventHandler* handler) 00177 { 00178 _handlers.appendOnce(handler); 00179 _reenumerateEvents(); 00180 } 00181 00182 void Widget::unsetEventHandler(EventHandler *handler) 00183 { 00184 _handlers.remove(handler); 00185 _reenumerateEvents(); 00186 } 00187 00188 bool Widget::_isEventTarget(Event e) 00189 { 00190 return !_hidden 00191 && e.screenX >= _outer.x 00192 && e.screenX <= (_outer.x+_outer.width) 00193 && e.screenY >= _outer.y 00194 && e.screenY <= (_outer.y+_outer.height); 00195 } 00196 00197 void Widget::handleEvent(Event e) { 00198 e.target = this; 00199 if(_isEventTarget(e)) { 00200 _handlers.reset(); 00201 EventHandler *h; 00202 while((h = _handlers.next()) != NULL) { 00203 if(h->type == e.type) { 00204 h->handle(e); 00205 } 00206 } 00207 } 00208 } 00209 00210 void Widget::_reenumerateEvents() { 00211 _reenumerateHandledEvents(); 00212 if(_parent != NULL) { 00213 _parent->_reenumerateEvents(); 00214 } 00215 } 00216 00217 void Widget::_reenumerateHandledEvents() { 00218 _handledEvents = 0; 00219 EventHandler *h; 00220 LinkedListIterator<EventHandler> eit = _handlers.getIterator(); 00221 while((h = eit.next()) != NULL) { 00222 _handledEvents |= h->type; 00223 } 00224 } 00225 00226 uint16_t Widget::_getHandledEvents() { 00227 return _handledEvents; 00228 } 00229 00230 bool Widget::intersects(Widget *w) 00231 { 00232 return _outer.intersects(w->_outer); 00233 } 00234 00235 void Widget::dirty() 00236 { 00237 if(!_dirtying) { 00238 _dirtying = true; 00239 _dirty(); 00240 _dirtying = false; 00241 } 00242 } 00243 00244 bool Widget::isDirty() { 00245 return _dirtied; 00246 } 00247 00248 void Widget::dirtyAll() 00249 { 00250 _dirtied = true; 00251 } 00252 00253 void Widget::damage() { 00254 if(!_damaging) { 00255 _damaging = true; 00256 _damage(); 00257 _damaging = false; 00258 } 00259 } 00260 00261 bool Widget::isDamaged() { 00262 return _damaged; 00263 } 00264 00265 void Widget::adjust() 00266 { 00267 if(!_adjusting) { 00268 _adjusting = true; 00269 _adjust(); 00270 _adjusting = false; 00271 } 00272 } 00273 00274 GraphicsDisplay* Widget::display() 00275 { 00276 return _context->display(); 00277 } 00278 00279 /********************************************************** 00280 * Protected methods 00281 **********************************************************/ 00282 void Widget::_draw() { 00283 GraphicsDisplay *d = display(); 00284 //_clear(); 00285 // Draw the border 00286 // Top 00287 d->fillrect(_outer.x, _outer.y, _outer.x+_outer.width, _outer.y+_borderWidth, _borderColour); 00288 // Bottom 00289 d->fillrect(_outer.x, _outer.y + _outer.height - _borderWidth, _outer.x + _outer.width, _outer.y+_outer.height, _borderColour); 00290 // Left 00291 d->fillrect(_outer.x, _outer.y, _outer.x+_borderWidth, _outer.y+_outer.height, _borderColour); 00292 // Right 00293 d->fillrect(_outer.x+_outer.width-_borderWidth, _outer.y, _outer.x+_outer.width, _outer.y+_outer.height, _borderColour); 00294 } 00295 00296 void Widget::_clear() { 00297 display()->fillrect(_outer.x, _outer.y, _outer.x+_outer.width, _outer.y+_outer.height, display()->getBackground()); 00298 } 00299 00300 void Widget::_dirty() 00301 { 00302 _dirtied = true; 00303 if(_parent != NULL) { 00304 _parent->dirty(); 00305 } 00306 } 00307 00308 void Widget::_damage() 00309 { 00310 _damaged = true; 00311 if(_parent != NULL) { 00312 _parent->dirty(); 00313 } 00314 } 00315 00316 void Widget::_adjust() { 00317 // Recalculate size of inner Rect 00318 _inner.resize(_outer, _borderWidth + _padding); 00319 }
Generated on Tue Jul 12 2022 22:27:14 by
