1 // Copyright (c) 2012 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.
5 #include "ash/wm/custom_frame_view_ash.h"
7 #include "ash/wm/frame_painter.h"
8 #include "ash/wm/workspace/frame_maximize_button.h"
9 #include "grit/ash_resources.h"
10 #include "grit/ui_strings.h" // Accessibility names
11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/base/resource/resource_bundle.h"
13 #include "ui/compositor/layer_animator.h"
14 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/font.h"
17 #include "ui/gfx/image/image.h"
18 #include "ui/gfx/rect.h"
19 #include "ui/gfx/size.h"
20 #include "ui/views/controls/button/image_button.h"
21 #include "ui/views/widget/native_widget_aura.h"
22 #include "ui/views/widget/widget.h"
23 #include "ui/views/widget/widget_delegate.h"
27 const gfx::Font
& GetTitleFont() {
28 static gfx::Font
* title_font
= NULL
;
30 title_font
= new gfx::Font(views::NativeWidgetAura::GetWindowTitleFont());
39 const char CustomFrameViewAsh::kViewClassName
[] = "ash/wm/CustomFrameViewAsh";
41 ////////////////////////////////////////////////////////////////////////////////
42 // CustomFrameViewAsh, public:
43 CustomFrameViewAsh::CustomFrameViewAsh()
45 maximize_button_(NULL
),
48 frame_painter_(new ash::FramePainter
) {
51 CustomFrameViewAsh::~CustomFrameViewAsh() {
54 void CustomFrameViewAsh::Init(views::Widget
* frame
) {
57 maximize_button_
= new FrameMaximizeButton(this, this);
58 maximize_button_
->SetAccessibleName(
59 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE
));
60 AddChildView(maximize_button_
);
61 close_button_
= new views::ImageButton(this);
62 close_button_
->SetAccessibleName(
63 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE
));
64 AddChildView(close_button_
);
66 maximize_button_
->SetVisible(frame_
->widget_delegate()->CanMaximize());
68 if (frame_
->widget_delegate()->ShouldShowWindowIcon()) {
69 window_icon_
= new views::ImageButton(this);
70 AddChildView(window_icon_
);
73 frame_painter_
->Init(frame_
, window_icon_
, maximize_button_
, close_button_
,
74 FramePainter::SIZE_BUTTON_MAXIMIZES
);
77 ////////////////////////////////////////////////////////////////////////////////
78 // CustomFrameViewAsh, views::NonClientFrameView overrides:
79 gfx::Rect
CustomFrameViewAsh::GetBoundsForClientView() const {
80 int top_height
= NonClientTopBorderHeight();
81 return frame_painter_
->GetBoundsForClientView(top_height
,
85 gfx::Rect
CustomFrameViewAsh::GetWindowBoundsForClientBounds(
86 const gfx::Rect
& client_bounds
) const {
87 int top_height
= NonClientTopBorderHeight();
88 return frame_painter_
->GetWindowBoundsForClientBounds(top_height
,
92 int CustomFrameViewAsh::NonClientHitTest(const gfx::Point
& point
) {
93 return frame_painter_
->NonClientHitTest(this, point
);
96 void CustomFrameViewAsh::GetWindowMask(const gfx::Size
& size
,
97 gfx::Path
* window_mask
) {
98 // No window masks in Aura.
101 void CustomFrameViewAsh::ResetWindowControls() {
102 maximize_button_
->SetState(views::CustomButton::STATE_NORMAL
);
105 void CustomFrameViewAsh::UpdateWindowIcon() {
107 window_icon_
->SchedulePaint();
110 void CustomFrameViewAsh::UpdateWindowTitle() {
111 frame_painter_
->SchedulePaintForTitle(this, GetTitleFont());
114 ////////////////////////////////////////////////////////////////////////////////
115 // CustomFrameViewAsh, views::View overrides:
117 gfx::Size
CustomFrameViewAsh::GetPreferredSize() {
118 gfx::Size pref
= frame_
->client_view()->GetPreferredSize();
119 gfx::Rect
bounds(0, 0, pref
.width(), pref
.height());
120 return frame_
->non_client_view()->GetWindowBoundsForClientBounds(
124 void CustomFrameViewAsh::Layout() {
125 // Use the shorter maximized layout headers.
126 frame_painter_
->LayoutHeader(this, true);
129 void CustomFrameViewAsh::OnPaint(gfx::Canvas
* canvas
) {
130 if (frame_
->IsFullscreen())
133 // Prevent bleeding paint onto the client area below the window frame, which
134 // may become visible when the WebContent is transparent.
136 canvas
->ClipRect(gfx::Rect(0, 0, width(), NonClientTopBorderHeight()));
138 bool paint_as_active
= ShouldPaintAsActive();
139 int theme_image_id
= paint_as_active
? IDR_AURA_WINDOW_HEADER_BASE_ACTIVE
:
140 IDR_AURA_WINDOW_HEADER_BASE_INACTIVE
;
141 frame_painter_
->PaintHeader(
144 paint_as_active
? FramePainter::ACTIVE
: FramePainter::INACTIVE
,
147 frame_painter_
->PaintTitleBar(this, canvas
, GetTitleFont());
148 frame_painter_
->PaintHeaderContentSeparator(this, canvas
);
152 std::string
CustomFrameViewAsh::GetClassName() const {
153 return kViewClassName
;
156 gfx::Size
CustomFrameViewAsh::GetMinimumSize() {
157 return frame_painter_
->GetMinimumSize(this);
160 gfx::Size
CustomFrameViewAsh::GetMaximumSize() {
161 return frame_painter_
->GetMaximumSize(this);
164 ////////////////////////////////////////////////////////////////////////////////
165 // views::ButtonListener overrides:
166 void CustomFrameViewAsh::ButtonPressed(views::Button
* sender
,
167 const ui::Event
& event
) {
168 scoped_ptr
<ui::ScopedAnimationDurationScaleMode
> slow_duration_mode
;
169 if (event
.IsShiftDown()) {
170 slow_duration_mode
.reset(new ui::ScopedAnimationDurationScaleMode(
171 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION
));
173 if (sender
== maximize_button_
) {
174 // The maximize button may move out from under the cursor.
175 ResetWindowControls();
176 if (frame_
->IsMaximized())
180 // |this| may be deleted - some windows delete their frames on maximize.
181 } else if (sender
== close_button_
) {
186 ////////////////////////////////////////////////////////////////////////////////
187 // CustomFrameViewAsh, private:
189 int CustomFrameViewAsh::NonClientTopBorderHeight() const {
190 if (frame_
->IsFullscreen())
193 // Reserve enough space to see the buttons, including any offset from top and
194 // reserving space for the separator line.
195 return close_button_
->bounds().bottom() +
196 frame_painter_
->HeaderContentSeparatorSize();