// vi:ft=cpp /* * (c) 2010 Alexander Warg * economic rights: Technische Universität Dresden (Germany) * * This file is part of TUD:OS and distributed under the terms of the * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. */ #pragma once #include #include #include #include namespace Mag_server { using namespace Mag_gfx; class View_stack { private: class Dummy_view : public View { public: Dummy_view() : View(Rect(Point(0,0), Area(0,0)), F_ignore) {} void draw(Canvas *, View_stack const *, Mode, bool) const {} }; Canvas *_canvas; View *const _no_stay_top; View *_top; View *const _background; Mode _mode; View *_focused; L4Re::Video::View *_canvas_view; Dummy_view _no_stay_top_v; View *top() const { return _top; } Rect outline(View const *v) const; void draw_frame(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; } 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; } 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), _focused(bg), _canvas_view(canvas_view) { bg->_pn = &_top; insert_before(_no_stay_top, _top); } virtual void refresh_view(View const *v, View const *dst, Rect const &rect) const; /** * Draw whole view stack */ void update_all_views() const { //_place_labels(Rect(Point(), _canvas->size())); refresh_view(0, 0, Rect(Point(), _canvas->size())); } virtual void flush(); Canvas *canvas() const { return _canvas; } Mode mode() const { return _mode; } void toggle_mode(Mode::Mode_flag m, bool update = false) { _mode.toggle(m); if (update) update_all_views(); } void set_mode(Mode m, bool update = false) { _mode = m; if (update) update_all_views(); } virtual void viewport(View *v, Rect const &pos, bool redraw) const; virtual void draw_recursive(View const *v, View const *dst, Rect const &) const; virtual void stack(View *v, View *pivot, bool behind = true); 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 remove(View *v) { if (!v->_pn) return; *v->_pn = v->_n; if (v->_n) v->_n->_pn = v->_pn; v->_pn = 0; } View *focused() const { return _focused; } void set_focused(View *v) { _focused = v; } void forget_focus(View const *v) { if (_focused == v) _focused = 0; } void forget_view(View *v) { assert (v != _no_stay_top); assert (v != _background); forget_focus(v); remove(v); refresh_view(0, 0, outline(v)); } bool on_top(View const *v) const { return _no_stay_top->next() == v; } virtual View *find(Point const &pos) const; virtual ~View_stack() {} }; }