Merge lp:~brandontschaefer/unity/lp608124-overlay-scrollbar-dash into lp:unity

Proposed by Brandon Schaefer
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 2928
Proposed branch: lp:~brandontschaefer/unity/lp608124-overlay-scrollbar-dash
Merge into: lp:unity
Diff against target: 1700 lines (+1459/-15)
14 files modified
dash/DashView.cpp (+10/-3)
dash/LensView.cpp (+14/-2)
dash/previews/ApplicationPreview.cpp (+2/-2)
dash/previews/GenericPreview.cpp (+2/-2)
dash/previews/MoviePreview.cpp (+2/-2)
dash/previews/SocialPreview.cpp (+2/-2)
dash/previews/Tracks.cpp (+2/-2)
tests/CMakeLists.txt (+1/-0)
tests/test_overlay_scrollbar.cpp (+280/-0)
unity-shared/CMakeLists.txt (+2/-0)
unity-shared/PlacesOverlayVScrollBar.cpp (+417/-0)
unity-shared/PlacesOverlayVScrollBar.h (+107/-0)
unity-shared/VScrollBarOverlayWindow.cpp (+526/-0)
unity-shared/VScrollBarOverlayWindow.h (+92/-0)
To merge this branch: bzr merge lp:~brandontschaefer/unity/lp608124-overlay-scrollbar-dash
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
John Lea (community) design Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+134211@code.launchpad.net

Commit message

Add an overlay scroll bar thumb that allows you to control the scroll bars in the dash.

Description of the change

=== Problem ===
The scroll bars in the dash are hard to grab because they are to thin.

=== Fix ===
Add an overlay scroll bar thumb that allows you to control the scroll bar. (Check out the video for more detail.)

New video showing off the overlay scrollbars:
http://ubuntuone.com/7czr6JBvPNtycHDYCRG7PI

Video showing the connector.
http://ubuntuone.com/5XnzPBz8AvecDISZ1ydyYy

Three pixel wide connector...(Video is 2 pixels wide)
http://i.imgur.com/axkOC.jpg

Depends on this nux branch:
https://code.launchpad.net/~brandontschaefer/nux/mouse-near-signal/+merge/133387

This branch fixes the problem when you mouse to quickly off the dash leaving the overlay thumb visible.
https://code.launchpad.net/~brandontschaefer/nux/nux-failing-to-emit-mouse-beyond/+merge/135318

=== Test ===
Unit tests

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

First of all, looking at the screencast: awesome work!

430 + _prox_area = std::make_shared<nux::ProximityArea>(_overlay_window.GetPointer(), 7);

I like shared pointers, but since we're using a view here I think you should use an ObjectPtr instead. Also please remember to put the magic number to a global constant, so that is defined and easily editable.

773 +VScrollBarOverlayWindow::VScrollBarOverlayWindow(const nux::Geometry geo)
970 + nux::Color color = nux::color::White;
1208 + nux::Color bg_shadow = ProduceColorShade(bg, 0.2);
1239 + nux::Color bg_dark_line = ProduceColorShade(bg, 0.4);
1240 + nux::Color bg_bright_line = ProduceColorShade(bg, 1.2);

const& ;)

971 + nux::Geometry base = content_size_;
972 + base.SetX(0);
973 + base.SetY(mouse_offset_y_);
974 + base.SetWidth(THUMB_WIDTH);
975 + base.SetHeight(THUMB_HEIGHT);

No need to copy content_size_ here since you're changing everything, just initialize a new Geometry.

979 + if (!thumb_texture_)
980 + return;

Add this on top of the function... It's always better to return as soon as you can to avoid unneeded computation.

1130 + cairoGraphics = new nux::CairoGraphics(CAIRO_FORMAT_ARGB32, width, height);

Don't use a pointer here, you don't need it.

1250 + if (thumb_texture_)
1251 + thumb_texture_->UnReference();

You don't need this, just do:
thumb_texture_.Adopt(unity::texture_from_cairo_graphics(*cairoGraphics));

1255 + delete cairoGraphics;
Remove it with the pointer ;)

I see a lot of public methods in VScrollBarOverlayWindow and PlacesOverlayVScrollBar. Please make them private when possible and at least protected when you need them for testing (even if in that case you could just use the "friendship hack" to get things testable anyway).

Revision history for this message
Stephen M. Webb (bregma) wrote :

480 + _overlay_window = new VScrollBarOverlayWindow(_track->GetAbsoluteGeometry());

Why can't this member be initialized in the initialization list?

507 + _overlay_window.Release();

Does this not happen automatically? Is this going to mess up the refcount?

516 + _animation.SetDuration(400);

What is magic about 400?

656 + if (y < (thumb_height/2 + thumb_offset_y))
657 + return true;
658 +
659 + return false;

Or maybe "return y < (thumb_height/2 + thumb_offset_y)"?

1044 + const nux::Color& color = nux::color::White;

1122 + DrawGrip(cr, width/2 - 6.5, 13.5, 5, 6);
1123 + DrawGrip(cr, width/2 - 6.5, height/2 + 3.5, 5, 6);

Magic, everywhere. Are those pixels? Millimetres? Points? Ems? Will they
look as good on a 72 dpi screen as on a 300 dpi screen?

Same goes for a lot of the magic numbers used to generate color variants,
offsets, and sizes.

Revision history for this message
John Lea (johnlea) wrote :

*almost* there, looking very good ;-) Other than one missing element it looks perfect!

The missing element is the 'connector' between the scrollbar and the thumb that should appear and connect the scrollbar and the thumb together when these two elements are not otherwise attached.

If you need any further visual designs contact Otto, I spoke to him a moment ago and he said that you discussed with him at UDS using a very light semi-transparent line as the connector.

Also ping me on IRC if you can't get in touch with Otto or have any other questions.

cheers,
John

review: Needs Fixing (design)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Thank you for looking at it! I was using xchat as a reference and it seems to be missing that 'connector'. Ill get to working on that :).

I thought Otto and I talked about the outline of the thumb is self, which would refelct the color of the 'connector' I just missed the connector part!

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

@John

Video showing the connector.
http://ubuntuone.com/5XnzPBz8AvecDISZ1ydyYy

The connector is 2 pixels wide in the video because that matches up with the thumbs outline...though the slider is 3 pixels wide. Should it be left at 2?

Revision history for this message
John Lea (johnlea) wrote :

Reviewed latest video showing connector, looks good, design wise approved ;-)

review: Approve (design)
Revision history for this message
Andrea Azzarone (azzar1) wrote :

+ OnVisibleChanged.connect([&] (nux::Area* area, bool visible) {

I'd prefert to comment out area here so: nux::Area* /*area*/, bool visible.

576 + , _overlay_window(new VScrollBarOverlayWindow(_track->GetAbsoluteGeometry()))
577 + , _area_prox(_overlay_window.GetPointer(), PROXIMITY)
578 + , _thumb_above_slider(false)
579 + , _connector_height(0)
580 + , _mouse_down_offset(0)

For new files please use the new style member_variable_ :)

+void PlacesOverlayVScrollBar::OnTrackGeometryChanged(nux::Area* area, nux::Geometry& geo)

Comment out area and geo.

622 + _animation.SetDuration(SCROLL_ANIMATION);
623 + _animation.SetEasingCurve(nux::animation::EasingCurve(nux::animation::EasingCurve::Type::Linear));
624 +
625 + _animation.SetStartValue(0);
626 + _animation.SetFinishValue(stop);
627 +
628 + StartScrollAnimation(dir);

Maybe you can move 622..627 in a new function so you have:
  SetupScrollAnimation();
  StartScrollAnimation(dir);

But if you don't like it's ok :)

Sometimes you use this condition (content_height_ > container_height_)

I'd move this condition in a readable function (something like IsVScrollbarActive, but I'm sure you'll find a better name :)

+ _overlay_window->SetThumbOffsetY(new_offset - _overlay_window->GetThumbHeight()/4);

I'm sure this 4 is not a magic number but it's not so easy to get its purpose.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Looks very good both code-wise and result-wise... Awesome work, approving it! :)

review: Approve
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

623 +void PlacesOverlayVScrollBar::StopAnimation()
624 +{
625 + if (animation_.CurrentState() != nux::animation::Animation::State::Stopped)
626 + animation_.Stop();
627 +}

This shouldn't be needed, since animation_.Stop() already does that check...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'dash/DashView.cpp'
--- dash/DashView.cpp 2012-11-19 18:54:19 +0000
+++ dash/DashView.cpp 2012-11-23 23:52:20 +0000
@@ -166,6 +166,7 @@
166166
167 preview_navigation_mode_ = previews::Navigation::NONE;167 preview_navigation_mode_ = previews::Navigation::NONE;
168 preview_displaying_ = false;168 preview_displaying_ = false;
169 active_lens_view_->SetVisible(true);
169170
170 // re-focus dash view component.171 // re-focus dash view component.
171 nux::GetWindowCompositor().SetKeyFocusArea(default_focus());172 nux::GetWindowCompositor().SetKeyFocusArea(default_focus());
@@ -269,6 +270,7 @@
269270
270 preview_container_->SetGeometry(layout_->GetGeometry());271 preview_container_->SetGeometry(layout_->GetGeometry());
271 preview_displaying_ = true;272 preview_displaying_ = true;
273 active_lens_view_->SetVisible(false);
272274
273 // connect to nav left/right signals to request nav left/right movement.275 // connect to nav left/right signals to request nav left/right movement.
274 preview_container_->navigate_left.connect([&] () {276 preview_container_->navigate_left.connect([&] () {
@@ -328,18 +330,19 @@
328 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW330 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW
329 << " on '" << home_lens_->id() << "'";331 << " on '" << home_lens_->id() << "'";
330 }332 }
331 else if (active_lens_view_)333 else
332 {334 {
333 // careful here, the lens_view's view_type doesn't get reset when the dash335 // careful here, the lens_view's view_type doesn't get reset when the dash
334 // hides, but lens' view_type does, so we need to update the lens directly336 // hides, but lens' view_type does, so we need to update the lens directly
335 active_lens_view_->lens()->view_type = ViewType::LENS_VIEW;337 active_lens_view_->lens()->view_type = ViewType::LENS_VIEW;
336 }338 }
339 active_lens_view_->SetVisible(true);
337340
338 // this will make sure the spinner animates if the search takes a while341 // this will make sure the spinner animates if the search takes a while
339 search_bar_->ForceSearchChanged();342 search_bar_->ForceSearchChanged();
340343
341 // if a preview is open, close it344 // if a preview is open, close it
342 if (preview_displaying_) 345 if (preview_displaying_)
343 {346 {
344 ClosePreview();347 ClosePreview();
345 }348 }
@@ -363,8 +366,10 @@
363 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN366 LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN
364 << " on '" << home_lens_->id() << "'";367 << " on '" << home_lens_->id() << "'";
365368
369 active_lens_view_->SetVisible(false);
370
366 // if a preview is open, close it371 // if a preview is open, close it
367 if (preview_displaying_) 372 if (preview_displaying_)
368 {373 {
369 ClosePreview();374 ClosePreview();
370 }375 }
@@ -967,6 +972,8 @@
967 return;972 return;
968 }973 }
969974
975 lens_views_[id]->SetVisible(true);
976 active_lens_view_->SetVisible(false);
970 LensView* view = active_lens_view_ = lens_views_[id];977 LensView* view = active_lens_view_ = lens_views_[id];
971 view->JumpToTop();978 view->JumpToTop();
972979
973980
=== modified file 'dash/LensView.cpp'
--- dash/LensView.cpp 2012-11-19 18:54:19 +0000
+++ dash/LensView.cpp 2012-11-23 23:52:20 +0000
@@ -33,6 +33,7 @@
33#include "unity-shared/UBusMessages.h"33#include "unity-shared/UBusMessages.h"
34#include "unity-shared/UBusWrapper.h"34#include "unity-shared/UBusWrapper.h"
35#include "unity-shared/PlacesVScrollBar.h"35#include "unity-shared/PlacesVScrollBar.h"
36#include "unity-shared/PlacesOverlayVScrollBar.h"
3637
37#include <glib/gi18n-lib.h>38#include <glib/gi18n-lib.h>
3839
@@ -57,6 +58,13 @@
57 , up_area_(nullptr)58 , up_area_(nullptr)
58 {59 {
59 SetVScrollBar(scroll_bar);60 SetVScrollBar(scroll_bar);
61
62 OnVisibleChanged.connect([&] (nux::Area* /*area*/, bool visible) {
63 if (m_horizontal_scrollbar_enable)
64 _hscrollbar->SetVisible(visible);
65 if (m_vertical_scrollbar_enable)
66 _vscrollbar->SetVisible(visible);
67 });
60 }68 }
6169
62 void ScrollToPosition(nux::Geometry const& position)70 void ScrollToPosition(nux::Geometry const& position)
@@ -192,6 +200,10 @@
192 }200 }
193 });201 });
194202
203 OnVisibleChanged.connect([&] (nux::Area* area, bool visible) {
204 scroll_view_->SetVisible(visible);
205 });
206
195}207}
196208
197void LensView::SetupViews(nux::Area* show_filters)209void LensView::SetupViews(nux::Area* show_filters)
@@ -201,9 +213,9 @@
201 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);213 layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
202 layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenLensAndFilters());214 layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenLensAndFilters());
203215
204 scroll_view_ = new LensScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION),216 scroll_view_ = new LensScrollView(new PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION),
205 NUX_TRACKER_LOCATION);217 NUX_TRACKER_LOCATION);
206 scroll_view_->EnableVerticalScrollBar(false);218 scroll_view_->EnableVerticalScrollBar(true);
207 scroll_view_->EnableHorizontalScrollBar(false);219 scroll_view_->EnableHorizontalScrollBar(false);
208 layout_->AddView(scroll_view_);220 layout_->AddView(scroll_view_);
209221
210222
=== modified file 'dash/previews/ApplicationPreview.cpp'
--- dash/previews/ApplicationPreview.cpp 2012-10-29 09:34:54 +0000
+++ dash/previews/ApplicationPreview.cpp 2012-11-23 23:52:20 +0000
@@ -25,7 +25,7 @@
25#include "unity-shared/CoverArt.h"25#include "unity-shared/CoverArt.h"
26#include "unity-shared/IconTexture.h"26#include "unity-shared/IconTexture.h"
27#include "unity-shared/StaticCairoText.h"27#include "unity-shared/StaticCairoText.h"
28#include "unity-shared/PlacesVScrollBar.h"28#include "unity-shared/PlacesOverlayVScrollBar.h"
29#include <UnityCore/ApplicationPreview.h>29#include <UnityCore/ApplicationPreview.h>
30#include <NuxCore/Logger.h>30#include <NuxCore/Logger.h>
31#include <Nux/HLayout.h>31#include <Nux/HLayout.h>
@@ -54,7 +54,7 @@
54 DetailsScrollView(NUX_FILE_LINE_PROTO)54 DetailsScrollView(NUX_FILE_LINE_PROTO)
55 : ScrollView(NUX_FILE_LINE_PARAM)55 : ScrollView(NUX_FILE_LINE_PARAM)
56 {56 {
57 SetVScrollBar(new dash::PlacesVScrollBar(NUX_TRACKER_LOCATION));57 SetVScrollBar(new dash::PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION));
58 }58 }
5959
60};60};
6161
=== modified file 'dash/previews/GenericPreview.cpp'
--- dash/previews/GenericPreview.cpp 2012-10-29 09:34:54 +0000
+++ dash/previews/GenericPreview.cpp 2012-11-23 23:52:20 +0000
@@ -24,7 +24,7 @@
24#include "unity-shared/PreviewStyle.h"24#include "unity-shared/PreviewStyle.h"
25#include "unity-shared/CoverArt.h"25#include "unity-shared/CoverArt.h"
26#include "unity-shared/StaticCairoText.h"26#include "unity-shared/StaticCairoText.h"
27#include "unity-shared/PlacesVScrollBar.h"27#include "unity-shared/PlacesOverlayVScrollBar.h"
28#include <NuxCore/Logger.h>28#include <NuxCore/Logger.h>
29#include <Nux/HLayout.h>29#include <Nux/HLayout.h>
30#include <Nux/VLayout.h>30#include <Nux/VLayout.h>
@@ -49,7 +49,7 @@
49 DetailsScrollView(NUX_FILE_LINE_PROTO)49 DetailsScrollView(NUX_FILE_LINE_PROTO)
50 : ScrollView(NUX_FILE_LINE_PARAM)50 : ScrollView(NUX_FILE_LINE_PARAM)
51 {51 {
52 SetVScrollBar(new dash::PlacesVScrollBar(NUX_TRACKER_LOCATION));52 SetVScrollBar(new dash::PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION));
53 }53 }
5454
55};55};
5656
=== modified file 'dash/previews/MoviePreview.cpp'
--- dash/previews/MoviePreview.cpp 2012-10-29 09:34:54 +0000
+++ dash/previews/MoviePreview.cpp 2012-11-23 23:52:20 +0000
@@ -24,7 +24,7 @@
24#include "unity-shared/PreviewStyle.h"24#include "unity-shared/PreviewStyle.h"
25#include "unity-shared/CoverArt.h"25#include "unity-shared/CoverArt.h"
26#include "unity-shared/StaticCairoText.h"26#include "unity-shared/StaticCairoText.h"
27#include "unity-shared/PlacesVScrollBar.h"27#include "unity-shared/PlacesOverlayVScrollBar.h"
28#include <UnityCore/MoviePreview.h>28#include <UnityCore/MoviePreview.h>
29#include <NuxCore/Logger.h>29#include <NuxCore/Logger.h>
30#include <Nux/HLayout.h>30#include <Nux/HLayout.h>
@@ -50,7 +50,7 @@
50 DetailsScrollView(NUX_FILE_LINE_PROTO)50 DetailsScrollView(NUX_FILE_LINE_PROTO)
51 : ScrollView(NUX_FILE_LINE_PARAM)51 : ScrollView(NUX_FILE_LINE_PARAM)
52 {52 {
53 SetVScrollBar(new dash::PlacesVScrollBar(NUX_TRACKER_LOCATION));53 SetVScrollBar(new dash::PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION));
54 }54 }
5555
56};56};
5757
=== modified file 'dash/previews/SocialPreview.cpp'
--- dash/previews/SocialPreview.cpp 2012-11-08 09:12:24 +0000
+++ dash/previews/SocialPreview.cpp 2012-11-23 23:52:20 +0000
@@ -25,7 +25,7 @@
25#include "unity-shared/CoverArt.h"25#include "unity-shared/CoverArt.h"
26#include "unity-shared/IconTexture.h"26#include "unity-shared/IconTexture.h"
27#include "unity-shared/StaticCairoText.h"27#include "unity-shared/StaticCairoText.h"
28#include "unity-shared/PlacesVScrollBar.h"28#include "unity-shared/PlacesOverlayVScrollBar.h"
29#include <UnityCore/SocialPreview.h>29#include <UnityCore/SocialPreview.h>
30#include <NuxCore/Logger.h>30#include <NuxCore/Logger.h>
31#include <Nux/HLayout.h>31#include <Nux/HLayout.h>
@@ -54,7 +54,7 @@
54 DetailsScrollView(NUX_FILE_LINE_PROTO)54 DetailsScrollView(NUX_FILE_LINE_PROTO)
55 : ScrollView(NUX_FILE_LINE_PARAM)55 : ScrollView(NUX_FILE_LINE_PARAM)
56 {56 {
57 SetVScrollBar(new dash::PlacesVScrollBar(NUX_TRACKER_LOCATION));57 SetVScrollBar(new dash::PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION));
58 }58 }
5959
60};60};
6161
=== modified file 'dash/previews/Tracks.cpp'
--- dash/previews/Tracks.cpp 2012-10-29 09:34:54 +0000
+++ dash/previews/Tracks.cpp 2012-11-23 23:52:20 +0000
@@ -24,7 +24,7 @@
24#include <NuxCore/Logger.h>24#include <NuxCore/Logger.h>
25#include <Nux/VLayout.h>25#include <Nux/VLayout.h>
26#include "unity-shared/IntrospectableWrappers.h"26#include "unity-shared/IntrospectableWrappers.h"
27#include "unity-shared/PlacesVScrollBar.h"27#include "unity-shared/PlacesOverlayVScrollBar.h"
28#include "unity-shared/PreviewStyle.h"28#include "unity-shared/PreviewStyle.h"
29#include <UnityCore/Track.h>29#include <UnityCore/Track.h>
30#include <UnityCore/Variant.h>30#include <UnityCore/Variant.h>
@@ -76,7 +76,7 @@
7676
77void Tracks::SetupViews()77void Tracks::SetupViews()
78{78{
79 SetVScrollBar(new dash::PlacesVScrollBar(NUX_TRACKER_LOCATION));79 SetVScrollBar(new dash::PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION));
80 EnableHorizontalScrollBar(false);80 EnableHorizontalScrollBar(false);
81 layout_ = new nux::VLayout();81 layout_ = new nux::VLayout();
82 layout_->SetPadding(0, previews::Style::Instance().GetDetailsRightMargin(), 0, 0);82 layout_->SetPadding(0, previews::Style::Instance().GetDetailsRightMargin(), 0, 0);
8383
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2012-11-22 10:08:38 +0000
+++ tests/CMakeLists.txt 2012-11-23 23:52:20 +0000
@@ -233,6 +233,7 @@
233 test_previews_movie.cpp233 test_previews_movie.cpp
234 test_previews_music.cpp234 test_previews_music.cpp
235 test_previews_social.cpp235 test_previews_social.cpp
236 test_overlay_scrollbar.cpp
236 test_quicklist_menu_item.cpp237 test_quicklist_menu_item.cpp
237 test_quicklist_view.cpp238 test_quicklist_view.cpp
238 test_resultviewgrid.cpp239 test_resultviewgrid.cpp
239240
=== added file 'tests/test_overlay_scrollbar.cpp'
--- tests/test_overlay_scrollbar.cpp 1970-01-01 00:00:00 +0000
+++ tests/test_overlay_scrollbar.cpp 2012-11-23 23:52:20 +0000
@@ -0,0 +1,280 @@
1/*
2 * Copyright 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the applicable version of the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of both the GNU Lesser General Public
15 * License version 3 along with this program. If not, see
16 * <http://www.gnu.org/licenses/>
17 *
18 * Authored by: Brandon Schaefer <brandon.schaefer@canonical.com>
19 *
20 */
21
22#include <gtest/gtest.h>
23
24#include <Nux/Nux.h>
25#include <NuxCore/ObjectPtr.h>
26#include <Nux/VLayout.h>
27
28#include "unity-shared/VScrollBarOverlayWindow.h"
29#include "unity-shared/PlacesOverlayVScrollBar.h"
30#include "unity-shared/UScreen.h"
31
32using namespace testing;
33
34namespace
35{
36
37class TestOverlayWindow : public Test
38{
39public:
40 TestOverlayWindow()
41 {
42 overlay_window_ = new VScrollBarOverlayWindow(nux::Geometry(0,0,100,100));
43 }
44
45 int GetProxListSize() const
46 {
47 return nux::GetWindowThread()->GetWindowCompositor().GetProximityListSize();
48 }
49
50 nux::ObjectPtr<VScrollBarOverlayWindow> overlay_window_;
51};
52
53class TestOverlayScrollBar : public Test
54{
55public:
56 class MockScrollBar : public unity::dash::PlacesOverlayVScrollBar
57 {
58 public:
59 MockScrollBar(NUX_FILE_LINE_DECL)
60 : unity::dash::PlacesOverlayVScrollBar(NUX_FILE_LINE_PARAM)
61 , scroll_dy(0)
62 , scroll_up_signal_(false)
63 , scroll_down_signal_(false)
64 {
65 SetGeometry(nux::Geometry(0,0,200,500));
66 SetContainerSize(0,0,200,200);
67 SetContentSize(0,0,200,2000);
68 ComputeContentSize();
69
70 OnScrollUp.connect([&] (float step, int dy) {
71 scroll_dy = dy;
72 scroll_up_signal_ = true;
73 });
74
75 OnScrollDown.connect([&] (float step, int dy) {
76 scroll_dy = dy;
77 scroll_down_signal_ = true;
78 });
79 }
80
81 void ScrollDown(int scroll_dy)
82 {
83 // Shows we are over the Overlay Thumb
84 int x = _track->GetBaseX() + _track->GetBaseWidth() + 5;
85 int y = _track->GetBaseY();
86
87 MoveMouse(x,y);
88 MoveDown(x,y);
89
90 MoveMouse(x,y+scroll_dy);
91 MoveUp(x,y+scroll_dy);
92 }
93
94 void ScrollUp(int scroll_dy)
95 {
96 ScrollDown(scroll_dy);
97
98 // Shows we are over the Overlay Thumb
99 int x = _track->GetBaseX() + _track->GetBaseWidth() + 5;
100 int y = _track->GetBaseY();
101
102 MoveMouse(x,y+scroll_dy);
103 MoveDown(x,y+scroll_dy);
104
105 MoveMouse(x,y);
106 MoveUp(x,y);
107 }
108
109 void MoveDown(int x, int y)
110 {
111 nux::Event event;
112 event.type = nux::NUX_MOUSE_PRESSED;
113 event.x = x;
114 event.y = y;
115 nux::GetWindowCompositor().ProcessEvent(event);
116 }
117
118 void MoveUp(int x, int y)
119 {
120 nux::Event event;
121 event.type = nux::NUX_MOUSE_RELEASED;
122 event.x = x;
123 event.y = y;
124 nux::GetWindowCompositor().ProcessEvent(event);
125 }
126
127 void MoveMouse(int x, int y)
128 {
129 nux::Event event;
130 event.type = nux::NUX_MOUSE_MOVE;
131 event.x = x;
132 event.y = y;
133 nux::GetWindowCompositor().ProcessEvent(event);
134 }
135
136 using nux::VScrollBar::AtMinimum;
137 using nux::VScrollBar::GetBaseHeight;
138
139 int scroll_dy;
140 bool scroll_up_signal_;
141 bool scroll_down_signal_;
142 };
143
144 TestOverlayScrollBar()
145 {
146 scroll_bar_ = std::make_shared<MockScrollBar>(NUX_TRACKER_LOCATION);
147 }
148
149 std::shared_ptr<MockScrollBar> scroll_bar_;
150};
151
152TEST_F(TestOverlayWindow, TestOverlayShows)
153{
154 overlay_window_->MouseNear();
155 EXPECT_TRUE(overlay_window_->IsVisible());
156}
157
158TEST_F(TestOverlayWindow, TestOverlayHides)
159{
160 overlay_window_->MouseNear();
161 EXPECT_TRUE(overlay_window_->IsVisible());
162
163 overlay_window_->MouseBeyond();
164 EXPECT_FALSE(overlay_window_->IsVisible());
165}
166
167TEST_F(TestOverlayWindow, TestOverlayStaysOpenWhenMouseDown)
168{
169 overlay_window_->MouseNear();
170 overlay_window_->MouseDown();
171
172 overlay_window_->MouseBeyond();
173 EXPECT_TRUE(overlay_window_->IsVisible());
174}
175
176TEST_F(TestOverlayWindow, TestOverlayMouseDrags)
177{
178 overlay_window_->MouseDown();
179 EXPECT_FALSE(overlay_window_->IsMouseBeingDragged());
180
181 overlay_window_->SetThumbOffsetY(10);
182 EXPECT_TRUE(overlay_window_->IsMouseBeingDragged());
183}
184
185TEST_F(TestOverlayWindow, TestOverlayStopDraggingOnMouseUp)
186{
187 overlay_window_->MouseDown();
188 EXPECT_FALSE(overlay_window_->IsMouseBeingDragged());
189
190 overlay_window_->SetThumbOffsetY(10);
191 EXPECT_TRUE(overlay_window_->IsMouseBeingDragged());
192
193 overlay_window_->MouseUp();
194 EXPECT_FALSE(overlay_window_->IsMouseBeingDragged());
195}
196
197TEST_F(TestOverlayWindow, TestOverlaySetsOffsetY)
198{
199 int const offset_y = 30;
200
201 overlay_window_->SetThumbOffsetY(offset_y);
202 EXPECT_EQ(overlay_window_->GetThumbOffsetY(), offset_y);
203}
204
205TEST_F(TestOverlayWindow, TestOverlaySetsOffsetYOutOfBoundsLower)
206{
207 int const offset_y = -40;
208
209 overlay_window_->SetThumbOffsetY(offset_y);
210 EXPECT_EQ(overlay_window_->GetThumbOffsetY(), 0);
211}
212
213TEST_F(TestOverlayWindow, TestOverlaySetsOffsetYOutOfBoundsUpper)
214{
215 int const offset_y = 1000;
216 int const expected_offset = overlay_window_->GetBaseHeight() - overlay_window_->GetThumbHeight();
217
218 overlay_window_->SetThumbOffsetY(offset_y);
219 EXPECT_EQ(overlay_window_->GetThumbOffsetY(), expected_offset);
220}
221
222TEST_F(TestOverlayWindow, TestOverlayMouseIsInsideThumb)
223{
224 nux::Geometry const geo(0, 50, 50, 400);
225
226 overlay_window_->UpdateGeometry(geo);
227 EXPECT_TRUE(overlay_window_->IsMouseInsideThumb(0));
228}
229
230TEST_F(TestOverlayWindow, TestOverlayMouseIsInsideOnOffsetChange)
231{
232 nux::Geometry const geo(0, 50, 50, 400);
233 int const offset_y = 50;
234 int const thumb_height = overlay_window_->GetThumbHeight();
235
236 overlay_window_->UpdateGeometry(geo);
237 overlay_window_->SetThumbOffsetY(offset_y);
238
239 EXPECT_FALSE(overlay_window_->IsMouseInsideThumb(offset_y - 1));
240 EXPECT_TRUE(overlay_window_->IsMouseInsideThumb(offset_y + thumb_height/2));
241 EXPECT_FALSE(overlay_window_->IsMouseInsideThumb(offset_y + thumb_height + 1));
242}
243
244TEST_F(TestOverlayScrollBar, TestScrollDownSignal)
245{
246 scroll_bar_->ScrollDown(10);
247 EXPECT_TRUE(scroll_bar_->scroll_down_signal_);
248}
249
250TEST_F(TestOverlayScrollBar, TestScrollUpSignal)
251{
252 scroll_bar_->ScrollUp(10);
253 EXPECT_TRUE(scroll_bar_->scroll_up_signal_);
254}
255
256TEST_F(TestOverlayScrollBar, TestScrollDownDeltaY)
257{
258 int scroll_down = 15;
259 scroll_bar_->ScrollDown(scroll_down);
260 EXPECT_EQ(scroll_bar_->scroll_dy, scroll_down);
261}
262
263TEST_F(TestOverlayScrollBar, TestScrollUpDeltaY)
264{
265 int scroll_up = 7;
266 scroll_bar_->ScrollUp(scroll_up);
267 EXPECT_EQ(scroll_bar_->scroll_dy, scroll_up);
268}
269
270TEST_F(TestOverlayScrollBar, TestScrollsSlowlyDeltaY)
271{
272 int scroll_down = 10;
273 for (int i = 0; i < scroll_down; i++)
274 {
275 scroll_bar_->ScrollDown(1);
276 EXPECT_EQ(scroll_bar_->scroll_dy, 1);
277 }
278}
279
280}
0281
=== modified file 'unity-shared/CMakeLists.txt'
--- unity-shared/CMakeLists.txt 2012-11-15 18:44:55 +0000
+++ unity-shared/CMakeLists.txt 2012-11-23 23:52:20 +0000
@@ -49,6 +49,7 @@
49 OverlayRenderer.cpp49 OverlayRenderer.cpp
50 PanelStyle.cpp50 PanelStyle.cpp
51 PlacesVScrollBar.cpp51 PlacesVScrollBar.cpp
52 PlacesOverlayVScrollBar.cpp
52 PreviewStyle.cpp53 PreviewStyle.cpp
53 RatingsButton.cpp54 RatingsButton.cpp
54 SearchBar.cpp55 SearchBar.cpp
@@ -66,6 +67,7 @@
66 UnityWindowStyle.cpp67 UnityWindowStyle.cpp
67 UnityWindowView.cpp68 UnityWindowView.cpp
68 UserThumbnailProvider.cpp69 UserThumbnailProvider.cpp
70 VScrollBarOverlayWindow.cpp
69 WindowManager.cpp71 WindowManager.cpp
70 XPathQueryPart.cpp72 XPathQueryPart.cpp
71)73)
7274
=== added file 'unity-shared/PlacesOverlayVScrollBar.cpp'
--- unity-shared/PlacesOverlayVScrollBar.cpp 1970-01-01 00:00:00 +0000
+++ unity-shared/PlacesOverlayVScrollBar.cpp 2012-11-23 23:52:20 +0000
@@ -0,0 +1,417 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2012 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: Brandon Schaefer <brandon.schaefer@canonical.com>
18 */
19
20#include <Nux/Nux.h>
21
22#include "PlacesOverlayVScrollBar.h"
23#include "CairoTexture.h"
24
25namespace
26{
27 int const PROXIMITY = 7;
28 int const SCROLL_ANIMATION = 400;
29 int const MAX_CONNECTOR_ANIMATION = 200;
30}
31
32namespace unity
33{
34namespace dash
35{
36
37PlacesOverlayVScrollBar::PlacesOverlayVScrollBar(NUX_FILE_LINE_DECL)
38 : PlacesVScrollBar(NUX_FILE_LINE_PARAM)
39 , overlay_window_(new VScrollBarOverlayWindow(_track->GetAbsoluteGeometry()))
40 , area_prox_(overlay_window_.GetPointer(), PROXIMITY)
41 , thumb_above_slider_(false)
42 , connector_height_(0)
43 , mouse_down_offset_(0)
44 , delta_update_(0)
45{
46 area_prox_.mouse_near.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseNear));
47 area_prox_.mouse_beyond.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseBeyond));
48
49 overlay_window_->mouse_down.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseDown));
50 overlay_window_->mouse_up.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseUp));
51 overlay_window_->mouse_click.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseClick));
52 overlay_window_->mouse_move.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseMove));
53 overlay_window_->mouse_drag.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnMouseDrag));
54
55 _track->geometry_changed.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnTrackGeometryChanged));
56 OnVisibleChanged.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnVisibilityChanged));
57}
58
59void PlacesOverlayVScrollBar::OnTrackGeometryChanged(nux::Area* /*area*/, nux::Geometry& /*geo*/)
60{
61 UpdateStepY();
62 overlay_window_->UpdateGeometry(_track->GetAbsoluteGeometry());
63
64 if (overlay_window_->IsVisible() && !IsScrollBarVisible())
65 {
66 overlay_window_->ResetStates();
67 ResetConnector();
68 }
69}
70
71void PlacesOverlayVScrollBar::OnVisibilityChanged(nux::Area* /*area*/, bool visible)
72{
73 if (overlay_window_->IsVisible() && !visible)
74 {
75 overlay_window_->ResetStates();
76 ResetConnector();
77 }
78}
79
80void PlacesOverlayVScrollBar::StopAnimation()
81{
82 if (animation_.CurrentState() != nux::animation::Animation::State::Stopped)
83 animation_.Stop();
84}
85
86void PlacesOverlayVScrollBar::SetupAnimation(int start, int stop, int milliseconds)
87{
88 tweening_connection_.disconnect();
89 delta_update_ = 0;
90
91 animation_.SetDuration(milliseconds);
92 animation_.SetEasingCurve(nux::animation::EasingCurve(nux::animation::EasingCurve::Type::Linear));
93
94 animation_.SetStartValue(start);
95 animation_.SetFinishValue(stop);
96}
97
98void PlacesOverlayVScrollBar::StartScrollAnimation(ScrollDir dir, int stop)
99{
100 if (animation_.CurrentState() == nux::animation::Animation::State::Stopped)
101 {
102 SetupAnimation(0, stop, SCROLL_ANIMATION);
103
104 tweening_connection_ = animation_.updated.connect([this, dir] (int const& update) {
105 OnScroll(dir, update - delta_update_);
106 delta_update_ = update;
107
108 CheckIfThumbIsInsideSlider();
109 UpdateConnectorPosition();
110 QueueDraw();
111 });
112
113 animation_.Start();
114 }
115}
116
117void PlacesOverlayVScrollBar::OnScroll(ScrollDir dir, int mouse_dy)
118{
119 if (dir == ScrollDir::UP)
120 OnScrollUp.emit(stepY, mouse_dy);
121 else if (dir == ScrollDir::DOWN)
122 OnScrollDown.emit(stepY, mouse_dy);
123}
124
125void PlacesOverlayVScrollBar::StartConnectorAnimation()
126{
127 if (animation_.CurrentState() == nux::animation::Animation::State::Stopped)
128 {
129 SetupAnimation(connector_height_, 0, std::min(connector_height_, MAX_CONNECTOR_ANIMATION));
130
131 tweening_connection_ = animation_.updated.connect([this] (int const& update) {
132 connector_height_ = update;
133 UpdateConnectorTexture();
134 });
135
136 animation_.Start();
137 }
138}
139
140bool PlacesOverlayVScrollBar::IsScrollBarVisible() const
141{
142 return (content_height_ > container_height_);
143}
144
145void PlacesOverlayVScrollBar::OnMouseNear(nux::Point const& mouse_pos)
146{
147 if (IsVisible() && IsScrollBarVisible())
148 {
149 StopAnimation();
150
151 overlay_window_->MouseNear();
152 AdjustThumbOffsetFromMouse();
153 }
154}
155
156void PlacesOverlayVScrollBar::OnMouseBeyond(nux::Point const& mouse_pos)
157{
158 if (IsVisible() && IsScrollBarVisible())
159 {
160 overlay_window_->MouseBeyond();
161 UpdateConnectorPosition();
162 }
163}
164
165void PlacesOverlayVScrollBar::AdjustThumbOffsetFromMouse()
166{
167 if (!overlay_window_->IsMouseBeingDragged())
168 {
169 nux::Point const& mouse = nux::GetWindowCompositor().GetMousePosition();
170
171 if (mouse.y > 0)
172 {
173 int const quarter_of_thumb = overlay_window_->GetThumbHeight()/4;
174 int const new_offset = mouse.y - _track->GetAbsoluteY() - overlay_window_->GetThumbHeight()/2;
175
176 int const slider_offset = _slider->GetAbsoluteY() - _track->GetAbsoluteY() + _slider->GetBaseHeight()/3;
177 bool const mouse_above_slider = slider_offset < new_offset;
178
179 if (mouse_above_slider)
180 overlay_window_->SetThumbOffsetY(new_offset - quarter_of_thumb);
181 else
182 overlay_window_->SetThumbOffsetY(new_offset + quarter_of_thumb);
183 }
184
185 CheckIfThumbIsInsideSlider();
186 }
187}
188
189void PlacesOverlayVScrollBar::CheckIfThumbIsInsideSlider()
190{
191 nux::Geometry const& slider_geo = _slider->GetAbsoluteGeometry();
192 nux::Geometry const& thumb_geo = overlay_window_->GetThumbGeometry();
193 nux::Geometry const& intersection = (thumb_geo.Intersect(slider_geo));
194
195 if (!intersection.IsNull())
196 {
197 ResetConnector();
198 overlay_window_->ThumbInsideSlider();
199 }
200 else
201 {
202 UpdateConnectorPosition();
203 overlay_window_->ThumbOutsideSlider();
204 }
205}
206
207void PlacesOverlayVScrollBar::UpdateConnectorPosition()
208{
209 int const slider_y = _slider->GetBaseY() - GetBaseY();
210 int const thumb_y = overlay_window_->GetThumbOffsetY();
211 int const thumb_height = overlay_window_->GetThumbHeight();
212
213 if (!overlay_window_->IsVisible())
214 {
215 ResetConnector();
216 }
217 else if (slider_y > thumb_y)
218 {
219 thumb_above_slider_ = true;
220 connector_height_ = slider_y - (thumb_y + thumb_height);
221 }
222 else
223 {
224 thumb_above_slider_ = false;
225 connector_height_ = thumb_y - (_slider->GetBaseY() + _slider->GetBaseHeight()) + _track->GetBaseY();
226 }
227
228 UpdateConnectorTexture();
229}
230
231void PlacesOverlayVScrollBar::ResetConnector()
232{
233 StartConnectorAnimation();
234 QueueDraw();
235}
236
237void PlacesOverlayVScrollBar::OnMouseClick(int /*x*/, int y, unsigned int button_flags, unsigned int /*key_flags*/)
238{
239 if (!overlay_window_->IsMouseBeingDragged())
240 {
241 int const button = nux::GetEventButton(button_flags);
242
243 if (button == 1)
244 LeftMouseClick(y);
245 else if (button == 2)
246 MiddleMouseClick(y);
247 }
248
249 overlay_window_->MouseUp();
250}
251
252void PlacesOverlayVScrollBar::LeftMouseClick(int y)
253{
254 if (IsMouseInTopHalfOfThumb(y))
255 {
256 int const top = _slider->GetBaseY() - _track->GetBaseY();
257 StartScrollAnimation(ScrollDir::UP, std::min(_slider->GetBaseHeight(), top));
258 }
259 else
260 {
261 int const bottom = (_track->GetBaseY() + _track->GetBaseHeight()) -
262 (_slider->GetBaseHeight() + _slider->GetBaseY());
263 StartScrollAnimation(ScrollDir::DOWN, std::min(_slider->GetBaseHeight(), bottom));
264 }
265
266 UpdateConnectorPosition();
267}
268
269void PlacesOverlayVScrollBar::MiddleMouseClick(int y)
270{
271 int const slider_offset = _slider->GetBaseY() - _track->GetBaseY();
272 bool const move_up = slider_offset > overlay_window_->GetThumbOffsetY();
273
274 int const slider_thumb_diff = abs(overlay_window_->GetThumbOffsetY() - slider_offset);
275
276 if (move_up)
277 StartScrollAnimation(ScrollDir::UP, slider_thumb_diff);
278 else
279 StartScrollAnimation(ScrollDir::DOWN, slider_thumb_diff);
280}
281
282void PlacesOverlayVScrollBar::OnMouseDown(int /*x*/, int y, unsigned int /*button_flags*/, unsigned int /*key_flags*/)
283{
284 if (overlay_window_->IsMouseInsideThumb(y))
285 {
286 if (IsMouseInTopHalfOfThumb(y))
287 overlay_window_->PageUpAction();
288 else
289 overlay_window_->PageDownAction();
290
291 mouse_down_offset_ = y - overlay_window_->GetThumbOffsetY();
292 overlay_window_->MouseDown();
293 }
294}
295
296bool PlacesOverlayVScrollBar::IsMouseInTopHalfOfThumb(int y)
297{
298 int const thumb_height = overlay_window_->GetThumbHeight();
299 int const thumb_offset_y = overlay_window_->GetThumbOffsetY();
300
301 return (y < (thumb_height/2 + thumb_offset_y));
302}
303
304void PlacesOverlayVScrollBar::OnMouseUp(int x, int y, unsigned int /*button_flags*/, unsigned int /*key_flags*/)
305{
306 nux::Geometry const& geo = overlay_window_->GetAbsoluteGeometry();
307
308 if (!geo.IsPointInside(x + geo.x, y + geo.y))
309 {
310 overlay_window_->MouseUp();
311 UpdateConnectorPosition();
312 }
313}
314
315void PlacesOverlayVScrollBar::OnMouseMove(int /*x*/, int y, int /*dx*/, int /*dy*/, unsigned int /*button_flags*/, unsigned int /*key_flags*/)
316{
317 if (!overlay_window_->IsMouseInsideThumb(y))
318 AdjustThumbOffsetFromMouse();
319}
320
321void PlacesOverlayVScrollBar::OnMouseDrag(int /*x*/, int y, int /*dx*/, int dy, unsigned int /*button_flags*/, unsigned int /*key_flags*/)
322{
323 StopAnimation();
324 MouseDraggingOverlay(y, dy);
325}
326
327void PlacesOverlayVScrollBar::MouseDraggingOverlay(int y, int dys)
328{
329 int const dy = y - overlay_window_->GetThumbOffsetY() - mouse_down_offset_;
330 int const at_min = overlay_window_->GetThumbOffsetY() <= 0;
331 int const at_max = overlay_window_->GetThumbOffsetY() + overlay_window_->GetThumbHeight() >= _track->GetBaseHeight();
332
333 if (dy < 0 && !at_min)
334 {
335 OnScrollUp.emit(stepY, abs(dy));
336 }
337 else if (dy > 0 && !at_max)
338 {
339 OnScrollDown.emit(stepY, dy);
340 }
341
342 overlay_window_->SetThumbOffsetY(y - mouse_down_offset_);
343 CheckIfThumbIsInsideSlider();
344}
345
346void PlacesOverlayVScrollBar::UpdateStepY()
347{
348 stepY = (float) (content_height_ - container_height_) / (float) (_track->GetBaseHeight() - _slider->GetBaseHeight());
349}
350
351void PlacesOverlayVScrollBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
352{
353 PlacesVScrollBar::Draw(graphics_engine, force_draw);
354
355 if (connector_height_ > 0 && connector_texture_.IsValid())
356 {
357 int const connector_width = GetBaseWidth();
358 int offset_y = 0;
359 if (thumb_above_slider_)
360 {
361 offset_y = _slider->GetBaseY() - connector_height_;
362 }
363 else
364 {
365 offset_y = _slider->GetBaseY() + _slider->GetBaseHeight();
366 }
367
368 nux::Geometry base(_track->GetBaseX(), offset_y - 4, connector_width, connector_height_ + 5);
369 nux::TexCoordXForm texxform;
370
371 graphics_engine.QRP_1Tex(base.x,
372 base.y,
373 base.width,
374 base.height,
375 connector_texture_->GetDeviceTexture(),
376 texxform,
377 nux::color::White);
378 }
379}
380
381void PlacesOverlayVScrollBar::UpdateConnectorTexture()
382{
383 if (connector_height_ < 0)
384 return;
385
386 int width = 3;
387 int height = connector_height_;
388 float const radius = 1.5f;
389 float const aspect = 1.0f;
390
391 cairo_t* cr = NULL;
392
393 nux::color::RedGreenBlue const& connector_bg = nux::color::Gray;
394
395 nux::CairoGraphics cairoGraphics(CAIRO_FORMAT_ARGB32, width, height);
396 cr = cairoGraphics.GetContext();
397 cairo_save(cr);
398
399 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
400 cairo_paint(cr);
401
402 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
403 cairo_save(cr);
404
405 cairo_set_source_rgba(cr, connector_bg.red, connector_bg.green, connector_bg.blue, 0.8);
406 cairoGraphics.DrawRoundedRectangle(cr, aspect, 0.0f, 0.0f, radius, width, height);
407 cairo_fill_preserve(cr);
408
409 connector_texture_.Adopt(texture_from_cairo_graphics(cairoGraphics));
410 cairo_destroy(cr);
411
412 QueueDraw();
413}
414
415} // namespace dash
416} // namespace unity
417
0418
=== added file 'unity-shared/PlacesOverlayVScrollBar.h'
--- unity-shared/PlacesOverlayVScrollBar.h 1970-01-01 00:00:00 +0000
+++ unity-shared/PlacesOverlayVScrollBar.h 2012-11-23 23:52:20 +0000
@@ -0,0 +1,107 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2012 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: Brandon Schaefer <brandon.schaefer@canonical.com>
18 */
19
20#ifndef PLACES_OVERLAY_VSCROLLBAR_H
21#define PLACES_OVERLAY_VSCROLLBAR_H
22
23#include <Nux/Nux.h>
24#include <Nux/InputAreaProximity.h>
25#include <NuxCore/Animation.h>
26#include <memory>
27
28#include "unity-shared/PlacesVScrollBar.h"
29#include "unity-shared/VScrollBarOverlayWindow.h"
30
31namespace unity
32{
33namespace dash
34{
35
36class PlacesOverlayVScrollBar: public PlacesVScrollBar
37{
38public:
39 PlacesOverlayVScrollBar(NUX_FILE_LINE_PROTO);
40
41protected:
42 void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw);
43
44private:
45 enum class ScrollDir : unsigned int
46 {
47 UP,
48 DOWN,
49 };
50
51 void OnTrackGeometryChanged(nux::Area* area, nux::Geometry& geo);
52 void OnVisibilityChanged(nux::Area* area, bool visible);
53
54 void OnMouseNear(nux::Point const& mouse_pos);
55 void OnMouseBeyond(nux::Point const& mouse_pos);
56 void AdjustThumbOffsetFromMouse();
57
58 void OnMouseClick(int x, int y, unsigned int button_flags, unsigned int key_flags);
59 void LeftMouseClick(int y);
60 void MiddleMouseClick(int y);
61
62 void OnMouseDown(int x, int y, unsigned int button_flags, unsigned int key_flags);
63 void OnMouseUp(int x, int y, unsigned int button_flags, unsigned int key_flags);
64
65 void OnMouseMove(int x, int y, int dx, int dy, unsigned int button_flags, unsigned int key_flags);
66
67 void OnMouseDrag(int x, int y, int dx, int dy, unsigned int button_flags, unsigned int key_flags);
68 void MouseDraggingOverlay(int y, int dy);
69
70 bool IsMouseInTopHalfOfThumb(int y);
71 void CheckIfThumbIsInsideSlider();
72
73 bool IsScrollBarVisible() const;
74
75 void UpdateConnectorPosition();
76 void ResetConnector();
77
78 void UpdateStepY();
79
80 void SetupAnimation(int start, int stop, int milliseconds);
81 void StopAnimation();
82
83 void StartScrollAnimation(ScrollDir dir, int stop);
84 void OnScroll(ScrollDir dir, int mouse_dy);
85
86 void StartConnectorAnimation();
87
88 void UpdateConnectorTexture();
89
90 nux::ObjectPtr<VScrollBarOverlayWindow> overlay_window_;
91 nux::InputAreaProximity area_prox_;
92
93 nux::animation::AnimateValue<int> animation_;
94 sigc::connection tweening_connection_;
95
96 nux::ObjectPtr<nux::BaseTexture> connector_texture_;
97
98 bool thumb_above_slider_;
99 int connector_height_;
100 int mouse_down_offset_;
101 int delta_update_;
102};
103
104} // namespace dash
105} // namespace unity
106
107#endif // PLACES_OVERLAY_VSCROLLBAR_H
0108
=== added file 'unity-shared/VScrollBarOverlayWindow.cpp'
--- unity-shared/VScrollBarOverlayWindow.cpp 1970-01-01 00:00:00 +0000
+++ unity-shared/VScrollBarOverlayWindow.cpp 2012-11-23 23:52:20 +0000
@@ -0,0 +1,526 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2012 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: Brandon Schaefer <brandon.schaefer@canonical.com>
18 */
19
20#include <Nux/Nux.h>
21#include <NuxGraphics/CairoGraphics.h>
22
23#include "VScrollBarOverlayWindow.h"
24#include "UScreen.h"
25#include "DashStyle.h"
26#include "CairoTexture.h"
27
28namespace
29{
30 int const THUMB_WIDTH = 21;
31 int const THUMB_HEIGHT = 68;
32 int const THUMB_RADIUS = 3;
33}
34
35
36VScrollBarOverlayWindow::VScrollBarOverlayWindow(nux::Geometry const& geo)
37 : nux::BaseWindow("")
38 , content_size_(geo)
39 , content_offset_x_(0)
40 , mouse_offset_y_(0)
41 , mouse_down_(false)
42 , mouse_near_(false)
43 , inside_slider_(false)
44 , current_action_(ThumbAction::NONE)
45{
46 Area::SetGeometry(content_size_.x, content_size_.y, THUMB_WIDTH, content_size_.height);
47 SetBackgroundColor(nux::color::Transparent);
48
49 UpdateTexture();
50}
51
52void VScrollBarOverlayWindow::UpdateGeometry(nux::Geometry const& geo)
53{
54 if (content_size_.x != geo.x ||
55 content_size_.y != geo.y ||
56 content_size_.height != geo.height)
57 {
58 content_size_ = geo;
59 UpdateMouseOffsetX();
60
61 Area::SetGeometry(content_size_.x + content_offset_x_, content_size_.y, THUMB_WIDTH, content_size_.height);
62 }
63}
64
65void VScrollBarOverlayWindow::SetThumbOffsetY(int y)
66{
67 int const new_offset = GetValidOffsetYValue(y);
68
69 if (new_offset != mouse_offset_y_)
70 {
71 if (mouse_down_)
72 MouseDragging();
73
74 mouse_offset_y_ = new_offset;
75 QueueDraw();
76 }
77}
78
79int VScrollBarOverlayWindow::GetValidOffsetYValue(int new_offset) const
80{
81 if (new_offset < 0)
82 return 0;
83 else if (new_offset > content_size_.height - THUMB_HEIGHT)
84 return content_size_.height - THUMB_HEIGHT;
85
86 return new_offset;
87}
88
89void VScrollBarOverlayWindow::UpdateMouseOffsetX()
90{
91 int monitor = unity::UScreen::GetDefault()->GetMonitorWithMouse();
92 nux::Geometry const& geo = unity::UScreen::GetDefault()->GetMonitorGeometry(monitor);
93
94 if (content_size_.x + THUMB_WIDTH > geo.x + geo.width)
95 content_offset_x_ = geo.x + geo.width - (content_size_.x + THUMB_WIDTH);
96 else
97 content_offset_x_ = 0;
98}
99
100bool VScrollBarOverlayWindow::IsMouseInsideThumb(int y) const
101{
102 nux::Geometry const thumb(0, mouse_offset_y_, THUMB_WIDTH, THUMB_HEIGHT);
103 return thumb.IsPointInside(0,y);
104}
105
106bool VScrollBarOverlayWindow::IsMouseBeingDragged() const
107{
108 return current_action_ == ThumbAction::DRAGGING;
109}
110
111int VScrollBarOverlayWindow::GetThumbHeight() const
112{
113 return THUMB_HEIGHT;
114}
115
116int VScrollBarOverlayWindow::GetThumbOffsetY() const
117{
118 return mouse_offset_y_;
119}
120
121nux::Geometry VScrollBarOverlayWindow::GetThumbGeometry() const
122{
123 return nux::Geometry(content_size_.x + content_offset_x_,
124 content_size_.y + mouse_offset_y_,
125 THUMB_WIDTH, THUMB_HEIGHT);
126}
127
128void VScrollBarOverlayWindow::MouseDown()
129{
130 mouse_down_ = true;
131 UpdateTexture();
132}
133
134void VScrollBarOverlayWindow::MouseUp()
135{
136 mouse_down_ = false;
137 current_action_ = ThumbAction::NONE;
138 UpdateTexture();
139 ShouldHide();
140}
141
142void VScrollBarOverlayWindow::MouseNear()
143{
144 mouse_near_ = true;
145 ShouldShow();
146}
147
148void VScrollBarOverlayWindow::MouseBeyond()
149{
150 mouse_near_ = false;
151 ShouldHide();
152}
153
154void VScrollBarOverlayWindow::ThumbInsideSlider()
155{
156 if (!inside_slider_)
157 {
158 inside_slider_ = true;
159 UpdateTexture();
160 }
161}
162
163void VScrollBarOverlayWindow::ThumbOutsideSlider()
164{
165 if (inside_slider_)
166 {
167 inside_slider_ = false;
168 UpdateTexture();
169 }
170}
171
172void VScrollBarOverlayWindow::PageUpAction()
173{
174 current_action_ = ThumbAction::PAGE_UP;
175 UpdateTexture();
176}
177
178void VScrollBarOverlayWindow::PageDownAction()
179{
180 current_action_ = ThumbAction::PAGE_DOWN;
181 UpdateTexture();
182}
183
184void VScrollBarOverlayWindow::MouseDragging()
185{
186 if (current_action_ != ThumbAction::DRAGGING)
187 {
188 current_action_ = ThumbAction::DRAGGING;
189 UpdateTexture();
190 }
191}
192
193void VScrollBarOverlayWindow::ShouldShow()
194{
195 if (!IsVisible())
196 {
197 if (mouse_down_ || mouse_near_)
198 {
199 ShowWindow(true);
200 PushToFront();
201 QueueDraw();
202 }
203 }
204}
205
206void VScrollBarOverlayWindow::ShouldHide()
207{
208 if (IsVisible())
209 {
210 if (!mouse_down_ && !mouse_near_)
211 {
212 ShowWindow(false);
213 QueueDraw();
214 }
215 }
216}
217
218void VScrollBarOverlayWindow::ResetStates()
219{
220 mouse_down_ = false;
221 mouse_near_ = false;
222 current_action_ = ThumbAction::NONE;
223 ShouldHide();
224}
225
226void VScrollBarOverlayWindow::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
227{
228 if (!thumb_texture_)
229 return;
230
231 nux::Geometry base(0, mouse_offset_y_, THUMB_WIDTH, THUMB_HEIGHT);
232 nux::TexCoordXForm texxform;
233
234 graphics_engine.QRP_1Tex(base.x,
235 base.y,
236 base.width,
237 base.height,
238 thumb_texture_->GetDeviceTexture(),
239 texxform,
240 nux::color::White);
241}
242
243nux::color::RedGreenBlue ProduceColorShade(nux::color::RedGreenBlue const& rgb, float shade)
244{
245 if (shade == 1.0f)
246 return rgb;
247
248 nux::color::HueLightnessSaturation hls(rgb);
249
250 hls.lightness *= shade;
251 if (hls.lightness > 1.0f)
252 hls.lightness = 1.0f;
253 else if (hls.lightness < 0.0f)
254 hls.lightness = 0.0f;
255
256 hls.saturation *= shade;
257 if (hls.saturation > 1.0f)
258 hls.saturation = 1.0f;
259 else if (hls.saturation < 0.0f)
260 hls.saturation = 0.0f;
261
262 nux::color::RedGreenBlue rgb_shade(hls);
263
264 return rgb_shade;
265}
266
267void PatternAddRGBStop(cairo_pattern_t* pat, nux::color::RedGreenBlue const& rgb, double stop, float alpha)
268{
269 cairo_pattern_add_color_stop_rgba (pat, stop, rgb.red, rgb.green, rgb.blue, alpha);
270}
271
272void SetSourceRGB(cairo_t* cr, nux::color::RedGreenBlue const& rgb, float alpha)
273{
274 cairo_set_source_rgba(cr, rgb.red, rgb.green, rgb.blue, alpha);
275}
276
277void DrawGrip (cairo_t* cr, double x, double y, int nx, int ny)
278{
279 gint lx, ly;
280
281 for (ly = 0; ly < ny; ly++)
282 {
283 for (lx = 0; lx < nx; lx++)
284 {
285 gint sx = lx * 3;
286 gint sy = ly * 3;
287
288 cairo_rectangle (cr, x + sx, y + sy, 1, 1);
289 }
290 }
291}
292
293void DrawBothGrips(cairo_t* cr, nux::color::RedGreenBlue const& rgb, int width, int height)
294{
295 int const grip_width = 5;
296 int const grip_height = 6;
297 float const grip_y = 13.5;
298 float const offset = 6.5;
299
300 cairo_pattern_t* pat;
301 pat = cairo_pattern_create_linear(0, 0, 0, height);
302
303 PatternAddRGBStop(pat, rgb, 0.0, 0.0);
304 PatternAddRGBStop(pat, rgb, 0.49, 0.5);
305 PatternAddRGBStop(pat, rgb, 0.49, 0.5);
306 PatternAddRGBStop(pat, rgb, 1.0, 0.0);
307
308 cairo_set_source(cr, pat);
309 cairo_pattern_destroy(pat);
310
311 DrawGrip(cr, width/2 - offset, grip_y, grip_width, grip_height);
312 DrawGrip(cr, width/2 - offset, height/2 + (grip_y - 10), grip_width, grip_height);
313
314 cairo_fill(cr);
315}
316
317void DrawLineSeperator(cairo_t* cr, nux::color::RedGreenBlue const& top,
318 nux::color::RedGreenBlue const& bottom, int width, int height)
319{
320 int const offset = 1.5;
321
322 // Top
323 cairo_move_to(cr, offset, height/2);
324 cairo_line_to(cr, width - offset, height/2);
325 SetSourceRGB(cr, top, 0.36);
326 cairo_stroke(cr);
327
328 // Bottom
329 cairo_move_to(cr, offset, 1 + height/2);
330 cairo_line_to(cr, width - offset, 1 + height/2);
331 SetSourceRGB(cr, bottom, 0.5);
332 cairo_stroke(cr);
333}
334
335
336void DrawArrow (cairo_t* cr, nux::color::RedGreenBlue const& rgb, double x, double y, double width, double height)
337{
338 cairo_save (cr);
339
340 cairo_translate (cr, x, y);
341 cairo_move_to (cr, -width / 2, -height / 2);
342 cairo_line_to (cr, 0, height / 2);
343 cairo_line_to (cr, width / 2, -height / 2);
344 cairo_close_path (cr);
345
346 SetSourceRGB(cr, rgb, 0.75);
347 cairo_fill_preserve (cr);
348
349 SetSourceRGB(cr, rgb, 1.0);
350 cairo_stroke (cr);
351
352 cairo_restore (cr);
353}
354
355void DrawBothArrows(cairo_t* cr, nux::color::RedGreenBlue const& rgb, int width, int height)
356{
357 int const arrow_width = 5;
358 int const arrow_height = 3;
359 float const trans_height = 8.5;
360 float const offset_x = 0.5;
361
362 // Top
363 cairo_save(cr);
364 cairo_translate(cr, width/2 + offset_x, trans_height);
365 cairo_rotate(cr, G_PI);
366 DrawArrow(cr, rgb, offset_x, 0, arrow_width, arrow_height);
367 cairo_restore(cr);
368
369 // Bottom
370 cairo_save(cr);
371 cairo_translate(cr, width/2 + offset_x, height - trans_height);
372 cairo_rotate(cr, 0);
373 DrawArrow(cr, rgb, -offset_x, 0, arrow_width, arrow_height);
374 cairo_restore(cr);
375}
376
377void VScrollBarOverlayWindow::UpdateTexture()
378{
379 int width = THUMB_WIDTH;
380 int height = THUMB_HEIGHT;
381 int radius = THUMB_RADIUS;
382
383 float const aspect = 1.0f;
384 float current_x = 0.0f;
385 float current_y = 0.0f;
386
387 cairo_t* cr = NULL;
388 cairo_pattern_t* pat = NULL;
389
390 nux::color::RedGreenBlue const& bg = nux::color::WhiteSmoke;
391 nux::color::RedGreenBlue const& bg_selected = nux::color::White;
392 nux::color::RedGreenBlue const& bg_active = nux::color::Gray;
393 nux::color::RedGreenBlue const& arrow_color = nux::color::DarkSlateGray;
394
395 nux::color::RedGreenBlue const& bg_arrow_up = ProduceColorShade(bg, 0.86);
396 nux::color::RedGreenBlue const& bg_arrow_down = ProduceColorShade(bg, 1.1);
397 nux::color::RedGreenBlue const& bg_shadow = ProduceColorShade(bg, 0.2);
398
399 nux::color::RedGreenBlue const& bg_dark_line = ProduceColorShade(bg, 0.4);
400 nux::color::RedGreenBlue const& bg_bright_line = ProduceColorShade(bg, 1.2);
401
402 nux::CairoGraphics cairoGraphics(CAIRO_FORMAT_ARGB32, width, height);
403 cr = cairoGraphics.GetContext();
404
405 cairo_save(cr);
406
407 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
408 cairo_paint(cr);
409
410 cairo_save(cr);
411
412 cairo_translate (cr, 0.5, 0.5);
413 width--;
414 height--;
415
416 cairo_set_line_width (cr, 1.0);
417
418 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
419 cairo_save(cr);
420
421 // Draw backgound
422 SetSourceRGB(cr, bg, 1.0);
423 cairoGraphics.DrawRoundedRectangle(cr, aspect, current_x, current_y, radius, width, height);
424 cairo_fill_preserve(cr);
425
426 // Draw shaded background
427 pat = cairo_pattern_create_linear(0, 0, 0, height);
428
429 PatternAddRGBStop(pat, bg_arrow_up, 0.0, 0.8);
430 PatternAddRGBStop(pat, bg_arrow_down, 1.0, 0.8);
431
432 cairo_set_source(cr, pat);
433 cairo_pattern_destroy(pat);
434
435 if (current_action_ == ThumbAction::DRAGGING)
436 {
437 cairo_fill_preserve(cr);
438 SetSourceRGB(cr, bg, 0.8);
439 cairo_fill(cr);
440 }
441 else
442 {
443 cairo_fill(cr);
444 }
445
446 // Draw Page Up/Down Action
447 if (current_action_ == ThumbAction::PAGE_UP ||
448 current_action_ == ThumbAction::PAGE_DOWN)
449 {
450 if (current_action_ == ThumbAction::PAGE_UP)
451 cairo_rectangle(cr, 0, 0, width, height/2);
452 else
453 cairo_rectangle(cr, 0, height/2, width, height/2);
454
455 SetSourceRGB(cr, bg, 0.8);
456 cairo_fill(cr);
457 }
458
459 cairo_save(cr);
460
461 // Draw Outline
462 cairo_set_line_width (cr, 2.0);
463
464 current_x += 0.5;
465 current_y += 0.5;
466 cairoGraphics.DrawRoundedRectangle(cr, aspect, current_x, current_y, radius - 1, width - 1, height - 1);
467
468 if (inside_slider_)
469 SetSourceRGB(cr, bg_selected, 1.0);
470 else
471 SetSourceRGB(cr, bg_active, 0.9);
472
473 cairo_stroke(cr);
474
475 cairo_restore(cr);
476
477 // Draw shade outline
478 pat = cairo_pattern_create_linear(0, 0, 0, height);
479
480 PatternAddRGBStop(pat, bg_shadow, 0.5, 0.06);
481
482 switch(current_action_)
483 {
484 case ThumbAction::NONE:
485 PatternAddRGBStop(pat, bg_shadow, 0.0, 0.22);
486 PatternAddRGBStop(pat, bg_shadow, 1.0, 0.22);
487 break;
488 case ThumbAction::DRAGGING:
489 PatternAddRGBStop(pat, bg_shadow, 0.0, 0.2);
490 PatternAddRGBStop(pat, bg_shadow, 1.0, 0.2);
491 break;
492 case ThumbAction::PAGE_UP:
493 PatternAddRGBStop(pat, bg_shadow, 0.0, 0.1);
494 PatternAddRGBStop(pat, bg_shadow, 1.0, 0.22);
495 break;
496 case ThumbAction::PAGE_DOWN:
497 PatternAddRGBStop(pat, bg_shadow, 0.0, 0.22);
498 PatternAddRGBStop(pat, bg_shadow, 1.0, 0.1);
499 break;
500 default:
501 break;
502 }
503
504 cairo_set_source(cr, pat);
505 cairo_pattern_destroy(pat);
506
507 current_x += 0.5;
508 current_y += 0.5;
509 cairoGraphics.DrawRoundedRectangle(cr, aspect, current_x, current_y, radius, width- 2, height - 2);
510 cairo_stroke(cr);
511
512 current_x += 1.0;
513 current_y += 1.0;
514 cairoGraphics.DrawRoundedRectangle(cr, aspect, current_x, current_y, radius - 1, width - 4, height- 4);
515 SetSourceRGB(cr, bg_bright_line, 0.6);
516 cairo_stroke(cr);
517
518 DrawBothGrips(cr, bg_dark_line, width, height);
519 DrawLineSeperator(cr, bg_dark_line, bg_bright_line, width, height);
520 DrawBothArrows(cr, arrow_color, width, height);
521
522 thumb_texture_.Adopt(unity::texture_from_cairo_graphics(cairoGraphics));
523 cairo_destroy(cr);
524
525 QueueDraw();
526}
0527
=== added file 'unity-shared/VScrollBarOverlayWindow.h'
--- unity-shared/VScrollBarOverlayWindow.h 1970-01-01 00:00:00 +0000
+++ unity-shared/VScrollBarOverlayWindow.h 2012-11-23 23:52:20 +0000
@@ -0,0 +1,92 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2012 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: Brandon Schaefer <brandon.schaefer@canonical.com>
18 */
19
20
21#ifndef VSCROLLBAR_OVERLAY_WINDOW_H
22#define VSCROLLBAR_OVERLAY_WINDOW_H
23
24#include <Nux/Nux.h>
25#include <Nux/BaseWindow.h>
26
27
28class VScrollBarOverlayWindow : public nux::BaseWindow
29{
30public:
31 VScrollBarOverlayWindow(nux::Geometry const& geo);
32
33 void UpdateGeometry(nux::Geometry const& geo);
34 void SetThumbOffsetY(int y);
35
36 void MouseDown();
37 void MouseUp();
38
39 void MouseNear();
40 void MouseBeyond();
41
42 void ThumbInsideSlider();
43 void ThumbOutsideSlider();
44
45 void PageUpAction();
46 void PageDownAction();
47
48 bool IsMouseInsideThumb(int y) const;
49 bool IsMouseBeingDragged() const;
50
51 int GetThumbHeight() const;
52 int GetThumbOffsetY() const;
53
54 nux::Geometry GetThumbGeometry() const;
55
56 void ResetStates();
57
58protected:
59 virtual void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw);
60
61private:
62 enum class ThumbAction : unsigned int
63 {
64 NONE,
65 DRAGGING,
66 PAGE_UP,
67 PAGE_DOWN
68 };
69
70 void MouseDragging();
71 void UpdateMouseOffsetX();
72 int GetValidOffsetYValue(int y) const;
73
74 void ShouldShow();
75 void ShouldHide();
76
77 void UpdateTexture();
78
79 nux::Geometry content_size_;
80 nux::ObjectPtr<nux::BaseTexture> thumb_texture_;
81
82 int content_offset_x_;
83 int mouse_offset_y_;
84
85 bool mouse_down_;
86 bool mouse_near_;
87 bool inside_slider_;
88
89 ThumbAction current_action_;
90};
91
92#endif