Commit b7046495 authored by andresantoso's avatar andresantoso Committed by Commit bot

MacViews: Implement non-client frame view

Create Mac specific BrowserNonClientFrameViewMac, stop sharing
OpaqueBrowserFrameView.
Draw the frame using Mac colors, assets, and spacing.

Screenshot: https://code.google.com/p/chromium/issues/detail?id=425229#c40

BUG=425229

Review URL: https://codereview.chromium.org/1019023002

Cr-Commit-Position: refs/heads/master@{#321290}
parent 0e10bbd9
......@@ -23,6 +23,9 @@ namespace {
// Used for theme fallback colors.
const SkColor kDefaultColorFrame = SkColorSetRGB(109, 109, 109);
const SkColor kDefaultColorFrameInactive = SkColorSetRGB(176, 176, 176);
#elif defined(OS_MACOSX)
const SkColor kDefaultColorFrame = SkColorSetRGB(224, 224, 224);
const SkColor kDefaultColorFrameInactive = SkColorSetRGB(246, 246, 246);
#else
const SkColor kDefaultColorFrame = SkColorSetRGB(66, 116, 201);
const SkColor kDefaultColorFrameInactive = SkColorSetRGB(161, 182, 228);
......
......@@ -11,17 +11,21 @@
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/taskbar_decorator.h"
#include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
#include "chrome/browser/ui/views/profiles/new_avatar_button.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/browser/ui/views/theme_image_mapper.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/image/image.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/background.h"
#if defined(ENABLE_SUPERVISED_USERS)
......@@ -96,6 +100,79 @@ void BrowserNonClientFrameView::OnThemeChanged() {
}
#endif
bool BrowserNonClientFrameView::ShouldPaintAsThemed() const {
return browser_view_->IsBrowserTypeNormal();
}
SkColor BrowserNonClientFrameView::GetFrameColor() const {
const bool incognito = browser_view_->IsOffTheRecord();
ThemeProperties::OverwritableByUserThemeProperty color_id;
if (ShouldPaintAsActive()) {
color_id = incognito ? ThemeProperties::COLOR_FRAME_INCOGNITO
: ThemeProperties::COLOR_FRAME;
} else {
color_id = incognito ? ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE
: ThemeProperties::COLOR_FRAME_INACTIVE;
}
return ShouldPaintAsThemed() ? GetThemeProvider()->GetColor(color_id)
: ThemeProperties::GetDefaultColor(color_id);
}
gfx::ImageSkia* BrowserNonClientFrameView::GetFrameImage() const {
const bool incognito = browser_view_->IsOffTheRecord();
int resource_id;
if (browser_view_->IsBrowserTypeNormal()) {
if (ShouldPaintAsActive()) {
resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
} else {
resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE
: IDR_THEME_FRAME_INACTIVE;
}
return GetThemeProvider()->GetImageSkiaNamed(resource_id);
}
if (ShouldPaintAsActive()) {
resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_FRAME;
} else {
resource_id = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE
: IDR_THEME_FRAME_INACTIVE;
}
if (ShouldPaintAsThemed()) {
// On Linux, we want to use theme images provided by the system theme when
// enabled, even if we are an app or popup window.
return GetThemeProvider()->GetImageSkiaNamed(resource_id);
}
// Otherwise, never theme app and popup windows.
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
return rb.GetImageSkiaNamed(
chrome::MapThemeImage(chrome::GetHostDesktopTypeForNativeWindow(
browser_view_->GetNativeWindow()),
resource_id));
}
gfx::ImageSkia* BrowserNonClientFrameView::GetFrameOverlayImage() const {
ui::ThemeProvider* tp = GetThemeProvider();
if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
browser_view_->IsBrowserTypeNormal() &&
!browser_view_->IsOffTheRecord()) {
return tp->GetImageSkiaNamed(ShouldPaintAsActive() ?
IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE);
}
return nullptr;
}
int BrowserNonClientFrameView::GetTopAreaHeight() const {
gfx::ImageSkia* frame_image = GetFrameImage();
int top_area_height = frame_image->height();
if (browser_view_->IsTabStripVisible()) {
top_area_height = std::max(top_area_height,
GetBoundsForTabStrip(browser_view_->tabstrip()).bottom());
}
return top_area_height;
}
void BrowserNonClientFrameView::UpdateAvatar() {
if (browser_view()->IsRegularOrGuestSession() && switches::IsNewAvatarMenu())
UpdateNewStyleAvatar();
......
......@@ -67,6 +67,17 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
BrowserView* browser_view() const { return browser_view_; }
BrowserFrame* frame() const { return frame_; }
// Whether the frame should be painted with theming.
// By default, tabbed browser windows are themed but popup and app windows are
// not.
virtual bool ShouldPaintAsThemed() const;
// Compute aspects of the frame needed to paint the frame background.
SkColor GetFrameColor() const;
gfx::ImageSkia* GetFrameImage() const;
gfx::ImageSkia* GetFrameOverlayImage() const;
int GetTopAreaHeight() const;
// Updates the avatar button using the old or new UI based on the BrowserView
// type, and the presence of the --enable-new-avatar-menu flag. Calls either
// UpdateAvatarInfo() or UpdateNewStyleAvatar() accordingly.
......
......@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h"
#include "chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h"
namespace chrome {
BrowserNonClientFrameView* CreateBrowserNonClientFrameView(
BrowserFrame* frame, BrowserView* browser_view) {
return new OpaqueBrowserFrameView(frame, browser_view);
return new BrowserNonClientFrameViewMac(frame, browser_view);
}
} // namespace chrome
// Copyright 2015 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 CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_NON_CLIENT_FRAME_VIEW_MAC_H_
#define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_NON_CLIENT_FRAME_VIEW_MAC_H_
#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
class BrowserNonClientFrameViewMac : public BrowserNonClientFrameView {
public:
// Mac implementation of BrowserNonClientFrameView.
BrowserNonClientFrameViewMac(BrowserFrame* frame, BrowserView* browser_view);
~BrowserNonClientFrameViewMac() override;
// BrowserNonClientFrameView:
gfx::Rect GetBoundsForTabStrip(views::View* tabstrip) const override;
int GetTopInset() const override;
int GetThemeBackgroundXInset() const override;
void UpdateThrobber(bool running) override;
// views::NonClientFrameView:
gfx::Rect GetBoundsForClientView() const override;
gfx::Rect GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const override;
int NonClientHitTest(const gfx::Point& point) override;
void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override;
void ResetWindowControls() override;
void UpdateWindowIcon() override;
void UpdateWindowTitle() override;
void SizeConstraintsChanged() override;
// views::View:
gfx::Size GetMinimumSize() const override;
protected:
// views::View:
void OnPaint(gfx::Canvas* canvas) override;
// BrowserNonClientFrameView:
void UpdateNewStyleAvatar() override;
private:
void PaintThemedFrame(gfx::Canvas* canvas);
void PaintToolbarBackground(gfx::Canvas* canvas);
DISALLOW_COPY_AND_ASSIGN(BrowserNonClientFrameViewMac);
};
#endif // CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_NON_CLIENT_FRAME_VIEW_MAC_H_
// Copyright 2015 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 "chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/views/frame/browser_frame.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/browser_view_layout.h"
#include "grit/theme_resources.h"
#include "ui/base/hit_test.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/canvas.h"
namespace {
// How far to inset the tabstrip from the sides of the window.
const int kTabstripTopInset = 8;
const int kTabstripLeftInset = 70; // Make room for window control buttons.
const int kTabstripRightInset = 0;
} // namespace
///////////////////////////////////////////////////////////////////////////////
// BrowserNonClientFrameViewMac, public:
BrowserNonClientFrameViewMac::BrowserNonClientFrameViewMac(
BrowserFrame* frame, BrowserView* browser_view)
: BrowserNonClientFrameView(frame, browser_view) {
}
BrowserNonClientFrameViewMac::~BrowserNonClientFrameViewMac() {
}
///////////////////////////////////////////////////////////////////////////////
// BrowserNonClientFrameViewMac, BrowserNonClientFrameView implementation:
gfx::Rect BrowserNonClientFrameViewMac::GetBoundsForTabStrip(
views::View* tabstrip) const {
DCHECK(tabstrip);
gfx::Rect bounds = gfx::Rect(0, kTabstripTopInset,
width(), tabstrip->GetPreferredSize().height());
bounds.Inset(kTabstripLeftInset, 0, kTabstripRightInset, 0);
return bounds;
}
int BrowserNonClientFrameViewMac::GetTopInset() const {
return browser_view()->IsTabStripVisible() ? kTabstripTopInset : 0;
}
int BrowserNonClientFrameViewMac::GetThemeBackgroundXInset() const {
return 0;
}
void BrowserNonClientFrameViewMac::UpdateThrobber(bool running) {
}
///////////////////////////////////////////////////////////////////////////////
// BrowserNonClientFrameViewMac, views::NonClientFrameView implementation:
gfx::Rect BrowserNonClientFrameViewMac::GetBoundsForClientView() const {
return bounds();
}
gfx::Rect BrowserNonClientFrameViewMac::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const {
return client_bounds;
}
int BrowserNonClientFrameViewMac::NonClientHitTest(const gfx::Point& point) {
return frame()->client_view()->NonClientHitTest(point);
}
void BrowserNonClientFrameViewMac::GetWindowMask(const gfx::Size& size,
gfx::Path* window_mask) {
}
void BrowserNonClientFrameViewMac::ResetWindowControls() {
}
void BrowserNonClientFrameViewMac::UpdateWindowIcon() {
}
void BrowserNonClientFrameViewMac::UpdateWindowTitle() {
}
void BrowserNonClientFrameViewMac::SizeConstraintsChanged() {
}
///////////////////////////////////////////////////////////////////////////////
// BrowserNonClientFrameViewMac, views::View implementation:
gfx::Size BrowserNonClientFrameViewMac::GetMinimumSize() const {
return browser_view()->GetMinimumSize();
}
///////////////////////////////////////////////////////////////////////////////
// BrowserNonClientFrameViewMac, protected:
// views::View:
void BrowserNonClientFrameViewMac::OnPaint(gfx::Canvas* canvas) {
if (!browser_view()->IsBrowserTypeNormal())
return;
canvas->DrawColor(GetFrameColor());
if (!GetThemeProvider()->UsingSystemTheme())
PaintThemedFrame(canvas);
if (browser_view()->IsToolbarVisible())
PaintToolbarBackground(canvas);
}
// BrowserNonClientFrameView:
void BrowserNonClientFrameViewMac::UpdateNewStyleAvatar() {
NOTIMPLEMENTED();
}
///////////////////////////////////////////////////////////////////////////////
// BrowserNonClientFrameViewMac, private:
void BrowserNonClientFrameViewMac::PaintThemedFrame(gfx::Canvas* canvas) {
gfx::ImageSkia* image = GetFrameImage();
if (image)
canvas->TileImageInt(*image, 0, 0, width(), image->height());
gfx::ImageSkia* overlay = GetFrameOverlayImage();
if (overlay)
canvas->TileImageInt(*overlay, 0, 0, width(), overlay->height());
}
void BrowserNonClientFrameViewMac::PaintToolbarBackground(gfx::Canvas* canvas) {
gfx::Rect bounds(browser_view()->GetToolbarBounds());
if (bounds.IsEmpty())
return;
ui::ThemeProvider* tp = GetThemeProvider();
gfx::ImageSkia* border = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_TOP);
const int top_inset =
BrowserViewLayout::kToolbarTabStripVerticalOverlap - border->height();
const int x = bounds.x();
const int y = bounds.y() + top_inset;
const int w = bounds.width();
const int h = bounds.height() - top_inset;
// The tabstrip border image height is 2*scale pixels, but only the bottom 2
// pixels contain the actual border (the rest is transparent). We can't draw
// the toolbar image below this transparent upper area when scale > 1.
const int fill_y = y + canvas->image_scale() - 1;
const int fill_height = bounds.bottom() - fill_y;
// Draw the toolbar fill.
canvas->TileImageInt(*tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR),
x + GetThemeBackgroundXInset(), fill_y - GetTopInset(),
x, fill_y, w, fill_height);
// Draw the tabstrip/toolbar separator.
canvas->TileImageInt(*border, 0, 0, x, y, w, border->height());
// Draw the content/toolbar separator.
canvas->FillRect(
gfx::Rect(x, y + h - kClientEdgeThickness, w, kClientEdgeThickness),
ThemeProperties::GetDefaultColor(
ThemeProperties::COLOR_TOOLBAR_SEPARATOR));
}
......@@ -22,7 +22,6 @@
#include "chrome/browser/ui/views/profiles/new_avatar_button.h"
#include "chrome/browser/ui/views/tab_icon_view.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/browser/ui/views/theme_image_mapper.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/grit/generated_resources.h"
#include "components/signin/core/common/profile_management_switches.h"
......@@ -480,6 +479,12 @@ void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
}
// BrowserNonClientFrameView:
bool OpaqueBrowserFrameView::ShouldPaintAsThemed() const {
// Theme app and popup windows if |platform_observer_| wants it.
return browser_view()->IsBrowserTypeNormal() ||
platform_observer_->IsUsingSystemTheme();
}
void OpaqueBrowserFrameView::UpdateNewStyleAvatar() {
UpdateNewStyleAvatarInfo(this, NewAvatarButton::THEMED_BUTTON);
}
......@@ -838,82 +843,3 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
client_area_bottom + kClientEdgeThickness - client_area_top),
toolbar_color);
}
SkColor OpaqueBrowserFrameView::GetFrameColor() const {
bool is_incognito = browser_view()->IsOffTheRecord();
ThemeProperties::OverwritableByUserThemeProperty color_id;
if (ShouldPaintAsActive()) {
color_id = is_incognito ?
ThemeProperties::COLOR_FRAME_INCOGNITO :
ThemeProperties::COLOR_FRAME;
} else {
color_id = is_incognito ?
ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE :
ThemeProperties::COLOR_FRAME_INACTIVE;
}
if (browser_view()->IsBrowserTypeNormal() ||
platform_observer_->IsUsingSystemTheme()) {
return GetThemeProvider()->GetColor(color_id);
}
// Never theme app and popup windows unless the |platform_observer_|
// requested an override.
return ThemeProperties::GetDefaultColor(color_id);
}
gfx::ImageSkia* OpaqueBrowserFrameView::GetFrameImage() const {
bool is_incognito = browser_view()->IsOffTheRecord();
int resource_id;
if (browser_view()->IsBrowserTypeNormal()) {
if (ShouldPaintAsActive()) {
resource_id = is_incognito ?
IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
} else {
resource_id = is_incognito ?
IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE;
}
return GetThemeProvider()->GetImageSkiaNamed(resource_id);
}
if (ShouldPaintAsActive()) {
resource_id = is_incognito ?
IDR_THEME_FRAME_INCOGNITO : IDR_FRAME;
} else {
resource_id = is_incognito ?
IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE;
}
if (platform_observer_->IsUsingSystemTheme()) {
// We want to use theme images provided by the system theme when enabled,
// even if we are an app or popup window.
return GetThemeProvider()->GetImageSkiaNamed(resource_id);
}
// Otherwise, never theme app and popup windows.
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
return rb.GetImageSkiaNamed(chrome::MapThemeImage(
chrome::GetHostDesktopTypeForNativeWindow(
browser_view()->GetNativeWindow()),
resource_id));
}
gfx::ImageSkia* OpaqueBrowserFrameView::GetFrameOverlayImage() const {
ui::ThemeProvider* tp = GetThemeProvider();
if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
browser_view()->IsBrowserTypeNormal() &&
!browser_view()->IsOffTheRecord()) {
return tp->GetImageSkiaNamed(ShouldPaintAsActive() ?
IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE);
}
return nullptr;
}
int OpaqueBrowserFrameView::GetTopAreaHeight() const {
gfx::ImageSkia* frame_image = GetFrameImage();
int top_area_height = frame_image->height();
if (browser_view()->IsTabStripVisible()) {
top_area_height = std::max(top_area_height,
GetBoundsForTabStrip(browser_view()->tabstrip()).bottom());
}
return top_area_height;
}
......@@ -97,6 +97,7 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
void OnPaint(gfx::Canvas* canvas) override;
// BrowserNonClientFrameView:
bool ShouldPaintAsThemed() const override;
void UpdateNewStyleAvatar() override;
private:
......@@ -144,12 +145,6 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
void PaintToolbarBackground(gfx::Canvas* canvas);
void PaintRestoredClientEdge(gfx::Canvas* canvas);
// Compute aspects of the frame needed to paint the frame background.
SkColor GetFrameColor() const;
gfx::ImageSkia* GetFrameImage() const;
gfx::ImageSkia* GetFrameOverlayImage() const;
int GetTopAreaHeight() const;
// Returns the bounds of the client area for the specified view size.
gfx::Rect CalculateClientAreaBounds(int width, int height) const;
......
......@@ -114,7 +114,11 @@ const int kTouchResizeLayoutTimeMS = 2000;
// Amount the left edge of a tab is offset from the rectangle of the tab's
// favicon/title/close box. Related to the width of IDR_TAB_ACTIVE_LEFT.
// Affects the size of the "V" between adjacent tabs.
#if defined(OS_MACOSX)
const int kTabHorizontalOffset = -19;
#else
const int kTabHorizontalOffset = -26;
#endif
// Amount to adjust the clip by when the tab is stacked before the active index.
const int kStackedTabLeftClip = 20;
......@@ -521,11 +525,16 @@ void TabStrip::RemoveTabDelegate::AnimationCanceled(
// static
const char TabStrip::kViewClassName[] = "TabStrip";
const int TabStrip::kNewTabButtonHorizontalOffset = -11;
const int TabStrip::kNewTabButtonVerticalOffset = 7;
const int TabStrip::kMiniToNonMiniGap = 3;
const int TabStrip::kNewTabButtonAssetWidth = 34;
const int TabStrip::kNewTabButtonAssetHeight = 18;
#if defined(OS_MACOSX)
const int TabStrip::kNewTabButtonHorizontalOffset = -8;
const int TabStrip::kMiniToNonMiniGap = 2;
#else
const int TabStrip::kNewTabButtonHorizontalOffset = -11;
const int TabStrip::kMiniToNonMiniGap = 3;
#endif
TabStrip::TabStrip(TabStripController* controller)
: controller_(controller),
......
......@@ -2074,6 +2074,8 @@
'browser/ui/views/frame/browser_non_client_frame_view.h',
'browser/ui/views/frame/browser_non_client_frame_view_factory_aura.cc',
'browser/ui/views/frame/browser_non_client_frame_view_factory_mac.mm',
'browser/ui/views/frame/browser_non_client_frame_view_mac.h',
'browser/ui/views/frame/browser_non_client_frame_view_mac.mm',
'browser/ui/views/frame/browser_root_view.cc',
'browser/ui/views/frame/browser_root_view.h',
'browser/ui/views/frame/browser_shutdown.cc',
......
......@@ -123,9 +123,9 @@ bool NativeWidgetMac::ShouldUseNativeFrame() const {
}
bool NativeWidgetMac::ShouldWindowContentsBeTransparent() const {
// On Windows, this returns false when DWM is unavailable (e.g. XP, RDP or
// classic mode). OSX always has a compositing window manager.
return true;
// On Windows, this returns true when Aero is enabled which draws the titlebar
// with translucency.
return false;
}
void NativeWidgetMac::FrameTypeChanged() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment