genode/repos/demo/src/app/scout/elements.h

635 lines
12 KiB
C++

/*
* \brief Document structure elements
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* Copyright (C) 2005-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _ELEMENTS_H_
#define _ELEMENTS_H_
#include <scout/parent_element.h>
#include <scout/string.h>
#include <scout/fader.h>
#include <scout/platform.h>
namespace Scout {
class Style;
class Browser;
class Token;
class Link;
class Link_token;
class Launcher_config;
class Launcher;
class Launcher_link_token;
class Block;
class Center;
class Png_image;
class Chapter;
class Document;
class Spacer;
class Verbatim;
class Item;
class Generic_icon;
class Navbar;
/**
* Link anchor
*
* An anchor marks a location within a document that can be addressed by a
* link.
*/
typedef Element Anchor;
}
/**
* Textual style
*
* A style describes the font, color and accentuations of tokens.
*/
class Scout::Style
{
public:
enum {
ATTR_BOLD = 0x1,
};
Font *font;
Color color;
int attr;
Style(Font *f, Color c, int a) : font(f), color(c), attr(a) { }
};
/**
* String token
*
* A Token is a group of characters that are handled as an atomic text unit.
* Line wrapping is performed at the granularity of tokens.
*/
class Scout::Token : public Element
{
private:
/*
* Noncopyable
*/
Token(Token const &);
Token &operator = (Token const &);
protected:
const char *_str; /* start of string */
int _len; /* length of string */
Style *_style; /* textual style */
Color _col; /* current text color */
Color _outline; /* outline color */
public:
/**
* Constructor
*/
Token(Style *style, const char *str, int len);
/**
* Element interface
*/
void draw(Canvas_base &, Point) override;
void refresh() { redraw_area(-1, 0, _size.w() + 1, _size.h()); }
};
/**
* Link that references an anchor within the document
*/
class Scout::Link
{
protected:
Anchor *_dst; /* link destination */
public:
/**
* Constructor
*/
explicit Link(Anchor *dst) : _dst(dst) { }
/**
* Accessor function
*/
Anchor *dst() { return _dst; }
};
/**
* Textual link
*/
class Scout::Link_token : public Token, private Link, public Event_handler,
private Fader
{
private:
enum { _MAX_ALPHA = 50 };
protected:
using Link::_dst;
public:
/**
* Constructor
*/
Link_token(Style *style, const char *str, int len, Anchor *dst)
: Token(style, str, len), Link(dst)
{
_flags.takes_focus = 1;
_curr_value = 0;
event_handler(this);
}
using Fader::step;
using Fader::curr;
/**
* Element interface
*/
void draw(Canvas_base &canvas, Point abs_position) override
{
_outline = Color(_style->color.r,
_style->color.g,
_style->color.b, _curr_value);
Token::draw(canvas, abs_position);
canvas.draw_box(_position.x() + abs_position.x(),
_position.y() + abs_position.y() + _size.h() - 1,
_size.w(), 1, Color(0,0,255));
}
void mfocus(int flag) override
{
/*
* highlight link of all siblings that point to the same link.
*/
if (_dst) {
Element const *dst = _dst;
for_each_sibling([dst, flag] (Element &e) {
Link_token *l = dynamic_cast<Link_token *>(&e);
if (l && l->has_destination(dst))
l->highlight_link(flag);
});
}
Token::mfocus(flag);
}
void highlight_link(bool flag)
{
if (flag && _curr_value != _MAX_ALPHA)
fade_to(_MAX_ALPHA, 50);
if (!flag && _curr_value != 0)
fade_to(0, 2);
}
bool has_destination(Element const *e) { return e == _dst; }
/**
* Event handler interface
*/
void handle_event(Event const &) override;
/**
* Tick interface
*/
int on_tick() override
{
/* call on_tick function of the fader */
if (Fader::on_tick() == 0) return 0;
refresh();
return 1;
}
};
class Launchpad;
class Scout::Launcher : public Anchor
{
public:
typedef Genode::String<64> Name;
private:
/*
* Noncopyable
*/
Launcher(Launcher const &);
Launcher &operator = (Launcher const &);
Name _prg_name;
int _active = 0;
int _exec_once = 0;
Launchpad *_launchpad = nullptr;
unsigned long const _caps;
unsigned long _quota;
Launcher_config *_config;
public:
static void init(Genode::Env &, Genode::Allocator &);
/**
* Constructors
*/
Launcher(Name const &prg_name, int exec_once = 0,
unsigned long caps = 0, unsigned long quota = 0,
Launcher_config *config = 0)
:
_prg_name(prg_name), _active(1),
_exec_once(exec_once), _caps(caps), _quota(quota), _config(config)
{ }
Launcher(Name const &prg_name, Launchpad *launchpad,
unsigned long caps, unsigned long quota,
Launcher_config *config = 0)
:
_prg_name(prg_name), _launchpad(launchpad),
_caps(caps), _quota(quota), _config(config)
{ }
int active() const { return _active; }
Name prg_name() const { return _prg_name; }
void quota(unsigned long quota) { _quota = quota; }
unsigned long quota() const { return _quota; }
unsigned long caps() const { return _caps; }
Launcher_config *config() { return _config; }
/**
* Launch program
*/
void launch();
};
/**
* Executable launcher link
*
* This is a special link that enables us to start external applications.
*/
class Scout::Launcher_link_token : public Link_token
{
public:
/**
* Constructor
*/
Launcher_link_token(Style *style, const char *str, int len, Launcher *l)
: Link_token(style, str, len, l) { }
/**
* Event handler interface
*/
void handle_event(Event const &) override;
};
/**
* Text block
*
* A block is a group of tokens that form a paragraph. A block layouts its
* tokens while using line wrapping.
*/
class Scout::Block : public Parent_element
{
public:
enum Alignment { LEFT, CENTER, RIGHT };
enum Text_type { PLAIN, LINK, LAUNCHER };
private:
Alignment _align; /* text alignment */
int _second_indent; /* indentation of second line */
/**
* Append text to block
*/
void append_text(const char *str, Style *style, Text_type,
Anchor *a, Launcher *l);
public:
/**
* Constructors
*/
explicit Block(int second_indent = 0)
: _align(LEFT), _second_indent(second_indent) { }
explicit Block(Alignment align)
: _align(align), _second_indent(0) { }
/**
* Define alignment of text
*/
void align(Alignment);
/**
* Append a string of space-separated words
*/
void append_plaintext(const char *str, Style *style)
{
append_text(str, style, PLAIN, 0, 0);
}
/**
* Append a string of space-separated words a link
*
* \param dst anchor that defines the link destination
*/
void append_linktext(const char *str, Style *style, Anchor *a)
{
append_text(str, style, LINK, a, 0);
}
/**
* Append a string of space-separated words a launcher-link
*/
void append_launchertext(const char *str, Style *style, Launcher *l)
{
append_text(str, style, LAUNCHER, 0, l);
}
/**
* Element interface
*/
void format_fixed_width(int w) override;
};
/**
* Horizontally centered content
*/
class Scout::Center : public Parent_element
{
public:
/**
* Constructor
*/
explicit Center(Element *content = 0)
{
if (content) append(content);
}
/**
* Element interface
*/
void format_fixed_width(int w) override;
};
/**
* PNG Image
*/
class Scout::Png_image : public Element
{
private:
/*
* Noncopyable
*/
Png_image(Png_image const &);
Png_image &operator = (Png_image const &);
void *_png_data;
Texture_base *_texture = nullptr;
public:
static void init(Genode::Allocator &);
/**
* Constructor
*/
explicit Png_image(void *png_data) : _png_data(png_data) { }
/**
* Accessor functions
*/
inline void *png_data() { return _png_data; }
/**
* Element interface
*/
void fill_cache(Canvas_base &) override;
void flush_cache(Canvas_base &) override;
void draw(Canvas_base &, Point) override;
};
/**
* Document
*/
class Scout::Document : public Parent_element
{
private:
/*
* Noncopyable
*/
Document(Document const &);
Document &operator = (Document const &);
public:
Chapter *toc = nullptr; /* table of contents */
const char *title = ""; /* document title */
/**
* Constructor
*/
Document() { _flags.chapter = 1; }
/**
* Element interface
*/
void format_fixed_width(int w) override
{
_min_size = Area(w, _format_children(0, w));
}
};
/**
* Chapter
*/
class Scout::Chapter : public Document { };
/**
* Spacer
*
* A spacer is a place holder that consumes some screen space. It is used for
* tweaking the layout of the document.
*/
struct Scout::Spacer : Element
{
Spacer(int w, int h) { _min_size = _size = Area(w, h); }
};
/**
* Verbatim text block
*
* A verbatim text block consists of a number of preformatted text lines.
* The text is printed in a monospaced font and the whole verbatim area
* has a shaded background.
*/
class Scout::Verbatim : public Parent_element
{
public:
Color bgcol;
/**
* Constructor
*/
explicit Verbatim(Color bg) : bgcol(bg) { }
/**
* Append verbatim text line
*/
void append_textline(const char *str, Style *style)
{
append(new Token(style, str, strlen(str)));
}
/**
* Element interface
*/
void draw(Canvas_base &, Point) override;
void format_fixed_width(int) override;
};
/**
* An iten consists of a item tag and a list of blocks
*/
class Scout::Item : public Parent_element
{
private:
/*
* Noncopyable
*/
Item(Item const &);
Item &operator = (Item const &);
public:
Style *_style;
const char *_tag;
int _tag_ident;
/**
* Constructor
*/
Item(Style *style, const char *str, int ident)
: _style(style), _tag(str), _tag_ident(ident) { }
/**
* Element interface
*/
void format_fixed_width(int w) override
{
_min_size = Area(w, _format_children(_tag_ident, w - _tag_ident));
}
void draw(Canvas_base &canvas, Point abs_position) override
{
canvas.draw_string(_position.x() + abs_position.x(),
_position.y() + abs_position.y(),
_style->font, _style->color, _tag, 255);
Parent_element::draw(canvas, abs_position);
}
};
/**
* Document navigation bar
*/
class Scout::Navbar : public Parent_element, public Fader
{
private:
/*
* Noncopyable
*/
Navbar(Navbar const &);
Navbar &operator = (Navbar const &);
Block *_next_title = nullptr;
Block *_prev_title = nullptr;
Anchor *_next_anchor = nullptr;
Anchor *_prev_anchor = nullptr;
public:
/**
* These pointers must be initialized such that they
* point to valid Icon widgets that are used as graphics
* for the navigation bar.
*/
static Generic_icon *next_icon;
static Generic_icon *prev_icon;
static Generic_icon *nbox_icon;
static Generic_icon *pbox_icon;
/**
* Constructor
*/
Navbar();
/**
* Define link to next and previous chapter
*/
void next_link(const char *title, Anchor *dst);
void prev_link(const char *title, Anchor *dst);
/**
* Element interface
*/
void format_fixed_width(int) override;
void draw(Canvas_base &, Point) override;
Element *find(Point) override;
/**
* Tick interface
*/
int on_tick() override;
};
#endif /* _ELEMENTS_H_ */