1 // Copyright 2013 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 #ifndef ASH_WM_HEADER_PAINTER_H_
6 #define ASH_WM_HEADER_PAINTER_H_
8 #include "ash/ash_export.h"
9 #include "ash/wm/window_state_observer.h"
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h" // OVERRIDE
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "ui/aura/window_observer.h"
15 #include "ui/gfx/animation/animation_delegate.h"
16 #include "ui/gfx/rect.h"
35 class FrameCaptionButtonContainerView
;
37 // Helper class for painting the window header.
38 class ASH_EXPORT HeaderPainter
: public aura::WindowObserver
,
39 public gfx::AnimationDelegate
,
40 public wm::WindowStateObserver
{
42 // Opacity values for the window header in various states, from 0 to 255.
43 static int kActiveWindowOpacity
;
44 static int kInactiveWindowOpacity
;
45 static int kSoloWindowOpacity
;
58 virtual ~HeaderPainter();
60 // None of the parameters are owned.
61 void Init(views::Widget
* frame
,
62 views::View
* header_view
,
63 views::View
* window_icon
,
64 FrameCaptionButtonContainerView
* caption_button_container
);
66 // Enable/Disable the solo-window transparent header appearance feature.
67 static void SetSoloWindowHeadersEnabled(bool enabled
);
69 // Updates the solo-window transparent header appearance for all windows
70 // using frame painters in |root_window|.
71 static void UpdateSoloWindowHeader(aura::Window
* root_window
);
73 // Returns the bounds of the client view for a window with |header_height|
74 // and |window_bounds|. The return value and |window_bounds| are in the
75 // views::NonClientView's coordinates.
76 static gfx::Rect
GetBoundsForClientView(int header_height
,
77 const gfx::Rect
& window_bounds
);
79 // Returns the bounds of the window given |header_height| and |client_bounds|.
80 // The return value and |client_bounds| are in the views::NonClientView's
82 static gfx::Rect
GetWindowBoundsForClientBounds(
84 const gfx::Rect
& client_bounds
);
86 // Determines the window HT* code at |point|. Returns HTNOWHERE if |point| is
87 // not within the top |header_height_| of |header_view_|. |point| is in the
88 // coordinates of |header_view_|'s widget. The client view must be hittested
89 // before calling this method because a browser's tabs are in the top
90 // |header_height_| of |header_view_|.
91 int NonClientHitTest(const gfx::Point
& point
) const;
93 // Returns the header's minimum width.
94 int GetMinimumHeaderWidth() const;
96 // Returns the inset from the right edge.
97 int GetRightInset() const;
99 // Returns the amount that the theme background should be inset.
100 int GetThemeBackgroundXInset() const;
102 // Returns true if the header should be painted using a minimalistic style.
103 bool ShouldUseMinimalHeaderStyle(Themed header_themed
) const;
105 // Paints the header.
106 // |theme_frame_overlay_id| is 0 if no overlay image should be used.
107 void PaintHeader(gfx::Canvas
* canvas
,
108 HeaderMode header_mode
,
110 int theme_frame_overlay_id
);
112 // Paints the header/content separator line. Exists as a separate function
113 // because some windows with complex headers (e.g. browsers with tab strips)
114 // need to draw their own line.
115 void PaintHeaderContentSeparator(gfx::Canvas
* canvas
);
117 // Returns size of the header/content separator line in pixels.
118 int HeaderContentSeparatorSize() const;
120 // Paint the title bar, primarily the title string.
121 void PaintTitleBar(gfx::Canvas
* canvas
, const gfx::Font
& title_font
);
123 // Performs layout for the header based on whether we want the shorter
124 // appearance. |shorter_layout| is typically used for maximized windows, but
126 void LayoutHeader(bool shorter_layout
);
128 // Sets the height of the header. The height of the header affects painting,
129 // and non client hit tests. It does not affect layout.
130 void set_header_height(int header_height
) {
131 header_height_
= header_height
;
134 // Schedule a re-paint of the entire title.
135 void SchedulePaintForTitle(const gfx::Font
& title_font
);
137 // Called when the browser theme changes.
138 void OnThemeChanged();
140 // aura::WindowObserver overrides:
141 virtual void OnWindowVisibilityChanged(aura::Window
* window
,
142 bool visible
) OVERRIDE
;
143 virtual void OnWindowDestroying(aura::Window
* window
) OVERRIDE
;
144 virtual void OnWindowBoundsChanged(aura::Window
* window
,
145 const gfx::Rect
& old_bounds
,
146 const gfx::Rect
& new_bounds
) OVERRIDE
;
147 virtual void OnWindowAddedToRootWindow(aura::Window
* window
) OVERRIDE
;
148 virtual void OnWindowRemovingFromRootWindow(aura::Window
* window
) OVERRIDE
;
150 // ash::WindowStateObserver override:
151 virtual void OnTrackedByWorkspaceChanged(wm::WindowState
* window_state
,
154 // Overridden from gfx::AnimationDelegate
155 virtual void AnimationProgressed(const gfx::Animation
* animation
) OVERRIDE
;
158 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, CreateAndDeleteSingleWindow
);
159 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeader
);
160 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeaderWithApp
);
161 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeaderWithPanel
);
162 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeaderModal
);
163 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeaderConstrained
);
164 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeaderNotDrawn
);
165 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, UseSoloWindowHeaderMultiDisplay
);
166 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, GetHeaderOpacity
);
167 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, TitleIconAlignment
);
168 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
, ChildWindowVisibility
);
169 FRIEND_TEST_ALL_PREFIXES(HeaderPainterTest
,
170 NoCrashShutdownWithAlwaysOnTopWindow
);
172 // Returns the header bounds in the coordinates of |header_view_|. The header
173 // is assumed to be positioned at the top left corner of |header_view_| and to
174 // have the same width as |header_view_|.
175 gfx::Rect
GetHeaderLocalBounds() const;
177 // Returns the offset between window left edge and title string.
178 int GetTitleOffsetX() const;
180 // Returns the vertical center of the caption button container in window
182 int GetCaptionButtonContainerCenterY() const;
184 // Returns the opacity value used to paint the header.
185 // |theme_frame_overlay_id| is 0 if no overlay image is used.
186 int GetHeaderOpacity(HeaderMode header_mode
,
188 int theme_frame_overlay_id
) const;
190 // Returns the radius of the header's top corners.
191 int GetHeaderCornerRadius() const;
193 // Returns true if |window_->GetRootWindow()| should be drawing transparent
195 bool UseSoloWindowHeader() const;
197 // Returns true if |root_window| has exactly one visible, normal-type window.
198 // It ignores |ignore_window| while calculating the number of windows.
199 // Pass NULL for |ignore_window| to consider all windows.
200 static bool UseSoloWindowHeaderInRoot(aura::Window
* root_window
,
201 aura::Window
* ignore_window
);
203 // Updates the solo-window transparent header appearance for all windows in
204 // |root_window|. If |ignore_window| is not NULL it is ignored for when
205 // counting visible windows. This is useful for updates when a window is about
206 // to be closed or is moving to another root. If the solo window status
207 // changes it schedules paints as necessary.
208 static void UpdateSoloWindowInRoot(aura::Window
* root_window
,
209 aura::Window
* ignore_window
);
211 // Schedules a paint for the header. Used when transitioning from no header to
212 // a header (or other way around).
213 void SchedulePaintForHeader();
215 // Get the bounds for the title. The provided |title_font| is used to
216 // determine the correct dimensions.
217 gfx::Rect
GetTitleBounds(const gfx::Font
& title_font
);
220 views::Widget
* frame_
;
221 views::View
* header_view_
;
222 views::View
* window_icon_
; // May be NULL.
223 FrameCaptionButtonContainerView
* caption_button_container_
;
224 aura::Window
* window_
;
226 // The height of the header.
229 // Window frame header/caption parts.
230 const gfx::ImageSkia
* top_left_corner_
;
231 const gfx::ImageSkia
* top_edge_
;
232 const gfx::ImageSkia
* top_right_corner_
;
233 const gfx::ImageSkia
* header_left_edge_
;
234 const gfx::ImageSkia
* header_right_edge_
;
236 // Image ids and opacity last used for painting header.
237 int previous_theme_frame_id_
;
238 int previous_theme_frame_overlay_id_
;
239 int previous_opacity_
;
241 // Image ids and opacity we are crossfading from.
242 int crossfade_theme_frame_id_
;
243 int crossfade_theme_frame_overlay_id_
;
244 int crossfade_opacity_
;
246 scoped_ptr
<gfx::SlideAnimation
> crossfade_animation_
;
248 DISALLOW_COPY_AND_ASSIGN(HeaderPainter
);
253 #endif // ASH_WM_HEADER_PAINTER_H_