blob: 267111902144415eaead9361980e7c7483b158f4 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/window/custom_frame_view.h"
#include <vector>
#include "ui/views/controls/button/image_button.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/window_button_order_provider.h"
namespace views {
namespace {
// Allows for the control of whether or not the widget can maximize or not.
// This can be set after initial setup in order to allow testing of both forms
// of delegates. By default this can maximize.
class MaximizeStateControlDelegate : public WidgetDelegateView {
public:
MaximizeStateControlDelegate() : can_maximize_(true) {}
virtual ~MaximizeStateControlDelegate() {}
void set_can_maximize(bool can_maximize) {
can_maximize_ = can_maximize;
}
// WidgetDelegate:
virtual bool CanMaximize() const OVERRIDE { return can_maximize_; }
private:
bool can_maximize_;
DISALLOW_COPY_AND_ASSIGN(MaximizeStateControlDelegate);
};
} // namespace
class CustomFrameViewTest : public ViewsTestBase {
public:
CustomFrameViewTest() {}
virtual ~CustomFrameViewTest() {}
CustomFrameView* custom_frame_view() {
return custom_frame_view_;
}
MaximizeStateControlDelegate* maximize_state_control_delegate() {
return maximize_state_control_delegate_;
}
Widget* widget() {
return widget_;
}
// ViewsTestBase:
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
protected:
const std::vector<views::FrameButton>& leading_buttons() {
return WindowButtonOrderProvider::GetInstance()->leading_buttons();
}
const std::vector<views::FrameButton>& trailing_buttons() {
return WindowButtonOrderProvider::GetInstance()->trailing_buttons();
}
ImageButton* minimize_button() {
return custom_frame_view_->minimize_button_;
}
ImageButton* maximize_button() {
return custom_frame_view_->maximize_button_;
}
ImageButton* restore_button() {
return custom_frame_view_->restore_button_;
}
ImageButton* close_button() {
return custom_frame_view_->close_button_;
}
gfx::Rect title_bounds() {
return custom_frame_view_->title_bounds_;
}
void SetWindowButtonOrder(
const std::vector<views::FrameButton> leading_buttons,
const std::vector<views::FrameButton> trailing_buttons);
private:
// Parent container for |custom_frame_view_|
Widget* widget_;
// Owned by |widget_|
CustomFrameView* custom_frame_view_;
// Delegate of |widget_| which controls maximizing
MaximizeStateControlDelegate* maximize_state_control_delegate_;
DISALLOW_COPY_AND_ASSIGN(CustomFrameViewTest);
};
void CustomFrameViewTest::SetUp() {
ViewsTestBase::SetUp();
maximize_state_control_delegate_ = new MaximizeStateControlDelegate;
widget_ = new Widget;
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.delegate = maximize_state_control_delegate_;
params.remove_standard_frame = true;
widget_->Init(params);
custom_frame_view_ = new CustomFrameView;
widget_->non_client_view()->SetFrameView(custom_frame_view_);
}
void CustomFrameViewTest::TearDown() {
widget_->CloseNow();
ViewsTestBase::TearDown();
}
void CustomFrameViewTest::SetWindowButtonOrder(
const std::vector<views::FrameButton> leading_buttons,
const std::vector<views::FrameButton> trailing_buttons) {
WindowButtonOrderProvider::GetInstance()->
SetWindowButtonOrder(leading_buttons, trailing_buttons);
}
// Tests that there is a default button ordering before initialization causes
// a configuration file check.
TEST_F(CustomFrameViewTest, DefaultButtons) {
const std::vector<views::FrameButton>& trailing = trailing_buttons();
EXPECT_EQ(trailing.size(), 3u);
EXPECT_TRUE(leading_buttons().empty());
EXPECT_EQ(trailing[0], FRAME_BUTTON_MINIMIZE);
EXPECT_EQ(trailing[1], FRAME_BUTTON_MAXIMIZE);
EXPECT_EQ(trailing[2], FRAME_BUTTON_CLOSE);
}
// Tests that layout places the buttons in order, that the restore button is
// hidden and the buttons are placed after the title.
TEST_F(CustomFrameViewTest, DefaultButtonLayout) {
Widget* parent = widget();
CustomFrameView* view = custom_frame_view();
view->Init(parent);
parent->SetBounds(gfx::Rect(0, 0, 300, 100));
parent->Show();
EXPECT_LT(minimize_button()->x(), maximize_button()->x());
EXPECT_LT(maximize_button()->x(), close_button()->x());
EXPECT_FALSE(restore_button()->visible());
EXPECT_GT(minimize_button()->x(),
title_bounds().x() + title_bounds().width());
}
// Tests that setting the buttons to leading places them before the title.
TEST_F(CustomFrameViewTest, LeadingButtonLayout) {
Widget* parent = widget();
CustomFrameView* view = custom_frame_view();
std::vector<views::FrameButton> leading;
leading.push_back(views::FRAME_BUTTON_CLOSE);
leading.push_back(views::FRAME_BUTTON_MINIMIZE);
leading.push_back(views::FRAME_BUTTON_MAXIMIZE);
std::vector<views::FrameButton> trailing;
SetWindowButtonOrder(leading, trailing);
view->Init(parent);
parent->SetBounds(gfx::Rect(0, 0, 300, 100));
parent->Show();
EXPECT_LT(close_button()->x(), minimize_button()->x());
EXPECT_LT(minimize_button()->x(), maximize_button()->x());
EXPECT_FALSE(restore_button()->visible());
EXPECT_LT(maximize_button()->x() + maximize_button()->width(),
title_bounds().x());
}
// Tests that layouts occuring while maximized swap the maximize button for the
// restore button
TEST_F(CustomFrameViewTest, MaximizeRevealsRestoreButton) {
Widget* parent = widget();
CustomFrameView* view = custom_frame_view();
view->Init(parent);
parent->SetBounds(gfx::Rect(0, 0, 300, 100));
parent->Show();
ASSERT_FALSE(restore_button()->visible());
ASSERT_TRUE(maximize_button()->visible());
parent->Maximize();
view->Layout();
EXPECT_TRUE(restore_button()->visible());
EXPECT_FALSE(maximize_button()->visible());
}
// Tests that when the parent cannot maximize that the maximize button is not
// visible
TEST_F(CustomFrameViewTest, CannotMaximizeHidesButton) {
Widget* parent = widget();
CustomFrameView* view = custom_frame_view();
MaximizeStateControlDelegate* delegate = maximize_state_control_delegate();
delegate->set_can_maximize(false);
view->Init(parent);
parent->SetBounds(gfx::Rect(0, 0, 300, 100));
parent->Show();
EXPECT_FALSE(restore_button()->visible());
EXPECT_FALSE(maximize_button()->visible());
}
// Tests that when maximized that the edge button has an increased width.
TEST_F(CustomFrameViewTest, LargerEdgeButtonsWhenMaximized) {
Widget* parent = widget();
CustomFrameView* view = custom_frame_view();
// Custom ordering to have a button on each edge.
std::vector<views::FrameButton> leading;
leading.push_back(views::FRAME_BUTTON_CLOSE);
leading.push_back(views::FRAME_BUTTON_MAXIMIZE);
std::vector<views::FrameButton> trailing;
trailing.push_back(views::FRAME_BUTTON_MINIMIZE);
SetWindowButtonOrder(leading, trailing);
view->Init(parent);
parent->SetBounds(gfx::Rect(0, 0, 300, 100));
parent->Show();
gfx::Rect close_button_initial_bounds = close_button()->bounds();
gfx::Rect minimize_button_initial_bounds = minimize_button()->bounds();
parent->Maximize();
view->Layout();
EXPECT_GT(close_button()->bounds().width(),
close_button_initial_bounds.width());
EXPECT_GT(minimize_button()->bounds().width(),
minimize_button_initial_bounds.width());
}
} // namespace views