blob: 49b33984a2b7f6fd7ce24948904b57a84aa5c194 [file] [log] [blame]
// Copyright (c) 2012 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.
#ifndef ASH_WM_FRAME_PAINTER_H_
#define ASH_WM_FRAME_PAINTER_H_
#include "ash/ash_export.h"
#include "ash/wm/window_state_observer.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h" // OVERRIDE
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/rect.h"
namespace aura {
class RootWindow;
class Window;
}
namespace gfx {
class Canvas;
class Font;
class ImageSkia;
class Point;
class Size;
class SlideAnimation;
}
namespace views {
class NonClientFrameView;
class View;
class Widget;
}
namespace ash {
class FrameCaptionButtonContainerView;
// Helper class for painting window frames. Exists to share code between
// various implementations of views::NonClientFrameView. Canonical source of
// layout constants for Ash window frames.
class ASH_EXPORT FramePainter : public aura::WindowObserver,
public gfx::AnimationDelegate,
public wm::WindowStateObserver {
public:
// Opacity values for the window header in various states, from 0 to 255.
static int kActiveWindowOpacity;
static int kInactiveWindowOpacity;
static int kSoloWindowOpacity;
enum HeaderMode {
ACTIVE,
INACTIVE
};
enum Themed {
THEMED_YES,
THEMED_NO
};
// What happens when the |size_button_| is pressed.
enum SizeButtonBehavior {
SIZE_BUTTON_MINIMIZES,
SIZE_BUTTON_MAXIMIZES
};
FramePainter();
virtual ~FramePainter();
// |frame| and buttons are used for layout and are not owned.
void Init(views::Widget* frame,
views::View* window_icon,
FrameCaptionButtonContainerView* caption_button_container);
// Enable/Disable the solo-window transparent header appearance feature.
static void SetSoloWindowHeadersEnabled(bool enabled);
// Updates the solo-window transparent header appearance for all windows
// using frame painters in |root_window|.
static void UpdateSoloWindowHeader(aura::RootWindow* root_window);
// Helpers for views::NonClientFrameView implementations.
gfx::Rect GetBoundsForClientView(int top_height,
const gfx::Rect& window_bounds) const;
gfx::Rect GetWindowBoundsForClientBounds(
int top_height,
const gfx::Rect& client_bounds) const;
int NonClientHitTest(views::NonClientFrameView* view,
const gfx::Point& point);
gfx::Size GetMinimumSize(views::NonClientFrameView* view);
gfx::Size GetMaximumSize(views::NonClientFrameView* view);
// Returns the inset from the right edge.
int GetRightInset() const;
// Returns the amount that the theme background should be inset.
int GetThemeBackgroundXInset() const;
// Returns true if the header should be painted using a minimalistic style.
bool ShouldUseMinimalHeaderStyle(Themed header_themed) const;
// Paints the frame header.
// |theme_frame_overlay_id| is 0 if no overlay image should be used.
void PaintHeader(views::NonClientFrameView* view,
gfx::Canvas* canvas,
HeaderMode header_mode,
int theme_frame_id,
int theme_frame_overlay_id);
// Paints the header/content separator line. Exists as a separate function
// because some windows with complex headers (e.g. browsers with tab strips)
// need to draw their own line.
void PaintHeaderContentSeparator(views::NonClientFrameView* view,
gfx::Canvas* canvas);
// Returns size of the header/content separator line in pixels.
int HeaderContentSeparatorSize() const;
// Paint the title bar, primarily the title string.
void PaintTitleBar(views::NonClientFrameView* view,
gfx::Canvas* canvas,
const gfx::Font& title_font);
// Performs layout for the header based on whether we want the shorter
// appearance. |shorter_layout| is typically used for maximized windows, but
// not always.
void LayoutHeader(views::NonClientFrameView* view, bool shorter_layout);
// Schedule a re-paint of the entire title.
void SchedulePaintForTitle(const gfx::Font& title_font);
// Called when the browser theme changes.
void OnThemeChanged();
// aura::WindowObserver overrides:
virtual void OnWindowVisibilityChanged(aura::Window* window,
bool visible) OVERRIDE;
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE;
virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE;
virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE;
// ash::WindowStateObserver overrides:
virtual void OnTrackedByWorkspaceChanged(wm::WindowState* window_state,
bool old) OVERRIDE;
virtual void OnWindowShowTypeChanged(wm::WindowState* window_state,
wm::WindowShowType old_type) OVERRIDE;
// Overridden from gfx::AnimationDelegate
virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
private:
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, CreateAndDeleteSingleWindow);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeader);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderWithApp);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderWithPanel);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderModal);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderConstrained);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderNotDrawn);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, UseSoloWindowHeaderMultiDisplay);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, GetHeaderOpacity);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, TitleIconAlignment);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest, ChildWindowVisibility);
FRIEND_TEST_ALL_PREFIXES(FramePainterTest,
NoCrashShutdownWithAlwaysOnTopWindow);
// Returns the offset between window left edge and title string.
int GetTitleOffsetX() const;
// Returns the vertical center of the caption button container in window
// coordinates.
int GetCaptionButtonContainerCenterY() const;
// Returns the opacity value used to paint the header.
// |theme_frame_overlay_id| is 0 if no overlay image is used.
int GetHeaderOpacity(HeaderMode header_mode,
int theme_frame_id,
int theme_frame_overlay_id) const;
// Returns the radius of the header's top corners.
int GetHeaderCornerRadius() const;
// Returns true if |window_->GetRootWindow()| should be drawing transparent
// window headers.
bool UseSoloWindowHeader() const;
// Returns true if |root_window| has exactly one visible, normal-type window.
// It ignores |ignore_window| while calculating the number of windows.
// Pass NULL for |ignore_window| to consider all windows.
static bool UseSoloWindowHeaderInRoot(aura::RootWindow* root_window,
aura::Window* ignore_window);
// Updates the solo-window transparent header appearance for all windows in
// |root_window|. If |ignore_window| is not NULL it is ignored for when
// counting visible windows. This is useful for updates when a window is about
// to be closed or is moving to another root. If the solo window status
// changes it schedules paints as necessary.
static void UpdateSoloWindowInRoot(aura::RootWindow* root_window,
aura::Window* ignore_window);
// Updates the size of the region inside of |window_| in which the resize
// handles are shown based on |window_|'s show type.
void UpdateHitTestBoundsOverrideInner();
// Schedules a paint for the header. Used when transitioning from no header to
// a header (or other way around).
void SchedulePaintForHeader();
// Get the bounds for the title. The provided |title_font| is used to
// determine the correct dimensions.
gfx::Rect GetTitleBounds(const gfx::Font& title_font);
// Not owned
views::Widget* frame_;
views::View* window_icon_; // May be NULL.
FrameCaptionButtonContainerView* caption_button_container_;
aura::Window* window_;
// Window frame header/caption parts.
const gfx::ImageSkia* top_left_corner_;
const gfx::ImageSkia* top_edge_;
const gfx::ImageSkia* top_right_corner_;
const gfx::ImageSkia* header_left_edge_;
const gfx::ImageSkia* header_right_edge_;
// Image ids and opacity last used for painting header.
int previous_theme_frame_id_;
int previous_theme_frame_overlay_id_;
int previous_opacity_;
// Image ids and opacity we are crossfading from.
int crossfade_theme_frame_id_;
int crossfade_theme_frame_overlay_id_;
int crossfade_opacity_;
gfx::Rect header_frame_bounds_;
scoped_ptr<gfx::SlideAnimation> crossfade_animation_;
DISALLOW_COPY_AND_ASSIGN(FramePainter);
};
} // namespace ash
#endif // ASH_WM_FRAME_PAINTER_H_