diff --git a/demo/include/scout/alloc.h b/demo/include/scout/alloc.h
new file mode 100644
index 0000000000..e5885940e6
--- /dev/null
+++ b/demo/include/scout/alloc.h
@@ -0,0 +1,35 @@
+/*
+ * \brief Malloc/free wrappers for Genode
+ * \date 2008-07-24
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 2008-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 _INCLUDE__SCOUT__ALLOC_H_
+#define _INCLUDE__SCOUT__ALLOC_H_
+
+#include
+
+namespace Scout {
+
+ static inline void *malloc(unsigned long size)
+ {
+ return Genode::env()->heap()->alloc(size);
+ }
+
+ static inline void free(void *addr)
+ {
+ /*
+ * FIXME: We expect the heap to know the size of the
+ * block and thus, just specify zero as size.
+ */
+ Genode::env()->heap()->free(addr, 0); }
+}
+
+#endif /* _INCLUDE__SCOUT__ALLOC_H_ */
diff --git a/demo/include/scout/canvas.h b/demo/include/scout/canvas.h
new file mode 100644
index 0000000000..0b71103110
--- /dev/null
+++ b/demo/include/scout/canvas.h
@@ -0,0 +1,216 @@
+/*
+ * \brief Generic interface of graphics backend and chunky template
+ * \date 2005-10-24
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 2005-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 _INCLUDE__SCOUT__CANVAS_H_
+#define _INCLUDE__SCOUT__CANVAS_H_
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Scout {
+ using Genode::Color;
+ using Genode::Pixel_rgba;
+
+ typedef Text_painter::Font Font;
+
+ struct Canvas_base;
+ template class Canvas;
+}
+
+
+struct Scout::Canvas_base : Texture_allocator
+{
+ virtual ~Canvas_base() { }
+
+ virtual Area size() const = 0;
+
+ virtual Rect clip() const = 0;
+
+ virtual void clip(Rect rect) = 0;
+
+ virtual void draw_box(int x, int y, int w, int h, Color c) = 0;
+
+ virtual void draw_string(int x, int y, Font *font, Color color,
+ char const *str, int len) = 0;
+
+ virtual void draw_horizontal_shadow(Rect rect, int intensity) = 0;
+
+ virtual void draw_icon(Rect, Texture_base const &, unsigned alpha) = 0;
+
+ virtual void draw_sky_texture(int py,
+ Sky_texture_painter::Sky_texture_base const &,
+ bool detail) = 0;
+
+ virtual void draw_refracted_icon(Point pos,
+ Scout::Refracted_icon_painter::Distmap const &distmap,
+ Texture_base &tmp, Texture_base const &foreground,
+ bool detail, bool filter_backbuf) = 0;
+
+ virtual void draw_texture(Point pos, Texture_base const &texture) = 0;
+};
+
+
+#include
+#include
+
+
+namespace Genode {
+
+ template <>
+ inline void
+ Texture::rgba(unsigned char const *rgba, unsigned len, int y)
+ {
+ if (len > size().w()) len = size().w();
+ if (y < 0 || y >= (int)size().h()) return;
+
+ Genode::Pixel_rgb565 *dst_pixel = pixel() + y*size().w();
+ unsigned char *dst_alpha = alpha() ? alpha() + y*size().w() : 0;
+
+ Genode::Dither_matrix::Row dither_row = Dither_matrix::row(y);
+
+ for (unsigned i = 0; i < len; i++) {
+
+ int v = dither_row.value(i) >> 5;
+ int r = *rgba++ + v;
+ int g = *rgba++ + v;
+ int b = *rgba++ + v;
+ int a = *rgba++ + v;
+
+ using Genode::min;
+ dst_pixel[i].rgba(min(r, 255), min(g, 255), min(b, 255));
+
+ if (dst_alpha)
+ dst_alpha[i] = min(a, 255);
+ }
+ }
+}
+
+
+template
+class Scout::Canvas : public Canvas_base
+{
+ private:
+
+ Genode::Surface _surface;
+
+ public:
+
+ Canvas(PT *base, Area size) : _surface(base, size) { }
+
+ Area size() const { return _surface.size(); }
+
+ Rect clip() const { return _surface.clip(); }
+
+ void clip(Rect rect) { _surface.clip(rect); }
+
+ void draw_string(int x, int y, Font *font, Color color, char const *str, int len)
+ {
+ char buf[len + 1];
+ Genode::strncpy(buf, str, len + 1);
+ Text_painter::paint(_surface, Point(x, y), *font, color, buf);
+ }
+
+ void draw_box(int x, int y, int w, int h, Color c)
+ {
+ Box_painter::paint(_surface, Rect(Point(x, y), Area(w, h)), c);
+ }
+
+ void draw_horizontal_shadow(Rect rect, int intensity)
+ {
+ Horizontal_shadow_painter::paint(_surface, rect, intensity);
+ }
+
+ void draw_icon(Rect rect, Texture_base const &icon, unsigned alpha)
+ {
+ Icon_painter::paint(_surface, rect,
+ static_cast const &>(icon), alpha);
+ }
+
+ void draw_sky_texture(int py,
+ Sky_texture_painter::Sky_texture_base const &texture,
+ bool detail)
+ {
+ Sky_texture_painter::paint(_surface, py, texture, detail);
+ }
+
+ void draw_refracted_icon(Point pos,
+ Scout::Refracted_icon_painter::Distmap const &distmap,
+ Texture_base &tmp, Texture_base const &foreground,
+ bool detail, bool filter_backbuf)
+ {
+ using namespace Scout;
+ Refracted_icon_painter::paint(_surface, pos, distmap,
+ static_cast &>(tmp),
+ static_cast const &>(foreground),
+ detail, filter_backbuf);
+ }
+
+ void draw_texture(Point pos, Texture_base const &texture_base)
+ {
+ Texture const &texture = static_cast const &>(texture_base);
+
+ Texture_painter::paint(_surface, texture, Color(0, 0, 0), pos,
+ Texture_painter::SOLID, true);
+ }
+
+ Texture_base *alloc_texture(Area size, bool has_alpha)
+ {
+ using namespace Genode;
+
+ PT *pixel = (PT *)env()->heap()->alloc(size.count()*sizeof(PT));
+
+ unsigned char *alpha = 0;
+
+ if (has_alpha)
+ alpha = (unsigned char *)env()->heap()->alloc(size.count());
+
+ return new (env()->heap()) Genode::Texture(pixel, alpha, size);
+ }
+
+ virtual void free_texture(Texture_base *texture_base)
+ {
+ using namespace Genode;
+
+ Texture *texture = static_cast *>(texture_base);
+
+ size_t const num_pixels = texture->size().count();
+
+ if (texture->alpha())
+ env()->heap()->free(texture->alpha(), num_pixels);
+
+ env()->heap()->free(texture->pixel(), sizeof(PT)*num_pixels);
+
+ destroy(env()->heap(), texture);
+ }
+
+ virtual void set_rgba_texture(Texture_base *texture_base,
+ unsigned char const *rgba,
+ unsigned len, int y)
+ {
+ Texture *texture = static_cast *>(texture_base);
+
+ texture->rgba(rgba, len, y);
+ }
+};
+
+#endif /* _INCLUDE__SCOUT__CANVAS_H_ */
diff --git a/demo/include/scout/element.h b/demo/include/scout/element.h
new file mode 100644
index 0000000000..59f2d4578d
--- /dev/null
+++ b/demo/include/scout/element.h
@@ -0,0 +1,212 @@
+/*
+ * \brief Scout GUI element
+ * \author Norman Feske
+ * \date 2006-08-30
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT__ELEMENT_H_
+#define _INCLUDE__SCOUT__ELEMENT_H_
+
+#include
+#include
+
+namespace Scout {
+ class Element;
+ class Parent_element;
+}
+
+
+class Scout::Element
+{
+ protected:
+
+ Point _position; /* relative position managed by parent */
+ Area _size; /* size managed by parent */
+ Area _min_size; /* min size managed by element */
+ Parent_element *_parent; /* parent in element hierarchy */
+ Event_handler *_evh; /* event handler object */
+ struct {
+ int mfocus : 1; /* element has mouse focus */
+ int selected : 1; /* element has selected state */
+ int takes_focus : 1; /* element highlights mouse focus */
+ int chapter : 1; /* display element as single page */
+ int findable : 1; /* regard element in find function */
+ int bottom : 1; /* place element to the bottom */
+ } _flags;
+
+ public:
+
+ Element mutable *next = { 0 }; /* managed by parent */
+
+ /**
+ * Constructor
+ */
+ Element() : _parent(0), _evh(0)
+ {
+ _flags.mfocus = _flags.selected = 0;
+ _flags.takes_focus = 0;
+ _flags.chapter = 0;
+ _flags.findable = 1;
+ _flags.bottom = 0;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Element();
+
+ /**
+ * Accessor functionse
+ */
+ Point position() const { return _position; }
+ Area size() const { return _size; }
+ Area min_size() const { return _min_size; }
+ bool is_bottom() const { return _flags.bottom; }
+
+ void findable(int flag) { _flags.findable = flag; }
+
+ /**
+ * Set geometry of the element
+ *
+ * This function should only be called by the immediate parent
+ * element.
+ */
+ virtual void geometry(Rect rect)
+ {
+ _position = rect.p1();
+ _size = rect.area();
+ }
+
+ /**
+ * Set/reset the mouse focus
+ */
+ virtual void mfocus(int flag)
+ {
+ if ((_flags.mfocus == flag) || !_flags.takes_focus) return;
+ _flags.mfocus = flag;
+ refresh();
+ }
+
+ /**
+ * Define/request parent of an element
+ */
+ void parent(Parent_element *parent) { _parent = parent; }
+ Parent_element *parent() { return _parent; }
+
+ bool has_parent(Parent_element const *parent) const { return parent == _parent; }
+
+ /**
+ * Define event handler object
+ */
+ void event_handler(Event_handler *evh) { _evh = evh; }
+
+ /**
+ * Check if element is completely clipped and draw it otherwise
+ */
+ void try_draw(Canvas_base &canvas, Point abs_position)
+ {
+ Rect const abs_rect = Rect(abs_position + _position, _size);
+
+ /* check if element is completely outside the clipping area */
+ if (!Rect::intersect(canvas.clip(), abs_rect).valid())
+ return;
+
+ /* call actual drawing function */
+ draw(canvas, abs_position);
+ }
+
+ /**
+ * Format element and all child elements to specified width
+ */
+ virtual void format_fixed_width(int w) { }
+
+ /**
+ * Format element and all child elements to specified width and height
+ */
+ virtual void format_fixed_size(Area size) { }
+
+ /**
+ * Draw function
+ *
+ * This function must not be called directly.
+ * Instead, the function try_draw should be called.
+ */
+ virtual void draw(Canvas_base &, Point) { }
+
+ /**
+ * Find top-most element at specified position
+ *
+ * The default implementation can be used for elements without
+ * children. It just the element position and size against the
+ * specified position.
+ */
+ virtual Element *find(Point);
+
+ /**
+ * Find the back-most element at specified y position
+ *
+ * This function is used to query a document element at
+ * the current scroll position of the window. This way,
+ * we can adjust the y position to the right value
+ * when we browse the history.
+ */
+ virtual Element *find_by_y(int y);
+
+ /**
+ * Request absolute position of an element
+ */
+ Point abs_position() const;
+
+ /**
+ * Update area of an element on screen
+ *
+ * We propagate the redraw request through the element hierarchy to
+ * the parent. The root parent should overwrite this function with
+ * a function that performs the actual redraw.
+ */
+ virtual void redraw_area(int x, int y, int w, int h);
+
+ /**
+ * Trigger the refresh of an element on screen
+ */
+ void refresh() { redraw_area(0, 0, _size.w(), _size.h()); }
+
+ /**
+ * Handle user input or timer event
+ */
+ void handle_event(Event &ev) { if (_evh) _evh->handle(ev); }
+
+ /**
+ * Request the chapter in which the element lives
+ */
+ Element *chapter();
+
+ /**
+ * Fill image cache for element
+ */
+ virtual void fill_cache(Canvas_base &) { }
+
+ /**
+ * Flush image cache for element
+ */
+ virtual void flush_cache(Canvas_base &) { }
+
+ /**
+ * Execute function for each sibling including the element itself
+ *
+ * The functor FUNC takes a reference to the element as argument.
+ *
+ * This function template is implemented in 'scout/parent_element.h'.
+ */
+ template
+ inline void for_each_sibling(FUNC func);
+};
+
+#endif /* _INCLUDE__SCOUT__ELEMENT_H_ */
diff --git a/demo/src/app/scout/include/event.h b/demo/include/scout/event.h
similarity index 63%
rename from demo/src/app/scout/include/event.h
rename to demo/include/scout/event.h
index 9e7230282b..b94fc0fe52 100644
--- a/demo/src/app/scout/include/event.h
+++ b/demo/include/scout/event.h
@@ -11,16 +11,23 @@
* under the terms of the GNU General Public License version 2.
*/
-#ifndef _EVENT_H_
-#define _EVENT_H_
+#ifndef _INCLUDE__SCOUT__EVENT_H_
+#define _INCLUDE__SCOUT__EVENT_H_
+
+#include
+
+namespace Scout {
+ class Event;
+ class Event_handler;
+}
+
/**
* Event structure
*
- * This event structure covers timer events as
- * well as user input events.
+ * This event structure covers timer events as well as user input events.
*/
-class Event
+class Scout::Event
{
public:
@@ -39,34 +46,28 @@ class Event
RELEASE = 3, /* button/key released */
TIMER = 4, /* timer event */
QUIT = 5, /* quit application */
- REFRESH = 6, /* refresh screen */
- WHEEL = 7, /* mouse wheel */
+ WHEEL = 6, /* mouse wheel */
};
- ev_type type;
- int mx, my; /* mouse position */
- int wx, wy; /* wheel */
- int code; /* key code */
+ ev_type type;
+ Point mouse_position;
+ Point wheel_movement;
+ int code; /* key code */
/**
* Assign new event information to event structure
*/
inline void assign(ev_type new_type, int new_mx, int new_my, int new_code)
{
- type = new_type;
- mx = new_mx;
- my = new_my;
- wx = 0;
- wy = 0;
- code = new_code;
+ type = new_type;
+ mouse_position = Point(new_mx, new_my);
+ wheel_movement = Point(0, 0);
+ code = new_code;
}
};
-/**
- * Event handler
- */
-class Event_handler
+class Scout::Event_handler
{
public:
@@ -78,5 +79,4 @@ class Event_handler
virtual void handle(Event &e) = 0;
};
-
-#endif /* _EVENT_H_ */
+#endif /* _INCLUDE__SCOUT__EVENT_H_ */
diff --git a/demo/src/app/scout/include/fader.h b/demo/include/scout/fader.h
similarity index 84%
rename from demo/src/app/scout/include/fader.h
rename to demo/include/scout/fader.h
index 207f5d3cd8..00d9c0c0a8 100644
--- a/demo/src/app/scout/include/fader.h
+++ b/demo/include/scout/fader.h
@@ -11,16 +11,19 @@
* under the terms of the GNU General Public License version 2.
*/
-#ifndef _FADER_H_
-#define _FADER_H_
+#ifndef _INCLUDE__SCOUT__FADER_H_
+#define _INCLUDE__SCOUT__FADER_H_
+
+#include
+#include
+
+namespace Scout { class Fader; }
-#include "miscmath.h"
-#include "tick.h"
/**
* Class that manages the fading of a derived class.
*/
-class Fader : public Tick
+class Scout::Fader : public Tick
{
protected:
@@ -75,4 +78,4 @@ class Fader : public Tick
};
-#endif /* _FADER_H_ */
+#endif /* _INCLUDE__SCOUT__FADER_H_ */
diff --git a/demo/include/scout/graphics_backend.h b/demo/include/scout/graphics_backend.h
new file mode 100644
index 0000000000..6faedc2a49
--- /dev/null
+++ b/demo/include/scout/graphics_backend.h
@@ -0,0 +1,51 @@
+/*
+ * \brief Graphics backend interface
+ * \date 2013-12-30
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 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 _INCLUDE__SCOUT__GRAPHICS_BACKEND_H_
+#define _INCLUDE__SCOUT__GRAPHICS_BACKEND_H_
+
+#include
+#include
+
+namespace Scout { struct Graphics_backend; }
+
+
+/*
+ * We use two buffers, a foreground buffer that is displayed on screen and a
+ * back buffer. While the foreground buffer must contain valid data all the
+ * time, the back buffer can be used to prepare pixel data. For example,
+ * drawing multiple pixel layers with alpha channel must be done in the back
+ * buffer to avoid artifacts on the screen.
+ */
+struct Scout::Graphics_backend
+{
+ virtual Canvas_base &front() = 0;
+
+ virtual Canvas_base &back() = 0;
+
+ virtual void copy_back_to_front(Rect rect) = 0;
+
+ virtual void swap_back_and_front() = 0;
+
+ /*
+ * XXX todo mode-change notification
+ */
+
+ virtual void position(Point p) = 0;
+
+ virtual void bring_to_front() = 0;
+
+ virtual void view_area(Area area) = 0;
+};
+
+#endif /* _INCLUDE__SCOUT__GRAPHICS_BACKEND_H_ */
diff --git a/demo/include/scout/misc_math.h b/demo/include/scout/misc_math.h
new file mode 100644
index 0000000000..1f7b725ade
--- /dev/null
+++ b/demo/include/scout/misc_math.h
@@ -0,0 +1,24 @@
+/*
+ * \brief Misc math functions used here and there
+ * \date 2005-10-24
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 2005-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 _INCLUDE__SCOUT__MISC_MATH_H_
+#define _INCLUDE__SCOUT__MISC_MATH_H_
+
+#include
+
+namespace Scout {
+ using Genode::min;
+ using Genode::max;
+}
+
+#endif /* _INCLUDE__SCOUT__MISC_MATH_H_ */
diff --git a/demo/include/scout/nitpicker_graphics_backend.h b/demo/include/scout/nitpicker_graphics_backend.h
new file mode 100644
index 0000000000..0964aa5835
--- /dev/null
+++ b/demo/include/scout/nitpicker_graphics_backend.h
@@ -0,0 +1,158 @@
+/*
+ * \brief Nitpicker-based graphics backend for scout
+ * \date 2013-12-30
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 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 _INCLUDE__SCOUT__NITPICKER_GRAPHICS_BACKEND_H_
+#define _INCLUDE__SCOUT__NITPICKER_GRAPHICS_BACKEND_H_
+
+/* Genode includes */
+#include
+#include
+#include
+
+/* Scout includes */
+#include
+
+
+namespace Scout {
+ using Genode::Pixel_rgb565;
+ class Nitpicker_graphics_backend;
+}
+
+
+class Scout::Nitpicker_graphics_backend : public Graphics_backend
+{
+ private:
+
+ Nitpicker::Connection &_nitpicker;
+
+ Genode::Dataspace_capability _init_fb_ds(Area max_size)
+ {
+ _nitpicker.buffer(Framebuffer::Mode(max_size.w(), max_size.h()*2,
+ Framebuffer::Mode::RGB565), false);
+ return _nitpicker.framebuffer()->dataspace();
+ }
+
+ Area _max_size;
+
+ Genode::Dataspace_capability _fb_ds = { _init_fb_ds(_max_size) };
+
+ void *_map_fb_ds()
+ {
+ return Genode::env()->rm_session()->attach(_fb_ds);
+ }
+
+ void *_fb_local_base = { _map_fb_ds() };
+
+ Point _position;
+ Area _view_size;
+ Nitpicker::View_client _view;
+ Canvas_base *_canvas[2];
+ bool _flip_state = { false };
+
+ void _update_viewport()
+ {
+ _view.viewport(_position.x(), _position.y(),
+ _view_size.w(), _view_size.h(),
+ 0,
+ _flip_state ? -_max_size.h() : 0,
+ true);
+ }
+
+ void _refresh_view(Rect rect)
+ {
+ int const y_offset = _flip_state ? _max_size.h() : 0;
+ _nitpicker.framebuffer()->refresh(rect.x1(), rect.y1() + y_offset,
+ rect.w(), rect.h());
+ }
+
+ template
+ PT *_base(unsigned idx)
+ {
+ return (PT *)_fb_local_base + idx*_max_size.count();
+ }
+
+ unsigned _front_idx() const { return _flip_state ? 1 : 0; }
+ unsigned _back_idx() const { return _flip_state ? 0 : 1; }
+
+ public:
+
+ Nitpicker_graphics_backend(Nitpicker::Connection &nitpicker,
+ Area max_size, Point position, Area view_size)
+ :
+ _nitpicker(nitpicker),
+ _max_size(max_size),
+ _position(position),
+ _view_size(view_size),
+ _view(_nitpicker.create_view())
+ {
+ bring_to_front();
+
+ typedef Genode::Pixel_rgb565 PT;
+ static Canvas canvas_0(_base(0), max_size);
+ static Canvas canvas_1(_base(1), max_size);
+
+ _canvas[0] = &canvas_0;
+ _canvas[1] = &canvas_1;
+ }
+
+
+ /********************************
+ ** Graphics_backend interface **
+ ********************************/
+
+ Canvas_base &front() { return *_canvas[_front_idx()]; }
+ Canvas_base &back() { return *_canvas[ _back_idx()]; }
+
+ void copy_back_to_front(Rect rect)
+ {
+
+ typedef Genode::Pixel_rgb565 PT;
+
+ PT const *src = _base( _back_idx());
+ PT *dst = _base(_front_idx());
+
+ unsigned long const offset = rect.y1()*_max_size.w() + rect.x1();
+
+ src += offset;
+ dst += offset;
+
+ blit(src, sizeof(PT)*_max_size.w(),
+ dst, sizeof(PT)*_max_size.w(), sizeof(PT)*rect.w(), rect.h());
+
+ _refresh_view(rect);
+ }
+
+ void swap_back_and_front()
+ {
+ _flip_state = !_flip_state;
+ _update_viewport();
+ }
+
+ void position(Point p)
+ {
+ _position = p;
+ _update_viewport();
+ }
+
+ void bring_to_front()
+ {
+ _view.stack(Nitpicker::View_capability(), true, true);
+ }
+
+ void view_area(Area area)
+ {
+ _view_size = area;
+ }
+};
+
+#endif /* _INCLUDE__SCOUT__NITPICKER_GRAPHICS_BACKEND_H_ */
diff --git a/demo/include/scout/parent_element.h b/demo/include/scout/parent_element.h
new file mode 100644
index 0000000000..d2984bee06
--- /dev/null
+++ b/demo/include/scout/parent_element.h
@@ -0,0 +1,95 @@
+/*
+ * \brief Scout GUI parent element
+ * \author Norman Feske
+ * \date 2006-08-30
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT__PARENT_ELEMENT_H_
+#define _INCLUDE__SCOUT__PARENT_ELEMENT_H_
+
+#include
+
+namespace Scout {
+ class Element;
+ class Parent_element;
+}
+
+class Scout::Parent_element : public Element
+{
+ protected:
+
+ Element *_first;
+ Element *_last;
+
+ /**
+ * Format child element by a given width an horizontal offset
+ */
+ int _format_children(int x, int w);
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Parent_element() { _first = _last = 0; }
+
+ /**
+ * Adopt a child element
+ */
+ void append(Element *e);
+
+ /**
+ * Release child element from parent element
+ */
+ void remove(Element const *e);
+
+ /**
+ * Dispose references to the specified element
+ *
+ * The element is not necessarily an immediate child but some element
+ * of the element-subtree. This function gets propagated to the root
+ * parent (e.g., user state manager), which can reset the mouse focus
+ * of the focused element vanishes.
+ */
+ virtual void forget(Element const *e);
+
+ /**
+ * Element interface
+ */
+ void draw(Canvas_base &, Point);
+ Element *find(Point);
+ Element *find_by_y(int);
+ void fill_cache(Canvas_base &);
+ void flush_cache(Canvas_base &);
+ void geometry(Rect);
+
+ /**
+ * Execute function on each child
+ *
+ * The functor FUNC takes a reference to the element as argument.
+ */
+ template
+ void for_each_child(FUNC func)
+ {
+ for (Element *e = _first; e; e = e->next)
+ func(*e);
+ }
+};
+
+
+template
+void Scout::Element::for_each_sibling(FUNC func)
+{
+ if (parent())
+ parent()->for_each_child(func);
+}
+
+
+#endif /* _INCLUDE__SCOUT__PARENT_ELEMENT_H_ */
diff --git a/demo/include/scout/platform.h b/demo/include/scout/platform.h
new file mode 100644
index 0000000000..45c21ca7f2
--- /dev/null
+++ b/demo/include/scout/platform.h
@@ -0,0 +1,200 @@
+/*
+ * \brief Platform abstraction
+ * \date 2005-10-24
+ * \author Norman Feske
+ *
+ * This interface specifies the target-platform-specific functions.
+ */
+
+/*
+ * Copyright (C) 2005-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 _INCLUDE__SCOUT__PLATFORM_H_
+#define _INCLUDE__SCOUT__PLATFORM_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Scout {
+
+ typedef Genode::Point<> Point;
+ typedef Genode::Area<> Area;
+ typedef Genode::Rect<> Rect;
+
+ class Platform;
+}
+
+
+inline void *operator new(Genode::size_t size)
+{
+ using Genode::env;
+ void *addr = env()->heap()->alloc(size);
+ if (!addr) {
+ PERR("env()->heap() has consumed %zd", env()->heap()->consumed());
+ PERR("env()->ram_session()->quota = %zd", env()->ram_session()->quota());
+ throw Genode::Allocator::Out_of_memory();
+ }
+ return addr;
+}
+
+
+class Scout::Platform
+{
+ private:
+
+ /*****************
+ ** Event queue **
+ *****************/
+
+ class Event_queue
+ {
+ private:
+
+ static const int queue_size = 1024;
+
+ int _head;
+ int _tail;
+ Genode::Semaphore _sem;
+ Genode::Lock _head_lock; /* synchronize add */
+
+ Event _queue[queue_size];
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Event_queue(): _head(0), _tail(0)
+ {
+ Genode::memset(_queue, 0, sizeof(_queue));
+ }
+
+ void add(Event ev)
+ {
+ Genode::Lock::Guard lock_guard(_head_lock);
+
+ if ((_head + 1)%queue_size != _tail) {
+
+ _queue[_head] = ev;
+ _head = (_head + 1)%queue_size;
+ _sem.up();
+ }
+ }
+
+ Event get()
+ {
+ _sem.down();
+ Event ev = _queue[_tail];
+ _tail = (_tail + 1)%queue_size;
+ return ev;
+ }
+
+ int pending() const { return _head != _tail; }
+
+ } _event_queue;
+
+ /******************
+ ** Timer thread **
+ ******************/
+
+ class Timer_thread : public Genode::Thread<4096>
+ {
+ private:
+
+ Timer::Connection _timer;
+ Input::Session &_input;
+ Input::Event *_ev_buf = { Genode::env()->rm_session()->attach(_input.dataspace()) };
+ Event_queue &_event_queue;
+ int _mx, _my;
+ unsigned long _ticks = { 0 };
+
+ void _import_events()
+ {
+ if (_input.is_pending() == false) return;
+
+ for (int i = 0, num = _input.flush(); i < num; i++)
+ {
+ Event ev;
+ Input::Event e = _ev_buf[i];
+
+ if (e.type() == Input::Event::RELEASE
+ || e.type() == Input::Event::PRESS) {
+ _mx = e.ax();
+ _my = e.ay();
+ ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE,
+ e.ax(), e.ay(), e.code());
+ _event_queue.add(ev);
+ }
+
+ if (e.type() == Input::Event::MOTION) {
+ _mx = e.ax();
+ _my = e.ay();
+ ev.assign(Event::MOTION, e.ax(), e.ay(), e.code());
+ _event_queue.add(ev);
+ }
+ }
+ }
+
+ public:
+
+ /**
+ * Constructor
+ *
+ * Start thread immediately on construction.
+ */
+ Timer_thread(Input::Session &input, Event_queue &event_queue)
+ : Thread("timer"), _input(input), _event_queue(event_queue)
+ { start(); }
+
+ void entry()
+ {
+ while (1) {
+ Event ev;
+ ev.assign(Event::TIMER, _mx, _my, 0);
+ _event_queue.add(ev);
+
+ _import_events();
+
+ _timer.msleep(10);
+ _ticks += 10;
+ }
+ }
+
+ unsigned long ticks() const { return _ticks; }
+ } _timer_thread;
+
+ public:
+
+ Platform(Input::Session &input) : _timer_thread(input, _event_queue) { }
+
+ /**
+ * Get timer ticks in miilliseconds
+ */
+ unsigned long timer_ticks() const { return _timer_thread.ticks(); }
+
+ /**
+ * Return true if an event is pending
+ */
+ bool event_pending() const { return _event_queue.pending(); }
+
+ /**
+ * Request event
+ *
+ * \param e destination where to store event information.
+ *
+ * If there is no event pending, this function blocks
+ * until there is an event to deliver.
+ */
+ Event get_event() { return _event_queue.get(); }
+};
+
+#endif /* _INCLUDE__SCOUT__PLATFORM_H_ */
diff --git a/demo/src/app/scout/include/genode/printf.h b/demo/include/scout/printf.h
similarity index 52%
rename from demo/src/app/scout/include/genode/printf.h
rename to demo/include/scout/printf.h
index 45a95a79a9..d1b15eb625 100644
--- a/demo/src/app/scout/include/genode/printf.h
+++ b/demo/include/scout/printf.h
@@ -1,5 +1,5 @@
/*
- * \brief Printf wrappers for Genode
+ * \brief Printf wrapper for Genode
* \date 2008-07-24
* \author Norman Feske
*/
@@ -11,20 +11,11 @@
* under the terms of the GNU General Public License version 2.
*/
-#ifndef _GENODE_PRINTF_H_
-#define _GENODE_PRINTF_H_
+#ifndef _INCLUDE__SCOUT__PRINTF_H_
+#define _INCLUDE__SCOUT__PRINTF_H_
#include
-inline int printf(const char *format, ...)
-{
- va_list list;
- va_start(list, format);
+namespace Scout { using Genode::printf; }
- Genode::vprintf(format, list);
-
- va_end(list);
- return 0;
-}
-
-#endif
+#endif /* _INCLUDE__SCOUT__PRINTF_H_ */
diff --git a/demo/include/scout/string.h b/demo/include/scout/string.h
new file mode 100644
index 0000000000..59bc916558
--- /dev/null
+++ b/demo/include/scout/string.h
@@ -0,0 +1,25 @@
+/*
+ * \brief String function wrappers for Genode
+ * \date 2008-07-24
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 2008-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 _INCLUDE__SCOUT__STRING_H_
+#define _INCLUDE__SCOUT__STRING_H_
+
+#include
+
+namespace Scout {
+ using Genode::strlen;
+ using Genode::memset;
+ using Genode::memcpy;
+}
+
+#endif /* _INCLUDE__SCOUT__STRING_H_ */
diff --git a/demo/include/scout/texture_allocator.h b/demo/include/scout/texture_allocator.h
new file mode 100644
index 0000000000..5c7b759801
--- /dev/null
+++ b/demo/include/scout/texture_allocator.h
@@ -0,0 +1,42 @@
+/*
+ * \brief Generic interface of texture allocator
+ * \date 2013-12-31
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 2005-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 _INCLUDE__SCOUT__TEXTURE_ALLOCATOR_H_
+#define _INCLUDE__SCOUT__TEXTURE_ALLOCATOR_H_
+
+#include
+#include
+
+
+namespace Scout {
+ struct Texture_allocator;
+
+ using Genode::Texture;
+ using Genode::Texture_base;
+
+ struct Texture_allocator;
+}
+
+
+struct Scout::Texture_allocator
+{
+ virtual Texture_base *alloc_texture(Area size, bool alpha) = 0;
+
+ virtual void free_texture(Texture_base *) = 0;
+
+ virtual void set_rgba_texture(Texture_base *texture,
+ unsigned char const *rgba,
+ unsigned len, int y) = 0;
+};
+
+#endif /* _INCLUDE__SCOUT__TEXTURE_ALLOCATOR_H_ */
diff --git a/demo/src/app/scout/include/tick.h b/demo/include/scout/tick.h
similarity index 90%
rename from demo/src/app/scout/include/tick.h
rename to demo/include/scout/tick.h
index da090cad28..e6d22e07a5 100644
--- a/demo/src/app/scout/include/tick.h
+++ b/demo/include/scout/tick.h
@@ -11,11 +11,13 @@
* under the terms of the GNU General Public License version 2.
*/
-#ifndef _TICK_H_
-#define _TICK_H_
+#ifndef _INCLUDE__SCOUT__TICK_H_
+#define _INCLUDE__SCOUT__TICK_H_
-class Tick;
-class Tick
+namespace Scout { class Tick; }
+
+
+class Scout::Tick
{
public:
@@ -84,4 +86,4 @@ class Tick
};
-#endif /* _TICK_H_ */
+#endif /* _INCLUDE__SCOUT__TICK_H_ */
diff --git a/demo/include/scout/types.h b/demo/include/scout/types.h
new file mode 100644
index 0000000000..241024755d
--- /dev/null
+++ b/demo/include/scout/types.h
@@ -0,0 +1,25 @@
+/*
+ * \brief Basic types used by scout widgets
+ * \date 2013-12-31
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 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 _INCLUDE__SCOUT__TYPES_H_
+#define _INCLUDE__SCOUT__TYPES_H_
+
+#include
+
+namespace Scout {
+ typedef Genode::Point<> Point;
+ typedef Genode::Area<> Area;
+ typedef Genode::Rect<> Rect;
+}
+
+#endif /* _INCLUDE__SCOUT__TYPES_H_ */
diff --git a/demo/src/app/scout/include/user_state.h b/demo/include/scout/user_state.h
similarity index 64%
rename from demo/src/app/scout/include/user_state.h
rename to demo/include/scout/user_state.h
index 22fc196f0a..5bc2ead9f2 100644
--- a/demo/src/app/scout/include/user_state.h
+++ b/demo/include/scout/user_state.h
@@ -11,25 +11,26 @@
* under the terms of the GNU General Public License version 2.
*/
-#ifndef _USER_STATE_H_
-#define _USER_STATE_H_
+#ifndef _INCLUDE__SCOUT__USER_STATE_H_
+#define _INCLUDE__SCOUT__USER_STATE_H_
-#include "window.h"
-#include "elements.h"
+#include
+
+namespace Scout { class User_state; }
-class User_state : public Parent_element
+class Scout::User_state : public Parent_element
{
private:
+ Element *_mfocus; /* element that owns the current mouse focus */
+ Element *_active; /* currently activated element */
Window *_window;
Element *_root; /* root of element tree */
- Element *_mfocus; /* element that owns the current mouse focus */
- Element *_dst; /* current link destination */
- Element *_active; /* currently activated element */
int _key_cnt; /* number of currently pressed keys */
- int _mx, _my; /* current mouse position */
- int _vx, _vy; /* current view offset */
+
+ Point _mouse_position;
+ Point _view_position;
/**
* Assign new mouse focus element
@@ -47,18 +48,6 @@ class User_state : public Parent_element
/* notify new mouse focus */
if (_mfocus) _mfocus->mfocus(1);
-
- /* determine new current link destination */
- Element *old_dst = _dst;
- if (_mfocus && _mfocus->is_link()) {
- Link_token *l = static_cast(_mfocus);
- _dst = l->dst();
- } else
- _dst = 0;
-
- /* nofify element tree about new link destination */
- if (_dst != old_dst)
- _root->curr_link_destination(_dst);
}
public:
@@ -67,30 +56,23 @@ class User_state : public Parent_element
* Constructor
*/
User_state(Window *window, Element *root, int vx, int vy)
- {
- _mfocus = _dst = _active = 0;
- _window = window;
- _root = root;
- _key_cnt = 0;
- _vx = vx;
- _vy = vy;
- }
+ :
+ _mfocus(0), _active(0), _window(window), _root(root),
+ _key_cnt(0), _view_position(Point(vx, vy))
+ { }
/**
* Accessor functions
*/
- int mx() { return _mx; }
- int my() { return _my; }
- int vx() { return _vx; }
- int vy() { return _vy; }
+ Point mouse_position() const { return _mouse_position; }
+ Point view_position() const { return _view_position; }
/**
* Update the current view offset
*/
void update_view_offset()
{
- _vx = _window->view_x();
- _vy = _window->view_y();
+ _view_position = Point(_window->view_x(), _window->view_y());
}
/**
@@ -107,9 +89,9 @@ class User_state : public Parent_element
_active->handle_event(ev);
/* find element under the mouse cursor */
- _mx = ev.mx;
- _my = ev.my;
- Element *e = _root->find(_mx, _my);
+ _mouse_position = ev.mouse_position;
+
+ Element *e = _root->find(_mouse_position);
switch (ev.type) {
@@ -123,7 +105,7 @@ class User_state : public Parent_element
update_view_offset();
- _assign_mfocus(_root->find(ev.mx, ev.my), 1);
+ _assign_mfocus(_root->find(ev.mouse_position), 1);
break;
@@ -146,7 +128,7 @@ class User_state : public Parent_element
case Event::WHEEL:
if (_key_cnt == 0)
- _window->ypos(_window->ypos() + 23 * ev.my);
+ _window->ypos(_window->ypos() + 23 * ev.mouse_position.y());
break;
default:
@@ -160,12 +142,11 @@ class User_state : public Parent_element
** Parent element **
********************/
- void forget(Element *e)
+ void forget(Element const *e)
{
if (_mfocus == e) _mfocus = 0;
- if (_dst == e) _dst = 0;
if (_active == e) _active = 0;
}
};
-#endif /* _USER_STATE_H_ */
+#endif /* _INCLUDE__SCOUT__USER_STATE_H_ */
diff --git a/demo/include/scout/window.h b/demo/include/scout/window.h
new file mode 100644
index 0000000000..23d49dfdd8
--- /dev/null
+++ b/demo/include/scout/window.h
@@ -0,0 +1,297 @@
+/*
+ * \brief Window interface
+ * \author Norman Feske
+ * \date 2006-08-30
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT__WINDOW_H_
+#define _INCLUDE__SCOUT__WINDOW_H_
+
+#include
+#include
+#include
+#include
+
+namespace Scout {
+ class Window;
+ class Drag_event_handler;
+ class Sizer_event_handler;
+ class Mover_event_handler;
+}
+
+
+class Scout::Window : public Parent_element
+{
+ private:
+
+ Graphics_backend &_gfx_backend;
+ Rect _dirty;
+ Area _max_size;
+ Point _view_position;
+ int _request_cnt; /* nb of requests since last process */
+ bool const _scout_quirk; /* enable redraw quirk for scout */
+
+ public:
+
+ Window(Graphics_backend &gfx_backend, Point position, Area size,
+ Area max_size, bool scout_quirk)
+ :
+ _gfx_backend(gfx_backend), _max_size(max_size), _request_cnt(0),
+ _scout_quirk(scout_quirk)
+ {
+ /* init element attributes */
+ _view_position = position;
+ _size = size;
+ }
+
+ virtual ~Window() { }
+
+ /**
+ * Return current window position
+ */
+ int view_x() const { return _view_position.x(); }
+ int view_y() const { return _view_position.y(); }
+ int view_w() const { return _size.w(); }
+ int view_h() const { return _size.h(); }
+
+ Area max_size() const { return _max_size; }
+
+ /**
+ * Bring window to front
+ */
+ virtual void top() { _gfx_backend.bring_to_front(); }
+
+ /**
+ * Move window to new position
+ */
+ virtual void vpos(int x, int y)
+ {
+ _view_position = Point(x, y);
+ _gfx_backend.position(_view_position);
+ }
+
+ /**
+ * Define vertical scroll offset
+ */
+ virtual void ypos(int ypos) { }
+ virtual int ypos() { return 0; }
+
+ /**
+ * Format window
+ */
+ virtual void format(Area size)
+ {
+ _gfx_backend.view_area(size);
+ }
+
+ /**
+ * Element interface
+ *
+ * This function just collects the specified regions to be redrawn but
+ * does not perform any immediate drawing operation. The actual drawing
+ * must be initiated by calling the process_redraw function.
+ */
+ void redraw_area(int x, int y, int w, int h)
+ {
+ /*
+ * Scout redraw quirk
+ *
+ * Quick fix to avoid artifacts at the icon bar. The icon bar must
+ * always be drawn completely because of the interaction of the
+ * different layers.
+ */
+ if (_scout_quirk && y < 64 + 32) {
+ h = max(h + y, 64 + 32);
+ w = _size.w();
+ x = 0;
+ y = 0;
+ }
+
+ Rect rect(Point(x, y), Area(w, h));
+
+ /* first request since last process operation */
+ if (_request_cnt == 0) {
+ _dirty = rect;
+
+ /* merge subsequencing requests */
+ } else {
+ _dirty = Rect::compound(_dirty, rect);
+ }
+
+ _request_cnt++;
+ }
+
+ /**
+ * Process redrawing operations
+ */
+ void process_redraw()
+ {
+ if (_request_cnt == 0) return;
+
+ /* get actual drawing area (clipped against canvas dimensions) */
+ int x1 = max(0, _dirty.x1());
+ int y1 = max(0, _dirty.y1());
+ int x2 = min((int)_size.w() - 1, _dirty.x2());
+ int y2 = min((int)_size.h() - 1, _dirty.y2());
+
+ if (x1 > x2 || y1 > y2) return;
+
+ Canvas_base &canvas = _gfx_backend.back();
+ canvas.clip(Rect(Point(x1, y1), Area(x2 - x1 + 1, y2 - y1 + 1)));
+
+ /* draw into back buffer */
+ try_draw(canvas, Point(0, 0));
+
+ /*
+ * If we draw the whole area, we can flip the front
+ * and back buffers instead of copying pixels from the
+ * back to the front buffer.
+ */
+
+ /* detemine if the whole area must be drawn */
+ if (x1 == 0 && x2 == (int)_size.w() - 1
+ && y1 == 0 && y2 == (int)_size.h() - 1) {
+
+ /* flip back end front buffers */
+ _gfx_backend.swap_back_and_front();
+
+ } else {
+ _gfx_backend.copy_back_to_front(Rect(Point(x1, y1),
+ Area(x2 - x1 + 1, y2 - y1 + 1)));
+ }
+
+ /* reset request state */
+ _request_cnt = 0;
+ }
+};
+
+
+/********************
+ ** Event handlers **
+ ********************/
+
+class Scout::Drag_event_handler : public Event_handler
+{
+ protected:
+
+ int _key_cnt; /* number of curr. pressed keys */
+ Point _current_mouse_position;
+ Point _old_mouse_position;
+
+ virtual void start_drag() = 0;
+ virtual void do_drag() = 0;
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Drag_event_handler() { _key_cnt = 0; }
+
+ /**
+ * Event handler interface
+ */
+ void handle(Event &ev)
+ {
+ if (ev.type == Event::PRESS) _key_cnt++;
+ if (ev.type == Event::RELEASE) _key_cnt--;
+
+ if (_key_cnt == 0) return;
+
+ /* first click starts dragging */
+ if ((ev.type == Event::PRESS) && (_key_cnt == 1)) {
+ _current_mouse_position = _old_mouse_position = ev.mouse_position;
+ start_drag();
+ }
+
+ /* check if mouse was moved */
+ if ((ev.mouse_position.x() == _current_mouse_position.x())
+ && (ev.mouse_position.y() == _current_mouse_position.y()))
+ return;
+
+ /* remember current mouse position */
+ _current_mouse_position = ev.mouse_position;
+
+ do_drag();
+ }
+};
+
+
+class Scout::Sizer_event_handler : public Drag_event_handler
+{
+ protected:
+
+ Window *_window;
+ int _obw, _obh; /* original window size */
+
+ /**
+ * Event handler interface
+ */
+ void start_drag()
+ {
+ _obw = _window->view_w();
+ _obh = _window->view_h();
+ }
+
+ void do_drag()
+ {
+ /* calculate new window size */
+ int nbw = _obw + _current_mouse_position.x() - _old_mouse_position.x();
+ int nbh = _obh + _current_mouse_position.y() - _old_mouse_position.y();
+
+ _window->format(Area(nbw, nbh));
+ }
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Sizer_event_handler(Window *window)
+ {
+ _window = window;
+ }
+};
+
+
+class Scout::Mover_event_handler : public Drag_event_handler
+{
+ protected:
+
+ Window *_window;
+ int _obx, _oby; /* original launchpad position */
+
+ void start_drag()
+ {
+ _obx = _window->view_x();
+ _oby = _window->view_y();
+ _window->top();
+ }
+
+ void do_drag()
+ {
+ int nbx = _obx + _current_mouse_position.x() - _old_mouse_position.x();
+ int nby = _oby + _current_mouse_position.y() - _old_mouse_position.y();
+
+ _window->vpos(nbx, nby);
+ }
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Mover_event_handler(Window *window)
+ {
+ _window = window;
+ }
+};
+
+#endif /* _INCLUDE__SCOUT__WINDOW_H_ */
diff --git a/demo/include/scout_gfx/horizontal_shadow_painter.h b/demo/include/scout_gfx/horizontal_shadow_painter.h
new file mode 100644
index 0000000000..1c6179ecef
--- /dev/null
+++ b/demo/include/scout_gfx/horizontal_shadow_painter.h
@@ -0,0 +1,77 @@
+/*
+ * \brief Functor for drawing a horizonatal shadow onto a surface
+ * \author Norman Feske
+ * \date 2005-10-24
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT_GFX__HORIZONTAL_SHADOW_PAINTER_H_
+#define _INCLUDE__SCOUT_GFX__HORIZONTAL_SHADOW_PAINTER_H_
+
+#include
+
+struct Horizontal_shadow_painter
+{
+ typedef Genode::Surface_base::Rect Rect;
+
+ template
+ static inline void paint(Genode::Surface &surface, Rect rect,
+ int intensity)
+ {
+ PT *addr = surface.addr();
+
+ if (!addr) return;
+
+ const int cx1 = surface.clip().x1();
+ const int cy1 = surface.clip().y1();
+ const int cx2 = surface.clip().x2();
+ const int cy2 = surface.clip().y2();
+
+ int x = rect.x1();
+ int y = rect.y1();
+ int w = rect.w();
+ int h = rect.h();
+
+ int curr_a = intensity;
+ int step = rect.h() ? (curr_a/rect.h()) : 0;
+
+ if (x < cx1) {
+ w -= cx1 - x;
+ x = cx1;
+ }
+
+ if (y < cy1) {
+ h -= cy1 - y;
+ curr_a -= (cy1 - y)*step;
+ y = cy1;
+ }
+
+ if (w > cx2 - x + 1)
+ w = cx2 - x + 1;
+
+ if (h > cy2 - y + 1)
+ h = cy2 - y + 1;
+
+ addr += surface.size().w()*y + x;
+
+ PT shadow_color(0,0,0);
+
+ for (int j = 0; j < h; j++, addr += surface.size().w()) {
+
+ PT *d = addr;
+
+ for (int i = 0; i < w; i++, d++)
+ *d = PT::mix(*d, shadow_color, curr_a);
+
+ curr_a -= step;
+ }
+ }
+};
+
+#endif /* _INCLUDE__SCOUT_GFX__HORIZONTAL_SHADOW_PAINTER_H_ */
diff --git a/demo/include/scout_gfx/icon_painter.h b/demo/include/scout_gfx/icon_painter.h
new file mode 100644
index 0000000000..f64b139d28
--- /dev/null
+++ b/demo/include/scout_gfx/icon_painter.h
@@ -0,0 +1,270 @@
+/*
+ * \brief Functor for drawing an icon onto a surface
+ * \author Norman Feske
+ * \date 2005-10-24
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT_GFX__ICON_PAINTER_H_
+#define _INCLUDE__SCOUT_GFX__ICON_PAINTER_H_
+
+#include
+
+class Icon_painter
+{
+ private:
+
+ /*
+ * An Icon has the following layout:
+ *
+ * P1---+--------+----+
+ * | cs | hs | cs | top row
+ * +----P2-------+----+
+ * | | | |
+ * | vs | | vs | mid row
+ * | | | |
+ * +----+--------P3---+
+ * | cs | hs | cs | low row
+ * +------------------P4
+ *
+ * cs ... corner slice
+ * hs ... horizontal slice
+ * vs ... vertical slice
+ */
+
+
+ /**
+ * Copy pixel with alpha
+ */
+ template
+ static inline void _transfer_pixel(PT const &src, int src_a, int alpha, PT *dst)
+ {
+ if (src_a) {
+ int register a = (src_a * alpha)>>8;
+ if (a) *dst = PT::mix(*dst, src, a);
+ }
+ }
+
+
+ /**
+ * Draw corner slice
+ */
+ template
+ static void _draw_cslice(PT const *src, unsigned char const *src_a,
+ unsigned src_pitch, int alpha, PT *dst,
+ unsigned dst_pitch, int w, int h)
+ {
+ for (int j = 0; j < h; j++) {
+
+ PT const *s = src;
+ unsigned char const *sa = src_a;
+ PT *d = dst;
+
+ for (int i = 0; i < w; i++, s++, sa++, d++)
+ _transfer_pixel(*s, *sa, alpha, d);
+
+ src += src_pitch, src_a += src_pitch, dst += dst_pitch;
+ }
+ }
+
+
+ /**
+ * Draw horizontal slice
+ */
+ template
+ static void _draw_hslice(PT const *src, unsigned char const *src_a,
+ int src_pitch, int alpha, PT *dst,
+ int dst_pitch, int w, int h)
+ {
+ for (int j = 0; j < h; j++) {
+
+ PT s = *src;
+ int sa = *src_a;
+ PT *d = dst;
+
+ for (int i = 0; i < w; i++, d++)
+ _transfer_pixel(s, sa, alpha, d);
+
+ src += src_pitch, src_a += src_pitch, dst += dst_pitch;
+ }
+ }
+
+
+ /**
+ * Draw vertical slice
+ */
+ template
+ static void _draw_vslice(PT const *src, unsigned char const *src_a,
+ int src_pitch, int alpha, PT *dst,
+ int dst_pitch, int w, int h)
+ {
+ for (int i = 0; i < w; i++) {
+
+ PT s = *src;
+ int sa = *src_a;
+ PT *d = dst;
+
+ for (int j = 0; j < h; j++, d += dst_pitch)
+ _transfer_pixel(s, sa, alpha, d);
+
+ src += 1, src_a += 1, dst += 1;
+ }
+ }
+
+
+ /**
+ * Draw center slice
+ */
+ template
+ static void _draw_center(PT const *src, unsigned char const *src_a,
+ int src_pitch, int alpha, PT *dst,
+ int dst_pitch, int w, int h)
+ {
+ PT s = *src;
+ int sa = *src_a;
+
+ for (int j = 0; j < h; j++, dst += dst_pitch) {
+
+ PT *d = dst;
+
+ for (int i = 0; i < w; i++, d++)
+ _transfer_pixel(s, sa, alpha, d);
+ }
+ }
+
+
+ /**
+ * Clip rectangle against clipping region
+ *
+ * The out parameters are the resulting x/y offsets and the
+ * visible width and height.
+ *
+ * \return 1 if rectangle intersects with clipping region,
+ * 0 otherwise
+ */
+ static inline int _clip(int px1, int py1, int px2, int py2,
+ int cx1, int cy1, int cx2, int cy2,
+ int *out_x, int *out_y, int *out_w, int *out_h)
+ {
+ /* determine intersection of rectangle and clipping region */
+ int x1 = Genode::max(px1, cx1);
+ int y1 = Genode::max(py1, cy1);
+ int x2 = Genode::min(px2, cx2);
+ int y2 = Genode::min(py2, cy2);
+
+ *out_w = x2 - x1 + 1;
+ *out_h = y2 - y1 + 1;
+ *out_x = x1 - px1;
+ *out_y = y1 - py1;
+
+ return (*out_w > 0) && (*out_h > 0);
+ }
+
+ public:
+
+ typedef Genode::Surface_base::Area Area;
+ typedef Genode::Surface_base::Rect Rect;
+
+
+ template
+ static inline void paint(Genode::Surface &surface, Rect rect,
+ Genode::Texture const &icon, unsigned alpha)
+ {
+ PT *addr = surface.addr();
+
+ if (!addr || (alpha == 0)) return;
+
+ int const cx1 = surface.clip().x1();
+ int const cy1 = surface.clip().y1();
+ int const cx2 = surface.clip().x2();
+ int const cy2 = surface.clip().y2();
+
+ unsigned const icon_w = icon.size().w(),
+ icon_h = icon.size().h();
+
+ /* determine point positions */
+ int const x1 = rect.x1();
+ int const y1 = rect.y1();
+ int const x4 = x1 + rect.w() - 1;
+ int const y4 = y1 + rect.h() - 1;
+ int const x2 = x1 + icon_w/2;
+ int const y2 = y1 + icon_h/2;
+ int const x3 = Genode::max(x4 - (int)icon_w/2, x2);
+ int const y3 = Genode::max(y4 - (int)icon_h/2, y2);
+
+ int const tx1 = 0;
+ int const ty1 = 0;
+ int const tx4 = icon_w - 1;
+ int const ty4 = icon_h - 1;
+ int const tx2 = icon_w/2;
+ int const ty2 = icon_h/2;
+ int const tx3 = Genode::max(tx4 - (int)icon_w/2, tx2);
+ int const ty3 = Genode::max(ty4 - (int)icon_h/2, ty2);
+
+ PT const *src = icon.pixel() + icon_w*ty1;
+ unsigned char const *src_a = icon.alpha() + icon_w*ty1;
+ int dx, dy, w, h;
+
+ /*
+ * top row
+ */
+
+ if (_clip(x1, y1, x2 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_cslice(src + tx1 + dy*icon_w + dx, src_a + tx1 + dy*icon_w + dx, icon_w, alpha,
+ addr + (y1 + dy)*surface.size().w() + x1 + dx, surface.size().w(), w, h);
+
+ if (_clip(x2, y1, x3 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_hslice(src + tx2 + dy*icon_w + dx, src_a + tx2 + dy*icon_w + dx, icon_w, alpha,
+ addr + (y1 + dy)*surface.size().w() + x2 + dx, surface.size().w(), w, h);
+
+ if (_clip(x3, y1, x4, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_cslice(src + tx3 + dy*icon_w + dx, src_a + tx3 + dy*icon_w + dx, icon_w, alpha,
+ addr + (y1 + dy)*surface.size().w() + x3 + dx, surface.size().w(), w, h);
+
+ /*
+ * mid row
+ */
+
+ src = icon.pixel() + icon_w*ty2;
+ src_a = icon.alpha() + icon_w*ty2;
+
+ if (_clip(x1, y2, x2 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_vslice(src + tx1 + dx, src_a + tx1 + dx, icon_w, alpha,
+ addr + (y2 + dy)*surface.size().w() + x1 + dx, surface.size().w(), w, h);
+
+ if (_clip(x2, y2, x3 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_center(src + tx2, src_a + tx2, icon_w, alpha,
+ addr + (y2 + dy)*surface.size().w() + x2 + dx, surface.size().w(), w, h);
+
+ if (_clip(x3, y2, x4, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_vslice(src + tx3 + dx, src_a + tx3 + dx, icon_w, alpha,
+ addr + (y2 + dy)*surface.size().w() + x3 + dx, surface.size().w(), w, h);
+
+ /*
+ * low row
+ */
+
+ src = icon.pixel() + icon_w*ty3;
+ src_a = icon.alpha() + icon_w*ty3;
+
+ if (_clip(x1, y3, x2 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_cslice(src + tx1 + dy*icon_w + dx, src_a + tx1 + dy*icon_w + dx, icon_w, alpha,
+ addr + (y3 + dy)*surface.size().w() + x1 + dx, surface.size().w(), w, h);
+
+ if (_clip(x2, y3, x3 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_hslice(src + tx2 + dy*icon_w + dx, src_a + tx2 + dy*icon_w + dx, icon_w, alpha,
+ addr + (y3 + dy)*surface.size().w() + x2 + dx, surface.size().w(), w, h);
+
+ if (_clip(x3, y3, x4, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
+ _draw_cslice(src + tx3 + dy*icon_w + dx, src_a + tx3 + dy*icon_w + dx, icon_w, alpha,
+ addr + (y3 + dy)*surface.size().w() + x3 + dx, surface.size().w(), w, h);
+ }
+};
+
+#endif /* _INCLUDE__SCOUT_GFX__ICON_PAINTER_H_ */
diff --git a/demo/include/scout_gfx/random.h b/demo/include/scout_gfx/random.h
new file mode 100644
index 0000000000..389435e1f5
--- /dev/null
+++ b/demo/include/scout_gfx/random.h
@@ -0,0 +1,31 @@
+/*
+ * \brief Pseudo random-number generator
+ * \date 2005-10-24
+ * \author Norman Feske
+ */
+
+/*
+ * Copyright (C) 2005-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 _INCLUDE__SCOUT_GFX__RANDOM_H_
+#define _INCLUDE__SCOUT_GFX__RANDOM_H_
+
+namespace Scout {
+
+ /**
+ * Produce pseudo random values
+ */
+ static inline int random()
+ {
+ static unsigned int seed = 93186752;
+ const unsigned int a = 1588635695, q = 2, r = 1117695901;
+ seed = a*(seed % q) - r*(seed / q);
+ return seed;
+ }
+}
+
+#endif /* _INCLUDE__SCOUT_GFX__RANDOM_H_ */
diff --git a/demo/include/scout_gfx/refracted_icon_painter.h b/demo/include/scout_gfx/refracted_icon_painter.h
new file mode 100644
index 0000000000..3a332d83a9
--- /dev/null
+++ b/demo/include/scout_gfx/refracted_icon_painter.h
@@ -0,0 +1,170 @@
+/*
+ * \brief Functor for drawing a refracted icon onto a surface
+ * \author Norman Feske
+ * \date 2005-10-24
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT_GFX__REFRACTED_ICON_PAINTER_H_
+#define _INCLUDE__SCOUT_GFX__REFRACTED_ICON_PAINTER_H_
+
+#include
+#include
+#include
+
+namespace Scout { struct Refracted_icon_painter; }
+
+/*
+ * NOTE: There is no support for clipping.
+ * Use this code with caution!
+ */
+struct Scout::Refracted_icon_painter
+{
+ typedef Genode::Surface_base::Point Point;
+ typedef Genode::Surface_base::Area Area;
+ typedef Genode::Surface_base::Rect Rect;
+
+
+ template
+ class Distmap
+ {
+ private:
+
+ Area _size;
+ DT const *_base;
+
+ public:
+
+ Distmap(DT *base, Area size) : _size(size), _base(base) { }
+
+ Area size() const { return _size; }
+ DT const *base() const { return _base; }
+ };
+
+
+ /**
+ * Copy and distort back-buffer pixels to front buffer
+ */
+ template
+ static void distort(PT const *src, DT const *distmap,
+ int distmap_w, int distmap_h,
+ PT const *fg, unsigned char const *alpha,
+ PT *dst, int dst_w, int width)
+ {
+ int line_offset = (distmap_w>>1) - width;
+ width <<= 1;
+
+ for (int j = 0; j < distmap_h; j += 2, dst += dst_w) {
+
+ PT *d = dst;
+
+ for (int i = 0; i < width; i += 2, src += 2, distmap += 2) {
+
+ /* fetch distorted pixel from back buffer */
+ PT v = PT::avr(src[distmap[0]],
+ src[distmap[1] + 1],
+ src[distmap[distmap_w] + distmap_w],
+ src[distmap[distmap_w + 1] + distmap_w + 1]);
+
+ /* mix back-buffer pixel with foreground */
+ *d++ = PT::mix(v, *fg++, *alpha++);
+ }
+
+ fg += line_offset;
+ alpha += line_offset;
+ src += line_offset*2 + distmap_w; /* skip one line in back buffer */
+ distmap += line_offset*2 + distmap_w; /* skip one line in distmap */
+ }
+ }
+
+
+ /**
+ * Copy back-buffer pixels to front buffer
+ */
+ template
+ static void copy(PT const *src, int src_w, PT *dst, int dst_w, int w, int h)
+ {
+ for (int j = 0; j < h; j ++, src += src_w, dst += dst_w)
+ Genode::memcpy(dst, src, w*sizeof(PT));
+ }
+
+
+ /**
+ * Backup original (background) pixel data into back buffer
+ */
+ template
+ static void filter_src_to_backbuf(PT const *src, int src_w,
+ PT *dst, int dst_w, int dst_h, int width)
+ {
+ for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w) {
+ for (int i = 0; i < width; i++) {
+ dst[2*i] = src[i];
+ dst[2*i + 1] = PT::avr(src[i], src[i + 1]);
+ dst[2*i + dst_w] = PT::avr(src[i], src[i + src_w]);
+ dst[2*i + dst_w + 1] = PT::avr(dst[2*i + dst_w], dst[2*i + 1]);
+ }
+ }
+ }
+
+
+ /**
+ * Backup original (background) pixel data into back buffer
+ */
+ template
+ static void copy_src_to_backbuf(PT *src, int src_w,
+ PT *dst, int dst_w, int dst_h, int width)
+ {
+ for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w)
+ for (int i = 0; i < width; i++)
+ dst[2*i] = dst[2*i + 1] = dst[2*i + dst_w] = dst[2*i + dst_w + 1] = src[i];
+ }
+
+
+ /*
+ * The distmap and tmp textures must be dimensioned with twice the height
+ * and width of the foreground.
+ */
+ template
+ static inline void paint(Genode::Surface &surface,
+ Point pos,
+ Distmap const &distmap,
+ Genode::Texture &tmp,
+ Genode::Texture const &foreground,
+ bool detail,
+ bool filter_backbuf)
+ {
+ PT *dst = surface.addr() + surface.size().w()*(pos.y()) + pos.x();
+
+ Rect const clipped = Rect::intersect(surface.clip(), Rect(pos, foreground.size()));
+
+ if (detail == false) {
+ copy(foreground.pixel(), foreground.size().w(),
+ dst, surface.size().w(), clipped.w(), foreground.size().h());
+ return;
+ }
+
+ /* backup old canvas pixels */
+ if (filter_backbuf)
+ filter_src_to_backbuf(dst, surface.size().w(), tmp.pixel(),
+ tmp.size().w(), tmp.size().h(),
+ foreground.size().w());
+ else
+ copy_src_to_backbuf(dst, surface.size().w(),
+ tmp.pixel(), tmp.size().w(),
+ tmp.size().h(), foreground.size().w());
+
+ /* draw distorted pixels back to canvas */
+ distort(tmp.pixel(),
+ distmap.base(), distmap.size().w(), distmap.size().h(),
+ foreground.pixel(), foreground.alpha(),
+ dst, surface.size().w(), clipped.w());
+ }
+};
+
+#endif /* _INCLUDE__SCOUT_GFX__REFRACTED_ICON_PAINTER_H_ */
diff --git a/demo/include/scout_gfx/sky_texture_painter.h b/demo/include/scout_gfx/sky_texture_painter.h
new file mode 100644
index 0000000000..0a6f4acf7c
--- /dev/null
+++ b/demo/include/scout_gfx/sky_texture_painter.h
@@ -0,0 +1,264 @@
+/*
+ * \brief Functor for drawing a sky texture into a surface
+ * \author Norman Feske
+ * \date 2005-10-24
+ */
+
+/*
+ * 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 _INCLUDE__SCOUT_GFX__SKY_TEXTURE_PAINTER_H_
+#define _INCLUDE__SCOUT_GFX__SKY_TEXTURE_PAINTER_H_
+
+#include
+#include
+
+
+struct Sky_texture_painter
+{
+ typedef Genode::Surface_base::Area Area;
+ typedef Genode::Surface_base::Rect Rect;
+ typedef Genode::Color Color;
+
+
+ template
+ static void _compose(PT *dst, int dst_w, int dst_h, int x_start, int x_end,
+ short const src1[], int src1_y,
+ short const src2[], int src2_y,
+ short const src3[], int src3_y, int src_w, int src_h,
+ PT const coltab[])
+ {
+ for (int k = 0; k <= x_end; k += src_w) {
+
+ int x_offset = Genode::max(0, x_start - k);
+ int x_max = Genode::min(x_end - k, src_w - 1);
+
+ for (int j = 0; j < dst_h; j++) {
+
+ short const *s1 = src1 + x_offset + ((src1_y + j)%src_h)*src_w;
+ short const *s2 = src2 + x_offset + ((src2_y + j)%src_h)*src_w;
+ short const *s3 = src3 + x_offset + ((src3_y + j)%src_h)*src_w;
+ PT *d = dst + x_offset + j*dst_w + k;
+
+ for (int i = x_offset; i <= x_max; i++)
+ *d++ = coltab[*s1++ + *s2++ + *s3++];
+ }
+ }
+ }
+
+
+ class Sky_texture_base
+ {
+ protected:
+
+ static void _brew_texture(short tmp[], short tmp2[], short dst[], int w, int h,
+ int lf_start, int lf_end, int lf_incr, int lf_mul,
+ int hf_val, int hf_mul);
+
+ /**
+ * Multiply buffer values with 24:8 fixpoint value
+ */
+ static void _multiply_buf(short dst[], int len, int factor)
+ {
+ for (int i = 0; i < len; i++)
+ dst[i] = (dst[i]*factor)>>8;
+ }
+
+ static inline int _mix_channel(int value1, int value2, int alpha)
+ {
+ return (value1*(255 - alpha) + value2*alpha)>>8;
+ }
+ };
+
+
+ template
+ class Sky_texture : public Sky_texture_base
+ {
+ private:
+
+ Area _size;
+
+ public:
+
+ Sky_texture(Area size) : _size(size) { }
+
+ virtual PT const *fallback() const = 0;
+ virtual short const *buf(unsigned i) const = 0;
+ virtual PT const *coltab() const = 0;
+
+ Area size() const { return _size; }
+ };
+
+
+ /*
+ * The texture is composed of four generated 4-bit maps based on bicubic
+ * interpolation of some noise at different frequencies. At runtime, we
+ * overlay (add their values) the generated map and use the result as index
+ * of a color table.
+ */
+ template
+ class Static_sky_texture : public Sky_texture
+ {
+ private:
+
+ short _bufs[3][TH][TW];
+ short _buf[TH][TW];
+ short _tmp[TH][TW];
+ PT _coltab[16*16*16];
+ PT _fallback[TH][TW]; /* fallback texture */
+
+ using Sky_texture::_mix_channel;
+ using Sky_texture::_brew_texture;
+ using Sky_texture::_multiply_buf;
+
+ public:
+
+ /**
+ * Create 3D color table
+ */
+ static void _create_coltab(PT *dst, Color c0, Color c1, Color c2, Color bg)
+ {
+ for (int i = 0; i < 16; i++)
+ for (int j = 0; j < 16; j++)
+ for (int k = 0; k < 16; k++) {
+
+ int r = bg.r;
+ int g = bg.g;
+ int b = bg.b;
+
+ r = _mix_channel(r, c2.r, k*16);
+ g = _mix_channel(g, c2.g, k*16);
+ b = _mix_channel(b, c2.b, k*16);
+
+ r = _mix_channel(r, c1.r, j*16);
+ g = _mix_channel(g, c1.g, j*16);
+ b = _mix_channel(b, c1.b, j*16);
+
+ r = _mix_channel(r, c0.r, i*8);
+ g = _mix_channel(g, c0.g, i*8);
+ b = _mix_channel(b, c0.b, i*8);
+
+ int v = (((i ^ j ^ k)<<1) & 0xff) + 128 + 64;
+
+ r = (r + v)>>1;
+ g = (g + v)>>1;
+ b = (b + v)>>1;
+
+ v = 180;
+ r = (v*r + (255 - v)*255)>>8;
+ g = (v*g + (255 - v)*255)>>8;
+ b = (v*b + (255 - v)*255)>>8;
+
+ dst[(k<<8) + (j<<4) + i].rgba(r, g, b);
+ }
+ }
+
+
+
+ /**
+ * Constructor
+ */
+ Static_sky_texture()
+ :
+ Sky_texture(Area(TW, TH))
+ {
+ /* create nice-looking textures */
+ _brew_texture(_tmp[0], _buf[0], _bufs[0][0], TW, TH, 3, 7, 1, 30, 30, 10);
+ _brew_texture(_tmp[0], _buf[0], _bufs[1][0], TW, TH, 3, 16, 3, 50, 40, 30);
+ _brew_texture(_tmp[0], _buf[0], _bufs[2][0], TW, TH, 5, 40, 11, 70, 0, 0);
+
+ /* shift texture 1 to bits 4 to 7 */
+ _multiply_buf(_bufs[1][0], TW*TH, 16*256);
+
+ /* shift texture 2 to bits 8 to 11 */
+ _multiply_buf(_bufs[2][0], TW*TH, 16*16*256);
+
+ /* create color table */
+ _create_coltab(_coltab, Color(255, 255, 255),
+ Color( 0, 0, 0),
+ Color(255, 255, 255),
+ Color( 80, 88, 112));
+
+ /* create fallback texture */
+ _compose(_fallback[0], TW, TH, 0, TW - 1,
+ _bufs[0][0], 0, _bufs[1][0], 0, _bufs[2][0], 0,
+ TW, TH, _coltab);
+ }
+
+ PT const *fallback() const { return _fallback[0]; }
+
+ short const *buf(unsigned i) const
+ {
+ if (i >= 3)
+ return 0;
+
+ return _bufs[i][0];
+ }
+
+ PT const *coltab() const { return _coltab; }
+ };
+
+
+ template
+ static void _copy(PT *dst, int dst_w, int dst_h, int x_start, int x_end,
+ PT const *src, int src_y, int src_w, int src_h)
+ {
+ for (int k = 0; k <= x_end; k += src_w) {
+
+ int x_offset = Genode::max(0, x_start - k);
+ int x_max = Genode::min(x_end - k, src_w - 1);
+
+ for (int j = 0; j < dst_h; j++) {
+
+ PT const *s = src + x_offset + ((src_y + j)%src_h)*src_w;
+ PT *d = dst + x_offset + j*dst_w + k;
+
+ if (x_max - x_offset >= 0)
+ Genode::memcpy(d, s, (x_max - x_offset + 1)*sizeof(PT));
+ }
+ }
+ }
+
+
+ template
+ static inline void paint(Genode::Surface &surface, int py,
+ Sky_texture_base const &texture_base,
+ bool detail)
+ {
+ PT *addr = surface.addr();
+
+ if (!addr) return;
+
+ Sky_texture const &texture = static_cast const &>(texture_base);
+
+ int cx1 = surface.clip().x1();
+ int cy1 = surface.clip().y1();
+ int cx2 = surface.clip().x2();
+ int cy2 = surface.clip().y2();
+
+ int v = -py;
+ int y0 = cy1 + v;
+ int y1 = cy1 + (( (5*v)/16)%texture.size().h());
+ int y2 = cy1 + (((11*v)/16)%texture.size().h());
+
+ addr += cy1*surface.size().w();
+
+ if (detail == false) {
+ _copy(addr, surface.size().w(), cy2 - cy1 + 1, cx1, cx2,
+ texture.fallback(), cy1 - py, texture.size().w(), texture.size().h());
+ return;
+ }
+
+ _compose(addr, surface.size().w(), cy2 - cy1 + 1, cx1, cx2,
+ texture.buf(0), y0, texture.buf(1), y1, texture.buf(2), y2,
+ texture.size().w(), texture.size().h(), texture.coltab());
+
+ surface.flush_pixels(surface.clip());
+ }
+};
+
+#endif /* _INCLUDE__SCOUT_GFX__SKY_TEXTURE_PAINTER_H_ */
diff --git a/demo/lib/mk/scout_gfx.mk b/demo/lib/mk/scout_gfx.mk
new file mode 100644
index 0000000000..14cf3d77b5
--- /dev/null
+++ b/demo/lib/mk/scout_gfx.mk
@@ -0,0 +1,3 @@
+SRC_CC = sky_texture_painter.cc
+
+vpath %.cc $(REP_DIR)/src/lib/scout_gfx
diff --git a/demo/lib/mk/scout_widgets.mk b/demo/lib/mk/scout_widgets.mk
index 4126d6eea2..04191e2fa6 100644
--- a/demo/lib/mk/scout_widgets.mk
+++ b/demo/lib/mk/scout_widgets.mk
@@ -1,23 +1,12 @@
-LIBS = base blit
-
-SRC_CC = sky_texture.cc startup.cc \
- elements.cc widgets.cc \
- tick.cc scrollbar.cc \
- refracted_icon.cc
-
-SRC_CC += platform_genode.cc
+LIBS = base blit scout_gfx
+SRC_CC = tick.cc elements.cc widgets.cc scrollbar.cc
SCOUT_DIR = $(REP_DIR)/src/app/scout
-INC_DIR += $(SCOUT_DIR)/include \
- $(SCOUT_DIR)/include/genode
-
-vpath % $(SCOUT_DIR)/data
-vpath %.cc $(SCOUT_DIR)/common
-vpath startup.cc $(SCOUT_DIR)/genode
-vpath launcher.cc $(SCOUT_DIR)/genode
-vpath platform_genode.cc $(SCOUT_DIR)/genode
+INC_DIR += $(SCOUT_DIR)/include
+vpath % $(SCOUT_DIR)/data
+vpath %.cc $(SCOUT_DIR)
SRC_TFF = vera16.tff \
verai16.tff \
diff --git a/demo/src/app/launchpad/child_entry.h b/demo/src/app/launchpad/child_entry.h
index 3cb08893b1..27256bf848 100644
--- a/demo/src/app/launchpad/child_entry.h
+++ b/demo/src/app/launchpad/child_entry.h
@@ -28,7 +28,7 @@ extern unsigned char OPENED_ICON_RGBA[];
extern unsigned char CLOSED_ICON_RGBA[];
-class Kill_event_handler : public Event_handler
+class Kill_event_handler : public Scout::Event_handler
{
private:
@@ -43,10 +43,12 @@ class Kill_event_handler : public Event_handler
/**
* Event handler interface
*/
- void handle(Event &ev)
+ void handle(Scout::Event &ev)
{
static int key_cnt;
+ using Scout::Event;
+
if (ev.type == Event::PRESS) key_cnt++;
if (ev.type == Event::RELEASE) key_cnt--;
@@ -57,7 +59,8 @@ class Kill_event_handler : public Event_handler
template
-class Child_entry : public Parent_element, public Genode::List >::Element
+class Child_entry : public Scout::Parent_element,
+ public Genode::List >::Element
{
private:
@@ -67,13 +70,13 @@ class Child_entry : public Parent_element, public Genode::List >
enum { _PADX = 10 }; /* horizontal padding */
enum { _NAME_LEN = 64 }; /* max length of child name */
- Block _block;
+ Scout::Block _block;
Kbyte_loadbar _loadbar;
char _name[_NAME_LEN];
- Fade_icon _kill_icon;
- Fade_icon _fold_icon;
+ Scout::Fade_icon _kill_icon;
+ Scout::Fade_icon _fold_icon;
Kill_event_handler _kill_event_handler;
@@ -85,11 +88,11 @@ class Child_entry : public Parent_element, public Genode::List >
Child_entry(const char *name, int quota_kb, int max_quota_kb,
Launchpad *launchpad, Launchpad_child *launchpad_child)
:
- _block(Block::RIGHT), _loadbar(0, &label_font),
+ _block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font),
_kill_event_handler(launchpad, launchpad_child)
{
Genode::strncpy(_name, name, sizeof(_name));
- _block.append_plaintext(_name, &plain_style);
+ _block.append_plaintext(_name, &Scout::plain_style);
_loadbar.max_value(max_quota_kb);
_loadbar.value(quota_kb);
@@ -108,7 +111,7 @@ class Child_entry : public Parent_element, public Genode::List >
append(&_kill_icon);
append(&_fold_icon);
- _min_w = _PTW + 100;
+ _min_size = Scout::Area(_PTW + 100, _min_size.h());
}
@@ -124,22 +127,25 @@ class Child_entry : public Parent_element, public Genode::List >
void format_fixed_width(int w)
{
+ using namespace Scout;
+
_block.format_fixed_width(_PTW);
- int bh = _block.min_h();
- int iy = max(0, (bh - _loadbar.min_h())/2);
+ int bh = _block.min_size().h();
+ int iy = max(0U, (bh - _loadbar.min_size().h())/2);
- _fold_icon.geometry(0, iy, _IW, _IH);
- _kill_icon.geometry(w - _IW - 8, iy, _IW, _IH);
+ _fold_icon.geometry(Rect(Point(0, iy), Area(_IW, _IH)));
+ _kill_icon.geometry(Rect(Point(w - _IW - 8, iy), Area(_IW, _IH)));
- _block.geometry(max(10, _PTW - _block.min_w()),
- max(0, (bh - _block.min_h())/2),
- min((int)_PTW, _block.min_w()), bh);
+ _block.geometry(Rect(Point(max(10, _PTW - (int)_block.min_size().w()),
+ max(0, (bh - (int)_block.min_size().h())/2)),
+ Area(min((int)_PTW,
+ (int)_block.min_size().w()), bh)));
int lw = w - 2*_PADX - _PTW - _IW;
_loadbar.format_fixed_width(lw);
- _loadbar.geometry(_PADX + _PTW, iy, lw, 16);
- _min_h = bh;
- _min_w = w;
+ _loadbar.geometry(Rect(Point(_PADX + _PTW, iy), Area(lw, 16)));
+
+ _min_size = Scout::Area(w, bh);
}
};
diff --git a/demo/src/app/launchpad/launch_entry.h b/demo/src/app/launchpad/launch_entry.h
index 0408fe17dd..8e0ef5f836 100644
--- a/demo/src/app/launchpad/launch_entry.h
+++ b/demo/src/app/launchpad/launch_entry.h
@@ -18,15 +18,15 @@
#include "launcher_config.h"
template
-class Launch_entry : public Parent_element, public Loadbar_listener
+class Launch_entry : public Scout::Parent_element, public Loadbar_listener
{
private:
- Block _block;
- Kbyte_loadbar _loadbar;
- Launcher_config _config;
- Launcher _launcher;
- int _lh; /* launch entry height */
+ Scout::Block _block;
+ Kbyte_loadbar _loadbar;
+ Scout::Launcher_config _config;
+ Scout::Launcher _launcher;
+ int _lh; /* launch entry height */
enum { _PTW = 100 }; /* program text width */
enum { _PADX = 10 }; /* program text width */
@@ -40,16 +40,19 @@ class Launch_entry : public Parent_element, public Loadbar_listener
Launch_entry(const char *prg_name, int initial_quota, int max_quota,
Launchpad *launchpad,
Genode::Dataspace_capability config_ds)
- : _block(Block::RIGHT), _loadbar(this, &label_font), _config(config_ds),
- _launcher(prg_name, launchpad, 1024 * initial_quota, &_config)
+ :
+ _block(Scout::Block::RIGHT), _loadbar(this, &Scout::label_font),
+ _config(config_ds),
+ _launcher(prg_name, launchpad, 1024 * initial_quota, &_config)
{
- _block.append_launchertext(prg_name, &link_style, &_launcher);
+ _block.append_launchertext(prg_name, &Scout::link_style, &_launcher);
_loadbar.max_value(max_quota);
_loadbar.value(initial_quota);
append(&_loadbar);
append(&_block);
- _min_w = _PTW + 100;
+
+ _min_size = Scout::Area(_PTW + 100, _min_size.h());
}
@@ -59,7 +62,7 @@ class Launch_entry : public Parent_element, public Loadbar_listener
void loadbar_changed(int mx)
{
- int value = _loadbar.value_by_xpos(mx - _loadbar.abs_x());
+ int value = _loadbar.value_by_xpos(mx - _loadbar.abs_position().x());
_loadbar.value(value);
_loadbar.refresh();
_launcher.quota(1024 * (unsigned long)value);
@@ -72,18 +75,20 @@ class Launch_entry : public Parent_element, public Loadbar_listener
void format_fixed_width(int w)
{
+ using namespace Scout;
+
_block.format_fixed_width(_PTW);
- _lh = _block.min_h();
- _block.geometry(max(10, _PTW - _block.min_w()),
- max(0, (_lh - _block.min_h())/2),
- min((int)_PTW, _block.min_w()), _lh);
+ _lh = _block.min_size().h();
+ _block.geometry(Rect(Point(max(10U, _PTW - _block.min_size().w()),
+ max(0U, (_lh - _block.min_size().h())/2)),
+ Area(min((unsigned)_PTW, _block.min_size().w()), _lh)));
int lw = max(0, w - 2*_PADX - _PTW - _PADR);
- int ly = max(0, (_lh - _loadbar.min_h())/2);
+ int ly = max(0U, (_lh - _loadbar.min_size().h())/2);
_loadbar.format_fixed_width(lw);
- _loadbar.geometry(_PADX + _PTW, ly, lw, 16);
- _min_h = _lh;
- _min_w = w;
+ _loadbar.geometry(Rect(Point(_PADX + _PTW, ly), Area(lw, 16)));
+
+ _min_size = Scout::Area(w, _lh);
}
};
diff --git a/demo/src/app/launchpad/launcher.cc b/demo/src/app/launchpad/launcher.cc
index 15266fd0d6..1e31e1089a 100644
--- a/demo/src/app/launchpad/launcher.cc
+++ b/demo/src/app/launchpad/launcher.cc
@@ -15,10 +15,8 @@
#include "elements.h"
#include "launcher_config.h"
+using namespace Scout;
-/************************
- ** Launcher interface **
- ************************/
void Launcher::launch()
{
diff --git a/demo/src/app/launchpad/launchpad_window.cc b/demo/src/app/launchpad/launchpad_window.cc
index 4ed2984af0..ed4b25808b 100644
--- a/demo/src/app/launchpad/launchpad_window.cc
+++ b/demo/src/app/launchpad/launchpad_window.cc
@@ -11,10 +11,14 @@
* under the terms of the GNU General Public License version 2.
*/
-#include "miscmath.h"
+#include
+
#include "launchpad_window.h"
#include "styles.h"
+using namespace Scout;
+
+
/****************************
** External graphics data **
****************************/
@@ -31,13 +35,12 @@ extern unsigned char TITLEBAR_RGBA[];
********************************/
template
-Launchpad_window::Launchpad_window(Platform *pf,
- Redraw_manager *redraw,
- int max_w, int max_h,
+Launchpad_window::Launchpad_window(Graphics_backend &gfx_backend,
+ Point position, Area size, Area max_size,
unsigned long initial_quota)
:
Launchpad(initial_quota),
- Window(pf, redraw, max_w, max_h),
+ Window(gfx_backend, position, size, max_size, false),
_docview(0),
_spacer(1, _TH),
_info_section("Status", &subsection_font),
@@ -55,8 +58,7 @@ Launchpad_window::Launchpad_window(Platform *pf,
_titlebar.text("Launchpad");
_titlebar.event_handler(new Mover_event_handler(this));
- _min_w = 200;
- _min_h = 200;
+ _min_size = Scout::Area(200, 200);
_status_entry.max_value(initial_quota / 1024);
@@ -81,15 +83,15 @@ Launchpad_window::Launchpad_window(Platform *pf,
template
void Launchpad_window::ypos_sb(int ypos, int update_scrollbar)
{
- if (ypos < -_docview.h() + _h)
- ypos = -_docview.h() + _h;
+ if (ypos < -(int)(_docview.size().h() + _size.h()))
+ ypos = -_docview.size().h() + _size.h();
_ypos = ypos <= 0 ? ypos : 0;
- _docview.geometry(_docview.x(), _ypos, _docview.w(), _docview.h());
+ _docview.geometry(Rect(Point(_docview.position().x(), _ypos), _docview.size()));
if (update_scrollbar)
- _scrollbar.view(_docview.h(), _h, -_ypos);
+ _scrollbar.view(_docview.size().h(), _size.h(), -_ypos);
refresh();
}
@@ -100,54 +102,57 @@ void Launchpad_window::ypos_sb(int ypos, int update_scrollbar)
*************************/
template
-void Launchpad_window::format(int w, int h)
+void Launchpad_window::format(Scout::Area size)
{
/* limit window size to valid values */
- w = (w < _min_w) ? _min_w : w;
- h = (h < _min_h) ? _min_h : h;
- w = (w > max_w()) ? max_w() : w;
- h = (h > max_h()) ? max_h() : h;
+ unsigned w = size.w();
+ unsigned h = size.h();
+
+ w = max(w, min_size().w());
+ h = max(h, min_size().h());
+ w = min(w, max_size().w());
+ h = min(h, max_size().h());
/* determine old scrollbar visibility */
- int old_sb_visibility = (_docview.min_h() > _h);
+ int old_sb_visibility = (_docview.min_size().h() > _size.h());
/* assign new size to window */
- _w = w;
- _h = h;
+ _size = Scout::Area(w, h);
/* format document */
- _docview.format_fixed_width(_w);
+ _docview.format_fixed_width(_size.w());
/* format titlebar */
- _titlebar.format_fixed_width(_w);
+ _titlebar.format_fixed_width(_size.w());
/* determine new scrollbar visibility */
- int new_sb_visibility = (_docview.min_h() > _h);
+ int new_sb_visibility = (_docview.min_size().h() > _size.h());
/* reformat docview on change of scrollbar visibility */
if (old_sb_visibility ^ new_sb_visibility) {
- _docview.right_pad(new_sb_visibility ? _scrollbar.min_w() : 0);
- _docview.format_fixed_width(_w);
+ _docview.right_pad(new_sb_visibility ? _scrollbar.min_size().w() : 0);
+ _docview.format_fixed_width(_size.w());
}
/* position docview */
- _docview.geometry(0, _ypos, _docview.min_w(), max(_docview.min_h(), _h));
+ _docview.geometry(Rect(Point(0, _ypos),
+ Area(_docview.min_size().w(),
+ max(_docview.min_size().h(), _size.h()))));
/* start at top */
int y = 0;
/* position titlebar */
- _titlebar.geometry(y, 0, _w, _TH);
+ _titlebar.geometry(Rect(Point(y, 0), Area(_size.w(), _TH)));
y += _TH;
- _scrollbar.geometry(w - _scrollbar.min_w() - _SB_XPAD, y + _SB_YPAD,
- _scrollbar.min_w(), h - y - _SB_YPAD*2 - 8);
+ _scrollbar.geometry(Rect(Point(w - _scrollbar.min_size().w() - _SB_XPAD, y + _SB_YPAD),
+ Area(_scrollbar.min_size().w(), h - y - _SB_YPAD*2 - 8)));
- _sizer.geometry(_w - 32, _h - 32, 32, 32);
+ _sizer.geometry(Rect(Point(_size.w() - 32, _size.h() - 32), Area(32, 32)));
- pf()->view_geometry(pf()->vx(), pf()->vy(), _w, _h);
- redraw()->size(_w, _h);
+ Window::format(_size);
ypos(_ypos);
refresh();
}
@@ -169,5 +174,4 @@ void Launchpad_window::handle_scroll(int view_pos)
ypos_sb(-view_pos, 0);
}
-#include "canvas_rgb565.h"
-template class Launchpad_window;
+template class Launchpad_window;
diff --git a/demo/src/app/launchpad/launchpad_window.h b/demo/src/app/launchpad/launchpad_window.h
index b010981cc1..b59ee8c413 100644
--- a/demo/src/app/launchpad/launchpad_window.h
+++ b/demo/src/app/launchpad/launchpad_window.h
@@ -14,13 +14,14 @@
#ifndef _LAUNCHPAD_WINDOW_H_
#define _LAUNCHPAD_WINDOW_H_
+#include
+#include
+
#include "elements.h"
#include "widgets.h"
#include "sky_texture.h"
#include "scrollbar.h"
#include "fade_icon.h"
-#include "platform.h"
-#include "window.h"
#include "titlebar.h"
#include "launch_entry.h"
@@ -32,9 +33,9 @@
#include
template
-class Launchpad_window : public Scrollbar_listener,
+class Launchpad_window : public Scout::Scrollbar_listener,
public Launchpad,
- public Window
+ public Scout::Window
{
private:
@@ -50,20 +51,20 @@ class Launchpad_window : public Scrollbar_listener,
/**
* Widgets
*/
- Titlebar _titlebar;
- Sky_texture _texture;
- Fade_icon _sizer;
- Scrollbar _scrollbar;
- Genode::List > _child_entry_list;
- Docview _docview;
- Spacer _spacer;
- Document _document;
+ Scout::Titlebar _titlebar;
+ Scout::Sky_texture _texture;
+ Scout::Fade_icon _sizer;
+ Scout::Scrollbar _scrollbar;
+ Genode::List > _child_entry_list;
+ Scout::Docview _docview;
+ Scout::Spacer _spacer;
+ Scout::Document _document;
- Section _info_section;
- Section _launch_section;
- Section _kiddy_section;
+ Section _info_section;
+ Section _launch_section;
+ Section _kiddy_section;
- Status_entry _status_entry;
+ Status_entry _status_entry;
public:
@@ -72,9 +73,9 @@ class Launchpad_window : public Scrollbar_listener,
*
* \param initial_quota maximum value of quota displays
*/
- Launchpad_window(Platform *pf,
- Redraw_manager *redraw, int max_w, int max_h,
- unsigned long inital_quota);
+ Launchpad_window(Scout::Graphics_backend &gfx_backend,
+ Scout::Point position, Scout::Area size,
+ Scout::Area max_size, unsigned long inital_quota);
/**
* Define vertical scroll offset of document
@@ -87,22 +88,24 @@ class Launchpad_window : public Scrollbar_listener,
/**
* Window interface
*/
- void format(int w, int h);
+ void format(Scout::Area);
void ypos(int ypos) { ypos_sb(ypos, 1); }
/**
* Element interface
*/
- void draw(Canvas *c, int x, int y)
+ void draw(Scout::Canvas_base &canvas, Scout::Point abs_position)
{
- ::Parent_element::draw(c, x, y);
+ using namespace Scout;
+
+ Parent_element::draw(canvas, abs_position);
/* border */
- Color col(0, 0, 0);
- c->draw_box(0, 0, _w, 1, col);
- c->draw_box(0, _h - 1, _w, 1, col);
- c->draw_box(0, 1, 1, _h - 2, col);
- c->draw_box(_w - 1, 1, 1, _h - 2, col);
+ Color color(0, 0, 0);
+ canvas.draw_box(0, 0, _size.w(), 1, color);
+ canvas.draw_box(0, _size.h() - 1, _size.w(), 1, color);
+ canvas.draw_box(0, 1, 1, _size.h() - 2, color);
+ canvas.draw_box(_size.w() - 1, 1, 1, _size.h() - 2, color);
};
/**
@@ -143,7 +146,7 @@ class Launchpad_window : public Scrollbar_listener,
this, launchpad_child);
_child_entry_list.insert(ce);
_kiddy_section.append(ce);
- format(_w, _h);
+ format(_size);
refresh();
}
@@ -163,7 +166,7 @@ class Launchpad_window : public Scrollbar_listener,
_child_entry_list.remove(ce);
_kiddy_section.forget(ce);
destroy(alloc, ce);
- format(_w, _h);
+ format(_size);
refresh();
}
};
diff --git a/demo/src/app/launchpad/loadbar.h b/demo/src/app/launchpad/loadbar.h
index 00f91480c7..ec3c5a4ca5 100644
--- a/demo/src/app/launchpad/loadbar.h
+++ b/demo/src/app/launchpad/loadbar.h
@@ -39,7 +39,7 @@ class Loadbar_listener
};
-class Loadbar_event_handler : public Event_handler
+class Loadbar_event_handler : public Scout::Event_handler
{
private:
@@ -53,22 +53,23 @@ class Loadbar_event_handler : public Event_handler
/**
* Event handler interface
*/
- void handle(Event &ev)
+ void handle(Scout::Event &ev)
{
static int key_cnt;
+ using Scout::Event;
if (ev.type == Event::PRESS) key_cnt++;
if (ev.type == Event::RELEASE) key_cnt--;
if (ev.type == Event::PRESS || ev.type == Event::MOTION)
if (_listener && key_cnt > 0)
- _listener->loadbar_changed(ev.mx);
+ _listener->loadbar_changed(ev.mouse_position.x());
}
};
template
-class Loadbar : public Parent_element
+class Loadbar : public Scout::Parent_element
{
private:
@@ -79,8 +80,8 @@ class Loadbar : public Parent_element
bool _active;
- Fade_icon _cover;
- Fade_icon _bar;
+ Scout::Fade_icon _cover;
+ Scout::Fade_icon _bar;
Loadbar_event_handler _ev_handler;
@@ -89,26 +90,31 @@ class Loadbar : public Parent_element
const char *_txt;
int _txt_w, _txt_h, _txt_len;
- Font *_font;
+ Scout::Font *_font;
void _update_bar_geometry(int w)
{
+ using namespace Scout;
+
int max_w = w - _LW;
int bar_w = (_value * max_w) / _max_value;
bar_w += _LW;
- _bar.geometry(_bar.x(), _bar.y(), bar_w, _LH);
+ _bar.geometry(Rect(Point(_bar.position().x(), _bar.position().y()),
+ Area(bar_w, _LH)));
}
public:
- Loadbar(Loadbar_listener *listener = 0, Font *font = 0):
+ Loadbar(Loadbar_listener *listener = 0, Scout::Font *font = 0):
_active(listener ? true : false),
_ev_handler(listener),
_value(0), _max_value(100),
_txt(""), _txt_w(0), _txt_h(0), _txt_len(0),
_font(font)
{
- _min_h = _LH;
+ using namespace Scout;
+
+ _min_size = Area(_min_size.w(), _LH);
_cover.rgba(LOADBAR_RGBA);
_cover.alpha(100);
_cover.focus_alpha(150);
@@ -127,16 +133,16 @@ class Loadbar : public Parent_element
int value_by_xpos(int xpos)
{
xpos -= _LW/2;
- int max_w = _w - _LW;
- return max(min((_max_value * xpos) / max_w, _max_value), 0);
+ int max_w = _size.w() - _LW;
+ return Scout::max(Scout::min((_max_value * xpos) / max_w, _max_value), 0);
}
int value() { return _value; }
void value(int value)
{
- _value = max(min(value, _max_value), 0);
- _update_bar_geometry(_w);
+ _value = Scout::max(Scout::min(value, _max_value), 0);
+ _update_bar_geometry(_size.w());
}
int max_value() { return _max_value; }
@@ -144,16 +150,16 @@ class Loadbar : public Parent_element
void max_value(int max_value)
{
_max_value = max_value;
- _update_bar_geometry(_w);
+ _update_bar_geometry(_size.w());
}
void txt(const char *txt)
{
if (!_font) return;
_txt = txt;
- _txt_w = _font->str_w(_txt, strlen(_txt));
- _txt_h = _font->str_h(_txt, strlen(_txt));
- _txt_len = strlen(_txt);
+ _txt_w = _font->str_w(_txt, Scout::strlen(_txt));
+ _txt_h = _font->str_h(_txt, Scout::strlen(_txt));
+ _txt_len = Scout::strlen(_txt);
}
/**
@@ -161,34 +167,37 @@ class Loadbar : public Parent_element
*/
void format_fixed_width(int w)
{
- _cover.geometry(0, 0, w, _LH);
+ using namespace Scout;
+ _cover.geometry(Rect(Point(0, 0), Area(w, _LH)));
_update_bar_geometry(w);
- _min_w = w;
+ _min_size = Scout::Area(w, _min_size.h());
}
- void draw(Canvas *c, int x, int y)
+ void draw(Scout::Canvas_base &canvas, Scout::Point abs_position)
{
- Parent_element::draw(c, x, y);
+ Parent_element::draw(canvas, abs_position);
if (!_font) return;
- int txt_x = x + _x + max((_w - _txt_w)/2, 8);
- int txt_y = y + _y + max((_h - _txt_h)/2, 0) - 1;
+ using namespace Scout;
+
+ int txt_x = abs_position.x() + _position.x() + max((_size.w() - _txt_w)/2, 8UL);
+ int txt_y = abs_position.y() + _position.y() + max((_size.h() - _txt_h)/2, 0UL) - 1;
/* shrink clipping area to text area (limit too long label) */
- int cx1 = c->clip_x1(), cy1 = c->clip_y1();
- int cx2 = c->clip_x2(), cy2 = c->clip_y2();
- int nx1 = max(cx1, _x + x);
- int ny1 = max(cy1, _y + y);
- int nx2 = min(cx2, nx1 + _w - 8);
- int ny2 = min(cy2, ny1 + _h);
- c->clip(nx1, ny1, nx2 - nx1 + 1, ny2 - ny1 + 1);
+ int cx1 = canvas.clip().x1(), cy1 = canvas.clip().y1();
+ int cx2 = canvas.clip().x2(), cy2 = canvas.clip().y2();
+ int nx1 = max(cx1, _position.x() + abs_position.x());
+ int ny1 = max(cy1, _position.y() + abs_position.y());
+ int nx2 = min(cx2, nx1 + (int)_size.w() - 8);
+ int ny2 = min(cy2, ny1 + (int)_size.h());
+ canvas.clip(Rect(Point(nx1, ny1), Area(nx2 - nx1 + 1, ny2 - ny1 + 1)));
- c->draw_string(txt_x , txt_y+1, _font, Color(0,0,0,150), _txt, strlen(_txt));
- c->draw_string(txt_x , txt_y, _font, Color(255,255,255,230), _txt, strlen(_txt));
+ canvas.draw_string(txt_x , txt_y+1, _font, Color(0,0,0,150), _txt, strlen(_txt));
+ canvas.draw_string(txt_x , txt_y, _font, Color(255,255,255,230), _txt, strlen(_txt));
/* reset clipping */
- c->clip(cx1, cy1, cx2 - cx1 + 1, cy2 - cy1 + 1);
+ canvas.clip(Rect(Point(cx1, cy1), Area(cx2 - cx1 + 1, cy2 - cy1 + 1)));
}
void mfocus(int flag)
@@ -231,7 +240,7 @@ class Kbyte_loadbar : public Loadbar
public:
- Kbyte_loadbar(Loadbar_listener *listener, Font *font = 0):
+ Kbyte_loadbar(Loadbar_listener *listener, Scout::Font *font = 0):
Loadbar(listener, font)
{
_label[0] = 0;
diff --git a/demo/src/app/launchpad/main.cc b/demo/src/app/launchpad/main.cc
index 4968cfd698..74c5e7ae5a 100644
--- a/demo/src/app/launchpad/main.cc
+++ b/demo/src/app/launchpad/main.cc
@@ -11,15 +11,15 @@
* under the terms of the GNU General Public License version 2.
*/
+#include
+#include
+#include
+#include
+#include
+
#include "config.h"
#include "elements.h"
-#include "platform.h"
-#include "canvas_rgb565.h"
-#include "tick.h"
-#include "redraw_manager.h"
-#include "user_state.h"
#include "launchpad_window.h"
-#include "printf.h"
#include
#include
@@ -29,21 +29,18 @@
/**
* Runtime configuration
*/
-namespace Config
-{
+namespace Scout { namespace Config {
int iconbar_detail = 1;
int background_detail = 1;
int mouse_cursor = 1;
int browser_attr = 0;
-}
-
-extern int native_startup(int, char **);
+} }
/**
* Facility to keep the available quota display up-to-date
*/
-class Avail_quota_update : public Tick
+class Avail_quota_update : public Scout::Tick
{
private:
@@ -104,7 +101,7 @@ static void process_config(Launchpad *launchpad)
enum { MAX_NAME_LEN = 128 };
char *filename = (char *)env()->heap()->alloc(MAX_NAME_LEN);
if (!filename) {
- ::printf("Error: Out of memory while processing configuration\n");
+ printf("Error: Out of memory while processing configuration\n");
return;
}
filename_attr.value(filename, MAX_NAME_LEN);
@@ -148,13 +145,13 @@ static void process_config(Launchpad *launchpad)
launcher_cnt++;
} catch (...) {
- ::printf("Warning: Launcher entry %d is malformed.\n",
+ printf("Warning: Launcher entry %d is malformed.\n",
launcher_cnt + 1);
}
else {
char buf[32];
node.type_name(buf, sizeof(buf));
- ::printf("Warning: Ignoring unsupported tag <%s>.\n", buf);
+ printf("Warning: Ignoring unsupported tag <%s>.\n", buf);
}
}
}
@@ -175,9 +172,7 @@ static long read_int_attr_from_config(const char *attr, long default_value)
*/
int main(int argc, char **argv)
{
- using namespace Genode;
-
- if (native_startup(argc, argv)) return -1;
+ using namespace Scout;
/* look for dynamic linker */
try {
@@ -185,29 +180,26 @@ int main(int argc, char **argv)
Genode::Process::dynamic_linker(rom.dataspace());
} catch (...) { }
+ static Nitpicker::Connection nitpicker;
+ static Platform pf(*nitpicker.input());
+
long initial_x = read_int_attr_from_config("xpos", 550);
long initial_y = read_int_attr_from_config("ypos", 150);
long initial_w = read_int_attr_from_config("width", 400);
long initial_h = read_int_attr_from_config("height", 400);
- /* init platform */
- static Platform pf(initial_x, initial_y, initial_w, initial_h, 400);
+ Area const max_size (530, 620);
+ Point const initial_position(initial_x, initial_y);
+ Area const initial_size (initial_w, initial_h);
- /* init canvas */
- static Chunky_canvas canvas;
- canvas.init(static_cast(pf.buf_adr()),
- pf.scr_w()*pf.scr_h());
- canvas.set_size(pf.scr_w(), pf.scr_h());
- canvas.clip(0, 0, pf.scr_w(), pf.scr_h());
-
- /* init redraw manager */
- static Redraw_manager redraw(&canvas, &pf, pf.vw(), pf.vh());
+ static Nitpicker_graphics_backend
+ graphics_backend(nitpicker, max_size, initial_position, initial_size);
/* create instance of launchpad window */
static Launchpad_window
launchpad(
- &pf, &redraw, pf.scr_w(), pf.scr_h(),
- env()->ram_session()->avail()
+ graphics_backend, initial_position, initial_size, max_size,
+ Genode::env()->ram_session()->avail()
);
/* request config file from ROM service */
@@ -218,37 +210,28 @@ int main(int argc, char **argv)
Avail_quota_update avail_quota_update(&launchpad);
/* create user state manager */
- static User_state user_state(&launchpad, &launchpad, pf.vx(), pf.vy());
+ static User_state user_state(&launchpad, &launchpad,
+ initial_position.x(), initial_position.y());
- /* assign launchpad window as root element to redraw manager */
- redraw.root(&launchpad);
-
- pf.view_geometry(pf.vx(), pf.vy(), pf.vw(), pf.vh());
launchpad.parent(&user_state);
- launchpad.format(pf.vw(), pf.vh());
+ launchpad.format(initial_size);
launchpad.ypos(0);
Genode::printf("--- entering main loop ---\n");
/* enter main loop */
- Event ev;
unsigned long curr_time, old_time;
curr_time = old_time = pf.timer_ticks();
- do {
- pf.get_event(&ev);
+ for (;;) {
+ Event ev = pf.get_event();
launchpad.gui_lock.lock();
- if (ev.type != Event::WHEEL) {
- ev.mx -= user_state.vx();
- ev.my -= user_state.vy();
- }
+ if (ev.type != Event::WHEEL)
+ ev.mouse_position = ev.mouse_position - user_state.view_position();
user_state.handle_event(ev);
- if (ev.type == Event::REFRESH)
- pf.scr_update(0, 0, pf.scr_w(), pf.scr_h());
-
if (ev.type == Event::TIMER)
Tick::handle(pf.timer_ticks());
@@ -256,12 +239,14 @@ int main(int argc, char **argv)
curr_time = pf.timer_ticks();
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
old_time = curr_time;
- redraw.process();
+ launchpad.process_redraw();
}
launchpad.gui_lock.unlock();
- } while (ev.type != Event::QUIT);
+ if (ev.type == Event::QUIT)
+ break;
+ }
return 0;
}
diff --git a/demo/src/app/launchpad/section.h b/demo/src/app/launchpad/section.h
index a7234dc7f6..751acf5d33 100644
--- a/demo/src/app/launchpad/section.h
+++ b/demo/src/app/launchpad/section.h
@@ -18,29 +18,30 @@
template
-class Section : public Parent_element
+class Section : public Scout::Parent_element
{
private:
enum { _SH = 8 }; /* shadow height */
enum { _STH = 20 }; /* shadow height */
- Horizontal_shadow _bg;
- Horizontal_shadow _shadow;
- const char *_txt;
- int _txt_w, _txt_h;
- int _txt_len;
- Font *_font;
- int _r_add;
+ Scout::Horizontal_shadow _bg;
+ Scout::Horizontal_shadow _shadow;
+
+ char const *_txt;
+ int _txt_w, _txt_h;
+ int _txt_len;
+ Scout::Font *_font;
+ int _r_add;
public:
- Section(const char *txt, Font *font)
+ Section(const char *txt, Scout::Font *font)
: _bg(_STH), _shadow(_SH), _txt(txt), _font(font), _r_add(100)
{
- _txt_w = font->str_w(_txt, strlen(_txt));
- _txt_h = font->str_h(_txt, strlen(_txt));
- _txt_len = strlen(_txt);
+ _txt_w = font->str_w(_txt, Scout::strlen(_txt));
+ _txt_h = font->str_h(_txt, Scout::strlen(_txt));
+ _txt_len = Scout::strlen(_txt);
append(&_bg);
append(&_shadow);
}
@@ -50,23 +51,34 @@ class Section : public Parent_element
*/
void format_fixed_width(int w)
{
- _min_h = _format_children(0, w) + _SH/2;
- _min_w = w;
+ using namespace Scout;
- _bg.geometry(_bg.x(), _bg.y(), _bg.w() + _r_add, _bg.h());
- _shadow.geometry(_shadow.x(), _shadow.y(), _shadow.w() + _r_add, _shadow.h());
+ _min_size = Area(w, _format_children(0, w) + _SH/2);
+
+ _bg.geometry(Rect(_bg.position(),
+ Area(_bg.size().w() + _r_add, _bg.size().h())));
+
+ _shadow.geometry(Rect(_shadow.position(),
+ Area(_shadow.size().w() + _r_add,
+ _shadow.size().h())));
}
- void draw(Canvas *c, int x, int y)
+ void draw(Scout::Canvas_base &canvas, Scout::Point abs_position)
{
- c->draw_box(x + _x, y + _y + 1, _w + _r_add, _txt_h - 1, Color(240,240,240,130));
+ using namespace Scout;
- int _txt_x = x + _x + max((_w - _txt_w)/2, 8);
- int _txt_y = y + _y + max((_STH - _SH - _txt_h)/2, 0) - 1;
+ canvas.draw_box(abs_position.x() + _position.x(),
+ abs_position.y() + _position.y() + 1,
+ _size.w() + _r_add, _txt_h - 1, Color(240,240,240,130));
- Parent_element::draw(c, x, y);
- c->draw_string(_txt_x , _txt_y, _font, Color(0,0,0,150), _txt, strlen(_txt));
- c->draw_box(x + _x, y + _y, _w + _r_add, 1, Color(0,0,0,64));
+ int _txt_x = abs_position.x() + _position.x() + max((_size.w() - _txt_w)/2, 8UL);
+ int _txt_y = abs_position.y() + _position.y() + max((_STH - _SH - _txt_h)/2, 0) - 1;
+
+ Parent_element::draw(canvas, abs_position);
+
+ canvas.draw_string(_txt_x , _txt_y, _font, Color(0,0,0,150), _txt, strlen(_txt));
+ canvas.draw_box(abs_position.x() + _position.x(), abs_position.y() + _position.y(),
+ _size.w() + _r_add, 1, Color(0,0,0,64));
}
};
diff --git a/demo/src/app/launchpad/status_entry.h b/demo/src/app/launchpad/status_entry.h
index 442d1c262b..4b2ba56ace 100644
--- a/demo/src/app/launchpad/status_entry.h
+++ b/demo/src/app/launchpad/status_entry.h
@@ -17,11 +17,11 @@
#include "loadbar.h"
template
-class Status_entry : public Parent_element
+class Status_entry : public Scout::Parent_element
{
private:
- Block _block;
+ Scout::Block _block;
Kbyte_loadbar _loadbar;
int _lh; /* launch entry height */
@@ -35,9 +35,9 @@ class Status_entry : public Parent_element
* Constructor
*/
Status_entry(const char *label)
- : _block(Block::RIGHT), _loadbar(0, &label_font)
+ : _block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font)
{
- _block.append_plaintext(label, &plain_style);
+ _block.append_plaintext(label, &Scout::plain_style);
_loadbar.max_value(20*1024);
_loadbar.value(3*1024);
@@ -45,23 +45,25 @@ class Status_entry : public Parent_element
append(&_loadbar);
append(&_block);
- _min_w = _PTW + 100;
+ _min_size = Scout::Area(_PTW + 100, _min_size.h());
}
void format_fixed_width(int w)
{
+ using namespace Scout;
+
_block.format_fixed_width(_PTW);
- _lh = _block.min_h();
- _block.geometry(max(10, _PTW - _block.min_w()),
- max(0, (_lh - _block.min_h())/2),
- min((int)_PTW, _block.min_w()), _lh);
+ _lh = _block.min_size().h();
+ _block.geometry(Rect(Point(max(10U, _PTW - _block.min_size().w()),
+ max(0U, (_lh - _block.min_size().h())/2)),
+ Area(min((unsigned)_PTW, _block.min_size().w()), _lh)));
int lw = max(0, w - 2*_PADX - _PTW - _PADR);
- int ly = max(0, (_lh - _loadbar.min_h())/2);
+ int ly = max(0U, (_lh - _loadbar.min_size().h())/2);
_loadbar.format_fixed_width(lw);
- _loadbar.geometry(_PADX + _PTW, ly, lw, 16);
- _min_h = _lh;
- _min_w = w;
+ _loadbar.geometry(Rect(Point(_PADX + _PTW, ly), Area(lw, 16)));
+
+ _min_size = Scout::Area(w, _lh);
}
void value(int value) { _loadbar.value(value); }
diff --git a/demo/src/app/launchpad/target.mk b/demo/src/app/launchpad/target.mk
index 0b54bd0868..4cecb63cf9 100644
--- a/demo/src/app/launchpad/target.mk
+++ b/demo/src/app/launchpad/target.mk
@@ -6,6 +6,4 @@ SRC_CC = launchpad_window.cc \
SCOUT_DIR = $(REP_DIR)/src/app/scout
-INC_DIR = $(PRG_DIR) \
- $(SCOUT_DIR)/include \
- $(SCOUT_DIR)/include/genode
+INC_DIR = $(PRG_DIR) $(SCOUT_DIR)
diff --git a/demo/src/app/scout/common/about.cc b/demo/src/app/scout/about.cc
similarity index 98%
rename from demo/src/app/scout/common/about.cc
rename to demo/src/app/scout/about.cc
index e3ce5f1abf..b1b7cbf534 100644
--- a/demo/src/app/scout/common/about.cc
+++ b/demo/src/app/scout/about.cc
@@ -14,8 +14,13 @@
#include "elements.h"
#include "styles.h"
-Document *create_about()
+namespace Scout { Document *create_about(); }
+
+
+Scout::Document *Scout::create_about()
{
+ using namespace Scout;
+
Document *doc = new Document();
doc->title = "";
diff --git a/demo/src/app/scout/include/browser.h b/demo/src/app/scout/browser.h
similarity index 94%
rename from demo/src/app/scout/include/browser.h
rename to demo/src/app/scout/browser.h
index 46f297f835..6626d5a68a 100644
--- a/demo/src/app/scout/include/browser.h
+++ b/demo/src/app/scout/browser.h
@@ -17,10 +17,13 @@
#include "elements.h"
#include "history.h"
+namespace Scout {
+ extern Document *create_about();
+ class Browser;
+}
-extern Document *create_about();
-class Browser
+class Scout::Browser
{
protected:
@@ -74,7 +77,7 @@ class Browser
/**
* Format browser window
*/
- virtual void format(int w, int h) { }
+ virtual void format(Area) { }
/**
* Travel backward in history
@@ -123,10 +126,9 @@ class Browser
_content(new_content);
ypos(0);
- ypos(_ypos - anchor->abs_y() + _voffset);
+ ypos(_ypos - anchor->abs_position().y() + _voffset);
if (new_content) {
- new_content->curr_link_destination(0);
new_content->refresh();
}
}
@@ -158,5 +160,4 @@ class Browser
int go_about() { go_to(_about); return 1; }
};
-
#endif /* _BROWSER_H_ */
diff --git a/demo/src/app/scout/common/browser_window.cc b/demo/src/app/scout/browser_window.cc
similarity index 77%
rename from demo/src/app/scout/common/browser_window.cc
rename to demo/src/app/scout/browser_window.cc
index 0637fdcfeb..5b838aeda0 100644
--- a/demo/src/app/scout/common/browser_window.cc
+++ b/demo/src/app/scout/browser_window.cc
@@ -13,9 +13,13 @@
* under the terms of the GNU General Public License version 2.
*/
-#include "miscmath.h"
+#include
+#include
+
#include "browser_window.h"
+using namespace Scout;
+
/****************************
** External graphics data **
@@ -109,7 +113,7 @@ static void extract_rgba(const unsigned char *src, int w, int h,
** Event handlers **
********************/
-class Iconbar_event_handler : public Event_handler
+class Iconbar_event_handler : public Scout::Event_handler
{
private:
@@ -185,7 +189,7 @@ class Iconbar_event_handler : public Event_handler
template
-class Browser_sizer_event_handler : public Sizer_event_handler
+class Browser_sizer_event_handler : public Scout::Sizer_event_handler
{
private:
@@ -226,10 +230,12 @@ class Browser_sizer_event_handler : public Sizer_event_handler
template
Browser_window::Browser_window(Document *initial_content,
- Platform *pf,
- Redraw_manager *redraw,
- int max_w, int max_h, int attr)
-: Browser(_IH + _TH), Window(pf, redraw, max_w, max_h)
+ Graphics_backend &gfx_backend,
+ Point position, Area size,
+ Area max_size, int attr)
+:
+ Browser(_IH + _TH), Window(gfx_backend, position, size, max_size, true),
+ _gfx_backend(gfx_backend)
{
/* init attributes */
_ypos = 0;
@@ -280,6 +286,7 @@ Browser_window::Browser_window(Document *initial_content,
/*
* NOTE: The panel height must be the same as the icon height.
*/
+ using Scout::random;
for (int j = 0; j < _PANEL_H; j++)
for (int i = 0; i < _PANEL_W; i++) {
_panel_fg [j][i] = _icon_fg [ICON_INDEX][j][i&0x1];
@@ -303,8 +310,7 @@ Browser_window::Browser_window(Document *initial_content,
_titlebar.text(_document->title);
_titlebar.event_handler(new Mover_event_handler(this));
- _min_w = _NUM_ICONS*_IW;
- _min_h = _IH + 250;
+ _min_size = Scout::Area(_NUM_ICONS*_IW, _IH + 250);
/* adopt widgets as child elements */
append(&_docview);
@@ -330,15 +336,16 @@ Browser_window::Browser_window(Document *initial_content,
template
void Browser_window::ypos_sb(int ypos, int update_scrollbar)
{
- if (ypos < -_docview.h() + _h)
- ypos = -_docview.h() + _h;
+ if (ypos < -(int)_docview.size().h() + (int)_size.h())
+ ypos = -(int)_docview.size().h() + (int)_size.h();
_ypos = ypos <= 0 ? ypos : 0;
- _docview.geometry(_docview.x(), _ypos, _docview.w(), _docview.h());
+ _docview.geometry(Rect(Point(_docview.position().x(), _ypos),
+ Area(_docview.size().w(), _docview.size().h())));
if (update_scrollbar)
- _scrollbar.view(_docview.h(), _h, -_ypos);
+ _scrollbar.view(_docview.size().h(), _size.h(), -_ypos);
refresh();
}
@@ -359,80 +366,85 @@ template
void Browser_window::_content(Element *content)
{
if (!content || (content == _docview.content())) return;
- content->fill_cache(redraw()->canvas());
+
+ content->fill_cache(_gfx_backend.front());
_docview.content(content);
- format(_w, _h);
+ format(_size);
_ypos = 0;
}
template
-void Browser_window::format(int w, int h)
+void Browser_window::format(Area size)
{
+ unsigned w = size.w();
+ unsigned h = size.h();
+
/* limit browser window size to valid values */
- w = (w < _min_w) ? _min_w : w;
- h = (h < _min_h) ? _min_h : h;
- w = (w > max_w()) ? max_w() : w;
- h = (h > max_h()) ? max_h() : h;
+ w = max(w, min_size().w());
+ h = max(h, min_size().h());
+ w = min(w, max_size().w());
+ h = min(h, max_size().h());
/* determine old scrollbar visibility */
- int old_sb_visibility = (_docview.min_h() > _h);
+ int old_sb_visibility = (_docview.min_size().h() > _size.h());
/* assign new size to browser window */
- _w = w;
- _h = h;
+ _size = Scout::Area(w, h);
/* format document */
- _docview.format_fixed_width(_w);
+ _docview.format_fixed_width(_size.w());
/* format titlebar */
- _titlebar.format_fixed_width(_w);
+ _titlebar.format_fixed_width(_size.w());
/* determine new scrollbar visibility */
- int new_sb_visibility = (_docview.min_h() > _h);
+ int new_sb_visibility = (_docview.min_size().h() > _size.h());
/* reformat docview on change of scrollbar visibility */
if (old_sb_visibility ^ new_sb_visibility) {
- _docview.right_pad(new_sb_visibility ? _scrollbar.min_w() : 0);
- _docview.format_fixed_width(_w);
+ _docview.right_pad(new_sb_visibility ? _scrollbar.min_size().w() : 0);
+ _docview.format_fixed_width(_size.w());
}
/* position docview */
- _docview.geometry(0, _ypos, _docview.min_w(), max(_docview.min_h(), _h));
+ _docview.geometry(Rect(Point(0, _ypos),
+ Area(_docview.min_size().w(),
+ max(_docview.min_size().h(), _size.h()))));
/* start at top */
int y = 0;
/* position titlebar */
if (_attr & ATTR_TITLEBAR) {
- _titlebar.geometry(y, 0, _w, _TH);
+ _titlebar.geometry(Rect(Point(y, 0), Area(_size.w(), _TH)));
y += _TH;
}
/* position icons */
for (int i = 0; i <= ICON_INDEX; i++) {
- _icon[i].geometry(i*_IW, y, _IW, _IH);
- _glow_icon[i].geometry(i*_IW, y, _IW, _IH);
+ _icon[i].geometry(Rect(Point(i*_IW, y), Area(_IW, _IH)));
+ _glow_icon[i].geometry(Rect(Point(i*_IW, y), Area(_IW, _IH)));
}
- _icon[ICON_ABOUT].geometry(_w - _IW, y, _IW, _IH);
- _glow_icon[ICON_ABOUT].geometry(_w - _IW, y, _IW, _IH);
+ _icon[ICON_ABOUT].geometry(Rect(Point(_size.w() - _IW, y), Area(_IW, _IH)));
+ _glow_icon[ICON_ABOUT].geometry(Rect(Point(_size.w() - _IW, y), Area(_IW, _IH)));
/* the panel is the space between the left icon set and the right about icon */
- int panel_x = _icon[ICON_INDEX].x() + _IW;
- _panel.geometry(panel_x, y, _icon[ICON_ABOUT].x() - panel_x, _IH);
+ int panel_x = _icon[ICON_INDEX].position().x() + _IW;
+ _panel.geometry(Rect(Point(panel_x, y),
+ Area(_icon[ICON_ABOUT].position().x() - panel_x, _IH)));
y += _IH;
- _scrollbar.geometry(w - _scrollbar.min_w() - _SB_XPAD, y + _SB_YPAD,
- _scrollbar.min_w(), h - y - _SB_YPAD*2 -
- (_attr & ATTR_SIZER ? 8 : 0));
- _shadow.geometry(0, y, _w, 10);
+ _scrollbar.geometry(Rect(Point(w - _scrollbar.min_size().w() - _SB_XPAD, y + _SB_YPAD),
+ Area(_scrollbar.min_size().w(),
+ h - y - _SB_YPAD*2 - (_attr & ATTR_SIZER ? 8 : 0))));
+ _shadow.geometry(Rect(Point(0, y), Area(_size.w(), 10)));
if (_attr & ATTR_SIZER)
- _sizer.geometry(_w - 32, _h - 32, 32, 32);
+ _sizer.geometry(Rect(Point(_size.w() - 32, _size.h() - 32), Area(32, 32)));
- pf()->view_geometry(pf()->vx(), pf()->vy(), _w, _h);
- redraw()->size(_w, _h);
+ Window::format(_size);
}
@@ -456,5 +468,4 @@ void Browser_window::handle_scroll(int view_pos)
ypos_sb(-view_pos, 0);
}
-#include "canvas_rgb565.h"
-template class Browser_window;
+template class Browser_window;
diff --git a/demo/src/app/scout/include/browser_window.h b/demo/src/app/scout/browser_window.h
similarity index 79%
rename from demo/src/app/scout/include/browser_window.h
rename to demo/src/app/scout/browser_window.h
index b868c97f34..28194848fc 100644
--- a/demo/src/app/scout/include/browser_window.h
+++ b/demo/src/app/scout/browser_window.h
@@ -14,22 +14,24 @@
#ifndef _BROWSER_WINDOW_H_
#define _BROWSER_WINDOW_H_
+#include
+#include
+
#include "elements.h"
#include "widgets.h"
#include "sky_texture.h"
#include "refracted_icon.h"
#include "scrollbar.h"
-#include "platform.h"
-#include "redraw_manager.h"
#include "browser.h"
-#include "window.h"
#include "titlebar.h"
+namespace Scout { template class Browser_window; }
+
template
-class Browser_window : public Scrollbar_listener,
- public Browser,
- public Window
+class Scout::Browser_window : public Scrollbar_listener,
+ public Browser,
+ public Window
{
enum {
ICON_HOME = 0,
@@ -61,6 +63,11 @@ class Browser_window : public Scrollbar_listener,
*/
int _attr; /* attribute mask */
+ /**
+ * Remember graphics backend used as texture allocator
+ */
+ Graphics_backend &_gfx_backend;
+
/**
* Widgets
*/
@@ -102,15 +109,9 @@ class Browser_window : public Scrollbar_listener,
/**
* Constructor
- *
- * \param scr_adr base address of screen buffer
- * \param scr_w width of screen buffer
- * \param scr_h height of screen buffer
- * \param doc initial content
- * \param w, h initial size of the browser window
*/
- Browser_window(Document *content, Platform *pf,
- Redraw_manager *redraw, int max_w, int max_h,
+ Browser_window(Document *content, Graphics_backend &gfx_backend,
+ Point position, Area size, Area max_size,
int attr = ATTR_SIZER | ATTR_TITLEBAR);
/**
@@ -129,7 +130,7 @@ class Browser_window : public Scrollbar_listener,
/**
* Browser interface
*/
- void format(int w, int h);
+ void format(Area);
void ypos(int ypos) { ypos_sb(ypos, 1); }
Anchor *curr_anchor();
Browser *browser() { return this; }
@@ -137,16 +138,16 @@ class Browser_window : public Scrollbar_listener,
/**
* Element interface
*/
- void draw(Canvas *c, int x, int y)
+ void draw(Canvas_base &canvas, Point abs_position)
{
- ::Parent_element::draw(c, x, y);
+ Parent_element::draw(canvas, abs_position);
if (_attr & ATTR_BORDER) {
- Color col(0, 0, 0);
- c->draw_box(0, 0, _w, 1, col);
- c->draw_box(0, _h - 1, _w, 1, col);
- c->draw_box(0, 1, 1, _h - 2, col);
- c->draw_box(_w - 1, 1, 1, _h - 2, col);
+ Color color(0, 0, 0);
+ canvas.draw_box(0, 0, _size.w(), 1, color);
+ canvas.draw_box(0, _size.h() - 1, _size.w(), 1, color);
+ canvas.draw_box(0, 1, 1, _size.h() - 2, color);
+ canvas.draw_box(_size.w() - 1, 1, 1, _size.h() - 2, color);
}
};
diff --git a/demo/src/app/scout/common/refracted_icon.cc b/demo/src/app/scout/common/refracted_icon.cc
deleted file mode 100644
index bf7df6e345..0000000000
--- a/demo/src/app/scout/common/refracted_icon.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * \brief Implementation of refracted icons
- * \date 2005-10-24
- * \author Norman Feske
- *
- * A refracted icon is a icon that refracts its background
- * using a distortion map.
- */
-
-/*
- * Copyright (C) 2005-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.
- */
-
-#include "config.h"
-#include "miscmath.h"
-#include "refracted_icon.h"
-
-
-/***************
- ** Utilities **
- ***************/
-
-/**
- * Backup original (background) pixel data into back buffer
- */
-template
-static void filter_src_to_backbuf(PT *src, int src_w,
- PT *dst, int dst_w, int dst_h, int width)
-{
- for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w) {
- for (int i = 0; i < width; i++) {
- dst[2*i] = src[i];
- dst[2*i + 1] = PT::avr(src[i], src[i + 1]);
- dst[2*i + dst_w] = PT::avr(src[i], src[i + src_w]);
- dst[2*i + dst_w + 1] = PT::avr(dst[2*i + dst_w], dst[2*i + 1]);
- }
- }
-}
-
-
-/**
- * Backup original (background) pixel data into back buffer
- */
-template
-static void copy_src_to_backbuf(PT *src, int src_w,
- PT *dst, int dst_w, int dst_h, int width)
-{
- for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w)
- for (int i = 0; i < width; i++)
- dst[2*i] = dst[2*i + 1] = dst[2*i + dst_w] = dst[2*i + dst_w + 1] = src[i];
-}
-
-
-/**
- * Copy and distort back-buffer pixels to front buffer
- */
-template
-void distort(PT src[], DT distmap[], int distmap_w, int distmap_h,
- PT fg[], unsigned char alpha[],
- PT dst[], int dst_w, int width)
-{
- int line_offset = (distmap_w>>1) - width;
- width <<= 1;
-
- for (int j = 0; j < distmap_h; j += 2, dst += dst_w) {
-
- PT *d = dst;
-
- for (int i = 0; i < width; i += 2, src += 2, distmap += 2) {
-
- /* fetch distorted pixel from back buffer */
- PT v = PT::avr(src[distmap[0]],
- src[distmap[1] + 1],
- src[distmap[distmap_w] + distmap_w],
- src[distmap[distmap_w + 1] + distmap_w + 1]);
-
- /* mix back-buffer pixel with foreground */
- *d++ = PT::mix(v, *fg++, *alpha++);
- }
-
- fg += line_offset;
- alpha += line_offset;
- src += line_offset*2 + distmap_w; /* skip one line in back buffer */
- distmap += line_offset*2 + distmap_w; /* skip one line in distmap */
- }
-}
-
-
-/**
- * Copy and distort back-buffer pixels to front buffer
- */
-template
-void copy(PT src[], int src_w, PT dst[], int dst_w, int w, int h)
-{
- for (int j = 0; j < h; j ++, src += src_w, dst += dst_w)
- memcpy(dst, src, w*sizeof(PT));
-}
-
-
-/******************************
- ** Refracted icon interface **
- ******************************/
-
-template
-void Refracted_icon::scratch(int jitter)
-{
- PT ref_color = _fg[0];
- for (int j = 0; j < _distmap_h; j++) for (int i = 0; i < _distmap_w; i++) {
-
- int fg_offset = (j>>1)*(_distmap_w>>1) + (i>>1);
-
- int dr = _fg[fg_offset].r() - ref_color.r();
- int dg = _fg[fg_offset].g() - ref_color.g();
- int db = _fg[fg_offset].b() - ref_color.b();
-
- if (dr < 0) dr = -dr;
- if (dg < 0) dg = -dg;
- if (db < 0) db = -db;
-
- static const int limit = 20;
- if (dr > limit || dg > limit || db > limit) continue;
-
- int dx, dy;
-
- do {
- dx = jitter ? ((random()%jitter) - (jitter>>1)) : 0;
- dy = jitter ? ((random()%jitter) - (jitter>>1)) : 0;
- } while ((dx < -i) || (dx > _distmap_w - 2 - i)
- || (dy < -j) || (dy > _distmap_h - 2 - j));
-
- _distmap[j*_distmap_w + i] += dy*_distmap_w + dx;
- }
-}
-
-
-/***********************
- ** Element interface **
- ***********************/
-
-template
-void Refracted_icon::draw(Canvas *c, int x, int y)
-{
- PT *addr = static_cast(c->addr());
-
- if (!addr || !_backbuf || !_fg || !_fg_alpha) return;
-
- /*
- * NOTE: There is no support for clipping.
- * Use this code with caution!
- */
-
- addr += c->w()*(y + _y) + x + _x;
-
- int fg_w = _distmap_w>>1;
-
- for (int i = 0; i < _w; i += fg_w, addr += fg_w) {
-
- int curr_w = min(fg_w, _w - i);
-
- if (Config::iconbar_detail == 0) {
- copy(_fg, _distmap_w>>1, addr, c->w(), curr_w, _distmap_h>>1);
- continue;
- }
-
- /* backup old canvas pixels */
- if (_filter_backbuf)
- filter_src_to_backbuf(addr, c->w(), _backbuf, _distmap_w,
- _distmap_h, fg_w);
- else
- copy_src_to_backbuf(addr, c->w(), _backbuf, _distmap_w,
- _distmap_h, fg_w);
-
- /* draw distorted pixels back to canvas */
- distort(_backbuf, _distmap, _distmap_w, _distmap_h,
- _fg, _fg_alpha, addr, c->w(), curr_w);
- }
-}
-
-
-#include "canvas_rgb565.h"
-template class Refracted_icon;
diff --git a/demo/src/app/scout/common/sky_texture.cc b/demo/src/app/scout/common/sky_texture.cc
deleted file mode 100644
index e8e8c980a6..0000000000
--- a/demo/src/app/scout/common/sky_texture.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * \brief Sky texture element for the use as background
- * \date 2005-10-24
- * \author Norman Feske
- *
- * At initialization time, we generate four 4-bit maps based on
- * bicubic interpolation of some noise at different frequencies.
- * At runtime, we overlay (add their values) the generated map
- * and use the result as index of a color table.
- */
-
-/*
- * Copyright (C) 2005-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.
- */
-
-#include "config.h"
-#include "miscmath.h"
-#include "sky_texture.h"
-
-
-/***********************
- ** Texture generator **
- ***********************/
-
-/**
- * Calculate fractional part of texture position for a given coordinate
- */
-static inline int calc_u(int x, int w, int texture_w)
-{
- return ((texture_w*x<<8)/w) & 0xff;
-}
-
-
-/**
- * Kubic interpolation
- *
- * \param u relative position between x1 and x2 (0..255)
- */
-static inline int filter(int x0, int x1, int x2, int x3, int u)
-{
- static int cached_u = -1;
- static int k0, k1, k2, k3;
-
- /*
- * Do not recompute coefficients when called
- * with the same subsequencing u values.
- */
- if (u != cached_u) {
-
- int v = 255 - u;
- int uuu = (u*u*u)>>16;
- int vvv = (v*v*v)>>16;
- int uu = (u*u)>>8;
- int vv = (v*v)>>8;
-
- k0 = vvv/6;
- k3 = uuu/6;
- k1 = k3*3 - uu + (4<<8)/6;
- k2 = k0*3 - vv + (4<<8)/6;
-
- cached_u = u;
- }
-
- return (x0*k0 + x1*k1 + x2*k2 + x3*k3)>>8;
-}
-
-
-/**
- * Determine texture position by given position in image
- */
-static inline int get_idx(int x, int w, int texture_w, int offset)
-{
- return (offset + texture_w + (texture_w*x)/w) % texture_w;
-}
-
-
-/**
- * Generate sky texture based on bicubic interpolation of some noise
- */
-static void gen_buf(short tmp[], int noise_w, int noise_h,
- short dst[], int dst_w, int dst_h)
-{
- /* generate noise */
- for (int i = 0; i < noise_h; i++) for (int j = 0; j < noise_w; j++)
- dst[i*dst_w + j] = random()%256 - 128;
-
- /* interpolate horizontally */
- for (int j = dst_w - 1; j >= 0; j--) {
-
- int x0_idx = get_idx(j, dst_w, noise_w, -1);
- int x1_idx = get_idx(j, dst_w, noise_w, 0);
- int x2_idx = get_idx(j, dst_w, noise_w, 1);
- int x3_idx = get_idx(j, dst_w, noise_w, 2);
- int u = calc_u(j, dst_w, noise_w);
-
- for (int i = 0; i < noise_h; i++) {
-
- int x0 = dst[i*dst_w + x0_idx];
- int x1 = dst[i*dst_w + x1_idx];
- int x2 = dst[i*dst_w + x2_idx];
- int x3 = dst[i*dst_w + x3_idx];
-
- tmp[i*dst_w + j] = filter(x0, x1, x2, x3, u);
- }
- }
-
- /* vertical interpolation */
- for (int i = dst_h - 1; i >= 0; i--) {
-
- int y0_idx = get_idx(i, dst_h, noise_h, -1)*dst_w;
- int y1_idx = get_idx(i, dst_h, noise_h, 0)*dst_w;
- int y2_idx = get_idx(i, dst_h, noise_h, 1)*dst_w;
- int y3_idx = get_idx(i, dst_h, noise_h, 2)*dst_w;
- int u = calc_u(i, dst_h, noise_h);
-
- for (int j = 0; j < dst_w; j++) {
-
- int y0 = tmp[y0_idx + j];
- int y1 = tmp[y1_idx + j];
- int y2 = tmp[y2_idx + j];
- int y3 = tmp[y3_idx + j];
-
- dst[i*dst_w + j] = filter(y0, y1, y2, y3, u);
- }
- }
-}
-
-
-/**
- * Normalize buffer values to specified maximum
- */
-static void normalize_buf(short dst[], int len, int amp)
-{
- int min = 0x7ffffff, max = 0;
-
- for (int i = 0; i < len; i++) {
- if (dst[i] < min) min = dst[i];
- if (dst[i] > max) max = dst[i];
- }
-
- if (max == min) return;
-
- for (int i = 0; i < len; i++)
- dst[i] = (amp*(dst[i] - min))/(max - min);
-}
-
-
-/**
- * Multiply buffer values with 24:8 fixpoint value
- */
-static void multiply_buf(short dst[], int len, int factor)
-{
- for (int i = 0; i < len; i++)
- dst[i] = (dst[i]*factor)>>8;
-}
-
-
-/**
- * Add each pair of values of two buffers
- */
-static void add_bufs(short src1[], short src2[], short dst[], int len)
-{
- for (int i = 0; i < len; i++)
- dst[i] = src1[i] + src2[i];
-}
-
-
-/**
- * We combine (add) multiple low-frequency textures with one high-frequency
- * texture to get nice shapes.
- */
-static void brew_texture(short tmp[], short tmp2[], short dst[], int w, int h,
- int lf_start, int lf_end, int lf_incr, int lf_mul,
- int hf_val, int hf_mul)
-{
- for (int i = lf_start; i < lf_end; i += lf_incr) {
- gen_buf(tmp, i, i, tmp2, w, h);
- multiply_buf(tmp2, w*h, (lf_mul - i)*32);
- add_bufs(tmp2, dst, dst, w*h);
- }
- if (hf_val) {
- gen_buf(tmp, hf_val, hf_val, tmp2, w, h);
- multiply_buf(tmp2, w*h, hf_mul*32);
- add_bufs(tmp2, dst, dst, w*h);
- }
-
- /* normalize texture to use four bits */
- normalize_buf(dst, w*h, 15);
-}
-
-
-/***************************
- ** Color table generator **
- ***************************/
-
-static inline int mix_channel(int value1, int value2, int alpha)
-{
- return (value1*(255 - alpha) + value2*alpha)>>8;
-}
-
-
-/**
- * Create 3D color table
- */
-template
-static void create_coltab(PT *dst, Color c0, Color c1, Color c2, Color bg)
-{
- for (int i = 0; i < 16; i++)
- for (int j = 0; j < 16; j++)
- for (int k = 0; k < 16; k++) {
-
- int r = bg.r;
- int g = bg.g;
- int b = bg.b;
-
- r = mix_channel(r, c2.r, k*16);
- g = mix_channel(g, c2.g, k*16);
- b = mix_channel(b, c2.b, k*16);
-
- r = mix_channel(r, c1.r, j*16);
- g = mix_channel(g, c1.g, j*16);
- b = mix_channel(b, c1.b, j*16);
-
- r = mix_channel(r, c0.r, i*8);
- g = mix_channel(g, c0.g, i*8);
- b = mix_channel(b, c0.b, i*8);
-
- int v = (((i ^ j ^ k)<<1) & 0xff) + 128 + 64;
-
- r = (r + v)>>1;
- g = (g + v)>>1;
- b = (b + v)>>1;
-
-// r = g = b = min(255, 50 + ((i*j*128 + j*k*128 + k*i*128)>>8));
-
- v = 180;
- r = (v*r + (255 - v)*255)>>8;
- g = (v*g + (255 - v)*255)>>8;
- b = (v*b + (255 - v)*255)>>8;
-
- dst[(k<<8) + (j<<4) + i].rgba(r, g, b);
- }
-}
-
-
-template
-static void compose(PT *dst, int dst_w, int dst_h, int x_start, int x_end,
- short src1[], int src1_y,
- short src2[], int src2_y,
- short src3[], int src3_y, int src_w, int src_h,
- PT coltab[])
-{
- for (int k = 0; k <= x_end; k += src_w) {
-
- int x_offset = max(0, x_start - k);
- int x_max = min(x_end - k, src_w - 1);
-
- for (int j = 0; j < dst_h; j++) {
-
- short *s1 = src1 + x_offset + ((src1_y + j)%src_h)*src_w;
- short *s2 = src2 + x_offset + ((src2_y + j)%src_h)*src_w;
- short *s3 = src3 + x_offset + ((src3_y + j)%src_h)*src_w;
- PT *d = dst + x_offset + j*dst_w + k;
-
- for (int i = x_offset; i <= x_max; i++)
- *d++ = coltab[*s1++ + *s2++ + *s3++];
- }
- }
-}
-
-
-template
-static void copy(PT *dst, int dst_w, int dst_h, int x_start, int x_end,
- PT *src, int src_y, int src_w, int src_h)
-{
- for (int k = 0; k <= x_end; k += src_w) {
-
- int x_offset = max(0, x_start - k);
- int x_max = min(x_end - k, src_w - 1);
-
- for (int j = 0; j < dst_h; j++) {
-
- PT *s = src + x_offset + ((src_y + j)%src_h)*src_w;
- PT *d = dst + x_offset + j*dst_w + k;
-
- if (x_max - x_offset >= 0)
- memcpy(d, s, (x_max - x_offset + 1)*sizeof(PT));
- }
- }
-}
-
-
-/*****************
- ** Constructor **
- *****************/
-
-template
-Sky_texture::Sky_texture()
-{
- /* create nice-looking textures */
- brew_texture(_tmp[0], _buf[0], _bufs[0][0], TW, TH, 3, 7, 1, 30, 30, 10);
- brew_texture(_tmp[0], _buf[0], _bufs[1][0], TW, TH, 3, 16, 3, 50, 40, 30);
- brew_texture(_tmp[0], _buf[0], _bufs[2][0], TW, TH, 5, 40, 11, 70, 0, 0);
-
- /* shift texture 1 to bits 4 to 7 */
- multiply_buf(_bufs[1][0], TW*TH, 16*256);
-
- /* shift texture 2 to bits 8 to 11 */
- multiply_buf(_bufs[2][0], TW*TH, 16*16*256);
-
- /* create color table */
- create_coltab(_coltab, Color(255, 255, 255),
- Color( 0, 0, 0),
- Color(255, 255, 255),
- Color( 80, 88, 112));
-
- /* create fallback texture */
- compose(_fallback[0], TW, TH, 0, TW - 1,
- _bufs[0][0], 0, _bufs[1][0], 0, _bufs[2][0], 0,
- TW, TH, _coltab);
-}
-
-
-/*****************************************
- ** Implementation of Element interface **
- *****************************************/
-
-template
-void Sky_texture::draw(Canvas *c, int px, int py)
-{
- PT *addr = static_cast(c->addr());
-
- if (!addr) return;
-
- int cx1 = c->clip_x1();
- int cy1 = c->clip_y1();
- int cx2 = c->clip_x2();
- int cy2 = c->clip_y2();
-
- int v = -py;
- int y0 = cy1 + v;
- int y1 = cy1 + (( (5*v)/16)%TH);
- int y2 = cy1 + (((11*v)/16)%TH);
-
- addr += cy1*c->w();
-
- if (Config::background_detail == 0) {
- copy(addr, c->w(), cy2 - cy1 + 1, cx1, cx2,
- _fallback[0], cy1 - py, TW, TH);
- return;
- }
-
- compose(addr, c->w(), cy2 - cy1 + 1, cx1, cx2,
- _bufs[0][0], y0, _bufs[1][0], y1, _bufs[2][0], y2,
- TW, TH, _coltab);
-}
-
-
-#include "canvas_rgb565.h"
-template class Sky_texture;
diff --git a/demo/src/app/scout/common/test.txt b/demo/src/app/scout/common/test.txt
deleted file mode 100644
index d9e491ae6a..0000000000
--- a/demo/src/app/scout/common/test.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- Genode Demonstration
-
- Norman Feske
-
-[image setup]
-
-Introduction
-############
-
diff --git a/demo/src/app/scout/common/widgets.cc b/demo/src/app/scout/common/widgets.cc
deleted file mode 100644
index c53103a4d6..0000000000
--- a/demo/src/app/scout/common/widgets.cc
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * \brief GUI elements
- * \date 2005-10-24
- * \author Norman Feske
- */
-
-/*
- * Copyright (C) 2005-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.
- */
-
-#include "miscmath.h"
-#include "widgets.h"
-
-
-/*************
- ** Docview **
- *************/
-
-void Docview::format_fixed_width(int w)
-{
- _min_w = _min_h = 0;
-
- if (_cont) {
- _cont->format_fixed_width(w - 2*_padx - _right_pad);
- _min_w = w;
- _min_h = _voffset + _cont->min_h();
- }
-
- if (_bg)
- _bg->geometry(0, 0, _min_w, _min_h);
-}
-
-
-void Docview::draw(Canvas *c, int x, int y)
-{
- if (_bg) _bg->draw(c, _x + x, _y + y);
- if (_cont) _cont->draw(c, _x + x, _y + y);
-}
-
-
-Element *Docview::find(int x, int y)
-{
- if (!Element::find(x, y)) return 0;
- Element *res = _cont ? _cont->find(x - _x, y - _y) : 0;
- return res ? res : this;
-}
-
-
-void Docview::geometry(int x, int y, int w, int h)
-{
- ::Element::geometry(x, y, w, h);
-
- if (_cont) _cont->geometry(_padx, _voffset, _cont->min_w(), h - _voffset);
-}
-
-
-/***********************
- ** Horizontal shadow **
- ***********************/
-
-template
-void Horizontal_shadow::draw(Canvas *c, int x, int y)
-{
- PT *addr = static_cast(c->addr());
-
- if (!addr) return;
-
- const int cx1 = c->clip_x1();
- const int cy1 = c->clip_y1();
- const int cx2 = c->clip_x2();
- const int cy2 = c->clip_y2();
-
- x += _x;
- y += _y;
- int w = _w;
- int h = _h;
-
- int curr_a = INTENSITY;
- int step = _h ? (curr_a/_h) : 0;
-
- if (x < cx1) {
- w -= cx1 - x;
- x = cx1;
- }
-
- if (y < cy1) {
- h -= cy1 - y;
- curr_a -= (cy1 - y)*step;
- y = cy1;
- }
-
- if (w > cx2 - x + 1)
- w = cx2 - x + 1;
-
- if (h > cy2 - y + 1)
- h = cy2 - y + 1;
-
- addr += c->w()*y + x;
-
- PT shadow_color(0,0,0);
-
- for (int j = 0; j < h; j++, addr += c->w()) {
-
- PT *d = addr;
-
- for (int i = 0; i < w; i++, d++)
- *d = PT::mix(*d, shadow_color, curr_a);
-
- curr_a -= step;
- }
-}
-
-
-/**********
- ** Icon **
- **********/
-
-template
-Icon::Icon()
-{
- memset(_pixel, 0, sizeof(_pixel));
- memset(_alpha, 0, sizeof(_alpha));
- memset(_shadow, 0, sizeof(_shadow));
- _icon_alpha = 255;
-}
-
-
-template
-void Icon::rgba(unsigned char *src, int vshift, int shadow)
-{
- /* convert rgba values to pixel type and alpha channel */
- for (int j = 0; j < H; j++)
- for (int i = 0; i < W; i++, src += 4) {
- _pixel[j][i].rgba(src[0], src[1], src[2]);
- _alpha[j][i] = src[3];
- }
-
- /* handle special case of no shadow */
- if (shadow == 0) return;
-
- /* generate shadow shape from blurred alpha channel */
- for (int j = 1; j < H - 4; j++)
- for (int i = 1; i < W - 2; i++) {
- int v = 0;
- for (int k = -1; k <= 1; k++)
- for (int l = -1; l <=1; l++)
- v += _alpha[(j + k + H)%H][(i + l + W)%W];
-
- _shadow[j + 3][i] = v>>shadow;
- }
-
- /* shift vertically */
- if (vshift > 0)
- for (int j = H - 1; j >= vshift; j--)
- for (int i = 0; i < W; i++) {
- _pixel[j][i] = _pixel[j - vshift][i];
- _alpha[j][i] = _alpha[j - vshift][i];
- }
-
- /* apply shadow to pixels */
- PT shcol(0, 0, 0);
- for (int j = 0; j < H; j++)
- for (int i = 0; i < W; i++) {
- _pixel[j][i] = PT::mix(shcol, _pixel[j][i], _alpha[j][i]);
- _alpha[j][i] = min(255, _alpha[j][i] + _shadow[j][i]);
- }
-}
-
-
-static inline void blur(unsigned char *src, unsigned char *dst, int w, int h)
-{
- const int kernel = 3;
- int scale = (kernel*2 + 1)*(kernel*2 + 1);
-
- scale = (scale*210)>>8;
- for (int j = kernel; j < h - kernel; j++)
- for (int i = kernel; i < w - kernel; i++) {
- int v = 0;
- for (int k = -kernel; k <= kernel; k++)
- for (int l = -kernel; l <= kernel; l++)
- v += src[w*(j + k) + (i + l)];
-
- dst[w*j + i] = min(v/scale, 255);
- }
-}
-
-
-template
-void Icon::glow(unsigned char *src, Color c)
-{
- /* extract shape from alpha channel of rgba source image */
- for (int j = 0; j < H; j++)
- for (int i = 0; i < W; i++, src += 4)
- _alpha[j][i] = src[3] ? 255 : 0;
-
- for (int i = 0; i < 2; i++) {
- blur(_alpha[0], _shadow[0], W, H);
- blur(_shadow[0], _alpha[0], W, H);
- }
-
- /* assign pixels and alpha */
- PT s(c.r, c.g, c.b);
- for (int j = 0; j < H; j++)
- for (int i = 0; i < W; i++, src += 4)
- _pixel[j][i] = s;
-}
-
-
-/*
- * An Icon has the following layout:
- *
- * P1---+--------+----+
- * | cs | hs | cs | top row
- * +----P2-------+----+
- * | | | |
- * | vs | | vs | mid row
- * | | | |
- * +----+--------P3---+
- * | cs | hs | cs | low row
- * +------------------P4
- *
- * cs ... corner slice
- * hs ... horizontal slice
- * vs ... vertical slice
- */
-
-
-/**
- * Copy pixel with alpha
- */
-template
-static inline void transfer_pixel(PT &src, int src_a, int alpha, PT *dst)
-{
- if (src_a) {
- int register a = (src_a * alpha)>>8;
- if (a) *dst = PT::mix(*dst, src, a);
- }
-}
-
-
-/**
- * Draw corner slice
- */
-template
-static void draw_cslice(PT *src, unsigned char *src_a, int src_pitch, int alpha,
- PT *dst, int dst_pitch, int w, int h)
-{
- for (int j = 0; j < h; j++) {
-
- PT *s = src;
- unsigned char *sa = src_a;
- PT *d = dst;
-
- for (int i = 0; i < w; i++, s++, sa++, d++)
- transfer_pixel(*s, *sa, alpha, d);
-
- src += src_pitch, src_a += src_pitch, dst += dst_pitch;
- }
-}
-
-
-/**
- * Draw horizontal slice
- */
-template
-static void draw_hslice(PT *src, unsigned char *src_a, int src_pitch, int alpha,
- PT *dst, int dst_pitch, int w, int h)
-{
- for (int j = 0; j < h; j++) {
-
- PT s = *src;
- int sa = *src_a;
- PT *d = dst;
-
- for (int i = 0; i < w; i++, d++)
- transfer_pixel(s, sa, alpha, d);
-
- src += src_pitch, src_a += src_pitch, dst += dst_pitch;
- }
-}
-
-
-/**
- * Draw vertical slice
- */
-template
-static void draw_vslice(PT *src, unsigned char *src_a, int src_pitch, int alpha,
- PT *dst, int dst_pitch, int w, int h)
-{
- for (int i = 0; i < w; i++) {
-
- PT s = *src;
- int sa = *src_a;
- PT *d = dst;
-
- for (int j = 0; j < h; j++, d += dst_pitch)
- transfer_pixel(s, sa, alpha, d);
-
- src += 1, src_a += 1, dst += 1;
- }
-}
-
-
-/**
- * Draw center slice
- */
-template
-static void draw_center(PT *src, unsigned char *src_a, int src_pitch, int alpha,
- PT *dst, int dst_pitch, int w, int h)
-{
- PT s = *src;
- int sa = *src_a;
-
- for (int j = 0; j < h; j++, dst += dst_pitch) {
-
- PT *d = dst;
-
- for (int i = 0; i < w; i++, d++)
- transfer_pixel(s, sa, alpha, d);
- }
-}
-
-
-/**
- * Clip rectangle against clipping region
- *
- * The out parameters are the resulting x/y offsets and the
- * visible width and height.
- *
- * \return 1 if rectangle intersects with clipping region,
- * 0 otherwise
- */
-static inline int clip(int px1, int py1, int px2, int py2,
- int cx1, int cy1, int cx2, int cy2,
- int *out_x, int *out_y, int *out_w, int *out_h)
-{
- /* determine intersection of rectangle and clipping region */
- int x1 = max(px1, cx1);
- int y1 = max(py1, cy1);
- int x2 = min(px2, cx2);
- int y2 = min(py2, cy2);
-
- *out_w = x2 - x1 + 1;
- *out_h = y2 - y1 + 1;
- *out_x = x1 - px1;
- *out_y = y1 - py1;
-
- return (*out_w > 0) && (*out_h > 0);
-}
-
-
-template
-void Icon::draw(Canvas *c, int x, int y)
-{
- PT *addr = static_cast(c->addr());
-
- if (!addr || (_icon_alpha == 0)) return;
-
- const int cx1 = c->clip_x1();
- const int cy1 = c->clip_y1();
- const int cx2 = c->clip_x2();
- const int cy2 = c->clip_y2();
-
- /* determine point positions */
- const int x1 = x + _x;
- const int y1 = y + _y;
- const int x4 = x1 + _w - 1;
- const int y4 = y1 + _h - 1;
- const int x2 = x1 + W/2;
- const int y2 = y1 + H/2;
- const int x3 = max(x4 - W/2, x2);
- const int y3 = max(y4 - H/2, y2);
-
- const int tx1 = 0;
- const int ty1 = 0;
- const int tx4 = W - 1;
- const int ty4 = H - 1;
- const int tx2 = W/2;
- const int ty2 = H/2;
- const int tx3 = max(tx4 - W/2, tx2);
- const int ty3 = max(ty4 - H/2, ty2);
-
- PT *src = _pixel[0] + W*ty1;
- unsigned char *src_a = _alpha[0] + W*ty1;
- int dx, dy, w, h;
-
- /*
- * top row
- */
-
- if (clip(x1, y1, x2 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_cslice(src + tx1 + dy*W + dx, src_a + tx1 + dy*W + dx, W, _icon_alpha,
- addr + (y1 + dy)*c->w() + x1 + dx, c->w(), w, h);
-
- if (clip(x2, y1, x3 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_hslice(src + tx2 + dy*W + dx, src_a + tx2 + dy*W + dx, W, _icon_alpha,
- addr + (y1 + dy)*c->w() + x2 + dx, c->w(), w, h);
-
- if (clip(x3, y1, x4, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_cslice(src + tx3 + dy*W + dx, src_a + tx3 + dy*W + dx, W, _icon_alpha,
- addr + (y1 + dy)*c->w() + x3 + dx, c->w(), w, h);
-
- /*
- * mid row
- */
-
- src = _pixel[0] + W*ty2;
- src_a = _alpha[0] + W*ty2;
-
- if (clip(x1, y2, x2 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_vslice(src + tx1 + dx, src_a + tx1 + dx, W, _icon_alpha,
- addr + (y2 + dy)*c->w() + x1 + dx, c->w(), w, h);
-
- if (clip(x2, y2, x3 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_center(src + tx2, src_a + tx2, W, _icon_alpha,
- addr + (y2 + dy)*c->w() + x2 + dx, c->w(), w, h);
-
- if (clip(x3, y2, x4, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_vslice(src + tx3 + dx, src_a + tx3 + dx, W, _icon_alpha,
- addr + (y2 + dy)*c->w() + x3 + dx, c->w(), w, h);
-
- /*
- * low row
- */
-
- src = _pixel[0] + W*ty3;
- src_a = _alpha[0] + W*ty3;
-
- if (clip(x1, y3, x2 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_cslice(src + tx1 + dy*W + dx, src_a + tx1 + dy*W + dx, W, _icon_alpha,
- addr + (y3 + dy)*c->w() + x1 + dx, c->w(), w, h);
-
- if (clip(x2, y3, x3 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_hslice(src + tx2 + dy*W + dx, src_a + tx2 + dy*W + dx, W, _icon_alpha,
- addr + (y3 + dy)*c->w() + x2 + dx, c->w(), w, h);
-
- if (clip(x3, y3, x4, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h))
- draw_cslice(src + tx3 + dy*W + dx, src_a + tx3 + dy*W + dx, W, _icon_alpha,
- addr + (y3 + dy)*c->w() + x3 + dx, c->w(), w, h);
-}
-
-
-template
-Element *Icon::find(int x, int y)
-{
- if (!Element::find(x, y)) return 0;
-
- x -= _x;
- y -= _y;
-
- /* check icon boundaries (the height is flexible) */
- if ((x < 0) || (x >= W) || (y < 0) || (y >= _h)) return 0;
-
- /* upper part of the icon */
- if (y <= H/2) return _alpha[y][x] ? this : 0;
-
- /* lower part of the icon */
- if (y > _h - H/2) return _alpha[y - _h + H][x] ? this : 0;
-
- /* middle part of the icon */
- if (_alpha[H/2][x]) return this;
-
- return 0;
-}
-
-#include "canvas_rgb565.h"
-template class Horizontal_shadow;
-template class Horizontal_shadow;
-template class Icon;
-template class Icon;
-template class Icon;
diff --git a/demo/src/app/scout/include/config.h b/demo/src/app/scout/config.h
similarity index 92%
rename from demo/src/app/scout/include/config.h
rename to demo/src/app/scout/config.h
index 3578e247fe..4aad14e6f5 100644
--- a/demo/src/app/scout/include/config.h
+++ b/demo/src/app/scout/config.h
@@ -14,13 +14,12 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
-namespace Config
-{
+namespace Scout { namespace Config {
extern int iconbar_detail;
extern int background_detail;
extern int mouse_cursor;
extern int browser_attr;
-};
+} }
#endif /* _CONFIG_H_ */
diff --git a/demo/src/app/scout/common/doc.cc b/demo/src/app/scout/doc.cc
similarity index 99%
rename from demo/src/app/scout/common/doc.cc
rename to demo/src/app/scout/doc.cc
index c69aacbcef..d08afda6f7 100644
--- a/demo/src/app/scout/common/doc.cc
+++ b/demo/src/app/scout/doc.cc
@@ -14,6 +14,8 @@
#include "elements.h"
#include "styles.h"
+using namespace Scout;
+
Document *create_document()
{
Document *doc = new Document();
diff --git a/demo/src/app/scout/common/elements.cc b/demo/src/app/scout/elements.cc
similarity index 52%
rename from demo/src/app/scout/common/elements.cc
rename to demo/src/app/scout/elements.cc
index 7f942ee1db..02b4c94496 100644
--- a/demo/src/app/scout/common/elements.cc
+++ b/demo/src/app/scout/elements.cc
@@ -11,10 +11,13 @@
* under the terms of the GNU General Public License version 2.
*/
-#include "miscmath.h"
+#include
+
#include "elements.h"
#include "browser.h"
+using namespace Scout;
+
/*************
** Element **
@@ -29,14 +32,14 @@ Element::~Element()
void Element::redraw_area(int x, int y, int w, int h)
{
- x += _x;
- y += _y;
+ x += _position.x();
+ y += _position.y();
/* intersect specified area with element geometry */
- int x1 = max(x, _x);
- int y1 = max(y, _y);
- int x2 = min(x + w - 1, _x + _w - 1);
- int y2 = min(y + h - 1, _y + _h - 1);
+ int x1 = max(x, _position.x());
+ int y1 = max(y, _position.y());
+ int x2 = min(x + w - 1, _position.x() + (int)_size.w() - 1);
+ int y2 = min(y + h - 1, _position.y() + (int)_size.h() - 1);
if (x1 > x2 || y1 > y2) return;
@@ -46,10 +49,10 @@ void Element::redraw_area(int x, int y, int w, int h)
}
-Element *Element::find(int x, int y)
+Element *Element::find(Point position)
{
- if (x >= _x && x < _x + _w
- && y >= _y && y < _y + _h
+ if (position.x() >= _position.x() && position.x() < _position.x() + (int)_size.w()
+ && position.y() >= _position.y() && position.y() < _position.y() + (int)_size.h()
&& _flags.findable)
return this;
@@ -59,12 +62,14 @@ Element *Element::find(int x, int y)
Element *Element::find_by_y(int y)
{
- return (y >= _y && y < _y + _h) ? this : 0;
+ return (y >= _position.y() && y < _position.y() + (int)_size.h()) ? this : 0;
}
-int Element::abs_x() { return _x + (_parent ? _parent->abs_x() : 0); }
-int Element::abs_y() { return _y + (_parent ? _parent->abs_y() : 0); }
+Point Element::abs_position() const
+{
+ return _position + (_parent ? _parent->abs_position() : Point(0, 0));
+}
Element *Element::chapter()
@@ -74,12 +79,6 @@ Element *Element::chapter()
}
-Browser *Element::browser()
-{
- return _parent ? _parent->browser() : 0;
-}
-
-
/********************
** Parent element **
********************/
@@ -97,7 +96,7 @@ void Parent_element::append(Element *e)
}
-void Parent_element::remove(Element *e)
+void Parent_element::remove(Element const *e)
{
if (e == _first)
_first = e->next;
@@ -124,12 +123,13 @@ void Parent_element::remove(Element *e)
}
-void Parent_element::forget(Element *e)
+void Parent_element::forget(Element const *e)
{
- if (e->parent() == this)
+ if (e->has_parent(this))
remove(e);
- _parent->forget(e);
+ if (_parent)
+ _parent->forget(e);
}
@@ -141,35 +141,34 @@ int Parent_element::_format_children(int x, int w)
for (Element *e = _first; e; e = e->next) {
e->format_fixed_width(w);
- e->geometry(x, y, e->min_w(), e->min_h());
- y += e->min_h();
+ e->geometry(Rect(Point(x, y), e->min_size()));
+ y += e->min_size().h();
}
return y;
}
-void Parent_element::draw(Canvas *c, int x, int y)
+void Parent_element::draw(Canvas_base &canvas, Point abs_position)
{
for (Element *e = _first; e; e = e->next)
- e->try_draw(c, _x + x, _y + y);
+ e->try_draw(canvas, abs_position + _position);
}
-Element *Parent_element::find(int x, int y)
+Element *Parent_element::find(Point position)
{
/* check if position is outside the parent element */
- if (x < _x || x >= _x + _w
- || y < _y || y >= _y + _h)
+ if (position.x() < _position.x() || position.x() >= _position.x() + (int)_size.w()
+ || position.y() < _position.y() || position.y() >= _position.y() + (int)_size.h())
return 0;
- x -= _x;
- y -= _y;
+ position = position - _position;
/* check children */
Element *ret = this;
for (Element *e = _first; e; e = e->next) {
- Element *res = e->find(x, y);
+ Element *res = e->find(position);
if (res) ret = res;
}
@@ -180,10 +179,10 @@ Element *Parent_element::find(int x, int y)
Element *Parent_element::find_by_y(int y)
{
/* check if position is outside the parent element */
- if (y < _y || y >= _y + _h)
+ if (y < _position.y() || y >= _position.y() + (int)_size.h())
return 0;
- y -= _y;
+ y -= _position.y();
/* check children */
for (Element *e = _first; e; e = e->next) {
@@ -195,31 +194,26 @@ Element *Parent_element::find_by_y(int y)
}
-void Parent_element::geometry(int x, int y, int w, int h)
+void Parent_element::geometry(Rect rect)
{
- ::Element::geometry(x, y, w, h);
+ ::Element::geometry(rect);
if (!_last || !_last->is_bottom()) return;
- _last->geometry(_last->x(), h - _last->h(), _last->w(), _last->h());
+ _last->geometry(Rect(Point(_last->position().x(),
+ rect.h() - _last->size().h()), _last->size()));
}
-void Parent_element::fill_cache(Canvas *c)
+void Parent_element::fill_cache(Canvas_base &canvas)
{
- for (Element *e = _first; e; e = e->next) e->fill_cache(c);
+ for (Element *e = _first; e; e = e->next) e->fill_cache(canvas);
}
-void Parent_element::flush_cache(Canvas *c)
+void Parent_element::flush_cache(Canvas_base &canvas)
{
- for (Element *e = _first; e; e = e->next) e->flush_cache(c);
-}
-
-
-void Parent_element::curr_link_destination(Element *dst)
-{
- for (Element *e = _first; e; e = e->next) e->curr_link_destination(dst);
+ for (Element *e = _first; e; e = e->next) e->flush_cache(canvas);
}
@@ -237,27 +231,28 @@ Token::Token(Style *style, const char *str, int len)
_outline = Color(0, 0, 0, 0);
if (!_style) return;
- _min_w = _style->font->str_w(str, len) + _style->font->str_w(" ", 1);
- _min_h = _style->font->str_h(str, len);
+ _min_size = Area(_style->font->str_w(str, len) + _style->font->str_w(" ", 1),
+ _style->font->str_h(str, len));
}
-void Token::draw(Canvas *c, int x, int y)
+void Token::draw(Canvas_base &canvas, Point abs_position)
{
if (!_style) return;
if (_style->attr & Style::ATTR_BOLD)
- _outline.rgba(_col.r, _col.g, _col.b, 32);
+ _outline = Color(_col.r, _col.g, _col.b, 32);
- x++; y++;
+ abs_position = abs_position + Point(1, 1);
if (_outline.a)
for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++)
- c->draw_string(_x + x +i , _y + y +j, _style->font, _outline, _str, _len);
+ canvas.draw_string(_position.x() + abs_position.x() + i,
+ _position.y() + abs_position.y() + j,
+ _style->font, _outline, _str, _len);
- c->draw_string(_x + x, _y + y, _style->font, _col, _str, _len);
-
- if (_flags.link)
- c->draw_box(_x + x, _y + y + _h - 1, _w, 1, Color(0,0,255));
+ canvas.draw_string(_position.x() + abs_position.x(),
+ _position.y() + abs_position.y(),
+ _style->font, _col, _str, _len);
}
@@ -302,29 +297,29 @@ void Block::append_text(const char *str, Style *style,
void Block::format_fixed_width(int w)
{
int x = 0, y = 0;
- int line_max_h = 0;
- int max_w = 0;
+ unsigned line_max_h = 0;
+ unsigned max_w = 0;
for (Element *e = _first; e; e = e->next) {
/* wrap at the end of the line */
- if (x + e->min_w() >= w) {
+ if (x + (int)e->min_size().w() >= w) {
x = _second_indent;
y += line_max_h;
line_max_h = 0;
}
/* position element */
- if (max_w < x + e->min_w())
- max_w = x + e->min_w();
+ if (max_w < x + e->min_size().w())
+ max_w = x + e->min_size().w();
- e->geometry(x, y, e->min_w(), e->min_h());
+ e->geometry(Rect(Point(x, y), e->min_size()));
/* determine token with the biggest height of the line */
- if (line_max_h < e->min_h())
- line_max_h = e->min_h();
+ if (line_max_h < e->min_size().h())
+ line_max_h = e->min_size().h();
- x += e->min_w();
+ x += e->min_size().w();
}
/*
@@ -336,30 +331,30 @@ void Block::format_fixed_width(int w)
for (Element *line = _first; line; ) {
Element *e;
- int cy = line->y(); /* y position of current line */
- int max_x; /* rightmost position */
+ int cy = line->position().y(); /* y position of current line */
+ int max_x; /* rightmost position */
/* determine free space at the end of the line */
- for (max_x = 0, e = line; e && (e->y() == cy); e = e->next)
- max_x = max(max_x, e->x() + e->w() - 1);
+ for (max_x = 0, e = line; e && (e->position().y() == cy); e = e->next)
+ max_x = max(max_x, e->position().x() + (int)e->size().w() - 1);
/* indent elements of the line according to the alignment */
int dx = 0;
- if (_align == CENTER) dx = max(0, (max_w - max_x)/2);
- if (_align == RIGHT) dx = max(0, max_w - max_x);
- for (e = line; e && (e->y() == cy); e = e->next)
- e->geometry(e->x() + dx, e->y(), e->w(), e->h());
+ if (_align == CENTER) dx = max(0UL, (max_w - max_x)/2);
+ if (_align == RIGHT) dx = max(0UL, max_w - max_x);
+ for (e = line; e && (e->position().y() == cy); e = e->next)
+ e->geometry(Rect(Point(e->position().x() + dx, e->position().y()),
+ e->size()));
/* find first element of next line */
- for (; line && (line->y() == cy); line = line->next);
+ for (; line && (line->position().y() == cy); line = line->next);
}
}
/* line break at the end of the last line */
if (line_max_h) y += line_max_h;
- _min_h = y + 5;
- _min_w = max_w;
+ _min_size = Area(max_w, y + 5);
}
@@ -369,20 +364,21 @@ void Block::format_fixed_width(int w)
void Center::format_fixed_width(int w)
{
- _min_h = _format_children(0, w);
+ _min_size = Area(_min_size.w(), _format_children(0, w));
/* determine highest min with of children */
- int highest_min_w = 0;
+ unsigned highest_min_w = 0;
for (Element *e = _first; e; e = e->next)
- if (highest_min_w < e->min_w())
- highest_min_w = e->min_w();
+ if (highest_min_w < e->min_size().w())
+ highest_min_w = e->min_size().w();
- int dx = (w - highest_min_w)>>1;
- _min_w = max(w, highest_min_w);
+ unsigned dx = (w - highest_min_w)>>1;
+
+ _min_size = Area(max((unsigned)w, highest_min_w), _min_size.h());
/* move children to center */
for (Element *e = _first; e; e = e->next)
- e->geometry(dx, e->y(), e->w(), e->h());
+ e->geometry(Rect(Point(dx, e->position().y()), e->size()));
}
@@ -390,18 +386,23 @@ void Center::format_fixed_width(int w)
** Verbatim **
**************/
-void Verbatim::draw(Canvas *c, int x, int y)
+void Verbatim::draw(Canvas_base &canvas, Point abs_position)
{
static const int pad = 5;
- c->draw_box(_x + x + pad, _y + y + pad, _w - 2*pad, _h - 2*pad, bgcol);
+ canvas.draw_box(_position.x() + abs_position.x() + pad,
+ _position.y() + abs_position.x() + pad,
+ _size.w() - 2*pad, _size.h() - 2*pad, bgcol);
- int cx1 = c->clip_x1(), cy1 = c->clip_y1();
- int cx2 = c->clip_x2(), cy2 = c->clip_y2();
+ int cx1 = canvas.clip().x1(), cy1 = canvas.clip().y1();
+ int cx2 = canvas.clip().x2(), cy2 = canvas.clip().y2();
- c->clip(_x + x + pad, _y + y + pad, _w - 2*pad, _h - 2*pad);
- Parent_element::draw(c, x, y);
- c->clip(cx1, cy1, cx2 - cx1 + 1, cy2 - cy1 + 1);
+ canvas.clip(Rect(Point(_position.x() + abs_position.x() + pad,
+ _position.y() + abs_position.y() + pad),
+ Area(_size.w() - 2*pad, _size.h() - 2*pad)));
+ Parent_element::draw(canvas, abs_position);
+
+ canvas.clip(Rect(Point(cx1, cy1), Area(cx2 - cx1 + 1, cy2 - cy1 + 1)));
}
@@ -412,13 +413,12 @@ void Verbatim::format_fixed_width(int w)
for (Element *e = _first; e; e = e->next) {
/* position element */
- e->geometry(10, y, e->min_w(), e->min_h());
+ e->geometry(Rect(Point(10, y), e->min_size()));
- y += e->min_h();
+ y += e->min_size().h();
}
- _min_h = y + 10;
- _min_w = w;
+ _min_size = Area(w, y + 10);
}
@@ -430,8 +430,12 @@ void Link_token::handle(Event &e)
{
if (e.type != Event::PRESS) return;
- /* make browser to follow link */
- Browser *b = browser();
+ /* lookup browser, in which the link token resides */
+ Browser *b = 0;
+ for (Element *e = this; e && !b; e = e->parent())
+ b = dynamic_cast(e);
+
+ /* let browser follow link */
if (b && _dst) b->go_to(_dst);
}
diff --git a/demo/src/app/scout/elements.h b/demo/src/app/scout/elements.h
new file mode 100644
index 0000000000..3801907149
--- /dev/null
+++ b/demo/src/app/scout/elements.h
@@ -0,0 +1,590 @@
+/*
+ * \brief Document structure elements
+ * \date 2005-10-24
+ * \author Norman Feske