Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: athena/wm/split_view_controller.cc

Issue 545393002: Adding split view divider widget. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code format Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "athena/wm/split_view_controller.h" 5 #include "athena/wm/split_view_controller.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "athena/screen/public/screen_manager.h" 9 #include "athena/screen/public/screen_manager.h"
10 #include "athena/wm/public/window_list_provider.h" 10 #include "athena/wm/public/window_list_provider.h"
11 #include "athena/wm/public/window_manager.h" 11 #include "athena/wm/public/window_manager.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "ui/aura/scoped_window_targeter.h"
13 #include "ui/aura/window.h" 14 #include "ui/aura/window.h"
15 #include "ui/aura/window_targeter.h"
14 #include "ui/compositor/closure_animation_observer.h" 16 #include "ui/compositor/closure_animation_observer.h"
15 #include "ui/compositor/layer_animation_observer.h" 17 #include "ui/compositor/layer.h"
16 #include "ui/compositor/scoped_layer_animation_settings.h" 18 #include "ui/compositor/scoped_layer_animation_settings.h"
17 #include "ui/events/event_handler.h" 19 #include "ui/events/event_handler.h"
18 #include "ui/gfx/display.h" 20 #include "ui/gfx/display.h"
19 #include "ui/gfx/screen.h" 21 #include "ui/gfx/screen.h"
22 #include "ui/views/background.h"
23 #include "ui/views/layout/box_layout.h"
24 #include "ui/views/widget/root_view.h"
25 #include "ui/views/widget/root_view_targeter.h"
26 #include "ui/views/widget/widget.h"
20 #include "ui/wm/core/window_util.h" 27 #include "ui/wm/core/window_util.h"
21 28
22 namespace athena { 29 namespace athena {
23 30
24 namespace { 31 namespace {
25 32
26 // Returns a target transform which is suitable for animating a windows's 33 const int kDragHandleWidth = 4;
27 // bounds. 34 const int kDragHandleHeight = 80;
28 gfx::Transform GetTargetTransformForBoundsAnimation(const gfx::Rect& from, 35 const int kDragHandleMargin = 1;
29 const gfx::Rect& to) { 36 const int kDividerWidth = kDragHandleWidth + 2 * kDragHandleMargin;
37
38 // Always returns the same target.
39 class StaticViewTargeterDelegate : public views::ViewTargeterDelegate {
40 public:
41 explicit StaticViewTargeterDelegate(views::View* target) : target_(target) {}
42
43 virtual ~StaticViewTargeterDelegate() {}
44
45 private:
46 // views::ViewTargeterDelegate:
47 virtual views::View* TargetForRect(views::View* root,
48 const gfx::Rect& rect) OVERRIDE {
49 return target_;
50 }
51
52 // Not owned.
53 views::View* target_;
54
55 DISALLOW_COPY_AND_ASSIGN(StaticViewTargeterDelegate);
56 };
57
58 // Expands the effective target area of the window of the widget containing the
59 // specified view. If the view is large enough to begin with, there should be
60 // no change from the default targeting behavior.
61 class PriorityWindowTargeter : public aura::WindowTargeter,
62 public aura::WindowObserver {
63 public:
64 explicit PriorityWindowTargeter(views::View* priority_view)
65 : priority_view_(priority_view) {
66 CHECK(priority_view->GetWidget());
67 window_ = priority_view->GetWidget()->GetNativeWindow();
68 CHECK(window_);
69 window_->AddObserver(this);
70 }
71
72 virtual ~PriorityWindowTargeter() {
73 window_->RemoveObserver(this);
74 }
75
76 private:
77 // aura::WindowTargeter:
78 virtual ui::EventTarget* FindTargetForLocatedEvent(
79 ui::EventTarget* root,
80 ui::LocatedEvent* event) OVERRIDE {
81 if (!window_ || (event->type() != ui::ET_TOUCH_PRESSED))
82 return WindowTargeter::FindTargetForLocatedEvent(root, event);
83 CHECK_EQ(window_, priority_view_->GetWidget()->GetNativeWindow());
84
85 // Bounds of the view in root window's coordinates.
86 gfx::Rect view_bounds = priority_view_->GetBoundsInScreen();
87 // If there is a transform on the window's layer - apply it.
88 gfx::Transform window_transform = window_->layer()->transform();
89 gfx::RectF transformed_bounds_f = view_bounds;
90 window_transform.TransformRect(&transformed_bounds_f);
91 gfx::Rect transformed_bounds = gfx::Rect(transformed_bounds_f.x(),
92 transformed_bounds_f.y(),
93 transformed_bounds_f.width(),
94 transformed_bounds_f.height());
95 // Now expand the bounds to be at least
96 // kMinTouchDimension x kMinTouchDimension and target the event to the
97 // window if it falls within the expanded bounds
98 gfx::Point center = transformed_bounds.CenterPoint();
99 gfx::Rect extension_rect = gfx::Rect(
100 center.x() - kMinTouchDimension / 2,
101 center.y() - kMinTouchDimension / 2,
102 kMinTouchDimension,
103 kMinTouchDimension);
104 gfx::Rect extended_bounds =
105 gfx::UnionRects(transformed_bounds, extension_rect);
106 if (extended_bounds.Contains(event->root_location())) {
107 root->ConvertEventToTarget(window_, event);
108 return window_;
109 }
110
111 return WindowTargeter::FindTargetForLocatedEvent(root, event);
112 }
113
114 // aura::WindowObserver:
115 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
116 DCHECK_EQ(window, window_);
117 window_->RemoveObserver(this);
118 window_ = NULL;
119 }
120
121 // Minimum dimension of a target to be comfortably touchable.
122 // The effective touch target area of |priority_window_| gets expanded so
123 // that it's width and height is ayt least |kMinTouchDimension|.
124 int const kMinTouchDimension = 26;
125
126 aura::Window* window_;
127 views::View* priority_view_;
128
129 DISALLOW_COPY_AND_ASSIGN(PriorityWindowTargeter);
130 };
131
132 // Returns a target transform required to transform |from| to |to|.
133 gfx::Transform GetTransformForBounds(const gfx::Rect& from,
134 const gfx::Rect& to) {
30 gfx::Transform transform; 135 gfx::Transform transform;
31 transform.Translate(to.x() - from.x(), to.y() - from.y()); 136 transform.Translate(to.x() - from.x(), to.y() - from.y());
32 transform.Scale(to.width() / static_cast<float>(from.width()), 137 transform.Scale(to.width() / static_cast<float>(from.width()),
33 to.height() / static_cast<float>(from.height())); 138 to.height() / static_cast<float>(from.height()));
34 return transform; 139 return transform;
35 } 140 }
36 141
37 bool IsLandscapeOrientation(gfx::Display::Rotation rotation) { 142 bool IsLandscapeOrientation(gfx::Display::Rotation rotation) {
38 return rotation == gfx::Display::ROTATE_0 || 143 return rotation == gfx::Display::ROTATE_0 ||
39 rotation == gfx::Display::ROTATE_180; 144 rotation == gfx::Display::ROTATE_180;
40 } 145 }
41 146
42 } // namespace 147 } // namespace
43 148
44 SplitViewController::SplitViewController( 149 SplitViewController::SplitViewController(
45 aura::Window* container, 150 aura::Window* container,
46 WindowListProvider* window_list_provider) 151 WindowListProvider* window_list_provider)
47 : state_(INACTIVE), 152 : state_(INACTIVE),
48 container_(container), 153 container_(container),
49 window_list_provider_(window_list_provider), 154 window_list_provider_(window_list_provider),
50 left_window_(NULL), 155 left_window_(NULL),
51 right_window_(NULL), 156 right_window_(NULL),
52 separator_position_(0), 157 divider_position_(0),
158 divider_scroll_start_position_(0),
159 divider_widget_(NULL),
160 drag_handle_(NULL),
53 weak_factory_(this) { 161 weak_factory_(this) {
54 } 162 }
55 163
56 SplitViewController::~SplitViewController() { 164 SplitViewController::~SplitViewController() {
57 } 165 }
58 166
59 bool SplitViewController::IsSplitViewModeActive() const { 167 bool SplitViewController::IsSplitViewModeActive() const {
60 return state_ == ACTIVE; 168 return state_ == ACTIVE;
61 } 169 }
62 170
(...skipping 24 matching lines...) Expand all
87 195
88 if (!right && iter != windows.rend()) { 196 if (!right && iter != windows.rend()) {
89 right = *iter; 197 right = *iter;
90 iter++; 198 iter++;
91 if (right == left && iter != windows.rend()) { 199 if (right == left && iter != windows.rend()) {
92 right = *iter; 200 right = *iter;
93 iter++; 201 iter++;
94 } 202 }
95 } 203 }
96 204
205 divider_position_ = GetDefaultDividerPosition();
97 SetState(ACTIVE); 206 SetState(ACTIVE);
98 right_window_ = right; 207 right_window_ = right;
99 left_window_ = left; 208 left_window_ = left;
100 UpdateLayout(true); 209 UpdateLayout(true);
101 } 210 }
102 211
103 void SplitViewController::ReplaceWindow(aura::Window* window, 212 void SplitViewController::ReplaceWindow(aura::Window* window,
104 aura::Window* replace_with) { 213 aura::Window* replace_with) {
105 CHECK(IsSplitViewModeActive()); 214 CHECK(IsSplitViewModeActive());
106 CHECK(replace_with); 215 CHECK(replace_with);
(...skipping 15 matching lines...) Expand all
122 window->Hide(); 231 window->Hide();
123 } 232 }
124 233
125 void SplitViewController::DeactivateSplitMode() { 234 void SplitViewController::DeactivateSplitMode() {
126 CHECK_EQ(ACTIVE, state_); 235 CHECK_EQ(ACTIVE, state_);
127 SetState(INACTIVE); 236 SetState(INACTIVE);
128 UpdateLayout(false); 237 UpdateLayout(false);
129 left_window_ = right_window_ = NULL; 238 left_window_ = right_window_ = NULL;
130 } 239 }
131 240
132 gfx::Rect SplitViewController::GetLeftTargetBounds() { 241 void SplitViewController::InitializeDivider() {
242 CHECK(!divider_widget_);
243 CHECK(!drag_handle_);
244
245 drag_handle_ = CreateDragHandleView(DRAG_HANDLE_HORIZONTAL,
246 this,
247 kDragHandleWidth,
248 kDragHandleHeight);
249 views::View* content_view = new views::View;
250 content_view->set_background(
251 views::Background::CreateSolidBackground(SK_ColorBLACK));
252 views::BoxLayout* layout =
253 new views::BoxLayout(views::BoxLayout::kHorizontal,
254 kDragHandleMargin,
255 kDragHandleMargin,
256 0);
257 layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
258 layout->set_cross_axis_alignment(
259 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
260 content_view->SetLayoutManager(layout);
261 content_view->AddChildView(drag_handle_);
262
263 divider_widget_ = new views::Widget();
264 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
265 params.parent = container_;
266 params.bounds = gfx::Rect(-kDividerWidth / 2,
267 0,
268 kDividerWidth,
269 container_->bounds().height());
270 divider_widget_->Init(params);
271 divider_widget_->SetContentsView(content_view);
272
273 // Install a static view targeter on the root view which always targets
274 // divider_view.
275 // TODO(mfomitchev,tdanderson): This should not be needed:
276 // 1. crbug.com/414339 - divider_view is the only view and it completely
277 // overlaps the root view.
278 // 2. The logic in ViewTargeterDelegate::TargetForRect could be improved to
279 // work better for views that are narrow in one dimension and long in
280 // another dimension.
281 views::internal::RootView* root_view =
282 static_cast<views::internal::RootView*>(divider_widget_->GetRootView());
283 view_targeter_delegate_.reset(new StaticViewTargeterDelegate(drag_handle_));
284 views::ViewTargeter* targeter =
285 new views::RootViewTargeter(view_targeter_delegate_.get(), root_view);
286 divider_widget_->GetRootView()->SetEventTargeter(
287 scoped_ptr<views::ViewTargeter>(targeter));
288 }
289
290 void SplitViewController::HideDivider() {
291 divider_widget_->Hide();
292 window_targeter_.reset();
293 }
294
295 void SplitViewController::ShowDivider() {
296 divider_widget_->Show();
297 if (!window_targeter_) {
298 scoped_ptr<ui::EventTargeter> window_targeter =
299 scoped_ptr<ui::EventTargeter>(new PriorityWindowTargeter(drag_handle_));
300 window_targeter_.reset(
301 new aura::ScopedWindowTargeter(container_, window_targeter.Pass()));
302 }
303 }
304
305 gfx::Rect SplitViewController::GetLeftAreaBounds() {
133 gfx::Rect work_area = 306 gfx::Rect work_area =
134 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area(); 307 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
pkotwicz 2014/09/23 05:13:40 Shouldn't this use |divider_position_| ? How abou
mfomitchev 2014/09/23 15:46:02 Oops, I totally messed this up by copy/pasting old
pkotwicz 2014/09/23 19:44:46 I understand now, thanks!
135 return gfx::Rect(0, 0, container_->bounds().width() / 2, work_area.height()); 308 return gfx::Rect(0, 0, container_->bounds().width() / 2, work_area.height());
136 } 309 }
137 310
138 gfx::Rect SplitViewController::GetRightTargetBounds() { 311 gfx::Rect SplitViewController::GetRightAreaBounds() {
139 gfx::Rect work_area = 312 gfx::Rect work_area =
140 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area(); 313 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
141 int container_width = container_->bounds().width(); 314 int container_width = container_->bounds().width();
142 return gfx::Rect( 315 return gfx::Rect(
143 container_width / 2, 0, container_width / 2, work_area.height()); 316 container_width / 2, 0, container_width / 2, work_area.height());
144 } 317 }
145 318
146 void SplitViewController::SetState(SplitViewController::State state) { 319 void SplitViewController::SetState(SplitViewController::State state) {
147 if (state_ == state) 320 if (state_ == state)
148 return; 321 return;
149 322
323 if (divider_widget_ == NULL)
324 InitializeDivider();
325
150 state_ = state; 326 state_ = state;
327
151 ScreenManager::Get()->SetRotationLocked(state_ != INACTIVE); 328 ScreenManager::Get()->SetRotationLocked(state_ != INACTIVE);
329 if (state == INACTIVE)
330 HideDivider();
331 else
332 ShowDivider();
152 } 333 }
153 334
154 void SplitViewController::UpdateLayout(bool animate) { 335 void SplitViewController::UpdateLayout(bool animate) {
155 CHECK(left_window_); 336 CHECK(left_window_);
156 CHECK(right_window_); 337 CHECK(right_window_);
157
158 // Splitview can be activated from SplitViewController::ActivateSplitMode or 338 // Splitview can be activated from SplitViewController::ActivateSplitMode or
159 // SplitViewController::ScrollEnd. Additionally we don't want to rotate the 339 // SplitViewController::ScrollEnd. Additionally we don't want to rotate the
160 // screen while engaging splitview (i.e. state_ == SCROLLING). 340 // screen while engaging splitview (i.e. state_ == SCROLLING).
161 if (state_ == INACTIVE && !animate) { 341 if (state_ == INACTIVE && !animate) {
162 if (!wm::IsActiveWindow(left_window_)) 342 aura::Window* top_window = window_list_provider_->GetWindowList().back();
343 if (top_window != left_window_) {
163 left_window_->Hide(); 344 left_window_->Hide();
164 if (!wm::IsActiveWindow(right_window_)) 345 right_window_->SetBounds(gfx::Rect(container_->bounds().size()));
pkotwicz 2014/09/23 19:44:46 This is wrong. It needs to into account the work a
mfomitchev 2014/09/23 21:02:09 Ok, updated. I wish all activity windows were insi
346 }
347 if (top_window != right_window_) {
348 left_window_->SetBounds(gfx::Rect(container_->bounds().size()));
pkotwicz 2014/09/23 19:44:46 Ditto
mfomitchev 2014/09/23 21:02:09 Done.
165 right_window_->Hide(); 349 right_window_->Hide();
166 SetWindowTransforms(gfx::Transform(), gfx::Transform(), false); 350 }
351 SetWindowTransforms(
352 gfx::Transform(), gfx::Transform(), gfx::Transform(), false);
167 return; 353 return;
168 } 354 }
169 355
170 left_window_->Show(); 356 left_window_->Show();
171 right_window_->Show(); 357 right_window_->Show();
172 window_list_provider_->MoveToFront(right_window_); 358 window_list_provider_->MoveToFront(right_window_);
173 window_list_provider_->MoveToFront(left_window_); 359 window_list_provider_->MoveToFront(left_window_);
174 360
361 gfx::Transform divider_transform;
362 divider_transform.Translate(divider_position_, 0);
175 if (state_ == ACTIVE) { 363 if (state_ == ACTIVE) {
176 if (animate) { 364 if (animate) {
177 gfx::Transform left_transform = GetTargetTransformForBoundsAnimation( 365 gfx::Transform left_transform =
178 left_window_->bounds(), GetLeftTargetBounds()); 366 GetTransformForBounds(left_window_->bounds(), GetLeftAreaBounds());
179 gfx::Transform right_transform = GetTargetTransformForBoundsAnimation( 367 gfx::Transform right_transform =
180 right_window_->bounds(), GetRightTargetBounds()); 368 GetTransformForBounds(right_window_->bounds(), GetRightAreaBounds());
181 SetWindowTransforms(left_transform, right_transform, true); 369 SetWindowTransforms(
370 left_transform, right_transform, divider_transform, true);
182 } else { 371 } else {
183 left_window_->SetBounds(GetLeftTargetBounds()); 372 left_window_->SetBounds(GetLeftAreaBounds());
184 right_window_->SetBounds(GetRightTargetBounds()); 373 right_window_->SetBounds(GetRightAreaBounds());
185 SetWindowTransforms(gfx::Transform(), gfx::Transform(), false); 374 SetWindowTransforms(
375 gfx::Transform(), gfx::Transform(), divider_transform, false);
186 } 376 }
187 } else { 377 } else {
188 gfx::Transform left_transform; 378 gfx::Transform left_transform;
189 left_transform.Translate(separator_position_ - container_->bounds().width(),
190 0);
191 gfx::Transform right_transform; 379 gfx::Transform right_transform;
192 right_transform.Translate(separator_position_, 0); 380 gfx::Rect left_area_bounds = GetLeftAreaBounds();
193 SetWindowTransforms(left_transform, right_transform, animate); 381 gfx::Rect right_area_bounds = GetRightAreaBounds();
382 // If the width of the window is greater than the width of the area which it
383 // is supposed to occupy - translate the window. Otherwise scale the window
384 // up to fill the target area.
385 if (left_window_->bounds().width() >= left_area_bounds.width()) {
386 left_transform.Translate(
387 left_area_bounds.right() - left_window_->bounds().right(), 0);
388 } else {
389 left_transform =
390 GetTransformForBounds(left_window_->bounds(), left_area_bounds);
391 }
392 if (right_window_->bounds().width() >= right_area_bounds.width()) {
393 right_transform.Translate(
394 right_area_bounds.x() - right_window_->bounds().x(), 0);
395 } else {
396 right_transform =
397 GetTransformForBounds(right_window_->bounds(), right_area_bounds);
398 }
399 SetWindowTransforms(
400 left_transform, right_transform, divider_transform, animate);
194 } 401 }
195 // Note: |left_window_| and |right_window_| may be NULL if calling 402 // Note: |left_window_| and |right_window_| may be NULL if calling
196 // SetWindowTransforms(): 403 // SetWindowTransforms():
197 // - caused the in-progress animation to abort. 404 // - caused the in-progress animation to abort.
198 // - started a zero duration animation. 405 // - started a zero duration animation.
199 } 406 }
200 407
201 void SplitViewController::SetWindowTransforms( 408 void SplitViewController::SetWindowTransforms(
202 const gfx::Transform& left_transform, 409 const gfx::Transform& left_transform,
203 const gfx::Transform& right_transform, 410 const gfx::Transform& right_transform,
411 const gfx::Transform& divider_transform,
204 bool animate) { 412 bool animate) {
205 if (animate) { 413 if (animate) {
206 ui::ScopedLayerAnimationSettings left_settings( 414 ui::ScopedLayerAnimationSettings left_settings(
207 left_window_->layer()->GetAnimator()); 415 left_window_->layer()->GetAnimator());
208 left_settings.SetPreemptionStrategy( 416 left_settings.SetPreemptionStrategy(
209 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 417 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
210 left_window_->SetTransform(left_transform); 418 left_window_->SetTransform(left_transform);
211 419
420 ui::ScopedLayerAnimationSettings divider_widget_settings(
421 divider_widget_->GetNativeWindow()->layer()->GetAnimator());
422 divider_widget_settings.SetPreemptionStrategy(
423 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
424 divider_widget_->GetNativeWindow()->SetTransform(divider_transform);
425
212 ui::ScopedLayerAnimationSettings right_settings( 426 ui::ScopedLayerAnimationSettings right_settings(
213 right_window_->layer()->GetAnimator()); 427 right_window_->layer()->GetAnimator());
214 right_settings.SetPreemptionStrategy( 428 right_settings.SetPreemptionStrategy(
215 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 429 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
216 right_settings.AddObserver(new ui::ClosureAnimationObserver( 430 right_settings.AddObserver(new ui::ClosureAnimationObserver(
217 base::Bind(&SplitViewController::OnAnimationCompleted, 431 base::Bind(&SplitViewController::OnAnimationCompleted,
218 weak_factory_.GetWeakPtr()))); 432 weak_factory_.GetWeakPtr())));
219 right_window_->SetTransform(right_transform); 433 right_window_->SetTransform(right_transform);
220 } else { 434 } else {
221 left_window_->SetTransform(left_transform); 435 left_window_->SetTransform(left_transform);
436 divider_widget_->GetNativeWindow()->SetTransform(divider_transform);
222 right_window_->SetTransform(right_transform); 437 right_window_->SetTransform(right_transform);
223 } 438 }
224 } 439 }
225 440
226 void SplitViewController::OnAnimationCompleted() { 441 void SplitViewController::OnAnimationCompleted() {
227 // Animation can be cancelled when deactivated. 442 // Animation can be cancelled when deactivated.
228 if (left_window_ == NULL) 443 if (left_window_ == NULL)
229 return; 444 return;
230 UpdateLayout(false); 445 UpdateLayout(false);
231 446
232 if (state_ == INACTIVE) { 447 if (state_ == INACTIVE) {
233 left_window_ = NULL; 448 left_window_ = NULL;
234 right_window_ = NULL; 449 right_window_ = NULL;
235 } 450 }
236 } 451 }
237 452
238 void SplitViewController::UpdateSeparatorPositionFromScrollDelta(float delta) { 453 int SplitViewController::GetDefaultDividerPosition() {
239 gfx::Screen* screen = gfx::Screen::GetScreenFor(container_); 454 return container_->GetBoundsInScreen().width() / 2;
240 const gfx::Rect& display_bounds =
241 screen->GetDisplayNearestWindow(container_).bounds();
242 gfx::Rect container_bounds = container_->GetBoundsInScreen();
243 separator_position_ =
244 delta > 0 ? ((int)delta) + display_bounds.x() - container_bounds.x()
245 : display_bounds.right() - container_bounds.x() + delta;
246 } 455 }
247 456
248 /////////////////////////////////////////////////////////////////////////////// 457 ///////////////////////////////////////////////////////////////////////////////
249 // BezelController::ScrollDelegate: 458 // BezelController::ScrollDelegate:
250 459
251 void SplitViewController::ScrollBegin(BezelController::Bezel bezel, 460 void SplitViewController::BezelScrollBegin(BezelController::Bezel bezel,
252 float delta) { 461 float delta) {
253 if (!CanScroll()) 462 if (!BezelCanScroll())
254 return; 463 return;
464
255 SetState(SCROLLING); 465 SetState(SCROLLING);
256 466
257 aura::Window::Windows windows = window_list_provider_->GetWindowList(); 467 aura::Window::Windows windows = window_list_provider_->GetWindowList();
258 CHECK(windows.size() >= 2); 468 CHECK(windows.size() >= 2);
259 aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); 469 aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
260 aura::Window* current_window = *(iter); 470 aura::Window* current_window = *(iter);
261 CHECK(wm::IsActiveWindow(current_window));
262 471
263 if (delta > 0) { 472 if (delta > 0) {
264 right_window_ = current_window; 473 right_window_ = current_window;
265 left_window_ = *(iter + 1); 474 left_window_ = *(iter + 1);
266 } else { 475 } else {
267 left_window_ = current_window; 476 left_window_ = current_window;
268 right_window_ = *(iter + 1); 477 right_window_ = *(iter + 1);
269 } 478 }
270 479
271 CHECK(left_window_); 480 CHECK(left_window_);
272 CHECK(right_window_); 481 CHECK(right_window_);
273 482
274 UpdateSeparatorPositionFromScrollDelta(delta); 483 // Calculate divider_scroll_start_position_
pkotwicz 2014/09/23 19:44:46 Nit: "|" around variable name and period at the en
mfomitchev 2014/09/23 21:02:09 Done.
484 gfx::Screen* screen = gfx::Screen::GetScreenFor(container_);
485 const gfx::Rect& display_bounds =
486 screen->GetDisplayNearestWindow(container_).bounds();
487 gfx::Rect container_bounds = container_->GetBoundsInScreen();
488 divider_scroll_start_position_ =
489 delta > 0 ? display_bounds.x() - container_bounds.x()
490 : display_bounds.right() - container_bounds.x();
491
492 divider_position_ = divider_scroll_start_position_ + delta;
275 UpdateLayout(false); 493 UpdateLayout(false);
276 } 494 }
277 495
278 void SplitViewController::ScrollEnd() { 496 void SplitViewController::BezelScrollEnd() {
279 if (state_ != SCROLLING) 497 if (state_ != SCROLLING)
280 return; 498 return;
281 499
282 // Max distance from the scroll end position to the middle of the screen where 500 // Max distance from the scroll end position to the middle of the screen where
283 // we would go into the split view mode. 501 // we would go into the split view mode.
284 const int kMaxDistanceFromMiddle = 120; 502 const int kMaxDistanceFromMiddle = 120;
285 int container_width = container_->GetBoundsInScreen().width(); 503 const int default_divider_position = GetDefaultDividerPosition();
286 if (std::abs(container_width / 2 - separator_position_) <= 504 if (std::abs(default_divider_position - divider_position_) <=
287 kMaxDistanceFromMiddle) { 505 kMaxDistanceFromMiddle) {
506 divider_position_ = default_divider_position;
288 SetState(ACTIVE); 507 SetState(ACTIVE);
289 separator_position_ = container_width / 2; 508 } else if (divider_position_ < default_divider_position) {
290 } else if (separator_position_ < container_width / 2) { 509 divider_position_ = 0;
291 separator_position_ = 0;
292 SetState(INACTIVE); 510 SetState(INACTIVE);
293 wm::ActivateWindow(right_window_); 511 wm::ActivateWindow(right_window_);
294 } else { 512 } else {
295 separator_position_ = container_width; 513 divider_position_ = container_->GetBoundsInScreen().width();
296 SetState(INACTIVE); 514 SetState(INACTIVE);
297 wm::ActivateWindow(left_window_); 515 wm::ActivateWindow(left_window_);
298 } 516 }
299 UpdateLayout(true); 517 UpdateLayout(true);
300 } 518 }
301 519
302 void SplitViewController::ScrollUpdate(float delta) { 520 void SplitViewController::BezelScrollUpdate(float delta) {
303 if (state_ != SCROLLING) 521 if (state_ != SCROLLING)
304 return; 522 return;
305 UpdateSeparatorPositionFromScrollDelta(delta); 523 divider_position_ = divider_scroll_start_position_ + delta;
306 UpdateLayout(false); 524 UpdateLayout(false);
307 } 525 }
308 526
309 bool SplitViewController::CanScroll() { 527 bool SplitViewController::BezelCanScroll() {
310 // TODO(mfomitchev): return false in full screen. 528 // TODO(mfomitchev): return false in full screen.
311 bool result = (!IsSplitViewModeActive() && 529 bool result = (!IsSplitViewModeActive() &&
312 window_list_provider_->GetWindowList().size() >= 2 && 530 window_list_provider_->GetWindowList().size() >= 2 &&
313 IsLandscapeOrientation(gfx::Screen::GetNativeScreen()-> 531 IsLandscapeOrientation(gfx::Screen::GetNativeScreen()->
314 GetDisplayNearestWindow(container_).rotation())); 532 GetDisplayNearestWindow(container_).rotation()));
315 return result; 533 return result;
316 } 534 }
317 535
536 ///////////////////////////////////////////////////////////////////////////////
537 // ScrollHandle::ScrollDelegate:
538
539 void SplitViewController::HandleScrollBegin(float delta) {
540 CHECK(state_ == ACTIVE);
541 state_ = SCROLLING;
542 divider_scroll_start_position_ = GetDefaultDividerPosition();
543 divider_position_ = divider_scroll_start_position_ + delta;
544 UpdateLayout(false);
545 }
546
547 void SplitViewController::HandleScrollEnd() {
548 BezelScrollEnd();
549 }
550
551 void SplitViewController::HandleScrollUpdate(float delta) {
552 BezelScrollUpdate(delta);
553 }
554
555 bool SplitViewController::HandleCanScroll() {
556 CHECK(IsLandscapeOrientation(gfx::Screen::GetNativeScreen()
557 ->GetDisplayNearestWindow(container_)
558 .rotation()));
559 return true;
560 }
561
562 ///////////////////////////////////////////////////////////////////////////////
563 // WindowManagerObserver:
564
565 void SplitViewController::OnOverviewModeEnter() {
566 if (divider_widget_)
567 HideDivider();
568 }
569
570 void SplitViewController::OnOverviewModeExit() {
571 if (state_ != INACTIVE)
572 ShowDivider();
573 }
574
575 void SplitViewController::OnSplitViewModeEnter() {
576 }
577
578 void SplitViewController::OnSplitViewModeExit() {
579 }
580
318 } // namespace athena 581 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698