2
* Copyright 2012 Canonical Ltd.
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.
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.
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/>
18
* Authored by: Brandon Schaefer <brandon.schaefer@canonical.com>
22
#include <gtest/gtest.h>
25
#include <Nux/NuxTimerTickSource.h>
26
#include <Nux/VLayout.h>
27
#include <NuxCore/ObjectPtr.h>
28
#include <NuxCore/AnimationController.h>
31
#include "unity-shared/VScrollBarOverlayWindow.h"
32
#include "unity-shared/PlacesOverlayVScrollBar.h"
33
#include "unity-shared/UScreen.h"
35
using namespace unity::dash;
36
using namespace testing;
43
const unsigned SCROLL_TICK = 1000 * 401;
44
const unsigned SHOW_TICK = 1000 * 91;
47
class TestOverlayWindow : public Test
52
, animation_controller_(tick_source_)
53
, overlay_window_(new VScrollBarOverlayWindow(nux::Geometry(0,0,100,100)))
56
int GetProxListSize() const
58
return nux::GetWindowThread()->GetWindowCompositor().GetProximityListSize();
64
show_tick_ += SHOW_TICK;
65
tick_source_.tick(show_tick_);
69
nux::NuxTimerTickSource tick_source_;
70
nux::animation::AnimationController animation_controller_;
71
nux::ObjectPtr<VScrollBarOverlayWindow> overlay_window_;
77
class MockScrollBar : public unity::dash::PlacesOverlayVScrollBar
80
MockScrollBar(NUX_FILE_LINE_DECL)
81
: PlacesOverlayVScrollBar(NUX_FILE_LINE_PARAM)
82
, animation_controller(tick_source_)
85
, thumbs_height_(overlay_window_->GetThumbGeometry().height)
86
, scroll_up_signal_(false)
87
, scroll_down_signal_(false)
89
OnScrollUp.connect([&] (float step, int dy) {
91
scroll_up_signal_ = true;
94
OnScrollDown.connect([&] (float step, int dy) {
96
scroll_down_signal_ = true;
100
virtual ~MockScrollBar() {}
102
// ScrollDown/Up moves the mouse over the overlay scroll bar, then
103
// moves it down/up by scroll_dy
104
void ScrollDown(int scroll_dy)
108
auto geo = overlay_window_->GetThumbGeometry();
115
MoveMouse(x, y+scroll_dy);
116
MoveUp(x, y+scroll_dy);
119
void ScrollUp(int scroll_dy)
123
auto geo = overlay_window_->GetThumbGeometry();
130
MoveMouse(x, y-scroll_dy);
131
MoveUp(x, y-scroll_dy);
134
void MoveDown(int x, int y)
137
event.type = nux::NUX_MOUSE_PRESSED;
140
nux::GetWindowCompositor().ProcessEvent(event);
143
void MoveUp(int x, int y)
146
event.type = nux::NUX_MOUSE_RELEASED;
149
nux::GetWindowCompositor().ProcessEvent(event);
152
void MoveMouse(int x, int y)
155
event.type = nux::NUX_MOUSE_MOVE;
158
nux::GetWindowCompositor().ProcessEvent(event);
163
auto geo = overlay_window_->GetThumbGeometry();
164
MoveMouse(geo.x, geo.y);
167
void ScrollUpAnimation(int scroll_dy)
172
StartScrollAnimation(ScrollDir::UP, scroll_dy);
173
scroll_tick_ += SCROLL_TICK;
174
tick_source_.tick(scroll_tick_);
177
void ScrollDownAnimation(int scroll_dy)
182
StartScrollAnimation(ScrollDir::DOWN, scroll_dy);
183
scroll_tick_ += SCROLL_TICK;
184
tick_source_.tick(scroll_tick_);
187
void SetThumbOffset(int y)
189
overlay_window_->SetThumbOffsetY(y);
190
UpdateConnectorPosition();
193
void StartScrollThenConnectorAnimation()
195
StartScrollAnimation(ScrollDir::DOWN, 20);
197
StartConnectorAnimation();
199
scroll_tick_ += SCROLL_TICK;
200
tick_source_.tick(scroll_tick_);
205
OnMouseDrag(0, overlay_window_->GetThumbOffsetY() + 1, 0, 5, 0, 0);
208
nux::NuxTimerTickSource tick_source_;
209
nux::animation::AnimationController animation_controller;
211
using PlacesOverlayVScrollBar::connector_height_;
212
using VScrollBar::_slider;
214
unsigned scroll_tick_;
217
bool scroll_up_signal_;
218
bool scroll_down_signal_;
223
class MockScrollView : public nux::ScrollView
226
MockScrollView(NUX_FILE_LINE_DECL)
227
: nux::ScrollView(NUX_FILE_LINE_PARAM)
229
scroll_bar_ = new MockScrollBar(NUX_TRACKER_LOCATION);
230
SetVScrollBar(scroll_bar_.GetPointer());
233
nux::ObjectPtr<MockScrollBar> scroll_bar_;
236
class TestOverlayVScrollBar : public Test
239
TestOverlayVScrollBar()
241
nux::VLayout* scroll_layout_ = new nux::VLayout(NUX_TRACKER_LOCATION);
242
scroll_layout_->SetGeometry(0,0,1000,5000);
243
scroll_layout_->SetScaleFactor(0);
245
scroll_view_ = new MockScrollView(NUX_TRACKER_LOCATION);
246
scroll_view_->EnableVerticalScrollBar(true);
247
scroll_view_->EnableHorizontalScrollBar(false);
248
scroll_view_->SetLayout(scroll_layout_);
250
scroll_view_->scroll_bar_->SetContentSize(0, 0, 201, 2000);
251
scroll_view_->scroll_bar_->SetContainerSize(0, 0, 202, 400);
254
nux::ObjectPtr<MockScrollView> scroll_view_;
257
TEST_F(TestOverlayWindow, TestOverlayShows)
259
ASSERT_FALSE(overlay_window_->IsVisible());
260
overlay_window_->MouseNear();
261
EXPECT_TRUE(overlay_window_->IsVisible());
262
EXPECT_DOUBLE_EQ(0.0f, overlay_window_->GetOpacity());
265
EXPECT_DOUBLE_EQ(1.0f, overlay_window_->GetOpacity());
268
TEST_F(TestOverlayWindow, TestOverlayHides)
270
overlay_window_->MouseNear();
272
EXPECT_TRUE(overlay_window_->IsVisible());
274
overlay_window_->MouseBeyond();
277
overlay_window_->MouseLeave();
280
EXPECT_FALSE(overlay_window_->IsVisible());
281
EXPECT_DOUBLE_EQ(0.0f, overlay_window_->GetOpacity());
284
TEST_F(TestOverlayWindow, TestOverlayStaysOpenWhenMouseDown)
286
overlay_window_->MouseNear();
289
overlay_window_->MouseDown();
292
overlay_window_->MouseBeyond();
295
overlay_window_->MouseLeave();
298
EXPECT_TRUE(overlay_window_->IsVisible());
301
TEST_F(TestOverlayWindow, TestOverlayMouseDrags)
303
overlay_window_->MouseDown();
304
EXPECT_FALSE(overlay_window_->IsMouseBeingDragged());
306
overlay_window_->SetThumbOffsetY(10);
307
EXPECT_TRUE(overlay_window_->IsMouseBeingDragged());
310
TEST_F(TestOverlayWindow, TestOverlayStopDraggingOnMouseUp)
312
overlay_window_->MouseDown();
313
EXPECT_FALSE(overlay_window_->IsMouseBeingDragged());
315
overlay_window_->SetThumbOffsetY(10);
316
EXPECT_TRUE(overlay_window_->IsMouseBeingDragged());
318
overlay_window_->MouseUp();
319
EXPECT_FALSE(overlay_window_->IsMouseBeingDragged());
322
TEST_F(TestOverlayWindow, TestOverlaySetsOffsetY)
324
int const offset_y = 30;
326
overlay_window_->SetThumbOffsetY(offset_y);
327
EXPECT_EQ(overlay_window_->GetThumbOffsetY(), offset_y);
330
TEST_F(TestOverlayWindow, TestOverlaySetsOffsetYOutOfBoundsLower)
332
int const offset_y = -40;
334
overlay_window_->SetThumbOffsetY(offset_y);
335
EXPECT_EQ(overlay_window_->GetThumbOffsetY(), 0);
338
TEST_F(TestOverlayWindow, TestOverlaySetsOffsetYOutOfBoundsUpper)
340
int const offset_y = 1000;
341
int const expected_offset = overlay_window_->GetBaseHeight() - overlay_window_->GetThumbHeight();
343
overlay_window_->SetThumbOffsetY(offset_y);
344
EXPECT_EQ(overlay_window_->GetThumbOffsetY(), expected_offset);
347
TEST_F(TestOverlayWindow, TestOverlayMouseIsInsideThumb)
349
nux::Geometry const geo(0, 50, 50, 400);
351
overlay_window_->UpdateGeometry(geo);
352
EXPECT_TRUE(overlay_window_->IsMouseInsideThumb(0));
355
TEST_F(TestOverlayWindow, TestOverlayMouseIsInsideOnOffsetChange)
357
nux::Geometry const geo(0, 50, 50, 400);
358
int const offset_y = 50;
359
int const thumb_height = overlay_window_->GetThumbHeight();
361
overlay_window_->UpdateGeometry(geo);
362
overlay_window_->SetThumbOffsetY(offset_y);
364
EXPECT_FALSE(overlay_window_->IsMouseInsideThumb(offset_y - 1));
365
EXPECT_TRUE(overlay_window_->IsMouseInsideThumb(offset_y + thumb_height/2));
366
EXPECT_FALSE(overlay_window_->IsMouseInsideThumb(offset_y + thumb_height + 1));
370
TEST_F(TestOverlayVScrollBar, TestScrollDownSignal)
372
scroll_view_->scroll_bar_->ScrollDown(10);
373
EXPECT_TRUE(scroll_view_->scroll_bar_->scroll_down_signal_);
376
TEST_F(TestOverlayVScrollBar, TestScrollUpSignal)
378
scroll_view_->scroll_bar_->ScrollDown(10);
379
scroll_view_->scroll_bar_->ScrollUp(10);
380
EXPECT_TRUE(scroll_view_->scroll_bar_->scroll_up_signal_);
383
TEST_F(TestOverlayVScrollBar, TestScrollDownDeltaY)
385
int scroll_down = 15;
386
scroll_view_->scroll_bar_->ScrollDown(scroll_down);
387
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, scroll_down);
390
TEST_F(TestOverlayVScrollBar, TestScrollUpDeltaY)
393
scroll_view_->scroll_bar_->ScrollDown(scroll_up+1);
394
scroll_view_->scroll_bar_->ScrollUp(scroll_up);
395
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, scroll_up);
398
TEST_F(TestOverlayVScrollBar, TestScrollDownBaseYMoves)
400
int slider_y = scroll_view_->scroll_bar_->_slider->GetBaseY();
401
int scroll_down = 10;
402
scroll_view_->scroll_bar_->ScrollDown(scroll_down);
403
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, scroll_down);
404
EXPECT_GT(scroll_view_->scroll_bar_->_slider->GetBaseY(), slider_y);
407
TEST_F(TestOverlayVScrollBar, TestScrollUpBaseYMoves)
410
scroll_view_->scroll_bar_->ScrollDown(scroll_up+1);
412
int slider_y = scroll_view_->scroll_bar_->_slider->GetBaseY();
413
scroll_view_->scroll_bar_->ScrollUp(scroll_up);
414
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, scroll_up);
415
EXPECT_LT(scroll_view_->scroll_bar_->_slider->GetBaseY(), slider_y);
418
TEST_F(TestOverlayVScrollBar, TestScrollsSlowlyDeltaY)
420
int scroll_down = 10;
421
for (int i = 0; i < scroll_down; i++)
423
scroll_view_->scroll_bar_->ScrollDown(1);
424
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, 1);
428
TEST_F(TestOverlayVScrollBar, TestScrollUpAnimationMovesSlider)
431
scroll_view_->scroll_bar_->ScrollDown(scroll_up+10);
433
int slider_y = scroll_view_->scroll_bar_->_slider->GetBaseY();
434
scroll_view_->scroll_bar_->ScrollUpAnimation(scroll_up);
436
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, scroll_up);
437
EXPECT_LT(scroll_view_->scroll_bar_->_slider->GetBaseY(), slider_y);
440
TEST_F(TestOverlayVScrollBar, TestScrollDownAnimationMovesSlider)
442
int scroll_down = 10;
443
int slider_y = scroll_view_->scroll_bar_->_slider->GetBaseY();
445
scroll_view_->scroll_bar_->ScrollDownAnimation(scroll_down);
447
EXPECT_EQ(scroll_view_->scroll_bar_->scroll_dy_, scroll_down);
448
EXPECT_GT(scroll_view_->scroll_bar_->_slider->GetBaseY(), slider_y);
451
TEST_F(TestOverlayVScrollBar, TestConnectorResetsDuringScrollAnimation)
453
scroll_view_->scroll_bar_->MoveMouseNear();
454
scroll_view_->scroll_bar_->SetThumbOffset(100);
456
int connector_height = scroll_view_->scroll_bar_->connector_height_;
457
EXPECT_GT(connector_height, 0);
459
scroll_view_->scroll_bar_->StartScrollThenConnectorAnimation();
461
connector_height = scroll_view_->scroll_bar_->connector_height_;
462
EXPECT_EQ(connector_height, 0);
466
TEST_F(TestOverlayVScrollBar, TestAllowDragIfOverlayIsAtMaximum)
468
// Offset that sets the thumb at the bottom of the scrollbar
469
int thumb_offset = scroll_view_->scroll_bar_->GetHeight() -
470
scroll_view_->scroll_bar_->thumbs_height_;
472
scroll_view_->scroll_bar_->SetThumbOffset(thumb_offset);
473
scroll_view_->scroll_bar_->FakeDragDown();
474
EXPECT_TRUE(scroll_view_->scroll_bar_->scroll_down_signal_);