| Index: chrome/browser/views/frame/aero_glass_non_client_view.cc
|
| ===================================================================
|
| --- chrome/browser/views/frame/aero_glass_non_client_view.cc (revision 9393)
|
| +++ chrome/browser/views/frame/aero_glass_non_client_view.cc (working copy)
|
| @@ -7,12 +7,8 @@
|
| #include "chrome/app/theme/theme_resources.h"
|
| #include "chrome/browser/views/frame/browser_view.h"
|
| #include "chrome/browser/views/tabs/tab_strip.h"
|
| -#include "chrome/common/gfx/chrome_canvas.h"
|
| -#include "chrome/common/gfx/chrome_font.h"
|
| -#include "chrome/common/gfx/path.h"
|
| #include "chrome/common/resource_bundle.h"
|
| #include "chrome/views/client_view.h"
|
| -#include "chrome/views/window_delegate.h"
|
| #include "chrome/views/window_resources.h"
|
|
|
| // An enumeration of bitmap resources used by this window.
|
| @@ -89,28 +85,17 @@
|
| AeroGlassWindowResources* AeroGlassNonClientView::resources_ = NULL;
|
| SkBitmap AeroGlassNonClientView::distributor_logo_;
|
|
|
| -// The width of the client edge to the left and right of the window.
|
| -static const int kClientEdgeWidth = 3;
|
| -// The height of the client edge to the bottom of the window.
|
| -static const int kClientEdgeHeight = 2;
|
| +namespace {
|
| +// There are 3 px of client edge drawn inside the outer frame borders.
|
| +const int kNonClientBorderThickness = 3;
|
| +// 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;
|
| // In the window corners, the resize areas don't actually expand bigger, but the
|
| // 16 px at the end of the top and bottom edges triggers diagonal resizing.
|
| -const int kResizeEdgeWidth = 16;
|
| -// The horizontal distance between the left of the minimize button and the
|
| -// right edge of the distributor logo.
|
| -static const int kDistributorLogoHorizontalOffset = 7;
|
| -// The distance from the top of the non-client view and the top edge of the
|
| -// distributor logo.
|
| -static const int kDistributorLogoVerticalOffset = 3;
|
| -// The distance of the TabStrip from the top of the window's client area.
|
| -static const int kTabStripY = 19;
|
| -// How much space on the right is not used for the tab strip (to provide
|
| -// separation between the tabs and the window controls).
|
| -static const int kTabStripRightHorizOffset = 30;
|
| -// A single pixel.
|
| -static const int kPixel = 1;
|
| -// The size (width/height) of the window icon.
|
| -static const int kWindowIconSize = 16;
|
| +const int kResizeAreaCornerSize = 16;
|
| +// The distributor logo is drawn 3 px from the top of the window.
|
| +static const int kLogoTopSpacing = 3;
|
| // In maximized mode, the OTR avatar starts 2 px below the top of the screen, so
|
| // that it doesn't extend into the "3D edge" portion of the titlebar.
|
| const int kOTRMaximizedTopSpacing = 2;
|
| @@ -121,6 +106,18 @@
|
| // There are 2 px on each side of the OTR avatar (between the frame border and
|
| // it on the left, and between it and the tabstrip on the right).
|
| const int kOTRSideSpacing = 2;
|
| +// In restored mode, the New Tab button isn't at the same height as the caption
|
| +// buttons, but the space will look cluttered if it actually slides under them,
|
| +// so we stop it when the gap between the two is down to 5 px.
|
| +const int kNewTabCaptionRestoredSpacing = 5;
|
| +// In maximized mode, where the New Tab button and the caption buttons are at
|
| +// similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
|
| +// looking too cluttered.
|
| +const int kNewTabCaptionMaximizedSpacing = 16;
|
| +// When there's a distributor logo, we leave a 7 px gap between it and the
|
| +// caption buttons.
|
| +const int kLogoCaptionSpacing = 7;
|
| +}
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // AeroGlassNonClientView, public:
|
| @@ -137,39 +134,32 @@
|
|
|
| gfx::Rect AeroGlassNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
|
| int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
|
| - (otr_avatar_bounds_.right() + kOTRSideSpacing) : kClientEdgeWidth;
|
| - int tabstrip_width = width() - tabstrip_x - kTabStripRightHorizOffset -
|
| - (frame_->IsMaximized() ? frame_->GetMinimizeButtonOffset() : 0);
|
| - int tabstrip_y =
|
| - frame_->IsMaximized() ? (CalculateNonClientTopHeight() - 2) : kTabStripY;
|
| - return gfx::Rect(tabstrip_x, tabstrip_y, std::max(0, tabstrip_width),
|
| - tabstrip->GetPreferredHeight());
|
| + (otr_avatar_bounds_.right() + kOTRSideSpacing) :
|
| + NonClientBorderThickness();
|
| + int tabstrip_width = frame_->GetMinimizeButtonOffset() - tabstrip_x -
|
| + (frame_->IsMaximized() ?
|
| + kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing);
|
| + return gfx::Rect(tabstrip_x, NonClientTopBorderHeight(),
|
| + std::max(0, tabstrip_width), tabstrip->GetPreferredHeight());
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // AeroGlassNonClientView, views::NonClientView implementation:
|
|
|
| -gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int win_width,
|
| - int win_height) const {
|
| +gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int width,
|
| + int height) const {
|
| if (!browser_view_->IsTabStripVisible())
|
| - return gfx::Rect(0, 0, width(), height());
|
| + return gfx::Rect(0, 0, this->width(), this->height());
|
|
|
| - int top_margin = CalculateNonClientTopHeight();
|
| - return gfx::Rect(kClientEdgeWidth, top_margin,
|
| - std::max(0, win_width - (2 * kClientEdgeWidth)),
|
| - std::max(0, win_height - top_margin - kClientEdgeHeight));
|
| + int top_height = NonClientTopBorderHeight();
|
| + int border_thickness = NonClientBorderThickness();
|
| + return gfx::Rect(border_thickness, top_height,
|
| + std::max(0, width - (2 * border_thickness)),
|
| + std::max(0, height - top_height - border_thickness));
|
| }
|
|
|
| -gfx::Size AeroGlassNonClientView::CalculateWindowSizeForClientSize(
|
| - int width,
|
| - int height) const {
|
| - int top_margin = CalculateNonClientTopHeight();
|
| - return gfx::Size(width + (2 * kClientEdgeWidth),
|
| - height + top_margin + kClientEdgeHeight);
|
| -}
|
| -
|
| CPoint AeroGlassNonClientView::GetSystemMenuPoint() const {
|
| - CPoint offset(0, 0);
|
| + CPoint offset;
|
| MapWindowPoints(GetWidget()->GetHWND(), HWND_DESKTOP, &offset, 1);
|
| return offset;
|
| }
|
| @@ -181,58 +171,19 @@
|
| if (!browser_view_->IsTabStripVisible() || !bounds().Contains(point))
|
| return HTNOWHERE;
|
|
|
| - // See if the client view intersects the non-client area (e.g. blank areas
|
| - // of the TabStrip).
|
| int frame_component = frame_->client_view()->NonClientHitTest(point);
|
| if (frame_component != HTNOWHERE)
|
| return frame_component;
|
|
|
| - int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
|
| - int resize_width = kResizeEdgeWidth - border_thickness;
|
| - if (point.x() < kClientEdgeWidth) {
|
| - if (point.y() < border_thickness)
|
| - return HTTOPLEFT;
|
| - if (point.y() >= (height() - kClientEdgeHeight))
|
| - return HTBOTTOMLEFT;
|
| - return HTLEFT;
|
| - }
|
| - if (point.x() >= (width() - kClientEdgeWidth)) {
|
| - if (point.y() < border_thickness)
|
| - return HTTOPRIGHT;
|
| - if (point.y() >= (height() - kClientEdgeHeight))
|
| - return HTBOTTOMRIGHT;
|
| - return HTRIGHT;
|
| - }
|
| - if (point.y() < border_thickness) {
|
| - if (point.x() < resize_width)
|
| - return HTTOPLEFT;
|
| - if (point.x() >= (width() - resize_width))
|
| - return HTTOPRIGHT;
|
| - return HTTOP;
|
| - }
|
| - if (point.y() >= (height() - kClientEdgeHeight)) {
|
| - if (point.x() < resize_width)
|
| - return HTBOTTOMLEFT;
|
| - if (point.x() >= (width() - resize_width))
|
| - return HTBOTTOMRIGHT;
|
| - return HTBOTTOM;
|
| - }
|
| - return HTCAPTION;
|
| + int border_thickness = FrameBorderThickness();
|
| + int window_component = GetHTComponentForFrame(point, border_thickness,
|
| + NonClientBorderThickness(), border_thickness,
|
| + kResizeAreaCornerSize - border_thickness,
|
| + frame_->window_delegate()->CanResize());
|
| + // Fall back to the caption if no other component matches.
|
| + return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
|
| }
|
|
|
| -void AeroGlassNonClientView::GetWindowMask(const gfx::Size& size,
|
| - gfx::Path* window_mask) {
|
| - // We use the native window region.
|
| -}
|
| -
|
| -void AeroGlassNonClientView::EnableClose(bool enable) {
|
| - // This is handled exclusively by Window.
|
| -}
|
| -
|
| -void AeroGlassNonClientView::ResetWindowControls() {
|
| - // Our window controls are rendered by the system and do not require reset.
|
| -}
|
| -
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // AeroGlassNonClientView, views::View overrides:
|
|
|
| @@ -246,18 +197,11 @@
|
| }
|
|
|
| void AeroGlassNonClientView::Layout() {
|
| - LayoutOTRAvatar();
|
| LayoutDistributorLogo();
|
| + LayoutOTRAvatar();
|
| LayoutClientView();
|
| }
|
|
|
| -gfx::Size AeroGlassNonClientView::GetPreferredSize() {
|
| - gfx::Size prefsize = frame_->client_view()->GetPreferredSize();
|
| - prefsize.Enlarge(2 * kClientEdgeWidth,
|
| - CalculateNonClientTopHeight() + kClientEdgeHeight);
|
| - return prefsize;
|
| -}
|
| -
|
| void AeroGlassNonClientView::ViewHierarchyChanged(bool is_add,
|
| views::View* parent,
|
| views::View* child) {
|
| @@ -271,140 +215,126 @@
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // AeroGlassNonClientView, private:
|
|
|
| -int AeroGlassNonClientView::CalculateNonClientTopHeight() const {
|
| - return browser_view_->IsTabStripVisible() ?
|
| - GetSystemMetrics(SM_CYSIZEFRAME) : 0;
|
| +int AeroGlassNonClientView::FrameBorderThickness() const {
|
| + return GetSystemMetrics(SM_CXSIZEFRAME);
|
| }
|
|
|
| -void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
|
| - if (!browser_view_->ShouldShowOffTheRecordAvatar())
|
| - return;
|
| +int AeroGlassNonClientView::NonClientBorderThickness() const {
|
| + return kNonClientBorderThickness;
|
| +}
|
|
|
| - 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 AeroGlassNonClientView::NonClientTopBorderHeight() const {
|
| + return FrameBorderThickness() +
|
| + (frame_->IsMaximized() ? 0 : kNonClientRestoredExtraThickness);
|
| }
|
|
|
| void AeroGlassNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) {
|
| // The distributor logo is only painted when the frame is not maximized and
|
| // when we actually have a logo.
|
| - if (!frame_->IsMaximized() && !frame_->IsMinimized() &&
|
| - !distributor_logo_.empty()) {
|
| + if (!frame_->IsMaximized() && !distributor_logo_.empty()) {
|
| + // TODO: Do we need to mirror this?
|
| canvas->DrawBitmapInt(distributor_logo_, logo_bounds_.x(),
|
| logo_bounds_.y());
|
| }
|
| }
|
|
|
| void AeroGlassNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) {
|
| + gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
|
| + gfx::Point toolbar_origin(toolbar_bounds.origin());
|
| + View::ConvertPointToView(frame_->client_view(), this, &toolbar_origin);
|
| + toolbar_bounds.set_origin(toolbar_origin);
|
| +
|
| SkBitmap* toolbar_left =
|
| resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
|
| + canvas->DrawBitmapInt(*toolbar_left,
|
| + toolbar_bounds.x() - toolbar_left->width(),
|
| + toolbar_bounds.y());
|
| +
|
| SkBitmap* toolbar_center =
|
| resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
|
| - SkBitmap* toolbar_right =
|
| - resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT);
|
| + canvas->TileImageInt(*toolbar_center, toolbar_bounds.x(), toolbar_bounds.y(),
|
| + toolbar_bounds.width(), toolbar_center->height());
|
|
|
| - gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds();
|
| - gfx::Point topleft(toolbar_bounds.x(), toolbar_bounds.y());
|
| - View::ConvertPointToView(frame_->client_view(), this, &topleft);
|
| - toolbar_bounds.set_x(topleft.x());
|
| - toolbar_bounds.set_y(topleft.y());
|
| + canvas->DrawBitmapInt(*resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT),
|
| + toolbar_bounds.right(), toolbar_bounds.y());
|
| +}
|
|
|
| - // We use TileImageInt for the left and right caps to clip the rendering
|
| - // to the appropriate height of the toolbar.
|
| - canvas->TileImageInt(*toolbar_left,
|
| - toolbar_bounds.x() - toolbar_left->width(),
|
| - toolbar_bounds.y(), toolbar_left->width(),
|
| - toolbar_bounds.height());
|
| - canvas->TileImageInt(*toolbar_center,
|
| - toolbar_bounds.x(), toolbar_bounds.y(),
|
| - toolbar_bounds.width(), toolbar_center->height());
|
| - canvas->TileImageInt(*toolbar_right, toolbar_bounds.right(),
|
| - toolbar_bounds.y(), toolbar_right->width(),
|
| - toolbar_bounds.height());
|
| +void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
|
| + if (!browser_view_->ShouldShowOffTheRecordAvatar())
|
| + 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);
|
| }
|
|
|
| void AeroGlassNonClientView::PaintClientEdge(ChromeCanvas* canvas) {
|
| + int client_area_top =
|
| + frame_->client_view()->y() + browser_view_->GetToolbarBounds().bottom();
|
| + gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
|
| + // The toolbar draws a client edge along its own bottom edge when it's visible
|
| + // and in normal mode. However, it only draws this for the width of the
|
| + // actual client area, leaving a gap at the left and right edges:
|
| + //
|
| + // | Toolbar | <-- part of toolbar
|
| + // ----- (toolbar client edge) ----- <-- gap
|
| + // | Client area | <-- right client edge
|
| + //
|
| + // To address this, we extend the left and right client edges up to fill the
|
| + // gap, by pretending the toolbar is shorter than it really is.
|
| + client_area_top -= kClientEdgeThickness;
|
| +
|
| + int client_area_bottom =
|
| + std::max(client_area_top, height() - NonClientBorderThickness());
|
| + int client_area_height = client_area_bottom - client_area_top;
|
| SkBitmap* right = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT);
|
| - SkBitmap* bottom_right =
|
| - resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT);
|
| - SkBitmap* bottom = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
|
| - SkBitmap* bottom_left =
|
| - resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
|
| - SkBitmap* left = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
|
| + canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
|
| + right->width(), client_area_height);
|
|
|
| - // The toolbar renders its own client edge in PaintToolbarBackground, however
|
| - // there are other bands that need to have a client edge rendered along their
|
| - // sides, such as the Bookmark bar, infobars, etc.
|
| - gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds();
|
| - gfx::Rect client_area_bounds = browser_view_->GetClientAreaBounds();
|
| - // For some reason things don't line up quite right, so we add and subtract
|
| - // pixels here and there for aesthetic bliss.
|
| - // Enlarge the client area to include the toolbar, since the top edge of
|
| - // the client area is the toolbar background and the client edge renders
|
| - // the left and right sides of the toolbar background.
|
| - client_area_bounds.SetRect(
|
| - client_area_bounds.x(),
|
| - frame_->client_view()->y() + toolbar_bounds.bottom() - kPixel,
|
| - client_area_bounds.width(),
|
| - std::max(0, height() - frame_->client_view()->y() -
|
| - toolbar_bounds.bottom() + kPixel));
|
| + canvas->DrawBitmapInt(
|
| + *resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT),
|
| + client_area_bounds.right(), client_area_bottom);
|
|
|
| - int fudge = frame_->window_delegate()->ShouldShowWindowTitle() ? kPixel : 0;
|
| - canvas->TileImageInt(*right, client_area_bounds.right(),
|
| - client_area_bounds.y() + fudge, right->width(),
|
| - client_area_bounds.height() - bottom_right->height() +
|
| - kPixel - fudge);
|
| - canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(),
|
| - client_area_bounds.bottom() - bottom_right->height() +
|
| - kPixel);
|
| + SkBitmap* bottom = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
|
| canvas->TileImageInt(*bottom, client_area_bounds.x(),
|
| - client_area_bounds.bottom() - bottom_right->height() +
|
| - kPixel, client_area_bounds.width(),
|
| - bottom_right->height());
|
| + client_area_bottom, client_area_bounds.width(),
|
| + bottom->height());
|
| +
|
| + SkBitmap* bottom_left =
|
| + resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
|
| canvas->DrawBitmapInt(*bottom_left,
|
| - client_area_bounds.x() - bottom_left->width(),
|
| - client_area_bounds.bottom() - bottom_left->height() +
|
| - kPixel);
|
| + client_area_bounds.x() - bottom_left->width(), client_area_bottom);
|
| +
|
| + SkBitmap* left = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
|
| canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
|
| - client_area_bounds.y() + fudge, left->width(),
|
| - client_area_bounds.height() - bottom_left->height() +
|
| - kPixel - fudge);
|
| + client_area_top, left->width(), client_area_height);
|
| }
|
|
|
| +void AeroGlassNonClientView::LayoutDistributorLogo() {
|
| + int logo_x = frame_->GetMinimizeButtonOffset() - (distributor_logo_.empty() ?
|
| + 0 : (distributor_logo_.width() + kLogoCaptionSpacing));
|
| + logo_bounds_.SetRect(logo_x, kLogoTopSpacing, distributor_logo_.width(),
|
| + distributor_logo_.height());
|
| +}
|
| +
|
| void AeroGlassNonClientView::LayoutOTRAvatar() {
|
| SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
|
| - int top_height = (frame_->IsMaximized() ?
|
| - (CalculateNonClientTopHeight() - 2) : kTabStripY);
|
| + int top_height = NonClientTopBorderHeight();
|
| int tabstrip_height = browser_view_->GetTabStripHeight() - kOTRBottomSpacing;
|
| int otr_height = frame_->IsMaximized() ?
|
| (tabstrip_height - kOTRMaximizedTopSpacing) :
|
| otr_avatar_icon.height();
|
| - otr_avatar_bounds_.SetRect(kClientEdgeWidth + kOTRSideSpacing,
|
| - top_height + tabstrip_height - otr_height, otr_avatar_icon.width(),
|
| - otr_height);
|
| + otr_avatar_bounds_.SetRect(NonClientBorderThickness() + kOTRSideSpacing,
|
| + top_height + tabstrip_height - otr_height,
|
| + otr_avatar_icon.width(), otr_height);
|
| }
|
|
|
| -void AeroGlassNonClientView::LayoutDistributorLogo() {
|
| - if (distributor_logo_.empty())
|
| - return;
|
| -
|
| - int logo_w = distributor_logo_.width();
|
| - int logo_h = distributor_logo_.height();
|
| -
|
| - int w = width();
|
| - int mbx = frame_->GetMinimizeButtonOffset();
|
| -
|
| - logo_bounds_.SetRect(
|
| - width() - frame_->GetMinimizeButtonOffset() - logo_w,
|
| - kDistributorLogoVerticalOffset, logo_w, logo_h);
|
| -}
|
| -
|
| void AeroGlassNonClientView::LayoutClientView() {
|
| - gfx::Rect client_bounds = CalculateClientAreaBounds(width(), height());
|
| - frame_->client_view()->SetBounds(client_bounds);
|
| + frame_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
|
| + height()));
|
| }
|
|
|
| // static
|
| @@ -412,6 +342,7 @@
|
| static bool initialized = false;
|
| if (!initialized) {
|
| resources_ = new AeroGlassWindowResources;
|
| +
|
| ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
| #if defined(GOOGLE_CHROME_BUILD)
|
| distributor_logo_ = *rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO);
|
|
|