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

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

Issue 465983002: Add shoftcut (ctrl-f6) to toggle split view (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« 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/common/closure_animation_observer.h"
mfomitchev 2014/08/12 18:52:50 Nice. Not part of this CL, but perhaps ClosureAnim
9 #include "athena/wm/public/window_list_provider.h" 10 #include "athena/wm/public/window_list_provider.h"
10 #include "athena/wm/public/window_manager.h" 11 #include "athena/wm/public/window_manager.h"
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "ui/aura/window.h" 13 #include "ui/aura/window.h"
13 #include "ui/compositor/layer_animation_observer.h" 14 #include "ui/compositor/layer_animation_observer.h"
14 #include "ui/compositor/scoped_layer_animation_settings.h" 15 #include "ui/compositor/scoped_layer_animation_settings.h"
15 #include "ui/events/event_handler.h" 16 #include "ui/events/event_handler.h"
16 #include "ui/gfx/display.h" 17 #include "ui/gfx/display.h"
17 #include "ui/gfx/screen.h" 18 #include "ui/gfx/screen.h"
19 #include "ui/wm/core/window_util.h"
18 20
19 namespace athena { 21 namespace athena {
20 namespace {
21
22 // An animation observer that runs a callback at the end of the animation, and
23 // destroys itself.
24 class CallbackAnimationObserver : public ui::ImplicitAnimationObserver {
25 public:
26 explicit CallbackAnimationObserver(const base::Closure& closure)
27 : closure_(closure) {}
28
29 virtual ~CallbackAnimationObserver() {}
30
31 private:
32 // Overridden from ui::ImplicitAnimationObserver:
33 virtual void OnImplicitAnimationsCompleted() OVERRIDE {
34 if (!closure_.is_null())
35 closure_.Run();
36 delete this;
37 }
38
39 const base::Closure closure_;
40
41 DISALLOW_COPY_AND_ASSIGN(CallbackAnimationObserver);
42 };
43
44 } // namespace
45 22
46 SplitViewController::SplitViewController( 23 SplitViewController::SplitViewController(
47 aura::Window* container, 24 aura::Window* container,
48 WindowListProvider* window_list_provider, 25 WindowListProvider* window_list_provider,
49 WindowManager* window_manager) 26 WindowManager* window_manager)
50 : state_(INACTIVE), 27 : state_(INACTIVE),
51 container_(container), 28 container_(container),
52 window_manager_(window_manager), 29 window_manager_(window_manager),
53 window_list_provider_(window_list_provider), 30 window_list_provider_(window_list_provider),
54 current_activity_window_(NULL), 31 current_activity_window_(NULL),
55 left_window_(NULL), 32 left_window_(NULL),
56 right_window_(NULL), 33 right_window_(NULL),
57 separator_position_(0), 34 separator_position_(0),
58 weak_factory_(this) { 35 weak_factory_(this) {
59 window_manager->AddObserver(this); 36 window_manager->AddObserver(this);
60 } 37 }
61 38
62 SplitViewController::~SplitViewController() { 39 SplitViewController::~SplitViewController() {
63 window_manager_->RemoveObserver(this); 40 window_manager_->RemoveObserver(this);
64 } 41 }
65 42
66 bool SplitViewController::IsSplitViewModeActive() const { 43 bool SplitViewController::IsSplitViewModeActive() const {
67 return state_ == ACTIVE; 44 return state_ == ACTIVE;
68 } 45 }
69 46
47 void SplitViewController::ToggleSplitView() {
48 if (IsSplitViewModeActive()) {
49 const gfx::Transform transform;
mfomitchev 2014/08/12 18:52:50 Can you add a TODO(mfomitchev): Use UpdateLayout()
50 left_window_->SetTransform(transform);
51 right_window_->SetTransform(transform);
52 left_window_->SetBounds(container_->bounds());
53 right_window_->SetBounds(container_->bounds());
54 left_window_ = NULL;
55 right_window_ = NULL;
56 current_activity_window_ = NULL;
57 state_ = INACTIVE;
58 } else if (window_list_provider_->GetWindowList().size() > 1) {
59 left_window_ = GetCurrentActivityWindow();
mfomitchev 2014/08/12 18:52:50 I'd use left_window_ and right_window if they are
mfomitchev 2014/08/13 15:08:47 You can also use ActivateSplitMode() if you land t
60 const aura::Window::Windows& windows =
61 window_list_provider_->GetWindowList();
62 const aura::Window::Windows::const_iterator iter =
63 std::find(windows.begin(), windows.end(), left_window_);
64 // TODO(oshima): Make WindowManagerImpl accessible within athena/wm.
65 right_window_ = (iter == windows.begin() ? *(iter + 1) : * (iter - 1));
66
67 separator_position_ = container_->bounds().width() / 2;
68
69 const gfx::Transform transform;
70 left_window_->SetTransform(transform);
71 right_window_->SetTransform(transform);
72 const gfx::Rect& bounds = container_->bounds();
73 int middle = bounds.width() / 2;
74 left_window_->SetBounds(gfx::Rect(0, 0, middle, bounds.height()));
75 right_window_->SetBounds(gfx::Rect(middle, 0, middle, bounds.height()));
76 state_ = ACTIVE;
77 }
78 }
79
70 void SplitViewController::UpdateLayout(bool animate) { 80 void SplitViewController::UpdateLayout(bool animate) {
71 if (!left_window_) 81 if (!left_window_)
72 return; 82 return;
73 CHECK(right_window_); 83 CHECK(right_window_);
74 gfx::Transform left_transform; 84 gfx::Transform left_transform;
75 gfx::Transform right_transform; 85 gfx::Transform right_transform;
76 int container_width = container_->GetBoundsInScreen().width(); 86 int container_width = container_->bounds().width();
77 if (state_ == ACTIVE) { 87 if (state_ == ACTIVE) {
78 // This method should only be called once in ACTIVE state when 88 // This method should only be called once in ACTIVE state when
79 // the left and rightwindows are still full screen and need to be resized. 89 // the left and rightwindows are still full screen and need to be resized.
80 CHECK_EQ(left_window_->bounds().width(), container_width); 90 CHECK_EQ(left_window_->bounds().width(), container_width);
81 CHECK_EQ(right_window_->bounds().width(), container_width); 91 CHECK_EQ(right_window_->bounds().width(), container_width);
82 // Windows should be resized via an animation when entering the ACTIVE 92 // Windows should be resized via an animation when entering the ACTIVE
83 // state. 93 // state.
84 CHECK(animate); 94 CHECK(animate);
85 // We scale the windows here, but when the animation finishes, we reset 95 // We scale the windows here, but when the animation finishes, we reset
86 // the scaling and update the window bounds to the proper size - see 96 // the scaling and update the window bounds to the proper size - see
(...skipping 12 matching lines...) Expand all
99 } 109 }
100 110
101 void SplitViewController::SetWindowTransform(aura::Window* window, 111 void SplitViewController::SetWindowTransform(aura::Window* window,
102 const gfx::Transform& transform, 112 const gfx::Transform& transform,
103 bool animate) { 113 bool animate) {
104 if (animate) { 114 if (animate) {
105 scoped_refptr<ui::LayerAnimator> animator = window->layer()->GetAnimator(); 115 scoped_refptr<ui::LayerAnimator> animator = window->layer()->GetAnimator();
106 ui::ScopedLayerAnimationSettings settings(animator); 116 ui::ScopedLayerAnimationSettings settings(animator);
107 settings.SetPreemptionStrategy( 117 settings.SetPreemptionStrategy(
108 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 118 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
109 settings.AddObserver(new CallbackAnimationObserver( 119 settings.AddObserver(new ClosureAnimationObserver(
110 base::Bind(&SplitViewController::OnAnimationCompleted, 120 base::Bind(&SplitViewController::OnAnimationCompleted,
111 weak_factory_.GetWeakPtr(), 121 weak_factory_.GetWeakPtr(),
112 window))); 122 window)));
113 window->SetTransform(transform); 123 window->SetTransform(transform);
114 } else { 124 } else {
115 window->SetTransform(transform); 125 window->SetTransform(transform);
116 } 126 }
117 } 127 }
118 128
119 void SplitViewController::OnAnimationCompleted(aura::Window* window) { 129 void SplitViewController::OnAnimationCompleted(aura::Window* window) {
(...skipping 23 matching lines...) Expand all
143 if (state_ == INACTIVE) 153 if (state_ == INACTIVE)
144 right_window_ = NULL; 154 right_window_ = NULL;
145 } 155 }
146 } 156 }
147 } 157 }
148 158
149 void SplitViewController::UpdateSeparatorPositionFromScrollDelta(float delta) { 159 void SplitViewController::UpdateSeparatorPositionFromScrollDelta(float delta) {
150 gfx::Screen* screen = gfx::Screen::GetScreenFor(container_); 160 gfx::Screen* screen = gfx::Screen::GetScreenFor(container_);
151 const gfx::Rect& display_bounds = 161 const gfx::Rect& display_bounds =
152 screen->GetDisplayNearestWindow(container_).bounds(); 162 screen->GetDisplayNearestWindow(container_).bounds();
153 gfx::Rect container_bounds = container_->GetBoundsInScreen(); 163 gfx::Rect container_bounds = container_->bounds();
154 separator_position_ = 164 separator_position_ =
155 delta > 0 ? ((int)delta) + display_bounds.x() - container_bounds.x() 165 delta > 0 ? ((int)delta) + display_bounds.x() - container_bounds.x()
156 : display_bounds.right() - container_bounds.x() + delta; 166 : display_bounds.right() - container_bounds.x() + delta;
157 } 167 }
158 168
159 aura::Window* SplitViewController::GetCurrentActivityWindow() { 169 aura::Window* SplitViewController::GetCurrentActivityWindow() {
160 if (!current_activity_window_) { 170 if (!current_activity_window_) {
161 aura::Window::Windows windows = window_list_provider_->GetWindowList(); 171 aura::Window::Windows windows = window_list_provider_->GetWindowList();
162 if (windows.empty()) 172 if (windows.empty())
163 return NULL; 173 return NULL;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 UpdateLayout(false); 220 UpdateLayout(false);
211 } 221 }
212 222
213 // Max distance from the scroll end position to the middle of the screen where 223 // Max distance from the scroll end position to the middle of the screen where
214 // we would go into the split view mode. 224 // we would go into the split view mode.
215 const int kMaxDistanceFromMiddle = 120; 225 const int kMaxDistanceFromMiddle = 120;
216 void SplitViewController::ScrollEnd() { 226 void SplitViewController::ScrollEnd() {
217 if (state_ != SCROLLING) 227 if (state_ != SCROLLING)
218 return; 228 return;
219 229
220 int container_width = container_->GetBoundsInScreen().width(); 230 int container_width = container_->bounds().width();
221 if (std::abs(container_width / 2 - separator_position_) <= 231 if (std::abs(container_width / 2 - separator_position_) <=
222 kMaxDistanceFromMiddle) { 232 kMaxDistanceFromMiddle) {
223 state_ = ACTIVE; 233 state_ = ACTIVE;
224 separator_position_ = container_width / 2; 234 separator_position_ = container_width / 2;
225 } else if (separator_position_ < container_width / 2) { 235 } else if (separator_position_ < container_width / 2) {
226 separator_position_ = 0; 236 separator_position_ = 0;
227 current_activity_window_ = right_window_; 237 current_activity_window_ = right_window_;
228 state_ = INACTIVE; 238 state_ = INACTIVE;
229 } else { 239 } else {
230 separator_position_ = container_width; 240 separator_position_ = container_width;
231 current_activity_window_ = left_window_; 241 current_activity_window_ = left_window_;
232 state_ = INACTIVE; 242 state_ = INACTIVE;
233 } 243 }
234 UpdateLayout(true); 244 UpdateLayout(true);
235 } 245 }
236 246
237 void SplitViewController::ScrollUpdate(float delta) { 247 void SplitViewController::ScrollUpdate(float delta) {
238 if (state_ != SCROLLING) 248 if (state_ != SCROLLING)
239 return; 249 return;
240 UpdateSeparatorPositionFromScrollDelta(delta); 250 UpdateSeparatorPositionFromScrollDelta(delta);
241 UpdateLayout(false); 251 UpdateLayout(false);
242 } 252 }
243 253
244 bool SplitViewController::CanScroll() { 254 bool SplitViewController::CanScroll() {
245 // TODO(mfomitchev): return false in vertical orientation, in full screen. 255 // TODO(mfomitchev): return false in vertical orientation, in full screen.
246 bool result = (!window_manager_->IsOverviewModeActive() && 256 bool result =
247 !IsSplitViewModeActive() && 257 (!window_manager_->IsOverviewModeActive() && !IsSplitViewModeActive() &&
248 window_list_provider_->GetWindowList().size() >= 2); 258 window_list_provider_->GetWindowList().size() >= 2);
249 return result; 259 return result;
250 } 260 }
251 261
252 /////////////////////////////////////////////////////////////////////////////// 262 ///////////////////////////////////////////////////////////////////////////////
253 // WindowManagerObserver overrides 263 // WindowManagerObserver overrides
254 void SplitViewController::OnOverviewModeEnter() { 264 void SplitViewController::OnOverviewModeEnter() {
255 if (state_ == ACTIVE) { 265 if (state_ == ACTIVE) {
256 CHECK(left_window_); 266 ToggleSplitView();
mfomitchev 2014/08/12 18:52:50 Not doing MoveToFront() can screw up the window or
257 CHECK(right_window_);
258 window_list_provider_->MoveToFront(right_window_);
259 window_list_provider_->MoveToFront(left_window_);
260 // TODO(mfomitchev): This shouldn't be done here, but the overview mode's
261 // transition animation currently looks bad if the starting transform of
262 // any window is not gfx::Transform().
263 right_window_->SetTransform(gfx::Transform());
264 } else if (current_activity_window_) { 267 } else if (current_activity_window_) {
268 CHECK_EQ(INACTIVE, state_);
mfomitchev 2014/08/12 18:52:50 This may not hold - you can hit the overview hot k
265 window_list_provider_->MoveToFront(current_activity_window_); 269 window_list_provider_->MoveToFront(current_activity_window_);
270 left_window_ = NULL;
271 right_window_ = NULL;
272 current_activity_window_ = NULL;
266 } 273 }
267 state_ = INACTIVE;
268 left_window_ = NULL;
269 right_window_ = NULL;
270 current_activity_window_ = NULL;
271 } 274 }
272 275
273 void SplitViewController::OnOverviewModeExit() { 276 void SplitViewController::OnOverviewModeExit() {
274 } 277 }
275 278
276 } // namespace athena 279 } // 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