OLD | NEW |
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 "ash/common/wm/window_cycle_list.h" | 5 #include "ash/common/wm/window_cycle_list.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "ash/common/ash_switches.h" | 10 #include "ash/common/ash_switches.h" |
11 #include "ash/common/shell_window_ids.h" | 11 #include "ash/common/shell_window_ids.h" |
12 #include "ash/common/wm/forwarding_layer_delegate.h" | 12 #include "ash/common/wm/forwarding_layer_delegate.h" |
13 #include "ash/common/wm/mru_window_tracker.h" | 13 #include "ash/common/wm/mru_window_tracker.h" |
14 #include "ash/common/wm/window_state.h" | 14 #include "ash/common/wm/window_state.h" |
15 #include "ash/common/wm_root_window_controller.h" | 15 #include "ash/common/wm_root_window_controller.h" |
16 #include "ash/common/wm_shell.h" | 16 #include "ash/common/wm_shell.h" |
17 #include "ash/common/wm_window.h" | 17 #include "ash/common/wm_window.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "ui/views/background.h" | 19 #include "ui/views/background.h" |
| 20 #include "ui/views/border.h" |
| 21 #include "ui/views/controls/label.h" |
20 #include "ui/views/layout/box_layout.h" | 22 #include "ui/views/layout/box_layout.h" |
21 #include "ui/views/painter.h" | 23 #include "ui/views/painter.h" |
22 #include "ui/views/view.h" | 24 #include "ui/views/view.h" |
23 #include "ui/views/widget/widget.h" | 25 #include "ui/views/widget/widget.h" |
24 #include "ui/wm/core/visibility_controller.h" | 26 #include "ui/wm/core/visibility_controller.h" |
25 | 27 |
26 namespace ash { | 28 namespace ash { |
27 | 29 |
28 // Returns the window immediately below |window| in the current container. | 30 // Returns the window immediately below |window| in the current container. |
29 WmWindow* GetWindowBelow(WmWindow* window) { | 31 WmWindow* GetWindowBelow(WmWindow* window) { |
(...skipping 29 matching lines...) Expand all Loading... |
59 | 61 |
60 // The window immediately below where window_ belongs. | 62 // The window immediately below where window_ belongs. |
61 WmWindow* stack_window_above_; | 63 WmWindow* stack_window_above_; |
62 | 64 |
63 // If true, minimize window_ on going out of scope. | 65 // If true, minimize window_ on going out of scope. |
64 bool minimized_; | 66 bool minimized_; |
65 | 67 |
66 DISALLOW_COPY_AND_ASSIGN(ScopedShowWindow); | 68 DISALLOW_COPY_AND_ASSIGN(ScopedShowWindow); |
67 }; | 69 }; |
68 | 70 |
| 71 // This view represents a single WmWindow by displaying a title and a thumbnail |
| 72 // of the window's contents. |
| 73 class WindowPreviewView : public views::View { |
| 74 public: |
| 75 explicit WindowPreviewView(WmWindow* window) |
| 76 : window_title_(new views::Label), |
| 77 preview_background_(new views::View), |
| 78 mirror_view_(window->CreateViewWithRecreatedLayers().release()) { |
| 79 window_title_->SetText(window->GetTitle()); |
| 80 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 81 window_title_->SetEnabledColor(SK_ColorWHITE); |
| 82 window_title_->SetAutoColorReadabilityEnabled(false); |
| 83 // The base font is 12pt (for English) so this comes out to 14pt. |
| 84 const int kLabelSizeDelta = 2; |
| 85 window_title_->SetFontList( |
| 86 window_title_->font_list().DeriveWithSizeDelta(kLabelSizeDelta)); |
| 87 const int kAboveLabelPadding = 5; |
| 88 const int kBelowLabelPadding = 10; |
| 89 window_title_->SetBorder(views::Border::CreateEmptyBorder( |
| 90 kAboveLabelPadding, 0, kBelowLabelPadding, 0)); |
| 91 AddChildView(window_title_); |
| 92 |
| 93 // Preview padding is black at 50% opacity. |
| 94 preview_background_->set_background( |
| 95 views::Background::CreateSolidBackground( |
| 96 SkColorSetA(SK_ColorBLACK, 0xFF / 2))); |
| 97 AddChildView(preview_background_); |
| 98 |
| 99 AddChildView(mirror_view_); |
| 100 } |
| 101 ~WindowPreviewView() override {} |
| 102 |
| 103 // views::View: |
| 104 gfx::Size GetPreferredSize() const override { |
| 105 gfx::Size size = GetSizeForPreviewArea(); |
| 106 size.Enlarge(0, window_title_->GetPreferredSize().height()); |
| 107 return size; |
| 108 } |
| 109 |
| 110 void Layout() override { |
| 111 const gfx::Size preview_area_size = GetSizeForPreviewArea(); |
| 112 // The window title is positioned above the preview area. |
| 113 window_title_->SetBounds(0, 0, width(), |
| 114 height() - preview_area_size.height()); |
| 115 |
| 116 gfx::Rect preview_area_bounds(preview_area_size); |
| 117 preview_area_bounds.set_y(height() - preview_area_size.height()); |
| 118 mirror_view_->SetSize(GetMirrorViewScaledSize()); |
| 119 if (mirror_view_->size() == preview_area_size) { |
| 120 // Padding is not needed, hide the background and set the mirror view |
| 121 // to take up the entire preview area. |
| 122 mirror_view_->SetPosition(preview_area_bounds.origin()); |
| 123 preview_background_->SetVisible(false); |
| 124 return; |
| 125 } |
| 126 |
| 127 // Padding is needed, so show the background and set the mirror view to be |
| 128 // centered within it. |
| 129 preview_background_->SetBoundsRect(preview_area_bounds); |
| 130 preview_background_->SetVisible(true); |
| 131 preview_area_bounds.ClampToCenteredSize(mirror_view_->size()); |
| 132 mirror_view_->SetPosition(preview_area_bounds.origin()); |
| 133 } |
| 134 |
| 135 private: |
| 136 // The maximum width of a window preview. |
| 137 static const int kMaxPreviewWidth = 512; |
| 138 // All previews are the same height (this is achieved via a combination of |
| 139 // scaling and padding). |
| 140 static const int kFixedPreviewHeight = 256; |
| 141 |
| 142 // Returns the size for the mirror view, scaled to fit within the max bounds. |
| 143 // Scaling is always 1:1 and we only scale down, never up. |
| 144 gfx::Size GetMirrorViewScaledSize() const { |
| 145 gfx::Size mirror_pref_size = mirror_view_->GetPreferredSize(); |
| 146 |
| 147 if (mirror_pref_size.width() > kMaxPreviewWidth || |
| 148 mirror_pref_size.height() > kFixedPreviewHeight) { |
| 149 float scale = std::min( |
| 150 kMaxPreviewWidth / static_cast<float>(mirror_pref_size.width()), |
| 151 kFixedPreviewHeight / static_cast<float>(mirror_pref_size.height())); |
| 152 mirror_pref_size = |
| 153 gfx::ScaleToFlooredSize(mirror_pref_size, scale, scale); |
| 154 } |
| 155 |
| 156 return mirror_pref_size; |
| 157 } |
| 158 |
| 159 // Returns the size for the entire preview area (mirror view and additional |
| 160 // padding). All previews will be the same height, so if the mirror view isn't |
| 161 // tall enough we will add top and bottom padding. Previews can range in width |
| 162 // from kMaxPreviewWidth down to half that value. Again, padding will be added |
| 163 // to the sides to achieve this if the preview is too narrow. |
| 164 gfx::Size GetSizeForPreviewArea() const { |
| 165 gfx::Size mirror_size = GetMirrorViewScaledSize(); |
| 166 float aspect_ratio = |
| 167 static_cast<float>(mirror_size.width()) / mirror_size.height(); |
| 168 gfx::Size preview_size = mirror_size; |
| 169 // Very narrow windows get vertical bars of padding on the sides. |
| 170 if (aspect_ratio < 0.5f) |
| 171 preview_size.set_width(mirror_size.height() / 2); |
| 172 |
| 173 // All previews are the same height (this may add padding on top and |
| 174 // bottom). |
| 175 preview_size.set_height(kFixedPreviewHeight); |
| 176 // Previews should never be narrower than half their max width (128dip). |
| 177 preview_size.set_width( |
| 178 std::max(preview_size.width(), kMaxPreviewWidth / 2)); |
| 179 |
| 180 return preview_size; |
| 181 } |
| 182 |
| 183 // Displays the title of the window above the preview. |
| 184 views::Label* window_title_; |
| 185 // When visible, shows a darkened background area behind |mirror_view_| |
| 186 // (effectively padding the preview to fit the desired bounds). |
| 187 views::View* preview_background_; |
| 188 // The view that actually renders a thumbnail version of the window. |
| 189 views::View* mirror_view_; |
| 190 |
| 191 DISALLOW_COPY_AND_ASSIGN(WindowPreviewView); |
| 192 }; |
| 193 |
69 // A view that shows a collection of windows the user can tab through. | 194 // A view that shows a collection of windows the user can tab through. |
70 class WindowCycleView : public views::View { | 195 class WindowCycleView : public views::View { |
71 public: | 196 public: |
72 explicit WindowCycleView(const WindowCycleList::WindowList& windows) | 197 explicit WindowCycleView(const WindowCycleList::WindowList& windows) |
73 : mirror_container_(new views::View()), | 198 : mirror_container_(new views::View()), |
74 highlight_view_(new views::View()), | 199 highlight_view_(new views::View()), |
75 target_window_(nullptr) { | 200 target_window_(nullptr) { |
76 DCHECK(!windows.empty()); | 201 DCHECK(!windows.empty()); |
77 SetPaintToLayer(true); | 202 SetPaintToLayer(true); |
78 layer()->SetFillsBoundsOpaquely(false); | 203 layer()->SetFillsBoundsOpaquely(false); |
(...skipping 11 matching lines...) Expand all Loading... |
90 mirror_container_->SetLayoutManager(layout); | 215 mirror_container_->SetLayoutManager(layout); |
91 mirror_container_->SetPaintToLayer(true); | 216 mirror_container_->SetPaintToLayer(true); |
92 mirror_container_->layer()->SetFillsBoundsOpaquely(false); | 217 mirror_container_->layer()->SetFillsBoundsOpaquely(false); |
93 // The preview list animates bounds changes (other animatable properties | 218 // The preview list animates bounds changes (other animatable properties |
94 // never change). | 219 // never change). |
95 mirror_container_->layer()->SetAnimator( | 220 mirror_container_->layer()->SetAnimator( |
96 ui::LayerAnimator::CreateImplicitAnimator()); | 221 ui::LayerAnimator::CreateImplicitAnimator()); |
97 | 222 |
98 for (WmWindow* window : windows) { | 223 for (WmWindow* window : windows) { |
99 // |mirror_container_| owns |view|. | 224 // |mirror_container_| owns |view|. |
100 views::View* view = window->CreateViewWithRecreatedLayers().release(); | 225 views::View* view = new WindowPreviewView(window); |
101 window_view_map_[window] = view; | 226 window_view_map_[window] = view; |
102 mirror_container_->AddChildView(view); | 227 mirror_container_->AddChildView(view); |
103 } | 228 } |
104 | 229 |
105 const float kHighlightCornerRadius = 4; | 230 const float kHighlightCornerRadius = 4; |
106 highlight_view_->set_background(views::Background::CreateBackgroundPainter( | 231 highlight_view_->set_background(views::Background::CreateBackgroundPainter( |
107 true, views::Painter::CreateRoundRectWith1PxBorderPainter( | 232 true, views::Painter::CreateRoundRectWith1PxBorderPainter( |
108 SkColorSetA(SK_ColorWHITE, 0x4D), | 233 SkColorSetA(SK_ColorWHITE, 0x4D), |
109 SkColorSetA(SK_ColorWHITE, 0x33), kHighlightCornerRadius))); | 234 SkColorSetA(SK_ColorWHITE, 0x33), kHighlightCornerRadius))); |
110 highlight_view_->SetPaintToLayer(true); | 235 highlight_view_->SetPaintToLayer(true); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 } | 462 } |
338 } | 463 } |
339 | 464 |
340 bool WindowCycleList::ShouldShowUi() { | 465 bool WindowCycleList::ShouldShowUi() { |
341 return windows_.size() > 1 && | 466 return windows_.size() > 1 && |
342 base::CommandLine::ForCurrentProcess()->HasSwitch( | 467 base::CommandLine::ForCurrentProcess()->HasSwitch( |
343 switches::kAshEnableWindowCycleUi); | 468 switches::kAshEnableWindowCycleUi); |
344 } | 469 } |
345 | 470 |
346 } // namespace ash | 471 } // namespace ash |
OLD | NEW |