Home | History | Annotate | Download | only in window
      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:
     24   MinimizeAndMaximizeStateControlDelegate()
     25         : can_maximize_(true),
     26           can_minimize_(true) {}
     27   virtual ~MinimizeAndMaximizeStateControlDelegate() {}
     28 
     29   void set_can_maximize(bool can_maximize) {
     30     can_maximize_ = can_maximize;
     31   }
     32 
     33   void set_can_minimize(bool can_minimize) {
     34     can_minimize_ = can_minimize;
     35   }
     36 
     37   // WidgetDelegate:
     38   virtual bool CanMaximize() const OVERRIDE { return can_maximize_; }
     39   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:
     52   CustomFrameViewTest() {}
     53   virtual ~CustomFrameViewTest() {}
     54 
     55   CustomFrameView* custom_frame_view() {
     56     return custom_frame_view_;
     57   }
     58 
     59   MinimizeAndMaximizeStateControlDelegate*
     60         minimize_and_maximize_state_control_delegate() {
     61     return minimize_and_maximize_state_control_delegate_;
     62   }
     63 
     64   Widget* widget() {
     65     return widget_;
     66   }
     67 
     68   // ViewsTestBase:
     69   virtual void SetUp() OVERRIDE;
     70   virtual void TearDown() OVERRIDE;
     71 
     72  protected:
     73   const std::vector<views::FrameButton>& leading_buttons() {
     74     return WindowButtonOrderProvider::GetInstance()->leading_buttons();
     75   }
     76 
     77   const std::vector<views::FrameButton>& trailing_buttons() {
     78     return WindowButtonOrderProvider::GetInstance()->trailing_buttons();
     79   }
     80 
     81   ImageButton* minimize_button() {
     82     return custom_frame_view_->minimize_button_;
     83   }
     84 
     85   ImageButton* maximize_button() {
     86     return custom_frame_view_->maximize_button_;
     87   }
     88 
     89   ImageButton* restore_button() {
     90     return custom_frame_view_->restore_button_;
     91   }
     92 
     93   ImageButton* close_button() {
     94     return custom_frame_view_->close_button_;
     95   }
     96 
     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 
    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 
    134 void CustomFrameViewTest::TearDown() {
    135   widget_->CloseNow();
    136 
    137   ViewsTestBase::TearDown();
    138 }
    139 
    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.
    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.
    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.
    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
    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
    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
    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.
    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