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; /* element has mouse focus */
38 int selected : 1; /* element has selected state */
39 int takes_focus : 1; /* element highlights mouse focus */
40 int findable : 1; /* regard element in find function */
47 : _pos(0, 0), _size(1, 0), _parent(0), _evh(0), next(0)
56 Area size() const { return _size; }
57 Point pos() const { return _pos; }
58 Rect geometry() const { return Rect(_pos, _size); }
59 void set_geometry(Rect const &g)
65 inline Point map_to_parent(Point const &po, Widget *p = 0) const;
67 Point map_from_parent(Point const &po, Widget *p = 0) const
68 { return po - map_to_parent(Point(0, 0), p); }
71 void findable(int flag) { _flags.findable = flag; }
72 bool findable() { return _flags.findable; }
74 virtual void draw(Canvas *c, Point const &p) = 0;
75 virtual Widget *find(Point const &p);
76 //virtual Widget *find_child(Point const &p);
77 virtual void fill_cache(Mag_gfx::Pixel_info const *) {}
78 virtual void flush_cache(Mag_gfx::Pixel_info const *) {}
80 void parent(Parent_widget *parent) { _parent = parent; }
81 Parent_widget *parent() const { return _parent; }
84 * Define event handler object
86 void event_handler(Event_handler *evh) { _evh = evh; }
89 * Check if element is completely clipped and draw it otherwise
91 void try_draw(Canvas *c, Point const &p)
94 /* check if element is completely outside the clipping area */
95 if (!(c->clip() & Rect(p + _pos, _size)).valid())
98 /* call actual drawing function */
103 * Update area of an element on screen
105 * We propagate the redraw request through the element hierarchy to
106 * the parent. The root parent should overwrite this function with
107 * a function that performs the actual redraw.
109 virtual void redraw_area(Rect const &r) const;
112 * Trigger the refresh of an element on screen
115 { redraw_area(Rect(_size)); }
117 virtual void mfocus(int flag)
119 if ((_flags.mfocus == flag) || !_flags.takes_focus)
122 _flags.mfocus = flag;
126 * Handle user input or timer event
128 virtual Widget *handle_event(Event const &ev)
130 if (_evh && _evh->handle(ev))
136 class Parent_widget : public Widget
143 Layout *_child_layout;
147 Parent_widget() : Widget(), _first(0), _last(0), _child_layout(0) {}
149 Layout *child_layout() const { return _child_layout; }
151 * Adopt a child element
153 virtual void append(Widget *e);
156 * Release child element from parent element
158 virtual void remove(Widget *e);
161 * Dispose references to the specified element
163 * The element is not necessarily an immediate child but some element
164 * of the element-subtree. This function gets propagated to the root
165 * parent (e.g., user state manager), which can reset the mouse focus
166 * of the focused element vanishes.
168 virtual void forget(Widget *e);
170 void set_child_layout(Layout *l)
174 l->set_parent_layout_item(this);
177 Area preferred_size() const
179 return child_layout() ? child_layout()->preferred_size() : Area(0, 0);
182 Area min_size() const
184 return child_layout() ? child_layout()->min_size() : Area(0, 0);
187 Area max_size() const
189 return child_layout() ? child_layout()->max_size() : Area(Area::Max_w, Area::Max_h);
192 Orientations expanding() const
194 return child_layout() ? child_layout()->expanding() : 0;
199 return child_layout() ? child_layout()->empty() : true;
202 void set_geometry(Rect const &r)
205 child_layout()->set_geometry(Rect(r.area()));
208 _size = min_size().max(r.area()).min(max_size());
211 Rect geometry() const { return Rect(_pos, _size); }
213 void child_invalidate()
216 bool has_height_for_width() const
217 { return child_layout() ? child_layout()->has_height_for_width() : false; }
219 int height_for_width(int w) const
220 { return child_layout() ? child_layout()->height_for_width(w) : -1; }
222 int min_height_for_width(int w) const
223 { return child_layout() ? child_layout()->min_height_for_width(w) : -1; }
226 void draw(Canvas *c, Point const &p);
227 Widget *find(Point const &p);
228 virtual Widget *find_child(Point const &p);
233 Widget::map_to_parent(Point const &po, Widget *p) const
235 if (p == _parent || !_parent)
238 return _parent->map_to_parent(po + _pos, p);