]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/mag/include/server/view_stack
update
[l4.git] / l4 / pkg / mag / include / server / view_stack
index 96a7ce94292e0e8bada9e5f624f3f0cc29e696cc..53cf9dbca82321423bf19d78c2ecac1aa2b98001 100644 (file)
@@ -9,12 +9,14 @@
  */
 #pragma once
 
+#include <l4/cxx/dlist>
 #include <l4/re/video/view>
 
 #include <l4/mag-gfx/canvas>
 #include <l4/mag/server/view>
+#include <l4/cxx/observer>
 
-#include <assert.h>
+#include <cassert>
 
 namespace Mag_server {
 
@@ -30,19 +32,19 @@ private:
     void draw(Canvas *, View_stack const *, Mode) const {}
   };
 
+  Dummy_view _no_stay_top_v;
+
   Canvas *_canvas;
   View *const _no_stay_top;
-  View *_top;
+  cxx::D_list<View> _top;
   View *const _background;
+  View *_focused;
 
   Mode _mode;
 
   L4Re::Video::View *_canvas_view;
-
-
-  Dummy_view _no_stay_top_v;
-
-  View *top() const { return _top; }
+  Font const *_label_font;
+  cxx::Notifier _mode_notifier;
 
   Rect outline(View const *v) const;
 
@@ -50,32 +52,22 @@ private:
   void draw_label(View const *v) const;
 
   void insert_before(View *o, View *p)
-  {
-    o->_n = p;
-    o->_pn = p->_pn;
-    *p->_pn = o;
-    p->_pn = &o->_n;
-  }
+  { o->l_add_before(p); }
 
   void insert_after(View *o, View *p)
-  {
-    o->_n = p->_n;
-    o->_pn = &p->_n;
-    if (p->_n)
-      p->_n->_pn = &o->_n;
-
-    p->_n = o;
-  }
+  { o->l_add_after(p); }
 
 public:
-  explicit View_stack(Canvas *canvas, L4Re::Video::View *canvas_view, View *bg)
-  : _canvas(canvas), _no_stay_top(&_no_stay_top_v),  _top(bg),
-    _background(bg), _canvas_view(canvas_view)
+  explicit View_stack(Canvas *canvas, L4Re::Video::View *canvas_view, View *bg,
+                      Font const *label_font)
+  : _canvas(canvas), _no_stay_top(&_no_stay_top_v),  _top(&_no_stay_top_v),
+    _background(bg), _canvas_view(canvas_view), _label_font(label_font)
   {
-    bg->_pn = &_top;
-    insert_before(_no_stay_top, _top);
+    bg->l_add_after(_no_stay_top);
   }
 
+  View *top() const { return _top.first(); }
+
   virtual
   void refresh_view(View const *v, View const *dst, Rect const &rect) const;
 
@@ -84,8 +76,9 @@ public:
    */
   void update_all_views() const
   {
-    //_place_labels(Rect(Point(), _canvas->size()));
-    refresh_view(0, 0, Rect(Point(), _canvas->size()));
+    Rect r(Point(), _canvas->size());
+    place_labels(r);
+    refresh_view(0, 0, r);
   }
 
   virtual void flush();
@@ -99,6 +92,7 @@ public:
     _mode.toggle(m);
     if (update)
       update_all_views();
+    _mode_notifier.notify();
   }
 
   void set_mode(Mode::Mode_flag m, bool on, bool update = false)
@@ -106,10 +100,18 @@ public:
     _mode.set(m, on);
     if (update)
       update_all_views();
+    _mode_notifier.notify();
   }
 
+  void set_focused(View *v);
+  View *focused() const { return _focused; }
+
   virtual
   void viewport(View *v, Rect const &pos, bool redraw) const;
+
+  void draw_recursive(View const *v, View const *dst, Rect const &,
+                      View const *bg) const;
+
   virtual
   void draw_recursive(View const *v, View const *dst, Rect const &) const;
 
@@ -119,20 +121,10 @@ public:
   void push_top(View *v, bool stay_top = false)
   { stack(v, _no_stay_top, !stay_top); }
 
-  void push_bottom(View *v) { stack(v, _background, false); }
+  void push_bottom(View *v);
 
   void remove(View *v)
-  {
-    if (!v->_pn)
-      return;
-
-    *v->_pn = v->_n;
-    if (v->_n)
-      v->_n->_pn = v->_pn;
-
-    v->_pn = 0;
-  }
-
+  { v->l_remove(); }
 
   void forget_view(View *v)
   {
@@ -143,13 +135,39 @@ public:
   }
 
   bool on_top(View const *v) const
-  { return _no_stay_top->next() == v; }
+  { return _top.next(_no_stay_top) == v; }
+
+  View *next_view(View *c) const { return _top.next(c); }
+
+  void add_mode_observer(cxx::Observer *o) { _mode_notifier.add(o); }
 
   virtual
   View *find(Point const &pos) const;
 
   virtual ~View_stack() {}
 
+private:
+  View *current_background() const
+  {
+    Session *current_session = focused() ? focused()->session() : 0;
+    return current_session ? current_session->background() : 0;
+  }
+
+  View const *next_view(View const*, View const *bg) const;
+  View *next_view(View *v, View const *bg) const
+  { return const_cast<View*>(next_view(const_cast<View const *>(v), bg)); }
+
+  void optimize_label_rec(View *cv, View *lv, Rect const &rect, Rect *optimal,
+                          View *bg) const;
+  void do_place_labels(Rect const &rect) const;
+
+  void place_labels(Rect const &rect) const
+  {
+    if (_mode.flat())
+      return;
+
+    do_place_labels(rect);
+  }
 };
 
 }