diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-04 18:02:58 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-04 18:02:58 +0000 |
commit | 75f02038e43469d00b94c496da89557a660f5116 (patch) | |
tree | 4541c77f6656bf862625ddec95bad25432f52a96 /chrome/browser/views | |
parent | 8b034b702cd11acb174a1ece9ab837afbda86b77 (diff) | |
download | chromium_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')
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_; |