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); |
79 | 204 |
80 set_background(views::Background::CreateSolidBackground( | 205 set_background(views::Background::CreateSolidBackground( |
81 SkColorSetA(SK_ColorBLACK, 0xCC))); | 206 SkColorSetA(SK_ColorBLACK, 0xCC))); |
82 | 207 |
83 const int kInsideBorderPaddingDip = 64; | 208 const int kInsideBorderPaddingDip = 64; |
84 const int kBetweenChildPaddingDip = 10; | 209 const int kBetweenChildPaddingDip = 10; |
85 views::BoxLayout* layout = new views::BoxLayout( | 210 views::BoxLayout* layout = new views::BoxLayout( |
86 views::BoxLayout::kHorizontal, kInsideBorderPaddingDip, | 211 views::BoxLayout::kHorizontal, kInsideBorderPaddingDip, |
87 kInsideBorderPaddingDip, kBetweenChildPaddingDip); | 212 kInsideBorderPaddingDip, kBetweenChildPaddingDip); |
88 layout->set_cross_axis_alignment( | 213 layout->set_cross_axis_alignment( |
89 views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); | 214 views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); |
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) { |
sky
2016/07/20 19:48:45
Not related to this change, but recreating layers
Evan Stade
2016/07/20 19:53:42
Yes. It's an open question whether we want to be a
| |
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 |