]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/scout/lib/src/panel.h
Some minor fixes.
[l4.git] / l4 / pkg / scout / lib / src / panel.h
1 #pragma once
2
3 #include "browser_if.h"
4 #include "refracted_icon.h"
5
6 #include <l4/scout-gfx/box_layout>
7 #include <l4/scout-gfx/stack_layout>
8
9
10 class Factory;
11
12
13 #define IOR_MAP       _binary_ior_map_start
14 #define HOME_RGBA     _binary_home_rgba_start
15 #define COVER_RGBA    _binary_cover_rgba_start
16 #define INDEX_RGBA    _binary_index_rgba_start
17 #define ABOUT_RGBA    _binary_about_rgba_start
18 #define FORWARD_RGBA  _binary_forward_rgba_start
19 #define BACKWARD_RGBA _binary_backward_rgba_start
20
21 extern short         IOR_MAP[];
22 extern unsigned char HOME_RGBA[];
23 extern unsigned char COVER_RGBA[];
24 extern unsigned char INDEX_RGBA[];
25 extern unsigned char ABOUT_RGBA[];
26 extern unsigned char FORWARD_RGBA[];
27 extern unsigned char BACKWARD_RGBA[];
28
29 /* icon graphics data */
30 static unsigned char *glow_icon_gfx[] = {
31     HOME_RGBA,
32     BACKWARD_RGBA,
33     FORWARD_RGBA,
34     INDEX_RGBA,
35     ABOUT_RGBA,
36 };
37
38 /* color definitions for glowing effect of the icons */
39 static Scout_gfx::Color glow_icon_col[] = {
40     Scout_gfx::Color(210, 210,   0),
41     Scout_gfx::Color(  0,   0, 160),
42     Scout_gfx::Color(  0,   0, 160),
43     Scout_gfx::Color(  0, 160,   0),
44     Scout_gfx::Color(160,   0,   0),
45 };
46
47 /**
48  * Transform rgba source image to image with native pixel type
49  *
50  * If we specify an empty buffer as alpha channel (all values zero), we simply
51  * assign the source image data to the destination buffer. If there are valid
52  * values in the destination alpha channel, we paint the source image on top
53  * of the already present image data. This enables us to combine multiple
54  * rgba buffers (layers) into one destination buffer.
55  */
56 template <typename PTx>
57 static void extract_rgba(const unsigned char *_src, int w, int h,
58     typename PTx::Pixel *dst_pixel, unsigned char *dst_alpha)
59 {
60   using namespace Mag_gfx;
61   typedef typename PTx::Color Color;
62
63   Rgba32::Pixel const *src = reinterpret_cast<Rgba32::Pixel const*>(_src);
64
65   for (int i = 0; i < w*h; ++i, ++src)
66     {
67       Rgba32::Color const s = *src;
68       if (dst_alpha[i])
69         {
70           dst_pixel[i] = PTx::mix(dst_pixel[i], color_conv<Color>(s), s.a());
71           dst_alpha[i] = std::max((int)dst_alpha[i], s.a());
72         }
73       else
74         {
75           dst_pixel[i] = color_conv<Color>(s);
76           dst_alpha[i] = s.a();
77         }
78     }
79 }
80
81
82 template< typename PT >
83 class Panel : public Scout_gfx::Parent_widget
84 {
85   enum
86   {
87     ICON_HOME     = 0,
88     ICON_BACKWARD = 1,
89     ICON_FORWARD  = 2,
90     ICON_INDEX    = 3,
91     ICON_ABOUT    = 4
92   };
93
94   /**
95    * Constants
96    */
97   enum
98   {
99     _NUM_ICONS = 5,     /* number of icons          */
100     _IW        = 64,    /* browser icon width       */
101     _IH        = 64,    /* browser icon height      */
102     _PANEL_W   = 320,   /* panel tile width         */
103     _PANEL_H   = _IH,   /* panel tile height        */
104     _SB_XPAD   = 5,     /* hor. pad of scrollbar    */
105     _SB_YPAD   = 10,    /* vert. pad of scrollbar   */
106     _SCRATCH   = 7      /* scratching factor        */
107   };
108 protected:
109   typedef typename PT::Pixel Pixel;
110   Area preferred_size() const
111   {
112     if (child_layout())
113       return child_layout()->preferred_size();
114
115     return Area(0, 0);
116   }
117
118   Area min_size() const
119   {
120     if (child_layout())
121       return child_layout()->min_size();
122
123     return Area(0, 0);
124   }
125
126   Area max_size() const
127   {
128     if (child_layout())
129       return child_layout()->max_size();
130
131     return Area(Area::Max_w, Area::Max_h);
132   }
133
134   Mag_gfx::Orientations expanding() const { return Mag_gfx::Horizontal; }
135   bool empty() const { return false; }
136
137   void set_geometry(Rect const &r)
138   {
139     if (child_layout())
140       child_layout()->set_geometry(Rect(r.area()));
141
142     _pos = r.p1();
143     _size = min_size().max(r.area()).min(max_size());
144   }
145
146   Rect geometry() const { return Rect(_pos, _size); }
147
148   /**
149    * Widgets
150    */
151   Pixel                      _icon_fg        [_NUM_ICONS][_IH][_IW];
152   unsigned char              _icon_fg_alpha  [_NUM_ICONS][_IH][_IW];
153   Refracted_icon<PT, short>  _icon           [_NUM_ICONS];
154   Pixel                      _icon_backbuf   [_IH*2][_IW*2];
155   Pixel                      _panel_fg       [_PANEL_H][_PANEL_W];
156   unsigned char              _panel_fg_alpha [_PANEL_H][_PANEL_W];
157   short                      _panel_distmap  [_PANEL_H*2][_PANEL_W*2];
158   Refracted_icon<PT, short>  _panel;
159   Pixel                      _panel_backbuf  [_PANEL_H*2][_PANEL_W*2];
160   Scout_gfx::Icon           *_glow_icon[_NUM_ICONS];
161
162   class Ev_proxy : public Scout_gfx::Event_handler
163   {
164   private:
165     Widget *b;
166
167   public:
168     Ev_proxy(Widget *b) : b(b) {}
169     /**
170      * Event handler interface
171      */
172     bool handle(Scout_gfx::Event const &ev)
173     { return b->handle_event(ev); }
174   };
175
176   Ev_proxy _ev_proxy;
177
178   void handler(Widget *e, Browser_if *b, bool (Browser_if::*f)());
179
180 public:
181   Panel(Scout_gfx::Factory *f, Browser_if *);
182
183 };
184
185
186 /********************
187  ** Event handlers **
188  ********************/
189
190 class Iconbar_event_handler : public Scout_gfx::Event_handler
191 {
192 private:
193
194   Scout_gfx::Fader *_fader;
195   Browser_if *_b;
196   bool (Browser_if::*_f)();
197
198 public:
199
200   /**
201    * Constructor
202    */
203   Iconbar_event_handler(Scout_gfx::Fader *fader, Browser_if *b,
204                         bool (Browser_if::*f)())
205   : _fader(fader), _b(b), _f(f) {}
206
207   /**
208    * Event handler interface
209    */
210   bool handle(Scout_gfx::Event const &ev)
211   {
212     /* start movement with zero speed */
213     if ((ev.type != Scout_gfx::Event::PRESS) || (ev.key_cnt != 1))
214       return true;
215
216     /* no flashing by default */
217     int flash = (_b->*_f)();
218
219     /* flash clicked icon */
220     if (0 && flash)
221       {
222
223         /* flash fader to the max */
224         _fader->step(4);
225         _fader->curr(190);
226       }
227
228     return true;
229   }
230 };
231
232 template< typename PT >
233 void
234 Panel<PT>::handler(Widget *e, Browser_if *b, bool (Browser_if::*f)())
235 {
236   e->event_handler(new Iconbar_event_handler(dynamic_cast<Scout_gfx::Fader*>(e), b, f));
237 }
238
239 template< typename PT >
240 Panel<PT>::Panel(Scout_gfx::Factory *f, Browser_if *b)
241 : _ev_proxy(this)
242 {
243   using namespace Mag_gfx;
244   using namespace Scout_gfx;
245
246
247   _size = Area(_NUM_ICONS*_IW, _IH);
248
249   /* init icons */
250   memset(_icon_fg,       0, sizeof(_icon_fg));
251   memset(_icon_fg_alpha, 0, sizeof(_icon_fg_alpha));
252   for (int i = 0; i < _NUM_ICONS; i++)
253     {
254       /* convert rgba raw image to PT pixel format and alpha channel */
255       extract_rgba<PT>(COVER_RGBA, _IW, _IH,
256           _icon_fg[i][0], _icon_fg_alpha[i][0]);
257
258       /* assign back buffer, foreground and distmap to icon */
259       _icon[i].backbuf(_icon_backbuf[0], 1);
260       _icon[i].distmap(IOR_MAP, _IW*2, _IH*2);
261       _icon[i]._min_size = Area(_IW, _IH);
262       _icon[i].foreground(_icon_fg[i][0], _icon_fg_alpha[i][0]);
263
264       /* apply foreground graphics to icon */
265       extract_rgba<PT>(glow_icon_gfx[i], _IW, _IH,
266           _icon_fg[i][0], _icon_fg_alpha[i][0]);
267
268       _icon[i].event_handler(&_ev_proxy);
269
270       /* init glow icon */
271       Scout_gfx::Icon *fadeicon = f->create_icon();
272
273       _glow_icon[i] = fadeicon;
274       fadeicon->glow(glow_icon_gfx[i], Area(_IW, _IH), glow_icon_col[i]);
275       fadeicon->default_alpha(0);
276       fadeicon->focus_alpha(100);
277       fadeicon->alpha(0);
278     }
279
280   handler(_glow_icon[ICON_HOME], b, &Browser_if::go_home);
281   handler(_glow_icon[ICON_FORWARD], b, &Browser_if::go_forward);
282   handler(_glow_icon[ICON_BACKWARD], b, &Browser_if::go_backward);
283   handler(_glow_icon[ICON_INDEX], b, &Browser_if::go_toc);
284   handler(_glow_icon[ICON_ABOUT], b, &Browser_if::go_about);
285
286   /*
287    * All icons share the same distmap. Therefore we need to scratch
288    * only one distmap to affect all icons.
289    */
290   _icon[0].scratch(_SCRATCH);
291
292   /* create panel tile texture */
293   /*
294    * NOTE: The panel height must be the same as the icon height.
295    */
296   for (int j = 0; j < _PANEL_H; j++)
297     for (int i = 0; i < _PANEL_W; i++) {
298         _panel_fg       [j][i] = _icon_fg       [ICON_INDEX][j][i&0x1];
299         _panel_fg_alpha [j][i] = _icon_fg_alpha [ICON_INDEX][j][i&0x1] + random()%3;
300     }
301
302   /* init panel background */
303   _panel.backbuf(&_panel_backbuf[0][0]);
304   _panel.distmap(_panel_distmap[0], _PANEL_W*2, _PANEL_H*2);
305   _panel.foreground(_panel_fg[0], _panel_fg_alpha[0]);
306   _panel.scratch(_SCRATCH);
307   _panel.event_handler(&_ev_proxy);
308   _panel._min_size = Area(_IW, _IH);
309
310   Scout_gfx::Layout *l = Scout_gfx::Box_layout::create_horz();
311   set_child_layout(l);
312   for (int i = 0; i <= ICON_INDEX; i++) {
313       Scout_gfx::Layout *sl = Scout_gfx::Stack_layout::create();
314       sl->add_item(&_icon[i]);
315       sl->add_item(_glow_icon[i]);
316       l->add_item(sl);
317       append(&_icon[i]);
318       append(_glow_icon[i]);
319   }
320   append(&_panel);
321   l->add_item(&_panel);
322   Scout_gfx::Layout *sl = Scout_gfx::Stack_layout::create();
323   sl->add_item(&_icon[ICON_ABOUT]);
324   sl->add_item(_glow_icon[ICON_ABOUT]);
325   l->add_item(sl);
326   append(&_icon[ICON_ABOUT]);
327   append(_glow_icon[ICON_ABOUT]);
328 }
329
330