2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Nitpicker view stack
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2006-08-08
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _VIEW_STACK_H_
|
|
|
|
#define _VIEW_STACK_H_
|
|
|
|
|
|
|
|
#include "view.h"
|
2013-12-28 21:29:30 +00:00
|
|
|
#include "canvas.h"
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
class Session;
|
|
|
|
|
|
|
|
class View_stack
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2014-02-11 14:11:31 +00:00
|
|
|
Area _size;
|
2013-09-07 11:16:25 +00:00
|
|
|
Mode &_mode;
|
|
|
|
Genode::List<View_stack_elem> _views;
|
|
|
|
View *_default_background;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return outline geometry of a view
|
|
|
|
*
|
|
|
|
* This geometry depends on the view geometry and the currently
|
|
|
|
* active Nitpicker mode. In non-flat modes, we incorporate the
|
|
|
|
* surrounding frame.
|
|
|
|
*/
|
2013-12-28 21:29:30 +00:00
|
|
|
Rect _outline(View const &view) const;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return top-most view of the view stack
|
|
|
|
*/
|
|
|
|
View *_first_view() { return static_cast<View *>(_views.first()); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find position in view stack for inserting a view
|
|
|
|
*/
|
2013-09-07 00:02:26 +00:00
|
|
|
View const *_target_stack_position(View const *neighbor, bool behind);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Find best visible label position
|
|
|
|
*/
|
2013-09-07 00:02:26 +00:00
|
|
|
void _optimize_label_rec(View const *cv, View const *lv, Rect rect, Rect *optimal);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Position labels that are affected by specified area
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void _place_labels(Canvas_base &, Rect);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return view following the specified view in the view stack
|
2013-09-07 00:02:26 +00:00
|
|
|
*
|
|
|
|
* The function is a template to capture both const and non-const
|
|
|
|
* usage.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2013-09-07 00:02:26 +00:00
|
|
|
template <typename VIEW>
|
|
|
|
VIEW *_next_view(VIEW *view) const;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
View_stack(Area size, Mode &mode) :
|
|
|
|
_size(size), _mode(mode), _default_background(0) { }
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return size
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
Area size() const { return _size; }
|
|
|
|
|
|
|
|
void size(Area size) { _size = size; }
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Draw views in specified area (recursivly)
|
|
|
|
*
|
|
|
|
* \param view current view in view stack
|
|
|
|
* \param dst_view desired view to draw or NULL
|
|
|
|
* if all views should be drawn
|
|
|
|
* \param exclude do not draw views of this session
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void draw_rec(Canvas_base &, View const *view, View const *dst_view, Session const *exclude, Rect) const;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Draw whole view stack
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void update_all_views(Canvas_base &canvas)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2014-02-11 14:11:31 +00:00
|
|
|
_place_labels(canvas, Rect(Point(), _size));
|
|
|
|
draw_rec(canvas, _first_view(), 0, 0, Rect(Point(), _size));
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update all views belonging to the specified session
|
|
|
|
*
|
2013-09-07 00:02:26 +00:00
|
|
|
* \param Session Session that created the view
|
|
|
|
* \param Rect Buffer area to update
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* Note: For now, we perform an independent view-stack traversal
|
|
|
|
* for each view when calling 'refresh_view'. This becomes
|
|
|
|
* a potentially high overhead with many views. Having
|
|
|
|
* a tailored 'draw_rec_session' function would overcome
|
|
|
|
* this problem.
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void update_session_views(Canvas_base &canvas, Session const &session, Rect rect)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2013-09-07 00:02:26 +00:00
|
|
|
for (View const *view = _first_view(); view; view = view->view_stack_next()) {
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2013-09-07 00:02:26 +00:00
|
|
|
if (!view->belongs_to(session))
|
2011-12-22 15:19:25 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine view portion that displays the buffer portion
|
|
|
|
* specified by 'rect'.
|
|
|
|
*/
|
|
|
|
Point offset = view->p1() + view->buffer_off();
|
|
|
|
Rect r = Rect::intersect(Rect(rect.p1() + offset,
|
|
|
|
rect.p2() + offset), *view);
|
2014-02-11 14:11:31 +00:00
|
|
|
refresh_view(canvas, *view, view, r);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Refresh area within a view
|
|
|
|
*
|
|
|
|
* \param view view that should be updated on screen
|
|
|
|
* \param dst NULL if all views in the specified area should be
|
|
|
|
* refreshed or 'view' if the refresh should be limited to
|
|
|
|
* the specified view.
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void refresh_view(Canvas_base &, View const &view, View const *dst, Rect);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Define position and viewport
|
|
|
|
*
|
|
|
|
* \param pos position of view on screen
|
|
|
|
* \param buffer_off view offset of displayed buffer
|
|
|
|
* \param do_redraw perform screen update immediately
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void viewport(Canvas_base &, View &view, Rect pos, Point buffer_off, bool do_redraw);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert view at specified position in view stack
|
|
|
|
*
|
|
|
|
* \param behind insert view in front (true) or
|
|
|
|
* behind (false) the specified neighbor
|
|
|
|
*
|
|
|
|
* To insert a view at the top of the view stack, specify
|
|
|
|
* neighbor = 0 and behind = true. To insert a view at the
|
|
|
|
* bottom of the view stack, specify neighbor = 0 and
|
|
|
|
* behind = false.
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void stack(Canvas_base &, View const &view, View const *neighbor = 0,
|
2013-09-07 00:02:26 +00:00
|
|
|
bool behind = true, bool do_redraw = true);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set view title
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void title(Canvas_base &, View &view, char const *title);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Find view at specified position
|
|
|
|
*/
|
|
|
|
View *find_view(Point);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove view from view stack
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void remove_view(Canvas_base &, View const &, bool redraw = true);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Define default background
|
|
|
|
*/
|
2013-09-07 00:02:26 +00:00
|
|
|
void default_background(View &view) { _default_background = &view; }
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if view is the default background
|
|
|
|
*/
|
2013-09-07 00:02:26 +00:00
|
|
|
bool is_default_background(View const *view) const { return view == _default_background; }
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove all views of specified session from view stack
|
|
|
|
*
|
|
|
|
* Rather than removing the views from the view stack, this function moves
|
|
|
|
* the session views out of the visible screen area.
|
|
|
|
*/
|
2014-02-11 14:11:31 +00:00
|
|
|
void lock_out_session(Canvas_base &canvas, Session const &session)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2013-09-07 00:02:26 +00:00
|
|
|
View const *view = _first_view(), *next_view = view->view_stack_next();
|
2011-12-22 15:19:25 +00:00
|
|
|
while (view) {
|
2014-02-11 14:11:31 +00:00
|
|
|
if (view->belongs_to(session)) remove_view(canvas, *view);
|
2011-12-22 15:19:25 +00:00
|
|
|
view = next_view;
|
|
|
|
next_view = view ? view->view_stack_next() : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|