• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "ui/views/window/custom_frame_view.h"
6 
7 #include <vector>
8 
9 #include "ui/views/controls/button/image_button.h"
10 #include "ui/views/test/views_test_base.h"
11 #include "ui/views/widget/widget.h"
12 #include "ui/views/widget/widget_delegate.h"
13 #include "ui/views/window/window_button_order_provider.h"
14 
15 namespace views {
16 
17 namespace {
18 
19 // Allows for the control of whether or not the widget can minimize/maximize or
20 // not. This can be set after initial setup in order to allow testing of both
21 // forms of delegates. By default this can minimize and maximize.
22 class MinimizeAndMaximizeStateControlDelegate : public WidgetDelegateView {
23  public:
MinimizeAndMaximizeStateControlDelegate()24   MinimizeAndMaximizeStateControlDelegate()
25         : can_maximize_(true),
26           can_minimize_(true) {}
~MinimizeAndMaximizeStateControlDelegate()27   virtual ~MinimizeAndMaximizeStateControlDelegate() {}
28 
set_can_maximize(bool can_maximize)29   void set_can_maximize(bool can_maximize) {
30     can_maximize_ = can_maximize;
31   }
32 
set_can_minimize(bool can_minimize)33   void set_can_minimize(bool can_minimize) {
34     can_minimize_ = can_minimize;
35   }
36 
37   // WidgetDelegate:
CanMaximize() const38   virtual bool CanMaximize() const OVERRIDE { return can_maximize_; }
CanMinimize() const39   virtual bool CanMinimize() const OVERRIDE { return can_minimize_; }
40 
41  private:
42   bool can_maximize_;
43   bool can_minimize_;
44 
45   DISALLOW_COPY_AND_ASSIGN(MinimizeAndMaximizeStateControlDelegate);
46 };
47 
48 }  // namespace
49 
50 class CustomFrameViewTest : public ViewsTestBase {
51  public:
CustomFrameViewTest()52   CustomFrameViewTest() {}
~CustomFrameViewTest()53   virtual ~CustomFrameViewTest() {}
54 
custom_frame_view()55   CustomFrameView* custom_frame_view() {
56     return custom_frame_view_;
57   }
58 
59   MinimizeAndMaximizeStateControlDelegate*
minimize_and_maximize_state_control_delegate()60         minimize_and_maximize_state_control_delegate() {
61     return minimize_and_maximize_state_control_delegate_;
62   }
63 
widget()64   Widget* widget() {
65     return widget_;
66   }
67 
68   // ViewsTestBase:
69   virtual void SetUp() OVERRIDE;
70   virtual void TearDown() OVERRIDE;
71 
72  protected:
leading_buttons()73   const std::vector<views::FrameButton>& leading_buttons() {
74     return WindowButtonOrderProvider::GetInstance()->leading_buttons();
75   }
76 
trailing_buttons()77   const std::vector<views::FrameButton>& trailing_buttons() {
78     return WindowButtonOrderProvider::GetInstance()->trailing_buttons();
79   }
80 
minimize_button()81   ImageButton* minimize_button() {
82     return custom_frame_view_->minimize_button_;
83   }
84 
maximize_button()85   ImageButton* maximize_button() {
86     return custom_frame_view_->maximize_button_;
87   }
88 
restore_button()89   ImageButton* restore_button() {
90     return custom_frame_view_->restore_button_;
91   }
92 
close_button()93   ImageButton* close_button() {
94     return custom_frame_view_->close_button_;
95   }
96 
title_bounds()97   gfx::Rect title_bounds() {
98     return custom_frame_view_->title_bounds_;
99   }
100 
101   void SetWindowButtonOrder(
102       const std::vector<views::FrameButton> leading_buttons,
103       const std::vector<views::FrameButton> trailing_buttons);
104 
105  private:
106   // Parent container for |custom_frame_view_|
107   Widget* widget_;
108 
109   // Owned by |widget_|
110   CustomFrameView* custom_frame_view_;
111 
112   // Delegate of |widget_| which controls minimizing and maximizing
113   MinimizeAndMaximizeStateControlDelegate*
114         minimize_and_maximize_state_control_delegate_;
115 
116   DISALLOW_COPY_AND_ASSIGN(CustomFrameViewTest);
117 };
118 
SetUp()119 void CustomFrameViewTest::SetUp() {
120   ViewsTestBase::SetUp();
121 
122   minimize_and_maximize_state_control_delegate_ =
123       new MinimizeAndMaximizeStateControlDelegate;
124   widget_ = new Widget;
125   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
126   params.delegate = minimize_and_maximize_state_control_delegate_;
127   params.remove_standard_frame = true;
128   widget_->Init(params);
129 
130   custom_frame_view_ = new CustomFrameView;
131   widget_->non_client_view()->SetFrameView(custom_frame_view_);
132 }
133 
TearDown()134 void CustomFrameViewTest::TearDown() {
135   widget_->CloseNow();
136 
137   ViewsTestBase::TearDown();
138 }
139 
SetWindowButtonOrder(const std::vector<views::FrameButton> leading_buttons,const std::vector<views::FrameButton> trailing_buttons)140 void CustomFrameViewTest::SetWindowButtonOrder(
141     const std::vector<views::FrameButton> leading_buttons,
142     const std::vector<views::FrameButton> trailing_buttons) {
143   WindowButtonOrderProvider::GetInstance()->
144       SetWindowButtonOrder(leading_buttons, trailing_buttons);
145 }
146 
147 // Tests that there is a default button ordering before initialization causes
148 // a configuration file check.
TEST_F(CustomFrameViewTest,DefaultButtons)149 TEST_F(CustomFrameViewTest, DefaultButtons) {
150   const std::vector<views::FrameButton>& trailing = trailing_buttons();
151   EXPECT_EQ(trailing.size(), 3u);
152   EXPECT_TRUE(leading_buttons().empty());
153   EXPECT_EQ(trailing[0], FRAME_BUTTON_MINIMIZE);
154   EXPECT_EQ(trailing[1], FRAME_BUTTON_MAXIMIZE);
155   EXPECT_EQ(trailing[2], FRAME_BUTTON_CLOSE);
156 }
157 
158 // Tests that layout places the buttons in order, that the restore button is
159 // hidden and the buttons are placed after the title.
TEST_F(CustomFrameViewTest,DefaultButtonLayout)160 TEST_F(CustomFrameViewTest, DefaultButtonLayout) {
161   Widget* parent = widget();
162   CustomFrameView* view = custom_frame_view();
163   view->Init(parent);
164   parent->SetBounds(gfx::Rect(0, 0, 300, 100));
165   parent->Show();
166 
167   EXPECT_LT(minimize_button()->x(), maximize_button()->x());
168   EXPECT_LT(maximize_button()->x(), close_button()->x());
169   EXPECT_FALSE(restore_button()->visible());
170 
171   EXPECT_GT(minimize_button()->x(),
172             title_bounds().x() + title_bounds().width());
173 }
174 
175 // Tests that setting the buttons to leading places them before the title.
TEST_F(CustomFrameViewTest,LeadingButtonLayout)176 TEST_F(CustomFrameViewTest, LeadingButtonLayout) {
177   Widget* parent = widget();
178   CustomFrameView* view = custom_frame_view();
179 
180   std::vector<views::FrameButton> leading;
181   leading.push_back(views::FRAME_BUTTON_CLOSE);
182   leading.push_back(views::FRAME_BUTTON_MINIMIZE);
183   leading.push_back(views::FRAME_BUTTON_MAXIMIZE);
184 
185   std::vector<views::FrameButton> trailing;
186 
187   SetWindowButtonOrder(leading, trailing);
188 
189   view->Init(parent);
190   parent->SetBounds(gfx::Rect(0, 0, 300, 100));
191   parent->Show();
192   EXPECT_LT(close_button()->x(), minimize_button()->x());
193   EXPECT_LT(minimize_button()->x(), maximize_button()->x());
194   EXPECT_FALSE(restore_button()->visible());
195   EXPECT_LT(maximize_button()->x() + maximize_button()->width(),
196             title_bounds().x());
197 }
198 
199 // Tests that layouts occuring while maximized swap the maximize button for the
200 // restore button
TEST_F(CustomFrameViewTest,MaximizeRevealsRestoreButton)201 TEST_F(CustomFrameViewTest, MaximizeRevealsRestoreButton) {
202   Widget* parent = widget();
203   CustomFrameView* view = custom_frame_view();
204   view->Init(parent);
205   parent->SetBounds(gfx::Rect(0, 0, 300, 100));
206   parent->Show();
207 
208   ASSERT_FALSE(restore_button()->visible());
209   ASSERT_TRUE(maximize_button()->visible());
210 
211   parent->Maximize();
212   view->Layout();
213 
214   EXPECT_TRUE(restore_button()->visible());
215   EXPECT_FALSE(maximize_button()->visible());
216 }
217 
218 // Tests that when the parent cannot maximize that the maximize button is not
219 // visible
TEST_F(CustomFrameViewTest,CannotMaximizeHidesButton)220 TEST_F(CustomFrameViewTest, CannotMaximizeHidesButton) {
221   Widget* parent = widget();
222   CustomFrameView* view = custom_frame_view();
223   MinimizeAndMaximizeStateControlDelegate* delegate =
224         minimize_and_maximize_state_control_delegate();
225   delegate->set_can_maximize(false);
226 
227   view->Init(parent);
228   parent->SetBounds(gfx::Rect(0, 0, 300, 100));
229   parent->Show();
230 
231   EXPECT_FALSE(restore_button()->visible());
232   EXPECT_FALSE(maximize_button()->visible());
233 }
234 
235 // Tests that when the parent cannot minimize that the minimize button is not
236 // visible
TEST_F(CustomFrameViewTest,CannotMinimizeHidesButton)237 TEST_F(CustomFrameViewTest, CannotMinimizeHidesButton) {
238   Widget* parent = widget();
239   CustomFrameView* view = custom_frame_view();
240   MinimizeAndMaximizeStateControlDelegate* delegate =
241       minimize_and_maximize_state_control_delegate();
242   delegate->set_can_minimize(false);
243 
244   view->Init(parent);
245   parent->SetBounds(gfx::Rect(0, 0, 300, 100));
246   parent->Show();
247 
248   EXPECT_FALSE(minimize_button()->visible());
249 }
250 
251 // Tests that when maximized that the edge button has an increased width.
TEST_F(CustomFrameViewTest,LargerEdgeButtonsWhenMaximized)252 TEST_F(CustomFrameViewTest, LargerEdgeButtonsWhenMaximized) {
253   Widget* parent = widget();
254   CustomFrameView* view = custom_frame_view();
255 
256   // Custom ordering to have a button on each edge.
257   std::vector<views::FrameButton> leading;
258   leading.push_back(views::FRAME_BUTTON_CLOSE);
259   leading.push_back(views::FRAME_BUTTON_MAXIMIZE);
260   std::vector<views::FrameButton> trailing;
261   trailing.push_back(views::FRAME_BUTTON_MINIMIZE);
262   SetWindowButtonOrder(leading, trailing);
263 
264   view->Init(parent);
265   parent->SetBounds(gfx::Rect(0, 0, 300, 100));
266   parent->Show();
267 
268   gfx::Rect close_button_initial_bounds = close_button()->bounds();
269   gfx::Rect minimize_button_initial_bounds = minimize_button()->bounds();
270 
271   parent->Maximize();
272   view->Layout();
273 
274   EXPECT_GT(close_button()->bounds().width(),
275             close_button_initial_bounds.width());
276   EXPECT_GT(minimize_button()->bounds().width(),
277             minimize_button_initial_bounds.width());
278 }
279 
280 }  // namespace views
281