blob: 551658a8d045501525b7add532b7e62fbd909d82 [file] [log] [blame]
// Copyright 2013 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 "ash/wm/header_painter.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/caption_buttons/frame_caption_button_container_view.h"
#include "ash/wm/window_state.h"
#include "base/memory/scoped_ptr.h"
#include "grit/ash_resources.h"
#include "ui/gfx/font.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/non_client_view.h"
using ash::HeaderPainter;
using views::NonClientFrameView;
using views::Widget;
namespace {
// Modifies the values of kInactiveWindowOpacity, kActiveWindowOpacity, and
// kSoloWindowOpacity for the lifetime of the class. This is useful so that
// the constants each have different values.
class ScopedOpacityConstantModifier {
public:
ScopedOpacityConstantModifier()
: initial_active_window_opacity_(
ash::HeaderPainter::kActiveWindowOpacity),
initial_inactive_window_opacity_(
ash::HeaderPainter::kInactiveWindowOpacity),
initial_solo_window_opacity_(ash::HeaderPainter::kSoloWindowOpacity) {
ash::HeaderPainter::kActiveWindowOpacity = 100;
ash::HeaderPainter::kInactiveWindowOpacity = 120;
ash::HeaderPainter::kSoloWindowOpacity = 140;
}
~ScopedOpacityConstantModifier() {
ash::HeaderPainter::kActiveWindowOpacity = initial_active_window_opacity_;
ash::HeaderPainter::kInactiveWindowOpacity =
initial_inactive_window_opacity_;
ash::HeaderPainter::kSoloWindowOpacity = initial_solo_window_opacity_;
}
private:
int initial_active_window_opacity_;
int initial_inactive_window_opacity_;
int initial_solo_window_opacity_;
DISALLOW_COPY_AND_ASSIGN(ScopedOpacityConstantModifier);
};
// Creates a new HeaderPainter with empty buttons. Caller owns the memory.
HeaderPainter* CreateTestPainter(Widget* widget) {
HeaderPainter* painter = new HeaderPainter();
NonClientFrameView* frame_view = widget->non_client_view()->frame_view();
ash::FrameCaptionButtonContainerView* container =
new ash::FrameCaptionButtonContainerView(
widget,
ash::FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
// Add the container to the widget's non-client frame view so that it will be
// deleted when the widget is destroyed.
frame_view->AddChildView(container);
painter->Init(widget, frame_view, NULL, container);
return painter;
}
} // namespace
namespace ash {
class HeaderPainterTest : public ash::test::AshTestBase {
public:
// Creates a test widget that owns its native widget.
Widget* CreateTestWidget() {
Widget* widget = new Widget;
Widget::InitParams params;
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.context = CurrentContext();
widget->Init(params);
return widget;
}
};
TEST_F(HeaderPainterTest, GetHeaderOpacity) {
// Create a widget and a painter for it.
scoped_ptr<Widget> w1(CreateTestWidget());
scoped_ptr<HeaderPainter> p1(CreateTestPainter(w1.get()));
w1->Show();
// Modify the values of the opacity constants so that they each have a
// different value.
ScopedOpacityConstantModifier opacity_constant_modifier;
// Solo active window has solo window opacity.
EXPECT_EQ(HeaderPainter::kSoloWindowOpacity,
p1->GetHeaderOpacity(HeaderPainter::ACTIVE,
IDR_AURA_WINDOW_HEADER_BASE_ACTIVE,
0));
// Create a second widget and painter.
scoped_ptr<Widget> w2(CreateTestWidget());
scoped_ptr<HeaderPainter> p2(CreateTestPainter(w2.get()));
w2->Show();
// Active window has active window opacity.
EXPECT_EQ(HeaderPainter::kActiveWindowOpacity,
p2->GetHeaderOpacity(HeaderPainter::ACTIVE,
IDR_AURA_WINDOW_HEADER_BASE_ACTIVE,
0));
// Inactive window has inactive window opacity.
EXPECT_EQ(HeaderPainter::kInactiveWindowOpacity,
p2->GetHeaderOpacity(HeaderPainter::INACTIVE,
IDR_AURA_WINDOW_HEADER_BASE_INACTIVE,
0));
// Regular maximized windows are fully opaque.
wm::GetWindowState(w1->GetNativeWindow())->Maximize();
EXPECT_EQ(255,
p1->GetHeaderOpacity(HeaderPainter::ACTIVE,
IDR_AURA_WINDOW_HEADER_BASE_ACTIVE,
0));
}
// Test that the minimal header style is used in the proper situations.
TEST_F(HeaderPainterTest, MinimalHeaderStyle) {
// Create a widget and a painter for it.
scoped_ptr<Widget> w(CreateTestWidget());
scoped_ptr<HeaderPainter> p(CreateTestPainter(w.get()));
w->Show();
// Regular non-maximized windows should not use the minimal header style.
EXPECT_FALSE(p->ShouldUseMinimalHeaderStyle(HeaderPainter::THEMED_NO));
// Regular maximized windows should use the minimal header style.
w->Maximize();
EXPECT_TRUE(p->ShouldUseMinimalHeaderStyle(HeaderPainter::THEMED_NO));
// Test cases where the maximized window should not use the minimal header
// style.
EXPECT_FALSE(p->ShouldUseMinimalHeaderStyle(HeaderPainter::THEMED_YES));
wm::GetWindowState(w->GetNativeWindow())->SetTrackedByWorkspace(false);
EXPECT_FALSE(p->ShouldUseMinimalHeaderStyle(HeaderPainter::THEMED_NO));
wm::GetWindowState(w->GetNativeWindow())->SetTrackedByWorkspace(true);
}
// Ensure the title text is vertically aligned with the window icon.
TEST_F(HeaderPainterTest, TitleIconAlignment) {
scoped_ptr<Widget> w(CreateTestWidget());
HeaderPainter p;
ash::FrameCaptionButtonContainerView container(w.get(),
ash::FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
views::View window_icon;
window_icon.SetBounds(0, 0, 16, 16);
p.Init(w.get(),
w->non_client_view()->frame_view(),
&window_icon,
&container);
w->SetBounds(gfx::Rect(0, 0, 500, 500));
w->Show();
// Title and icon are aligned when shorter_header is false.
p.LayoutHeader(false);
gfx::Font default_font;
gfx::Rect large_header_title_bounds = p.GetTitleBounds(default_font);
EXPECT_EQ(window_icon.bounds().CenterPoint().y(),
large_header_title_bounds.CenterPoint().y());
// Title and icon are aligned when shorter_header is true.
p.LayoutHeader(true);
gfx::Rect short_header_title_bounds = p.GetTitleBounds(default_font);
EXPECT_EQ(window_icon.bounds().CenterPoint().y(),
short_header_title_bounds.CenterPoint().y());
}
} // namespace ash