~canonical-dx-team/unity/unity.fix-ql-losing-focus

702.3.1 by Michael Terry
add modelines and fix up some inconsistent tabbings
1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
572.5.2 by Jay Taoko
* Adding license to files
2
/*
604.2.3 by Jay Taoko
* In progress: Quicklist
3
* Copyright (C) 2010 Canonical Ltd
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 3 as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*
17
* Authored by: Jay Taoko <jay.taoko@canonical.com>
18
* Authored by: Mirco Müller <mirco.mueller@canonical.com
19
*/
572.5.2 by Jay Taoko
* Adding license to files
20
572.4.1 by Jay Taoko
* Added StaticCairoText files
21
#include "Nux/Nux.h"
22
#include "Nux/VLayout.h"
23
#include "Nux/HLayout.h"
24
#include "Nux/WindowThread.h"
25
#include "Nux/WindowCompositor.h"
26
#include "Nux/BaseWindow.h"
27
#include "Nux/Button.h"
28
#include "NuxGraphics/GraphicsEngine.h"
29
#include "Nux/TextureArea.h"
30
#include "NuxImage/CairoGraphics.h"
31
32
#include "QuicklistView.h"
613.1.1 by Jay Taoko
* Merged Mirco's QuicklistMenuItem work with trunk.
33
#include "QuicklistMenuItem.h"
613.1.5 by Jay Taoko
* QuicklistView test
34
#include "QuicklistMenuItemLabel.h"
35
#include "QuicklistMenuItemSeparator.h"
613.1.10 by Jay Taoko
* Quicklist check mark
36
#include "QuicklistMenuItemCheckmark.h"
613.1.17 by Jay Taoko
* Corrected issues resulting from code review
37
#include "QuicklistMenuItemRadio.h"
604.2.3 by Jay Taoko
* In progress: Quicklist
38
648.3.1 by Jay Taoko
* In progress: introspection
39
#include "Introspectable.h"
40
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
41
#include "ubus-server.h"
42
#include "UBusMessages.h"
43
604.2.3 by Jay Taoko
* In progress: Quicklist
44
NUX_IMPLEMENT_OBJECT_TYPE (QuicklistView);
45
46
QuicklistView::QuicklistView ()
47
{
648.3.1 by Jay Taoko
* In progress: introspection
48
  _name = g_strdup ("Quicklist");
604.2.3 by Jay Taoko
* In progress: Quicklist
49
  _texture_bg = 0;
50
  _texture_mask = 0;
51
  _texture_outline = 0;
52
  _cairo_text_has_changed = true;
53
54
  _anchorX   = 0;
55
  _anchorY   = 0;
56
  _labelText = TEXT ("QuicklistView 1234567890");
57
58
  _anchor_width   = 10;
59
  _anchor_height  = 18;
60
  _corner_radius  = 4;
61
  _padding        = 13;
605.1.1 by Jay Taoko
* Support for Quicklist
62
  _top_size       = 4;
604.2.3 by Jay Taoko
* In progress: Quicklist
63
613.1.9 by Jay Taoko
Quicklist Rendering code:
64
  SetGeometry (nux::Geometry (0, 0, 1, 1));
604.2.3 by Jay Taoko
* In progress: Quicklist
65
  _hlayout         = new nux::HLayout (TEXT(""), NUX_TRACKER_LOCATION);
66
  _vlayout         = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
605.1.1 by Jay Taoko
* Support for Quicklist
67
  _item_layout     = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
68
  _default_item_layout = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
69
  
604.2.3 by Jay Taoko
* In progress: Quicklist
70
  _left_space = new nux::SpaceLayout (_padding + _anchor_width + _corner_radius, _padding + _anchor_width + _corner_radius, 1, 1000);
71
  _right_space = new nux::SpaceLayout (_padding + _corner_radius, _padding + _corner_radius, 1, 1000);
72
73
  _top_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
74
  _bottom_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
75
605.1.1 by Jay Taoko
* Support for Quicklist
76
  _vlayout->AddLayout (_top_space, 0);
604.2.3 by Jay Taoko
* In progress: Quicklist
77
605.1.1 by Jay Taoko
* Support for Quicklist
78
  _vlayout->AddLayout (_item_layout, 0);
79
  
80
  _vlayout->AddLayout (_default_item_layout, 0);
636.6.4 by Mirco Müller
make outline-gradient correctly adapt to width of quicklist, don't call FillInDefaultItems()
81
605.1.1 by Jay Taoko
* Support for Quicklist
82
  _vlayout->AddLayout (_bottom_space, 0);
604.2.3 by Jay Taoko
* In progress: Quicklist
83
605.1.1 by Jay Taoko
* Support for Quicklist
84
  _hlayout->AddLayout (_left_space, 0);
613.1.9 by Jay Taoko
Quicklist Rendering code:
85
  _hlayout->AddLayout (_vlayout, 0, nux::eCenter, nux::eFull);
605.1.1 by Jay Taoko
* Support for Quicklist
86
  _hlayout->AddLayout (_right_space, 0);
604.2.3 by Jay Taoko
* In progress: Quicklist
87
88
  SetWindowSizeMatchLayout (true);
89
  SetLayout (_hlayout);
90
  
91
  OnMouseDownOutsideArea.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDownOutsideOfQuicklist));
92
  OnMouseDown.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDown));
93
  OnMouseUp.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseUp));
94
  OnMouseClick.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseClick));
95
  OnMouseMove.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseMove));
96
  OnMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDrag));
854.3.1 by macslow at bangang
Hook up callback to watch the Focus-state on the launcher and quicklist
97
  OnKeyPressed.connect (sigc::mem_fun (this, &QuicklistView::RecvKeyPressed));
884.2.5 by Jay Taoko
* Dash Fixes:
98
  OnStartFocus.connect (sigc::mem_fun (this, &QuicklistView::RecvStartFocus));
99
  OnEndFocus.connect   (sigc::mem_fun (this, &QuicklistView::RecvEndFocus));
854.3.1 by macslow at bangang
Hook up callback to watch the Focus-state on the launcher and quicklist
100
613.1.13 by Jay Taoko
* Connected events to items states
101
  _mouse_down = false;
648.5.8 by Mirco Müller
use separate thread to inject fake events (mouse-clicks) into event-loop
102
  _enable_quicklist_for_testing = false;
738.3.1 by Jay Taoko
* Support for Quicklist background effect
103
  _compute_blur_bkg = true;
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
104
105
  _current_item_index = 0;
854.3.1 by macslow at bangang
Hook up callback to watch the Focus-state on the launcher and quicklist
106
}
107
108
void
884.2.5 by Jay Taoko
* Dash Fixes:
109
QuicklistView::RecvStartFocus ()
110
{
111
  PushToFront ();
112
}
113
114
void
115
QuicklistView::RecvEndFocus ()
116
{
117
}
118
119
void
854.3.1 by macslow at bangang
Hook up callback to watch the Focus-state on the launcher and quicklist
120
QuicklistView::RecvKeyPressed (unsigned int  key_sym,
121
                               unsigned long key_code,
122
                               unsigned long key_state)
123
{
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
124
  switch (key_sym)
125
  {
126
    // up (highlight previous menu-item)
127
    case NUX_VK_UP:
128
      if (_current_item_index > 0)
129
      {
130
        GetNthItems (_current_item_index)->_prelight = false;
131
        _current_item_index--;
132
        GetNthItems (_current_item_index)->_prelight = true;
133
        QueueDraw ();
134
      }
135
    break;
136
137
    // down (highlight next menu-item)
138
    case NUX_VK_DOWN:
139
      if (_current_item_index < GetNumItems () - 1)
140
      {
141
        GetNthItems (_current_item_index)->_prelight = false;
142
        _current_item_index++;
143
        GetNthItems (_current_item_index)->_prelight = true;
144
        QueueDraw ();
145
      }
146
    break;
147
148
    // left (close quicklist, go back to laucher key-nav)
149
    case NUX_VK_LEFT:
150
      _current_item_index = 0;
151
      GetNthItems (_current_item_index)->_prelight = true;
152
      Hide ();
854.3.5 by macslow at bangang
no longer crashing on ESC... phew, all UBus-control goes via UnityScreen now, renamed the UBus-signals for key-nav
153
      // inform Launcher we switch back to Launcher key-nav
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
154
      ubus_server_send_message (ubus_server_get_default (),
854.3.5 by macslow at bangang
no longer crashing on ESC... phew, all UBus-control goes via UnityScreen now, renamed the UBus-signals for key-nav
155
                                UBUS_QUICKLIST_END_KEY_NAV,
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
156
                                NULL);
157
    break;
158
159
    // esc (close quicklist, exit key-nav)
160
    case NUX_VK_ESCAPE:
161
      _current_item_index = 0;
162
      GetNthItems (_current_item_index)->_prelight = true;
163
      Hide ();
854.3.5 by macslow at bangang
no longer crashing on ESC... phew, all UBus-control goes via UnityScreen now, renamed the UBus-signals for key-nav
164
      // inform UnityScreen we leave key-nav completely
165
      ubus_server_send_message (ubus_server_get_default (),
166
                                UBUS_LAUNCHER_END_KEY_NAV,
167
                                NULL);
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
168
    break;
169
170
    // <SPACE>, <RETURN> (activate selected menu-item)          
171
    case NUX_VK_SPACE:
172
    case NUX_VK_ENTER:
173
      if (_current_item_index >= 0 && _current_item_index < GetNumItems ())
174
      {
175
176
        dbusmenu_menuitem_handle_event (GetNthItems (_current_item_index)->_menuItem,
177
                                        "clicked",
178
                                        NULL,
179
                                        0);
180
        _current_item_index = 0;
181
        GetNthItems (_current_item_index)->_prelight = true;
182
        Hide ();
183
      }
184
    break;
185
186
    default:
187
    break;
188
  }
854.3.1 by macslow at bangang
Hook up callback to watch the Focus-state on the launcher and quicklist
189
}
190
604.2.3 by Jay Taoko
* In progress: Quicklist
191
QuicklistView::~QuicklistView ()
192
{
648.3.1 by Jay Taoko
* In progress: introspection
193
  if (_name)
194
    g_free (_name);
195
  
604.2.3 by Jay Taoko
* In progress: Quicklist
196
  if (_texture_bg)
197
    _texture_bg->UnReference ();
613.1.8 by Jay Taoko
* YOU NEED TO UPDATE NUX
198
  
199
  if (_texture_outline)
200
    _texture_outline->UnReference ();
201
  
202
    if (_texture_mask)
203
    _texture_mask->UnReference ();
204
  
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
205
  std::list<QuicklistMenuItem*>::iterator it;
604.2.3 by Jay Taoko
* In progress: Quicklist
206
  for (it = _item_list.begin(); it != _item_list.end(); it++)
207
  {
648.3.1 by Jay Taoko
* In progress: introspection
208
    // Remove from introspection
209
    RemoveChild (*it);
604.2.3 by Jay Taoko
* In progress: Quicklist
210
    (*it)->UnReference();
211
  }
613.1.8 by Jay Taoko
* YOU NEED TO UPDATE NUX
212
213
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
214
  {
648.3.1 by Jay Taoko
* In progress: introspection
215
    // Remove from introspection
216
    RemoveChild (*it);
613.1.8 by Jay Taoko
* YOU NEED TO UPDATE NUX
217
    (*it)->UnReference();
218
  }
219
  
220
  _default_item_list.clear ();
604.2.3 by Jay Taoko
* In progress: Quicklist
221
  _item_list.clear ();
222
}
223
648.5.8 by Mirco Müller
use separate thread to inject fake events (mouse-clicks) into event-loop
224
void
225
QuicklistView::EnableQuicklistForTesting (bool enable_testing)
226
{
227
  _enable_quicklist_for_testing = enable_testing;
228
}
229
605.1.1 by Jay Taoko
* Support for Quicklist
230
void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y)
231
{
232
  _anchorX = anchor_tip_x;
233
  _anchorY = anchor_tip_y;
234
  
743.1.2 by Jay Taoko
* Fixed Quicklist position in QuicklistView::ShowQuicklistWithTipAt
235
  if (!_enable_quicklist_for_testing)
236
  {
237
    if ((_item_list.size () != 0) || (_default_item_list.size () != 0))
238
    {
239
      int offscreen_size = GetBaseY () +
240
                           GetBaseHeight () -
241
                           nux::GetWindow().GetWindowHeight ();
242
243
      if (offscreen_size > 0)
244
        _top_size = offscreen_size;
245
      else
246
        _top_size = 4;
247
248
      int x = _anchorX - _padding;
249
      int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding;
250
251
      SetBaseX (x);
252
      SetBaseY (y);
253
    }
254
    else
255
    {
256
      _top_size = 0;
257
      int x = _anchorX - _padding;
258
      int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding;
259
260
      SetBaseX (x);
261
      SetBaseY (y);    
262
    }
263
  }
743.1.1 by macslow at bangang
Avoid Quicklists being positioned so that they are partially offscreen at the bottom screen-edge. Fixes LP: #691114
264
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
265
  Show ();
605.1.1 by Jay Taoko
* Support for Quicklist
266
}
267
604.2.3 by Jay Taoko
* In progress: Quicklist
268
void QuicklistView::ShowWindow (bool b, bool start_modal)
269
{
270
  BaseWindow::ShowWindow (b, start_modal);
271
}
272
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
273
void QuicklistView::Show ()
274
{
275
  if (!IsVisible())
276
  {
679.4.8 by Jamal Fanaian
Fixed weird input issue in the quicklist view
277
    // FIXME: ShowWindow shouldn't need to be called first
278
    ShowWindow (true);
884.2.5 by Jay Taoko
* Dash Fixes:
279
    PushToFront ();
280
    EnableInputWindow (true, "quicklist", false, true);
281
    //SetInputFocus ();
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
282
    GrabPointer ();
884.2.5 by Jay Taoko
* Dash Fixes:
283
    GrabKeyboard ();
284
    QueueDraw ();
738.3.1 by Jay Taoko
* Support for Quicklist background effect
285
    _compute_blur_bkg = true;
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
286
  }
287
}
288
289
void QuicklistView::Hide ()
290
{
679.4.7 by Jamal Fanaian
meant to do a check for _enable_quicklist_for_testing in QuicklistView::Hide()
291
  if (IsVisible() && !_enable_quicklist_for_testing)
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
292
  {
679.4.7 by Jamal Fanaian
meant to do a check for _enable_quicklist_for_testing in QuicklistView::Hide()
293
    CancelItemsPrelightStatus ();
294
    CaptureMouseDownAnyWhereElse (false);
295
    ForceStopFocus (1, 1);
296
    UnGrabPointer ();
297
    EnableInputWindow (false);
298
    ShowWindow (false);
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
299
  }
300
}
301
604.2.3 by Jay Taoko
* In progress: Quicklist
302
long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long ProcessEventInfo)
303
{
304
  long ret = TraverseInfo;
305
  long ProcEvInfo = 0;
306
307
  nux::IEvent window_event = ievent;
308
  nux::Geometry base = GetGeometry();
309
  window_event.e_x_root = base.x;
310
  window_event.e_y_root = base.y;
311
312
  // The child layout get the Mouse down button only if the MouseDown happened inside the client view Area
313
  nux::Geometry viewGeometry = GetGeometry();
314
315
  if (ievent.e_event == nux::NUX_MOUSE_PRESSED)
316
  {
317
    if (!viewGeometry.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) )
318
    {
319
      ProcEvInfo = nux::eDoNotProcess;
320
    }
321
  }
322
323
  // We choose to test the quicklist items ourselves instead of processing them as it is usual in nux.
613.1.15 by Jay Taoko
* Quicklist item rendering
324
  // This is meant to be easier since the quicklist has a atypical way of working.
613.1.13 by Jay Taoko
* Connected events to items states
325
  if (m_layout)
639.1.1 by Jay Taoko
* Improved mouse event handling
326
  {
613.1.13 by Jay Taoko
* Connected events to items states
327
    ret = m_layout->ProcessEvent (window_event, ret, ProcEvInfo);
639.1.1 by Jay Taoko
* Improved mouse event handling
328
  }
329
  
330
  // The quicklist itself does not process the evvent. Instead we do some analysis of the event 
331
  // to detect the user action and perform the correct operation.
613.1.13 by Jay Taoko
* Connected events to items states
332
  if (ievent.e_event == nux::NUX_MOUSE_PRESSED)
333
  {
334
    if (GetGeometry ().IsPointInside (ievent.e_x, ievent.e_y))
335
    {
336
      _mouse_down = true;
337
    }
338
    else
339
    {
340
      _mouse_down = false;
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
341
      Hide ();
648.5.8 by Mirco Müller
use separate thread to inject fake events (mouse-clicks) into event-loop
342
      return nux::eMouseEventSolved;
343
    }
344
  }
345
  else if ((ievent.e_event == nux::NUX_MOUSE_RELEASED) && _mouse_down)
346
  {
347
    _mouse_down = false;
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
348
    Hide ();
613.1.13 by Jay Taoko
* Connected events to items states
349
    return nux::eMouseEventSolved;
350
  }
648.5.8 by Mirco Müller
use separate thread to inject fake events (mouse-clicks) into event-loop
351
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
352
  ret = OnEvent (ievent, ret, ProcessEventInfo);
353
604.2.3 by Jay Taoko
* In progress: Quicklist
354
  return ret;    
355
}
356
357
void QuicklistView::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw)
358
{
738.3.1 by Jay Taoko
* Support for Quicklist background effect
359
  // Get the geometry of the QuicklistView on the display
604.2.3 by Jay Taoko
* In progress: Quicklist
360
  nux::Geometry base = GetGeometry();
361
738.3.1 by Jay Taoko
* Support for Quicklist background effect
362
  // Get the background of the QuicklistView and apply some 
815.1.1 by Jay Taoko
* Quicklist blurred background for all systems
363
  if (_compute_blur_bkg /* Refresh the blurred background*/)
738.3.1 by Jay Taoko
* Support for Quicklist background effect
364
  {
365
    nux::ObjectPtr<nux::IOpenGLFrameBufferObject> current_fbo = nux::GetGpuDevice ()->GetCurrentFrameBufferObject ();
366
    nux::GetGpuDevice ()->DeactivateFrameBuffer ();
367
  
368
    gfxContext.SetViewport (0, 0, gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ());
369
    gfxContext.SetScissor (0, 0, gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ());
370
    gfxContext.GetRenderStates ().EnableScissor (false);
371
372
    nux::ObjectPtr <nux::IOpenGLBaseTexture> bkg_texture = gfxContext.CreateTextureFromBackBuffer (base.x, base.y, base.width, base.height);
373
374
    nux::TexCoordXForm texxform_bkg;
755 by Jay Taoko
* Support for Quicklist background effect
375
    bkg_blur_texture = gfxContext.QRP_GetBlurTexture (0, 0, base.width, base.height, bkg_texture, texxform_bkg, nux::Color::White, 1.0f, 3);
738.3.1 by Jay Taoko
* Support for Quicklist background effect
376
377
    if (current_fbo.IsValid ())
378
    { 
379
      current_fbo->Activate (true);
380
      gfxContext.Push2DWindow (current_fbo->GetWidth (), current_fbo->GetHeight ());
381
    }
382
    else
383
    {
384
      gfxContext.SetViewport (0, 0, gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ());
385
      gfxContext.Push2DWindow (gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ());
386
      gfxContext.ApplyClippingRectangle ();
387
    }
388
    _compute_blur_bkg = false;
389
  }
390
604.2.3 by Jay Taoko
* In progress: Quicklist
391
  // the elements position inside the window are referenced to top-left window
392
  // corner. So bring base to (0, 0).
393
  base.SetX (0);
394
  base.SetY (0);
395
  gfxContext.PushClippingRectangle (base);
396
738.3.1 by Jay Taoko
* Support for Quicklist background effect
397
  nux::TexCoordXForm texxform_blur_bkg;
398
  //texxform_blur_bkg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
399
  //texxform_blur_bkg.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
604.2.3 by Jay Taoko
* In progress: Quicklist
400
401
  nux::TexCoordXForm texxform_bg;
402
  texxform_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
403
  texxform_bg.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
404
405
  nux::TexCoordXForm texxform_mask;
406
  texxform_mask.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
407
  texxform_mask.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
408
815.1.1 by Jay Taoko
* Quicklist blurred background for all systems
409
  if (bkg_blur_texture.IsValid ())
738.3.1 by Jay Taoko
* Support for Quicklist background effect
410
  {
411
    gfxContext.QRP_2TexMod (
412
      base.x,
413
      base.y,
414
      base.width,
415
      base.height,
416
      bkg_blur_texture,
417
      texxform_blur_bkg,
418
      nux::Color::White,
419
      _texture_mask->GetDeviceTexture(),
420
      texxform_mask,
421
      nux::Color::White);
422
  }
423
778.2.8 by Loïc Molinari
Made sure blending is enabled before setting the blend factors
424
  nux::GetGraphicsEngine ().GetRenderStates ().SetBlend (true);
425
  nux::GetGraphicsEngine ().GetRenderStates ().SetPremultipliedBlend (nux::SRC_OVER);
730.1.1 by Jay Taoko
Rendering call correction
426
  gfxContext.QRP_2TexMod (base.x,
604.2.3 by Jay Taoko
* In progress: Quicklist
427
    base.y,
428
    base.width,
429
    base.height,
430
    _texture_bg->GetDeviceTexture(),
431
    texxform_bg,
432
    nux::Color(1.0f, 1.0f, 1.0f, 1.0f),
433
    _texture_mask->GetDeviceTexture(),
434
    texxform_mask,
435
    nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
436
437
438
  nux::TexCoordXForm texxform;
439
  texxform.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
440
  texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD);
441
778.2.8 by Loïc Molinari
Made sure blending is enabled before setting the blend factors
442
  nux::GetGraphicsEngine ().GetRenderStates ().SetBlend (true);
443
  nux::GetGraphicsEngine ().GetRenderStates ().SetPremultipliedBlend (nux::SRC_OVER);
730.1.1 by Jay Taoko
Rendering call correction
444
  gfxContext.QRP_1Tex (base.x,
604.2.3 by Jay Taoko
* In progress: Quicklist
445
    base.y,
446
    base.width,
447
    base.height,
448
    _texture_outline->GetDeviceTexture(),
449
    texxform,
450
    nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
451
452
  nux::GetGraphicsEngine().GetRenderStates().SetBlend (false);
453
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
454
  std::list<QuicklistMenuItem*>::iterator it;
604.2.3 by Jay Taoko
* In progress: Quicklist
455
  for (it = _item_list.begin(); it != _item_list.end(); it++)
456
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
457
    if ((*it)->GetVisible())
458
      (*it)->ProcessDraw(gfxContext, forceDraw);
604.2.3 by Jay Taoko
* In progress: Quicklist
459
  }
460
605.1.1 by Jay Taoko
* Support for Quicklist
461
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
462
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
463
    if ((*it)->GetVisible())
464
      (*it)->ProcessDraw(gfxContext, forceDraw);
605.1.1 by Jay Taoko
* Support for Quicklist
465
  }
466
604.2.3 by Jay Taoko
* In progress: Quicklist
467
  gfxContext.PopClippingRectangle ();
468
}
469
470
void QuicklistView::DrawContent (nux::GraphicsEngine& GfxContext, bool force_draw)
471
{
472
473
}
474
475
void QuicklistView::PreLayoutManagement ()
476
{
477
  int MaxItemWidth = 0;
478
  int TotalItemHeight = 0;
479
  
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
480
  std::list<QuicklistMenuItem*>::iterator it;
604.2.3 by Jay Taoko
* In progress: Quicklist
481
  for (it = _item_list.begin(); it != _item_list.end(); it++)
482
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
483
    // Make sure item is in layout if it should be
484
    if (!(*it)->GetVisible()) {
485
      _item_layout->RemoveChildObject(*it);
486
      continue;
487
    }
488
    else if (!(*it)->GetParentObject())
489
      _item_layout->AddView(*it, 1, nux::eCenter, nux::eFull);
490
604.2.3 by Jay Taoko
* In progress: Quicklist
491
    int  textWidth  = 0;
492
    int  textHeight = 0;
493
    (*it)->GetTextExtents(textWidth, textHeight);
494
    if (textWidth > MaxItemWidth)
495
      MaxItemWidth = textWidth;
496
    TotalItemHeight += textHeight;
497
  }
498
605.1.1 by Jay Taoko
* Support for Quicklist
499
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
500
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
501
    // Make sure item is in layout if it should be
502
    if (!(*it)->GetVisible()) {
503
      _default_item_layout->RemoveChildObject(*it);
504
      continue;
505
    }
506
    else if (!(*it)->GetParentObject())
507
      _default_item_layout->AddView(*it, 1, nux::eCenter, nux::eFull);
508
605.1.1 by Jay Taoko
* Support for Quicklist
509
    int  textWidth  = 0;
510
    int  textHeight = 0;
511
    (*it)->GetTextExtents(textWidth, textHeight);
512
    if (textWidth > MaxItemWidth)
513
      MaxItemWidth = textWidth;
514
    TotalItemHeight += textHeight;
515
  }
613.1.9 by Jay Taoko
Quicklist Rendering code:
516
604.2.3 by Jay Taoko
* In progress: Quicklist
517
  if(TotalItemHeight < _anchor_height)
518
  {
519
    _top_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
520
    _bottom_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
521
  }
613.1.9 by Jay Taoko
Quicklist Rendering code:
522
  else
523
  {
524
    _top_space->SetMinMaxSize(_padding + _corner_radius, _padding + _corner_radius);
525
    _bottom_space->SetMinMaxSize(_padding + _corner_radius, _padding + _corner_radius);
526
   }
604.2.3 by Jay Taoko
* In progress: Quicklist
527
613.1.15 by Jay Taoko
* Quicklist item rendering
528
  _item_layout->SetMinimumWidth(MaxItemWidth);
529
  _default_item_layout->SetMinimumWidth(MaxItemWidth);
530
604.2.3 by Jay Taoko
* In progress: Quicklist
531
  BaseWindow::PreLayoutManagement ();
532
}
533
534
long QuicklistView::PostLayoutManagement (long LayoutResult)
535
{
536
  long result = BaseWindow::PostLayoutManagement (LayoutResult);
613.1.9 by Jay Taoko
Quicklist Rendering code:
537
  
604.2.3 by Jay Taoko
* In progress: Quicklist
538
  UpdateTexture ();
539
540
  int x = _padding + _anchor_width + _corner_radius;
541
  int y = _padding + _corner_radius;
542
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
543
  std::list<QuicklistMenuItem*>::iterator it;
604.2.3 by Jay Taoko
* In progress: Quicklist
544
  for (it = _item_list.begin(); it != _item_list.end(); it++)
545
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
546
    if (!(*it)->GetVisible())
547
      continue;
548
604.2.3 by Jay Taoko
* In progress: Quicklist
549
    (*it)->SetBaseX (x);
550
    (*it)->SetBaseY (y);
551
552
    y += (*it)->GetBaseHeight ();
553
  }
554
605.1.1 by Jay Taoko
* Support for Quicklist
555
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
556
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
557
    if (!(*it)->GetVisible())
558
      continue;
559
605.1.1 by Jay Taoko
* Support for Quicklist
560
    (*it)->SetBaseX (x);
561
    (*it)->SetBaseY (y);
562
563
    y += (*it)->GetBaseHeight ();
564
  }
613.1.9 by Jay Taoko
Quicklist Rendering code:
565
566
  // We must correct the width of line separators. The rendering of the separator can be smaller than the width of the
567
  // quicklist. The reason for that is, the quicklist width is determined by the largest entry it contains. That size is 
568
  // only after MaxItemWidth is computed in QuicklistView::PreLayoutManagement.
613.1.15 by Jay Taoko
* Quicklist item rendering
569
  // The setting of the separator width is done here after the Layout cycle for this widget is over. The width of the separator 
613.1.9 by Jay Taoko
Quicklist Rendering code:
570
  // has bee set correctly during the layout cycle, but the cairo rendering still need to be adjusted.
571
  int separator_width = nux::Max<int>(_default_item_layout->GetBaseWidth (), _item_layout->GetBaseWidth ());
572
  
573
  for (it = _item_list.begin(); it != _item_list.end(); it++)
574
  {
613.1.15 by Jay Taoko
* Quicklist item rendering
575
    QuicklistMenuItem* item = (QuicklistMenuItem*) (*it);
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
576
    if (item->GetVisible() && item->CairoSurfaceWidth () != separator_width)
613.1.9 by Jay Taoko
Quicklist Rendering code:
577
    {
613.1.15 by Jay Taoko
* Quicklist item rendering
578
      // Compute textures of the item.
579
      item->UpdateTexture ();
613.1.9 by Jay Taoko
Quicklist Rendering code:
580
    }
581
  }
605.1.1 by Jay Taoko
* Support for Quicklist
582
  
613.1.15 by Jay Taoko
* Quicklist item rendering
583
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
584
  {
585
    QuicklistMenuItem* item = (QuicklistMenuItem*) (*it);
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
586
    if (item->GetVisible() && item->CairoSurfaceWidth () != separator_width)
613.1.15 by Jay Taoko
* Quicklist item rendering
587
    {
588
      // Compute textures of the item.
589
      item->UpdateTexture ();
590
    }
591
  }
592
604.2.3 by Jay Taoko
* In progress: Quicklist
593
  return result;
594
}
595
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
596
void QuicklistView::RecvCairoTextChanged (QuicklistMenuItem* cairo_text)
604.2.3 by Jay Taoko
* In progress: Quicklist
597
{
598
  _cairo_text_has_changed = true;
599
}
600
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
601
void QuicklistView::RecvCairoTextColorChanged (QuicklistMenuItem* cairo_text)
604.2.3 by Jay Taoko
* In progress: Quicklist
602
{
603
  NeedRedraw ();
604
}
605
641 by Jay Taoko
* Fix click event on menu item
606
void QuicklistView::RecvItemMouseClick (QuicklistMenuItem* item, int x, int y)
613.1.13 by Jay Taoko
* Connected events to items states
607
{
608
  _mouse_down = false;
609
  if (IsVisible ())
610
  {
641 by Jay Taoko
* Fix click event on menu item
611
    // Check if the mouse was released over an item and emit the signal
612
    CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ());
613
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
614
    Hide ();
613.1.13 by Jay Taoko
* Connected events to items states
615
  }
616
}
617
639.1.1 by Jay Taoko
* Improved mouse event handling
618
void QuicklistView::CheckAndEmitItemSignal (int x, int y)
641 by Jay Taoko
* Fix click event on menu item
619
{ 
639.1.1 by Jay Taoko
* Improved mouse event handling
620
  nux::Geometry geo;
621
  std::list<QuicklistMenuItem*>::iterator it;
622
  for (it = _item_list.begin(); it != _item_list.end(); it++)
623
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
624
    if (!(*it)->GetVisible())
625
      continue;
626
639.1.1 by Jay Taoko
* Improved mouse event handling
627
    geo = (*it)->GetGeometry ();
628
    geo.width = _item_layout->GetBaseWidth ();
629
    
630
    if (geo.IsPointInside (x, y))
631
    {
632
      // An action is performed: send the signal back to the application
639.2.8 by Jason Smith
merge trunk
633
      if ((*it)->_menuItem)
634
      {
635
        dbusmenu_menuitem_handle_event ((*it)->_menuItem, "clicked", NULL, 0);
636
      }
639.1.1 by Jay Taoko
* Improved mouse event handling
637
    }
638
  }
639
640
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
641
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
642
    if (!(*it)->GetVisible())
643
      continue;
644
639.1.1 by Jay Taoko
* Improved mouse event handling
645
    geo = (*it)->GetGeometry ();
646
    geo.width = _default_item_layout->GetBaseWidth ();
647
    
648
    if (geo.IsPointInside (x, y))
649
    {
650
      // An action is performed: send the signal back to the application
639.2.8 by Jason Smith
merge trunk
651
      if ((*it)->_menuItem)
652
      {
653
        dbusmenu_menuitem_handle_event ((*it)->_menuItem, "clicked", NULL, 0);
654
      }
639.1.1 by Jay Taoko
* Improved mouse event handling
655
    }
656
  } 
657
}
658
659
void QuicklistView::RecvItemMouseRelease (QuicklistMenuItem* item, int x, int y)
613.1.13 by Jay Taoko
* Connected events to items states
660
{
661
  _mouse_down = false;
639.1.1 by Jay Taoko
* Improved mouse event handling
662
  
663
  
613.1.13 by Jay Taoko
* Connected events to items states
664
  if (IsVisible ())
665
  {
639.1.1 by Jay Taoko
* Improved mouse event handling
666
    // Check if the mouse was released over an item and emit the signal
667
    CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ());
668
    
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
669
    Hide ();
613.1.13 by Jay Taoko
* Connected events to items states
670
  }  
671
}
672
639.1.1 by Jay Taoko
* Improved mouse event handling
673
void QuicklistView::CancelItemsPrelightStatus ()
674
{
675
  std::list<QuicklistMenuItem*>::iterator it;
676
  for (it = _item_list.begin(); it != _item_list.end(); it++)
677
  {
678
    (*it)->_prelight = false;
679
  }
680
681
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
682
  {
683
    (*it)->_prelight = false;
684
  }
685
}
686
687
void QuicklistView::RecvItemMouseDrag (QuicklistMenuItem* item, int x, int y)
688
{
689
  nux::Geometry geo;
690
  std::list<QuicklistMenuItem*>::iterator it;
691
  for (it = _item_list.begin(); it != _item_list.end(); it++)
692
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
693
    if (!(*it)->GetVisible())
694
      continue;
695
639.1.1 by Jay Taoko
* Improved mouse event handling
696
    geo = (*it)->GetGeometry ();
697
    geo.width = _item_layout->GetBaseWidth ();
698
    
699
    if (geo.IsPointInside (x + item->GetBaseX (), y + item->GetBaseY ()))
700
    {
701
      (*it)->_prelight = true;
702
    }
703
    else
704
    {
705
      (*it)->_prelight = false;
706
    }
707
  }
708
709
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
710
  {
743.2.1 by Michael Terry
keep track of visible state of quick list menu items
711
    if (!(*it)->GetVisible())
712
      continue;
713
639.1.1 by Jay Taoko
* Improved mouse event handling
714
    geo = (*it)->GetGeometry ();
715
    geo.width = _default_item_layout->GetBaseWidth ();
716
    
717
    if (geo.IsPointInside (x + item->GetBaseX (), y + item->GetBaseY ()))
718
    {
719
      (*it)->_prelight = true;
720
    }
721
    else
722
    {
723
      (*it)->_prelight = false;
724
    }
725
  }
726
  
727
  NeedRedraw ();
728
}
729
613.1.13 by Jay Taoko
* Connected events to items states
730
void QuicklistView::RecvItemMouseEnter (QuicklistMenuItem* item)
731
{
732
  NeedRedraw ();
733
}
734
735
void QuicklistView::RecvItemMouseLeave (QuicklistMenuItem* item)
736
{
737
  NeedRedraw ();
738
}
739
604.2.3 by Jay Taoko
* In progress: Quicklist
740
void QuicklistView::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags)
741
{
742
//     if (IsVisible ())
572.8.1 by Jay Taoko
In progres: quicklist
743
//     {
604.2.3 by Jay Taoko
* In progress: Quicklist
744
//       CaptureMouseDownAnyWhereElse (false);
745
//       ForceStopFocus (1, 1);
746
//       UnGrabPointer ();
747
//       EnableInputWindow (false);
748
//       ShowWindow (false);
572.8.1 by Jay Taoko
In progres: quicklist
749
//     }
604.2.3 by Jay Taoko
* In progress: Quicklist
750
}
751
752
void QuicklistView::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags)
753
{
639.1.1 by Jay Taoko
* Improved mouse event handling
754
    // Check if the mouse was released over an item and emit the signal
755
    CheckAndEmitItemSignal (x, y);
604.2.3 by Jay Taoko
* In progress: Quicklist
756
}
757
758
void QuicklistView::RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags)
759
{
760
  if (IsVisible ())
761
  {
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
762
    Hide ();
604.2.3 by Jay Taoko
* In progress: Quicklist
763
  }
764
}
765
766
void QuicklistView::RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
767
{
613.1.15 by Jay Taoko
* Quicklist item rendering
768
604.2.3 by Jay Taoko
* In progress: Quicklist
769
}
770
771
void QuicklistView::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
772
{
613.1.15 by Jay Taoko
* Quicklist item rendering
773
604.2.3 by Jay Taoko
* In progress: Quicklist
774
}
775
  
776
void QuicklistView::RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long button_flags, unsigned long key_flags)
777
{
679.4.2 by Jamal Fanaian
QuicklistManager now listens for show/hide signals from QuicklistView. Created Hide and Show methods in QuicklistView.
778
  Hide ();
604.2.3 by Jay Taoko
* In progress: Quicklist
779
}
780
605.1.1 by Jay Taoko
* Support for Quicklist
781
void QuicklistView::RemoveAllMenuItem ()
782
{
639.2.7 by Jason Smith
some memory work
783
  std::list<QuicklistMenuItem*>::iterator it;
784
  for (it = _item_list.begin(); it != _item_list.end(); it++)
785
  {
648.3.1 by Jay Taoko
* In progress: introspection
786
    // Remove from introspection
787
    RemoveChild (*it);
639.2.7 by Jason Smith
some memory work
788
    (*it)->UnReference();
789
  }
790
  
791
  for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
792
  {
648.3.1 by Jay Taoko
* In progress: introspection
793
    // Remove from introspection
794
    RemoveChild (*it);
639.2.7 by Jason Smith
some memory work
795
    (*it)->UnReference();
796
  }
797
  
605.1.1 by Jay Taoko
* Support for Quicklist
798
  _item_list.clear ();
613.1.8 by Jay Taoko
* YOU NEED TO UPDATE NUX
799
  _default_item_list.clear ();
800
  
605.1.1 by Jay Taoko
* Support for Quicklist
801
  _item_layout->Clear ();
613.1.8 by Jay Taoko
* YOU NEED TO UPDATE NUX
802
  _default_item_layout->Clear ();
605.1.1 by Jay Taoko
* Support for Quicklist
803
  _cairo_text_has_changed = true;
804
  nux::GetGraphicsThread ()->AddObjectToRefreshList (this);
805
}
806
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
807
void QuicklistView::AddMenuItem (QuicklistMenuItem* item)
808
{
613.1.15 by Jay Taoko
* Quicklist item rendering
809
  if (item == 0)
810
    return;
811
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
812
  item->sigTextChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextChanged));
813
  item->sigColorChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextColorChanged));
613.1.13 by Jay Taoko
* Connected events to items states
814
  item->sigMouseClick.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseClick));
815
  item->sigMouseReleased.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseRelease));
816
  item->sigMouseEnter.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseEnter));
817
  item->sigMouseLeave.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseLeave));
639.1.1 by Jay Taoko
* Improved mouse event handling
818
  item->sigMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseDrag));
613.1.15 by Jay Taoko
* Quicklist item rendering
819
   
613.1.4 by Jay Taoko
* Using QuicklistMenuItemLabel instead of StaticCairoText in Quicklistview
820
  _item_list.push_back (item);
821
  item->Reference();
648.3.1 by Jay Taoko
* In progress: introspection
822
  // Add to introspection
823
  AddChild (item);
605.1.1 by Jay Taoko
* Support for Quicklist
824
  
825
  _cairo_text_has_changed = true;
826
  nux::GetGraphicsThread ()->AddObjectToRefreshList (this);
827
  NeedRedraw ();
604.2.3 by Jay Taoko
* In progress: Quicklist
828
}
829
830
void QuicklistView::RenderQuicklistView ()
831
{
832
  
833
}
613.1.1 by Jay Taoko
* Merged Mirco's QuicklistMenuItem work with trunk.
834
835
int QuicklistView::GetNumItems ()
836
{
837
  return _item_list.size () + _default_item_list.size ();
838
}
839
840
QuicklistMenuItem* QuicklistView::GetNthItems (int index)
841
{
613.1.5 by Jay Taoko
* QuicklistView test
842
  if (index < (int)_item_list.size ())
843
  {
844
    int i = 0;
845
    std::list<QuicklistMenuItem*>::iterator it;
846
    for (i = 0, it = _item_list.begin(); it != _item_list.end(); i++, it++)
847
    {
848
      if (i == index)
849
        return *it;
850
    }
851
  }
852
853
  if (index < (int)_item_list.size () + (int)_default_item_list.size ())
854
  {
855
    int i = 0;
856
    if (_item_list.size () > 0)
857
      i = _item_list.size () -1;
858
    std::list<QuicklistMenuItem*>::iterator it;
859
    for (it = _item_list.begin(); it != _item_list.end(); i++, it++)
860
    {
861
      if (i == index)
862
        return *it;
863
    }
864
  }
865
613.1.1 by Jay Taoko
* Merged Mirco's QuicklistMenuItem work with trunk.
866
  return 0;
867
}
868
613.1.5 by Jay Taoko
* QuicklistView test
869
QuicklistMenuItemType QuicklistView::GetNthType  (int index)
613.1.1 by Jay Taoko
* Merged Mirco's QuicklistMenuItem work with trunk.
870
{
613.1.5 by Jay Taoko
* QuicklistView test
871
  QuicklistMenuItem* item = GetNthItems (index);
872
  if (item)
873
    return item->GetItemType ();
874
  return MENUITEM_TYPE_UNKNOWN;
613.1.1 by Jay Taoko
* Merged Mirco's QuicklistMenuItem work with trunk.
875
}
876
877
std::list<QuicklistMenuItem*> QuicklistView::GetChildren ()
878
{
879
  std::list<QuicklistMenuItem*> l;
880
  return l;
881
}
882
854.3.3 by Mirco Müller
Removed debugging output, got rid of FocusIn/Out callbacks, hooked up ql-key-nav with real functionality, switching from ql-key-nav back to launcher-key-nav still failing, disabled menu-items in ql are not dealt with atm for ql-key-nav
883
void QuicklistView::DefaultToFirstItem ()
884
{
885
  if (GetNumItems () >= 1)
886
  {
887
    GetNthItems (0)->_prelight= true;
888
    QueueDraw ();
889
  }
890
}
891
604.2.3 by Jay Taoko
* In progress: Quicklist
892
static inline void ql_blurinner (guchar* pixel,
893
  gint   *zR,
894
  gint   *zG,
895
  gint   *zB,
896
  gint   *zA,
897
  gint    alpha,
898
  gint    aprec,
899
  gint    zprec)
900
{
901
  gint R;
902
  gint G;
903
  gint B;
904
  guchar A;
905
906
  R = *pixel;
907
  G = *(pixel + 1);
908
  B = *(pixel + 2);
909
  A = *(pixel + 3);
910
911
  *zR += (alpha * ((R << zprec) - *zR)) >> aprec;
912
  *zG += (alpha * ((G << zprec) - *zG)) >> aprec;
913
  *zB += (alpha * ((B << zprec) - *zB)) >> aprec;
914
  *zA += (alpha * ((A << zprec) - *zA)) >> aprec;
915
916
  *pixel       = *zR >> zprec;
917
  *(pixel + 1) = *zG >> zprec;
918
  *(pixel + 2) = *zB >> zprec;
919
  *(pixel + 3) = *zA >> zprec;
920
}
921
922
static inline void ql_blurrow (guchar* pixels,
923
  gint    width,
924
  gint    height,
925
  gint    channels,
926
  gint    line,
927
  gint    alpha,
928
  gint    aprec,
929
  gint    zprec)
930
{
931
  gint    zR;
932
  gint    zG;
933
  gint    zB;
934
  gint    zA;
935
  gint    index;
936
  guchar* scanline;
937
938
  scanline = &(pixels[line * width * channels]);
939
940
  zR = *scanline << zprec;
941
  zG = *(scanline + 1) << zprec;
942
  zB = *(scanline + 2) << zprec;
943
  zA = *(scanline + 3) << zprec;
944
945
  for (index = 0; index < width; index ++)
946
    ql_blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec,
947
    zprec);
948
949
  for (index = width - 2; index >= 0; index--)
950
    ql_blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec,
951
    zprec);
952
}
953
954
static inline void ql_blurcol (guchar* pixels,
955
  gint    width,
956
  gint    height,
957
  gint    channels,
958
  gint    x,
959
  gint    alpha,
960
  gint    aprec,
961
  gint    zprec)
962
{
963
  gint zR;
964
  gint zG;
965
  gint zB;
966
  gint zA;
967
  gint index;
968
  guchar* ptr;
969
970
  ptr = pixels;
971
972
  ptr += x * channels;
973
974
  zR = *((guchar*) ptr    ) << zprec;
975
  zG = *((guchar*) ptr + 1) << zprec;
976
  zB = *((guchar*) ptr + 2) << zprec;
977
  zA = *((guchar*) ptr + 3) << zprec;
978
979
  for (index = width; index < (height - 1) * width; index += width)
980
    ql_blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha,
981
    aprec, zprec);
982
983
  for (index = (height - 2) * width; index >= 0; index -= width)
984
    ql_blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha,
985
    aprec, zprec);
986
}
987
988
//
989
// pixels   image-data
990
// width    image-width
991
// height   image-height
992
// channels image-channels
993
//
994
// in-place blur of image 'img' with kernel of approximate radius 'radius'
995
//
996
// blurs with two sided exponential impulse response
997
//
998
// aprec = precision of alpha parameter in fixed-point format 0.aprec
999
//
1000
// zprec = precision of state parameters zR,zG,zB and zA in fp format 8.zprec
1001
//
1002
void ql_expblur (guchar* pixels,
1003
  gint    width,
1004
  gint    height,
1005
  gint    channels,
1006
  gint    radius,
1007
  gint    aprec,
1008
  gint    zprec)
1009
{
1010
  gint alpha;
1011
  gint row = 0;
1012
  gint col = 0;
1013
1014
  if (radius < 1)
572.4.1 by Jay Taoko
* Added StaticCairoText files
1015
    return;
604.2.3 by Jay Taoko
* In progress: Quicklist
1016
1017
  // calculate the alpha such that 90% of 
1018
  // the kernel is within the radius.
1019
  // (Kernel extends to infinity)
1020
  alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f))));
1021
1022
  for (; row < height; row++)
1023
    ql_blurrow (pixels, width, height, channels, row, alpha, aprec, zprec);
1024
1025
  for(; col < width; col++)
1026
    ql_blurcol (pixels, width, height, channels, col, alpha, aprec, zprec);
1027
1028
  return;
1029
}
572.4.1 by Jay Taoko
* Added StaticCairoText files
1030
1031
/**
604.2.3 by Jay Taoko
* In progress: Quicklist
1032
* ctk_surface_blur:
1033
* @surface: pointer to a cairo image-surface
1034
* @radius: unsigned integer acting as the blur-radius to apply
1035
*
1036
* Applies an exponential blur on the passed surface executed on the CPU. Not as
1037
* nice as a real gaussian blur, but much faster.
1038
**/
572.4.1 by Jay Taoko
* Added StaticCairoText files
1039
void ql_surface_blur (cairo_surface_t* surface,
604.2.3 by Jay Taoko
* In progress: Quicklist
1040
                guint            radius)
1041
{
1042
guchar*        pixels;
1043
guint          width;
1044
guint          height;
1045
cairo_format_t format;
1046
1047
// before we mess with the surface execute any pending drawing
1048
cairo_surface_flush (surface);
1049
1050
pixels = cairo_image_surface_get_data (surface);
1051
width  = cairo_image_surface_get_width (surface);
1052
height = cairo_image_surface_get_height (surface);
1053
format = cairo_image_surface_get_format (surface);
1054
1055
switch (format)
1056
{
1057
  case CAIRO_FORMAT_ARGB32:
1058
    ql_expblur (pixels, width, height, 4, radius, 16, 7);
1059
  break;
1060
1061
  case CAIRO_FORMAT_RGB24:
1062
    ql_expblur (pixels, width, height, 3, radius, 16, 7);
1063
  break;
1064
1065
  case CAIRO_FORMAT_A8:
1066
    ql_expblur (pixels, width, height, 1, radius, 16, 7);
1067
  break;
1068
1069
  default :
1070
    // do nothing
1071
  break;
1072
}
1073
1074
// inform cairo we altered the surfaces contents
1075
cairo_surface_mark_dirty (surface);	
1076
}
1077
1078
  
1079
void ql_tint_dot_hl (cairo_t* cr,
1080
  gint    width,
1081
  gint    height,
1082
  gfloat  hl_x,
1083
  gfloat  hl_y,
1084
  gfloat  hl_size,
1085
  gfloat* rgba_tint,
1086
  gfloat* rgba_hl,
1087
  gfloat* rgba_dot)
1088
{
1089
  cairo_surface_t* dots_surf    = NULL;
1090
  cairo_t*         dots_cr      = NULL;
1091
  cairo_pattern_t* dots_pattern = NULL;
1092
  cairo_pattern_t* hl_pattern   = NULL;
1093
1094
  // create context for dot-pattern
1095
  dots_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4, 4);
1096
  dots_cr = cairo_create (dots_surf);
1097
1098
  // clear normal context
1099
  cairo_scale (cr, 1.0f, 1.0f);
1100
  cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
1101
  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
1102
  cairo_paint (cr);
1103
1104
  // prepare drawing for normal context
1105
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1106
1107
  // create path in normal context
1108
  cairo_rectangle (cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height);  
1109
1110
  // fill path of normal context with tint
1111
  cairo_set_source_rgba (cr,
1112
    rgba_tint[0],
1113
    rgba_tint[1],
1114
    rgba_tint[2],
1115
    rgba_tint[3]);
1116
  cairo_fill_preserve (cr);
1117
1118
  // create pattern in dot-context
1119
  cairo_set_operator (dots_cr, CAIRO_OPERATOR_CLEAR);
1120
  cairo_paint (dots_cr);
1121
  cairo_scale (dots_cr, 1.0f, 1.0f);
1122
  cairo_set_operator (dots_cr, CAIRO_OPERATOR_OVER);
1123
  cairo_set_source_rgba (dots_cr,
1124
    rgba_dot[0],
1125
    rgba_dot[1],
1126
    rgba_dot[2],
1127
    rgba_dot[3]);
1128
  cairo_rectangle (dots_cr, 0.0f, 0.0f, 1.0f, 1.0f);
1129
  cairo_fill (dots_cr);
1130
  cairo_rectangle (dots_cr, 2.0f, 2.0f, 1.0f, 1.0f);
1131
  cairo_fill (dots_cr);
1132
  dots_pattern = cairo_pattern_create_for_surface (dots_surf);
1133
1134
  // fill path of normal context with dot-pattern
1135
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1136
  cairo_set_source (cr, dots_pattern);
1137
  cairo_pattern_set_extend (dots_pattern, CAIRO_EXTEND_REPEAT);
1138
  cairo_fill_preserve (cr);
1139
  cairo_pattern_destroy (dots_pattern);
1140
  cairo_surface_destroy (dots_surf);
1141
  cairo_destroy (dots_cr);
1142
1143
  // draw highlight
1144
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
1145
  hl_pattern = cairo_pattern_create_radial (hl_x,
1146
    hl_y,
1147
    0.0f,
1148
    hl_x,
1149
    hl_y,
1150
    hl_size);
1151
  cairo_pattern_add_color_stop_rgba (hl_pattern,
1152
    0.0f,
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1153
    rgba_hl[0],
1154
    rgba_hl[1],
1155
    rgba_hl[2],
1156
    rgba_hl[3]);
604.2.3 by Jay Taoko
* In progress: Quicklist
1157
  cairo_pattern_add_color_stop_rgba (hl_pattern, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f);
1158
  cairo_set_source (cr, hl_pattern);
1159
  cairo_fill (cr);
1160
  cairo_pattern_destroy (hl_pattern);
1161
}
1162
1163
void ql_setup (cairo_surface_t** surf,
1164
  cairo_t**         cr,
1165
  gboolean          outline,
1166
  gint              width,
1167
  gint              height,
1168
  gboolean          negative)
1169
{
572.4.1 by Jay Taoko
* Added StaticCairoText files
1170
//     // create context
1171
//     if (outline)
1172
//       *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
1173
//     else
1174
//       *surf = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
1175
//     *cr = cairo_create (*surf);
1176
604.2.3 by Jay Taoko
* In progress: Quicklist
1177
  // clear context
1178
  cairo_scale (*cr, 1.0f, 1.0f);
1179
  if (outline)
1180
  {
1181
    cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
1182
    cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR);
1183
  }  
1184
  else
1185
  {
1186
    cairo_set_operator (*cr, CAIRO_OPERATOR_OVER);
1187
    if (negative)
572.4.1 by Jay Taoko
* Added StaticCairoText files
1188
      cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
604.2.3 by Jay Taoko
* In progress: Quicklist
1189
    else
1190
      cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
1191
  }
1192
  cairo_paint (*cr);
1193
}
1194
1195
void ql_compute_full_mask_path (cairo_t* cr,
1196
  gfloat   anchor_width,
1197
  gfloat   anchor_height,
1198
  gint     width,
1199
  gint     height,
1200
  gint     upper_size,
1201
  gfloat   radius,
1202
  guint    pad)
1203
{
1204
  //     0  1        2  3
1205
  //     +--+--------+--+
1206
  //     |              |
1207
  //     + 14           + 4
1208
  //     |              |
1209
  //     |              |
1210
  //     |              |
1211
  //     + 13           |
1212
  //    /               |
1213
  //   /                |
1214
  //  + 12              |
1215
  //   \                |
1216
  //    \               |
1217
  //  11 +              |
1218
  //     |              |
1219
  //     |              |
1220
  //     |              |
1221
  //  10 +              + 5
1222
  //     |              |
1223
  //     +--+--------+--+ 6
1224
  //     9  8        7
1225
1226
1227
  gfloat padding  = pad;
1228
  int ZEROPOINT5 = 0.0f;
1229
1230
  gfloat HeightToAnchor = 0.0f;
1231
  HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
1232
  if (HeightToAnchor < 0.0f)
1233
  {
1234
    g_warning ("Anchor-height and corner-radius a higher than whole texture!");
1235
    return;
1236
  }
1237
1238
  //gint dynamic_size = height - 2*radius - 2*padding - anchor_height;
1239
  //gint upper_dynamic_size = upper_size;
1240
  //gint lower_dynamic_size = dynamic_size - upper_dynamic_size;
1241
1242
  if(upper_size >= 0)
1243
  {
1244
    if(upper_size > height - 2.0f * radius - anchor_height -2 * padding)
1245
    {
1246
      //g_warning ("[_compute_full_mask_path] incorrect upper_size value");
1247
      HeightToAnchor = 0;
1248
    }
1249
    else
1250
    {
1251
      HeightToAnchor = height - 2.0f * radius - anchor_height -2 * padding - upper_size;
1252
    }
1253
  }
1254
  else
1255
  {
1256
    HeightToAnchor = (height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
1257
  }
1258
1259
  cairo_translate (cr, -0.5f, -0.5f);
1260
1261
  // create path
1262
  cairo_move_to (cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5); // Point 1
1263
  cairo_line_to (cr, width - padding - radius, padding + ZEROPOINT5);   // Point 2
1264
  cairo_arc (cr,
1265
    width  - padding - radius + ZEROPOINT5,
1266
    padding + radius + ZEROPOINT5,
1267
    radius,
1268
    -90.0f * G_PI / 180.0f,
1269
    0.0f * G_PI / 180.0f);   // Point 4
1270
  cairo_line_to (cr,
1271
    (gdouble) width - padding + ZEROPOINT5,
1272
    (gdouble) height - radius - padding + ZEROPOINT5); // Point 5
1273
  cairo_arc (cr,
1274
    (gdouble) width - padding - radius + ZEROPOINT5,
1275
    (gdouble) height - padding - radius + ZEROPOINT5,
1276
    radius,
1277
    0.0f * G_PI / 180.0f,
1278
    90.0f * G_PI / 180.0f);  // Point 7
1279
  cairo_line_to (cr,
1280
    anchor_width + padding + radius + ZEROPOINT5,
1281
    (gdouble) height - padding + ZEROPOINT5); // Point 8
1282
1283
  cairo_arc (cr,
1284
    anchor_width + padding + radius + ZEROPOINT5,
1285
    (gdouble) height - padding - radius,
1286
    radius,
1287
    90.0f * G_PI / 180.0f,
1288
    180.0f * G_PI / 180.0f); // Point 10
1289
1290
  cairo_line_to (cr,
1291
    padding + anchor_width + ZEROPOINT5,
1292
    (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5 );  // Point 11
1293
  cairo_line_to (cr,
1294
    padding + ZEROPOINT5,
1295
    (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12
1296
  cairo_line_to (cr,
1297
    padding + anchor_width + ZEROPOINT5,
1298
    (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5);  // Point 13
1299
1300
  cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, padding + radius  + ZEROPOINT5);  // Point 14
1301
  cairo_arc (cr,
1302
    padding + anchor_width + radius + ZEROPOINT5,
1303
    padding + radius + ZEROPOINT5,
1304
    radius,
1305
    180.0f * G_PI / 180.0f,
1306
    270.0f * G_PI / 180.0f);
1307
1308
  cairo_close_path (cr);
1309
}
1310
1311
void ql_compute_mask (cairo_t* cr)
1312
{
1313
  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
1314
  cairo_fill_preserve (cr);
1315
}
1316
1317
void ql_compute_outline (cairo_t* cr,
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1318
                         gfloat   line_width,
1319
                         gfloat*  rgba_line,
1320
                         gfloat   size)
604.2.3 by Jay Taoko
* In progress: Quicklist
1321
{
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1322
  cairo_pattern_t* pattern = NULL;
1323
  float            x       = 0.0f;
1324
  float            y       = 0.0f;
636.6.4 by Mirco Müller
make outline-gradient correctly adapt to width of quicklist, don't call FillInDefaultItems()
1325
  float            offset  = 2.5f * ANCHOR_WIDTH / size;
1326
604.2.3 by Jay Taoko
* In progress: Quicklist
1327
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1328
1329
  pattern = cairo_pattern_create_linear (x, y, size, y);
1330
  cairo_pattern_add_color_stop_rgba (pattern, 0.0f,
1331
    rgba_line[0],
1332
    rgba_line[1],
1333
    rgba_line[2],
1334
    rgba_line[3]);
636.6.4 by Mirco Müller
make outline-gradient correctly adapt to width of quicklist, don't call FillInDefaultItems()
1335
  cairo_pattern_add_color_stop_rgba (pattern, offset,
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1336
    rgba_line[0],
1337
    rgba_line[1],
1338
    rgba_line[2],
1339
    rgba_line[3]);
636.6.4 by Mirco Müller
make outline-gradient correctly adapt to width of quicklist, don't call FillInDefaultItems()
1340
  cairo_pattern_add_color_stop_rgba (pattern, 1.1f * offset,
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1341
    rgba_line[0] * 0.65f,
1342
    rgba_line[1] * 0.65f,
1343
    rgba_line[2] * 0.65f,
1344
    rgba_line[3]);
1345
  cairo_pattern_add_color_stop_rgba (pattern, 1.0f,
1346
    rgba_line[0] * 0.65f,
1347
    rgba_line[1] * 0.65f,
1348
    rgba_line[2] * 0.65f,
1349
    rgba_line[3]);
1350
  cairo_set_source (cr, pattern);
604.2.3 by Jay Taoko
* In progress: Quicklist
1351
  cairo_set_line_width (cr, line_width);
1352
  cairo_stroke (cr);
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1353
  cairo_pattern_destroy (pattern);
604.2.3 by Jay Taoko
* In progress: Quicklist
1354
}
1355
1356
void ql_draw (cairo_t* cr,
1357
  gboolean outline,
1358
  gfloat   line_width,
1359
  gfloat*  rgba,
1360
  gboolean negative,
1361
  gboolean stroke)
1362
{
1363
  // prepare drawing
1364
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
1365
1366
  // actually draw the mask
1367
  if (outline)
1368
  {
572.4.1 by Jay Taoko
* Added StaticCairoText files
1369
    cairo_set_line_width (cr, line_width);
604.2.3 by Jay Taoko
* In progress: Quicklist
1370
    cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
1371
  }
1372
  else
1373
  {
1374
    if (negative)
1375
      cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
1376
    else
1377
      cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
1378
  }
1379
1380
  // stroke or fill?
1381
  if (stroke)
1382
    cairo_stroke_preserve (cr);
1383
  else
1384
    cairo_fill_preserve (cr);
1385
}
1386
1387
void ql_finalize (cairo_t** cr,
1388
  gboolean  outline,
1389
  gfloat    line_width,
1390
  gfloat*   rgba,
1391
  gboolean  negative,
1392
  gboolean  stroke)
1393
{
1394
  // prepare drawing
1395
  cairo_set_operator (*cr, CAIRO_OPERATOR_SOURCE);
1396
1397
  // actually draw the mask
1398
  if (outline)
1399
  {
1400
    cairo_set_line_width (*cr, line_width);
1401
    cairo_set_source_rgba (*cr, rgba[0], rgba[1], rgba[2], rgba[3]);
1402
  }
1403
  else
1404
  {
1405
    if (negative)
1406
      cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
1407
    else
1408
      cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
1409
  }
1410
1411
  // stroke or fill?
1412
  if (stroke)
1413
    cairo_stroke (*cr);
1414
  else
1415
    cairo_fill (*cr);
1416
}
1417
1418
void
1419
  ql_compute_full_outline_shadow (
1420
  cairo_t* cr,
1421
  cairo_surface_t* surf,
1422
  gint    width,
1423
  gint    height,
1424
  gfloat  anchor_width,
1425
  gfloat  anchor_height,
1426
  gint    upper_size,
1427
  gfloat  corner_radius,
1428
  guint   blur_coeff,
1429
  gfloat* rgba_shadow,
1430
  gfloat  line_width,
1431
  gint    padding_size,
1432
  gfloat* rgba_line)
1433
{
1434
  ql_setup (&surf, &cr, TRUE, width, height, FALSE);
1435
  ql_compute_full_mask_path (cr,
1436
    anchor_width,
1437
    anchor_height,
1438
    width,
1439
    height,
1440
    upper_size,
1441
    corner_radius,
1442
    padding_size);
1443
1444
  ql_draw (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
1445
  ql_surface_blur (surf, blur_coeff);
1446
  ql_compute_mask (cr);
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1447
  ql_compute_outline (cr, line_width, rgba_line, width);
604.2.3 by Jay Taoko
* In progress: Quicklist
1448
}
1449
1450
void ql_compute_full_mask (
1451
  cairo_t* cr,
1452
  cairo_surface_t* surf,
1453
  gint     width,
1454
  gint     height,
1455
  gfloat   radius,
1456
  guint    shadow_radius,
1457
  gfloat   anchor_width,
1458
  gfloat   anchor_height,
1459
  gint     upper_size,
1460
  gboolean negative,
1461
  gboolean outline,
1462
  gfloat   line_width,
1463
  gint     padding_size,
1464
  gfloat*  rgba)
1465
{
1466
  ql_setup (&surf, &cr, outline, width, height, negative);
1467
  ql_compute_full_mask_path (cr,
1468
    anchor_width,
1469
    anchor_height,
1470
    width,
1471
    height,
1472
    upper_size,
1473
    radius,
1474
    padding_size);
1475
  ql_finalize (&cr, outline, line_width, rgba, negative, outline);
1476
}
1477
1478
void QuicklistView::UpdateTexture ()
1479
{
1480
  if (_cairo_text_has_changed == false)
1481
    return;
1482
743.1.1 by macslow at bangang
Avoid Quicklists being positioned so that they are partially offscreen at the bottom screen-edge. Fixes LP: #691114
1483
  int size_above_anchor = -1; // equal to size below
648.5.8 by Mirco Müller
use separate thread to inject fake events (mouse-clicks) into event-loop
1484
1485
  if (!_enable_quicklist_for_testing)
1486
  {
1487
    if ((_item_list.size () != 0) || (_default_item_list.size () != 0))
1488
    {
743.1.1 by macslow at bangang
Avoid Quicklists being positioned so that they are partially offscreen at the bottom screen-edge. Fixes LP: #691114
1489
      int offscreen_size = GetBaseY () +
1490
                           GetBaseHeight () -
1491
                           nux::GetWindow().GetWindowHeight ();
1492
1493
      if (offscreen_size > 0)
1494
        _top_size = offscreen_size;
1495
      else
1496
        _top_size = 4;
1497
648.5.8 by Mirco Müller
use separate thread to inject fake events (mouse-clicks) into event-loop
1498
      size_above_anchor = _top_size;
1499
      int x = _anchorX - _padding;
1500
      int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding;
1501
1502
      SetBaseX (x);
1503
      SetBaseY (y);
1504
    }
1505
    else
1506
    {
1507
      _top_size = 0;
1508
      size_above_anchor = -1;
1509
      int x = _anchorX - _padding;
1510
      int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding;
1511
1512
      SetBaseX (x);
1513
      SetBaseY (y);    
1514
    }
605.1.1 by Jay Taoko
* Support for Quicklist
1515
  }
1516
  
604.2.3 by Jay Taoko
* In progress: Quicklist
1517
  float blur_coef         = 6.0f;
1518
1519
  nux::CairoGraphics* cairo_bg       = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
1520
  nux::CairoGraphics* cairo_mask     = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
1521
  nux::CairoGraphics* cairo_outline  = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
1522
1523
  cairo_t *cr_bg      = cairo_bg->GetContext ();
1524
  cairo_t *cr_mask    = cairo_mask->GetContext ();
1525
  cairo_t *cr_outline = cairo_outline->GetContext ();
1526
1527
  float   tint_color[4]    = {0.0f, 0.0f, 0.0f, 0.80f};
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1528
  float   hl_color[4]      = {1.0f, 1.0f, 1.0f, 0.65f};
1529
  float   dot_color[4]     = {1.0f, 1.0f, 1.0f, 0.10f};
604.2.3 by Jay Taoko
* In progress: Quicklist
1530
  float   shadow_color[4]  = {0.0f, 0.0f, 0.0f, 1.00f};
636.6.3 by Mirco Müller
fix the padding and intensity of the separator, fix the gradient on the outline
1531
  float   outline_color[4] = {1.0f, 1.0f, 1.0f, 0.65f};
604.2.3 by Jay Taoko
* In progress: Quicklist
1532
  float   mask_color[4]    = {1.0f, 1.0f, 1.0f, 1.00f};
605.1.1 by Jay Taoko
* Support for Quicklist
1533
//   float   anchor_width      = 10;
1534
//   float   anchor_height     = 18;
604.2.3 by Jay Taoko
* In progress: Quicklist
1535
1536
  ql_tint_dot_hl (cr_bg,
1537
    GetBaseWidth (),
1538
    GetBaseHeight (),
1539
    GetBaseWidth () / 2.0f,
1540
    0,
1541
    nux::Max<float>(GetBaseWidth () / 1.3f, GetBaseHeight () / 1.3f),
1542
    tint_color,
1543
    hl_color,
1544
    dot_color);
1545
1546
  ql_compute_full_outline_shadow
1547
    (
1548
    cr_outline,
1549
    cairo_outline->GetSurface(),
1550
    GetBaseWidth (),
1551
    GetBaseHeight (),
605.1.1 by Jay Taoko
* Support for Quicklist
1552
    _anchor_width,
1553
    _anchor_height,
1554
    size_above_anchor,
604.2.3 by Jay Taoko
* In progress: Quicklist
1555
    _corner_radius,
1556
    blur_coef,
1557
    shadow_color,
1558
    1.0f,
1559
    _padding,
1560
    outline_color);
1561
1562
  ql_compute_full_mask (
1563
    cr_mask,
1564
    cairo_mask->GetSurface(),
1565
    GetBaseWidth (),
1566
    GetBaseHeight(),
1567
    _corner_radius,  // radius,
1568
    16,             // shadow_radius,
605.1.1 by Jay Taoko
* Support for Quicklist
1569
    _anchor_width,   // anchor_width,
1570
    _anchor_height,  // anchor_height,
1571
    size_above_anchor,             // upper_size,
604.2.3 by Jay Taoko
* In progress: Quicklist
1572
    true,           // negative,
1573
    false,          // outline,
1574
    1.0,            // line_width,
1575
    _padding,        // padding_size,
1576
    mask_color);
1577
1578
  cairo_destroy (cr_bg);
1579
  cairo_destroy (cr_outline);
1580
  cairo_destroy (cr_mask);
1581
1582
  nux::NBitmapData* bitmap = cairo_bg->GetBitmap();
1583
1584
  if (_texture_bg)
1585
    _texture_bg->UnReference ();
1586
  _texture_bg = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
1587
  _texture_bg->Update(bitmap);
1588
  delete bitmap;
1589
1590
  bitmap = cairo_mask->GetBitmap();
1591
  if (_texture_mask)
1592
    _texture_mask->UnReference ();
1593
  _texture_mask = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
1594
  _texture_mask->Update(bitmap);
1595
  delete bitmap;
1596
1597
  bitmap = cairo_outline->GetBitmap();
1598
  if (_texture_outline)
1599
    _texture_outline->UnReference ();
1600
  _texture_outline = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
1601
  _texture_outline->Update(bitmap);
1602
  delete bitmap;
1603
1604
  delete cairo_bg;
1605
  delete cairo_mask;
1606
  delete cairo_outline;
1607
  _cairo_text_has_changed = false;
605.1.1 by Jay Taoko
* Support for Quicklist
1608
  
1609
  // Request a redraw, so this area will be added to Compiz list of dirty areas.
1610
  NeedRedraw ();
604.2.3 by Jay Taoko
* In progress: Quicklist
1611
}
1612
1613
void QuicklistView::PositionChildLayout (float offsetX, float offsetY)
1614
{
1615
}
1616
1617
void QuicklistView::LayoutWindowElements ()
1618
{
1619
}
1620
1621
void QuicklistView::NotifyConfigurationChange (int width, int height)
1622
{
1623
}
1624
1625
void QuicklistView::SetText (nux::NString text)
1626
{
1627
  if (_labelText == text)
1628
    return;
1629
1630
  _labelText = text;
1631
  UpdateTexture ();
1632
}
613.1.5 by Jay Taoko
* QuicklistView test
1633
1634
void QuicklistView::TestMenuItems (DbusmenuMenuitem* root)
1635
{
613.1.8 by Jay Taoko
* YOU NEED TO UPDATE NUX
1636
  RemoveAllMenuItem ();
1637
  
613.1.5 by Jay Taoko
* QuicklistView test
1638
  if (root == 0)
1639
    return;
1640
  
1641
  GList * child = NULL;
1642
  for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child))
1643
  {
1644
    const gchar* type = dbusmenu_menuitem_property_get ((DbusmenuMenuitem*)child->data, DBUSMENU_MENUITEM_PROP_TYPE);
613.1.17 by Jay Taoko
* Corrected issues resulting from code review
1645
    const gchar* toggle_type = dbusmenu_menuitem_property_get ((DbusmenuMenuitem*)child->data, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE);
1646
    
613.1.9 by Jay Taoko
Quicklist Rendering code:
1647
    if (g_strcmp0 (type, DBUSMENU_CLIENT_TYPES_SEPARATOR) == 0)
613.1.5 by Jay Taoko
* QuicklistView test
1648
    {
1649
      QuicklistMenuItemSeparator* item = new QuicklistMenuItemSeparator ((DbusmenuMenuitem*)child->data, NUX_TRACKER_LOCATION);
1650
      AddMenuItem (item);
1651
    }
613.1.17 by Jay Taoko
* Corrected issues resulting from code review
1652
    else if (g_strcmp0 (toggle_type, DBUSMENU_MENUITEM_TOGGLE_CHECK) == 0)    
1653
    {
1654
      QuicklistMenuItemCheckmark* item = new QuicklistMenuItemCheckmark ((DbusmenuMenuitem*)child->data, NUX_TRACKER_LOCATION);
1655
      AddMenuItem (item);
1656
    }
1657
    else if (g_strcmp0 (toggle_type, DBUSMENU_MENUITEM_TOGGLE_RADIO) == 0)    
1658
    {
1659
      QuicklistMenuItemRadio* item = new QuicklistMenuItemRadio ((DbusmenuMenuitem*)child->data, NUX_TRACKER_LOCATION);
1660
      AddMenuItem (item);
1661
    }
1662
    else //if (g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0)    
613.1.5 by Jay Taoko
* QuicklistView test
1663
    {
1664
      QuicklistMenuItemLabel* item = new QuicklistMenuItemLabel ((DbusmenuMenuitem*)child->data, NUX_TRACKER_LOCATION);
1665
      AddMenuItem (item);
1666
    }
1667
  }
1668
}
1669
648.3.1 by Jay Taoko
* In progress: introspection
1670
// Introspection
1671
1672
const gchar* QuicklistView::GetName ()
1673
{
1674
  return g_strdup (_name);
1675
}
1676
1677
void QuicklistView::AddProperties (GVariantBuilder *builder)
1678
{
1679
  g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32  (GetBaseX ()));
1680
  g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32  (GetBaseY ()));
655.1.1 by Jay Taoko
* Added introspection to Quicklist, QuicklistMenuItem and Tooltip
1681
  g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (GetBaseWidth ()));
1682
  g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (GetBaseHeight ()));
1683
  g_variant_builder_add (builder, "{sv}", "active", g_variant_new_boolean (IsVisible ()));
648.3.1 by Jay Taoko
* In progress: introspection
1684
}
1685