Merge lp:~thumper/unity/launcher-messing-around into lp:unity

Proposed by Tim Penhey
Status: Work in progress
Proposed branch: lp:~thumper/unity/launcher-messing-around
Merge into: lp:unity
Diff against target: 907 lines (+338/-122)
7 files modified
launcher/Launcher.cpp (+269/-108)
launcher/Launcher.h (+8/-0)
launcher/LauncherHoverMachine.h (+2/-2)
launcher/LauncherModel.cpp (+3/-0)
launcher/LauncherOptions.cpp (+2/-0)
launcher/LauncherOptions.h (+7/-0)
launcher/StandaloneLauncher.cpp (+47/-12)
To merge this branch: bzr merge lp:~thumper/unity/launcher-messing-around
Reviewer Review Type Date Requested Status
Neil J. Patel Pending
Review via email: mp+133846@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

2886. By Tim Penhey

Drag positions now correct.

2885. By Tim Penhey

Logging adjustments.

2884. By Tim Penhey

Positional expansion on mouse entry now working properly.

2883. By Tim Penhey

Fix the launcher drag values.

2882. By Tim Penhey

Sort of working...

2881. By Tim Penhey

Working but bouncing top folding.

2880. By Tim Penhey

Mostly working, has some jumping around though.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/Launcher.cpp'
2--- launcher/Launcher.cpp 2012-11-08 09:12:24 +0000
3+++ launcher/Launcher.cpp 2012-11-12 02:05:28 +0000
4@@ -123,6 +123,7 @@
5 , _initial_drag_animation(false)
6 , _dash_is_open(false)
7 , _hud_is_open(false)
8+ , _draw_inverted(false)
9 , _folded_angle(1.0f)
10 , _neg_folded_angle(-1.0f)
11 , _folded_z_distance(10.0f)
12@@ -524,16 +525,27 @@
13 if (anchor)
14 {
15 float position = y;
16+ LOG_DEBUG(logger) << "y: " << y << ", entry_y: " << _enter_y
17+ << ", geo.height: " << geo.height;
18 for (AbstractLauncherIcon::Ptr const& model_icon : *_model)
19 {
20 if (model_icon == anchor)
21 {
22 position += _icon_size / 2;
23- _launcher_drag_delta = _enter_y - position;
24+ LOG_DEBUG(logger) << "anchor: " << anchor->tooltip_text()
25+ << ", position: " << position;
26+ // TODO: log out the details here to figure out what is going on.
27+ if (_draw_inverted)
28+ _launcher_drag_delta = geo.height - _enter_y - position;
29+ else
30+ _launcher_drag_delta = _enter_y - position;
31+ LOG_DEBUG(logger) << "ldd: " << _launcher_drag_delta;
32
33 if (position + _icon_size / 2 + _launcher_drag_delta > geo.height)
34+ {
35 _launcher_drag_delta -= (position + _icon_size / 2 + _launcher_drag_delta) - geo.height;
36-
37+ LOG_DEBUG(logger) << " adjusted ldd: " << _launcher_drag_delta;
38+ }
39 break;
40 }
41 position += (_icon_size + _space_between_icons) * IconVisibleProgress(model_icon, current);
42@@ -866,14 +878,13 @@
43 {
44 SetupRenderArg(icon, current, arg);
45
46- // reset z
47- center.z = 0;
48+ nux::Point3 local_center(center);
49
50 float size_modifier = IconVisibleProgress(icon, current);
51 if (size_modifier < 1.0f)
52 {
53 arg.alpha *= size_modifier;
54- center.z = 300.0f * (1.0f - size_modifier);
55+ local_center.z = 300.0f * (1.0f - size_modifier);
56 }
57
58 float drop_dim_value = 0.2f + 0.8f * IconDropDimValue(icon, current);
59@@ -907,46 +918,75 @@
60 arg.skip = true;
61
62 // goes for 0.0f when fully unfolded, to 1.0f folded
63- float folding_progress = CLAMP((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f);
64+ float icon_size = _icon_size; // we want a float value for calculations.
65+ // If the initial folding progress is negative, then there is no folding, if
66+ // the value is between zero and icon size, then there is partial folding, and
67+ // if the value is greater than icon_size, then the icon is considered fully
68+ // folded.
69+ float folding_progress = center.y + icon_size - folding_threshold;
70+ folding_progress = CLAMP(folding_progress / icon_size, 0.0f, 1.0f);
71 float present_progress = IconPresentProgress(icon, current);
72
73 folding_progress *= 1.0f - present_progress;
74
75- float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress);
76+ // Now recalculate the icon_size based on the folding progress.
77+ // This will give us a size between the folded_size and the icon_size
78+ // based on the folding_progress value.
79+ icon_size = folded_size + (icon_size - folded_size) * (1 - folding_progress);
80+ // Update icon_size based on the size_modifier (appearing or disappearing)
81+ icon_size *= size_modifier;
82+ float half_size = icon_size / 2;
83 float icon_hide_offset = autohide_offset;
84
85 icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency());
86
87 // icon is crossing threshold, start folding
88- center.z += folded_z_distance * folding_progress;
89+ local_center.z += folded_z_distance * folding_progress;
90 arg.x_rotation = animation_neg_rads * folding_progress;
91
92- float spacing_overlap = CLAMP((float)(center.y + (2.0f * half_size * size_modifier) + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f);
93+ float spacing_overlap = CLAMP((float)(center.y + icon_size + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f);
94 float spacing = (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier;
95
96 nux::Point3 centerOffset;
97 float center_transit_progress = IconCenterTransitionProgress(icon, current);
98+
99+ local_center.y += half_size; // move to center
100+
101+ if (_draw_inverted)
102+ {
103+ local_center.y = -local_center.y + parent_abs_geo.height;
104+ }
105+
106 if (center_transit_progress <= 1.0f)
107 {
108 int saved_center = icon->GetSavedCenter(monitor).y - parent_abs_geo.y;
109- centerOffset.y = (saved_center - (center.y + (half_size * size_modifier))) * (1.0f - center_transit_progress);
110+ centerOffset.y = (saved_center - local_center.y) * (1.0f - center_transit_progress);
111 }
112
113- center.y += half_size * size_modifier; // move to center
114-
115- arg.render_center = nux::Point3(roundf(center.x + icon_hide_offset), roundf(center.y + centerOffset.y), roundf(center.z));
116- arg.logical_center = nux::Point3(roundf(center.x + icon_hide_offset), roundf(center.y), roundf(center.z));
117-
118- icon->SetCenter(nux::Point3(roundf(center.x), roundf(center.y), roundf(center.z)), monitor, parent_abs_geo);
119-
120- // FIXME: this is a hack, to avoid that we set the target to the end of the icon
121- if (!_initial_drag_animation && icon == _drag_icon && _drag_window && _drag_window->Animating())
122+ arg.render_center = nux::Point3(roundf(local_center.x + icon_hide_offset),
123+ roundf(local_center.y + centerOffset.y),
124+ roundf(local_center.z));
125+ arg.logical_center = nux::Point3(roundf(local_center.x + icon_hide_offset),
126+ roundf(local_center.y),
127+ roundf(local_center.z));
128+
129+ icon->SetCenter(nux::Point3(roundf(local_center.x),
130+ roundf(local_center.y),
131+ roundf(local_center.z)),
132+ monitor, parent_abs_geo);
133+
134+ // FIXME: this is a hack, to avoid that we set the target to the end of the
135+ // icon
136+ if (!_initial_drag_animation &&
137+ icon == _drag_icon &&
138+ _drag_window &&
139+ _drag_window->Animating())
140 {
141 auto const& icon_center = _drag_icon->GetCenter(monitor);
142 _drag_window->SetAnimationTarget(icon_center.x, icon_center.y);
143 }
144
145- center.y += (half_size * size_modifier) + spacing; // move to end
146+ center.y += icon_size + spacing; // move to end
147 }
148
149 float Launcher::DragLimiter(float x)
150@@ -969,11 +1009,15 @@
151 }
152
153 void Launcher::RenderArgs(std::list<RenderArg> &launcher_args,
154- nux::Geometry& box_geo, float* launcher_alpha, nux::Geometry const& parent_abs_geo)
155+ nux::Geometry& box_geo,
156+ float* launcher_alpha,
157+ nux::Geometry const& parent_abs_geo)
158 {
159+ LOG_TRACE_BLOCK(logger);
160 nux::Geometry const& geo = GetGeometry();
161+ LOG_TRACE(logger) << "Launcher geometry: Location(" << geo.x << ", " << geo.y
162+ << "), Size(" << geo.width << ", " << geo.height << ")";
163 LauncherModel::iterator it;
164- nux::Point3 center;
165 struct timespec current;
166 clock_gettime(CLOCK_MONOTONIC, &current);
167
168@@ -989,9 +1033,18 @@
169 float folded_size = _icon_size * folding_not_constant;
170 float folded_spacing = _space_between_icons * folding_not_constant;
171
172- center.x = geo.width / 2;
173- center.y = _space_between_icons;
174- center.z = 0;
175+ LOG_TRACE(logger) << "Render args:\n\thover_progress: " << hover_progress
176+ << "\n\tfolded_z_distance: " << folded_z_distance
177+ << "\n\tanimation_neg_rads: " << animation_neg_rads
178+ << "\n\tfolding_constant: " << folding_constant
179+ << "\n\tfolding_not_constant: " << folding_not_constant
180+ << "\n\tfolded_size: " << folded_size
181+ << "\n\tfolded_spacing: " << folded_spacing;
182+
183+
184+ nux::Point3 center(geo.width / 2,
185+ _space_between_icons,
186+ 0);
187
188 int launcher_height = geo.height;
189
190@@ -1000,14 +1053,26 @@
191 float folding_threshold = launcher_height - _icon_size / 2.5f;
192 for (it = _model->begin(); it != _model->end(); ++it)
193 {
194- float height = (_icon_size + _space_between_icons) * IconVisibleProgress(*it, current);
195+ float height = (_icon_size + _space_between_icons) *
196+ IconVisibleProgress(*it, current);
197 sum += height;
198
199- // magic constant must some day be explained, for now suffice to say this constant prevents the bottom from "marching";
200+ // magic constant must some day be explained, for now suffice to say this
201+ // constant prevents the bottom from "marching";
202 float magic_constant = 1.3f;
203
204 float present_progress = IconPresentProgress(*it, current);
205- folding_threshold -= CLAMP(sum - launcher_height, 0.0f, height * magic_constant) * (folding_constant + (1.0f - folding_constant) * present_progress);
206+ folding_threshold -= CLAMP(sum - launcher_height,
207+ 0.0f,
208+ height * magic_constant) *
209+ (folding_constant +
210+ (1.0f - folding_constant) * present_progress);
211+
212+ LOG_TRACE(logger) << "iter through icons:"
213+ << "\n\ticon: " << (*it)->tooltip_text()
214+ << "\n\tsum: " << sum
215+ << "\n\tpresent_progress: " << present_progress
216+ << "\n\tfolding_threshold: " << folding_threshold;
217 }
218
219 if (sum - _space_between_icons <= launcher_height)
220@@ -1015,7 +1080,8 @@
221
222 float autohide_offset = 0.0f;
223 *launcher_alpha = 1.0f;
224- if (options()->hide_mode != LAUNCHER_HIDE_NEVER || _hide_machine.GetQuirk(LauncherHideMachine::LOCK_HIDE))
225+ if (options()->hide_mode != LAUNCHER_HIDE_NEVER ||
226+ _hide_machine.GetQuirk(LauncherHideMachine::LOCK_HIDE))
227 {
228
229 float autohide_progress = AutohideProgress(current) * (1.0f - DragOutProgress(current));
230@@ -1057,15 +1123,30 @@
231 */
232 static nux::Geometry last_geo = box_geo;
233
234- // this happens on hover, basically its a flag and a value in one, we translate this into a dnd offset
235- if (_enter_y != 0 && _enter_y + _icon_size / 2 > folding_threshold)
236- SetDndDelta(last_geo.x + last_geo.width / 2, center.y, geo, current);
237-
238+ // This happens on hover, basically its a flag and a value in one, we
239+ // translate this into a dnd offset. The idea here is that if the mouse
240+ // entered in the folding area, then expand that area.
241+ // NOTE: _entry_y is being used as both a flag and a value. This means that
242+ // if the launcher is being drawn inverted, and the mouse enters from the top
243+ // the dnd delta is not set.
244+ if (_enter_y != 0)
245+ {
246+ // If we are folding at the top, we do this by reversing the positions of
247+ // everything when determining rendering position. This means that in order
248+ // to determine if we are entering a folded area, we need to fake the entry
249+ // position.
250+ auto entry_position = _enter_y + _icon_size / 2;
251+ if (_draw_inverted)
252+ {
253+ entry_position = geo.height - entry_position + _icon_size;
254+ }
255+ if (entry_position > folding_threshold)
256+ SetDndDelta(last_geo.x + last_geo.width / 2, center.y, geo, current);
257+ }
258 // Update the last_geo value.
259 last_geo = box_geo;
260 _enter_y = 0;
261
262-
263 // logically dnd exit only restores to the clamped ranges
264 // hover_progress restores to 0
265 _launcher_drag_delta_max = 0.0f;
266@@ -1102,18 +1183,28 @@
267 _launcher_drag_delta = 0;
268 }
269
270- // The functional position we wish to represent for these icons is not smooth. Rather than introducing
271- // special casing to represent this, we use MIN/MAX functions. This helps ensure that even though our
272- // function is not smooth it is continuous, which is more important for our visual representation (icons
273- // wont start jumping around). As a general rule ANY if () statements that modify center.y should be seen
274- // as bugs.
275+ // The functional position we wish to represent for these icons is not smooth.
276+ // Rather than introducing special casing to represent this, we use MIN/MAX
277+ // functions. This helps ensure that even though our function is not smooth it
278+ // is continuous, which is more important for our visual representation (icons
279+ // wont start jumping around). As a general rule ANY if () statements that
280+ // modify center.y should be seen as bugs.
281 int index = 1;
282 for (it = _model->main_begin(); it != _model->main_end(); ++it)
283 {
284 RenderArg arg;
285 AbstractLauncherIcon::Ptr const& icon = *it;
286- FillRenderArg(icon, arg, center, parent_abs_geo, folding_threshold, folded_size, folded_spacing,
287- autohide_offset, folded_z_distance, animation_neg_rads, current);
288+ FillRenderArg(icon,
289+ arg,
290+ center,
291+ parent_abs_geo,
292+ folding_threshold,
293+ folded_size,
294+ folded_spacing,
295+ autohide_offset,
296+ folded_z_distance,
297+ animation_neg_rads,
298+ current);
299 arg.colorify = colorify;
300 launcher_args.push_back(arg);
301 index++;
302@@ -1125,13 +1216,23 @@
303 {
304 float height = (_icon_size + _space_between_icons) * IconVisibleProgress(*it, current);
305 shelf_sum += height;
306+
307+// LOG_TRACE(logger) << "iter through shelf icons:"
308+// << "\n\ticon: " << (*it)->tooltip_text()
309+// << "\n\tshelf_sum: " << shelf_sum;
310 }
311
312 // add bottom padding
313 if (shelf_sum > 0.0f)
314 shelf_sum += _space_between_icons;
315
316+ // The whole point of the shelf_delta is to push the shelf down to the
317+ // bottom of the launcher, so the trash (in almost all cases) is rendered
318+ // at the bottom of the screen.
319 float shelf_delta = MAX(((launcher_height - shelf_sum) + _space_between_icons) - center.y, 0.0f);
320+ //LOG_DEBUG(logger) << "lh: " << launcher_height << ", ss: " << shelf_sum
321+ // << ", c.y: " << center.y
322+ // << ", shelf_delta: " << shelf_delta;
323 folding_threshold += shelf_delta;
324 center.y += shelf_delta;
325
326@@ -1433,11 +1534,22 @@
327 UpdateOptions(options());
328 }
329
330+void Launcher::SetDrawInverted(bool inverted)
331+{
332+ if (inverted == _draw_inverted)
333+ return;
334+
335+ _draw_inverted = inverted;
336+ _folded_angle *= -1;
337+ _neg_folded_angle *= -1;
338+}
339+
340 void Launcher::UpdateOptions(Options::Ptr options)
341 {
342+ LOG_DEBUG_BLOCK(logger);
343 SetIconSize(options->tile_size, options->icon_size);
344 SetHideMode(options->hide_mode);
345-
346+ SetDrawInverted(options->fold_behaviour != FOLD_AT_BOTTOM);
347 ConfigureBarrier();
348 EnsureAnimation();
349 }
350@@ -1555,7 +1667,7 @@
351 bool Launcher::OnScrollTimeout()
352 {
353 bool continue_animation = true;
354-
355+ int drag_delta = 0;
356 if (IsInKeyNavMode() || !_hovered ||
357 GetActionState() == ACTION_DRAG_LAUNCHER)
358 {
359@@ -1563,27 +1675,31 @@
360 }
361 else if (MouseOverTopScrollArea())
362 {
363- if (_launcher_drag_delta >= _launcher_drag_delta_max)
364+ if ((!_draw_inverted && _launcher_drag_delta >= _launcher_drag_delta_max) ||
365+ (_draw_inverted && _launcher_drag_delta <= _launcher_drag_delta_min))
366 continue_animation = false;
367 else if (MouseOverTopScrollExtrema())
368- _launcher_drag_delta += 6;
369+ drag_delta = 6;
370 else
371- _launcher_drag_delta += 3;
372+ drag_delta = 3;
373 }
374 else if (MouseOverBottomScrollArea())
375 {
376- if (_launcher_drag_delta <= _launcher_drag_delta_min)
377+ if ((!_draw_inverted && _launcher_drag_delta <= _launcher_drag_delta_min) ||
378+ (_draw_inverted && _launcher_drag_delta >= _launcher_drag_delta_max))
379 continue_animation = false;
380 else if (MouseOverBottomScrollExtrema())
381- _launcher_drag_delta -= 6;
382+ drag_delta = -6;
383 else
384- _launcher_drag_delta -= 3;
385+ drag_delta = -3;
386 }
387 else
388 {
389 continue_animation = false;
390 }
391-
392+ if (_draw_inverted)
393+ drag_delta *= -1;
394+ _launcher_drag_delta += drag_delta;
395 if (continue_animation)
396 {
397 EnsureAnimation();
398@@ -1639,6 +1755,16 @@
399 ConfigureBarrier();
400 }
401
402+void Launcher::SetHeight(int height)
403+{
404+ int width = _icon_size + ICON_PADDING*2 + RIGHT_LINE_WIDTH - 2;
405+ nux::Geometry new_geometry(0, 0, width, height);
406+ SetMaximumHeight(new_geometry.height);
407+ _parent->SetGeometry(new_geometry);
408+ SetGeometry(new_geometry);
409+}
410+
411+
412 void Launcher::OnIconAdded(AbstractLauncherIcon::Ptr const& icon)
413 {
414 EnsureAnimation();
415@@ -1731,6 +1857,24 @@
416
417 }
418
419+void Launcher::DrawFromRenderArg(RenderArg const& arg,
420+ nux::GraphicsEngine& GfxContext,
421+ nux::Geometry const& base,
422+ nux::Geometry const& bkg_box)
423+{
424+ if (arg.stick_thingy)
425+ gPainter.Paint2DQuadColor(GfxContext,
426+ nux::Geometry(bkg_box.x,
427+ arg.render_center.y - 3,
428+ bkg_box.width,
429+ 2),
430+ nux::Color(0xAAAAAAAA));
431+ if (arg.skip)
432+ return;
433+
434+ icon_renderer->RenderIcon(GfxContext, arg, bkg_box, base);
435+}
436+
437 void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
438 {
439 icon_renderer->monitor = monitor();
440@@ -1816,49 +1960,49 @@
441
442 if (BackgroundEffectHelper::blur_type != unity::BLUR_NONE && (bkg_box.x + bkg_box.width > 0))
443 {
444- blur_texture = bg_effect_helper_.GetBlurRegion(blur_geo);
445+ blur_texture = bg_effect_helper_.GetBlurRegion(blur_geo);
446 }
447 else
448 {
449- blur_texture = bg_effect_helper_.GetRegion(blur_geo);
450+ blur_texture = bg_effect_helper_.GetRegion(blur_geo);
451 }
452
453 if (blur_texture.IsValid())
454 {
455- nux::TexCoordXForm texxform_blur_bg;
456- texxform_blur_bg.flip_v_coord = true;
457- texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
458- texxform_blur_bg.uoffset = ((float) base.x) / geo_absolute.width;
459- texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height;
460+ nux::TexCoordXForm texxform_blur_bg;
461+ texxform_blur_bg.flip_v_coord = true;
462+ texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
463+ texxform_blur_bg.uoffset = ((float) base.x) / geo_absolute.width;
464+ texxform_blur_bg.voffset = ((float) base.y) / geo_absolute.height;
465
466- GfxContext.PushClippingRectangle(bkg_box);
467+ GfxContext.PushClippingRectangle(bkg_box);
468
469 #ifndef NUX_OPENGLES_20
470- if (GfxContext.UsingGLSLCodePath())
471- gPainter.PushDrawCompositionLayer(GfxContext, base,
472- blur_texture,
473- texxform_blur_bg,
474- nux::color::White,
475- _background_color, nux::LAYER_BLEND_MODE_OVERLAY,
476- true, ROP);
477- else
478- gPainter.PushDrawTextureLayer(GfxContext, base,
479- blur_texture,
480- texxform_blur_bg,
481- nux::color::White,
482- true,
483- ROP);
484+ if (GfxContext.UsingGLSLCodePath())
485+ gPainter.PushDrawCompositionLayer(GfxContext, base,
486+ blur_texture,
487+ texxform_blur_bg,
488+ nux::color::White,
489+ _background_color, nux::LAYER_BLEND_MODE_OVERLAY,
490+ true, ROP);
491+ else
492+ gPainter.PushDrawTextureLayer(GfxContext, base,
493+ blur_texture,
494+ texxform_blur_bg,
495+ nux::color::White,
496+ true,
497+ ROP);
498 #else
499- gPainter.PushDrawCompositionLayer(GfxContext, base,
500- blur_texture,
501- texxform_blur_bg,
502- nux::color::White,
503- _background_color, nux::LAYER_BLEND_MODE_OVERLAY,
504- true, ROP);
505+ gPainter.PushDrawCompositionLayer(GfxContext, base,
506+ blur_texture,
507+ texxform_blur_bg,
508+ nux::color::White,
509+ _background_color, nux::LAYER_BLEND_MODE_OVERLAY,
510+ true, ROP);
511 #endif
512- GfxContext.PopClippingRectangle();
513+ GfxContext.PopClippingRectangle();
514
515- push_count++;
516+ push_count++;
517 }
518
519 unsigned int alpha = 0, src = 0, dest = 0;
520@@ -1872,7 +2016,7 @@
521 // apply the bg colour
522 #ifndef NUX_OPENGLES_20
523 if (GfxContext.UsingGLSLCodePath() == false)
524- gPainter.Paint2DQuadColor(GfxContext, bkg_box, _background_color);
525+ gPainter.Paint2DQuadColor(GfxContext, bkg_box, _background_color);
526 #endif
527
528 // apply the shine
529@@ -1883,9 +2027,9 @@
530 texxform.uoffset = (1.0f / launcher_sheen_->GetWidth()); // TODO (gord) don't use absolute values here
531 texxform.voffset = (1.0f / launcher_sheen_->GetHeight()) * panel::Style::Instance().panel_height;
532 GfxContext.QRP_1Tex(base.x, base.y, base.width, base.height,
533- launcher_sheen_->GetDeviceTexture(),
534- texxform,
535- nux::color::White);
536+ launcher_sheen_->GetDeviceTexture(),
537+ texxform,
538+ nux::color::White);
539
540 //reset the blend state
541 GfxContext.GetRenderStates().SetBlend (alpha, src, dest);
542@@ -1903,19 +2047,16 @@
543 icon_renderer->PreprocessIcons(args, base);
544 EventLogic();
545
546- /* draw launcher */
547- for (rev_it = args.rbegin(); rev_it != args.rend(); ++rev_it)
548- {
549- if ((*rev_it).stick_thingy)
550- gPainter.Paint2DQuadColor(GfxContext,
551- nux::Geometry(bkg_box.x, (*rev_it).render_center.y - 3, bkg_box.width, 2),
552- nux::Color(0xAAAAAAAA));
553-
554- if ((*rev_it).skip)
555- continue;
556-
557- icon_renderer->RenderIcon(GfxContext, *rev_it, bkg_box, base);
558- }
559+ // Draw the launcher from the bottom up if folding at the bottom,
560+ // and from the top down if folding at the top.
561+ //if (options()->fold_behaviour == FOLD_AT_BOTTOM)
562+ for (rev_it = args.rbegin(); rev_it != args.rend(); ++rev_it)
563+ {
564+ DrawFromRenderArg(*rev_it, GfxContext, base, bkg_box);
565+ }
566+ //else
567+ //for (auto& arg : args)
568+ //DrawFromRenderArg(arg, GfxContext, base, bkg_box);
569
570 if (!IsOverlayOpen())
571 {
572@@ -2130,9 +2271,11 @@
573 struct timespec current;
574 clock_gettime(CLOCK_MONOTONIC, &current);
575 float progress = DragThresholdProgress(current);
576-
577+ LOG_DEBUG(logger) << "Update drag (" << x << ", " << y
578+ << "), progress: " << progress;
579 if (hovered_icon && _drag_icon != hovered_icon)
580 {
581+ LOG_DEBUG(logger) << " hovered_icon: " << hovered_icon->tooltip_text();
582 if (progress >= 1.0f)
583 {
584 _model->ReorderSmart(_drag_icon, hovered_icon, true);
585@@ -2154,6 +2297,7 @@
586
587 if (y >= icon->GetCenter(monitor).y)
588 {
589+ LOG_DEBUG(logger) << " icon: " << icon->tooltip_text();
590 _model->ReorderAfter(_drag_icon, icon);
591 break;
592 }
593@@ -2210,6 +2354,9 @@
594 _dnd_delta_y += dy;
595 _dnd_delta_x += dx;
596
597+ //LOG_DEBUG(logger) << "Drag: dy: " << dy << ", _dnd_delta_y:" << _dnd_delta_y
598+ // << ", ldd: " << _launcher_drag_delta;
599+
600 if (nux::Abs(_dnd_delta_y) < MOUSE_DEADZONE &&
601 nux::Abs(_dnd_delta_x) < MOUSE_DEADZONE &&
602 GetActionState() == ACTION_NONE)
603@@ -2226,7 +2373,10 @@
604 #ifdef UNITY_HAS_X_ORG_SUPPORT
605 if (nux::Abs(_dnd_delta_y) >= nux::Abs(_dnd_delta_x))
606 {
607- _launcher_drag_delta += _dnd_delta_y;
608+ if (_draw_inverted)
609+ _launcher_drag_delta -= _dnd_delta_y;
610+ else
611+ _launcher_drag_delta += _dnd_delta_y;
612 SetActionState(ACTION_DRAG_LAUNCHER);
613 _hide_machine.SetQuirk(LauncherHideMachine::VERTICAL_SLIDE_ACTIVE, true);
614 }
615@@ -2240,7 +2390,10 @@
616 }
617 else if (GetActionState() == ACTION_DRAG_LAUNCHER)
618 {
619- _launcher_drag_delta += dy;
620+ if (_draw_inverted)
621+ _launcher_drag_delta -= dy;
622+ else
623+ _launcher_drag_delta += dy;
624 ubus_.SendMessage(UBUS_LAUNCHER_END_DND);
625 }
626 else if (GetActionState() == ACTION_DRAG_ICON)
627@@ -2283,18 +2436,20 @@
628 {
629 if (!_hovered)
630 return;
631-
632+ int value = 0;
633 if (wheel_delta < 0)
634 {
635 // scroll up
636- _launcher_drag_delta -= 25;
637+ value = -25;
638 }
639 else
640 {
641 // scroll down
642- _launcher_drag_delta += 25;
643+ value = 25;
644 }
645-
646+ if (_draw_inverted)
647+ value *= -1;
648+ _launcher_drag_delta += value;
649 EnsureAnimation();
650 }
651
652@@ -2472,25 +2627,31 @@
653
654 for (it = _model->begin(); it != _model->end(); ++it)
655 {
656- if (!(*it)->IsVisible() || !(*it)->IsVisibleOnMonitor(monitor))
657+ AbstractLauncherIcon::Ptr const& icon = *it;
658+ if (!icon->IsVisible() || !icon->IsVisibleOnMonitor(monitor))
659 continue;
660
661 nux::Point2 screen_coord [4];
662+ auto hit_transform = icon->GetTransform(AbstractLauncherIcon::TRANSFORM_HIT_AREA, monitor);
663 for (int i = 0; i < 4; ++i)
664 {
665- auto hit_transform = (*it)->GetTransform(AbstractLauncherIcon::TRANSFORM_HIT_AREA, monitor);
666 screen_coord [i].x = hit_transform [i].x;
667 screen_coord [i].y = hit_transform [i].y;
668 }
669 inside = PointInside2DPolygon(screen_coord, 4, mouse_position, 1);
670 if (inside)
671- return (*it);
672+ {
673+ LOG_TRACE(logger) << "Hit " << icon->tooltip_text();
674+ return icon;
675+ }
676 }
677
678 return AbstractLauncherIcon::Ptr();
679 }
680
681-void Launcher::RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherIcon::Ptr const& icon, nux::ObjectPtr<nux::IOpenGLBaseTexture> texture)
682+void Launcher::RenderIconToTexture(nux::GraphicsEngine& GfxContext,
683+ AbstractLauncherIcon::Ptr const& icon,
684+ nux::ObjectPtr<nux::IOpenGLBaseTexture> texture)
685 {
686 RenderArg arg;
687 struct timespec current;
688
689=== modified file 'launcher/Launcher.h'
690--- launcher/Launcher.h 2012-11-06 18:19:09 +0000
691+++ launcher/Launcher.h 2012-11-12 02:05:28 +0000
692@@ -123,6 +123,7 @@
693 int GetMouseY() const;
694
695 void Resize();
696+ void SetHeight(int height);
697
698 int GetDragDelta() const;
699 void SetHover(bool hovered);
700@@ -257,6 +258,7 @@
701 float IconVisibleProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const;
702
703 void SetHidden(bool hidden);
704+ void SetDrawInverted(bool inverted);
705
706 void UpdateChangeInMousePosition(int delta_x, int delta_y);
707
708@@ -279,6 +281,11 @@
709 void RenderArgs(std::list<ui::RenderArg> &launcher_args,
710 nux::Geometry& box_geo, float* launcher_alpha, nux::Geometry const& parent_abs_geo);
711
712+ void DrawFromRenderArg(ui::RenderArg const& arg,
713+ nux::GraphicsEngine& GfxContext,
714+ nux::Geometry const& base,
715+ nux::Geometry const& bkg_box);
716+
717 void OnIconAdded(AbstractLauncherIcon::Ptr const& icon);
718 void OnIconRemoved(AbstractLauncherIcon::Ptr const& icon);
719 void OnOrderChanged();
720@@ -348,6 +355,7 @@
721 bool _initial_drag_animation;
722 bool _dash_is_open;
723 bool _hud_is_open;
724+ bool _draw_inverted;
725
726 float _folded_angle;
727 float _neg_folded_angle;
728
729=== modified file 'launcher/LauncherHoverMachine.h'
730--- launcher/LauncherHoverMachine.h 2012-10-10 22:33:14 +0000
731+++ launcher/LauncherHoverMachine.h 2012-11-12 02:05:28 +0000
732@@ -29,7 +29,7 @@
733 {
734 public:
735
736- typedef enum
737+ enum HoverQuirk
738 {
739 DEFAULT = 0,
740 LAUNCHER_HIDDEN = 1 << 0,
741@@ -39,7 +39,7 @@
742 KEY_NAV_ACTIVE = 1 << 4,
743 LAUNCHER_IN_ACTION = 1 << 5,
744 PLACES_VISIBLE = 1 << 6,
745- } HoverQuirk;
746+ };
747
748 LauncherHoverMachine();
749
750
751=== modified file 'launcher/LauncherModel.cpp'
752--- launcher/LauncherModel.cpp 2012-10-11 01:44:15 +0000
753+++ launcher/LauncherModel.cpp 2012-11-12 02:05:28 +0000
754@@ -19,6 +19,8 @@
755 */
756
757 #include "LauncherModel.h"
758+
759+#include <NuxCore/Logger.h>
760 #include "AbstractLauncherIcon.h"
761
762 #include <UnityCore/GLibWrapper.h>
763@@ -28,6 +30,7 @@
764 {
765 namespace launcher
766 {
767+DECLARE_LOGGER(logger, "unity.launcher.model");
768
769 LauncherModel::LauncherModel()
770 : selection_(0)
771
772=== modified file 'launcher/LauncherOptions.cpp'
773--- launcher/LauncherOptions.cpp 2012-08-30 18:14:19 +0000
774+++ launcher/LauncherOptions.cpp 2012-11-12 02:05:28 +0000
775@@ -33,6 +33,7 @@
776 , auto_hide_animation(FADE_AND_SLIDE)
777 , backlight_mode(BACKLIGHT_NORMAL)
778 , reveal_trigger(RevealTrigger::EDGE)
779+ , fold_behaviour(FOLD_AT_BOTTOM)
780 , icon_size(48)
781 , tile_size(54)
782 , background_alpha(0.6667)
783@@ -54,6 +55,7 @@
784 edge_reveal_pressure.changed.connect ([this] (int value) { option_changed.emit(); });
785 edge_stop_velocity.changed.connect ([this] (int value) { option_changed.emit(); });
786 edge_passed_disabled_ms.changed.connect([this] (unsigned value) { option_changed.emit(); });
787+ fold_behaviour.changed.connect ([this] (FoldBehaviour value) { option_changed.emit(); });
788 hide_mode.changed.connect ([this] (LauncherHideMode value) { option_changed.emit(); });
789 icon_size.changed.connect ([this] (int value) { option_changed.emit(); });
790 launch_animation.changed.connect ([this] (LaunchAnimation value) { option_changed.emit(); });
791
792=== modified file 'launcher/LauncherOptions.h'
793--- launcher/LauncherOptions.h 2012-08-07 10:53:16 +0000
794+++ launcher/LauncherOptions.h 2012-11-12 02:05:28 +0000
795@@ -76,6 +76,12 @@
796 CORNER,
797 };
798
799+enum FoldBehaviour
800+{
801+ FOLD_AT_BOTTOM,
802+ FOLD_AT_TOP,
803+};
804+
805 class Options : public sigc::trackable
806 {
807 public:
808@@ -89,6 +95,7 @@
809 nux::Property<AutoHideAnimation> auto_hide_animation;
810 nux::Property<BacklightMode> backlight_mode;
811 nux::Property<RevealTrigger> reveal_trigger;
812+ nux::Property<FoldBehaviour> fold_behaviour;
813 nux::Property<int> icon_size;
814 nux::Property<int> tile_size;
815 nux::Property<float> background_alpha;
816
817=== modified file 'launcher/StandaloneLauncher.cpp'
818--- launcher/StandaloneLauncher.cpp 2012-10-17 22:16:48 +0000
819+++ launcher/StandaloneLauncher.cpp 2012-11-12 02:05:28 +0000
820@@ -18,7 +18,9 @@
821 *
822 */
823
824-#include "Nux/Nux.h"
825+#include <memory>
826+#include <Nux/Nux.h>
827+#include <NuxCore/Logger.h>
828 #include <gtk/gtk.h>
829
830 #include "unity-shared/BackgroundEffectHelper.h"
831@@ -31,32 +33,65 @@
832
833 using namespace unity;
834
835-static launcher::Controller::Ptr controller;
836-
837-void ThreadWidgetInit(nux::NThread* thread, void* InitData)
838+class StandaloneLauncher
839 {
840-// launcherWindow->SetGeometry (nux::Geometry(0, 0, 300, 800));
841- controller.reset(new launcher::Controller());
842-}
843+public:
844+ StandaloneLauncher(std::string const& param)
845+ : top_fold(param == "top")
846+ {
847+ }
848+
849+ void OnWindowGeometryChanged(int, int, int, int height)
850+ {
851+ controller->launcher().SetHeight(height);
852+ }
853+
854+ static void ThreadInit(nux::NThread* , void* data)
855+ {
856+ StandaloneLauncher* self = static_cast<StandaloneLauncher*>(data);
857+ self->controller.reset(new launcher::Controller());
858+ auto& launcher = self->controller->launcher();
859+ launcher.SetHeight(800);
860+ if (self->top_fold)
861+ launcher.options()->fold_behaviour = launcher::FOLD_AT_TOP;
862+ }
863+
864+private:
865+ bool top_fold;
866+ launcher::Controller::Ptr controller;
867+};
868+
869
870 int main(int argc, char** argv)
871 {
872 g_type_init();
873 gtk_init(&argc, &argv);
874 nux::NuxInitialize(0);
875+ nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY"));
876
877 unity::Settings settings;
878 panel::Style panel_style;
879 internal::FavoriteStoreGSettings favorite_store;
880
881 BackgroundEffectHelper::blur_type = BLUR_NONE;
882- nux::WindowThread* wt = nux::CreateGUIThread(TEXT("Unity Switcher"), 300, 800, 0, &ThreadWidgetInit, 0);
883-
884- wt->Run(NULL);
885+ std::unique_ptr<nux::WindowThread> wt;
886+ {
887+ std::string arg;
888+ if (argc > 1)
889+ arg = argv[1];
890+ StandaloneLauncher standalone_launcher(arg);
891+ wt.reset(
892+ nux::CreateGUIThread("Unity Launcher",
893+ 300, 800, 0,
894+ &StandaloneLauncher::ThreadInit,
895+ &standalone_launcher));
896+ wt->window_configuration.connect(
897+ sigc::mem_fun(&standalone_launcher,
898+ &StandaloneLauncher::OnWindowGeometryChanged));
899+ wt->Run(NULL);
900+ }
901 // Make sure the controller is destroyed before the window thread.
902- controller.reset();
903 ::unity::ui::IconRenderer::DestroyTextures();
904
905- delete wt;
906 return 0;
907 }