summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-04 18:02:58 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-04 18:02:58 +0000
commit75f02038e43469d00b94c496da89557a660f5116 (patch)
tree4541c77f6656bf862625ddec95bad25432f52a96 /chrome/browser/views
parent8b034b702cd11acb174a1ece9ab837afbda86b77 (diff)
downloadchromium_src-75f02038e43469d00b94c496da89557a660f5116.zip
chromium_src-75f02038e43469d00b94c496da89557a660f5116.tar.gz
chromium_src-75f02038e43469d00b94c496da89557a660f5116.tar.bz2
Fixes layout of side tabs on windows.
BUG=none TEST=none Review URL: http://codereview.chromium.org/2608002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48949 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views')
-rw-r--r--chrome/browser/views/frame/app_panel_browser_frame_view.cc4
-rw-r--r--chrome/browser/views/frame/app_panel_browser_frame_view.h1
-rw-r--r--chrome/browser/views/frame/browser_frame.h5
-rw-r--r--chrome/browser/views/frame/browser_frame_gtk.cc4
-rw-r--r--chrome/browser/views/frame/browser_frame_gtk.h1
-rw-r--r--chrome/browser/views/frame/browser_frame_win.cc27
-rw-r--r--chrome/browser/views/frame/browser_frame_win.h4
-rw-r--r--chrome/browser/views/frame/browser_non_client_frame_view.h5
-rw-r--r--chrome/browser/views/frame/browser_view.cc9
-rw-r--r--chrome/browser/views/frame/browser_view.h4
-rw-r--r--chrome/browser/views/frame/browser_view_layout.cc5
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.cc234
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.h1
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.cc167
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.h6
15 files changed, 269 insertions, 208 deletions
diff --git a/chrome/browser/views/frame/app_panel_browser_frame_view.cc b/chrome/browser/views/frame/app_panel_browser_frame_view.cc
index 1437c50..16ebec3 100644
--- a/chrome/browser/views/frame/app_panel_browser_frame_view.cc
+++ b/chrome/browser/views/frame/app_panel_browser_frame_view.cc
@@ -109,10 +109,6 @@ gfx::Size AppPanelBrowserFrameView::GetMinimumSize() {
return min_size;
}
-void AppPanelBrowserFrameView::PaintTabStripShadow(gfx::Canvas* canvas) {
- // NOP, no tabstrip.
-}
-
///////////////////////////////////////////////////////////////////////////////
// AppPanelBrowserFrameView, views::NonClientFrameView implementation:
diff --git a/chrome/browser/views/frame/app_panel_browser_frame_view.h b/chrome/browser/views/frame/app_panel_browser_frame_view.h
index 4982f0c..0f8bd3a 100644
--- a/chrome/browser/views/frame/app_panel_browser_frame_view.h
+++ b/chrome/browser/views/frame/app_panel_browser_frame_view.h
@@ -36,7 +36,6 @@ class AppPanelBrowserFrameView : public BrowserNonClientFrameView,
virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const;
virtual void UpdateThrobber(bool running);
virtual gfx::Size GetMinimumSize();
- virtual void PaintTabStripShadow(gfx::Canvas* canvas);
protected:
// Overridden from views::NonClientFrameView:
diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h
index 392200d..31b489f 100644
--- a/chrome/browser/views/frame/browser_frame.h
+++ b/chrome/browser/views/frame/browser_frame.h
@@ -66,11 +66,6 @@ class BrowserFrame {
// Returns the NonClientFrameView of this frame.
virtual views::View* GetFrameView() const = 0;
- // Paints the shadow edge along the side of the side tabstrip. The BrowserView
- // calls this method _after_ the TabStrip has painted itself so the shadow is
- // rendered above the tabs.
- virtual void PaintTabStripShadow(gfx::Canvas* canvas) = 0;
-
// Notifies the frame that the tab strip display mode changed so it can update
// its frame treatment if necessary.
virtual void TabStripDisplayModeChanged() = 0;
diff --git a/chrome/browser/views/frame/browser_frame_gtk.cc b/chrome/browser/views/frame/browser_frame_gtk.cc
index cb67b3b..74a6cf9 100644
--- a/chrome/browser/views/frame/browser_frame_gtk.cc
+++ b/chrome/browser/views/frame/browser_frame_gtk.cc
@@ -50,7 +50,6 @@ class PopupNonClientFrameView : public BrowserNonClientFrameView {
return gfx::Rect(0, 0, width(), tabstrip->GetPreferredHeight());
}
virtual void UpdateThrobber(bool running) {}
- virtual void PaintTabStripShadow(gfx::Canvas* canvas) {}
private:
DISALLOW_COPY_AND_ASSIGN(PopupNonClientFrameView);
@@ -133,9 +132,6 @@ views::View* BrowserFrameGtk::GetFrameView() const {
return browser_frame_view_;
}
-void BrowserFrameGtk::PaintTabStripShadow(gfx::Canvas* canvas) {
-}
-
void BrowserFrameGtk::TabStripDisplayModeChanged() {
GetRootView()->Layout();
}
diff --git a/chrome/browser/views/frame/browser_frame_gtk.h b/chrome/browser/views/frame/browser_frame_gtk.h
index f8e8f2a..10904dd 100644
--- a/chrome/browser/views/frame/browser_frame_gtk.h
+++ b/chrome/browser/views/frame/browser_frame_gtk.h
@@ -35,7 +35,6 @@ class BrowserFrameGtk : public BrowserFrame,
virtual ThemeProvider* GetThemeProviderForFrame() const;
virtual bool AlwaysUseNativeFrame() const;
virtual views::View* GetFrameView() const;
- virtual void PaintTabStripShadow(gfx::Canvas* canvas);
virtual void TabStripDisplayModeChanged();
// Overridden from views::Widget:
diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc
index e0b420e..7ddd92f 100644
--- a/chrome/browser/views/frame/browser_frame_win.cc
+++ b/chrome/browser/views/frame/browser_frame_win.cc
@@ -12,6 +12,7 @@
#include "app/resource_bundle.h"
#include "app/theme_provider.h"
#include "app/win_util.h"
+#include "base/win_util.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_theme_provider.h"
@@ -68,6 +69,15 @@ void BrowserFrameWin::Init() {
BrowserFrameWin::~BrowserFrameWin() {
}
+int BrowserFrameWin::GetTitleBarHeight() {
+ RECT caption = { 0 };
+ if (DwmGetWindowAttribute(GetNativeView(), DWMWA_CAPTION_BUTTON_BOUNDS,
+ &caption, sizeof(RECT)) == S_OK) {
+ return caption.bottom;
+ }
+ return GetSystemMetrics(SM_CYCAPTION);
+}
+
views::Window* BrowserFrameWin::GetWindow() {
return this;
}
@@ -126,10 +136,6 @@ views::View* BrowserFrameWin::GetFrameView() const {
return browser_frame_view_;
}
-void BrowserFrameWin::PaintTabStripShadow(gfx::Canvas* canvas) {
- browser_frame_view_->PaintTabStripShadow(canvas);
-}
-
void BrowserFrameWin::TabStripDisplayModeChanged() {
GetRootView()->Layout();
UpdateDWMFrame();
@@ -307,9 +313,7 @@ void BrowserFrameWin::UpdateDWMFrame() {
// borders.
if (!browser_view_->IsFullscreen()) {
if (browser_view_->UseVerticalTabs()) {
- margins.cxLeftWidth +=
- GetBoundsForTabStrip(browser_view_->tabstrip()).right();
- margins.cyTopHeight += GetSystemMetrics(SM_CYSIZEFRAME);
+ margins.cyTopHeight = GetTitleBarHeight();
} else {
margins.cyTopHeight =
GetBoundsForTabStrip(browser_view_->tabstrip()).bottom() +
@@ -320,13 +324,4 @@ void BrowserFrameWin::UpdateDWMFrame() {
// For popup and app windows we want to use the default margins.
}
DwmExtendFrameIntoClientArea(GetNativeView(), &margins);
-
- DWORD window_style = GetWindowLong(GWL_STYLE);
- if (browser_view_->UseVerticalTabs()) {
- if (window_style & WS_CAPTION)
- SetWindowLong(GWL_STYLE, window_style & ~WS_CAPTION);
- } else {
- if (!(window_style & WS_CAPTION))
- SetWindowLong(GWL_STYLE, window_style | WS_CAPTION);
- }
}
diff --git a/chrome/browser/views/frame/browser_frame_win.h b/chrome/browser/views/frame/browser_frame_win.h
index 42e8974..365497b 100644
--- a/chrome/browser/views/frame/browser_frame_win.h
+++ b/chrome/browser/views/frame/browser_frame_win.h
@@ -35,6 +35,9 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
BrowserView* browser_view() const { return browser_view_; }
+ // Returns the height of the title bar.
+ int GetTitleBarHeight();
+
// BrowserFrame implementation.
virtual views::Window* GetWindow();
virtual int GetMinimizeButtonOffset() const;
@@ -44,7 +47,6 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
virtual ThemeProvider* GetThemeProviderForFrame() const;
virtual bool AlwaysUseNativeFrame() const;
virtual views::View* GetFrameView() const;
- virtual void PaintTabStripShadow(gfx::Canvas* canvas);
virtual void TabStripDisplayModeChanged();
protected:
diff --git a/chrome/browser/views/frame/browser_non_client_frame_view.h b/chrome/browser/views/frame/browser_non_client_frame_view.h
index 63f4044..e891f0b 100644
--- a/chrome/browser/views/frame/browser_non_client_frame_view.h
+++ b/chrome/browser/views/frame/browser_non_client_frame_view.h
@@ -21,11 +21,6 @@ class BrowserNonClientFrameView : public views::NonClientFrameView {
// Updates the throbber.
virtual void UpdateThrobber(bool running) = 0;
-
- // Paints the shadow edge along the side of the side tabstrip. The BrowserView
- // calls this method _after_ the TabStrip has painted itself so the shadow is
- // rendered above the tabs.
- virtual void PaintTabStripShadow(gfx::Canvas* canvas) = 0;
};
#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_NON_CLIENT_FRAME_VIEW_H_
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 0e7a780..67f0eb0 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -546,8 +546,7 @@ int BrowserView::GetTabStripHeight() const {
// We want to return tabstrip_->height(), but we might be called in the midst
// of layout, when that hasn't yet been updated to reflect the current state.
// So return what the tabstrip height _ought_ to be right now.
- return IsTabStripVisible() ? tabstrip_->GetPreferredSize().height()
- : 0;
+ return IsTabStripVisible() ? tabstrip_->GetPreferredSize().height() : 0;
}
gfx::Rect BrowserView::GetTabStripBounds() const {
@@ -1617,11 +1616,6 @@ std::string BrowserView::GetClassName() const {
return kViewClassName;
}
-void BrowserView::PaintChildren(gfx::Canvas* canvas) {
- View::PaintChildren(canvas);
- frame_->PaintTabStripShadow(canvas);
-}
-
void BrowserView::Layout() {
if (ignore_layout_)
return;
@@ -1981,7 +1975,6 @@ bool BrowserView::UpdateChildViewAndLayout(views::View* new_view,
return changed;
}
-
void BrowserView::ProcessFullscreen(bool fullscreen) {
// Reduce jankiness during the following position changes by:
// * Hiding the window until it's in the final position
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 4ecba98..b017939 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -160,6 +160,9 @@ class BrowserView : public BrowserBubbleHost,
// Accessor for the TabStrip.
BaseTabStrip* tabstrip() const { return tabstrip_; }
+ // Accessor for the Toolbar.
+ ToolbarView* toolbar() const { return toolbar_; }
+
// Accessor for the ExtensionShelf.
ExtensionShelf* extension_shelf() const { return extension_shelf_; }
@@ -398,7 +401,6 @@ class BrowserView : public BrowserBubbleHost,
protected:
// Overridden from views::View:
virtual std::string GetClassName() const;
- virtual void PaintChildren(gfx::Canvas* canvas);
virtual void Layout();
virtual void ViewHierarchyChanged(bool is_add,
views::View* parent,
diff --git a/chrome/browser/views/frame/browser_view_layout.cc b/chrome/browser/views/frame/browser_view_layout.cc
index 91c0646..e26b669c 100644
--- a/chrome/browser/views/frame/browser_view_layout.cc
+++ b/chrome/browser/views/frame/browser_view_layout.cc
@@ -30,9 +30,6 @@ namespace {
const int kTabShadowSize = 2;
// The vertical overlap between the TabStrip and the Toolbar.
const int kToolbarTabStripVerticalOverlap = 3;
-// The horizontal overlap between the SideTabStrip the other contents of the
-// BrowserView.
-const int kBrowserViewTabStripHorizontalOverlap = 2;
// An offset distance between certain toolbars and the toolbar that preceded
// them in layout.
const int kSeparationLineHeight = 1;
@@ -320,7 +317,7 @@ int BrowserViewLayout::LayoutTabStrip() {
if (browser_view_->UseVerticalTabs()) {
vertical_layout_rect_.Inset(
- layout_bounds.right() - kBrowserViewTabStripHorizontalOverlap, 0, 0, 0);
+ layout_bounds.width(), 0, 0, 0);
} else {
gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds();
tabstrip_->SetBackgroundOffset(
diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc
index 2d48a06..953cfab 100644
--- a/chrome/browser/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/views/frame/glass_browser_frame_view.cc
@@ -25,6 +25,8 @@ HICON GlassBrowserFrameView::throbber_icons_[
namespace {
// There are 3 px of client edge drawn inside the outer frame borders.
const int kNonClientBorderThickness = 3;
+// Vertical tabs have 4 px border.
+const int kNonClientVerticalTabStripBorderThickness = 4;
// Besides the frame border, there's another 11 px of empty space atop the
// window in restored mode, to use to drag the window around.
const int kNonClientRestoredExtraThickness = 11;
@@ -114,27 +116,6 @@ void GlassBrowserFrameView::UpdateThrobber(bool running) {
}
}
-void GlassBrowserFrameView::PaintTabStripShadow(gfx::Canvas* canvas) {
- if (!base::i18n::IsRTL() || !browser_view_->UseVerticalTabs())
- return;
-
- ThemeProvider* tp = GetThemeProvider();
- SkBitmap* shadow_top = tp->GetBitmapNamed(IDR_SIDETABS_SHADOW_TOP);
- SkBitmap* shadow_middle = tp->GetBitmapNamed(IDR_SIDETABS_SHADOW_MIDDLE);
- SkBitmap* shadow_bottom = tp->GetBitmapNamed(IDR_SIDETABS_SHADOW_BOTTOM);
-
- gfx::Rect bounds = GetBoundsForTabStrip(browser_view_->tabstrip());
- canvas->DrawBitmapInt(*shadow_top, bounds.right() - 2 * shadow_top->width(),
- bounds.y());
- canvas->TileImageInt(
- *shadow_middle, bounds.right() - 2 * shadow_middle->width(),
- bounds.y() + shadow_top->height(), shadow_middle->width(),
- bounds.height() - shadow_top->height() - shadow_bottom->height());
- canvas->DrawBitmapInt(*shadow_bottom,
- bounds.right() - 2 * shadow_bottom->width(),
- bounds.bottom() - shadow_bottom->height());
-}
-
///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, views::NonClientFrameView implementation:
@@ -228,20 +209,24 @@ int GlassBrowserFrameView::FrameBorderThickness() const {
int GlassBrowserFrameView::NonClientBorderThickness() const {
views::Window* window = frame_->GetWindow();
- return (window->IsMaximized() || window->IsFullscreen()) ?
- 0 : kNonClientBorderThickness;
+ if (window->IsMaximized() || window->IsFullscreen())
+ return 0;
+
+ return browser_view_->UseVerticalTabs() ?
+ kNonClientVerticalTabStripBorderThickness :
+ kNonClientBorderThickness;
}
int GlassBrowserFrameView::NonClientTopBorderHeight() const {
if (frame_->GetWindow()->IsFullscreen())
return 0;
+ if (browser_view_->UseVerticalTabs())
+ return static_cast<BrowserFrameWin*>(frame_)->GetTitleBarHeight();
// We'd like to use FrameBorderThickness() here, but the maximized Aero glass
// frame has a 0 frame border around most edges and a CXSIZEFRAME-thick border
// at the top (see AeroGlassFrame::OnGetMinMaxInfo()).
- const int kRestoredHeight = browser_view_->UseVerticalTabs() ?
- -2 : kNonClientRestoredExtraThickness;
return GetSystemMetrics(SM_CXSIZEFRAME) + (browser_view_->IsMaximized() ?
- -kTabstripTopShadowThickness : kRestoredHeight);
+ -kTabstripTopShadowThickness : kNonClientRestoredExtraThickness);
}
void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
@@ -254,61 +239,100 @@ void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
toolbar_bounds.set_origin(toolbar_origin);
SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR);
-
- // Draw the toolbar background, setting src_y of the paint to the tab
- // strip height as the toolbar background begins at the top of the tabs.
- int src_y = browser_view_->UseVerticalTabs()
- ? Tab::GetMinimumUnselectedSize().height()
- : browser_view_->GetTabStripHeight() - 1;
- canvas->TileImageInt(*theme_toolbar, 0, src_y,
- toolbar_bounds.x() - 1, toolbar_bounds.y() + 2,
- toolbar_bounds.width() + 2, theme_toolbar->height());
-
- // Draw rounded corners for the tab.
- SkBitmap* toolbar_left_mask =
- tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK);
- SkBitmap* toolbar_right_mask =
- tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK);
-
- // We mask out the corners by using the DestinationIn transfer mode,
- // which keeps the RGB pixels from the destination and the alpha from
- // the source.
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
-
- // Mask out the top left corner.
- int left_x = toolbar_bounds.x() - kContentEdgeShadowThickness -
- kClientEdgeThickness;
- canvas->DrawBitmapInt(*toolbar_left_mask,
- left_x, toolbar_bounds.y(), paint);
-
- // Mask out the top right corner.
- int right_x = toolbar_bounds.right() - toolbar_right_mask->width() +
- kContentEdgeShadowThickness + kClientEdgeThickness;
- canvas->DrawBitmapInt(*toolbar_right_mask,
- right_x, toolbar_bounds.y(),
- paint);
-
- // Draw left edge.
SkBitmap* toolbar_left = tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER);
- canvas->DrawBitmapInt(*toolbar_left, left_x, toolbar_bounds.y());
-
- // Draw center edge.
- SkBitmap* toolbar_center =
- tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER);
- canvas->TileImageInt(*toolbar_center, left_x + toolbar_left->width(),
- toolbar_bounds.y(),
- right_x - (left_x + toolbar_left->width()),
- toolbar_center->height());
+ SkBitmap* toolbar_center = tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER);
- // Right edge.
- canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER),
- right_x, toolbar_bounds.y());
+ if (browser_view_->UseVerticalTabs()) {
+ gfx::Rect tabstrip_bounds(browser_view_->tabstrip()->bounds());
+ gfx::Point tabstrip_origin(tabstrip_bounds.origin());
+ View::ConvertPointToView(frame_->GetWindow()->GetClientView(),
+ this, &tabstrip_origin);
+ tabstrip_bounds.set_origin(tabstrip_origin);
+
+ int x = tabstrip_bounds.x();
+ int y = tabstrip_bounds.y();
+ int w = toolbar_bounds.right() - x;
+
+ int src_y = Tab::GetMinimumUnselectedSize().height();
+ canvas->TileImageInt(*theme_toolbar, 0, src_y,
+ MirroredLeftPointForRect(toolbar_bounds), y,
+ toolbar_bounds.width(), theme_toolbar->height());
+
+ // Draw left edge. We explicitly set a clip as the image is bigger than just
+ // the corner.
+ canvas->save();
+ canvas->ClipRectInt(x - kNonClientBorderThickness,
+ y - kNonClientBorderThickness,
+ kNonClientBorderThickness,
+ kNonClientBorderThickness);
+ canvas->DrawBitmapInt(*toolbar_left, x - kNonClientBorderThickness,
+ y - kNonClientBorderThickness);
+ canvas->restore();
+
+ // Draw center edge. We need to draw a while line above the toolbar for the
+ // image to overlay nicely.
+ canvas->FillRectInt(SK_ColorWHITE, x, y - 1, w, 1);
+ canvas->TileImageInt(*toolbar_center, x, y - kNonClientBorderThickness, w,
+ toolbar_center->height());
+ // Right edge. Again, we have to clip because of image size.
+ canvas->save();
+ canvas->ClipRectInt(x + w - kNonClientBorderThickness,
+ y - kNonClientBorderThickness,
+ kNonClientBorderThickness,
+ kNonClientBorderThickness);
+ canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER),
+ x + w, y);
+ canvas->restore();
+ } else {
+ // Draw the toolbar background, setting src_y of the paint to the tab
+ // strip height as the toolbar background begins at the top of the tabs.
+ int src_y = browser_view_->GetTabStripHeight() - 1;
+ canvas->TileImageInt(*theme_toolbar, 0, src_y,
+ toolbar_bounds.x() - 1, toolbar_bounds.y() + 2,
+ toolbar_bounds.width() + 2, theme_toolbar->height());
+ // Draw rounded corners for the tab.
+ SkBitmap* toolbar_left_mask =
+ tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK);
+ SkBitmap* toolbar_right_mask =
+ tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK);
+
+ // We mask out the corners by using the DestinationIn transfer mode,
+ // which keeps the RGB pixels from the destination and the alpha from
+ // the source.
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
+
+ // Mask out the top left corner.
+ int left_x = toolbar_bounds.x() - kContentEdgeShadowThickness -
+ kClientEdgeThickness;
+ canvas->DrawBitmapInt(*toolbar_left_mask,
+ left_x, toolbar_bounds.y(), paint);
+
+ // Mask out the top right corner.
+ int right_x = toolbar_bounds.right() - toolbar_right_mask->width() +
+ kContentEdgeShadowThickness + kClientEdgeThickness;
+ canvas->DrawBitmapInt(*toolbar_right_mask,
+ right_x, toolbar_bounds.y(),
+ paint);
+
+ // Draw left edge.
+ canvas->DrawBitmapInt(*toolbar_left, left_x, toolbar_bounds.y());
+
+ // Draw center edge.
+ canvas->TileImageInt(*toolbar_center, left_x + toolbar_left->width(),
+ toolbar_bounds.y(),
+ right_x - (left_x + toolbar_left->width()),
+ toolbar_center->height());
+
+ // Right edge.
+ canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER),
+ right_x, toolbar_bounds.y());
+ }
// Draw the content/toolbar separator.
canvas->DrawLineInt(ResourceBundle::toolbar_separator_color,
- toolbar_bounds.x(), toolbar_bounds.bottom() - 1,
- toolbar_bounds.right() - 1, toolbar_bounds.bottom() - 1);
+ toolbar_bounds.x(), toolbar_bounds.bottom() - 1,
+ toolbar_bounds.right() - 1, toolbar_bounds.bottom() - 1);
}
void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) {
@@ -316,29 +340,42 @@ void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) {
return;
SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
- canvas->DrawBitmapInt(otr_avatar_icon, 0,
- (otr_avatar_icon.height() - otr_avatar_bounds_.height()) / 2,
- otr_avatar_bounds_.width(), otr_avatar_bounds_.height(),
- MirroredLeftPointForRect(otr_avatar_bounds_), otr_avatar_bounds_.y(),
- otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false);
+ int src_x = 0;
+ int src_y = (otr_avatar_icon.height() - otr_avatar_bounds_.height()) / 2;
+ int dst_x = MirroredLeftPointForRect(otr_avatar_bounds_);
+ int dst_y = otr_avatar_bounds_.y();
+ int w = otr_avatar_bounds_.width();
+ int h = otr_avatar_bounds_.height();
+ if (browser_view_->UseVerticalTabs()) {
+ // Only a portion of the otr icon is visible for vertical tabs. Clip it
+ // so that it doesn't overlap shadows.
+ gfx::Point tabstrip_origin(browser_view_->tabstrip()->bounds().origin());
+ View::ConvertPointToView(frame_->GetWindow()->GetClientView(), this,
+ &tabstrip_origin);
+ canvas->save();
+ canvas->ClipRectInt(dst_x, 2, w, tabstrip_origin.y() - 4);
+ canvas->DrawBitmapInt(otr_avatar_icon, src_x, src_y, w, h, dst_x, dst_y,
+ w, h, false);
+ canvas->restore();
+ } else {
+ canvas->DrawBitmapInt(otr_avatar_icon, src_x, src_y, w, h, dst_x, dst_y,
+ w, h, false);
+ }
}
void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
ThemeProvider* tp = GetThemeProvider();
+ gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
+
// The client edges start below the toolbar upper corner images regardless
// of how tall the toolbar itself is.
- int client_area_top =
+ int client_area_top = browser_view_->UseVerticalTabs() ?
+ client_area_bounds.y() :
frame_->GetWindow()->GetClientView()->y() +
browser_view_->GetToolbarBounds().y() +
tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height();
- gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
- if (browser_view_->UseVerticalTabs()) {
- client_area_bounds.Inset(
- GetBoundsForTabStrip(browser_view_->tabstrip()).width() - 4, 0, 0, 0);
- }
-
int client_area_bottom =
std::max(client_area_top, height() - NonClientBorderThickness());
int client_area_height = client_area_bottom - client_area_top;
@@ -385,19 +422,22 @@ void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
}
void GlassBrowserFrameView::LayoutOTRAvatar() {
+ int otr_x = NonClientBorderThickness() + kOTRSideSpacing;
SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
- int top_height = NonClientTopBorderHeight();
- int tabstrip_height, otr_height;
- if (browser_view_->IsTabStripVisible()) {
- tabstrip_height = browser_view_->GetTabStripHeight() - kOTRBottomSpacing;
+ int otr_height = browser_view_->IsTabStripVisible() ?
+ otr_avatar_icon.height() : 0;
+ int otr_y = 0;
+ if (browser_view_->UseVerticalTabs()) {
+ otr_y = NonClientTopBorderHeight() - otr_avatar_icon.height();
+ } else if (browser_view_->IsTabStripVisible()) {
+ int top_height = NonClientTopBorderHeight();
+ int tabstrip_height =
+ browser_view_->GetTabStripHeight() - kOTRBottomSpacing;
otr_height = frame_->GetWindow()->IsMaximized() ?
(tabstrip_height - kOTRMaximizedTopSpacing) : otr_avatar_icon.height();
- } else {
- tabstrip_height = otr_height = 0;
+ otr_y = top_height + tabstrip_height - otr_height;
}
- otr_avatar_bounds_.SetRect(NonClientBorderThickness() + kOTRSideSpacing,
- top_height + tabstrip_height - otr_height,
- otr_avatar_icon.width(), otr_height);
+ otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), otr_height);
}
void GlassBrowserFrameView::LayoutClientView() {
diff --git a/chrome/browser/views/frame/glass_browser_frame_view.h b/chrome/browser/views/frame/glass_browser_frame_view.h
index 662d33b..559af54 100644
--- a/chrome/browser/views/frame/glass_browser_frame_view.h
+++ b/chrome/browser/views/frame/glass_browser_frame_view.h
@@ -22,7 +22,6 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView {
// Overridden from BrowserNonClientFrameView:
virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const;
virtual void UpdateThrobber(bool running);
- virtual void PaintTabStripShadow(gfx::Canvas* canvas);
// Overridden from views::NonClientFrameView:
virtual gfx::Rect GetBoundsForClientView() const;
diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc
index c8609fc..d18375a 100644
--- a/chrome/browser/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_strip.h"
+#include "chrome/browser/views/toolbar_view.h"
#include "gfx/canvas.h"
#include "gfx/font.h"
#include "gfx/path.h"
@@ -97,6 +98,11 @@ const int kNewTabCaptionMaximizedSpacing = 16;
const int kTabStripIndent = 1;
// Spacing between extension app icon/title and tab strip.
const int kExtensionAppTabStripLeftSpacing = 10;
+// Padding between the caption and start of vertical tabs.
+const int kVerticalTabPadding = 6;
+// Inset from the top of the toolbar/tabstrip to the shadow. Used only for
+// vertical tabs.
+const int kVerticalTabBorderInset = 3;
}
///////////////////////////////////////////////////////////////////////////////
@@ -195,13 +201,9 @@ OpaqueBrowserFrameView::~OpaqueBrowserFrameView() {
gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip(
BaseTabStrip* tabstrip) const {
if (browser_view_->UseVerticalTabs()) {
- // Position the tab strip slightly below the caption buttons.
- // TODO(sky): adjust the 2.
- int y = CaptionButtonY() + minimize_button_->GetPreferredSize().height() +
- 2;
gfx::Size ps = tabstrip->GetPreferredSize();
- return gfx::Rect(NonClientBorderThickness(), y, ps.width(),
- browser_view_->height());
+ return gfx::Rect(NonClientBorderThickness(), NonClientTopBorderHeight(),
+ ps.width(), browser_view_->height());
}
int tabstrip_y = NonClientTopBorderHeight();
@@ -256,10 +258,6 @@ gfx::Size OpaqueBrowserFrameView::GetMinimumSize() {
return min_size;
}
-void OpaqueBrowserFrameView::PaintTabStripShadow(gfx::Canvas* canvas) {
- // TODO(sky): SIDE tabs.
-}
-
///////////////////////////////////////////////////////////////////////////////
// OpaqueBrowserFrameView, views::NonClientFrameView implementation:
@@ -364,11 +362,36 @@ void OpaqueBrowserFrameView::Paint(gfx::Canvas* canvas) {
else
PaintRestoredFrameBorder(canvas);
PaintTitleBar(canvas);
- PaintToolbarBackground(canvas);
+ if (browser_view_->IsToolbarVisible())
+ PaintToolbarBackground(canvas);
if (!window->IsMaximized())
PaintRestoredClientEdge(canvas);
}
+void OpaqueBrowserFrameView::PaintChildren(gfx::Canvas* canvas) {
+ if (!browser_view_->UseVerticalTabs() || !otr_avatar_icon_->IsVisible()) {
+ View::PaintChildren(canvas);
+ return;
+ }
+
+ // The otr icon is clipped for side tabs.
+ for (int i = 0, count = GetChildViewCount(); i < count; ++i) {
+ View* child = GetChildViewAt(i);
+ if (!child) {
+ NOTREACHED() << "Should not have a NULL child View for index in bounds";
+ continue;
+ }
+ if (child == otr_avatar_icon_) {
+ canvas->save();
+ canvas->ClipRectInt(0, 2, width(), otr_avatar_icon_->height() - 10);
+ child->ProcessPaint(canvas);
+ canvas->restore();
+ } else {
+ child->ProcessPaint(canvas);
+ }
+ }
+}
+
void OpaqueBrowserFrameView::Layout() {
LayoutWindowControls();
LayoutTitleBar();
@@ -384,7 +407,11 @@ bool OpaqueBrowserFrameView::HitTest(const gfx::Point& l) const {
// Otherwise claim it only if it's in a non-tab portion of the tabstrip.
bool vertical_tabs = browser_view_->UseVerticalTabs();
- const gfx::Rect& tabstrip_bounds = browser_view_->tabstrip()->bounds();
+ gfx::Rect tabstrip_bounds = browser_view_->tabstrip()->bounds();
+ gfx::Point tabstrip_origin(tabstrip_bounds.origin());
+ View::ConvertPointToView(frame_->GetWindow()->GetClientView(),
+ this, &tabstrip_origin);
+ tabstrip_bounds.set_origin(tabstrip_origin);
if ((!vertical_tabs && l.y() > tabstrip_bounds.bottom()) ||
(vertical_tabs && l.x() > tabstrip_bounds.right())) {
return false;
@@ -465,6 +492,11 @@ int OpaqueBrowserFrameView::NonClientTopBorderHeight() const {
TitlebarBottomThickness();
}
+ if (browser_view_->IsTabStripVisible() && browser_view_->UseVerticalTabs()) {
+ return CaptionButtonY() + minimize_button_->GetPreferredSize().height() +
+ kVerticalTabPadding;
+ }
+
if (browser_view_->IsTabStripVisible() && window->IsMaximized())
return FrameBorderThickness() - kTabstripTopShadowThickness;
@@ -718,54 +750,56 @@ void OpaqueBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) {
}
void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
- if (!browser_view_->IsToolbarVisible())
- return;
-
- gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
+ gfx::Rect toolbar_bounds = GetViewBounds(browser_view_->toolbar(), this);
if (toolbar_bounds.IsEmpty())
return;
ThemeProvider* tp = GetThemeProvider();
- gfx::Point toolbar_origin(toolbar_bounds.origin());
- View::ConvertPointToView(frame_->GetWindow()->GetClientView(),
- this, &toolbar_origin);
- toolbar_bounds.set_origin(toolbar_origin);
+
+ int x, y, w, h;
+ if (browser_view_->UseVerticalTabs()) {
+ gfx::Rect tabstrip_bounds = GetViewBounds(browser_view_->tabstrip(), this);
+ x = tabstrip_bounds.x();
+ w = toolbar_bounds.right() - x;
+ y = tabstrip_bounds.y() - kVerticalTabBorderInset;
+ h = toolbar_bounds.bottom() - y;
+ } else {
+ x = toolbar_bounds.x();
+ w = toolbar_bounds.width();
+ y = toolbar_bounds.y();
+ h = toolbar_bounds.bottom();
+ }
// Gross hack: We split the toolbar images into two pieces, since sometimes
// (popup mode) the toolbar isn't tall enough to show the whole image. The
// split happens between the top shadow section and the bottom gradient
// section so that we never break the gradient.
int split_point = kFrameShadowThickness * 2;
- int bottom_y = toolbar_bounds.y() + split_point;
- SkBitmap* toolbar_left =
- tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER);
- int bottom_edge_height =
- std::min(toolbar_left->height(), toolbar_bounds.height()) - split_point;
+ int bottom_y = y + split_point;
+ SkBitmap* toolbar_left = tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER);
+ int bottom_edge_height = std::min(toolbar_left->height(), h) - split_point;
// Split our canvas out so we can mask out the corners of the toolbar
// without masking out the frame.
SkRect bounds;
- bounds.set(SkIntToScalar(toolbar_bounds.x() - kClientEdgeThickness),
- SkIntToScalar(toolbar_bounds.y()),
- SkIntToScalar(toolbar_bounds.x() + toolbar_bounds.width() +
- kClientEdgeThickness * 2),
- SkIntToScalar(toolbar_bounds.y() + toolbar_bounds.height()));
+ bounds.set(SkIntToScalar(x - kClientEdgeThickness), SkIntToScalar(y),
+ SkIntToScalar(x + w + kClientEdgeThickness * 2),
+ SkIntToScalar(y + h));
canvas->saveLayerAlpha(&bounds, 255);
canvas->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode);
SkColor theme_toolbar_color =
tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR);
- canvas->FillRectInt(theme_toolbar_color, toolbar_bounds.x(), bottom_y,
- toolbar_bounds.width(), bottom_edge_height);
+ canvas->FillRectInt(theme_toolbar_color, x, bottom_y, w, bottom_edge_height);
int strip_height = browser_view_->GetTabStripHeight();
SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR);
canvas->TileImageInt(*theme_toolbar,
- toolbar_bounds.x() - kClientEdgeThickness,
+ x - kClientEdgeThickness,
strip_height - kFrameShadowThickness,
- toolbar_bounds.x() - kClientEdgeThickness, bottom_y,
- toolbar_bounds.width() + (2 * kClientEdgeThickness),
+ x - kClientEdgeThickness, bottom_y,
+ w + (2 * kClientEdgeThickness),
theme_toolbar->height());
// Draw rounded corners for the tab.
@@ -781,11 +815,10 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
// Make the left edge.
- int left_x = toolbar_bounds.x() - kClientEdgeThickness -
- kContentEdgeShadowThickness;
+ int left_x = x - kClientEdgeThickness - kContentEdgeShadowThickness;
canvas->DrawBitmapInt(*toolbar_left_mask, 0, 0,
toolbar_left_mask->width(), split_point,
- left_x, toolbar_bounds.y(),
+ left_x, y,
toolbar_left_mask->width(), split_point, false, paint);
canvas->DrawBitmapInt(*toolbar_left_mask, 0,
toolbar_left_mask->height() - bottom_edge_height,
@@ -794,11 +827,10 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
toolbar_left_mask->width(), bottom_edge_height, false, paint);
// Mask the right edge.
- int right_x = toolbar_bounds.right() -
- toolbar_right_mask->width() + kClientEdgeThickness +
+ int right_x = x + w - toolbar_right_mask->width() + kClientEdgeThickness +
kContentEdgeShadowThickness;
canvas->DrawBitmapInt(*toolbar_right_mask, 0, 0,
- toolbar_right_mask->width(), split_point, right_x, toolbar_bounds.y(),
+ toolbar_right_mask->width(), split_point, right_x, y,
toolbar_right_mask->width(), split_point, false, paint);
canvas->DrawBitmapInt(*toolbar_right_mask, 0,
toolbar_right_mask->height() - bottom_edge_height,
@@ -807,7 +839,7 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
canvas->restore();
canvas->DrawBitmapInt(*toolbar_left, 0, 0, toolbar_left->width(), split_point,
- left_x, toolbar_bounds.y(),
+ left_x, y,
toolbar_left->width(), split_point, false);
canvas->DrawBitmapInt(*toolbar_left, 0,
toolbar_left->height() - bottom_edge_height, toolbar_left->width(),
@@ -817,12 +849,12 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
SkBitmap* toolbar_center =
tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER);
canvas->TileImageInt(*toolbar_center, 0, 0, left_x + toolbar_left->width(),
- toolbar_bounds.y(), right_x - (left_x + toolbar_left->width()),
+ y, right_x - (left_x + toolbar_left->width()),
split_point);
SkBitmap* toolbar_right = tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER);
canvas->DrawBitmapInt(*toolbar_right, 0, 0, toolbar_right->width(),
- split_point, right_x, toolbar_bounds.y(),
+ split_point, right_x, y,
toolbar_right->width(), split_point, false);
canvas->DrawBitmapInt(*toolbar_right, 0,
toolbar_right->height() - bottom_edge_height, toolbar_right->width(),
@@ -831,8 +863,9 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
// Draw the content/toolbar separator.
canvas->DrawLineInt(ResourceBundle::toolbar_separator_color,
- toolbar_bounds.x(), toolbar_bounds.bottom() - kClientEdgeThickness,
- toolbar_bounds.right() - kClientEdgeThickness,
+ MirroredLeftPointForRect(toolbar_bounds),
+ toolbar_bounds.bottom() - kClientEdgeThickness,
+ toolbar_bounds.width() - kClientEdgeThickness,
toolbar_bounds.bottom() - kClientEdgeThickness);
}
@@ -850,6 +883,8 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
client_area_top += browser_view_->GetToolbarBounds().y() +
std::min(tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height(),
toolbar_bounds.height());
+ if (browser_view_->UseVerticalTabs())
+ client_area_top -= kVerticalTabBorderInset;
} else if (!browser_view_->IsTabStripVisible()) {
// The toolbar isn't going to draw a client edge for us, so draw one
// ourselves.
@@ -1005,29 +1040,32 @@ void OpaqueBrowserFrameView::LayoutTitleBar() {
}
void OpaqueBrowserFrameView::LayoutOTRAvatar() {
- int top_height = NonClientTopBorderHeight();
+ int otr_y = NonClientTopBorderHeight();
if (!frame_->GetWindow()->IsMaximized() &&
!frame_->GetWindow()->IsFullscreen()) {
- top_height += kNonClientRestoredExtraThickness;
+ otr_y += kNonClientRestoredExtraThickness;
}
- int tabstrip_height, otr_height;
bool visible = browser_view_->ShouldShowOffTheRecordAvatar();
gfx::Size preferred_size = otr_avatar_icon_->GetPreferredSize();
+ int otr_height = 0;
if (browser_view_->IsTabStripVisible()) {
- tabstrip_height = browser_view_->GetTabStripHeight() - kOTRBottomSpacing;
- otr_height = frame_->GetWindow()->IsMaximized() ?
- (tabstrip_height - kOTRMaximizedTopSpacing) :
- preferred_size.height();
-
+ if (browser_view_->UseVerticalTabs()) {
+ otr_height = preferred_size.height();
+ otr_y = -2;
+ } else {
+ int tabstrip_height =
+ browser_view_->GetTabStripHeight() - kOTRBottomSpacing;
+ otr_height = frame_->GetWindow()->IsMaximized() ?
+ (tabstrip_height - kOTRMaximizedTopSpacing) :
+ preferred_size.height();
+ otr_y += tabstrip_height - otr_height;
+ }
} else {
- tabstrip_height = otr_height = 0;
visible = false;
}
otr_avatar_icon_->SetVisible(visible);
- otr_avatar_icon_->SetBounds(NonClientBorderThickness() + kOTRSideSpacing +
- 0,
- top_height + tabstrip_height - otr_height,
- preferred_size.width(), otr_height);
+ otr_avatar_icon_->SetBounds(NonClientBorderThickness() + kOTRSideSpacing,
+ otr_y, preferred_size.width(), otr_height);
}
gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width,
@@ -1038,3 +1076,14 @@ gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width,
std::max(0, width - (2 * border_thickness)),
std::max(0, height - top_height - border_thickness));
}
+
+// static
+gfx::Rect OpaqueBrowserFrameView::GetViewBounds(views::View* src,
+ views::View* dst) {
+ gfx::Rect bounds(src->bounds());
+
+ gfx::Point origin_in_dst(bounds.origin());
+ View::ConvertPointToView(src->GetParent(), dst, &origin_in_dst);
+ bounds.set_origin(origin_in_dst);
+ return bounds;
+}
diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.h b/chrome/browser/views/frame/opaque_browser_frame_view.h
index cc93fad..afa1106 100644
--- a/chrome/browser/views/frame/opaque_browser_frame_view.h
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.h
@@ -34,7 +34,6 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const;
virtual void UpdateThrobber(bool running);
virtual gfx::Size GetMinimumSize();
- virtual void PaintTabStripShadow(gfx::Canvas* canvas);
protected:
// Overridden from views::NonClientFrameView:
@@ -50,6 +49,7 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
// Overridden from views::View:
virtual void Paint(gfx::Canvas* canvas);
+ virtual void PaintChildren(gfx::Canvas* canvas);
virtual void Layout();
virtual bool HitTest(const gfx::Point& l) const;
virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
@@ -110,6 +110,10 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
// Returns the bounds of the client area for the specified view size.
gfx::Rect CalculateClientAreaBounds(int width, int height) const;
+ // Returns the bounds of |src| in the coordinate system of |dst|.
+ // TODO(sky): promote this to view.
+ static gfx::Rect GetViewBounds(views::View* src, views::View* dst);
+
// The layout rect of the title, if visible.
gfx::Rect title_bounds_;