nitpicker: Support for opaque views in X-ray mode

A session can be explicitly configured to present its views in a
completely opaque way when the X-ray mode is active as opposed to the
default where each view gets tinted and surrounded by a frame. This
is useful for decorator views, which look overly busy otherwise.
This commit is contained in:
Norman Feske 2014-06-19 12:42:24 +02:00
parent 2575fc0ade
commit 65e283142a
4 changed files with 83 additions and 18 deletions

View File

@ -28,16 +28,26 @@ class Domain_registry
typedef Genode::String<64> Name;
typedef Genode::Color Color;
/**
* Behaviour of the views of the domain when X-ray is activated
*/
enum Xray {
XRAY_NO, /* views are not subjected to X-ray mode */
XRAY_FRAME, /* views are tinted and framed */
XRAY_OPAQUE, /* views are replaced by opaque domain color */
};
private:
Name _name;
Color _color;
Xray _xray;
friend class Domain_registry;
Entry(Name const &name, Color color)
Entry(Name const &name, Color color, Xray xray)
:
_name(name), _color(color)
_name(name), _color(color), _xray(xray)
{ }
public:
@ -45,8 +55,30 @@ class Domain_registry
bool has_name(Name const &name) const { return name == _name; }
Color color() const { return _color; }
bool xray_opaque() const { return _xray == XRAY_OPAQUE; }
bool xray_no() const { return _xray == XRAY_NO; }
};
static Entry::Xray _xray(Genode::Xml_node domain)
{
char const * const attr_name = "xray";
Entry::Xray const default_xray = Entry::XRAY_FRAME;
if (!domain.has_attribute(attr_name))
return default_xray;
Genode::Xml_node::Attribute const attr = domain.attribute(attr_name);
if (attr.has_value("no")) return Entry::XRAY_NO;
if (attr.has_value("frame")) return Entry::XRAY_FRAME;
if (attr.has_value("opaque")) return Entry::XRAY_OPAQUE;
PWRN("invalid value of xray attribute");
return default_xray;
}
void _insert(Genode::Xml_node domain)
{
char buf[sizeof(Entry::Name)];
@ -69,9 +101,9 @@ class Domain_registry
return;
}
Entry::Color const color = domain.attribute_value("color", Entry::Color());
Entry::Color const color = domain.attribute_value("color", WHITE);
_entries.insert(new (_alloc) Entry(name, color));
_entries.insert(new (_alloc) Entry(name, color, _xray(domain)));
}
private:

View File

@ -66,6 +66,9 @@ class Session : public Session_list::Element
Genode::Session_label const &label() const { return _label; }
bool xray_opaque() const { return _domain ? _domain->xray_opaque() : false; }
bool xray_no() const { return _domain ? _domain->xray_no() : false; }
Texture_base const *texture() const { return _texture; }
void texture(Texture_base const *texture, bool uses_alpha)

View File

@ -73,22 +73,44 @@ void View::frame(Canvas_base &canvas, Mode const &mode) const
/* do not draw frame in flat mode */
if (mode.flat()) return;
draw_frame(canvas, abs_geometry(), _session.color(), frame_size(mode));
Rect const geometry = abs_geometry();
if (_session.xray_no())
return;
if (_session.xray_opaque()) {
Point frame_offset(frame_size(mode), frame_size(mode));
Rect rect(geometry.p1() - frame_offset, geometry.p2() + frame_offset);
canvas.draw_box(rect, _session.color());
return;
}
draw_frame(canvas, geometry, _session.color(), frame_size(mode));
}
void View::draw(Canvas_base &canvas, Mode const &mode) const
/**
* Return texture painter mode depending on nitpicker state and session policy
*/
static Texture_painter::Mode
texture_painter_mode(Mode const &mode, Session const &session)
{
bool const is_focused = _session.has_same_domain(mode.focused_session());
Color const frame_color = _session.color();
bool const is_focused = session.has_same_domain(mode.focused_session());
/*
* Use dimming in x-ray and kill mode, but do not dim the focused view in
* x-ray mode.
*/
Texture_painter::Mode const op = mode.flat() || (mode.xray() && is_focused)
? Texture_painter::SOLID : Texture_painter::MIXED;
if (mode.flat() || (session.xray_no()) || (mode.xray() && is_focused))
return Texture_painter::SOLID;
return Texture_painter::MIXED;
}
void View::draw(Canvas_base &canvas, Mode const &mode) const
{
Texture_painter::Mode const op = texture_painter_mode(mode, _session);
Rect const view_rect = abs_geometry();
@ -113,9 +135,8 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const
}
}
/* allow alpha blending only in flat mode */
bool allow_alpha = mode.flat();
bool allow_alpha = mode.flat() || _session.xray_no();
/* draw view content */
Color const mix_color = mode.kill() ? KILL_COLOR
@ -123,16 +144,22 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const
_session.color().g >> 1,
_session.color().b >> 1);
if (_session.texture()) {
canvas.draw_texture(_buffer_off + view_rect.p1(), *_session.texture(),
op, mix_color, allow_alpha);
if (mode.xray() && _session.xray_opaque()) {
canvas.draw_box(view_rect, _session.color());
} else {
canvas.draw_box(view_rect, BLACK);
if (_session.texture()) {
canvas.draw_texture(_buffer_off + view_rect.p1(), *_session.texture(),
op, mix_color, allow_alpha);
} else {
canvas.draw_box(view_rect, BLACK);
}
}
if (mode.flat()) return;
if (mode.flat() || _session.xray_opaque() || _session.xray_no()) return;
/* draw label */
Color const frame_color = _session.color();
draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE,
_title, frame_color);
}

View File

@ -164,6 +164,9 @@ class View : public Same_buffer_list_elem,
*/
virtual int frame_size(Mode const &mode) const
{
if (_session.xray_opaque()) return 1;
if (_session.xray_no()) return 0;
return mode.is_focused(_session) ? 5 : 3;
}