3 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
12 #include <l4/scout-gfx/event>
13 #include <l4/scout-gfx/layout_item>
14 #include <l4/scout-gfx/layout>
16 #include <l4/mag-gfx/gfx_colors>
24 using Mag_gfx::Canvas;
28 class Widget : public Layout_item
33 Parent_widget *_parent;
37 int mfocus : 1; ///< Widget has mouse focus
38 int selected : 1; ///< Widget is currently selected
39 int takes_focus : 1; ///< Widget highlights mouse focus
40 int findable : 1; ///< Regard element in find function
41 int visible : 1; ///< Widget is visible
48 : _pos(0, 0), _size(1, 0), _parent(0), _evh(0), next(0)
58 Area size() const { return _size; }
59 Point pos() const { return _pos; }
60 Rect geometry() const { return Rect(_pos, _size); }
61 void set_geometry(Rect const &g)
67 inline Point map_to_parent(Point const &po, Widget *p = 0) const;
69 Point map_from_parent(Point const &po, Widget *p = 0) const
70 { return po - map_to_parent(Point(0, 0), p); }
73 void findable(int flag) { _flags.findable = flag; }
74 bool findable() const { return _flags.findable; }
76 void visible(bool flag) { _flags.visible = flag; }
77 bool visible() const { return _flags.visible; }
79 virtual void draw(Canvas *c, Point const &p) = 0;
80 virtual Widget *find(Point const &p);
81 //virtual Widget *find_child(Point const &p);
82 virtual void fill_cache(Mag_gfx::Pixel_info const *) {}
83 virtual void flush_cache(Mag_gfx::Pixel_info const *) {}
85 void parent(Parent_widget *parent) { _parent = parent; }
86 Parent_widget *parent() const { return _parent; }
89 * Define event handler object
91 void event_handler(Event_handler *evh) { _evh = evh; }
94 * Check if element is completely clipped and draw it otherwise
96 void try_draw(Canvas *c, Point const &p)
101 /* check if element is completely outside the clipping area */
102 if (!(c->clip() & Rect(p + _pos, _size)).valid())
105 /* call actual drawing function */
110 * Update area of an element on screen
112 * We propagate the redraw request through the element hierarchy to
113 * the parent. The root parent should overwrite this function with
114 * a function that performs the actual redraw.
116 virtual void redraw_area(Rect const &r) const;
119 * Trigger the refresh of an element on screen
122 { redraw_area(Rect(_size)); }
124 virtual void mfocus(int flag)
126 if ((_flags.mfocus == flag) || !_flags.takes_focus)
129 _flags.mfocus = flag;
133 * Handle user input or timer event
135 virtual Widget *handle_event(Event const &ev)
137 if (_evh && _evh->handle(ev))
143 class Parent_widget : public Widget
150 Layout *_child_layout;
154 Parent_widget() : Widget(), _first(0), _last(0), _child_layout(0) {}
156 Layout *child_layout() const { return _child_layout; }
158 * Adopt a child element
160 virtual void append(Widget *e);
163 * Release child element from parent element
165 virtual void remove(Widget *e);
168 * Dispose references to the specified element
170 * The element is not necessarily an immediate child but some element
171 * of the element-subtree. This function gets propagated to the root
172 * parent (e.g., user state manager), which can reset the mouse focus
173 * of the focused element vanishes.
175 virtual void forget(Widget *e);
177 void set_child_layout(Layout *l)
181 l->set_parent_layout_item(this);
184 Area preferred_size() const
186 return child_layout() ? child_layout()->preferred_size() : Area(0, 0);
189 Area min_size() const
191 return child_layout() ? child_layout()->min_size() : Area(0, 0);
194 Area max_size() const
196 return child_layout() ? child_layout()->max_size() : Area(Area::Max_w, Area::Max_h);
199 Orientations expanding() const
201 return child_layout() ? child_layout()->expanding() : 0;
206 return child_layout() ? child_layout()->empty() : true;
209 void set_geometry(Rect const &r)
212 child_layout()->set_geometry(Rect(r.area()));
215 _size = min_size().max(r.area()).min(max_size());
218 Rect geometry() const { return Rect(_pos, _size); }
220 void child_invalidate()
223 bool has_height_for_width() const
224 { return child_layout() ? child_layout()->has_height_for_width() : false; }
226 int height_for_width(int w) const
227 { return child_layout() ? child_layout()->height_for_width(w) : -1; }
229 int min_height_for_width(int w) const
230 { return child_layout() ? child_layout()->min_height_for_width(w) : -1; }
233 void draw(Canvas *c, Point const &p);
234 Widget *find(Point const &p);
235 virtual Widget *find_child(Point const &p);
240 Widget::map_to_parent(Point const &po, Widget *p) const
242 if (p == _parent || !_parent)
245 return _parent->map_to_parent(po + _pos, p);