OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ash/wm/workspace/frame_caption_button_container_view.h" | |
6 | |
7 #include "ash/ash_switches.h" | |
8 #include "ash/test/ash_test_base.h" | |
9 #include "base/command_line.h" | |
10 #include "grit/ash_resources.h" | |
11 #include "ui/aura/root_window.h" | |
12 #include "ui/base/resource/resource_bundle.h" | |
13 #include "ui/views/border.h" | |
14 #include "ui/views/controls/button/custom_button.h" | |
15 #include "ui/views/controls/button/image_button.h" | |
16 #include "ui/views/widget/widget.h" | |
17 #include "ui/views/widget/widget_delegate.h" | |
18 | |
19 namespace ash { | |
20 | |
21 namespace { | |
22 | |
23 class TestWidgetDelegate : public views::WidgetDelegateView { | |
24 public: | |
25 TestWidgetDelegate(bool can_maximize) : can_maximize_(can_maximize) { | |
26 } | |
27 virtual ~TestWidgetDelegate() { | |
28 } | |
29 | |
30 virtual bool CanMaximize() const OVERRIDE { | |
31 return can_maximize_; | |
32 } | |
33 | |
34 private: | |
35 bool can_maximize_; | |
36 | |
37 DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate); | |
38 }; | |
39 | |
40 } // namespace | |
41 | |
42 class FrameCaptionButtonContainerViewTest : public ash::test::AshTestBase { | |
43 public: | |
44 enum MaximizeAllowed { | |
45 MAXIMIZE_ALLOWED, | |
46 MAXIMIZE_DISALLOWED | |
47 }; | |
48 | |
49 FrameCaptionButtonContainerViewTest() { | |
50 } | |
51 | |
52 virtual ~FrameCaptionButtonContainerViewTest() { | |
53 } | |
54 | |
55 // Creates a widget which allows maximizing based on |maximize_allowed|. | |
56 // The caller takes ownership of the returned widget. | |
57 views::Widget* CreateTestWidget( | |
58 MaximizeAllowed maximize_allowed) WARN_UNUSED_RESULT { | |
59 views::Widget* widget = new views::Widget; | |
60 views::Widget::InitParams params; | |
61 params.delegate = new TestWidgetDelegate( | |
62 maximize_allowed == MAXIMIZE_ALLOWED); | |
63 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
64 params.context = CurrentContext(); | |
65 widget->Init(params); | |
66 return widget; | |
67 } | |
68 | |
69 // Tests that |leftmost| and |rightmost| are at |container|'s edges. | |
70 bool CheckButtonsAtEdges(FrameCaptionButtonContainerView* container, | |
71 const views::CustomButton& leftmost, | |
72 const views::CustomButton& rightmost) { | |
73 gfx::Rect expected(container->GetPreferredSize()); | |
74 expected.Inset(container->GetLeftInset(), 0, container->GetRightInset(), 0); | |
75 | |
76 gfx::Rect container_size(container->GetPreferredSize()); | |
77 if (leftmost.y() == rightmost.y() && | |
78 leftmost.height() == rightmost.height() && | |
79 leftmost.x() == expected.x() && | |
80 leftmost.y() == expected.y() && | |
81 leftmost.height() == expected.height() && | |
82 rightmost.bounds().right() == expected.right()) { | |
83 return true; | |
84 } | |
85 | |
86 LOG(ERROR) << "Buttons " << leftmost.bounds().ToString() << " " | |
87 << rightmost.bounds().ToString() << " not at edges of " | |
88 << expected.ToString(); | |
89 return false; | |
90 } | |
91 | |
92 private: | |
93 DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTest); | |
94 }; | |
95 | |
96 class FrameCaptionButtonContainerViewTestOldStyle | |
97 : public FrameCaptionButtonContainerViewTest { | |
98 public: | |
99 FrameCaptionButtonContainerViewTestOldStyle() { | |
100 } | |
101 | |
102 virtual ~FrameCaptionButtonContainerViewTestOldStyle() { | |
103 } | |
104 | |
105 // Returns true if the images for |button|'s states match the passed in ids. | |
106 bool ImagesMatch(views::CustomButton* custom_button, | |
107 int normal_image_id, | |
108 int hovered_image_id, | |
109 int pressed_image_id) { | |
110 views::ImageButton* button = | |
111 static_cast<views::ImageButton*>(custom_button); | |
112 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
113 gfx::ImageSkia* normal = rb.GetImageSkiaNamed(normal_image_id); | |
114 gfx::ImageSkia* hovered = rb.GetImageSkiaNamed(hovered_image_id); | |
115 gfx::ImageSkia* pressed = rb.GetImageSkiaNamed(pressed_image_id); | |
116 using views::Button; | |
117 gfx::ImageSkia actual_normal = button->GetImage(Button::STATE_NORMAL); | |
118 gfx::ImageSkia actual_hovered = button->GetImage(Button::STATE_HOVERED); | |
119 gfx::ImageSkia actual_pressed = button->GetImage(Button::STATE_PRESSED); | |
120 return actual_normal.BackedBySameObjectAs(*normal) && | |
121 actual_hovered.BackedBySameObjectAs(*hovered) && | |
122 actual_pressed.BackedBySameObjectAs(*pressed); | |
123 } | |
124 | |
125 virtual void SetUp() OVERRIDE { | |
126 FrameCaptionButtonContainerViewTest::SetUp(); | |
127 CommandLine::ForCurrentProcess()->AppendSwitch( | |
128 switches::kAshDisableAlternateFrameCaptionButtonStyle); | |
129 } | |
130 | |
131 private: | |
132 DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTestOldStyle); | |
133 }; | |
134 | |
135 // Test how the allowed actions affect which caption buttons are visible. | |
136 TEST_F(FrameCaptionButtonContainerViewTestOldStyle, ButtonVisibility) { | |
137 // The minimize button should be hidden when both minimizing and maximizing | |
138 // are allowed because the size button can do both. | |
139 scoped_ptr<views::Widget> widget_can_maximize( | |
140 CreateTestWidget(MAXIMIZE_ALLOWED)); | |
141 FrameCaptionButtonContainerView container1(NULL, widget_can_maximize.get(), | |
142 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); | |
143 container1.Layout(); | |
144 FrameCaptionButtonContainerView::TestApi t1(&container1); | |
145 EXPECT_FALSE(t1.minimize_button()->visible()); | |
146 EXPECT_TRUE(t1.size_button()->visible()); | |
147 EXPECT_TRUE(t1.close_button()->visible()); | |
148 EXPECT_TRUE(CheckButtonsAtEdges( | |
149 &container1, *t1.size_button(), *t1.close_button())); | |
150 | |
151 // The minimize button should be visible when minimizing is allowed but | |
152 // maximizing is disallowed. | |
153 scoped_ptr<views::Widget> widget_cannot_maximize( | |
154 CreateTestWidget(MAXIMIZE_DISALLOWED)); | |
155 FrameCaptionButtonContainerView container2(NULL, widget_cannot_maximize.get(), | |
156 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); | |
157 container2.Layout(); | |
158 FrameCaptionButtonContainerView::TestApi t2(&container2); | |
159 EXPECT_TRUE(t2.minimize_button()->visible()); | |
160 EXPECT_FALSE(t2.size_button()->visible()); | |
161 EXPECT_TRUE(t2.close_button()->visible()); | |
162 EXPECT_TRUE(CheckButtonsAtEdges( | |
163 &container2, *t2.minimize_button(), *t2.close_button())); | |
164 | |
165 // Neither the minimize button nor the size button should be visible when | |
166 // neither minimizing nor maximizing are allowed. | |
167 FrameCaptionButtonContainerView container3(NULL, widget_cannot_maximize.get(), | |
168 FrameCaptionButtonContainerView::MINIMIZE_DISALLOWED); | |
169 container3.Layout(); | |
170 FrameCaptionButtonContainerView::TestApi t3(&container3); | |
171 EXPECT_FALSE(t3.minimize_button()->visible()); | |
172 EXPECT_FALSE(t3.size_button()->visible()); | |
173 EXPECT_TRUE(t3.close_button()->visible()); | |
174 EXPECT_TRUE(CheckButtonsAtEdges( | |
175 &container3, *t3.close_button(), *t3.close_button())); | |
176 | |
177 // Neither the minimize button nor the size button should be visible when the | |
178 // "force-maximize-mode" experiment is turned on. | |
179 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kForcedMaximizeMode); | |
180 FrameCaptionButtonContainerView container4(NULL, widget_can_maximize.get(), | |
181 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); | |
182 container4.Layout(); | |
183 FrameCaptionButtonContainerView::TestApi t4(&container4); | |
184 EXPECT_FALSE(t4.minimize_button()->visible()); | |
185 EXPECT_FALSE(t4.size_button()->visible()); | |
186 EXPECT_TRUE(t4.close_button()->visible()); | |
187 EXPECT_TRUE(CheckButtonsAtEdges( | |
188 &container4, *t4.close_button(), *t4.close_button())); | |
189 } | |
190 | |
191 // Test the layout when a border is set on the container. | |
192 TEST_F(FrameCaptionButtonContainerViewTestOldStyle, LayoutBorder) { | |
193 const int kTopInset = 1; | |
194 const int kLeftInset = 2; | |
195 const int kBottomInset = 3; | |
196 const int kRightInset = 4; | |
197 | |
198 scoped_ptr<views::Widget> widget(CreateTestWidget(MAXIMIZE_ALLOWED)); | |
199 FrameCaptionButtonContainerView container(NULL, widget.get(), | |
200 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); | |
201 container.set_border(views::Border::CreateEmptyBorder( | |
202 kTopInset, kLeftInset, kBottomInset, kRightInset)); | |
203 container.Layout(); | |
204 FrameCaptionButtonContainerView::TestApi t(&container); | |
205 | |
206 EXPECT_EQ(kLeftInset, t.size_button()->x()); | |
207 EXPECT_EQ(kTopInset, t.close_button()->y()); | |
208 EXPECT_EQ(container.GetPreferredSize().height(), | |
209 t.close_button()->bounds().bottom() + kBottomInset); | |
210 EXPECT_EQ(container.GetPreferredSize().width(), | |
211 t.close_button()->bounds().right() + kRightInset); | |
212 } | |
213 | |
214 // Test how the header style affects which images are used for the buttons. | |
215 TEST_F(FrameCaptionButtonContainerViewTestOldStyle, HeaderStyle) { | |
216 scoped_ptr<views::Widget> widget(CreateTestWidget(MAXIMIZE_ALLOWED)); | |
217 FrameCaptionButtonContainerView container(NULL, widget.get(), | |
218 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); | |
219 FrameCaptionButtonContainerView::TestApi t(&container); | |
220 | |
221 // Tall header style. | |
222 container.set_header_style( | |
223 FrameCaptionButtonContainerView::HEADER_STYLE_TALL); | |
224 container.Layout(); | |
225 EXPECT_TRUE(ImagesMatch(t.size_button(), | |
226 IDR_AURA_WINDOW_MAXIMIZE, | |
227 IDR_AURA_WINDOW_MAXIMIZE_H, | |
228 IDR_AURA_WINDOW_MAXIMIZE_P)); | |
229 EXPECT_TRUE(ImagesMatch(t.close_button(), | |
230 IDR_AURA_WINDOW_CLOSE, | |
231 IDR_AURA_WINDOW_CLOSE_H, | |
232 IDR_AURA_WINDOW_CLOSE_P)); | |
233 | |
234 // Short header style. | |
235 container.set_header_style( | |
236 FrameCaptionButtonContainerView::HEADER_STYLE_SHORT); | |
237 container.Layout(); | |
238 EXPECT_TRUE(ImagesMatch(t.size_button(), | |
239 IDR_AURA_WINDOW_MAXIMIZED_RESTORE, | |
240 IDR_AURA_WINDOW_MAXIMIZED_RESTORE_H, | |
241 IDR_AURA_WINDOW_MAXIMIZED_RESTORE_P)); | |
242 EXPECT_TRUE(ImagesMatch(t.close_button(), | |
243 IDR_AURA_WINDOW_MAXIMIZED_CLOSE, | |
244 IDR_AURA_WINDOW_MAXIMIZED_CLOSE_H, | |
245 IDR_AURA_WINDOW_MAXIMIZED_CLOSE_P)); | |
246 | |
247 // Maximized short header style. | |
248 widget->Maximize(); | |
249 container.Layout(); | |
250 EXPECT_TRUE(ImagesMatch(t.size_button(), | |
251 IDR_AURA_WINDOW_MAXIMIZED_RESTORE2, | |
252 IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_H, | |
253 IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_P)); | |
254 EXPECT_TRUE(ImagesMatch(t.close_button(), | |
255 IDR_AURA_WINDOW_MAXIMIZED_CLOSE2, | |
256 IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_H, | |
257 IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_P)); | |
258 | |
259 // The buttons are visible during a reveal of the top-of-window views in | |
260 // immersive fullscreen. They should use the same images as maximized. | |
261 widget->SetFullscreen(true); | |
262 container.Layout(); | |
263 EXPECT_TRUE(ImagesMatch(t.size_button(), | |
264 IDR_AURA_WINDOW_MAXIMIZED_RESTORE2, | |
265 IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_H, | |
266 IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_P)); | |
267 EXPECT_TRUE(ImagesMatch(t.close_button(), | |
268 IDR_AURA_WINDOW_MAXIMIZED_CLOSE2, | |
269 IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_H, | |
270 IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_P)); | |
271 | |
272 // AppNonClientFrameViewAsh has a dedicated set of images. | |
273 container.set_header_style( | |
274 FrameCaptionButtonContainerView::HEADER_STYLE_MAXIMIZED_HOSTED_APP); | |
275 container.Layout(); | |
276 EXPECT_TRUE(ImagesMatch(t.size_button(), | |
277 IDR_AURA_WINDOW_FULLSCREEN_RESTORE, | |
278 IDR_AURA_WINDOW_FULLSCREEN_RESTORE_H, | |
279 IDR_AURA_WINDOW_FULLSCREEN_RESTORE_P)); | |
280 EXPECT_TRUE(ImagesMatch(t.close_button(), | |
281 IDR_AURA_WINDOW_FULLSCREEN_CLOSE, | |
282 IDR_AURA_WINDOW_FULLSCREEN_CLOSE_H, | |
283 IDR_AURA_WINDOW_FULLSCREEN_CLOSE_P)); | |
284 } | |
285 | |
286 class FrameCaptionButtonContainerViewTestAlternateStyle | |
287 : public FrameCaptionButtonContainerViewTest { | |
288 public: | |
289 FrameCaptionButtonContainerViewTestAlternateStyle() { | |
290 } | |
291 | |
292 virtual ~FrameCaptionButtonContainerViewTestAlternateStyle() { | |
293 } | |
294 | |
295 virtual void SetUp() OVERRIDE { | |
296 FrameCaptionButtonContainerViewTest::SetUp(); | |
297 CommandLine::ForCurrentProcess()->AppendSwitch( | |
298 switches::kAshEnableAlternateFrameCaptionButtonStyle); | |
299 ASSERT_TRUE(switches::UseAlternateFrameCaptionButtonStyle()); | |
300 } | |
301 | |
302 private: | |
303 DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTestAlternateStyle); | |
304 }; | |
305 | |
306 // Test how the alternate button style affects which buttons are visible in the | |
307 // default case. | |
308 TEST_F(FrameCaptionButtonContainerViewTestAlternateStyle, ButtonVisibility) { | |
309 // Both the minimize button and the maximize button should be visible when | |
310 // both minimizing and maximizing are allowed when using the alternate | |
311 // button style. | |
312 scoped_ptr<views::Widget> widget_can_maximize( | |
313 CreateTestWidget(MAXIMIZE_ALLOWED)); | |
314 FrameCaptionButtonContainerView container(NULL, widget_can_maximize.get(), | |
315 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); | |
316 container.Layout(); | |
317 FrameCaptionButtonContainerView::TestApi t(&container); | |
318 EXPECT_TRUE(t.minimize_button()->visible()); | |
319 EXPECT_TRUE(t.size_button()->visible()); | |
320 EXPECT_TRUE(t.close_button()->visible()); | |
321 EXPECT_TRUE(CheckButtonsAtEdges( | |
322 &container, *t.minimize_button(), *t.close_button())); | |
323 } | |
324 | |
325 } // namespace ash | |
OLD | NEW |