Merge lp:~canonical-dx-team/unity/unity.quicklist-support into lp:unity

Proposed by Jay Taoko
Status: Merged
Merged at revision: 610
Proposed branch: lp:~canonical-dx-team/unity/unity.quicklist-support
Merge into: lp:unity
Diff against target: 2843 lines (+1510/-1015)
13 files modified
po/unity.pot (+1/-1)
src/BamfLauncherIcon.cpp (+3/-0)
src/Launcher.cpp (+21/-0)
src/Launcher.h (+45/-32)
src/LauncherIcon.cpp (+157/-10)
src/LauncherIcon.h (+21/-3)
src/QuicklistView.cpp (+1126/-883)
src/QuicklistView.h (+89/-74)
src/StaticCairoText.cpp (+2/-3)
src/StaticCairoText.h (+1/-0)
src/Tooltip.cpp (+39/-8)
src/Tooltip.h (+2/-0)
src/unity.cpp (+3/-1)
To merge this branch: bzr merge lp:~canonical-dx-team/unity/unity.quicklist-support
Reviewer Review Type Date Requested Status
Neil J. Patel (community) Approve
Review via email: mp+41125@code.launchpad.net

Description of the change

* Support for Quicklist

To post a comment you must log in.
Revision history for this message
Neil J. Patel (njpatel) wrote :

Approved, with understanding that tests are coming today.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'po/unity.pot'
2--- po/unity.pot 2010-11-12 09:42:09 +0000
3+++ po/unity.pot 2010-11-18 14:03:47 +0000
4@@ -8,7 +8,7 @@
5 msgstr ""
6 "Project-Id-Version: PACKAGE VERSION\n"
7 "Report-Msgid-Bugs-To: ayatana-dev@lists.launchpad.net\n"
8-"POT-Creation-Date: 2010-11-11 19:06+0000\n"
9+"POT-Creation-Date: 2010-11-15 11:43-0500\n"
10 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12 "Language-Team: LANGUAGE <LL@li.org>\n"
13
14=== modified file 'src/BamfLauncherIcon.cpp'
15--- src/BamfLauncherIcon.cpp 2010-11-17 14:40:39 +0000
16+++ src/BamfLauncherIcon.cpp 2010-11-18 14:03:47 +0000
17@@ -67,6 +67,9 @@
18 void
19 BamfLauncherIcon::OnMouseClick (int button)
20 {
21+ if (button != 1)
22+ return;
23+
24 BamfView *view;
25 GList *children, *l;
26 bool active, running;
27
28=== modified file 'src/Launcher.cpp'
29--- src/Launcher.cpp 2010-11-17 18:02:14 +0000
30+++ src/Launcher.cpp 2010-11-18 14:03:47 +0000
31@@ -35,6 +35,7 @@
32 #include "Launcher.h"
33 #include "LauncherIcon.h"
34 #include "LauncherModel.h"
35+#include "QuicklistView.h"
36
37 #define ANIM_DURATION_SHORT 125
38 #define ANIM_DURATION 200
39@@ -170,6 +171,8 @@
40 , _model (0)
41 {
42 _parent = parent;
43+ _active_quicklist = 0;
44+
45 m_Layout = new nux::HLayout(NUX_TRACKER_LOCATION);
46
47 OnMouseDown.connect(sigc::mem_fun(this, &Launcher::RecvMouseDown));
48@@ -1891,3 +1894,21 @@
49 // }
50 // glEnd();
51 }
52+
53+void Launcher::SetActiveQuicklist (QuicklistView *quicklist)
54+{
55+ // Assert: _active_quicklist should be 0
56+ _active_quicklist = quicklist;
57+}
58+
59+QuicklistView *Launcher::GetActiveQuicklist ()
60+{
61+ return _active_quicklist;
62+}
63+
64+void Launcher::CancelActiveQuicklist (QuicklistView *quicklist)
65+{
66+ if (_active_quicklist == quicklist)
67+ _active_quicklist = 0;
68+}
69+
70
71=== modified file 'src/Launcher.h'
72--- src/Launcher.h 2010-11-16 00:56:20 +0000
73+++ src/Launcher.h 2010-11-18 14:03:47 +0000
74@@ -29,42 +29,51 @@
75 #include "Nux/TimerProc.h"
76
77 class LauncherModel;
78+class QuicklistView;
79
80 class Launcher : public nux::View
81 {
82 public:
83- Launcher(nux::BaseWindow *parent, NUX_FILE_LINE_PROTO);
84- ~Launcher();
85-
86- virtual long ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo);
87- virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
88- virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
89- virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw);
90-
91- LauncherIcon* GetActiveTooltipIcon() {return m_ActiveTooltipIcon;}
92- LauncherIcon* GetActiveMenuIcon() {return m_ActiveMenuIcon;}
93-
94- bool TooltipNotify(LauncherIcon* Icon);
95- bool MenuNotify(LauncherIcon* Icon);
96-
97- void SetIconSize(int tile_size, int icon_size);
98- void NotifyMenuTermination(LauncherIcon* Icon);
99-
100- void SetModel (LauncherModel *model);
101-
102- void SetFloating (bool floating);
103-
104- void SetAutohide (bool autohide, nux::View *show_trigger);
105- bool AutohideEnabled ();
106-
107- virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags);
108- virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
109- virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
110- virtual void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags);
111- virtual void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags);
112- virtual void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
113- virtual void RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags);
114-
115+ Launcher(nux::BaseWindow *parent, NUX_FILE_LINE_PROTO);
116+ ~Launcher();
117+
118+ virtual long ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo);
119+ virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
120+ virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
121+ virtual void PostDraw(nux::GraphicsEngine& GfxContext, bool force_draw);
122+
123+ LauncherIcon* GetActiveTooltipIcon() {return m_ActiveTooltipIcon;}
124+ LauncherIcon* GetActiveMenuIcon() {return m_ActiveMenuIcon;}
125+
126+ bool TooltipNotify(LauncherIcon* Icon);
127+ bool MenuNotify(LauncherIcon* Icon);
128+
129+ void SetIconSize(int tile_size, int icon_size);
130+ void NotifyMenuTermination(LauncherIcon* Icon);
131+
132+ void SetModel (LauncherModel *model);
133+
134+ void SetFloating (bool floating);
135+
136+ void SetAutohide (bool autohide, nux::View *show_trigger);
137+ bool AutohideEnabled ();
138+
139+ virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags);
140+ virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
141+ virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
142+ virtual void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags);
143+ virtual void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags);
144+ virtual void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
145+ virtual void RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags);
146+
147+
148+ //! Called by LauncherIcon to signal that a Quicklist is becoming active.
149+ void SetActiveQuicklist (QuicklistView *quicklist);
150+ //! Get the active qicklist
151+ QuicklistView *GetActiveQuicklist ();
152+ //! Called by LauncherIcon to signal that a Quicklist is becoming unactive.
153+ void CancelActiveQuicklist (QuicklistView *quicklist);
154+
155 private:
156 typedef enum
157 {
158@@ -140,6 +149,7 @@
159 virtual void PreLayoutManagement();
160 virtual long PostLayoutManagement(long LayoutResult);
161 virtual void PositionChildLayout(float offsetX, float offsetY);
162+
163
164 nux::HLayout* m_Layout;
165 int m_ContentOffsetY;
166@@ -147,6 +157,9 @@
167 LauncherIcon* m_ActiveTooltipIcon;
168 LauncherIcon* m_ActiveMenuIcon;
169
170+
171+ QuicklistView* _active_quicklist;
172+
173 bool _hovered;
174 bool _floating;
175 bool _autohide;
176
177=== modified file 'src/LauncherIcon.cpp'
178--- src/LauncherIcon.cpp 2010-11-14 03:08:14 +0000
179+++ src/LauncherIcon.cpp 2010-11-18 14:03:47 +0000
180@@ -33,10 +33,13 @@
181
182 #define DEFAULT_ICON "application-default-icon"
183
184-LauncherIcon::LauncherIcon(Launcher* IconManager)
185+nux::Tooltip *LauncherIcon::_current_tooltip = 0;
186+QuicklistView *LauncherIcon::_current_quicklist = 0;
187+
188+LauncherIcon::LauncherIcon(Launcher* launcher)
189 {
190 _folding_angle = 0;
191- m_IconManager = IconManager;
192+ _launcher = launcher;
193 m_TooltipText = "blank";
194
195 _show_time.tv_sec = 0;
196@@ -67,8 +70,16 @@
197 _icon_type = LAUNCHER_ICON_TYPE_NONE;
198 _sort_priority = 0;
199
200+ _quicklist = new QuicklistView ();
201+ _quicklist->sigVisible.connect (sigc::mem_fun (this, &LauncherIcon::RecvShowQuicklist));
202+ _quicklist->sigHidden.connect (sigc::mem_fun (this, &LauncherIcon::RecvHideQuicklist));
203+ _quicklist_is_initialized = false;
204+
205 MouseEnter.connect (sigc::mem_fun(this, &LauncherIcon::RecvMouseEnter));
206 MouseLeave.connect (sigc::mem_fun(this, &LauncherIcon::RecvMouseLeave));
207+ MouseDown.connect (sigc::mem_fun(this, &LauncherIcon::RecvMouseDown));
208+ MouseUp.connect (sigc::mem_fun(this, &LauncherIcon::RecvMouseUp));
209+
210 }
211
212 LauncherIcon::~LauncherIcon()
213@@ -206,17 +217,47 @@
214 void
215 LauncherIcon::RecvMouseEnter ()
216 {
217- int icon_x = _xform_screen_coord[0].x;
218+ if (_quicklist_is_initialized == false)
219+ {
220+ std::list<DbusmenuClient *> menus_list = Menus ();
221+ std::list<DbusmenuClient *>::iterator it;
222+ for (it = menus_list.begin (); it != menus_list.end (); it++)
223+ {
224+ g_signal_connect(G_OBJECT(*it), DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(&LauncherIcon::root_changed), _quicklist);
225+ dbusmenu_client_add_type_handler (*it, DBUSMENU_CLIENT_TYPES_DEFAULT, (&LauncherIcon::label_handler));
226+ dbusmenu_client_add_type_handler (*it, DBUSMENU_CLIENT_TYPES_SEPARATOR, (&LauncherIcon::separator_handler));
227+ }
228+
229+ _quicklist_is_initialized = true;
230+ }
231+
232+ if (_launcher->GetActiveQuicklist ())
233+ {
234+ // A quicklist is active
235+ return;
236+ }
237+
238+// int icon_x = _xform_screen_coord[0].x;
239+// int icon_y = _xform_screen_coord[0].y;
240+// int icon_w = _xform_screen_coord[2].x - _xform_screen_coord[0].x;
241+// int icon_h = _xform_screen_coord[2].y - _xform_screen_coord[0].y;
242+
243+ //int icon_x = _xform_screen_coord[0].x;
244 int icon_y = _xform_screen_coord[0].y;
245- int icon_w = _xform_screen_coord[2].x - _xform_screen_coord[0].x;
246+ //int icon_w = _xform_screen_coord[2].x - _xform_screen_coord[0].x;
247 int icon_h = _xform_screen_coord[2].y - _xform_screen_coord[0].y;
248
249- _tooltip->SetBaseX (icon_x + icon_w - 10);
250- _tooltip->SetBaseY (icon_y +
251- 23 + // TODO: HARCODED, replace m_IconManager->GetBaseY ()
252- (icon_h / 2) -
253- (_tooltip->GetBaseHeight () / 2));
254- _tooltip->ShowWindow (true);
255+ int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w;
256+ int tip_y = 24 + // The BaseWindow where the launcher resides is 24 pixels away from the top of the screen: find a better way to get that number.
257+ icon_y +
258+ (icon_h / 2);
259+
260+ _tooltip->ShowTooltipWithTipAt (tip_x, tip_y);
261+
262+ if (!_quicklist->IsVisible ())
263+ {
264+ _tooltip->ShowWindow (true);
265+ }
266 }
267
268 void LauncherIcon::RecvMouseLeave ()
269@@ -224,6 +265,112 @@
270 _tooltip->ShowWindow (false);
271 }
272
273+
274+gboolean LauncherIcon::label_handler (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
275+{
276+ //const gchar* s = dbusmenu_menuitem_property_get (newitem, DBUSMENU_MENUITEM_PROP_LABEL);
277+ //printf ("label: %s\n", s);
278+
279+ return true;
280+}
281+
282+gboolean LauncherIcon::separator_handler (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
283+{
284+ //const gchar* s = dbusmenu_menuitem_property_get (newitem, DBUSMENU_MENUITEM_PROP_LABEL);
285+ //printf ("separator: %s\n", s);
286+
287+ return true;
288+}
289+
290+void LauncherIcon::child_realized (DbusmenuMenuitem *newitem, QuicklistView *quicklist)
291+{
292+ const gchar* label = dbusmenu_menuitem_property_get (newitem, DBUSMENU_MENUITEM_PROP_LABEL);
293+ const gchar* type = dbusmenu_menuitem_property_get (newitem, DBUSMENU_MENUITEM_PROP_TYPE);
294+
295+ if (g_strcmp0 (type, DBUSMENU_CLIENT_TYPES_SEPARATOR) == 0)
296+ {
297+ quicklist->AddMenuItem ("-----------------");
298+ }
299+ else
300+ {
301+ quicklist->AddMenuItem (label);
302+ }
303+
304+}
305+
306+void LauncherIcon::root_changed (DbusmenuClient * client, DbusmenuMenuitem * newroot, QuicklistView *quicklist)
307+{
308+ GList * child = NULL;
309+ for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child))
310+ {
311+ g_signal_connect(G_OBJECT(child->data), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(child_realized), quicklist);
312+ }
313+}
314+
315+void LauncherIcon::RecvMouseDown (int button)
316+{
317+ if (button == 3)
318+ {
319+ if (_launcher->GetActiveQuicklist () == _quicklist)
320+ {
321+ // this quicklist is already active
322+ return;
323+ }
324+
325+ if (_launcher->GetActiveQuicklist ())
326+ {
327+ // Hide the active quicklist. This will prevent it from Ungrabing the pointer in
328+ // QuicklistView::RecvMouseDownOutsideOfQuicklist or void QuicklistView::RecvMouseClick.
329+ // So the new quicklist that is about to be set as active will keep the grab of the pointer.
330+ // Also disable theinput window.
331+ _launcher->GetActiveQuicklist ()->EnableInputWindow (false);
332+ _launcher->GetActiveQuicklist ()->CaptureMouseDownAnyWhereElse (false);
333+ // This call must be last, because after, _launcher->GetActiveQuicklist () will return Null.
334+ // the launcher listen to the sigHidden signal emitted by the BaseWindow when it becomes invisible
335+ // and it set the active window to Null.
336+ _launcher->GetActiveQuicklist ()->ShowWindow (false);
337+ }
338+
339+ _tooltip->ShowWindow (false);
340+
341+
342+ //int icon_x = _xform_screen_coord[0].x;
343+ int icon_y = _xform_screen_coord[0].y;
344+ //int icon_w = _xform_screen_coord[2].x - _xform_screen_coord[0].x;
345+ int icon_h = _xform_screen_coord[2].y - _xform_screen_coord[0].y;
346+
347+ int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w;
348+ int tip_y = 24 + // The BaseWindow where the launcher resides is 24 pixels away from the top of the screen: find a better way to get that number.
349+ icon_y +
350+ (icon_h / 2);
351+
352+ _quicklist->ShowQuicklistWithTipAt (tip_x, tip_y);
353+ _quicklist->EnableInputWindow (true);
354+ _quicklist->GrabPointer ();
355+ nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_quicklist);
356+ _quicklist->NeedRedraw ();
357+ }
358+}
359+
360+void LauncherIcon::RecvMouseUp (int button)
361+{
362+ if (button == 3)
363+ {
364+ if (_quicklist->IsVisible ())
365+ _quicklist->CaptureMouseDownAnyWhereElse (true);
366+ }
367+}
368+
369+void LauncherIcon::RecvShowQuicklist (nux::BaseWindow *quicklist)
370+{
371+ _launcher->SetActiveQuicklist (_quicklist);
372+}
373+
374+void LauncherIcon::RecvHideQuicklist (nux::BaseWindow *quicklist)
375+{
376+ _launcher->CancelActiveQuicklist (_quicklist);
377+}
378+
379 void LauncherIcon::HideTooltip ()
380 {
381 _tooltip->ShowWindow (false);
382
383=== modified file 'src/LauncherIcon.h'
384--- src/LauncherIcon.h 2010-11-14 06:23:18 +0000
385+++ src/LauncherIcon.h 2010-11-18 14:03:47 +0000
386@@ -33,8 +33,10 @@
387 #include <libdbusmenu-glib/client.h>
388
389 #include "Tooltip.h"
390+#include "QuicklistView.h"
391
392 class Launcher;
393+class QuicklistView;
394
395 typedef enum
396 {
397@@ -51,7 +53,7 @@
398 class LauncherIcon : public nux::InitiallyUnownedObject, public sigc::trackable
399 {
400 public:
401- LauncherIcon(Launcher* IconManager);
402+ LauncherIcon(Launcher* launcher);
403 ~LauncherIcon();
404
405 void SetTooltipText (const TCHAR* text);
406@@ -66,6 +68,11 @@
407
408 void RecvMouseEnter ();
409 void RecvMouseLeave ();
410+ void RecvMouseDown (int button);
411+ void RecvMouseUp (int button);
412+
413+ void RecvShowQuicklist (nux::BaseWindow *quicklist);
414+ void RecvHideQuicklist (nux::BaseWindow *quicklist);
415
416 void HideTooltip ();
417
418@@ -121,20 +128,30 @@
419 nux::NString m_TooltipText;
420 //! the window this icon belong too.
421 nux::BaseWindow* m_Window;
422- Launcher* m_IconManager;
423+ Launcher* _launcher;
424
425 nux::Vector4 _xform_screen_coord [4];
426 nux::Vector4 _xform_icon_screen_coord [4];
427 bool _mouse_inside;
428 float _folding_angle;
429
430- nux::Tooltip* _tooltip;
431+ nux::Tooltip *_tooltip;
432+ QuicklistView *_quicklist;
433+
434+ static nux::Tooltip *_current_tooltip;
435+ static QuicklistView *_current_quicklist;
436
437
438 friend class Launcher;
439 friend class LauncherController;
440
441 private:
442+
443+ static gboolean label_handler (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
444+ static gboolean separator_handler (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
445+
446+ static void child_realized (DbusmenuMenuitem *newitem, QuicklistView *quicklist);
447+ static void root_changed (DbusmenuClient * client, DbusmenuMenuitem *newroot, QuicklistView *quicklist);
448 static gboolean OnPresentTimeout (gpointer data);
449
450 nux::Color ColorForIcon (GdkPixbuf *pixbuf);
451@@ -148,6 +165,7 @@
452 int _sort_priority;
453 int _related_windows;
454 guint _present_time_handle;
455+ bool _quicklist_is_initialized;
456
457 LauncherIconType _icon_type;
458
459
460=== modified file 'src/QuicklistView.cpp'
461--- src/QuicklistView.cpp 2010-11-11 10:46:30 +0000
462+++ src/QuicklistView.cpp 2010-11-18 14:03:47 +0000
463@@ -1,21 +1,21 @@
464 /*
465- * Copyright (C) 2010 Canonical Ltd
466- *
467- * This program is free software: you can redistribute it and/or modify
468- * it under the terms of the GNU General Public License version 3 as
469- * published by the Free Software Foundation.
470- *
471- * This program is distributed in the hope that it will be useful,
472- * but WITHOUT ANY WARRANTY; without even the implied warranty of
473- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
474- * GNU General Public License for more details.
475- *
476- * You should have received a copy of the GNU General Public License
477- * along with this program. If not, see <http://www.gnu.org/licenses/>.
478- *
479- * Authored by: Jay Taoko <jay.taoko@canonical.com>
480- * Authored by: Mirco Müller <mirco.mueller@canonical.com
481- */
482+* Copyright (C) 2010 Canonical Ltd
483+*
484+* This program is free software: you can redistribute it and/or modify
485+* it under the terms of the GNU General Public License version 3 as
486+* published by the Free Software Foundation.
487+*
488+* This program is distributed in the hope that it will be useful,
489+* but WITHOUT ANY WARRANTY; without even the implied warranty of
490+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
491+* GNU General Public License for more details.
492+*
493+* You should have received a copy of the GNU General Public License
494+* along with this program. If not, see <http://www.gnu.org/licenses/>.
495+*
496+* Authored by: Jay Taoko <jay.taoko@canonical.com>
497+* Authored by: Mirco Müller <mirco.mueller@canonical.com
498+*/
499
500 #include "Nux/Nux.h"
501 #include "Nux/VLayout.h"
502@@ -30,480 +30,701 @@
503
504 #include "QuicklistView.h"
505
506-namespace nux
507-{
508- NUX_IMPLEMENT_OBJECT_TYPE (QuicklistView);
509-
510- QuicklistView::QuicklistView ()
511- {
512- _texture_bg = 0;
513- _texture_mask = 0;
514- _texture_outline = 0;
515- _cairo_text_has_changed = true;
516-
517- _anchorX = 0;
518- _anchorY = 0;
519- _labelText = TEXT ("QuicklistView 1234567890");
520-
521- _anchor_width = 10;
522- _anchor_height = 18;
523- _corner_radius = 4;
524- _padding = 10;
525-
526- _hlayout = new nux::HLayout (TEXT(""), NUX_TRACKER_LOCATION);
527- _vlayout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
528-
529- _left_space = new nux::SpaceLayout (_padding + _anchor_width + _corner_radius, _padding + _anchor_width + _corner_radius, 1, 1000);
530- _right_space = new nux::SpaceLayout (_padding + _corner_radius, _padding + _corner_radius, 1, 1000);
531-
532- _top_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
533- _bottom_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
534-
535- _vlayout->AddLayout(_top_space, 0);
536-
537- for (int i = 0; i < 5; i++)
538- {
539- nux::StaticCairoText* tooltip_text;
540- if (i == 0)
541- tooltip_text = new nux::StaticCairoText (TEXT ("1234567890"), NUX_TRACKER_LOCATION);
542- else
543- tooltip_text = new nux::StaticCairoText (TEXT ("QuicklistView 1234567890"), NUX_TRACKER_LOCATION);
544-
545- tooltip_text->sigTextChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextChanged));
546- _vlayout->AddView(tooltip_text, 1, eCenter, eFull);
547- _item_list.push_back (tooltip_text);
548- tooltip_text->Reference();
549- }
550-
551- _vlayout->AddLayout(_bottom_space, 0);
552-
553- _hlayout->AddLayout(_left_space, 0);
554- _hlayout->AddLayout(_vlayout, 1, eCenter, eFull);
555- _hlayout->AddLayout(_right_space, 0);
556-
557- SetWindowSizeMatchLayout (true);
558- SetLayout (_hlayout);
559-
560- }
561-
562- QuicklistView::~QuicklistView ()
563- {
564- if (_texture_bg)
565- _texture_bg->UnReference ();
566-
567- std::list<nux::StaticCairoText*>::iterator it;
568- for (it = _item_list.begin(); it != _item_list.end(); it++)
569- {
570- (*it)->UnReference();
571- }
572- _item_list.clear ();
573- }
574-
575- long QuicklistView::ProcessEvent (IEvent& ievent, long TraverseInfo, long ProcessEventInfo)
576- {
577- long ret = TraverseInfo;
578- std::list<nux::StaticCairoText*>::iterator it;
579- for (it = _item_list.begin(); it != _item_list.end(); it++)
580- {
581- ret = (*it)->ProcessEvent(ievent, ret, ProcessEventInfo);
582- }
583- return ret;
584- }
585-
586- void QuicklistView::Draw (GraphicsEngine& gfxContext, bool forceDraw)
587- {
588- Geometry base = GetGeometry();
589-
590- // the elements position inside the window are referenced to top-left window
591- // corner. So bring base to (0, 0).
592- base.SetX (0);
593- base.SetY (0);
594- gfxContext.PushClippingRectangle (base);
595-
596- GetGraphicsEngine().GetRenderStates().SetBlend (false, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
597-
598- TexCoordXForm texxform_bg;
599- texxform_bg.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
600- texxform_bg.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
601-
602- TexCoordXForm texxform_mask;
603- texxform_mask.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
604- texxform_mask.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
605-
606-
607- gfxContext.QRP_GLSL_2TexMod (base.x,
608- base.y,
609- base.width,
610- base.height,
611- _texture_bg->GetDeviceTexture(),
612- texxform_bg,
613- Color(1.0f, 1.0f, 1.0f, 1.0f),
614- _texture_mask->GetDeviceTexture(),
615- texxform_mask,
616- Color(1.0f, 1.0f, 1.0f, 1.0f));
617-
618-
619- TexCoordXForm texxform;
620- texxform.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
621- texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
622-
623- GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
624- gfxContext.QRP_GLSL_1Tex (base.x,
625- base.y,
626- base.width,
627- base.height,
628- _texture_outline->GetDeviceTexture(),
629- texxform,
630- Color(1.0f, 1.0f, 1.0f, 1.0f));
631-
632- GetGraphicsEngine().GetRenderStates().SetBlend (false);
633-
634- std::list<nux::StaticCairoText*>::iterator it;
635- for (it = _item_list.begin(); it != _item_list.end(); it++)
636- {
637- (*it)->ProcessDraw(gfxContext, forceDraw);
638- }
639-
640- gfxContext.PopClippingRectangle ();
641- }
642-
643- void QuicklistView::DrawContent (GraphicsEngine& GfxContext, bool force_draw)
644- {
645-
646- }
647-
648- void QuicklistView::PreLayoutManagement ()
649- {
650- int MaxItemWidth = 0;
651- int TotalItemHeight = 0;
652-
653- std::list<nux::StaticCairoText*>::iterator it;
654- for (it = _item_list.begin(); it != _item_list.end(); it++)
655- {
656- int textWidth = 0;
657- int textHeight = 0;
658- (*it)->GetTextExtents(textWidth, textHeight);
659- if (textWidth > MaxItemWidth)
660- MaxItemWidth = textWidth;
661- TotalItemHeight += textHeight;
662- }
663-
664- if(TotalItemHeight < _anchor_height)
665- {
666- _top_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
667- _bottom_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
668- }
669-
670- BaseWindow::PreLayoutManagement ();
671- }
672-
673- long QuicklistView::PostLayoutManagement (long LayoutResult)
674- {
675- long result = BaseWindow::PostLayoutManagement (LayoutResult);
676- UpdateTexture ();
677-
678- int x = _padding + _anchor_width + _corner_radius;
679- int y = _padding + _corner_radius;
680-
681- std::list<nux::StaticCairoText*>::iterator it;
682- for (it = _item_list.begin(); it != _item_list.end(); it++)
683- {
684- (*it)->SetBaseX (x);
685- (*it)->SetBaseY (y);
686-
687- y += (*it)->GetBaseHeight ();
688- }
689-
690- return result;
691- }
692-
693- void QuicklistView::RecvCairoTextChanged (StaticCairoText& cairo_text)
694- {
695- _cairo_text_has_changed = true;
696- }
697-
698-/////////////////////////////////////////////////////////////////////////////////////////////////
699-/////////////////////////////////////////////////////////////////////////////////////////////////
700-/////////////////////////////////////////////////////////////////////////////////////////////////
701-
702- static inline void ql_blurinner (guchar* pixel,
703- gint *zR,
704- gint *zG,
705- gint *zB,
706- gint *zA,
707- gint alpha,
708- gint aprec,
709- gint zprec)
710- {
711- gint R;
712- gint G;
713- gint B;
714- guchar A;
715-
716- R = *pixel;
717- G = *(pixel + 1);
718- B = *(pixel + 2);
719- A = *(pixel + 3);
720-
721- *zR += (alpha * ((R << zprec) - *zR)) >> aprec;
722- *zG += (alpha * ((G << zprec) - *zG)) >> aprec;
723- *zB += (alpha * ((B << zprec) - *zB)) >> aprec;
724- *zA += (alpha * ((A << zprec) - *zA)) >> aprec;
725-
726- *pixel = *zR >> zprec;
727- *(pixel + 1) = *zG >> zprec;
728- *(pixel + 2) = *zB >> zprec;
729- *(pixel + 3) = *zA >> zprec;
730- }
731-
732- static inline void ql_blurrow (guchar* pixels,
733- gint width,
734- gint height,
735- gint channels,
736- gint line,
737- gint alpha,
738- gint aprec,
739- gint zprec)
740- {
741- gint zR;
742- gint zG;
743- gint zB;
744- gint zA;
745- gint index;
746- guchar* scanline;
747-
748- scanline = &(pixels[line * width * channels]);
749-
750- zR = *scanline << zprec;
751- zG = *(scanline + 1) << zprec;
752- zB = *(scanline + 2) << zprec;
753- zA = *(scanline + 3) << zprec;
754-
755- for (index = 0; index < width; index ++)
756- ql_blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec,
757- zprec);
758-
759- for (index = width - 2; index >= 0; index--)
760- ql_blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec,
761- zprec);
762- }
763-
764- static inline void ql_blurcol (guchar* pixels,
765- gint width,
766- gint height,
767- gint channels,
768- gint x,
769- gint alpha,
770- gint aprec,
771- gint zprec)
772- {
773- gint zR;
774- gint zG;
775- gint zB;
776- gint zA;
777- gint index;
778- guchar* ptr;
779-
780- ptr = pixels;
781-
782- ptr += x * channels;
783-
784- zR = *((guchar*) ptr ) << zprec;
785- zG = *((guchar*) ptr + 1) << zprec;
786- zB = *((guchar*) ptr + 2) << zprec;
787- zA = *((guchar*) ptr + 3) << zprec;
788-
789- for (index = width; index < (height - 1) * width; index += width)
790- ql_blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha,
791- aprec, zprec);
792-
793- for (index = (height - 2) * width; index >= 0; index -= width)
794- ql_blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha,
795- aprec, zprec);
796- }
797-
798- //
799- // pixels image-data
800- // width image-width
801- // height image-height
802- // channels image-channels
803- //
804- // in-place blur of image 'img' with kernel of approximate radius 'radius'
805- //
806- // blurs with two sided exponential impulse response
807- //
808- // aprec = precision of alpha parameter in fixed-point format 0.aprec
809- //
810- // zprec = precision of state parameters zR,zG,zB and zA in fp format 8.zprec
811- //
812- void ql_expblur (guchar* pixels,
813- gint width,
814- gint height,
815- gint channels,
816- gint radius,
817- gint aprec,
818- gint zprec)
819- {
820- gint alpha;
821- gint row = 0;
822- gint col = 0;
823-
824- if (radius < 1)
825- return;
826-
827- // calculate the alpha such that 90% of
828- // the kernel is within the radius.
829- // (Kernel extends to infinity)
830- alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f))));
831-
832- for (; row < height; row++)
833- ql_blurrow (pixels, width, height, channels, row, alpha, aprec, zprec);
834-
835- for(; col < width; col++)
836- ql_blurcol (pixels, width, height, channels, col, alpha, aprec, zprec);
837-
838+
839+NUX_IMPLEMENT_OBJECT_TYPE (QuicklistView);
840+
841+QuicklistView::QuicklistView ()
842+{
843+ _texture_bg = 0;
844+ _texture_mask = 0;
845+ _texture_outline = 0;
846+ _cairo_text_has_changed = true;
847+
848+ _anchorX = 0;
849+ _anchorY = 0;
850+ _labelText = TEXT ("QuicklistView 1234567890");
851+
852+ _anchor_width = 10;
853+ _anchor_height = 18;
854+ _corner_radius = 4;
855+ _padding = 13;
856+ _top_size = 4;
857+
858+ _hlayout = new nux::HLayout (TEXT(""), NUX_TRACKER_LOCATION);
859+ _vlayout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
860+ _item_layout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
861+ _default_item_layout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
862+
863+ _left_space = new nux::SpaceLayout (_padding + _anchor_width + _corner_radius, _padding + _anchor_width + _corner_radius, 1, 1000);
864+ _right_space = new nux::SpaceLayout (_padding + _corner_radius, _padding + _corner_radius, 1, 1000);
865+
866+ _top_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
867+ _bottom_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
868+
869+ _vlayout->AddLayout (_top_space, 0);
870+
871+ _vlayout->AddLayout (_item_layout, 0);
872+
873+ _vlayout->AddLayout (_default_item_layout, 0);
874+
875+ for (int i = 0; i < 2; i++)
876+ {
877+ nux::StaticCairoText* item_text;
878+ item_text = new nux::StaticCairoText (TEXT ("Default Item"), NUX_TRACKER_LOCATION);
879+
880+ item_text->sigTextChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextChanged));
881+ item_text->sigTextColorChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextColorChanged));
882+ _default_item_layout->AddView(item_text, 1, nux::eCenter, nux::eFull);
883+ _default_item_list.push_back (item_text);
884+ item_text->Reference();
885+ }
886+
887+ _vlayout->AddLayout (_bottom_space, 0);
888+
889+ _hlayout->AddLayout (_left_space, 0);
890+ _hlayout->AddLayout (_vlayout, 1, nux::eCenter, nux::eFull);
891+ _hlayout->AddLayout (_right_space, 0);
892+
893+ SetWindowSizeMatchLayout (true);
894+ SetLayout (_hlayout);
895+
896+ OnMouseDownOutsideArea.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDownOutsideOfQuicklist));
897+ OnMouseDown.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDown));
898+ OnMouseUp.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseUp));
899+ OnMouseClick.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseClick));
900+ OnMouseMove.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseMove));
901+ OnMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDrag));
902+
903+}
904+
905+QuicklistView::~QuicklistView ()
906+{
907+ if (_texture_bg)
908+ _texture_bg->UnReference ();
909+
910+ std::list<nux::StaticCairoText*>::iterator it;
911+ for (it = _item_list.begin(); it != _item_list.end(); it++)
912+ {
913+ (*it)->UnReference();
914+ }
915+ _item_list.clear ();
916+}
917+
918+void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y)
919+{
920+ int window_width;
921+ int window_height;
922+
923+ window_width = nux::GetWindow ().GetWindowWidth ();
924+ window_height = nux::GetWindow ().GetWindowHeight ();
925+
926+ _anchorX = anchor_tip_x;
927+ _anchorY = anchor_tip_y;
928+
929+ int x = _anchorX - _padding;
930+ int y = anchor_tip_y - _anchor_height/2 - _top_size - _corner_radius - _padding;
931+
932+ SetBaseX (x);
933+ SetBaseY (y);
934+
935+ ShowWindow (true);
936+}
937+
938+void QuicklistView::ShowWindow (bool b, bool start_modal)
939+{
940+ BaseWindow::ShowWindow (b, start_modal);
941+
942+ // Reset all colors to white
943+ std::list<nux::StaticCairoText*>::iterator it;
944+ for (it = _item_list.begin(); it != _item_list.end(); it++)
945+ {
946+ (*it)->SetTextColor (nux::Color::White);
947+ }
948+}
949+
950+long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long ProcessEventInfo)
951+{
952+ long ret = TraverseInfo;
953+ long ProcEvInfo = 0;
954+
955+ nux::IEvent window_event = ievent;
956+ nux::Geometry base = GetGeometry();
957+ window_event.e_x_root = base.x;
958+ window_event.e_y_root = base.y;
959+
960+ // The child layout get the Mouse down button only if the MouseDown happened inside the client view Area
961+ nux::Geometry viewGeometry = GetGeometry();
962+
963+ if (ievent.e_event == nux::NUX_MOUSE_PRESSED)
964+ {
965+ if (!viewGeometry.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) )
966+ {
967+ ProcEvInfo = nux::eDoNotProcess;
968+ }
969+ }
970+
971+ // We choose to test the quicklist items ourselves instead of processing them as it is usual in nux.
972+ // This is meantto be easier since the quicklist has a atypical way of working.
973+ // if (m_layout)
974+ // ret = m_layout->ProcessEvent (window_event, ret, ProcEvInfo);
975+
976+ // PostProcessEvent2 must always have its last parameter set to 0
977+ // because the m_BackgroundArea is the real physical limit of the window.
978+ // So the previous test about IsPointInside do not prevail over m_BackgroundArea
979+ // testing the event by itself.
980+ ret = PostProcessEvent2 (ievent, ret, 0);
981+ return ret;
982+}
983+
984+void QuicklistView::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw)
985+{
986+ nux::Geometry base = GetGeometry();
987+
988+ // the elements position inside the window are referenced to top-left window
989+ // corner. So bring base to (0, 0).
990+ base.SetX (0);
991+ base.SetY (0);
992+ gfxContext.PushClippingRectangle (base);
993+
994+ nux::GetGraphicsEngine().GetRenderStates().SetBlend (false, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
995+
996+ nux::TexCoordXForm texxform_bg;
997+ texxform_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
998+ texxform_bg.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
999+
1000+ nux::TexCoordXForm texxform_mask;
1001+ texxform_mask.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
1002+ texxform_mask.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
1003+
1004+
1005+ gfxContext.QRP_GLSL_2TexMod (base.x,
1006+ base.y,
1007+ base.width,
1008+ base.height,
1009+ _texture_bg->GetDeviceTexture(),
1010+ texxform_bg,
1011+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f),
1012+ _texture_mask->GetDeviceTexture(),
1013+ texxform_mask,
1014+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
1015+
1016+
1017+ nux::TexCoordXForm texxform;
1018+ texxform.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
1019+ texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
1020+
1021+ nux::GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1022+ gfxContext.QRP_GLSL_1Tex (base.x,
1023+ base.y,
1024+ base.width,
1025+ base.height,
1026+ _texture_outline->GetDeviceTexture(),
1027+ texxform,
1028+ nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
1029+
1030+ nux::GetGraphicsEngine().GetRenderStates().SetBlend (false);
1031+
1032+ std::list<nux::StaticCairoText*>::iterator it;
1033+ for (it = _item_list.begin(); it != _item_list.end(); it++)
1034+ {
1035+ (*it)->ProcessDraw(gfxContext, forceDraw);
1036+ }
1037+
1038+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
1039+ {
1040+ (*it)->ProcessDraw(gfxContext, forceDraw);
1041+ }
1042+
1043+
1044+ gfxContext.PopClippingRectangle ();
1045+}
1046+
1047+void QuicklistView::DrawContent (nux::GraphicsEngine& GfxContext, bool force_draw)
1048+{
1049+
1050+}
1051+
1052+void QuicklistView::PreLayoutManagement ()
1053+{
1054+ int MaxItemWidth = 0;
1055+ int TotalItemHeight = 0;
1056+
1057+ std::list<nux::StaticCairoText*>::iterator it;
1058+ for (it = _item_list.begin(); it != _item_list.end(); it++)
1059+ {
1060+ int textWidth = 0;
1061+ int textHeight = 0;
1062+ (*it)->GetTextExtents(textWidth, textHeight);
1063+ if (textWidth > MaxItemWidth)
1064+ MaxItemWidth = textWidth;
1065+ TotalItemHeight += textHeight;
1066+ }
1067+
1068+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
1069+ {
1070+ int textWidth = 0;
1071+ int textHeight = 0;
1072+ (*it)->GetTextExtents(textWidth, textHeight);
1073+ if (textWidth > MaxItemWidth)
1074+ MaxItemWidth = textWidth;
1075+ TotalItemHeight += textHeight;
1076+ }
1077+
1078+ if(TotalItemHeight < _anchor_height)
1079+ {
1080+ _top_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
1081+ _bottom_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
1082+ }
1083+
1084+ BaseWindow::PreLayoutManagement ();
1085+}
1086+
1087+long QuicklistView::PostLayoutManagement (long LayoutResult)
1088+{
1089+ long result = BaseWindow::PostLayoutManagement (LayoutResult);
1090+ UpdateTexture ();
1091+
1092+ int x = _padding + _anchor_width + _corner_radius;
1093+ int y = _padding + _corner_radius;
1094+
1095+ std::list<nux::StaticCairoText*>::iterator it;
1096+ for (it = _item_list.begin(); it != _item_list.end(); it++)
1097+ {
1098+ (*it)->SetBaseX (x);
1099+ (*it)->SetBaseY (y);
1100+
1101+ y += (*it)->GetBaseHeight ();
1102+ }
1103+
1104+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
1105+ {
1106+ (*it)->SetBaseX (x);
1107+ (*it)->SetBaseY (y);
1108+
1109+ y += (*it)->GetBaseHeight ();
1110+ }
1111+
1112+ return result;
1113+}
1114+
1115+void QuicklistView::RecvCairoTextChanged (nux::StaticCairoText& cairo_text)
1116+{
1117+ _cairo_text_has_changed = true;
1118+}
1119+
1120+void QuicklistView::RecvCairoTextColorChanged (nux::StaticCairoText& cairo_text)
1121+{
1122+ NeedRedraw ();
1123+}
1124+
1125+void QuicklistView::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags)
1126+{
1127+// if (IsVisible ())
1128+// {
1129+// CaptureMouseDownAnyWhereElse (false);
1130+// ForceStopFocus (1, 1);
1131+// UnGrabPointer ();
1132+// EnableInputWindow (false);
1133+// ShowWindow (false);
1134+// }
1135+}
1136+
1137+void QuicklistView::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags)
1138+{
1139+
1140+}
1141+
1142+void QuicklistView::RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags)
1143+{
1144+ if (IsVisible ())
1145+ {
1146+ CaptureMouseDownAnyWhereElse (false);
1147+ ForceStopFocus (1, 1);
1148+ UnGrabPointer ();
1149+ EnableInputWindow (false);
1150+ ShowWindow (false);
1151+ }
1152+}
1153+
1154+void QuicklistView::RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
1155+{
1156+ std::list<nux::StaticCairoText*>::iterator it;
1157+ for (it = _item_list.begin(); it != _item_list.end(); it++)
1158+ {
1159+ if ((*it)->GetGeometry ().IsPointInside (x, y))
1160+ {
1161+ (*it)->SetTextColor (nux::Color::DarkGray);
1162+ }
1163+ else
1164+ {
1165+ (*it)->SetTextColor (nux::Color::White);
1166+ }
1167+ }
1168+
1169+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
1170+ {
1171+ if ((*it)->GetGeometry ().IsPointInside (x, y))
1172+ {
1173+ (*it)->SetTextColor (nux::Color::DarkGray);
1174+ }
1175+ else
1176+ {
1177+ (*it)->SetTextColor (nux::Color::White);
1178+ }
1179+ }
1180+}
1181+
1182+void QuicklistView::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
1183+{
1184+ std::list<nux::StaticCairoText*>::iterator it;
1185+ for (it = _item_list.begin(); it != _item_list.end(); it++)
1186+ {
1187+ if ((*it)->GetGeometry ().IsPointInside (x, y))
1188+ {
1189+ (*it)->SetTextColor (nux::Color::DarkGray);
1190+ }
1191+ else
1192+ {
1193+ (*it)->SetTextColor (nux::Color::White);
1194+ }
1195+ }
1196+
1197+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
1198+ {
1199+ if ((*it)->GetGeometry ().IsPointInside (x, y))
1200+ {
1201+ (*it)->SetTextColor (nux::Color::DarkGray);
1202+ }
1203+ else
1204+ {
1205+ (*it)->SetTextColor (nux::Color::White);
1206+ }
1207+ }
1208+}
1209+
1210+void QuicklistView::RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long button_flags, unsigned long key_flags)
1211+{
1212+ if (IsVisible ())
1213+ {
1214+ CaptureMouseDownAnyWhereElse (false);
1215+ ForceStopFocus (1, 1);
1216+ UnGrabPointer ();
1217+ EnableInputWindow (false);
1218+ ShowWindow (false);
1219+ }
1220+}
1221+
1222+void QuicklistView::RemoveAllMenuItem ()
1223+{
1224+ _item_list.clear ();
1225+ _item_layout->Clear ();
1226+ _cairo_text_has_changed = true;
1227+ nux::GetGraphicsThread ()->AddObjectToRefreshList (this);
1228+}
1229+
1230+void QuicklistView::AddMenuItem (nux::NString str)
1231+{
1232+ nux::StaticCairoText* item_text;
1233+ item_text = new nux::StaticCairoText (str.GetTCharPtr (), NUX_TRACKER_LOCATION);
1234+
1235+ item_text->sigTextChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextChanged));
1236+ item_text->sigTextColorChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextColorChanged));
1237+ _item_layout->AddView(item_text, 1, nux::eCenter, nux::eFull);
1238+ _item_list.push_back (item_text);
1239+ item_text->Reference();
1240+
1241+ _cairo_text_has_changed = true;
1242+ nux::GetGraphicsThread ()->AddObjectToRefreshList (this);
1243+ NeedRedraw ();
1244+}
1245+
1246+void QuicklistView::RenderQuicklistView ()
1247+{
1248+
1249+}
1250+
1251+/////////////////////////////////////////////////////////////////////////////////////////////////
1252+/////////////////////////////////////////////////////////////////////////////////////////////////
1253+/////////////////////////////////////////////////////////////////////////////////////////////////
1254+
1255+static inline void ql_blurinner (guchar* pixel,
1256+ gint *zR,
1257+ gint *zG,
1258+ gint *zB,
1259+ gint *zA,
1260+ gint alpha,
1261+ gint aprec,
1262+ gint zprec)
1263+{
1264+ gint R;
1265+ gint G;
1266+ gint B;
1267+ guchar A;
1268+
1269+ R = *pixel;
1270+ G = *(pixel + 1);
1271+ B = *(pixel + 2);
1272+ A = *(pixel + 3);
1273+
1274+ *zR += (alpha * ((R << zprec) - *zR)) >> aprec;
1275+ *zG += (alpha * ((G << zprec) - *zG)) >> aprec;
1276+ *zB += (alpha * ((B << zprec) - *zB)) >> aprec;
1277+ *zA += (alpha * ((A << zprec) - *zA)) >> aprec;
1278+
1279+ *pixel = *zR >> zprec;
1280+ *(pixel + 1) = *zG >> zprec;
1281+ *(pixel + 2) = *zB >> zprec;
1282+ *(pixel + 3) = *zA >> zprec;
1283+}
1284+
1285+static inline void ql_blurrow (guchar* pixels,
1286+ gint width,
1287+ gint height,
1288+ gint channels,
1289+ gint line,
1290+ gint alpha,
1291+ gint aprec,
1292+ gint zprec)
1293+{
1294+ gint zR;
1295+ gint zG;
1296+ gint zB;
1297+ gint zA;
1298+ gint index;
1299+ guchar* scanline;
1300+
1301+ scanline = &(pixels[line * width * channels]);
1302+
1303+ zR = *scanline << zprec;
1304+ zG = *(scanline + 1) << zprec;
1305+ zB = *(scanline + 2) << zprec;
1306+ zA = *(scanline + 3) << zprec;
1307+
1308+ for (index = 0; index < width; index ++)
1309+ ql_blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec,
1310+ zprec);
1311+
1312+ for (index = width - 2; index >= 0; index--)
1313+ ql_blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec,
1314+ zprec);
1315+}
1316+
1317+static inline void ql_blurcol (guchar* pixels,
1318+ gint width,
1319+ gint height,
1320+ gint channels,
1321+ gint x,
1322+ gint alpha,
1323+ gint aprec,
1324+ gint zprec)
1325+{
1326+ gint zR;
1327+ gint zG;
1328+ gint zB;
1329+ gint zA;
1330+ gint index;
1331+ guchar* ptr;
1332+
1333+ ptr = pixels;
1334+
1335+ ptr += x * channels;
1336+
1337+ zR = *((guchar*) ptr ) << zprec;
1338+ zG = *((guchar*) ptr + 1) << zprec;
1339+ zB = *((guchar*) ptr + 2) << zprec;
1340+ zA = *((guchar*) ptr + 3) << zprec;
1341+
1342+ for (index = width; index < (height - 1) * width; index += width)
1343+ ql_blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha,
1344+ aprec, zprec);
1345+
1346+ for (index = (height - 2) * width; index >= 0; index -= width)
1347+ ql_blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha,
1348+ aprec, zprec);
1349+}
1350+
1351+//
1352+// pixels image-data
1353+// width image-width
1354+// height image-height
1355+// channels image-channels
1356+//
1357+// in-place blur of image 'img' with kernel of approximate radius 'radius'
1358+//
1359+// blurs with two sided exponential impulse response
1360+//
1361+// aprec = precision of alpha parameter in fixed-point format 0.aprec
1362+//
1363+// zprec = precision of state parameters zR,zG,zB and zA in fp format 8.zprec
1364+//
1365+void ql_expblur (guchar* pixels,
1366+ gint width,
1367+ gint height,
1368+ gint channels,
1369+ gint radius,
1370+ gint aprec,
1371+ gint zprec)
1372+{
1373+ gint alpha;
1374+ gint row = 0;
1375+ gint col = 0;
1376+
1377+ if (radius < 1)
1378 return;
1379- }
1380+
1381+ // calculate the alpha such that 90% of
1382+ // the kernel is within the radius.
1383+ // (Kernel extends to infinity)
1384+ alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f))));
1385+
1386+ for (; row < height; row++)
1387+ ql_blurrow (pixels, width, height, channels, row, alpha, aprec, zprec);
1388+
1389+ for(; col < width; col++)
1390+ ql_blurcol (pixels, width, height, channels, col, alpha, aprec, zprec);
1391+
1392+ return;
1393+}
1394
1395 /**
1396- * ctk_surface_blur:
1397- * @surface: pointer to a cairo image-surface
1398- * @radius: unsigned integer acting as the blur-radius to apply
1399- *
1400- * Applies an exponential blur on the passed surface executed on the CPU. Not as
1401- * nice as a real gaussian blur, but much faster.
1402- **/
1403+* ctk_surface_blur:
1404+* @surface: pointer to a cairo image-surface
1405+* @radius: unsigned integer acting as the blur-radius to apply
1406+*
1407+* Applies an exponential blur on the passed surface executed on the CPU. Not as
1408+* nice as a real gaussian blur, but much faster.
1409+**/
1410 void ql_surface_blur (cairo_surface_t* surface,
1411- guint radius)
1412-{
1413- guchar* pixels;
1414- guint width;
1415- guint height;
1416- cairo_format_t format;
1417-
1418- // before we mess with the surface execute any pending drawing
1419- cairo_surface_flush (surface);
1420-
1421- pixels = cairo_image_surface_get_data (surface);
1422- width = cairo_image_surface_get_width (surface);
1423- height = cairo_image_surface_get_height (surface);
1424- format = cairo_image_surface_get_format (surface);
1425-
1426- switch (format)
1427- {
1428- case CAIRO_FORMAT_ARGB32:
1429- ql_expblur (pixels, width, height, 4, radius, 16, 7);
1430- break;
1431-
1432- case CAIRO_FORMAT_RGB24:
1433- ql_expblur (pixels, width, height, 3, radius, 16, 7);
1434- break;
1435-
1436- case CAIRO_FORMAT_A8:
1437- ql_expblur (pixels, width, height, 1, radius, 16, 7);
1438- break;
1439-
1440- default :
1441- // do nothing
1442- break;
1443- }
1444-
1445- // inform cairo we altered the surfaces contents
1446- cairo_surface_mark_dirty (surface);
1447-}
1448-
1449-
1450- void ql_tint_dot_hl (cairo_t* cr,
1451- gint width,
1452- gint height,
1453- gfloat hl_x,
1454- gfloat hl_y,
1455- gfloat hl_size,
1456- gfloat* rgba_tint,
1457- gfloat* rgba_hl,
1458- gfloat* rgba_dot)
1459- {
1460- cairo_surface_t* dots_surf = NULL;
1461- cairo_t* dots_cr = NULL;
1462- cairo_pattern_t* dots_pattern = NULL;
1463- cairo_pattern_t* hl_pattern = NULL;
1464-
1465- // create context for dot-pattern
1466- dots_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4, 4);
1467- dots_cr = cairo_create (dots_surf);
1468-
1469- // clear normal context
1470- cairo_scale (cr, 1.0f, 1.0f);
1471- cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
1472- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
1473- cairo_paint (cr);
1474-
1475- // prepare drawing for normal context
1476- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1477-
1478- // create path in normal context
1479- cairo_rectangle (cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height);
1480-
1481- // fill path of normal context with tint
1482- cairo_set_source_rgba (cr,
1483- rgba_tint[0],
1484- rgba_tint[1],
1485- rgba_tint[2],
1486- rgba_tint[3]);
1487- cairo_fill_preserve (cr);
1488-
1489- // create pattern in dot-context
1490- cairo_set_operator (dots_cr, CAIRO_OPERATOR_CLEAR);
1491- cairo_paint (dots_cr);
1492- cairo_scale (dots_cr, 1.0f, 1.0f);
1493- cairo_set_operator (dots_cr, CAIRO_OPERATOR_OVER);
1494- cairo_set_source_rgba (dots_cr,
1495- rgba_dot[0],
1496- rgba_dot[1],
1497- rgba_dot[2],
1498- rgba_dot[3]);
1499- cairo_rectangle (dots_cr, 0.0f, 0.0f, 1.0f, 1.0f);
1500- cairo_fill (dots_cr);
1501- cairo_rectangle (dots_cr, 2.0f, 2.0f, 1.0f, 1.0f);
1502- cairo_fill (dots_cr);
1503- dots_pattern = cairo_pattern_create_for_surface (dots_surf);
1504-
1505- // fill path of normal context with dot-pattern
1506- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1507- cairo_set_source (cr, dots_pattern);
1508- cairo_pattern_set_extend (dots_pattern, CAIRO_EXTEND_REPEAT);
1509- cairo_fill_preserve (cr);
1510- cairo_pattern_destroy (dots_pattern);
1511- cairo_surface_destroy (dots_surf);
1512- cairo_destroy (dots_cr);
1513-
1514- // draw highlight
1515- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1516- hl_pattern = cairo_pattern_create_radial (hl_x,
1517- hl_y,
1518- 0.0f,
1519- hl_x,
1520- hl_y,
1521- hl_size);
1522- cairo_pattern_add_color_stop_rgba (hl_pattern,
1523- 0.0f,
1524- 1.0f,
1525- 1.0f,
1526- 1.0f,
1527- 0.65f);
1528- cairo_pattern_add_color_stop_rgba (hl_pattern, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f);
1529- cairo_set_source (cr, hl_pattern);
1530- cairo_fill (cr);
1531- cairo_pattern_destroy (hl_pattern);
1532- }
1533-
1534- void ql_setup (cairo_surface_t** surf,
1535- cairo_t** cr,
1536- gboolean outline,
1537- gint width,
1538- gint height,
1539- gboolean negative)
1540- {
1541+ guint radius)
1542+{
1543+guchar* pixels;
1544+guint width;
1545+guint height;
1546+cairo_format_t format;
1547+
1548+// before we mess with the surface execute any pending drawing
1549+cairo_surface_flush (surface);
1550+
1551+pixels = cairo_image_surface_get_data (surface);
1552+width = cairo_image_surface_get_width (surface);
1553+height = cairo_image_surface_get_height (surface);
1554+format = cairo_image_surface_get_format (surface);
1555+
1556+switch (format)
1557+{
1558+ case CAIRO_FORMAT_ARGB32:
1559+ ql_expblur (pixels, width, height, 4, radius, 16, 7);
1560+ break;
1561+
1562+ case CAIRO_FORMAT_RGB24:
1563+ ql_expblur (pixels, width, height, 3, radius, 16, 7);
1564+ break;
1565+
1566+ case CAIRO_FORMAT_A8:
1567+ ql_expblur (pixels, width, height, 1, radius, 16, 7);
1568+ break;
1569+
1570+ default :
1571+ // do nothing
1572+ break;
1573+}
1574+
1575+// inform cairo we altered the surfaces contents
1576+cairo_surface_mark_dirty (surface);
1577+}
1578+
1579+
1580+void ql_tint_dot_hl (cairo_t* cr,
1581+ gint width,
1582+ gint height,
1583+ gfloat hl_x,
1584+ gfloat hl_y,
1585+ gfloat hl_size,
1586+ gfloat* rgba_tint,
1587+ gfloat* rgba_hl,
1588+ gfloat* rgba_dot)
1589+{
1590+ cairo_surface_t* dots_surf = NULL;
1591+ cairo_t* dots_cr = NULL;
1592+ cairo_pattern_t* dots_pattern = NULL;
1593+ cairo_pattern_t* hl_pattern = NULL;
1594+
1595+ // create context for dot-pattern
1596+ dots_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4, 4);
1597+ dots_cr = cairo_create (dots_surf);
1598+
1599+ // clear normal context
1600+ cairo_scale (cr, 1.0f, 1.0f);
1601+ cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
1602+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
1603+ cairo_paint (cr);
1604+
1605+ // prepare drawing for normal context
1606+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1607+
1608+ // create path in normal context
1609+ cairo_rectangle (cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height);
1610+
1611+ // fill path of normal context with tint
1612+ cairo_set_source_rgba (cr,
1613+ rgba_tint[0],
1614+ rgba_tint[1],
1615+ rgba_tint[2],
1616+ rgba_tint[3]);
1617+ cairo_fill_preserve (cr);
1618+
1619+ // create pattern in dot-context
1620+ cairo_set_operator (dots_cr, CAIRO_OPERATOR_CLEAR);
1621+ cairo_paint (dots_cr);
1622+ cairo_scale (dots_cr, 1.0f, 1.0f);
1623+ cairo_set_operator (dots_cr, CAIRO_OPERATOR_OVER);
1624+ cairo_set_source_rgba (dots_cr,
1625+ rgba_dot[0],
1626+ rgba_dot[1],
1627+ rgba_dot[2],
1628+ rgba_dot[3]);
1629+ cairo_rectangle (dots_cr, 0.0f, 0.0f, 1.0f, 1.0f);
1630+ cairo_fill (dots_cr);
1631+ cairo_rectangle (dots_cr, 2.0f, 2.0f, 1.0f, 1.0f);
1632+ cairo_fill (dots_cr);
1633+ dots_pattern = cairo_pattern_create_for_surface (dots_surf);
1634+
1635+ // fill path of normal context with dot-pattern
1636+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1637+ cairo_set_source (cr, dots_pattern);
1638+ cairo_pattern_set_extend (dots_pattern, CAIRO_EXTEND_REPEAT);
1639+ cairo_fill_preserve (cr);
1640+ cairo_pattern_destroy (dots_pattern);
1641+ cairo_surface_destroy (dots_surf);
1642+ cairo_destroy (dots_cr);
1643+
1644+ // draw highlight
1645+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1646+ hl_pattern = cairo_pattern_create_radial (hl_x,
1647+ hl_y,
1648+ 0.0f,
1649+ hl_x,
1650+ hl_y,
1651+ hl_size);
1652+ cairo_pattern_add_color_stop_rgba (hl_pattern,
1653+ 0.0f,
1654+ 1.0f,
1655+ 1.0f,
1656+ 1.0f,
1657+ 0.65f);
1658+ cairo_pattern_add_color_stop_rgba (hl_pattern, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f);
1659+ cairo_set_source (cr, hl_pattern);
1660+ cairo_fill (cr);
1661+ cairo_pattern_destroy (hl_pattern);
1662+}
1663+
1664+void ql_setup (cairo_surface_t** surf,
1665+ cairo_t** cr,
1666+ gboolean outline,
1667+ gint width,
1668+ gint height,
1669+ gboolean negative)
1670+{
1671 // // create context
1672 // if (outline)
1673 // *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
1674@@ -511,401 +732,423 @@
1675 // *surf = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
1676 // *cr = cairo_create (*surf);
1677
1678- // clear context
1679- cairo_scale (*cr, 1.0f, 1.0f);
1680- if (outline)
1681- {
1682+ // clear context
1683+ cairo_scale (*cr, 1.0f, 1.0f);
1684+ if (outline)
1685+ {
1686+ cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
1687+ cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR);
1688+ }
1689+ else
1690+ {
1691+ cairo_set_operator (*cr, CAIRO_OPERATOR_OVER);
1692+ if (negative)
1693 cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
1694- cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR);
1695- }
1696- else
1697- {
1698- cairo_set_operator (*cr, CAIRO_OPERATOR_OVER);
1699- if (negative)
1700- cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
1701- else
1702- cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
1703- }
1704- cairo_paint (*cr);
1705- }
1706-
1707- void ql_compute_full_mask_path (cairo_t* cr,
1708- gfloat anchor_width,
1709- gfloat anchor_height,
1710- gint width,
1711- gint height,
1712- gint upper_size,
1713- gfloat radius,
1714- guint pad)
1715- {
1716- // 0 1 2 3
1717- // +--+--------+--+
1718- // | |
1719- // + 14 + 4
1720- // | |
1721- // | |
1722- // | |
1723- // + 13 |
1724- // / |
1725- // / |
1726- // + 12 |
1727- // \ |
1728- // \ |
1729- // 11 + |
1730- // | |
1731- // | |
1732- // | |
1733- // 10 + + 5
1734- // | |
1735- // +--+--------+--+ 6
1736- // 9 8 7
1737-
1738-
1739- gfloat padding = pad;
1740- int ZEROPOINT5 = 0.0f;
1741-
1742- gfloat HeightToAnchor = 0.0f;
1743- HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
1744- if (HeightToAnchor < 0.0f)
1745- {
1746- g_warning ("Anchor-height and corner-radius a higher than whole texture!");
1747- return;
1748- }
1749-
1750- //gint dynamic_size = height - 2*radius - 2*padding - anchor_height;
1751- //gint upper_dynamic_size = upper_size;
1752- //gint lower_dynamic_size = dynamic_size - upper_dynamic_size;
1753-
1754- if(upper_size >= 0)
1755- {
1756- if(upper_size > height - 2.0f * radius - anchor_height -2 * padding)
1757- {
1758- //g_warning ("[_compute_full_mask_path] incorrect upper_size value");
1759- HeightToAnchor = 0;
1760- }
1761- else
1762- {
1763- HeightToAnchor = height - 2.0f * radius - anchor_height -2 * padding - upper_size;
1764- }
1765- }
1766- else
1767- {
1768- HeightToAnchor = (height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
1769- }
1770-
1771- cairo_translate (cr, -0.5f, -0.5f);
1772-
1773- // create path
1774- cairo_move_to (cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5); // Point 1
1775- cairo_line_to (cr, width - padding - radius, padding + ZEROPOINT5); // Point 2
1776- cairo_arc (cr,
1777- width - padding - radius + ZEROPOINT5,
1778- padding + radius + ZEROPOINT5,
1779- radius,
1780- -90.0f * G_PI / 180.0f,
1781- 0.0f * G_PI / 180.0f); // Point 4
1782- cairo_line_to (cr,
1783- (gdouble) width - padding + ZEROPOINT5,
1784- (gdouble) height - radius - padding + ZEROPOINT5); // Point 5
1785- cairo_arc (cr,
1786- (gdouble) width - padding - radius + ZEROPOINT5,
1787- (gdouble) height - padding - radius + ZEROPOINT5,
1788- radius,
1789- 0.0f * G_PI / 180.0f,
1790- 90.0f * G_PI / 180.0f); // Point 7
1791- cairo_line_to (cr,
1792- anchor_width + padding + radius + ZEROPOINT5,
1793- (gdouble) height - padding + ZEROPOINT5); // Point 8
1794-
1795- cairo_arc (cr,
1796- anchor_width + padding + radius + ZEROPOINT5,
1797- (gdouble) height - padding - radius,
1798- radius,
1799- 90.0f * G_PI / 180.0f,
1800- 180.0f * G_PI / 180.0f); // Point 10
1801-
1802- cairo_line_to (cr,
1803- padding + anchor_width + ZEROPOINT5,
1804- (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5 ); // Point 11
1805- cairo_line_to (cr,
1806- padding + ZEROPOINT5,
1807- (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12
1808- cairo_line_to (cr,
1809- padding + anchor_width + ZEROPOINT5,
1810- (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5); // Point 13
1811-
1812- cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, padding + radius + ZEROPOINT5); // Point 14
1813- cairo_arc (cr,
1814- padding + anchor_width + radius + ZEROPOINT5,
1815- padding + radius + ZEROPOINT5,
1816- radius,
1817- 180.0f * G_PI / 180.0f,
1818- 270.0f * G_PI / 180.0f);
1819-
1820- cairo_close_path (cr);
1821- }
1822-
1823- void ql_compute_mask (cairo_t* cr)
1824- {
1825- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
1826- cairo_fill_preserve (cr);
1827- }
1828-
1829- void ql_compute_outline (cairo_t* cr,
1830- gfloat line_width,
1831- gfloat* rgba_line)
1832- {
1833- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
1834- cairo_set_source_rgba (cr,
1835- rgba_line[0],
1836- rgba_line[1],
1837- rgba_line[2],
1838- rgba_line[3]);
1839+ else
1840+ cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
1841+ }
1842+ cairo_paint (*cr);
1843+}
1844+
1845+void ql_compute_full_mask_path (cairo_t* cr,
1846+ gfloat anchor_width,
1847+ gfloat anchor_height,
1848+ gint width,
1849+ gint height,
1850+ gint upper_size,
1851+ gfloat radius,
1852+ guint pad)
1853+{
1854+ // 0 1 2 3
1855+ // +--+--------+--+
1856+ // | |
1857+ // + 14 + 4
1858+ // | |
1859+ // | |
1860+ // | |
1861+ // + 13 |
1862+ // / |
1863+ // / |
1864+ // + 12 |
1865+ // \ |
1866+ // \ |
1867+ // 11 + |
1868+ // | |
1869+ // | |
1870+ // | |
1871+ // 10 + + 5
1872+ // | |
1873+ // +--+--------+--+ 6
1874+ // 9 8 7
1875+
1876+
1877+ gfloat padding = pad;
1878+ int ZEROPOINT5 = 0.0f;
1879+
1880+ gfloat HeightToAnchor = 0.0f;
1881+ HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
1882+ if (HeightToAnchor < 0.0f)
1883+ {
1884+ g_warning ("Anchor-height and corner-radius a higher than whole texture!");
1885+ return;
1886+ }
1887+
1888+ //gint dynamic_size = height - 2*radius - 2*padding - anchor_height;
1889+ //gint upper_dynamic_size = upper_size;
1890+ //gint lower_dynamic_size = dynamic_size - upper_dynamic_size;
1891+
1892+ if(upper_size >= 0)
1893+ {
1894+ if(upper_size > height - 2.0f * radius - anchor_height -2 * padding)
1895+ {
1896+ //g_warning ("[_compute_full_mask_path] incorrect upper_size value");
1897+ HeightToAnchor = 0;
1898+ }
1899+ else
1900+ {
1901+ HeightToAnchor = height - 2.0f * radius - anchor_height -2 * padding - upper_size;
1902+ }
1903+ }
1904+ else
1905+ {
1906+ HeightToAnchor = (height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
1907+ }
1908+
1909+ cairo_translate (cr, -0.5f, -0.5f);
1910+
1911+ // create path
1912+ cairo_move_to (cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5); // Point 1
1913+ cairo_line_to (cr, width - padding - radius, padding + ZEROPOINT5); // Point 2
1914+ cairo_arc (cr,
1915+ width - padding - radius + ZEROPOINT5,
1916+ padding + radius + ZEROPOINT5,
1917+ radius,
1918+ -90.0f * G_PI / 180.0f,
1919+ 0.0f * G_PI / 180.0f); // Point 4
1920+ cairo_line_to (cr,
1921+ (gdouble) width - padding + ZEROPOINT5,
1922+ (gdouble) height - radius - padding + ZEROPOINT5); // Point 5
1923+ cairo_arc (cr,
1924+ (gdouble) width - padding - radius + ZEROPOINT5,
1925+ (gdouble) height - padding - radius + ZEROPOINT5,
1926+ radius,
1927+ 0.0f * G_PI / 180.0f,
1928+ 90.0f * G_PI / 180.0f); // Point 7
1929+ cairo_line_to (cr,
1930+ anchor_width + padding + radius + ZEROPOINT5,
1931+ (gdouble) height - padding + ZEROPOINT5); // Point 8
1932+
1933+ cairo_arc (cr,
1934+ anchor_width + padding + radius + ZEROPOINT5,
1935+ (gdouble) height - padding - radius,
1936+ radius,
1937+ 90.0f * G_PI / 180.0f,
1938+ 180.0f * G_PI / 180.0f); // Point 10
1939+
1940+ cairo_line_to (cr,
1941+ padding + anchor_width + ZEROPOINT5,
1942+ (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5 ); // Point 11
1943+ cairo_line_to (cr,
1944+ padding + ZEROPOINT5,
1945+ (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12
1946+ cairo_line_to (cr,
1947+ padding + anchor_width + ZEROPOINT5,
1948+ (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5); // Point 13
1949+
1950+ cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, padding + radius + ZEROPOINT5); // Point 14
1951+ cairo_arc (cr,
1952+ padding + anchor_width + radius + ZEROPOINT5,
1953+ padding + radius + ZEROPOINT5,
1954+ radius,
1955+ 180.0f * G_PI / 180.0f,
1956+ 270.0f * G_PI / 180.0f);
1957+
1958+ cairo_close_path (cr);
1959+}
1960+
1961+void ql_compute_mask (cairo_t* cr)
1962+{
1963+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
1964+ cairo_fill_preserve (cr);
1965+}
1966+
1967+void ql_compute_outline (cairo_t* cr,
1968+ gfloat line_width,
1969+ gfloat* rgba_line)
1970+{
1971+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
1972+ cairo_set_source_rgba (cr,
1973+ rgba_line[0],
1974+ rgba_line[1],
1975+ rgba_line[2],
1976+ rgba_line[3]);
1977+ cairo_set_line_width (cr, line_width);
1978+ cairo_stroke (cr);
1979+}
1980+
1981+void ql_draw (cairo_t* cr,
1982+ gboolean outline,
1983+ gfloat line_width,
1984+ gfloat* rgba,
1985+ gboolean negative,
1986+ gboolean stroke)
1987+{
1988+ // prepare drawing
1989+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
1990+
1991+ // actually draw the mask
1992+ if (outline)
1993+ {
1994 cairo_set_line_width (cr, line_width);
1995- cairo_stroke (cr);
1996- }
1997-
1998- void ql_draw (cairo_t* cr,
1999- gboolean outline,
2000- gfloat line_width,
2001- gfloat* rgba,
2002- gboolean negative,
2003- gboolean stroke)
2004- {
2005- // prepare drawing
2006- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2007-
2008- // actually draw the mask
2009- if (outline)
2010- {
2011- cairo_set_line_width (cr, line_width);
2012- cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
2013- }
2014- else
2015- {
2016- if (negative)
2017- cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
2018- else
2019- cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
2020- }
2021-
2022- // stroke or fill?
2023- if (stroke)
2024- cairo_stroke_preserve (cr);
2025- else
2026- cairo_fill_preserve (cr);
2027- }
2028-
2029- void ql_finalize (cairo_t** cr,
2030- gboolean outline,
2031- gfloat line_width,
2032- gfloat* rgba,
2033- gboolean negative,
2034- gboolean stroke)
2035- {
2036- // prepare drawing
2037- cairo_set_operator (*cr, CAIRO_OPERATOR_SOURCE);
2038-
2039- // actually draw the mask
2040- if (outline)
2041- {
2042- cairo_set_line_width (*cr, line_width);
2043- cairo_set_source_rgba (*cr, rgba[0], rgba[1], rgba[2], rgba[3]);
2044- }
2045- else
2046- {
2047- if (negative)
2048- cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
2049- else
2050- cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
2051- }
2052-
2053- // stroke or fill?
2054- if (stroke)
2055- cairo_stroke (*cr);
2056- else
2057- cairo_fill (*cr);
2058- }
2059-
2060- void
2061- ql_compute_full_outline_shadow (
2062- cairo_t* cr,
2063- cairo_surface_t* surf,
2064- gint width,
2065- gint height,
2066- gfloat anchor_width,
2067- gfloat anchor_height,
2068- gint upper_size,
2069- gfloat corner_radius,
2070- guint blur_coeff,
2071- gfloat* rgba_shadow,
2072- gfloat line_width,
2073- gint padding_size,
2074- gfloat* rgba_line)
2075- {
2076- ql_setup (&surf, &cr, TRUE, width, height, FALSE);
2077- ql_compute_full_mask_path (cr,
2078- anchor_width,
2079- anchor_height,
2080- width,
2081- height,
2082- upper_size,
2083- corner_radius,
2084- padding_size);
2085-
2086- ql_draw (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
2087- ql_surface_blur (surf, blur_coeff);
2088- ql_compute_mask (cr);
2089- ql_compute_outline (cr, line_width, rgba_line);
2090- }
2091-
2092- void ql_compute_full_mask (
2093- cairo_t* cr,
2094- cairo_surface_t* surf,
2095- gint width,
2096- gint height,
2097- gfloat radius,
2098- guint shadow_radius,
2099- gfloat anchor_width,
2100- gfloat anchor_height,
2101- gint upper_size,
2102- gboolean negative,
2103- gboolean outline,
2104- gfloat line_width,
2105- gint padding_size,
2106- gfloat* rgba)
2107- {
2108- ql_setup (&surf, &cr, outline, width, height, negative);
2109- ql_compute_full_mask_path (cr,
2110- anchor_width,
2111- anchor_height,
2112- width,
2113- height,
2114- upper_size,
2115- radius,
2116- padding_size);
2117- ql_finalize (&cr, outline, line_width, rgba, negative, outline);
2118- }
2119-
2120- void QuicklistView::UpdateTexture ()
2121- {
2122- if (_cairo_text_has_changed == false)
2123- return;
2124-
2125- float blur_coef = 6.0f;
2126-
2127- CairoGraphics* cairo_bg = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2128- CairoGraphics* cairo_mask = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2129- CairoGraphics* cairo_outline = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2130-
2131- cairo_t *cr_bg = cairo_bg->GetContext ();
2132- cairo_t *cr_mask = cairo_mask->GetContext ();
2133- cairo_t *cr_outline = cairo_outline->GetContext ();
2134-
2135- float tint_color[4] = {0.0f, 0.0f, 0.0f, 0.80f};
2136- float hl_color[4] = {1.0f, 1.0f, 1.0f, 0.15f};
2137- float dot_color[4] = {1.0f, 1.0f, 1.0f, 0.20f};
2138- float shadow_color[4] = {0.0f, 0.0f, 0.0f, 1.00f};
2139- float outline_color[4] = {1.0f, 1.0f, 1.0f, 0.75f};
2140- float mask_color[4] = {1.0f, 1.0f, 1.0f, 1.00f};
2141- float anchor_width = 10;
2142- float anchor_height = 18;
2143-
2144- ql_tint_dot_hl (cr_bg,
2145- GetBaseWidth (),
2146- GetBaseHeight (),
2147- GetBaseWidth () / 2.0f,
2148- 0,
2149- Max<float>(GetBaseWidth () / 1.3f, GetBaseHeight () / 1.3f),
2150- tint_color,
2151- hl_color,
2152- dot_color);
2153-
2154- ql_compute_full_outline_shadow
2155- (
2156- cr_outline,
2157- cairo_outline->GetSurface(),
2158- GetBaseWidth (),
2159- GetBaseHeight (),
2160- anchor_width,
2161- anchor_height,
2162- -1,
2163- _corner_radius,
2164- blur_coef,
2165- shadow_color,
2166- 1.0f,
2167- _padding,
2168- outline_color);
2169-
2170- ql_compute_full_mask (
2171- cr_mask,
2172- cairo_mask->GetSurface(),
2173- GetBaseWidth (),
2174- GetBaseHeight(),
2175- _corner_radius, // radius,
2176- 16, // shadow_radius,
2177- anchor_width, // anchor_width,
2178- anchor_height, // anchor_height,
2179- -1, // upper_size,
2180- true, // negative,
2181- false, // outline,
2182- 1.0, // line_width,
2183- _padding, // padding_size,
2184- mask_color);
2185-
2186- cairo_destroy (cr_bg);
2187- cairo_destroy (cr_outline);
2188- cairo_destroy (cr_mask);
2189-
2190- NBitmapData* bitmap = cairo_bg->GetBitmap();
2191-
2192- if (_texture_bg)
2193- _texture_bg->UnReference ();
2194- _texture_bg = GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
2195- _texture_bg->Update(bitmap);
2196- delete bitmap;
2197-
2198- bitmap = cairo_mask->GetBitmap();
2199- if (_texture_mask)
2200- _texture_mask->UnReference ();
2201- _texture_mask = GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
2202- _texture_mask->Update(bitmap);
2203- delete bitmap;
2204-
2205- bitmap = cairo_outline->GetBitmap();
2206- if (_texture_outline)
2207- _texture_outline->UnReference ();
2208- _texture_outline = GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
2209- _texture_outline->Update(bitmap);
2210- delete bitmap;
2211-
2212- delete cairo_bg;
2213- delete cairo_mask;
2214- delete cairo_outline;
2215- _cairo_text_has_changed = false;
2216- }
2217-
2218- void QuicklistView::PositionChildLayout (float offsetX,
2219- float offsetY)
2220- {
2221- }
2222-
2223- void QuicklistView::LayoutWindowElements ()
2224- {
2225- }
2226-
2227- void QuicklistView::NotifyConfigurationChange (int width,
2228- int height)
2229- {
2230- }
2231-
2232- void QuicklistView::SetText (NString text)
2233- {
2234- if (_labelText == text)
2235- return;
2236-
2237- _labelText = text;
2238- UpdateTexture ();
2239- }
2240-
2241-} // namespace nux
2242+ cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
2243+ }
2244+ else
2245+ {
2246+ if (negative)
2247+ cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
2248+ else
2249+ cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
2250+ }
2251+
2252+ // stroke or fill?
2253+ if (stroke)
2254+ cairo_stroke_preserve (cr);
2255+ else
2256+ cairo_fill_preserve (cr);
2257+}
2258+
2259+void ql_finalize (cairo_t** cr,
2260+ gboolean outline,
2261+ gfloat line_width,
2262+ gfloat* rgba,
2263+ gboolean negative,
2264+ gboolean stroke)
2265+{
2266+ // prepare drawing
2267+ cairo_set_operator (*cr, CAIRO_OPERATOR_SOURCE);
2268+
2269+ // actually draw the mask
2270+ if (outline)
2271+ {
2272+ cairo_set_line_width (*cr, line_width);
2273+ cairo_set_source_rgba (*cr, rgba[0], rgba[1], rgba[2], rgba[3]);
2274+ }
2275+ else
2276+ {
2277+ if (negative)
2278+ cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
2279+ else
2280+ cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
2281+ }
2282+
2283+ // stroke or fill?
2284+ if (stroke)
2285+ cairo_stroke (*cr);
2286+ else
2287+ cairo_fill (*cr);
2288+}
2289+
2290+void
2291+ ql_compute_full_outline_shadow (
2292+ cairo_t* cr,
2293+ cairo_surface_t* surf,
2294+ gint width,
2295+ gint height,
2296+ gfloat anchor_width,
2297+ gfloat anchor_height,
2298+ gint upper_size,
2299+ gfloat corner_radius,
2300+ guint blur_coeff,
2301+ gfloat* rgba_shadow,
2302+ gfloat line_width,
2303+ gint padding_size,
2304+ gfloat* rgba_line)
2305+{
2306+ ql_setup (&surf, &cr, TRUE, width, height, FALSE);
2307+ ql_compute_full_mask_path (cr,
2308+ anchor_width,
2309+ anchor_height,
2310+ width,
2311+ height,
2312+ upper_size,
2313+ corner_radius,
2314+ padding_size);
2315+
2316+ ql_draw (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
2317+ ql_surface_blur (surf, blur_coeff);
2318+ ql_compute_mask (cr);
2319+ ql_compute_outline (cr, line_width, rgba_line);
2320+}
2321+
2322+void ql_compute_full_mask (
2323+ cairo_t* cr,
2324+ cairo_surface_t* surf,
2325+ gint width,
2326+ gint height,
2327+ gfloat radius,
2328+ guint shadow_radius,
2329+ gfloat anchor_width,
2330+ gfloat anchor_height,
2331+ gint upper_size,
2332+ gboolean negative,
2333+ gboolean outline,
2334+ gfloat line_width,
2335+ gint padding_size,
2336+ gfloat* rgba)
2337+{
2338+ ql_setup (&surf, &cr, outline, width, height, negative);
2339+ ql_compute_full_mask_path (cr,
2340+ anchor_width,
2341+ anchor_height,
2342+ width,
2343+ height,
2344+ upper_size,
2345+ radius,
2346+ padding_size);
2347+ ql_finalize (&cr, outline, line_width, rgba, negative, outline);
2348+}
2349+
2350+void QuicklistView::UpdateTexture ()
2351+{
2352+ if (_cairo_text_has_changed == false)
2353+ return;
2354+
2355+ int size_above_anchor = -1; // equal to sise below
2356+
2357+ if ((_item_list.size () != 0) || (_default_item_list.size () != 0))
2358+ {
2359+ _top_size = 4;
2360+ size_above_anchor = _top_size;
2361+ int x = _anchorX - _padding;
2362+ int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding;
2363+
2364+ SetBaseX (x);
2365+ SetBaseY (y);
2366+ }
2367+ else
2368+ {
2369+ _top_size = 0;
2370+ size_above_anchor = -1;
2371+ int x = _anchorX - _padding;
2372+ int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding;
2373+
2374+ SetBaseX (x);
2375+ SetBaseY (y);
2376+ }
2377+
2378+ float blur_coef = 6.0f;
2379+
2380+ nux::CairoGraphics* cairo_bg = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2381+ nux::CairoGraphics* cairo_mask = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2382+ nux::CairoGraphics* cairo_outline = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2383+
2384+ cairo_t *cr_bg = cairo_bg->GetContext ();
2385+ cairo_t *cr_mask = cairo_mask->GetContext ();
2386+ cairo_t *cr_outline = cairo_outline->GetContext ();
2387+
2388+ float tint_color[4] = {0.0f, 0.0f, 0.0f, 0.80f};
2389+ float hl_color[4] = {1.0f, 1.0f, 1.0f, 0.15f};
2390+ float dot_color[4] = {1.0f, 1.0f, 1.0f, 0.20f};
2391+ float shadow_color[4] = {0.0f, 0.0f, 0.0f, 1.00f};
2392+ float outline_color[4] = {1.0f, 1.0f, 1.0f, 0.75f};
2393+ float mask_color[4] = {1.0f, 1.0f, 1.0f, 1.00f};
2394+// float anchor_width = 10;
2395+// float anchor_height = 18;
2396+
2397+ ql_tint_dot_hl (cr_bg,
2398+ GetBaseWidth (),
2399+ GetBaseHeight (),
2400+ GetBaseWidth () / 2.0f,
2401+ 0,
2402+ nux::Max<float>(GetBaseWidth () / 1.3f, GetBaseHeight () / 1.3f),
2403+ tint_color,
2404+ hl_color,
2405+ dot_color);
2406+
2407+ ql_compute_full_outline_shadow
2408+ (
2409+ cr_outline,
2410+ cairo_outline->GetSurface(),
2411+ GetBaseWidth (),
2412+ GetBaseHeight (),
2413+ _anchor_width,
2414+ _anchor_height,
2415+ size_above_anchor,
2416+ _corner_radius,
2417+ blur_coef,
2418+ shadow_color,
2419+ 1.0f,
2420+ _padding,
2421+ outline_color);
2422+
2423+ ql_compute_full_mask (
2424+ cr_mask,
2425+ cairo_mask->GetSurface(),
2426+ GetBaseWidth (),
2427+ GetBaseHeight(),
2428+ _corner_radius, // radius,
2429+ 16, // shadow_radius,
2430+ _anchor_width, // anchor_width,
2431+ _anchor_height, // anchor_height,
2432+ size_above_anchor, // upper_size,
2433+ true, // negative,
2434+ false, // outline,
2435+ 1.0, // line_width,
2436+ _padding, // padding_size,
2437+ mask_color);
2438+
2439+ cairo_destroy (cr_bg);
2440+ cairo_destroy (cr_outline);
2441+ cairo_destroy (cr_mask);
2442+
2443+ nux::NBitmapData* bitmap = cairo_bg->GetBitmap();
2444+
2445+ if (_texture_bg)
2446+ _texture_bg->UnReference ();
2447+ _texture_bg = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
2448+ _texture_bg->Update(bitmap);
2449+ delete bitmap;
2450+
2451+ bitmap = cairo_mask->GetBitmap();
2452+ if (_texture_mask)
2453+ _texture_mask->UnReference ();
2454+ _texture_mask = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
2455+ _texture_mask->Update(bitmap);
2456+ delete bitmap;
2457+
2458+ bitmap = cairo_outline->GetBitmap();
2459+ if (_texture_outline)
2460+ _texture_outline->UnReference ();
2461+ _texture_outline = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
2462+ _texture_outline->Update(bitmap);
2463+ delete bitmap;
2464+
2465+ delete cairo_bg;
2466+ delete cairo_mask;
2467+ delete cairo_outline;
2468+ _cairo_text_has_changed = false;
2469+
2470+ // Request a redraw, so this area will be added to Compiz list of dirty areas.
2471+ NeedRedraw ();
2472+}
2473+
2474+void QuicklistView::PositionChildLayout (float offsetX, float offsetY)
2475+{
2476+}
2477+
2478+void QuicklistView::LayoutWindowElements ()
2479+{
2480+}
2481+
2482+void QuicklistView::NotifyConfigurationChange (int width, int height)
2483+{
2484+}
2485+
2486+void QuicklistView::SetText (nux::NString text)
2487+{
2488+ if (_labelText == text)
2489+ return;
2490+
2491+ _labelText = text;
2492+ UpdateTexture ();
2493+}
2494
2495=== modified file 'src/QuicklistView.h'
2496--- src/QuicklistView.h 2010-11-11 10:46:30 +0000
2497+++ src/QuicklistView.h 2010-11-18 14:03:47 +0000
2498@@ -17,8 +17,8 @@
2499 * Authored by: Mirco Müller <mirco.mueller@canonical.com
2500 */
2501
2502-#ifndef TOOLTIP_H
2503-#define TOOLTIP_H
2504+#ifndef QUICKLISTVIEW_H
2505+#define QUICKLISTVIEW_H
2506
2507 #include "Nux/Nux.h"
2508 #include "Nux/BaseWindow.h"
2509@@ -46,77 +46,92 @@
2510 #define V_MARGIN 4
2511 #define FONT_FACE "Ubuntu 13"
2512
2513-namespace nux
2514+
2515+class VLayout;
2516+class HLayout;
2517+class SpaceLayout;
2518+
2519+class QuicklistView : public nux::BaseWindow
2520 {
2521- class VLayout;
2522- class HLayout;
2523- class SpaceLayout;
2524-
2525- class QuicklistView : public BaseWindow
2526- {
2527- NUX_DECLARE_OBJECT_TYPE (QuicklistView, BaseWindow);
2528- public:
2529- QuicklistView ();
2530-
2531- ~QuicklistView ();
2532-
2533- long ProcessEvent (IEvent& iEvent,
2534- long traverseInfo,
2535- long processEventInfo);
2536-
2537- void Draw (GraphicsEngine& gfxContext,
2538- bool forceDraw);
2539-
2540- void DrawContent (GraphicsEngine& gfxContext,
2541- bool forceDraw);
2542-
2543- void SetText (NString text);
2544-
2545- private:
2546- void RecvCairoTextChanged (StaticCairoText& cairo_text);
2547-
2548- void PreLayoutManagement ();
2549-
2550- long PostLayoutManagement (long layoutResult);
2551-
2552- void PositionChildLayout (float offsetX,
2553- float offsetY);
2554-
2555- void LayoutWindowElements ();
2556-
2557- void NotifyConfigurationChange (int width,
2558- int height);
2559-
2560- //nux::CairoGraphics* _cairo_graphics;
2561- int _anchorX;
2562- int _anchorY;
2563- nux::NString _labelText;
2564- int _dpiX;
2565- int _dpiY;
2566-
2567- cairo_font_options_t* _fontOpts;
2568-
2569- nux::StaticCairoText* _tooltip_text;
2570- nux::BaseTexture* _texture_bg;
2571- nux::BaseTexture* _texture_mask;
2572- nux::BaseTexture* _texture_outline;
2573-
2574- float _anchor_width;
2575- float _anchor_height;
2576- float _corner_radius;
2577- float _padding;
2578- nux::HLayout *_hlayout;
2579- VLayout *_vlayout;
2580- nux::SpaceLayout *_left_space; //!< Space from the left of the widget to the left of the text.
2581- nux::SpaceLayout *_right_space; //!< Space from the right of the text to the right of the widget.
2582- nux::SpaceLayout *_top_space; //!< Space from the left of the widget to the left of the text.
2583- nux::SpaceLayout *_bottom_space; //!< Space from the right of the text to the right of the widget.
2584-
2585- bool _cairo_text_has_changed;
2586- void UpdateTexture ();
2587- std::list<nux::StaticCairoText*> _item_list;
2588- };
2589-}
2590-
2591-#endif // TOOLTIP_H
2592+ NUX_DECLARE_OBJECT_TYPE (QuicklistView, nux::BaseWindow);
2593+public:
2594+ QuicklistView ();
2595+
2596+ ~QuicklistView ();
2597+
2598+ long ProcessEvent (nux::IEvent& iEvent,
2599+ long traverseInfo,
2600+ long processEventInfo);
2601+
2602+ void Draw (nux::GraphicsEngine& gfxContext,
2603+ bool forceDraw);
2604+
2605+ void DrawContent (nux::GraphicsEngine& gfxContext,
2606+ bool forceDraw);
2607+
2608+ void SetText (nux::NString text);
2609+
2610+ void RemoveAllMenuItem ();
2611+ void AddMenuItem (nux::NString str);
2612+ void RenderQuicklistView ();
2613+
2614+ void ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y);
2615+ virtual void ShowWindow (bool b, bool StartModal = false);
2616+
2617+private:
2618+ void RecvCairoTextChanged (nux::StaticCairoText& cairo_text);
2619+ void RecvCairoTextColorChanged (nux::StaticCairoText& cairo_text);
2620+
2621+ void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags);
2622+ void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags);
2623+ void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags);
2624+ void RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
2625+ void RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
2626+ void RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long button_flags, unsigned long key_flags);
2627+
2628+ void PreLayoutManagement ();
2629+
2630+ long PostLayoutManagement (long layoutResult);
2631+
2632+ void PositionChildLayout (float offsetX, float offsetY);
2633+
2634+ void LayoutWindowElements ();
2635+
2636+ void NotifyConfigurationChange (int width, int height);
2637+
2638+ //nux::CairoGraphics* _cairo_graphics;
2639+ int _anchorX;
2640+ int _anchorY;
2641+ nux::NString _labelText;
2642+ int _dpiX;
2643+ int _dpiY;
2644+ int _top_size; // size of the segment from point 13 to 14. See figure in ql_compute_full_mask_path.
2645+
2646+ cairo_font_options_t* _fontOpts;
2647+
2648+ nux::StaticCairoText* _tooltip_text;
2649+ nux::BaseTexture* _texture_bg;
2650+ nux::BaseTexture* _texture_mask;
2651+ nux::BaseTexture* _texture_outline;
2652+
2653+ float _anchor_width;
2654+ float _anchor_height;
2655+ float _corner_radius;
2656+ float _padding;
2657+ nux::HLayout *_hlayout;
2658+ nux::VLayout *_vlayout;
2659+ nux::VLayout *_item_layout;
2660+ nux::VLayout *_default_item_layout;
2661+ nux::SpaceLayout *_left_space; //!< Space from the left of the widget to the left of the text.
2662+ nux::SpaceLayout *_right_space; //!< Space from the right of the text to the right of the widget.
2663+ nux::SpaceLayout *_top_space; //!< Space from the left of the widget to the left of the text.
2664+ nux::SpaceLayout *_bottom_space; //!< Space from the right of the text to the right of the widget.
2665+
2666+ bool _cairo_text_has_changed;
2667+ void UpdateTexture ();
2668+ std::list<nux::StaticCairoText*> _item_list;
2669+ std::list<nux::StaticCairoText*> _default_item_list;
2670+};
2671+
2672+#endif // QUICKLISTVIEW_H
2673
2674
2675=== modified file 'src/StaticCairoText.cpp'
2676--- src/StaticCairoText.cpp 2010-11-10 15:45:18 +0000
2677+++ src/StaticCairoText.cpp 2010-11-18 14:03:47 +0000
2678@@ -170,7 +170,7 @@
2679 base.height,
2680 _texture2D->GetDeviceTexture(),
2681 texxform,
2682- Color(1.0f, 1.0f, 1.0f, 1.0f));
2683+ _textColor);
2684
2685 gfxContext.GetRenderStates().SetBlend (false);
2686
2687@@ -252,8 +252,7 @@
2688 if (_textColor != textColor)
2689 {
2690 _textColor = textColor;
2691- UpdateTexture ();
2692- sigTextChanged.emit (*this);
2693+ sigTextColorChanged.emit (*this);
2694 }
2695 }
2696
2697
2698=== modified file 'src/StaticCairoText.h'
2699--- src/StaticCairoText.h 2010-11-10 14:42:46 +0000
2700+++ src/StaticCairoText.h 2010-11-18 14:03:47 +0000
2701@@ -99,6 +99,7 @@
2702 void GetTextExtents (int &width, int &height);
2703
2704 sigc::signal<void, StaticCairoText&> sigTextChanged;
2705+ sigc::signal<void, StaticCairoText&> sigTextColorChanged;
2706
2707 protected:
2708
2709
2710=== modified file 'src/Tooltip.cpp'
2711--- src/Tooltip.cpp 2010-11-11 15:08:31 +0000
2712+++ src/Tooltip.cpp 2010-11-18 14:03:47 +0000
2713@@ -49,6 +49,7 @@
2714 _anchor_height = 18;
2715 _corner_radius = 4;
2716 _padding = 15;
2717+ _top_size = 4;
2718
2719 _hlayout = new nux::HLayout (TEXT(""), NUX_TRACKER_LOCATION);
2720 _vlayout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
2721@@ -94,6 +95,26 @@
2722
2723 return ret;
2724 }
2725+
2726+ void Tooltip::ShowTooltipWithTipAt (int anchor_tip_x, int anchor_tip_y)
2727+ {
2728+ int window_width;
2729+ int window_height;
2730+
2731+ window_width = nux::GetWindow ().GetWindowWidth ();
2732+ window_height = nux::GetWindow ().GetWindowHeight ();
2733+
2734+ _anchorX = anchor_tip_x;
2735+ _anchorY = anchor_tip_y;
2736+
2737+ int x = _anchorX - _padding;
2738+ int y = anchor_tip_y - _anchor_height/2 - _top_size - _corner_radius - _padding;
2739+
2740+ SetBaseX (x);
2741+ SetBaseY (y);
2742+
2743+ ShowWindow (true);
2744+ }
2745
2746 void Tooltip::Draw (GraphicsEngine& gfxContext, bool forceDraw)
2747 {
2748@@ -766,6 +787,18 @@
2749 if (_cairo_text_has_changed == false)
2750 return;
2751
2752+ int width = GetBaseWidth ();
2753+ int height = GetBaseHeight ();
2754+ int size_above_anchor = -1; // equal to sise below
2755+
2756+ _top_size = 0;
2757+ size_above_anchor = -1;
2758+ int x = _anchorX - _padding;
2759+ int y = _anchorY - height/2;
2760+
2761+ SetBaseX (x);
2762+ SetBaseY (y);
2763+
2764 float blur_coef = 6.0f;
2765
2766 CairoGraphics* cairo_bg = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
2767@@ -782,8 +815,6 @@
2768 float shadow_color[4] = {0.0f, 0.0f, 0.0f, 1.00f};
2769 float outline_color[4] = {1.0f, 1.0f, 1.0f, 0.75f};
2770 float mask_color[4] = {1.0f, 1.0f, 1.0f, 1.00f};
2771- float anchor_width = 10;
2772- float anchor_height = 18;
2773
2774 tint_dot_hl (cr_bg,
2775 GetBaseWidth (),
2776@@ -801,8 +832,8 @@
2777 cairo_outline->GetSurface(),
2778 GetBaseWidth (),
2779 GetBaseHeight (),
2780- anchor_width,
2781- anchor_height,
2782+ _anchor_width,
2783+ _anchor_height,
2784 -1,
2785 _corner_radius,
2786 blur_coef,
2787@@ -816,15 +847,15 @@
2788 cairo_mask->GetSurface(),
2789 GetBaseWidth (),
2790 GetBaseHeight(),
2791- _corner_radius, // radius,
2792+ _corner_radius, // radius,
2793 16, // shadow_radius,
2794- anchor_width, // anchor_width,
2795- anchor_height, // anchor_height,
2796+ _anchor_width, // anchor_width,
2797+ _anchor_height, // anchor_height,
2798 -1, // upper_size,
2799 true, // negative,
2800 false, // outline,
2801 1.0, // line_width,
2802- _padding, // padding_size,
2803+ _padding, // padding_size,
2804 mask_color);
2805
2806 cairo_destroy (cr_bg);
2807
2808=== modified file 'src/Tooltip.h'
2809--- src/Tooltip.h 2010-11-11 10:46:30 +0000
2810+++ src/Tooltip.h 2010-11-18 14:03:47 +0000
2811@@ -73,6 +73,7 @@
2812
2813 void SetText (NString text);
2814
2815+ void ShowTooltipWithTipAt (int anchor_tip_x, int anchor_tip_y);
2816 private:
2817 void RecvCairoTextChanged (StaticCairoText& cairo_text);
2818
2819@@ -94,6 +95,7 @@
2820 nux::NString _labelText;
2821 int _dpiX;
2822 int _dpiY;
2823+ int _top_size; // size of the segment from point 13 to 14. See figure in _compute_full_mask_path.
2824
2825 cairo_font_options_t* _fontOpts;
2826
2827
2828=== modified file 'src/unity.cpp'
2829--- src/unity.cpp 2010-11-12 12:03:25 +0000
2830+++ src/unity.cpp 2010-11-18 14:03:47 +0000
2831@@ -188,9 +188,11 @@
2832 UnityScreen::handleEvent (XEvent *event)
2833 {
2834 screen->handleEvent (event);
2835-
2836+
2837 if (screen->otherGrabExist ("deco", "move", NULL))
2838+ {
2839 wt->ProcessForeignEvent (event, NULL);
2840+ }
2841 }
2842
2843 bool