mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 11:27:29 +00:00
parent
93605c2b15
commit
1498bb740b
@ -31,8 +31,8 @@ struct Nitpicker::Session_client : public Genode::Rpc_client<Session>
|
||||
Input::Session_capability input_session() {
|
||||
return call<Rpc_input_session>(); }
|
||||
|
||||
View_capability create_view() {
|
||||
return call<Rpc_create_view>(); }
|
||||
View_capability create_view(View_capability parent = View_capability()) {
|
||||
return call<Rpc_create_view>(parent); }
|
||||
|
||||
void destroy_view(View_capability view) {
|
||||
call<Rpc_destroy_view>(view); }
|
||||
|
@ -51,9 +51,16 @@ struct Nitpicker::Session : Genode::Session
|
||||
/**
|
||||
* Create a new view at the buffer
|
||||
*
|
||||
* \param parent parent view
|
||||
*
|
||||
* \return capability to a new view
|
||||
*
|
||||
* The 'parent' argument allows the client to use the location of an
|
||||
* existing view as the coordinate origin for the to-be-created view.
|
||||
* If an invalid capability is specified (default), the view will be a
|
||||
* top-level view.
|
||||
*/
|
||||
virtual View_capability create_view() = 0;
|
||||
virtual View_capability create_view(View_capability parent = View_capability()) = 0;
|
||||
|
||||
/**
|
||||
* Destroy view
|
||||
@ -97,7 +104,7 @@ struct Nitpicker::Session : Genode::Session
|
||||
|
||||
GENODE_RPC(Rpc_framebuffer_session, Framebuffer::Session_capability, framebuffer_session);
|
||||
GENODE_RPC(Rpc_input_session, Input::Session_capability, input_session);
|
||||
GENODE_RPC(Rpc_create_view, View_capability, create_view);
|
||||
GENODE_RPC(Rpc_create_view, View_capability, create_view, View_capability);
|
||||
GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_capability);
|
||||
GENODE_RPC(Rpc_background, int, background, View_capability);
|
||||
GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode);
|
||||
|
@ -225,7 +225,7 @@ namespace Nitpicker {
|
||||
return _proxy_input_cap;
|
||||
}
|
||||
|
||||
View_capability create_view()
|
||||
View_capability create_view(View_capability)
|
||||
{
|
||||
return _proxy_view_cap;
|
||||
}
|
||||
|
@ -31,10 +31,11 @@ struct Background : private Texture_base, Session, View
|
||||
Background(Area size)
|
||||
:
|
||||
Texture_base(Area(0, 0)), Session(Genode::Session_label(""), 0, false),
|
||||
View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT,
|
||||
View::BACKGROUND, Rect(Point(0, 0), size)),
|
||||
View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT, View::BACKGROUND, 0),
|
||||
color(25, 37, 50)
|
||||
{ }
|
||||
{
|
||||
View::geometry(Rect(Point(0, 0), size));
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
@ -53,8 +54,9 @@ struct Background : private Texture_base, Session, View
|
||||
|
||||
void draw(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
canvas.draw_box(*this, color);
|
||||
Rect const view_rect = abs_geometry();
|
||||
Clip_guard clip_guard(canvas, view_rect);
|
||||
canvas.draw_box(view_rect, color);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -37,9 +37,10 @@ class Chunky_menubar : public Texture<PT>,
|
||||
Texture<PT>(pixels, 0, size),
|
||||
Session(Genode::Session_label(""), 0, false),
|
||||
View(*this, View::STAY_TOP, View::NOT_TRANSPARENT,
|
||||
View::NOT_BACKGROUND, Rect(Point(0, 0), size)),
|
||||
View::NOT_BACKGROUND, 0),
|
||||
_canvas(pixels, size)
|
||||
{
|
||||
View::geometry(Rect(Point(0, 0), size));
|
||||
Session::texture(this, false);
|
||||
}
|
||||
|
||||
@ -62,7 +63,7 @@ class Chunky_menubar : public Texture<PT>,
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
|
||||
/* draw menubar content */
|
||||
canvas.draw_texture(p1(), *this, Texture_painter::SOLID, BLACK, false);
|
||||
canvas.draw_texture(abs_position(), *this, Texture_painter::SOLID, BLACK, false);
|
||||
}
|
||||
|
||||
|
||||
@ -79,25 +80,28 @@ class Chunky_menubar : public Texture<PT>,
|
||||
int g = (mode.kill()) ? 70 : (mode.xray()) ? session_color.g : (session_color.g + 100) >> 1;
|
||||
int b = (mode.kill()) ? 70 : (mode.xray()) ? session_color.b : (session_color.b + 100) >> 1;
|
||||
|
||||
Rect const view_rect = abs_geometry();
|
||||
|
||||
/* highlight first line with slightly brighter color */
|
||||
_canvas.draw_box(Rect(Point(0, 0), Area(View::w(), 1)),
|
||||
_canvas.draw_box(Rect(Point(0, 0), Area(view_rect.w(), 1)),
|
||||
Color(r + (r / 2), g + (g / 2), b + (b / 2)));
|
||||
|
||||
/* draw slightly shaded background */
|
||||
for (unsigned i = 1; i < View::h() - 1; i++) {
|
||||
for (unsigned i = 1; i < view_rect.h() - 1; i++) {
|
||||
r -= r > 3 ? 4 : 0;
|
||||
g -= g > 3 ? 4 : 0;
|
||||
b -= b > 4 ? 4 : 0;
|
||||
_canvas.draw_box(Rect(Point(0, i), Area(View::w(), 1)), Color(r, g, b));
|
||||
_canvas.draw_box(Rect(Point(0, i), Area(view_rect.w(), 1)), Color(r, g, b));
|
||||
}
|
||||
|
||||
/* draw last line darker */
|
||||
_canvas.draw_box(Rect(Point(0, View::h() - 1), Area(View::w(), 1)),
|
||||
_canvas.draw_box(Rect(Point(0, view_rect.h() - 1), Area(view_rect.w(), 1)),
|
||||
Color(r / 4, g / 4, b / 4));
|
||||
|
||||
/* draw label */
|
||||
draw_label(_canvas, center(label_size(session_label.string(), view_title.string())),
|
||||
session_label.string(), WHITE, view_title.string(), session_color);
|
||||
draw_label(_canvas, view_rect.center(label_size(session_label.string(),
|
||||
view_title.string())), session_label.string(),
|
||||
WHITE, view_title.string(), session_color);
|
||||
}
|
||||
|
||||
using Menubar::state;
|
||||
|
@ -418,11 +418,11 @@ class View_component : public Genode::List<View_component>::Element,
|
||||
*/
|
||||
View_component(::Session &session, View_stack &view_stack,
|
||||
Canvas_accessor &canvas_accessor,
|
||||
Rpc_entrypoint &ep):
|
||||
Rpc_entrypoint &ep, ::View *parent_view):
|
||||
_view_stack(view_stack),
|
||||
_view(session,
|
||||
session.stay_top() ? ::View::STAY_TOP : ::View::NOT_STAY_TOP,
|
||||
::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, Rect()),
|
||||
::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, parent_view),
|
||||
_canvas_accessor(canvas_accessor),
|
||||
_ep(ep)
|
||||
{ }
|
||||
@ -437,8 +437,9 @@ class View_component : public Genode::List<View_component>::Element,
|
||||
int viewport(int x, int y, int w, int h,
|
||||
int buf_x, int buf_y, bool redraw)
|
||||
{
|
||||
/* transpose y position by vertical session offset */
|
||||
y += _view.session().v_offset();
|
||||
/* transpose y position of top-level views by vertical session offset */
|
||||
if (_view.top_level())
|
||||
y += _view.session().v_offset();
|
||||
|
||||
_view_stack.viewport(_canvas(), _view,
|
||||
Rect(Point(x, y), Area(w, h)),
|
||||
@ -605,15 +606,25 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
Input::Session_capability input_session() {
|
||||
return _input_session_cap; }
|
||||
|
||||
View_capability create_view()
|
||||
View_capability create_view(View_capability parent_cap)
|
||||
{
|
||||
/**
|
||||
/* lookup parent view */
|
||||
View_component *parent_view =
|
||||
dynamic_cast<View_component *>(_ep.lookup_and_lock(parent_cap));
|
||||
|
||||
/*
|
||||
* FIXME: Do not allocate View meta data from Heap!
|
||||
* Use a heap partition!
|
||||
*/
|
||||
View_component *view = new (env()->heap())
|
||||
View_component(*this, _view_stack,
|
||||
_canvas_accessor, _ep);
|
||||
View_component(*this, _view_stack, _canvas_accessor, _ep,
|
||||
parent_view ? &parent_view->view() : 0);
|
||||
|
||||
if (parent_view)
|
||||
parent_view->view().add_child(&view->view());
|
||||
|
||||
if (parent_view)
|
||||
parent_view->release();
|
||||
|
||||
_view_list.insert(view);
|
||||
return _ep.manage(view);
|
||||
|
@ -39,8 +39,7 @@ class Mouse_cursor : public Texture<PT>,
|
||||
:
|
||||
Texture<PT>(pixels, 0, size),
|
||||
Session(Genode::Session_label(""), 0, false),
|
||||
View(*this, View::STAY_TOP, View::TRANSPARENT, View::NOT_BACKGROUND,
|
||||
Rect()),
|
||||
View(*this, View::STAY_TOP, View::TRANSPARENT, View::NOT_BACKGROUND, 0),
|
||||
_view_stack(view_stack)
|
||||
{ }
|
||||
|
||||
@ -66,13 +65,15 @@ class Mouse_cursor : public Texture<PT>,
|
||||
|
||||
void draw(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
Rect const view_rect = abs_geometry();
|
||||
|
||||
Clip_guard clip_guard(canvas, view_rect);
|
||||
|
||||
/* draw area behind the mouse cursor */
|
||||
_view_stack.draw_rec(canvas, view_stack_next(), 0, 0, *this);
|
||||
_view_stack.draw_rec(canvas, view_stack_next(), 0, 0, view_rect);
|
||||
|
||||
/* draw mouse cursor */
|
||||
canvas.draw_texture(p1(), *this, Texture_painter::MASKED, BLACK, true);
|
||||
canvas.draw_texture(view_rect.p1(), *this, Texture_painter::MASKED, BLACK, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -73,7 +73,7 @@ void View::frame(Canvas_base &canvas, Mode const &mode) const
|
||||
/* do not draw frame in flat mode */
|
||||
if (mode.flat()) return;
|
||||
|
||||
draw_frame(canvas, *this, _session.color(), frame_size(mode));
|
||||
draw_frame(canvas, abs_geometry(), _session.color(), frame_size(mode));
|
||||
}
|
||||
|
||||
|
||||
@ -92,13 +92,15 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const
|
||||
Texture_painter::Mode const op = mode.flat() || (mode.xray() && view_is_focused)
|
||||
? Texture_painter::SOLID : Texture_painter::MIXED;
|
||||
|
||||
Rect const view_rect = abs_geometry();
|
||||
|
||||
/*
|
||||
* The view content and label should never overdraw the
|
||||
* frame of the view in non-flat Nitpicker modes. The frame
|
||||
* is located outside the view area. By shrinking the
|
||||
* clipping area to the view area, we protect the frame.
|
||||
*/
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
Clip_guard clip_guard(canvas, view_rect);
|
||||
|
||||
/*
|
||||
* If the clipping area shrinked to zero, we do not process drawing
|
||||
@ -116,8 +118,8 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const
|
||||
_session.color().b >> 1);
|
||||
|
||||
if (_session.texture())
|
||||
canvas.draw_texture(_buffer_off + p1(), *_session.texture(), op,
|
||||
mix_color, allow_alpha);
|
||||
canvas.draw_texture(_buffer_off + view_rect.p1(), *_session.texture(),
|
||||
op, mix_color, allow_alpha);
|
||||
|
||||
if (mode.flat()) return;
|
||||
|
||||
|
@ -33,9 +33,15 @@ struct Same_buffer_list_elem : Genode::List<Same_buffer_list_elem>::Element { };
|
||||
struct View_stack_elem : Genode::List<View_stack_elem>::Element { };
|
||||
|
||||
|
||||
/*
|
||||
* If a view has a parent, it is a list element of its parent view
|
||||
*/
|
||||
struct View_parent_elem : Genode::List<View_parent_elem>::Element { };
|
||||
|
||||
|
||||
class View : public Same_buffer_list_elem,
|
||||
public View_stack_elem,
|
||||
public Rect
|
||||
public View_parent_elem
|
||||
{
|
||||
public:
|
||||
|
||||
@ -51,21 +57,76 @@ class View : public Same_buffer_list_elem,
|
||||
Transparent const _transparent; /* background is partly visible */
|
||||
Background _background; /* view is a background view */
|
||||
|
||||
Rect _label_rect; /* position and size of label */
|
||||
Point _buffer_off; /* offset to the visible buffer area */
|
||||
Session &_session; /* session that created the view */
|
||||
View *_parent; /* parent view */
|
||||
Rect _geometry; /* position and size relative to parent */
|
||||
Rect _label_rect; /* position and size of label */
|
||||
Point _buffer_off; /* offset to the visible buffer area */
|
||||
Session &_session; /* session that created the view */
|
||||
char _title[TITLE_LEN];
|
||||
|
||||
Genode::List<View_parent_elem> _children;
|
||||
|
||||
public:
|
||||
|
||||
View(Session &session, Stay_top stay_top, Transparent transparent,
|
||||
Background background, Rect rect)
|
||||
Background bg, View *parent)
|
||||
:
|
||||
Rect(rect), _stay_top(stay_top), _transparent(transparent),
|
||||
_background(background), _session(session)
|
||||
_stay_top(stay_top), _transparent(transparent), _background(bg),
|
||||
_parent(parent), _session(session)
|
||||
{ title(""); }
|
||||
|
||||
virtual ~View() { }
|
||||
virtual ~View()
|
||||
{
|
||||
/* break link to our parent */
|
||||
if (_parent)
|
||||
_parent->remove_child(this);
|
||||
|
||||
/* break links to our children */
|
||||
while (View_parent_elem *e = _children.first())
|
||||
static_cast<View *>(e)->dissolve_from_parent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute view position
|
||||
*/
|
||||
Point abs_position() const
|
||||
{
|
||||
return _parent ? _geometry.p1() + _parent->abs_position()
|
||||
: _geometry.p1();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute view geometry
|
||||
*/
|
||||
Rect abs_geometry() const
|
||||
{
|
||||
return Rect(abs_position(), _geometry.area());
|
||||
}
|
||||
|
||||
/**
|
||||
* Break the relationship of a child view from its parent
|
||||
*
|
||||
* This function is called when a parent view gets destroyed.
|
||||
*/
|
||||
void dissolve_from_parent()
|
||||
{
|
||||
_parent = 0;
|
||||
_geometry = Rect();
|
||||
}
|
||||
|
||||
Rect geometry() const { return _geometry; }
|
||||
|
||||
void geometry(Rect geometry) { _geometry = geometry; }
|
||||
|
||||
void add_child(View const *child) { _children.insert(child); }
|
||||
|
||||
void remove_child(View const *child) { _children.remove(child); }
|
||||
|
||||
template <typename FN>
|
||||
void for_each_child(FN const &fn) const {
|
||||
for (View_parent_elem const *e = _children.first(); e; e = e->next())
|
||||
fn(*static_cast<View const *>(e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return thickness of frame that surrounds the view
|
||||
@ -119,12 +180,13 @@ class View : public Same_buffer_list_elem,
|
||||
bool belongs_to(Session const &session) const { return &session == &_session; }
|
||||
bool same_session_as(View const &other) const { return &_session == &other._session; }
|
||||
|
||||
bool stay_top() const { return _stay_top; }
|
||||
bool transparent() const { return _transparent || _session.uses_alpha(); }
|
||||
bool background() const { return _background; }
|
||||
Rect label_rect() const { return _label_rect; }
|
||||
bool uses_alpha() const { return _session.uses_alpha(); }
|
||||
Point buffer_off() const { return _buffer_off; }
|
||||
bool top_level() const { return _parent == 0; }
|
||||
bool stay_top() const { return _stay_top; }
|
||||
bool transparent() const { return _transparent || _session.uses_alpha(); }
|
||||
bool background() const { return _background; }
|
||||
Rect label_rect() const { return _label_rect; }
|
||||
bool uses_alpha() const { return _session.uses_alpha(); }
|
||||
Point buffer_off() const { return _buffer_off; }
|
||||
|
||||
char const *title() const { return _title; }
|
||||
|
||||
@ -137,14 +199,16 @@ class View : public Same_buffer_list_elem,
|
||||
*/
|
||||
bool input_response_at(Point p, Mode const &mode) const
|
||||
{
|
||||
Rect const view_rect = abs_geometry();
|
||||
|
||||
/* check if point lies outside view geometry */
|
||||
if ((p.x() < x1()) || (p.x() > x2())
|
||||
|| (p.y() < y1()) || (p.y() > y2()))
|
||||
if ((p.x() < view_rect.x1()) || (p.x() > view_rect.x2())
|
||||
|| (p.y() < view_rect.y1()) || (p.y() > view_rect.y2()))
|
||||
return false;
|
||||
|
||||
/* if view uses an alpha channel, check the input mask */
|
||||
if (mode.flat() && session().uses_alpha())
|
||||
return session().input_mask_at(p - p1() + _buffer_off);
|
||||
return session().input_mask_at(p - view_rect.p1() + _buffer_off);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -65,13 +65,15 @@ VIEW *View_stack::_next_view(VIEW *view) const
|
||||
|
||||
Rect View_stack::_outline(View const &view) const
|
||||
{
|
||||
if (_mode.flat()) return view;
|
||||
Rect const rect = view.abs_geometry();
|
||||
|
||||
if (_mode.flat()) return rect;
|
||||
|
||||
/* request thickness of view frame */
|
||||
int const frame_size = view.frame_size(_mode);
|
||||
|
||||
return Rect(Point(view.x1() - frame_size, view.y1() - frame_size),
|
||||
Point(view.x2() + frame_size, view.y2() + frame_size));
|
||||
return Rect(Point(rect.x1() - frame_size, rect.y1() - frame_size),
|
||||
Point(rect.x2() + frame_size, rect.y2() + frame_size));
|
||||
}
|
||||
|
||||
|
||||
@ -157,13 +159,15 @@ void View_stack::_place_labels(Canvas_base &canvas, Rect rect)
|
||||
View const *start = _next_view(_first_view());
|
||||
View *view = _next_view(_first_view());
|
||||
|
||||
for (; view && _next_view(view); view = _next_view(view))
|
||||
if (Rect::intersect(*view, rect).valid()) {
|
||||
for (; view && _next_view(view); view = _next_view(view)) {
|
||||
|
||||
Rect const view_rect = view->abs_geometry();
|
||||
if (Rect::intersect(view_rect, rect).valid()) {
|
||||
|
||||
Rect old = view->label_rect(), best;
|
||||
|
||||
/* calculate best visible label position */
|
||||
Rect rect = Rect::intersect(Rect(Point(), canvas.size()), *view);
|
||||
Rect rect = Rect::intersect(Rect(Point(), canvas.size()), view_rect);
|
||||
if (start) _optimize_label_rec(start, view, rect, &best);
|
||||
|
||||
/*
|
||||
@ -180,6 +184,7 @@ void View_stack::_place_labels(Canvas_base &canvas, Rect rect)
|
||||
refresh_view(canvas, *view, view, old);
|
||||
refresh_view(canvas, *view, view, view->label_rect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -235,15 +240,17 @@ void View_stack::refresh_view(Canvas_base &canvas, View const &view,
|
||||
}
|
||||
|
||||
|
||||
void View_stack::viewport(Canvas_base &canvas, View &view, Rect pos,
|
||||
void View_stack::viewport(Canvas_base &canvas, View &view, Rect rect,
|
||||
Point buffer_off, bool do_redraw)
|
||||
{
|
||||
Rect old = _outline(view);
|
||||
Rect const old_compound = _compound_outline(view);
|
||||
|
||||
static_cast<Rect &>(view) = Rect(pos);
|
||||
view.geometry(Rect(rect));
|
||||
view.buffer_off(buffer_off);
|
||||
|
||||
Rect compound = Rect::compound(old, _outline(view));
|
||||
Rect const new_compound = _compound_outline(view);
|
||||
|
||||
Rect const compound = Rect::compound(old_compound, new_compound);
|
||||
|
||||
/* update labels (except when moving the mouse cursor) */
|
||||
if (&view != _first_view())
|
||||
@ -263,7 +270,7 @@ void View_stack::stack(Canvas_base &canvas, View const &view,
|
||||
_views.remove(&view);
|
||||
_views.insert(&view, _target_stack_position(neighbor, behind));
|
||||
|
||||
_place_labels(canvas, view);
|
||||
_place_labels(canvas, view.abs_geometry());
|
||||
|
||||
/* refresh affected screen area */
|
||||
refresh_view(canvas, view, 0, _outline(view));
|
||||
@ -273,7 +280,7 @@ void View_stack::stack(Canvas_base &canvas, View const &view,
|
||||
void View_stack::title(Canvas_base &canvas, View &view, const char *title)
|
||||
{
|
||||
view.title(title);
|
||||
_place_labels(canvas, view);
|
||||
_place_labels(canvas, view.abs_geometry());
|
||||
refresh_view(canvas, view, 0, _outline(view));
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,19 @@ class View_stack
|
||||
*/
|
||||
void _place_labels(Canvas_base &, Rect);
|
||||
|
||||
/**
|
||||
* Return compound rectangle covering the view and all of its children
|
||||
*/
|
||||
Rect _compound_outline(View const &view)
|
||||
{
|
||||
Rect rect = _outline(view);
|
||||
|
||||
view.for_each_child([&] (View const &child) {
|
||||
rect = Rect::compound(_outline(child), rect); });
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return view following the specified view in the view stack
|
||||
*
|
||||
@ -123,9 +136,10 @@ class View_stack
|
||||
* 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);
|
||||
Point const offset = view->abs_position() + view->buffer_off();
|
||||
Rect const r = Rect::intersect(Rect(rect.p1() + offset,
|
||||
rect.p2() + offset),
|
||||
view->abs_geometry());
|
||||
refresh_view(canvas, *view, view, r);
|
||||
}
|
||||
}
|
||||
|
@ -29,18 +29,23 @@ class Test_view : public List<Test_view>::Element
|
||||
Nitpicker::View_capability _cap;
|
||||
int _x, _y, _w, _h;
|
||||
const char *_title;
|
||||
Test_view const *_parent_view;
|
||||
|
||||
public:
|
||||
|
||||
Test_view(Nitpicker::Session *nitpicker,
|
||||
int x, int y, int w, int h,
|
||||
const char *title)
|
||||
const char *title,
|
||||
Test_view *parent_view = 0)
|
||||
:
|
||||
_x(x), _y(y), _w(w), _h(h), _title(title)
|
||||
_x(x), _y(y), _w(w), _h(h), _title(title), _parent_view(parent_view)
|
||||
{
|
||||
using namespace Nitpicker;
|
||||
|
||||
_cap = nitpicker->create_view();
|
||||
View_capability parent_cap = parent_view ? parent_view->_cap
|
||||
: View_capability();
|
||||
|
||||
_cap = nitpicker->create_view(parent_cap);
|
||||
View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
|
||||
View_client(_cap).stack(Nitpicker::View_capability(), true, true);
|
||||
View_client(_cap).title(_title);
|
||||
@ -51,21 +56,30 @@ class Test_view : public List<Test_view>::Element
|
||||
Nitpicker::View_client(_cap).stack(Nitpicker::View_capability(), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move view to absolute position
|
||||
*/
|
||||
void move(int x, int y)
|
||||
{
|
||||
_x = x;
|
||||
_y = y;
|
||||
/*
|
||||
* If the view uses a parent view as corrdinate origin, we need to
|
||||
* transform the absolute coordinates to parent-relative
|
||||
* coordinates.
|
||||
*/
|
||||
_x = _parent_view ? x - _parent_view->x() : x;
|
||||
_y = _parent_view ? y - _parent_view->y() : y;
|
||||
|
||||
Nitpicker::View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
const char *title() { return _title; }
|
||||
int x() { return _x; }
|
||||
int y() { return _y; }
|
||||
int w() { return _w; }
|
||||
int h() { return _h; }
|
||||
const char *title() const { return _title; }
|
||||
int x() const { return _parent_view ? _parent_view->x() + _x : _x; }
|
||||
int y() const { return _parent_view ? _parent_view->y() + _y : _y; }
|
||||
int w() const { return _w; }
|
||||
int h() const { return _h; }
|
||||
};
|
||||
|
||||
|
||||
@ -83,6 +97,7 @@ class Test_view_stack : public List<Test_view>
|
||||
Test_view *find(int x, int y)
|
||||
{
|
||||
for (Test_view *tv = first(); tv; tv = tv->next()) {
|
||||
|
||||
if (x < tv->x() || x >= tv->x() + tv->w()
|
||||
|| y < tv->y() || y >= tv->y() + tv->h())
|
||||
continue;
|
||||
@ -151,9 +166,18 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
Test_view_stack tvs(input_mask, scr_w);
|
||||
|
||||
tvs.insert(new (env()->heap()) Test_view(&nitpicker, 150, 100, 230, 200, "Eins"));
|
||||
tvs.insert(new (env()->heap()) Test_view(&nitpicker, 170, 120, 230, 210, "Zwei"));
|
||||
tvs.insert(new (env()->heap()) Test_view(&nitpicker, 190, 140, 230, 220, "Drei"));
|
||||
{
|
||||
/*
|
||||
* View 'v1' is used as coordinate origin of 'v2' and 'v3'.
|
||||
*/
|
||||
static Test_view v1(&nitpicker, 150, 100, 230, 200, "Eins");
|
||||
static Test_view v2(&nitpicker, 20, 20, 230, 210, "Zwei", &v1);
|
||||
static Test_view v3(&nitpicker, 40, 40, 230, 220, "Drei", &v1);
|
||||
|
||||
tvs.insert(&v1);
|
||||
tvs.insert(&v2);
|
||||
tvs.insert(&v3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle input events
|
||||
|
Loading…
x
Reference in New Issue
Block a user