genode/os/src/server/nitpicker/view_stack.h
Norman Feske 35bfc34db5 Move nitpicker_gfx/geometry.h to util/geometry.h
This patch makes nitpicker's geometry utilities available for the use
by other programs. Thereby, the 'Point', 'Area', and 'Rect' classes
have become templates that take the coordinate type and distance type
as arguments.
2014-01-27 18:54:06 +01:00

210 lines
5.4 KiB
C++

/*
* \brief Nitpicker view stack
* \author Norman Feske
* \date 2006-08-08
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* 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"
class Session;
class View_stack
{
private:
typedef Canvas::Point Point;
typedef Canvas::Area Area;
typedef Canvas::Rect Rect;
Canvas &_canvas;
Mode &_mode;
Genode::List<View_stack_elem> _views;
View *_default_background;
/**
* 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.
*/
Canvas::Rect _outline(View const &view) const;
/**
* 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
*/
View const *_target_stack_position(View const *neighbor, bool behind);
/**
* Find best visible label position
*/
void _optimize_label_rec(View const *cv, View const *lv, Rect rect, Rect *optimal);
/**
* Position labels that are affected by specified area
*/
void _place_labels(Rect);
/**
* Return view following the specified view in the view stack
*
* The function is a template to capture both const and non-const
* usage.
*/
template <typename VIEW>
VIEW *_next_view(VIEW *view) const;
public:
/**
* Constructor
*/
View_stack(Canvas &canvas, Mode &mode) :
_canvas(canvas), _mode(mode), _default_background(0) { }
/**
* Return size
*/
Area size() { return _canvas.size(); }
/**
* 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
*/
void draw_rec(View const *view, View const *dst_view, Session const *exclude, Rect) const;
/**
* Draw whole view stack
*/
void update_all_views()
{
_place_labels(Rect(Point(), _canvas.size()));
draw_rec(_first_view(), 0, 0, Rect(Point(), _canvas.size()));
}
/**
* Update all views belonging to the specified session
*
* \param Session Session that created the view
* \param Rect Buffer area to update
*
* 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.
*/
void update_session_views(Session const &session, Rect rect)
{
for (View const *view = _first_view(); view; view = view->view_stack_next()) {
if (!view->belongs_to(session))
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);
refresh_view(*view, view, r);
}
}
/**
* 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.
*/
void refresh_view(View const &view, View const *dst, Rect);
/**
* 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
*/
void viewport(View &view, Rect pos, Point buffer_off, bool do_redraw);
/**
* 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.
*/
void stack(View const &view, View const *neighbor = 0,
bool behind = true, bool do_redraw = true);
/**
* Set view title
*/
void title(View &view, char const *title);
/**
* Find view at specified position
*/
View *find_view(Point);
/**
* Remove view from view stack
*/
void remove_view(View const &);
/**
* Define default background
*/
void default_background(View &view) { _default_background = &view; }
/**
* Return true if view is the default background
*/
bool is_default_background(View const *view) const { return view == _default_background; }
/**
* 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.
*/
void lock_out_session(Session const &session)
{
View const *view = _first_view(), *next_view = view->view_stack_next();
while (view) {
if (view->belongs_to(session)) remove_view(*view);
view = next_view;
next_view = view ? view->view_stack_next() : 0;
}
}
};
#endif