diff options
author | beng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-05 00:06:22 +0000 |
---|---|---|
committer | beng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-05 00:06:22 +0000 |
commit | ee0b38b16afa0a6d1cfd07df66ec67cee8bac6c8 (patch) | |
tree | 558132c0345c91f5b73c0ea03db2b1ce60ce7d69 /chrome | |
parent | 4ae627586ecb6184c3b766fd5128709442b17360 (diff) | |
download | chromium_src-ee0b38b16afa0a6d1cfd07df66ec67cee8bac6c8.zip chromium_src-ee0b38b16afa0a6d1cfd07df66ec67cee8bac6c8.tar.gz chromium_src-ee0b38b16afa0a6d1cfd07df66ec67cee8bac6c8.tar.bz2 |
Add the AeroGlassFrame and AeroGlassNonClientView for Vista.
Note that AeroGlassFrame needs a NonClientView as well - even though Windows draws most of the frame and its borders, we do some custom rendering in the non-client area, such as the distributor logo, the client edge and toolbar backgrounds. This necessitated allowing Window to support an optional NonClientView. I just jimmied this in for now... can clean up that API later if desired.
B=1031854
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@352 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/views/frame/aero_glass_frame.cc | 138 | ||||
-rw-r--r-- | chrome/browser/views/frame/aero_glass_frame.h | 44 | ||||
-rw-r--r-- | chrome/browser/views/frame/aero_glass_non_client_view.cc | 262 | ||||
-rw-r--r-- | chrome/browser/views/frame/aero_glass_non_client_view.h | 34 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view2.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_window_factory.cc | 51 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.cc | 6 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.h | 6 | ||||
-rw-r--r-- | chrome/views/window.cc | 22 | ||||
-rw-r--r-- | chrome/views/window.h | 7 |
10 files changed, 519 insertions, 53 deletions
diff --git a/chrome/browser/views/frame/aero_glass_frame.cc b/chrome/browser/views/frame/aero_glass_frame.cc index 32e7044..b3db14e 100644 --- a/chrome/browser/views/frame/aero_glass_frame.cc +++ b/chrome/browser/views/frame/aero_glass_frame.cc @@ -27,13 +27,147 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include <dwmapi.h> + #include "chrome/browser/views/frame/aero_glass_frame.h" +#include "chrome/app/theme/theme_resources.h" +#include "chrome/browser/views/frame/browser_view2.h" +#include "chrome/browser/views/frame/aero_glass_non_client_view.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/views/window_delegate.h" + +// static +static const int kResizeBorder = 5; + +// By how much the toolbar overlaps with the tab strip. +static const int kToolbarOverlapVertOffset = 3; + +// The DWM puts a light border around the client area - we need to +// take this border size into account when we reduce its size so that +// we don't draw our content border dropshadow images over the top. +static const int kDwmBorderSize = 1; + /////////////////////////////////////////////////////////////////////////////// -// AeroGlassFrame, public: +// OpaqueFrame, public: -AeroGlassFrame::AeroGlassFrame() : Window(NULL) { +AeroGlassFrame::AeroGlassFrame(BrowserView2* browser_view) + : Window(browser_view), + browser_view_(browser_view), + frame_initialized_(false) { + non_client_view_ = new AeroGlassNonClientView(this); + browser_view_->set_frame(this); } AeroGlassFrame::~AeroGlassFrame() { } + +void AeroGlassFrame::Init(const gfx::Rect& bounds) { + Window::Init(NULL, bounds); +} + +gfx::Rect AeroGlassFrame::GetToolbarBounds() const { + return browser_view_->GetToolbarBounds(); +} + +gfx::Rect AeroGlassFrame::GetContentsBounds() const { + return browser_view_->GetClientAreaBounds(); +} + +int AeroGlassFrame::GetMinimizeButtonOffset() const { + TITLEBARINFOEX titlebar_info; + titlebar_info.cbSize = sizeof(TITLEBARINFOEX); + SendMessage(GetHWND(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info); + + RECT wr; + GetWindowRect(&wr); + + return wr.right - titlebar_info.rgrect[2].left; +} + +/////////////////////////////////////////////////////////////////////////////// +// AeroGlassFrame, BrowserFrame implementation: + +ChromeViews::Window* AeroGlassFrame::GetWindow() { + return this; +} + +/////////////////////////////////////////////////////////////////////////////// +// AeroGlassFrame, ChromeViews::HWNDViewContainer implementation: + +LRESULT AeroGlassFrame::OnNCActivate(BOOL active) { + if (!frame_initialized_) { + ::SetWindowPos(GetHWND(), NULL, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED); + UpdateDWMFrame(); + frame_initialized_ = true; + } + return TRUE; +} + +LRESULT AeroGlassFrame::OnNCCalcSize(BOOL mode, LPARAM l_param) { + // By default the client side is set to the window size which is what + // we want. + if (mode == TRUE) { + // Calculate new NCCALCSIZE_PARAMS based on custom NCA inset. + NCCALCSIZE_PARAMS *pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param); + + // Hack necessary to stop black background flicker, we cut out + // resizeborder here to save us from having to do too much + // addition and subtraction in Layout(). We don't cut off the + // top + titlebar as that prevents the window controls from + // highlighting. + pncsp->rgrc[0].left = pncsp->rgrc[0].left + kResizeBorder; + pncsp->rgrc[0].right = pncsp->rgrc[0].right - kResizeBorder; + pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - kResizeBorder; + + // We need to reset the frame, as Vista resets it whenever it changes + // composition modes (and NCCALCSIZE is the closest thing we get to + // a reliable message about the change). + UpdateDWMFrame(); + + SetMsgHandled(TRUE); + return 0; + } + SetMsgHandled(FALSE); + return 0; +} + +LRESULT AeroGlassFrame::OnNCHitTest(const CPoint& pt) { + LRESULT result; + if (DwmDefWindowProc(GetHWND(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y), + &result)) { + return result; + } + return Window::OnNCHitTest(pt); +} + +/////////////////////////////////////////////////////////////////////////////// +// AeroGlassFrame, private: + +void AeroGlassFrame::UpdateDWMFrame() { + // Nothing to do yet. + if (!client_view()) + return; + + // Note: we don't use DwmEnableBlurBehindWindow because any region not + // included in the glass region is composited source over. This means + // that anything drawn directly with GDI appears fully transparent. + // + // We want this region to extend past our content border images, as they + // may be partially-transparent. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + SkBitmap left_edge = *rb.GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER); + SkBitmap bottom_edge = *rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER); + SkBitmap right_edge = *rb.GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER); + + // TODO(beng): when TabStrip is hooked up, obtain this offset from its + // bounds. + int toolbar_y = 36; + MARGINS margins = { kDwmBorderSize + left_edge.width(), + kDwmBorderSize + right_edge.width(), + kDwmBorderSize + client_view()->GetY() + + kToolbarOverlapVertOffset + toolbar_y, + kDwmBorderSize + bottom_edge.height() }; + DwmExtendFrameIntoClientArea(GetHWND(), &margins); +} diff --git a/chrome/browser/views/frame/aero_glass_frame.h b/chrome/browser/views/frame/aero_glass_frame.h index 3795098..df0d90ea 100644 --- a/chrome/browser/views/frame/aero_glass_frame.h +++ b/chrome/browser/views/frame/aero_glass_frame.h @@ -30,21 +30,55 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_FRAME_H_ #define CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_FRAME_H_ +#include "chrome/browser/views/frame/browser_frame.h" #include "chrome/views/window.h" +class BrowserView2; + /////////////////////////////////////////////////////////////////////////////// // AeroGlassFrame // -// AeroGlassFrame is a Window subclass that in conjunction with -// AeroGlassNonClientView provides the window frame on Windows Vista with -// DWM desktop compositing is enabled. A standard Windows frame is used. +// AeroGlassFrame is a Window subclass that provides the window frame on +// Windows Vista with DWM desktop compositing enabled. The window's non-client +// areas are drawn by the system. // -class AeroGlassFrame : public ChromeViews::Window { +class AeroGlassFrame : public BrowserFrame, + public ChromeViews::Window { public: - AeroGlassFrame(); + explicit AeroGlassFrame(BrowserView2* browser_view); virtual ~AeroGlassFrame(); + void Init(const gfx::Rect& bounds); + + bool IsToolbarVisible() const { return true; } + bool IsTabStripVisible() const { return true; } + + // Returns bounds of various areas within the BrowserView ClientView. + gfx::Rect GetToolbarBounds() const; + gfx::Rect GetContentsBounds() const; + + // Determine the distance of the left edge of the minimize button from the + // right edge of the window. Used in our Non-Client View's Layout. + int GetMinimizeButtonOffset() const; + + // Overridden from BrowserFrame: + virtual ChromeViews::Window* GetWindow(); + + protected: + // Overridden from ChromeViews::HWNDViewContainer: + virtual LRESULT OnNCActivate(BOOL active); + virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); + virtual LRESULT OnNCHitTest(const CPoint& pt); + private: + // Updates the DWM with the frame bounds. + void UpdateDWMFrame(); + + // The BrowserView2 is our ClientView. This is a pointer to it. + BrowserView2* browser_view_; + + bool frame_initialized_; + DISALLOW_EVIL_CONSTRUCTORS(AeroGlassFrame); }; diff --git a/chrome/browser/views/frame/aero_glass_non_client_view.cc b/chrome/browser/views/frame/aero_glass_non_client_view.cc index 87cd951..e298639 100644 --- a/chrome/browser/views/frame/aero_glass_non_client_view.cc +++ b/chrome/browser/views/frame/aero_glass_non_client_view.cc @@ -27,13 +27,107 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #include "chrome/browser/views/frame/aero_glass_non_client_view.h" +#include "chrome/app/theme/theme_resources.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" + +/////////////////////////////////////////////////////////////////////////////// +// WindowResources +// +// An enumeration of bitmap resources used by this window. +enum FramePartBitmap { + FRAME_PART_BITMAP_FIRST = 0, // must be first. + + // Client Edge Border. + FRAME_CLIENT_EDGE_TOP_LEFT, + FRAME_CLIENT_EDGE_TOP, + FRAME_CLIENT_EDGE_TOP_RIGHT, + FRAME_CLIENT_EDGE_RIGHT, + FRAME_CLIENT_EDGE_BOTTOM_RIGHT, + FRAME_CLIENT_EDGE_BOTTOM, + FRAME_CLIENT_EDGE_BOTTOM_LEFT, + FRAME_CLIENT_EDGE_LEFT, + + FRAME_PART_BITMAP_COUNT // Must be last. +}; + +class WindowResources { + public: + virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const = 0; + virtual const ChromeFont& GetTitleFont() const = 0; +}; + +class AeroGlassWindowResources : public WindowResources { + public: + AeroGlassWindowResources() { InitClass(); } + virtual ~AeroGlassWindowResources() { } + + // WindowResources implementation: + virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const { + return standard_frame_bitmaps_[part]; + } + virtual const ChromeFont& GetTitleFont() const { + return title_font_; + } + + private: + static void InitClass() { + static bool initialized = false; + if (!initialized) { + static const int kFramePartBitmapIds[] = { + 0, + IDR_CONTENT_TOP_LEFT_CORNER, IDR_CONTENT_TOP_CENTER, + IDR_CONTENT_TOP_RIGHT_CORNER, IDR_CONTENT_RIGHT_SIDE, + IDR_CONTENT_BOTTOM_RIGHT_CORNER, IDR_CONTENT_BOTTOM_CENTER, + IDR_CONTENT_BOTTOM_LEFT_CORNER, IDR_CONTENT_LEFT_SIDE, + 0 + }; + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { + int id = kFramePartBitmapIds[i]; + if (id != 0) + standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id); + } + title_font_ = + rb.GetFont(ResourceBundle::BaseFont).DeriveFont(1, ChromeFont::BOLD); + initialized = true; + } + } + + static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; + static ChromeFont title_font_; + + DISALLOW_EVIL_CONSTRUCTORS(AeroGlassWindowResources); +}; + +// static +SkBitmap* AeroGlassWindowResources::standard_frame_bitmaps_[]; +ChromeFont AeroGlassWindowResources::title_font_; + +WindowResources* AeroGlassNonClientView::resources_ = NULL; +SkBitmap AeroGlassNonClientView::distributor_logo_; + +static const int kTitleTopOffset = 6; +static const int kTitleBottomSpacing = 6; +static const int kNoTitleTopSpacing = 8; +static const int kWindowHorizontalBorderSize = 2; +static const int kWindowVerticalBorderSize = 2; +static const int kDistributorLogoHorizontalOffset = 7; +static const int kDistributorLogoVerticalOffset = 3; + /////////////////////////////////////////////////////////////////////////////// // AeroGlassNonClientView, public: -AeroGlassNonClientView::AeroGlassNonClientView() { +AeroGlassNonClientView::AeroGlassNonClientView(AeroGlassFrame* frame) + : frame_(frame) { + InitClass(); } AeroGlassNonClientView::~AeroGlassNonClientView() { @@ -44,13 +138,18 @@ AeroGlassNonClientView::~AeroGlassNonClientView() { gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int width, int height) const { - return gfx::Rect(); + int top_margin = CalculateNonClientTopHeight(); + return gfx::Rect(kWindowHorizontalBorderSize, top_margin, + std::max(0, width - (2 * kWindowHorizontalBorderSize)), + std::max(0, height - top_margin - kWindowVerticalBorderSize)); } gfx::Size AeroGlassNonClientView::CalculateWindowSizeForClientSize( int width, int height) const { - return gfx::Size(); + int top_margin = CalculateNonClientTopHeight(); + return gfx::Size(width + (2 * kWindowHorizontalBorderSize), + height + top_margin + kWindowVerticalBorderSize); } CPoint AeroGlassNonClientView::GetSystemMenuPoint() const { @@ -58,7 +157,16 @@ CPoint AeroGlassNonClientView::GetSystemMenuPoint() const { } int AeroGlassNonClientView::NonClientHitTest(const gfx::Point& point) { - return HTCLIENT; + CRect bounds; + CPoint test_point = point.ToPOINT(); + + // First see if it's within the grow box area, since that overlaps the client + // bounds. + int component = frame_->client_view()->NonClientHitTest(point); + if (component != HTNOWHERE) + return component; + + return HTNOWHERE; } void AeroGlassNonClientView::GetWindowMask(const gfx::Size& size, @@ -71,11 +179,151 @@ void AeroGlassNonClientView::EnableClose(bool enable) { /////////////////////////////////////////////////////////////////////////////// // AeroGlassNonClientView, ChromeViews::View overrides: +void AeroGlassNonClientView::Paint(ChromeCanvas* canvas) { + PaintDistributorLogo(canvas); + PaintToolbarBackground(canvas); + PaintClientEdge(canvas); + + // TODO(beng): remove this + gfx::Rect contents_bounds = frame_->GetContentsBounds(); + canvas->FillRectInt(SK_ColorGRAY, contents_bounds.x(), contents_bounds.y(), + contents_bounds.width(), contents_bounds.height()); +} + void AeroGlassNonClientView::Layout() { + LayoutDistributorLogo(); + LayoutClientView(); +} + +void AeroGlassNonClientView::GetPreferredSize(CSize* out) { + DCHECK(out); + frame_->client_view()->GetPreferredSize(out); + out->cx += 2 * kWindowHorizontalBorderSize; + out->cy += CalculateNonClientTopHeight() + kWindowVerticalBorderSize; +} + +void AeroGlassNonClientView::DidChangeBounds(const CRect& previous, + const CRect& current) { + Layout(); } void AeroGlassNonClientView::ViewHierarchyChanged(bool is_add, - ChromeViews::View* parent, - ChromeViews::View* child) { + ChromeViews::View* parent, + ChromeViews::View* child) { + if (is_add && child == this) { + DCHECK(GetViewContainer()); + DCHECK(frame_->client_view()->GetParent() != this); + AddChildView(frame_->client_view()); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// AeroGlassNonClientView, private: + +int AeroGlassNonClientView::CalculateNonClientTopHeight() const { + if (frame_->window_delegate()->ShouldShowWindowTitle()) { + return kTitleTopOffset + resources_->GetTitleFont().height() + + kTitleBottomSpacing; + } + return kNoTitleTopSpacing; +} + +void AeroGlassNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) { + // The distributor logo is only painted when the frame is not maximized. + if (!frame_->IsMaximized() && !frame_->IsMinimized()) { + canvas->DrawBitmapInt(distributor_logo_, logo_bounds_.x(), + logo_bounds_.y()); + } } +void AeroGlassNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) { + if (frame_->IsToolbarVisible() || frame_->IsTabStripVisible()) { + SkBitmap* toolbar_left = + resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); + SkBitmap* toolbar_center = + resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); + SkBitmap* toolbar_right = + resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT); + + gfx::Rect toolbar_bounds = frame_->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(*toolbar_left, + toolbar_bounds.x() - toolbar_left->width(), + toolbar_bounds.y()); + canvas->TileImageInt(*toolbar_center, + toolbar_bounds.x(), toolbar_bounds.y(), + toolbar_bounds.width(), toolbar_center->height()); + canvas->DrawBitmapInt(*toolbar_right, toolbar_bounds.right(), + toolbar_bounds.y()); + } +} + +void AeroGlassNonClientView::PaintClientEdge(ChromeCanvas* canvas) { + 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); + + // 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 = frame_->GetToolbarBounds(); + gfx::Rect client_area_bounds = frame_->GetContentsBounds(); + client_area_bounds.SetRect( + client_area_bounds.x(), + frame_->client_view()->GetY() + toolbar_bounds.bottom() - 1, + client_area_bounds.width(), + std::max(0, GetHeight() - frame_->client_view()->GetY() - + toolbar_bounds.bottom() + 1 - kWindowVerticalBorderSize)); + + canvas->TileImageInt(*right, client_area_bounds.right(), + client_area_bounds.y(), + right->width(), client_area_bounds.height()); + canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(), + client_area_bounds.bottom()); + canvas->TileImageInt(*bottom, client_area_bounds.x(), + client_area_bounds.bottom(), + client_area_bounds.width(), bottom_right->height()); + canvas->DrawBitmapInt(*bottom_left, + client_area_bounds.x() - bottom_left->width(), + client_area_bounds.bottom()); + canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), + client_area_bounds.y(), + left->width(), client_area_bounds.height()); +} + +void AeroGlassNonClientView::LayoutDistributorLogo() { + int logo_w = distributor_logo_.width(); + int logo_h = distributor_logo_.height(); + + int w = GetWidth(); + int mbx = frame_->GetMinimizeButtonOffset(); + + logo_bounds_.SetRect( + GetWidth() - frame_->GetMinimizeButtonOffset() - logo_w, + kDistributorLogoVerticalOffset, logo_w, logo_h); +} + +void AeroGlassNonClientView::LayoutClientView() { + gfx::Rect client_bounds( + CalculateClientAreaBounds(GetWidth(), GetHeight())); + frame_->client_view()->SetBounds(client_bounds.ToRECT()); +} + +// static +void AeroGlassNonClientView::InitClass() { + static bool initialized = false; + if (!initialized) { + resources_ = new AeroGlassWindowResources; + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + distributor_logo_ = *rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO); + initialized = true; + } +} diff --git a/chrome/browser/views/frame/aero_glass_non_client_view.h b/chrome/browser/views/frame/aero_glass_non_client_view.h index 31968e4..eea2e0b 100644 --- a/chrome/browser/views/frame/aero_glass_non_client_view.h +++ b/chrome/browser/views/frame/aero_glass_non_client_view.h @@ -30,12 +30,16 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_NON_CLIENT_VIEW_H_ #define CHROME_BROWSER_VIEWS_FRAME_AERO_GLASS_NON_CLIENT_VIEW_H_ - +#include "chrome/browser/views/frame/aero_glass_frame.h" #include "chrome/views/non_client_view.h" +#include "chrome/views/button.h" + +class WindowResources; class AeroGlassNonClientView : public ChromeViews::NonClientView { public: - AeroGlassNonClientView(); + // Constructs a non-client view for an AeroGlassFrame. + explicit AeroGlassNonClientView(AeroGlassFrame* frame); virtual ~AeroGlassNonClientView(); protected: @@ -49,12 +53,38 @@ class AeroGlassNonClientView : public ChromeViews::NonClientView { virtual void EnableClose(bool enable); // Overridden from ChromeViews::View: + virtual void Paint(ChromeCanvas* canvas); virtual void Layout(); + virtual void GetPreferredSize(CSize* out); + virtual void DidChangeBounds(const CRect& previous, const CRect& current); virtual void ViewHierarchyChanged(bool is_add, ChromeViews::View* parent, ChromeViews::View* child); private: + // Returns the height of the non-client area at the top of the window (the + // title bar, etc). + int CalculateNonClientTopHeight() const; + + // Paint various sub-components of this view. + void PaintDistributorLogo(ChromeCanvas* canvas); + void PaintToolbarBackground(ChromeCanvas* canvas); + void PaintClientEdge(ChromeCanvas* canvas); + + // Layout various sub-components of this view. + void LayoutDistributorLogo(); + void LayoutClientView(); + + // The layout rect of the distributor logo, if visible. + gfx::Rect logo_bounds_; + + // The frame that hosts this view. + AeroGlassFrame* frame_; + + static void InitClass(); + static SkBitmap distributor_logo_; + static WindowResources* resources_; + DISALLOW_EVIL_CONSTRUCTORS(AeroGlassNonClientView); }; diff --git a/chrome/browser/views/frame/browser_view2.cc b/chrome/browser/views/frame/browser_view2.cc index bc74d94..af62ab1 100644 --- a/chrome/browser/views/frame/browser_view2.cc +++ b/chrome/browser/views/frame/browser_view2.cc @@ -119,7 +119,7 @@ StatusBubble* BrowserView2::GetStatusBubble() { } ChromeViews::RootView* BrowserView2::GetRootView() { - // TODO(beng): get rid of this stupid method. + // TODO(beng): Get rid of this stupid method. return View::GetRootView(); } diff --git a/chrome/browser/views/frame/browser_window_factory.cc b/chrome/browser/views/frame/browser_window_factory.cc index 407e215..1897ebcf 100644 --- a/chrome/browser/views/frame/browser_window_factory.cc +++ b/chrome/browser/views/frame/browser_window_factory.cc @@ -31,6 +31,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/frame_util.h" +#include "chrome/browser/views/frame/aero_glass_frame.h" #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/frame/browser_view2.h" @@ -62,27 +63,29 @@ BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser, return window->GetBrowserView(); } -///////////////////////////////////////////////////////////////////////////////
-// BrowserFrame, public:
-
-// static
-BrowserFrame::FrameType BrowserFrame::GetActiveFrameType() {
- return win_util::ShouldUseVistaFrame() ? BrowserFrame::FRAMETYPE_AERO_GLASS
- : BrowserFrame::FRAMETYPE_OPAQUE;
-}
-
-// static
-BrowserFrame* BrowserFrame::CreateForBrowserView(BrowserFrame::FrameType type,
- BrowserView2* browser_view,
- const gfx::Rect& bounds,
- int show_command) {
- if (type == FRAMETYPE_OPAQUE) {
- OpaqueFrame* frame = new OpaqueFrame(browser_view);
- frame->Init(NULL, bounds);
- return frame;
- } else if (type == FRAMETYPE_AERO_GLASS) {
- NOTREACHED() << "Aero/Glass not supported yet by magic_browzR switch";
- }
- NOTREACHED() << "Unsupported frame type";
- return NULL;
-}
+/////////////////////////////////////////////////////////////////////////////// +// BrowserFrame, public: + +// static +BrowserFrame::FrameType BrowserFrame::GetActiveFrameType() { + return win_util::ShouldUseVistaFrame() ? BrowserFrame::FRAMETYPE_AERO_GLASS + : BrowserFrame::FRAMETYPE_OPAQUE; +} + +// static +BrowserFrame* BrowserFrame::CreateForBrowserView(BrowserFrame::FrameType type, + BrowserView2* browser_view, + const gfx::Rect& bounds, + int show_command) { + if (type == FRAMETYPE_OPAQUE) { + OpaqueFrame* frame = new OpaqueFrame(browser_view); + frame->Init(NULL, bounds); + return frame; + } else if (type == FRAMETYPE_AERO_GLASS) { + AeroGlassFrame* frame = new AeroGlassFrame(browser_view); + frame->Init(bounds); + return frame; + } + NOTREACHED() << "Unsupported frame type"; + return NULL; +} diff --git a/chrome/views/custom_frame_window.cc b/chrome/views/custom_frame_window.cc index 928947e..0acf4b3 100644 --- a/chrome/views/custom_frame_window.cc +++ b/chrome/views/custom_frame_window.cc @@ -833,16 +833,16 @@ void DefaultNonClientView::InitClass() { CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate) : Window(window_delegate), - non_client_view_(new DefaultNonClientView(this)), is_active_(false) { InitClass(); + non_client_view_ = new DefaultNonClientView(this); } CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate, NonClientView* non_client_view) - : Window(window_delegate), - non_client_view_(non_client_view) { + : Window(window_delegate) { InitClass(); + non_client_view_ = non_client_view; } CustomFrameWindow::~CustomFrameWindow() { diff --git a/chrome/views/custom_frame_window.h b/chrome/views/custom_frame_window.h index d61b6b8..b94cde3 100644 --- a/chrome/views/custom_frame_window.h +++ b/chrome/views/custom_frame_window.h @@ -86,12 +86,6 @@ class CustomFrameWindow : public Window { virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message); virtual void OnSize(UINT param, const CSize& size); - // The View that provides the non-client area of the window (title bar, - // window controls, sizing borders etc). To use an implementation other than - // the default, this class must be subclassed and this value set to the - // desired implementation before calling |Init|. - NonClientView* non_client_view_; - private: // Shows the system menu at the specified screen point. void RunSystemMenu(const CPoint& point); diff --git a/chrome/views/window.cc b/chrome/views/window.cc index 4ace937..7047d84 100644 --- a/chrome/views/window.cc +++ b/chrome/views/window.cc @@ -37,6 +37,7 @@ #include "chrome/common/resource_bundle.h" #include "chrome/common/win_util.h" #include "chrome/views/custom_frame_window.h" +#include "chrome/views/non_client_view.h" #include "chrome/views/window_delegate.h" #include "generated_resources.h" @@ -251,6 +252,7 @@ Window::Window(WindowDelegate* window_delegate) : HWNDViewContainer(), focus_on_creation_(true), window_delegate_(window_delegate), + non_client_view_(NULL), client_view_(NULL), owning_hwnd_(NULL), minimum_size_(100, 100), @@ -300,12 +302,21 @@ void Window::Init(HWND parent, const gfx::Rect& bounds) { void Window::SetClientView(ClientView* client_view) { DCHECK(client_view && !client_view_ && GetHWND()); client_view_ = client_view; - HWNDViewContainer::SetContentsView(client_view_); + if (non_client_view_) { + // This will trigger the ClientView to be added by the non-client view. + HWNDViewContainer::SetContentsView(non_client_view_); + } else { + HWNDViewContainer::SetContentsView(client_view_); + } } void Window::SizeWindowToDefault() { CSize pref(0, 0); - client_view_->GetPreferredSize(&pref); + if (non_client_view_) { + non_client_view_->GetPreferredSize(&pref); + } else { + client_view_->GetPreferredSize(&pref); + } DCHECK(pref.cx > 0 && pref.cy > 0); // CenterAndSizeWindow adjusts the window size to accommodate the non-client // area. @@ -343,7 +354,12 @@ LRESULT Window::OnNCHitTest(const CPoint& point) { // of the non-client area. CPoint temp = point; MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); - int component = client_view_->NonClientHitTest(gfx::Point(temp)); + int component = HTNOWHERE; + if (non_client_view_) { + component = non_client_view_->NonClientHitTest(gfx::Point(temp)); + } else { + component = client_view_->NonClientHitTest(gfx::Point(temp)); + } if (component != HTNOWHERE) return component; diff --git a/chrome/views/window.h b/chrome/views/window.h index a941cb2..d098938 100644 --- a/chrome/views/window.h +++ b/chrome/views/window.h @@ -44,6 +44,7 @@ namespace ChromeViews { class ClientView; class Client; +class NonClientView; class WindowDelegate; //////////////////////////////////////////////////////////////////////////////// @@ -174,6 +175,12 @@ class Window : public HWNDViewContainer { virtual void OnSize(UINT size_param, const CSize& new_size); virtual void OnSysCommand(UINT notification_code, CPoint click); + // The View that provides the non-client area of the window (title bar, + // window controls, sizing borders etc). To use an implementation other than + // the default, this class must be subclassed and this value set to the + // desired implementation before calling |Init|. + NonClientView* non_client_view_; + private: // Set the window as modal (by disabling all the other windows). void BecomeModal(); |