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

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

Issue 602603003: Revert of Adding split view divider widget. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « athena/wm/split_view_controller.h ('k') | athena/wm/window_manager_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
14 #include "ui/aura/window.h" 13 #include "ui/aura/window.h"
15 #include "ui/aura/window_targeter.h"
16 #include "ui/compositor/closure_animation_observer.h" 14 #include "ui/compositor/closure_animation_observer.h"
17 #include "ui/compositor/layer.h" 15 #include "ui/compositor/layer_animation_observer.h"
18 #include "ui/compositor/scoped_layer_animation_settings.h" 16 #include "ui/compositor/scoped_layer_animation_settings.h"
19 #include "ui/events/event_handler.h" 17 #include "ui/events/event_handler.h"
20 #include "ui/gfx/display.h" 18 #include "ui/gfx/display.h"
21 #include "ui/gfx/screen.h" 19 #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"
27 #include "ui/wm/core/window_util.h" 20 #include "ui/wm/core/window_util.h"
28 21
29 namespace athena { 22 namespace athena {
30 23
31 namespace { 24 namespace {
32 25
33 const int kDragHandleWidth = 4; 26 // Returns a target transform which is suitable for animating a windows's
34 const int kDragHandleHeight = 80; 27 // bounds.
35 const int kDragHandleMargin = 1; 28 gfx::Transform GetTargetTransformForBoundsAnimation(const gfx::Rect& from,
36 const int kDividerWidth = kDragHandleWidth + 2 * kDragHandleMargin; 29 const gfx::Rect& to) {
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) {
135 gfx::Transform transform; 30 gfx::Transform transform;
136 transform.Translate(to.x() - from.x(), to.y() - from.y()); 31 transform.Translate(to.x() - from.x(), to.y() - from.y());
137 transform.Scale(to.width() / static_cast<float>(from.width()), 32 transform.Scale(to.width() / static_cast<float>(from.width()),
138 to.height() / static_cast<float>(from.height())); 33 to.height() / static_cast<float>(from.height()));
139 return transform; 34 return transform;
140 } 35 }
141 36
142 bool IsLandscapeOrientation(gfx::Display::Rotation rotation) { 37 bool IsLandscapeOrientation(gfx::Display::Rotation rotation) {
143 return rotation == gfx::Display::ROTATE_0 || 38 return rotation == gfx::Display::ROTATE_0 ||
144 rotation == gfx::Display::ROTATE_180; 39 rotation == gfx::Display::ROTATE_180;
145 } 40 }
146 41
147 } // namespace 42 } // namespace
148 43
149 SplitViewController::SplitViewController( 44 SplitViewController::SplitViewController(
150 aura::Window* container, 45 aura::Window* container,
151 WindowListProvider* window_list_provider) 46 WindowListProvider* window_list_provider)
152 : state_(INACTIVE), 47 : state_(INACTIVE),
153 container_(container), 48 container_(container),
154 window_list_provider_(window_list_provider), 49 window_list_provider_(window_list_provider),
155 left_window_(NULL), 50 left_window_(NULL),
156 right_window_(NULL), 51 right_window_(NULL),
157 divider_position_(0), 52 separator_position_(0),
158 divider_scroll_start_position_(0),
159 divider_widget_(NULL),
160 drag_handle_(NULL),
161 weak_factory_(this) { 53 weak_factory_(this) {
162 } 54 }
163 55
164 SplitViewController::~SplitViewController() { 56 SplitViewController::~SplitViewController() {
165 } 57 }
166 58
167 bool SplitViewController::CanActivateSplitViewMode() const { 59 bool SplitViewController::CanActivateSplitViewMode() const {
168 // TODO(mfomitchev): return false in full screen. 60 // TODO(mfomitchev): return false in full screen.
169 return (!IsSplitViewModeActive() && 61 return (!IsSplitViewModeActive() &&
170 window_list_provider_->GetWindowList().size() >= 2 && 62 window_list_provider_->GetWindowList().size() >= 2 &&
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 iter++; 96 iter++;
205 } 97 }
206 } 98 }
207 99
208 to_hide_.clear(); 100 to_hide_.clear();
209 if (left_window_ && left_window_ != left && left_window_ != right) 101 if (left_window_ && left_window_ != left && left_window_ != right)
210 to_hide_.push_back(left_window_); 102 to_hide_.push_back(left_window_);
211 if (right_window_ && right_window_ != left && right_window_ != right) 103 if (right_window_ && right_window_ != left && right_window_ != right)
212 to_hide_.push_back(right_window_); 104 to_hide_.push_back(right_window_);
213 105
214 divider_position_ = GetDefaultDividerPosition();
215 SetState(ACTIVE); 106 SetState(ACTIVE);
216 right_window_ = right; 107 right_window_ = right;
217 left_window_ = left; 108 left_window_ = left;
218 UpdateLayout(true); 109 UpdateLayout(true);
219 } 110 }
220 111
221 void SplitViewController::ReplaceWindow(aura::Window* window, 112 void SplitViewController::ReplaceWindow(aura::Window* window,
222 aura::Window* replace_with) { 113 aura::Window* replace_with) {
223 CHECK(IsSplitViewModeActive()); 114 CHECK(IsSplitViewModeActive());
224 CHECK(replace_with); 115 CHECK(replace_with);
(...skipping 11 matching lines...) Expand all
236 window->Hide(); 127 window->Hide();
237 } 128 }
238 129
239 void SplitViewController::DeactivateSplitMode() { 130 void SplitViewController::DeactivateSplitMode() {
240 CHECK_EQ(ACTIVE, state_); 131 CHECK_EQ(ACTIVE, state_);
241 SetState(INACTIVE); 132 SetState(INACTIVE);
242 UpdateLayout(false); 133 UpdateLayout(false);
243 left_window_ = right_window_ = NULL; 134 left_window_ = right_window_ = NULL;
244 } 135 }
245 136
246 void SplitViewController::InitializeDivider() { 137 gfx::Rect SplitViewController::GetLeftTargetBounds() {
247 CHECK(!divider_widget_); 138 gfx::Rect work_area =
248 CHECK(!drag_handle_); 139 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
249 140 return gfx::Rect(0, 0, container_->bounds().width() / 2, work_area.height());
250 drag_handle_ = CreateDragHandleView(DRAG_HANDLE_HORIZONTAL,
251 this,
252 kDragHandleWidth,
253 kDragHandleHeight);
254 views::View* content_view = new views::View;
255 content_view->set_background(
256 views::Background::CreateSolidBackground(SK_ColorBLACK));
257 views::BoxLayout* layout =
258 new views::BoxLayout(views::BoxLayout::kHorizontal,
259 kDragHandleMargin,
260 kDragHandleMargin,
261 0);
262 layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
263 layout->set_cross_axis_alignment(
264 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
265 content_view->SetLayoutManager(layout);
266 content_view->AddChildView(drag_handle_);
267
268 divider_widget_ = new views::Widget();
269 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
270 params.parent = container_;
271 params.bounds = gfx::Rect(-kDividerWidth / 2,
272 0,
273 kDividerWidth,
274 container_->bounds().height());
275 divider_widget_->Init(params);
276 divider_widget_->SetContentsView(content_view);
277
278 // Install a static view targeter on the root view which always targets
279 // divider_view.
280 // TODO(mfomitchev,tdanderson): This should not be needed:
281 // 1. crbug.com/414339 - divider_view is the only view and it completely
282 // overlaps the root view.
283 // 2. The logic in ViewTargeterDelegate::TargetForRect could be improved to
284 // work better for views that are narrow in one dimension and long in
285 // another dimension.
286 views::internal::RootView* root_view =
287 static_cast<views::internal::RootView*>(divider_widget_->GetRootView());
288 view_targeter_delegate_.reset(new StaticViewTargeterDelegate(drag_handle_));
289 views::ViewTargeter* targeter =
290 new views::RootViewTargeter(view_targeter_delegate_.get(), root_view);
291 divider_widget_->GetRootView()->SetEventTargeter(
292 scoped_ptr<views::ViewTargeter>(targeter));
293 } 141 }
294 142
295 void SplitViewController::HideDivider() { 143 gfx::Rect SplitViewController::GetRightTargetBounds() {
296 divider_widget_->Hide();
297 window_targeter_.reset();
298 }
299
300 void SplitViewController::ShowDivider() {
301 divider_widget_->Show();
302 if (!window_targeter_) {
303 scoped_ptr<ui::EventTargeter> window_targeter =
304 scoped_ptr<ui::EventTargeter>(new PriorityWindowTargeter(drag_handle_));
305 window_targeter_.reset(
306 new aura::ScopedWindowTargeter(container_, window_targeter.Pass()));
307 }
308 }
309
310 gfx::Rect SplitViewController::GetLeftAreaBounds() {
311 gfx::Rect work_area =
312 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
313 return gfx::Rect(
314 0, 0, divider_position_ - kDividerWidth / 2, work_area.height());
315 }
316
317 gfx::Rect SplitViewController::GetRightAreaBounds() {
318 gfx::Rect work_area = 144 gfx::Rect work_area =
319 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area(); 145 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
320 int container_width = container_->bounds().width(); 146 int container_width = container_->bounds().width();
321 return gfx::Rect(divider_position_ + kDividerWidth / 2, 147 return gfx::Rect(
322 0, 148 container_width / 2, 0, container_width / 2, work_area.height());
323 container_width - divider_position_ - kDividerWidth / 2,
324 work_area.height());
325 } 149 }
326 150
327 void SplitViewController::SetState(SplitViewController::State state) { 151 void SplitViewController::SetState(SplitViewController::State state) {
328 if (state_ == state) 152 if (state_ == state)
329 return; 153 return;
330 154
331 if (divider_widget_ == NULL)
332 InitializeDivider();
333
334 state_ = state; 155 state_ = state;
335
336 ScreenManager::Get()->SetRotationLocked(state_ != INACTIVE); 156 ScreenManager::Get()->SetRotationLocked(state_ != INACTIVE);
337 if (state == INACTIVE)
338 HideDivider();
339 else
340 ShowDivider();
341 } 157 }
342 158
343 void SplitViewController::UpdateLayout(bool animate) { 159 void SplitViewController::UpdateLayout(bool animate) {
344 CHECK(left_window_); 160 CHECK(left_window_);
345 CHECK(right_window_); 161 CHECK(right_window_);
162
346 // Splitview can be activated from SplitViewController::ActivateSplitMode or 163 // Splitview can be activated from SplitViewController::ActivateSplitMode or
347 // SplitViewController::ScrollEnd. Additionally we don't want to rotate the 164 // SplitViewController::ScrollEnd. Additionally we don't want to rotate the
348 // screen while engaging splitview (i.e. state_ == SCROLLING). 165 // screen while engaging splitview (i.e. state_ == SCROLLING).
349 if (state_ == INACTIVE && !animate) { 166 if (state_ == INACTIVE && !animate) {
350 gfx::Rect work_area = 167 if (!wm::IsActiveWindow(left_window_))
351 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area();
352 aura::Window* top_window = window_list_provider_->GetWindowList().back();
353 if (top_window != left_window_) {
354 // TODO(mfomitchev): Use to_hide_ instead
355 left_window_->Hide(); 168 left_window_->Hide();
356 right_window_->SetBounds(gfx::Rect(work_area.size())); 169 if (!wm::IsActiveWindow(right_window_))
357 }
358 if (top_window != right_window_) {
359 left_window_->SetBounds(gfx::Rect(work_area.size()));
360 // TODO(mfomitchev): Use to_hide_ instead
361 right_window_->Hide(); 170 right_window_->Hide();
362 } 171 SetWindowTransforms(gfx::Transform(), gfx::Transform(), false);
363 SetWindowTransforms(
364 gfx::Transform(), gfx::Transform(), gfx::Transform(), false);
365 return; 172 return;
366 } 173 }
367 174
368 left_window_->Show(); 175 left_window_->Show();
369 right_window_->Show(); 176 right_window_->Show();
370 window_list_provider_->MoveToFront(right_window_); 177 window_list_provider_->MoveToFront(right_window_);
371 window_list_provider_->MoveToFront(left_window_); 178 window_list_provider_->MoveToFront(left_window_);
372 179
373 gfx::Transform divider_transform;
374 divider_transform.Translate(divider_position_, 0);
375 if (state_ == ACTIVE) { 180 if (state_ == ACTIVE) {
376 if (animate) { 181 if (animate) {
377 gfx::Transform left_transform = 182 gfx::Transform left_transform = GetTargetTransformForBoundsAnimation(
378 GetTransformForBounds(left_window_->bounds(), GetLeftAreaBounds()); 183 left_window_->bounds(), GetLeftTargetBounds());
379 gfx::Transform right_transform = 184 gfx::Transform right_transform = GetTargetTransformForBoundsAnimation(
380 GetTransformForBounds(right_window_->bounds(), GetRightAreaBounds()); 185 right_window_->bounds(), GetRightTargetBounds());
381 SetWindowTransforms( 186 SetWindowTransforms(left_transform, right_transform, true);
382 left_transform, right_transform, divider_transform, true);
383 } else { 187 } else {
384 left_window_->SetBounds(GetLeftAreaBounds()); 188 left_window_->SetBounds(GetLeftTargetBounds());
385 right_window_->SetBounds(GetRightAreaBounds()); 189 right_window_->SetBounds(GetRightTargetBounds());
386 SetWindowTransforms( 190 SetWindowTransforms(gfx::Transform(), gfx::Transform(), false);
387 gfx::Transform(), gfx::Transform(), divider_transform, false);
388 } 191 }
389 } else { 192 } else {
390 gfx::Transform left_transform; 193 gfx::Transform left_transform;
194 left_transform.Translate(separator_position_ - container_->bounds().width(),
195 0);
391 gfx::Transform right_transform; 196 gfx::Transform right_transform;
392 gfx::Rect left_area_bounds = GetLeftAreaBounds(); 197 right_transform.Translate(separator_position_, 0);
393 gfx::Rect right_area_bounds = GetRightAreaBounds(); 198 SetWindowTransforms(left_transform, right_transform, animate);
394 // If the width of the window is greater than the width of the area which it
395 // is supposed to occupy - translate the window. Otherwise scale the window
396 // up to fill the target area.
397 if (left_window_->bounds().width() >= left_area_bounds.width()) {
398 left_transform.Translate(
399 left_area_bounds.right() - left_window_->bounds().right(), 0);
400 } else {
401 left_transform =
402 GetTransformForBounds(left_window_->bounds(), left_area_bounds);
403 }
404 if (right_window_->bounds().width() >= right_area_bounds.width()) {
405 right_transform.Translate(
406 right_area_bounds.x() - right_window_->bounds().x(), 0);
407 } else {
408 right_transform =
409 GetTransformForBounds(right_window_->bounds(), right_area_bounds);
410 }
411 SetWindowTransforms(
412 left_transform, right_transform, divider_transform, animate);
413 } 199 }
414 // Note: |left_window_| and |right_window_| may be NULL if calling 200 // Note: |left_window_| and |right_window_| may be NULL if calling
415 // SetWindowTransforms(): 201 // SetWindowTransforms():
416 // - caused the in-progress animation to abort. 202 // - caused the in-progress animation to abort.
417 // - started a zero duration animation. 203 // - started a zero duration animation.
418 } 204 }
419 205
420 void SplitViewController::SetWindowTransforms( 206 void SplitViewController::SetWindowTransforms(
421 const gfx::Transform& left_transform, 207 const gfx::Transform& left_transform,
422 const gfx::Transform& right_transform, 208 const gfx::Transform& right_transform,
423 const gfx::Transform& divider_transform,
424 bool animate) { 209 bool animate) {
425 if (animate) { 210 if (animate) {
426 ui::ScopedLayerAnimationSettings left_settings( 211 ui::ScopedLayerAnimationSettings left_settings(
427 left_window_->layer()->GetAnimator()); 212 left_window_->layer()->GetAnimator());
428 left_settings.SetPreemptionStrategy( 213 left_settings.SetPreemptionStrategy(
429 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 214 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
430 left_window_->SetTransform(left_transform); 215 left_window_->SetTransform(left_transform);
431 216
432 ui::ScopedLayerAnimationSettings divider_widget_settings(
433 divider_widget_->GetNativeWindow()->layer()->GetAnimator());
434 divider_widget_settings.SetPreemptionStrategy(
435 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
436 divider_widget_->GetNativeWindow()->SetTransform(divider_transform);
437
438 ui::ScopedLayerAnimationSettings right_settings( 217 ui::ScopedLayerAnimationSettings right_settings(
439 right_window_->layer()->GetAnimator()); 218 right_window_->layer()->GetAnimator());
440 right_settings.SetPreemptionStrategy( 219 right_settings.SetPreemptionStrategy(
441 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 220 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
442 right_settings.AddObserver(new ui::ClosureAnimationObserver( 221 right_settings.AddObserver(new ui::ClosureAnimationObserver(
443 base::Bind(&SplitViewController::OnAnimationCompleted, 222 base::Bind(&SplitViewController::OnAnimationCompleted,
444 weak_factory_.GetWeakPtr()))); 223 weak_factory_.GetWeakPtr())));
445 right_window_->SetTransform(right_transform); 224 right_window_->SetTransform(right_transform);
446 } else { 225 } else {
447 left_window_->SetTransform(left_transform); 226 left_window_->SetTransform(left_transform);
448 divider_widget_->GetNativeWindow()->SetTransform(divider_transform);
449 right_window_->SetTransform(right_transform); 227 right_window_->SetTransform(right_transform);
450 } 228 }
451 } 229 }
452 230
453 void SplitViewController::OnAnimationCompleted() { 231 void SplitViewController::OnAnimationCompleted() {
454 // Animation can be cancelled when deactivated. 232 // Animation can be cancelled when deactivated.
455 if (left_window_ == NULL) 233 if (left_window_ == NULL)
456 return; 234 return;
457 UpdateLayout(false); 235 UpdateLayout(false);
458 236
459 for (size_t i = 0; i < to_hide_.size(); ++i) 237 for (size_t i = 0; i < to_hide_.size(); ++i)
460 to_hide_[i]->Hide(); 238 to_hide_[i]->Hide();
461 to_hide_.clear(); 239 to_hide_.clear();
462 240
463 if (state_ == INACTIVE) { 241 if (state_ == INACTIVE) {
464 left_window_ = NULL; 242 left_window_ = NULL;
465 right_window_ = NULL; 243 right_window_ = NULL;
466 } 244 }
467 } 245 }
468 246
469 int SplitViewController::GetDefaultDividerPosition() { 247 void SplitViewController::UpdateSeparatorPositionFromScrollDelta(float delta) {
470 return container_->GetBoundsInScreen().width() / 2; 248 gfx::Screen* screen = gfx::Screen::GetScreenFor(container_);
249 const gfx::Rect& display_bounds =
250 screen->GetDisplayNearestWindow(container_).bounds();
251 gfx::Rect container_bounds = container_->GetBoundsInScreen();
252 separator_position_ =
253 delta > 0 ? ((int)delta) + display_bounds.x() - container_bounds.x()
254 : display_bounds.right() - container_bounds.x() + delta;
471 } 255 }
472 256
473 /////////////////////////////////////////////////////////////////////////////// 257 ///////////////////////////////////////////////////////////////////////////////
474 // BezelController::ScrollDelegate: 258 // BezelController::ScrollDelegate:
475 259
476 void SplitViewController::BezelScrollBegin(BezelController::Bezel bezel, 260 void SplitViewController::ScrollBegin(BezelController::Bezel bezel,
477 float delta) { 261 float delta) {
478 if (!BezelCanScroll()) 262 if (!CanScroll())
479 return; 263 return;
480
481 SetState(SCROLLING); 264 SetState(SCROLLING);
482 265
483 const aura::Window::Windows& windows = window_list_provider_->GetWindowList(); 266 const aura::Window::Windows& windows = window_list_provider_->GetWindowList();
484 CHECK(windows.size() >= 2); 267 CHECK(windows.size() >= 2);
485 aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); 268 aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
486 aura::Window* current_window = *(iter); 269 aura::Window* current_window = *(iter);
270 CHECK(wm::IsActiveWindow(current_window));
487 271
488 if (delta > 0) { 272 if (delta > 0) {
489 right_window_ = current_window; 273 right_window_ = current_window;
490 left_window_ = *(iter + 1); 274 left_window_ = *(iter + 1);
491 } else { 275 } else {
492 left_window_ = current_window; 276 left_window_ = current_window;
493 right_window_ = *(iter + 1); 277 right_window_ = *(iter + 1);
494 } 278 }
495 279
496 CHECK(left_window_); 280 CHECK(left_window_);
497 CHECK(right_window_); 281 CHECK(right_window_);
498 282
499 // Calculate divider_scroll_start_position_ 283 UpdateSeparatorPositionFromScrollDelta(delta);
500 gfx::Screen* screen = gfx::Screen::GetScreenFor(container_);
501 const gfx::Rect& display_bounds =
502 screen->GetDisplayNearestWindow(container_).bounds();
503 gfx::Rect container_bounds = container_->GetBoundsInScreen();
504 divider_scroll_start_position_ =
505 delta > 0 ? display_bounds.x() - container_bounds.x()
506 : display_bounds.right() - container_bounds.x();
507
508 divider_position_ = divider_scroll_start_position_ + delta;
509 UpdateLayout(false); 284 UpdateLayout(false);
510 } 285 }
511 286
512 void SplitViewController::BezelScrollEnd() { 287 void SplitViewController::ScrollEnd() {
513 if (state_ != SCROLLING) 288 if (state_ != SCROLLING)
514 return; 289 return;
515 290
516 // Max distance from the scroll end position to the middle of the screen where 291 // Max distance from the scroll end position to the middle of the screen where
517 // we would go into the split view mode. 292 // we would go into the split view mode.
518 const int kMaxDistanceFromMiddle = 120; 293 const int kMaxDistanceFromMiddle = 120;
519 const int default_divider_position = GetDefaultDividerPosition(); 294 int container_width = container_->GetBoundsInScreen().width();
520 if (std::abs(default_divider_position - divider_position_) <= 295 if (std::abs(container_width / 2 - separator_position_) <=
521 kMaxDistanceFromMiddle) { 296 kMaxDistanceFromMiddle) {
522 divider_position_ = default_divider_position;
523 SetState(ACTIVE); 297 SetState(ACTIVE);
524 } else if (divider_position_ < default_divider_position) { 298 separator_position_ = container_width / 2;
525 divider_position_ = 0; 299 } else if (separator_position_ < container_width / 2) {
300 separator_position_ = 0;
526 SetState(INACTIVE); 301 SetState(INACTIVE);
527 wm::ActivateWindow(right_window_); 302 wm::ActivateWindow(right_window_);
528 } else { 303 } else {
529 divider_position_ = container_->GetBoundsInScreen().width(); 304 separator_position_ = container_width;
530 SetState(INACTIVE); 305 SetState(INACTIVE);
531 wm::ActivateWindow(left_window_); 306 wm::ActivateWindow(left_window_);
532 } 307 }
533 UpdateLayout(true); 308 UpdateLayout(true);
534 } 309 }
535 310
536 void SplitViewController::BezelScrollUpdate(float delta) { 311 void SplitViewController::ScrollUpdate(float delta) {
537 if (state_ != SCROLLING) 312 if (state_ != SCROLLING)
538 return; 313 return;
539 divider_position_ = divider_scroll_start_position_ + delta; 314 UpdateSeparatorPositionFromScrollDelta(delta);
540 UpdateLayout(false); 315 UpdateLayout(false);
541 } 316 }
542 317
543 bool SplitViewController::BezelCanScroll() { 318 bool SplitViewController::CanScroll() {
544 return CanActivateSplitViewMode(); 319 return CanActivateSplitViewMode();
545 } 320 }
546 321
547 ///////////////////////////////////////////////////////////////////////////////
548 // DragHandleScrollDelegate:
549
550 void SplitViewController::HandleScrollBegin(float delta) {
551 CHECK(state_ == ACTIVE);
552 state_ = SCROLLING;
553 divider_scroll_start_position_ = GetDefaultDividerPosition();
554 divider_position_ = divider_scroll_start_position_ + delta;
555 UpdateLayout(false);
556 }
557
558 void SplitViewController::HandleScrollEnd() {
559 BezelScrollEnd();
560 }
561
562 void SplitViewController::HandleScrollUpdate(float delta) {
563 BezelScrollUpdate(delta);
564 }
565
566 ///////////////////////////////////////////////////////////////////////////////
567 // WindowManagerObserver:
568
569 void SplitViewController::OnOverviewModeEnter() {
570 if (divider_widget_)
571 HideDivider();
572 }
573
574 void SplitViewController::OnOverviewModeExit() {
575 if (state_ != INACTIVE)
576 ShowDivider();
577 }
578
579 void SplitViewController::OnSplitViewModeEnter() {
580 }
581
582 void SplitViewController::OnSplitViewModeExit() {
583 }
584
585 } // namespace athena 322 } // namespace athena
OLDNEW
« no previous file with comments | « athena/wm/split_view_controller.h ('k') | athena/wm/window_manager_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698