]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/scout-gfx/lib/widget.cc
Inital import
[l4.git] / l4 / pkg / scout-gfx / lib / widget.cc
diff --git a/l4/pkg/scout-gfx/lib/widget.cc b/l4/pkg/scout-gfx/lib/widget.cc
new file mode 100644 (file)
index 0000000..f943c01
--- /dev/null
@@ -0,0 +1,131 @@
+#include <l4/scout-gfx/widget>
+
+namespace Scout_gfx {
+
+Widget::~Widget()
+{
+  if (_parent)
+    _parent->forget(this);
+}
+
+void
+Parent_widget::draw(Canvas *c, Point const &p)
+{
+  for (Widget *e = _first; e; e = e->next)
+    e->try_draw(c, e->pos() + p);
+}
+
+void Parent_widget::append(Widget *e)
+{
+  if (_last)
+    _last->next = e;
+  else
+    _first = e;
+
+  _last = e;
+
+  e->parent(this);
+}
+
+
+void Parent_widget::remove(Widget *e)
+{
+  if (_first == e)
+    {
+      _first = e->next;
+      if (_last == e)
+       _last = 0;
+
+      return;
+    }
+
+  /* search specified element in the list */
+  Widget *ce = _first;
+  for (; ce && ce->next != e; ce = ce->next)
+    ;
+
+  if (!ce)
+    return;
+
+  if (_last == e)
+    _last = ce;
+
+  ce->next = e->next;
+}
+
+
+void Parent_widget::forget(Widget *e)
+{
+  if (e->parent() == this)
+    remove(e);
+
+  _parent->forget(e);
+}
+
+
+
+Widget *
+Parent_widget::find_child(Point const &p)
+{
+  /* check if position is outside the parent element */
+  if (!geometry().contains(p))
+    return 0;
+
+  Point np = p - _pos;
+
+  /* check children */
+  for (Widget *e = _first; e; e = e->next)
+    {
+      if (e->geometry().contains(np) && e->findable())
+       return e;
+    }
+
+  return 0;
+}
+
+Widget *
+Widget::find(Point const &p)
+{
+  if (geometry().contains(p) && _flags.findable)
+    return this;
+
+  return 0;
+}
+
+
+Widget *
+Parent_widget::find(Point const &p)
+{
+  /* check if position is outside the parent element */
+  if (!geometry().contains(p))
+    return 0;
+
+  Point np = p - _pos;
+
+  /* check children */
+  Widget *ret = this;
+  for (Widget *e = _first; e; e = e->next)
+    {
+      Widget *res  = e->find(np);
+      if (res)
+       ret = res;
+    }
+
+  return ret;
+}
+
+void
+Widget::redraw_area(Rect const &r) const
+{
+  /* intersect specified area with element geometry */
+  Rect n = (r & Rect(_size));
+
+  if (!n.valid())
+    return;
+
+  /* propagate redraw request to the parent */
+  if (_parent)
+    _parent->redraw_area(n + _pos);
+}
+
+}