*/
#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 {
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;
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;
*/
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();
_mode.toggle(m);
if (update)
update_all_views();
+ _mode_notifier.notify();
}
void set_mode(Mode::Mode_flag m, bool on, bool update = false)
_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;
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)
{
}
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);
+ }
};
}