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

Side by Side Diff: ash/wm/overview/window_selector_item.cc

Issue 2918403006: CrOS Tablet Window management - Split Screen part I (Closed)
Patch Set: Add unittests. Will split the CL into two CLs. Created 3 years, 5 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 | « ash/wm/overview/window_selector_item.h ('k') | ash/wm/splitview/split_view_controller.h » ('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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "ash/wm/overview/window_selector_item.h" 5 #include "ash/wm/overview/window_selector_item.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "ash/metrics/user_metrics_action.h" 10 #include "ash/metrics/user_metrics_action.h"
11 #include "ash/metrics/user_metrics_recorder.h" 11 #include "ash/metrics/user_metrics_recorder.h"
12 #include "ash/public/cpp/shell_window_ids.h" 12 #include "ash/public/cpp/shell_window_ids.h"
13 #include "ash/resources/vector_icons/vector_icons.h" 13 #include "ash/resources/vector_icons/vector_icons.h"
14 #include "ash/root_window_controller.h" 14 #include "ash/root_window_controller.h"
15 #include "ash/shell.h" 15 #include "ash/shell.h"
16 #include "ash/wm/maximize_mode/maximize_mode_controller.h" 16 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
17 #include "ash/wm/overview/cleanup_animation_observer.h" 17 #include "ash/wm/overview/cleanup_animation_observer.h"
18 #include "ash/wm/overview/overview_animation_type.h" 18 #include "ash/wm/overview/overview_animation_type.h"
19 #include "ash/wm/overview/scoped_overview_animation_settings.h" 19 #include "ash/wm/overview/scoped_overview_animation_settings.h"
20 #include "ash/wm/overview/scoped_transform_overview_window.h" 20 #include "ash/wm/overview/scoped_transform_overview_window.h"
21 #include "ash/wm/overview/window_grid.h"
21 #include "ash/wm/overview/window_selector.h" 22 #include "ash/wm/overview/window_selector.h"
22 #include "ash/wm/overview/window_selector_controller.h" 23 #include "ash/wm/overview/window_selector_controller.h"
23 #include "ash/wm/window_state.h" 24 #include "ash/wm/window_state.h"
24 #include "base/auto_reset.h" 25 #include "base/auto_reset.h"
25 #include "base/strings/string_util.h" 26 #include "base/strings/string_util.h"
26 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
27 #include "base/time/time.h" 28 #include "base/time/time.h"
28 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/compositor/layer_animation_sequence.h" 30 #include "ui/compositor/layer_animation_sequence.h"
30 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 31 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 // Duration of background opacity transition for the selected label. 95 // Duration of background opacity transition for the selected label.
95 static const int kSelectorFadeInMilliseconds = 350; 96 static const int kSelectorFadeInMilliseconds = 350;
96 97
97 // Duration of background opacity transition when exiting overview mode. 98 // Duration of background opacity transition when exiting overview mode.
98 static const int kExitFadeInMilliseconds = 30; 99 static const int kExitFadeInMilliseconds = 30;
99 100
100 // Before closing a window animate both the window and the caption to shrink by 101 // Before closing a window animate both the window and the caption to shrink by
101 // this fraction of size. 102 // this fraction of size.
102 static const float kPreCloseScale = 0.02f; 103 static const float kPreCloseScale = 0.02f;
103 104
105 // Before dragging an overview window, the window will scale up |kPreDragScale|
106 // to indicate its selection.
107 static const float kDragWindowScale = 0.04f;
108
104 // Convenience method to fade in a Window with predefined animation settings. 109 // Convenience method to fade in a Window with predefined animation settings.
105 // Note: The fade in animation will occur after a delay where the delay is how 110 // Note: The fade in animation will occur after a delay where the delay is how
106 // long the lay out animations take. 111 // long the lay out animations take.
107 void SetupFadeInAfterLayout(views::Widget* widget) { 112 void SetupFadeInAfterLayout(views::Widget* widget) {
108 aura::Window* window = widget->GetNativeWindow(); 113 aura::Window* window = widget->GetNativeWindow();
109 window->layer()->SetOpacity(0.0f); 114 window->layer()->SetOpacity(0.0f);
110 ScopedOverviewAnimationSettings scoped_overview_animation_settings( 115 ScopedOverviewAnimationSettings scoped_overview_animation_settings(
111 OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN, 116 OverviewAnimationType::OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
112 window); 117 window);
113 window->layer()->SetOpacity(1.0f); 118 window->layer()->SetOpacity(1.0f);
114 } 119 }
115 120
116 // A Button that has a listener and listens to mouse clicks on the visible part 121 // A Button that has a listener and listens to mouse / gesture events on the
117 // of an overview window. 122 // visible part of an overview window. Note that the drag events are only
123 // handled in maximized mode.
118 class ShieldButton : public views::CustomButton { 124 class ShieldButton : public views::CustomButton {
119 public: 125 public:
120 ShieldButton(views::ButtonListener* listener, const base::string16& name) 126 ShieldButton(views::ButtonListener* listener, const base::string16& name)
121 : views::CustomButton(listener) { 127 : views::CustomButton(listener) {
122 SetAccessibleName(name); 128 SetAccessibleName(name);
123 } 129 }
124 ~ShieldButton() override {} 130 ~ShieldButton() override {}
125 131
126 // When WindowSelectorItem (which is a ButtonListener) is destroyed, its 132 // When WindowSelectorItem (which is a ButtonListener) is destroyed, its
127 // |item_widget_| is allowed to stay around to complete any animations. 133 // |item_widget_| is allowed to stay around to complete any animations.
128 // Resetting the listener in all views that are targeted by events is 134 // Resetting the listener in all views that are targeted by events is
129 // necessary to prevent a crash when a user clicks on the fading out widget 135 // necessary to prevent a crash when a user clicks on the fading out widget
130 // after the WindowSelectorItem has been destroyed. 136 // after the WindowSelectorItem has been destroyed.
131 void ResetListener() { listener_ = nullptr; } 137 void ResetListener() { listener_ = nullptr; }
132 138
139 // views::CustomButton:
140 bool OnMousePressed(const ui::MouseEvent& event) override {
141 if (listener() && SplitViewController::ShouldAllowSplitView()) {
142 gfx::Point location(event.location());
143 views::View::ConvertPointToScreen(this, &location);
144 listener()->HandlePressEvent(location);
145 return true;
146 }
147 return views::CustomButton::OnMousePressed(event);
148 }
149
150 void OnMouseReleased(const ui::MouseEvent& event) override {
151 if (listener() && SplitViewController::ShouldAllowSplitView()) {
152 gfx::Point location(event.location());
153 views::View::ConvertPointToScreen(this, &location);
154 listener()->HandleReleaseEvent(location);
155 return;
156 }
157 views::CustomButton::OnMouseReleased(event);
158 }
159
160 bool OnMouseDragged(const ui::MouseEvent& event) override {
161 if (listener() && SplitViewController::ShouldAllowSplitView()) {
162 gfx::Point location(event.location());
163 views::View::ConvertPointToScreen(this, &location);
164 listener()->HandleDragEvent(location);
165 return true;
166 }
167 return views::CustomButton::OnMouseDragged(event);
168 }
169
170 void OnGestureEvent(ui::GestureEvent* event) override {
171 if (listener() && SplitViewController::ShouldAllowSplitView()) {
172 gfx::Point location(event->location());
173 views::View::ConvertPointToScreen(this, &location);
174 switch (event->type()) {
175 case ui::ET_GESTURE_SCROLL_BEGIN:
176 case ui::ET_GESTURE_TAP_DOWN:
177 listener()->HandlePressEvent(location);
178 break;
179 case ui::ET_GESTURE_SCROLL_UPDATE:
180 listener()->HandleDragEvent(location);
181 break;
182 case ui::ET_GESTURE_END:
183 listener()->HandleReleaseEvent(location);
184 break;
185 default:
186 break;
187 }
188 event->SetHandled();
189 return;
190 }
191 views::CustomButton::OnGestureEvent(event);
192 }
193
194 WindowSelectorItem* listener() {
195 return static_cast<WindowSelectorItem*>(listener_);
196 }
197
133 protected: 198 protected:
134 // views::View: 199 // views::View:
135 const char* GetClassName() const override { return "ShieldButton"; } 200 const char* GetClassName() const override { return "ShieldButton"; }
136 201
137 private: 202 private:
138 DISALLOW_COPY_AND_ASSIGN(ShieldButton); 203 DISALLOW_COPY_AND_ASSIGN(ShieldButton);
139 }; 204 };
140 205
141 } // namespace 206 } // namespace
142 207
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 private: 455 private:
391 ShieldButton* listener_button_; 456 ShieldButton* listener_button_;
392 WindowSelectorItem::RoundedContainerView* background_; 457 WindowSelectorItem::RoundedContainerView* background_;
393 views::Label* label_; 458 views::Label* label_;
394 views::ImageButton* close_button_; 459 views::ImageButton* close_button_;
395 460
396 DISALLOW_COPY_AND_ASSIGN(CaptionContainerView); 461 DISALLOW_COPY_AND_ASSIGN(CaptionContainerView);
397 }; 462 };
398 463
399 WindowSelectorItem::WindowSelectorItem(aura::Window* window, 464 WindowSelectorItem::WindowSelectorItem(aura::Window* window,
400 WindowSelector* window_selector) 465 WindowSelector* window_selector,
466 WindowGrid* window_grid)
401 : dimmed_(false), 467 : dimmed_(false),
402 root_window_(window->GetRootWindow()), 468 root_window_(window->GetRootWindow()),
403 transform_window_(window), 469 transform_window_(this, window),
404 in_bounds_update_(false), 470 in_bounds_update_(false),
405 selected_(false), 471 selected_(false),
406 caption_container_view_(nullptr), 472 caption_container_view_(nullptr),
407 label_view_(nullptr), 473 label_view_(nullptr),
408 close_button_(new OverviewCloseButton(this)), 474 close_button_(new OverviewCloseButton(this)),
409 window_selector_(window_selector), 475 window_selector_(window_selector),
410 background_view_(nullptr) { 476 background_view_(nullptr),
477 window_grid_(window_grid) {
411 CreateWindowLabel(window->GetTitle()); 478 CreateWindowLabel(window->GetTitle());
412 GetWindow()->AddObserver(this); 479 GetWindow()->AddObserver(this);
413 } 480 }
414 481
415 WindowSelectorItem::~WindowSelectorItem() { 482 WindowSelectorItem::~WindowSelectorItem() {
416 GetWindow()->RemoveObserver(this); 483 GetWindow()->RemoveObserver(this);
417 } 484 }
418 485
419 aura::Window* WindowSelectorItem::GetWindow() { 486 aura::Window* WindowSelectorItem::GetWindow() {
420 return transform_window_.window(); 487 return transform_window_.window();
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 if (ash::Shell::Get() 603 if (ash::Shell::Get()
537 ->maximize_mode_controller() 604 ->maximize_mode_controller()
538 ->IsMaximizeModeWindowManagerEnabled()) { 605 ->IsMaximizeModeWindowManagerEnabled()) {
539 ash::Shell::Get()->metrics()->RecordUserMetricsAction( 606 ash::Shell::Get()->metrics()->RecordUserMetricsAction(
540 ash::UMA_TABLET_WINDOW_CLOSE_THROUGH_OVERVIEW_CLOSE_BUTTON); 607 ash::UMA_TABLET_WINDOW_CLOSE_THROUGH_OVERVIEW_CLOSE_BUTTON);
541 } 608 }
542 CloseWindow(); 609 CloseWindow();
543 return; 610 return;
544 } 611 }
545 CHECK(sender == caption_container_view_->listener_button()); 612 CHECK(sender == caption_container_view_->listener_button());
546 window_selector_->SelectWindow(this); 613
614 // For other cases, the event is handled in OverviewWindowDragController.
615 if (!SplitViewController::ShouldAllowSplitView())
616 window_selector_->SelectWindow(this);
547 } 617 }
548 618
549 void WindowSelectorItem::OnWindowDestroying(aura::Window* window) { 619 void WindowSelectorItem::OnWindowDestroying(aura::Window* window) {
550 window->RemoveObserver(this); 620 window->RemoveObserver(this);
551 transform_window_.OnWindowDestroyed(); 621 transform_window_.OnWindowDestroyed();
552 } 622 }
553 623
554 void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) { 624 void WindowSelectorItem::OnWindowTitleChanged(aura::Window* window) {
555 // TODO(flackr): Maybe add the new title to a vector of titles so that we can 625 // TODO(flackr): Maybe add the new title to a vector of titles so that we can
556 // filter any of the titles the window had while in the overview session. 626 // filter any of the titles the window had while in the overview session.
557 label_view_->SetText(window->GetTitle()); 627 label_view_->SetText(window->GetTitle());
558 UpdateAccessibilityName(); 628 UpdateAccessibilityName();
559 } 629 }
560 630
561 float WindowSelectorItem::GetItemScale(const gfx::Size& size) { 631 float WindowSelectorItem::GetItemScale(const gfx::Size& size) {
562 gfx::Size inset_size(size.width(), size.height() - 2 * kWindowMargin); 632 gfx::Size inset_size(size.width(), size.height() - 2 * kWindowMargin);
563 return ScopedTransformOverviewWindow::GetItemScale( 633 return ScopedTransformOverviewWindow::GetItemScale(
564 transform_window_.GetTargetBoundsInScreen().size(), inset_size, 634 transform_window_.GetTargetBoundsInScreen().size(), inset_size,
565 transform_window_.GetTopInset(), 635 transform_window_.GetTopInset(),
566 close_button_->GetPreferredSize().height()); 636 close_button_->GetPreferredSize().height());
567 } 637 }
568 638
639 void WindowSelectorItem::HandlePressEvent(
640 const gfx::Point& location_in_screen) {
641 StartDrag();
642 window_selector_->InitiateDrag(this, location_in_screen);
643 }
644
645 void WindowSelectorItem::HandleReleaseEvent(
646 const gfx::Point& location_in_screen) {
647 EndDrag();
648 window_selector_->CompleteDrag(this);
649 }
650
651 void WindowSelectorItem::HandleDragEvent(const gfx::Point& location_in_screen) {
652 window_selector_->Drag(this, location_in_screen);
653 }
654
569 gfx::Rect WindowSelectorItem::GetTargetBoundsInScreen() const { 655 gfx::Rect WindowSelectorItem::GetTargetBoundsInScreen() const {
570 return transform_window_.GetTargetBoundsInScreen(); 656 return transform_window_.GetTargetBoundsInScreen();
571 } 657 }
572 658
573 void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, 659 void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
574 OverviewAnimationType animation_type) { 660 OverviewAnimationType animation_type) {
575 DCHECK(root_window_ == GetWindow()->GetRootWindow()); 661 DCHECK(root_window_ == GetWindow()->GetRootWindow());
576 gfx::Rect screen_rect = transform_window_.GetTargetBoundsInScreen(); 662 gfx::Rect screen_rect = transform_window_.GetTargetBoundsInScreen();
577 663
578 // Avoid division by zero by ensuring screen bounds is not empty. 664 // Avoid division by zero by ensuring screen bounds is not empty.
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 } 835 }
750 836
751 gfx::SlideAnimation* WindowSelectorItem::GetBackgroundViewAnimation() { 837 gfx::SlideAnimation* WindowSelectorItem::GetBackgroundViewAnimation() {
752 return background_view_ ? background_view_->animation() : nullptr; 838 return background_view_ ? background_view_->animation() : nullptr;
753 } 839 }
754 840
755 aura::Window* WindowSelectorItem::GetOverviewWindowForMinimizedStateForTest() { 841 aura::Window* WindowSelectorItem::GetOverviewWindowForMinimizedStateForTest() {
756 return transform_window_.GetOverviewWindowForMinimizedState(); 842 return transform_window_.GetOverviewWindowForMinimizedState();
757 } 843 }
758 844
845 void WindowSelectorItem::StartDrag() {
846 gfx::Rect scaled_bounds(target_bounds_);
847 scaled_bounds.Inset(-target_bounds_.width() * kDragWindowScale,
848 -target_bounds_.height() * kDragWindowScale);
849 OverviewAnimationType animation_type =
850 OverviewAnimationType::OVERVIEW_ANIMATION_CLOSING_SELECTOR_ITEM;
851 SetBounds(scaled_bounds, animation_type);
852
853 aura::Window* widget_window = item_widget_->GetNativeWindow();
854 if (widget_window && widget_window->parent() == GetWindow()->parent()) {
855 // TODO(xdai): This might not work if there is an always on top window.
856 // See crbug.com/733760.
857 widget_window->parent()->StackChildAtTop(widget_window);
858 widget_window->parent()->StackChildBelow(GetWindow(), widget_window);
859 }
860 }
861
862 void WindowSelectorItem::EndDrag() {
863 // First stack this item's window below the snapped window if split view mode
864 // is active.
865 aura::Window* dragged_window = GetWindow();
866 aura::Window* dragged_widget_window = item_widget_->GetNativeWindow();
867 aura::Window* parent_window = dragged_widget_window->parent();
868 if (Shell::Get()->IsSplitViewModeActive()) {
869 aura::Window* snapped_window =
870 Shell::Get()->split_view_controller()->GetDefaultSnappedWindow();
871 if (snapped_window->parent() == parent_window &&
872 dragged_window->parent() == parent_window) {
873 parent_window->StackChildBelow(dragged_widget_window, snapped_window);
874 parent_window->StackChildBelow(dragged_window, dragged_widget_window);
875 }
876 }
877
878 // Then find the window which was stacked right above this selector item's
879 // window before dragging and stack this selector item's window below it.
880 const std::vector<std::unique_ptr<WindowSelectorItem>>& selector_items =
881 window_grid_->window_list();
882 size_t position_in_grid = 0;
883 for (size_t index = 0; index < selector_items.size(); index++) {
884 if (selector_items[index].get() == this) {
885 position_in_grid = index;
886 break;
887 }
888 }
889 for (int i = position_in_grid - 1; i >= 0; i--) {
890 aura::Window* stacking_target = selector_items[i].get()->GetWindow();
891 if (stacking_target->parent() == parent_window &&
892 dragged_window->parent() == parent_window) {
893 parent_window->StackChildBelow(dragged_widget_window, stacking_target);
894 parent_window->StackChildBelow(dragged_window, dragged_widget_window);
895 break;
896 }
897 }
898 }
899
759 } // namespace ash 900 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/overview/window_selector_item.h ('k') | ash/wm/splitview/split_view_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698