diff options
-rw-r--r-- | chrome/browser/browser.vcproj | 8 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_frame.h | 27 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view2.cc | 489 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view2.h | 195 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_window_factory.cc | 36 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_frame.cc | 24 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_frame.h | 24 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_non_client_view.cc | 811 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_non_client_view.h | 79 | ||||
-rw-r--r-- | chrome/browser/views/toolbar_view.cc | 10 | ||||
-rw-r--r-- | chrome/browser/views/toolbar_view.h | 1 | ||||
-rw-r--r-- | chrome/views/client_view.cc | 12 | ||||
-rw-r--r-- | chrome/views/client_view.h | 9 |
13 files changed, 1709 insertions, 16 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index f635dcc..835d78c 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -1721,6 +1721,14 @@ > </File> <File + RelativePath=".\views\frame\browser_view2.cc" + > + </File> + <File + RelativePath=".\views\frame\browser_view2.h" + > + </File> + <File RelativePath=".\views\frame\browser_window_factory.cc" > </File> diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h index e71f9dd..55b22fe 100644 --- a/chrome/browser/views/frame/browser_frame.h +++ b/chrome/browser/views/frame/browser_frame.h @@ -30,6 +30,14 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_ +class BrowserView2; +namespace ChromeViews { +class Window; +} +namespace gfx { +class Rect; +} + /////////////////////////////////////////////////////////////////////////////// // BrowserFrame // @@ -39,6 +47,25 @@ // class BrowserFrame { public: + // Returns the ChromeViews::Window associated with this frame. + virtual ChromeViews::Window* GetWindow() = 0; + + enum FrameType { + FRAMETYPE_OPAQUE, + FRAMETYPE_AERO_GLASS + }; + + // Returns the FrameType that should be constructed given the current system + // settings. + static FrameType GetActiveFrameType(); + + // Creates a BrowserFrame instance for the specified FrameType and + // BrowserView. + static BrowserFrame* CreateForBrowserView(FrameType type, + BrowserView2* browser_view, + const gfx::Rect& bounds, + int show_command); + }; #endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_ diff --git a/chrome/browser/views/frame/browser_view2.cc b/chrome/browser/views/frame/browser_view2.cc new file mode 100644 index 0000000..bc74d94 --- /dev/null +++ b/chrome/browser/views/frame/browser_view2.cc @@ -0,0 +1,489 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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/browser_view2.h" + +#include "chrome/browser/browser.h" +#include "chrome/browser/tab_contents_container_view.h" +#include "chrome/browser/view_ids.h" +#include "chrome/browser/views/bookmark_bar_view.h" +#include "chrome/browser/views/download_shelf_view.h" +#include "chrome/browser/views/frame/browser_frame.h" +#include "chrome/browser/views/status_bubble.h" +#include "chrome/browser/views/toolbar_view.h" +#include "chrome/common/l10n_util.h" +#include "generated_resources.h" + +// static +static const int kToolbarTabStripVerticalOverlap = 3; +static const int kStatusBubbleHeight = 20; +static const int kStatusBubbleOffset = 2; + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2, public: + +BrowserView2::BrowserView2(Browser* browser) + : ClientView(NULL, NULL), + frame_(NULL), + browser_(browser), + active_bookmark_bar_(NULL), + active_info_bar_(NULL), + active_download_shelf_(NULL), + toolbar_(NULL), + contents_container_(NULL), + initialized_(false) { +} + +BrowserView2::~BrowserView2() { +} + +gfx::Rect BrowserView2::GetToolbarBounds() const { + CRect bounds; + toolbar_->GetBounds(&bounds); + return gfx::Rect(bounds); +} + +gfx::Rect BrowserView2::GetClientAreaBounds() const { + CRect bounds; + contents_container_->GetBounds(&bounds); + bounds.OffsetRect(GetX(), GetY()); + return gfx::Rect(bounds); +} + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2, BrowserWindow implementation: + +void BrowserView2::Init() { + SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); + + toolbar_ = new BrowserToolbarView(browser_->controller(), browser_.get()); + AddChildView(toolbar_); + toolbar_->SetID(VIEW_ID_TOOLBAR); + toolbar_->Init(browser_->profile()); + toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR)); + + contents_container_ = new TabContentsContainerView; + set_contents_view(contents_container_); + AddChildView(contents_container_); + + status_bubble_.reset(new StatusBubble(GetViewContainer())); +} + +void BrowserView2::Show(int command, bool adjust_to_fit) { + frame_->GetWindow()->Show(); +} + +void BrowserView2::BrowserDidPaint(HRGN region) { +} + +void BrowserView2::Close() { + frame_->GetWindow()->Close(); +} + +void* BrowserView2::GetPlatformID() { + return GetViewContainer()->GetHWND(); +} + +TabStrip* BrowserView2::GetTabStrip() const { + return NULL; +} + +StatusBubble* BrowserView2::GetStatusBubble() { + return status_bubble_.get(); +} + +ChromeViews::RootView* BrowserView2::GetRootView() { + // TODO(beng): get rid of this stupid method. + return View::GetRootView(); +} + +void BrowserView2::ShelfVisibilityChanged() { + UpdateUIForContents(browser_->GetSelectedTabContents()); +} + +void BrowserView2::SelectedTabToolbarSizeChanged(bool is_animating) { + if (is_animating) { + contents_container_->set_fast_resize(true); + ShelfVisibilityChanged(); + contents_container_->set_fast_resize(false); + } else { + ShelfVisibilityChanged(); + contents_container_->UpdateHWNDBounds(); + } +} + +void BrowserView2::UpdateTitleBar() { +} + +void BrowserView2::SetWindowTitle(const std::wstring& title) { +} + +void BrowserView2::Activate() { +} + +void BrowserView2::FlashFrame() { +} + +void BrowserView2::ShowTabContents(TabContents* contents) { + contents_container_->SetTabContents(contents); + + // Force a LoadingStateChanged notification because the TabContents + // could be loading (such as when the user unconstrains a tab. + if (contents && contents->delegate()) + contents->delegate()->LoadingStateChanged(contents); + + UpdateUIForContents(contents); +} + +void BrowserView2::ContinueDetachConstrainedWindowDrag( + const gfx::Point& mouse_pt, + int frame_component) { +} + +void BrowserView2::SizeToContents(const gfx::Rect& contents_bounds) { +} + +void BrowserView2::SetAcceleratorTable( + std::map<ChromeViews::Accelerator, int>* accelerator_table) { +} + +void BrowserView2::ValidateThrobber() { +} + +gfx::Rect BrowserView2::GetNormalBounds() { + return gfx::Rect(); +} + +bool BrowserView2::IsMaximized() { + return false; +} + +gfx::Rect BrowserView2::GetBoundsForContentBounds( + const gfx::Rect content_rect) { + return gfx::Rect(); +} + +void BrowserView2::DetachFromBrowser() { +} + +void BrowserView2::InfoBubbleShowing() { +} + +void BrowserView2::InfoBubbleClosing() { +} + +ToolbarStarToggle* BrowserView2::GetStarButton() const { + return toolbar_->star_button(); +} + +LocationBarView* BrowserView2::GetLocationBarView() const { + return toolbar_->GetLocationBarView(); +} + +GoButton* BrowserView2::GetGoButton() const { + return toolbar_->GetGoButton(); +} + +BookmarkBarView* BrowserView2::GetBookmarkBarView() { + TabContents* current_tab = browser_->GetSelectedTabContents(); + if (!bookmark_bar_view_.get()) { + bookmark_bar_view_.reset(new BookmarkBarView(current_tab->profile(), + browser_.get())); + bookmark_bar_view_->SetParentOwned(false); + } else { + bookmark_bar_view_->SetProfile(current_tab->profile()); + } + bookmark_bar_view_->SetPageNavigator(current_tab); + return bookmark_bar_view_.get(); +} + +BrowserView* BrowserView2::GetBrowserView() const { + return NULL; +} + +void BrowserView2::Update(TabContents* contents, bool should_restore_state) { + toolbar_->Update(contents, should_restore_state); +} + +void BrowserView2::ProfileChanged(Profile* profile) { + toolbar_->SetProfile(profile); +} + +void BrowserView2::FocusToolbar() { + toolbar_->RequestFocus(); +} + +void BrowserView2::DestroyBrowser() { +} + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2, ChromeViews::WindowDelegate implementation: + +bool BrowserView2::CanResize() const { + return true; +} + +bool BrowserView2::CanMaximize() const { + return true; +} + +bool BrowserView2::IsModal() const { + return false; +} + +std::wstring BrowserView2::GetWindowTitle() const { + return L"Magic browzR"; +} + +ChromeViews::View* BrowserView2::GetInitiallyFocusedView() const { + return NULL; +} + +bool BrowserView2::ShouldShowWindowTitle() const { + return false; +} + +SkBitmap BrowserView2::GetWindowIcon() { + return SkBitmap(); +} + +bool BrowserView2::ShouldShowWindowIcon() const { + return false; +} + +void BrowserView2::ExecuteWindowsCommand(int command_id) { + if (browser_->SupportsCommand(command_id) && + browser_->IsCommandEnabled(command_id)) { + browser_->ExecuteCommand(command_id); + } +} + +void BrowserView2::WindowClosing() { +} + +ChromeViews::View* BrowserView2::GetContentsView() { + return NULL; +} + +ChromeViews::ClientView* BrowserView2::CreateClientView( + ChromeViews::Window* window) { + set_window(window); + return this; +} + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2, ChromeViews::ClientView overrides: + +bool BrowserView2::CanClose() const { + return true; +} + +int BrowserView2::NonClientHitTest(const gfx::Point& point) { + return HTNOWHERE; +} + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2, ChromeViews::View overrides: + +void BrowserView2::Layout() { + int top = LayoutTabStrip(); + top = LayoutToolbar(top); + top = LayoutBookmarkAndInfoBars(top); + int bottom = LayoutDownloadShelf(); + LayoutTabContents(top, bottom); + LayoutStatusBubble(bottom); + SchedulePaint(); +} + +void BrowserView2::DidChangeBounds(const CRect& previous, + const CRect& current) { + Layout(); +} + +void BrowserView2::ViewHierarchyChanged(bool is_add, + ChromeViews::View* parent, + ChromeViews::View* child) { + if (is_add && child == this && GetViewContainer() && !initialized_) { + Init(); + initialized_ = true; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2, private: + +int BrowserView2::LayoutTabStrip() { + return 40; // TODO(beng): hook this up. +} + +int BrowserView2::LayoutToolbar(int top) { + CSize ps; + toolbar_->GetPreferredSize(&ps); + int toolbar_y = top - kToolbarTabStripVerticalOverlap; + toolbar_->SetBounds(0, toolbar_y, GetWidth(), ps.cy); + return toolbar_y + ps.cy; + // TODO(beng): support toolbar-less windows. +} + +int BrowserView2::LayoutBookmarkAndInfoBars(int top) { + // If we have an Info-bar showing, and we're showing the New Tab Page, and + // the Bookmark bar isn't visible on all tabs, then we need to show the Info + // bar _above_ the Bookmark bar, since the Bookmark bar is styled to look + // like it's part of the New Tab Page... + if (active_info_bar_ && active_bookmark_bar_ && + bookmark_bar_view_->IsNewTabPage() && + !bookmark_bar_view_->IsAlwaysShown()) { + top = LayoutInfoBar(top); + return LayoutBookmarkBar(top); + } + // Otherwise, Bookmark bar first, Info bar second. + top = LayoutBookmarkBar(top); + return LayoutInfoBar(top); +} + +int BrowserView2::LayoutBookmarkBar(int top) { + if (active_bookmark_bar_) { + CSize ps; + active_bookmark_bar_->GetPreferredSize(&ps); + active_bookmark_bar_->SetBounds(0, top, GetWidth(), ps.cy); + top += ps.cy; + } + return top; +} +int BrowserView2::LayoutInfoBar(int top) { + if (active_info_bar_) { + CSize ps; + active_info_bar_->GetPreferredSize(&ps); + active_info_bar_->SetBounds(0, top, GetWidth(), ps.cy); + top += ps.cy; + } + return top; +} + +void BrowserView2::LayoutTabContents(int top, int bottom) { + contents_container_->SetBounds(0, top, GetWidth(), bottom - top); +} + +int BrowserView2::LayoutDownloadShelf() { + int bottom = GetHeight(); + if (active_download_shelf_) { + CSize ps; + active_download_shelf_->GetPreferredSize(&ps); + active_download_shelf_->SetBounds(0, bottom - ps.cy, GetWidth(), ps.cy); + bottom -= ps.cy; + } + return bottom; +} + +void BrowserView2::LayoutStatusBubble(int top) { + int status_bubble_y = + top - kStatusBubbleHeight + kStatusBubbleOffset + GetY(); + status_bubble_->SetBounds(kStatusBubbleOffset, status_bubble_y, + GetWidth() / 3, kStatusBubbleHeight); +} + +void BrowserView2::UpdateUIForContents(TabContents* contents) { + // Coalesce layouts. + bool changed = false; + + ChromeViews::View* new_shelf = NULL; + if (contents && contents->IsDownloadShelfVisible()) + new_shelf = contents->GetDownloadShelfView(); + changed |= UpdateChildViewAndLayout(new_shelf, &active_download_shelf_); + + ChromeViews::View* new_info_bar = NULL; + if (contents && contents->IsInfoBarVisible()) + new_info_bar = contents->GetInfoBarView(); + changed |= UpdateChildViewAndLayout(new_info_bar, &active_info_bar_); + + ChromeViews::View* new_bookmark_bar = NULL; + if (contents) // TODO(beng): check for support of BookmarkBar + new_bookmark_bar = GetBookmarkBarView(); + changed |= UpdateChildViewAndLayout(new_bookmark_bar, &active_bookmark_bar_); + + // Only do a Layout if the current contents is non-NULL. We assume that if + // the contents is NULL, we're either being destroyed, or ShowTabContents is + // going to be invoked with a non-NULL TabContents again so that there is no + // need to do a Layout now. + if (changed && contents) + Layout(); +} + +bool BrowserView2::UpdateChildViewAndLayout(ChromeViews::View* new_view, + ChromeViews::View** old_view) { + DCHECK(old_view); + if (*old_view == new_view) { + // The views haven't changed, if the views pref changed schedule a layout. + if (new_view) { + CSize pref_size; + new_view->GetPreferredSize(&pref_size); + if (pref_size.cy != new_view->GetHeight()) + return true; + } + return false; + } + + // The views differ, and one may be null (but not both). Remove the old + // view (if it non-null), and add the new one (if it is non-null). If the + // height has changed, schedule a layout, otherwise reuse the existing + // bounds to avoid scheduling a layout. + + int current_height = 0; + if (*old_view) { + current_height = (*old_view)->GetHeight(); + RemoveChildView(*old_view); + } + + int new_height = 0; + if (new_view) { + CSize preferred_size; + new_view->GetPreferredSize(&preferred_size); + new_height = preferred_size.cy; + AddChildView(new_view); + } + bool changed = false; + if (new_height != current_height) { + changed = true; + } else if (new_view && *old_view) { + // The view changed, but the new view wants the same size, give it the + // bounds of the last view and have it repaint. + CRect last_bounds; + (*old_view)->GetBounds(&last_bounds); + new_view->SetBounds(last_bounds.left, last_bounds.top, + last_bounds.Width(), last_bounds.Height()); + new_view->SchedulePaint(); + } else if (new_view) { + DCHECK(new_height == 0); + // The heights are the same, but the old view is null. This only happens + // when the height is zero. Zero out the bounds. + new_view->SetBounds(0, 0, 0, 0); + } + *old_view = new_view; + return changed; +} diff --git a/chrome/browser/views/frame/browser_view2.h b/chrome/browser/views/frame/browser_view2.h new file mode 100644 index 0000000..52973ef --- /dev/null +++ b/chrome/browser/views/frame/browser_view2.h @@ -0,0 +1,195 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW2_H_ +#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW2_H_ + +#include "chrome/browser/browser_window.h" +#include "chrome/browser/views/frame/browser_frame.h" +#include "chrome/views/client_view.h" +#include "chrome/views/window_delegate.h" + +// NOTE: For more information about the objects and files in this directory, +// view: https://sites.google.com/a/google.com/the-chrome-project/developers/design-documents/browser-window + +class BookmarkBarView; +class Browser; +class BrowserToolbarView; +class StatusBubble; +class TabContentsContainerView; + +/////////////////////////////////////////////////////////////////////////////// +// BrowserView2 +// +// A ClientView subclass that provides the contents of a browser window, +// including the TabStrip, toolbars, download shelves, the content area etc. +// +class BrowserView2 : public BrowserWindow, + public ChromeViews::WindowDelegate, + public ChromeViews::ClientView { + public: + explicit BrowserView2(Browser* browser); + virtual ~BrowserView2(); + + void set_frame(BrowserFrame* frame) { frame_ = frame; } + + // Returns the bounds of the toolbar, in BrowserView2 coordinates. + gfx::Rect GetToolbarBounds() const; + + // Returns the bounds of the content area, in the coordinates of the + // BrowserView2's parent. + gfx::Rect GetClientAreaBounds() const; + + // Overridden from BrowserWindow: + virtual void Init(); + virtual void Show(int command, bool adjust_to_fit); + virtual void BrowserDidPaint(HRGN region); + virtual void Close(); + virtual void* GetPlatformID(); + virtual TabStrip* GetTabStrip() const; + virtual StatusBubble* GetStatusBubble(); + virtual ChromeViews::RootView* GetRootView(); + virtual void ShelfVisibilityChanged(); + virtual void SelectedTabToolbarSizeChanged(bool is_animating); + virtual void UpdateTitleBar(); + virtual void SetWindowTitle(const std::wstring& title); + virtual void Activate(); + virtual void FlashFrame(); + virtual void ShowTabContents(TabContents* contents); + virtual void ContinueDetachConstrainedWindowDrag( + const gfx::Point& mouse_pt, + int frame_component); + virtual void SizeToContents(const gfx::Rect& contents_bounds); + virtual void SetAcceleratorTable( + std::map<ChromeViews::Accelerator, int>* accelerator_table); + virtual void ValidateThrobber(); + virtual gfx::Rect GetNormalBounds(); + virtual bool IsMaximized(); + virtual gfx::Rect GetBoundsForContentBounds(const gfx::Rect content_rect); + virtual void DetachFromBrowser(); + virtual void InfoBubbleShowing(); + virtual void InfoBubbleClosing(); + virtual ToolbarStarToggle* GetStarButton() const; + virtual LocationBarView* GetLocationBarView() const; + virtual GoButton* GetGoButton() const; + virtual BookmarkBarView* GetBookmarkBarView(); + virtual BrowserView* GetBrowserView() const; + virtual void Update(TabContents* contents, bool should_restore_state); + virtual void ProfileChanged(Profile* profile); + virtual void FocusToolbar(); + virtual void DestroyBrowser(); + + // Overridden from ChromeViews::WindowDelegate: + virtual bool CanResize() const; + virtual bool CanMaximize() const; + virtual bool IsModal() const; + virtual std::wstring GetWindowTitle() const; + virtual ChromeViews::View* GetInitiallyFocusedView() const; + virtual bool ShouldShowWindowTitle() const; + virtual SkBitmap GetWindowIcon(); + virtual bool ShouldShowWindowIcon() const; + virtual void ExecuteWindowsCommand(int command_id); + virtual void WindowClosing(); + virtual ChromeViews::View* GetContentsView(); + virtual ChromeViews::ClientView* CreateClientView( + ChromeViews::Window* window); + + // Overridden from ChromeViews::ClientView: + virtual bool CanClose() const; + virtual int NonClientHitTest(const gfx::Point& point); + + // Overridden from ChromeViews::View: + virtual void Layout(); + virtual void DidChangeBounds(const CRect& previous, const CRect& current); + virtual void ViewHierarchyChanged(bool is_add, + ChromeViews::View* parent, + ChromeViews::View* child); + + private: + // Layout the TabStrip, returns the coordinate of the bottom of the TabStrip, + // for laying out subsequent controls. + int LayoutTabStrip(); + // Layout the following controls, starting at |top|, returns the coordinate + // of the bottom of the control, for laying out the next control. + int LayoutToolbar(int top); + int LayoutBookmarkAndInfoBars(int top); + int LayoutBookmarkBar(int top); + int LayoutInfoBar(int top); + // Layout the TabContents container, between the coordinates |top| and + // |bottom|. + void LayoutTabContents(int top, int bottom); + // Layout the Download Shelf, returns the coordinate of the top of the\ + // control, for laying out the previous control. + int LayoutDownloadShelf(); + // Layout the Status Bubble. + void LayoutStatusBubble(int top); + + // Updates various optional child Views, e.g. Bookmarks Bar, Info Bar or the + // Download Shelf in response to a change notification from the specified + // |contents|. + void UpdateUIForContents(TabContents* contents); + + // Updates an optional child View, e.g. Bookmarks Bar, Info Bar, Download + // Shelf. If |*old_view| differs from new_view, the old_view is removed and + // the new_view is added. This is intended to be used when swapping in/out + // child views that are referenced via a field. + // Returns true if anything was changed, and a re-Layout is now required. + bool UpdateChildViewAndLayout(ChromeViews::View* new_view, + ChromeViews::View** old_view); + + // The BrowserFrame that hosts this view. + BrowserFrame* frame_; + + // The Browser object we are associated with. + scoped_ptr<Browser> browser_; + + // Tool/Info bars that we are currently showing. Used for layout. + ChromeViews::View* active_bookmark_bar_; + ChromeViews::View* active_info_bar_; + ChromeViews::View* active_download_shelf_; + + // The Toolbar containing the navigation buttons, menus and the address bar. + BrowserToolbarView* toolbar_; + + // The Bookmark Bar View for this window. Lazily created. + scoped_ptr<BookmarkBarView> bookmark_bar_view_; + + // The view that contains the selected TabContents. + TabContentsContainerView* contents_container_; + + // The Status information bubble that appears at the bottom of the window. + scoped_ptr<StatusBubble> status_bubble_; + + // True if we have already been initialized. + bool initialized_; + + DISALLOW_EVIL_CONSTRUCTORS(BrowserView2); +}; + +#endif // #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW2_H_ diff --git a/chrome/browser/views/frame/browser_window_factory.cc b/chrome/browser/views/frame/browser_window_factory.cc index 0742245..407e215 100644 --- a/chrome/browser/views/frame/browser_window_factory.cc +++ b/chrome/browser/views/frame/browser_window_factory.cc @@ -27,10 +27,15 @@ // (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 "base/command_line.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/frame_util.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" +#include "chrome/browser/views/frame/opaque_frame.h" +#include "chrome/common/win_util.h" /////////////////////////////////////////////////////////////////////////////// // BrowserWindow, public: @@ -46,7 +51,38 @@ BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser, // However BrowserView is the one that Browser has a ref to, and // calls that BrowserView can't perform directly are passed on to // its frame. Eventually this will be better, I promise. + CommandLine parsed_command_line; + if (parsed_command_line.HasSwitch(L"magic_browzR")) { + BrowserView2* browser_view = new BrowserView2(browser); + BrowserFrame::CreateForBrowserView(BrowserFrame::GetActiveFrameType(), + browser_view, bounds, show_command); + return browser_view; + } BrowserWindow* window = FrameUtil::CreateBrowserWindow(bounds, 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;
+}
diff --git a/chrome/browser/views/frame/opaque_frame.cc b/chrome/browser/views/frame/opaque_frame.cc index 9b65795..702c650 100644 --- a/chrome/browser/views/frame/opaque_frame.cc +++ b/chrome/browser/views/frame/opaque_frame.cc @@ -29,11 +29,33 @@ #include "chrome/browser/views/frame/opaque_frame.h" +#include "chrome/browser/views/frame/browser_view2.h" +#include "chrome/browser/views/frame/opaque_non_client_view.h" +#include "chrome/views/window_delegate.h" + /////////////////////////////////////////////////////////////////////////////// // OpaqueFrame, public: -OpaqueFrame::OpaqueFrame() : CustomFrameWindow(NULL, NULL) { +OpaqueFrame::OpaqueFrame(BrowserView2* browser_view) + : CustomFrameWindow(browser_view, new OpaqueNonClientView(this, false)), + browser_view_(browser_view) { + browser_view_->set_frame(this); } OpaqueFrame::~OpaqueFrame() { } + +gfx::Rect OpaqueFrame::GetToolbarBounds() const { + return browser_view_->GetToolbarBounds(); +} + +gfx::Rect OpaqueFrame::GetContentsBounds() const { + return browser_view_->GetClientAreaBounds(); +} + +/////////////////////////////////////////////////////////////////////////////// +// OpaqueFrame, BrowserFrame implementation: + +ChromeViews::Window* OpaqueFrame::GetWindow() { + return this; +} diff --git a/chrome/browser/views/frame/opaque_frame.h b/chrome/browser/views/frame/opaque_frame.h index 896729b..78b6475 100644 --- a/chrome/browser/views/frame/opaque_frame.h +++ b/chrome/browser/views/frame/opaque_frame.h @@ -30,8 +30,14 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_FRAME_H_ #define CHROME_BROWSER_VIEWS_FRAME_OPAQUE_FRAME_H_ +#include "chrome/browser/views/frame/browser_frame.h" #include "chrome/views/custom_frame_window.h" +class BrowserView2; +namespace ChromeViews { +class Window; +} + /////////////////////////////////////////////////////////////////////////////// // OpaqueFrame // @@ -40,12 +46,26 @@ // Vista when DWM desktop compositing is disabled. The window title and // borders are provided with bitmaps. // -class OpaqueFrame : public ChromeViews::CustomFrameWindow { +class OpaqueFrame : public BrowserFrame, + public ChromeViews::CustomFrameWindow { public: - OpaqueFrame(); + explicit OpaqueFrame(BrowserView2* browser_view); virtual ~OpaqueFrame(); + 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; + + // Overridden from BrowserFrame: + virtual ChromeViews::Window* GetWindow(); + private: + // The BrowserView2 is our ClientView. This is a pointer to it. + BrowserView2* browser_view_; + DISALLOW_EVIL_CONSTRUCTORS(OpaqueFrame); }; diff --git a/chrome/browser/views/frame/opaque_non_client_view.cc b/chrome/browser/views/frame/opaque_non_client_view.cc index 7504b3c..3378d36 100644 --- a/chrome/browser/views/frame/opaque_non_client_view.cc +++ b/chrome/browser/views/frame/opaque_non_client_view.cc @@ -29,52 +29,853 @@ #include "chrome/browser/views/frame/opaque_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" + +/////////////////////////////////////////////////////////////////////////////// +// WindowResources +// +// An enumeration of bitmap resources used by this window. +enum FramePartBitmap { + FRAME_PART_BITMAP_FIRST = 0, // must be first. + + // Window Controls. + FRAME_CLOSE_BUTTON_ICON, + FRAME_CLOSE_BUTTON_ICON_H, + FRAME_CLOSE_BUTTON_ICON_P, + FRAME_CLOSE_BUTTON_ICON_SA, + FRAME_CLOSE_BUTTON_ICON_SA_H, + FRAME_CLOSE_BUTTON_ICON_SA_P, + FRAME_RESTORE_BUTTON_ICON, + FRAME_RESTORE_BUTTON_ICON_H, + FRAME_RESTORE_BUTTON_ICON_P, + FRAME_MAXIMIZE_BUTTON_ICON, + FRAME_MAXIMIZE_BUTTON_ICON_H, + FRAME_MAXIMIZE_BUTTON_ICON_P, + FRAME_MINIMIZE_BUTTON_ICON, + FRAME_MINIMIZE_BUTTON_ICON_H, + FRAME_MINIMIZE_BUTTON_ICON_P, + + // Window Frame Border. + FRAME_BOTTOM_EDGE, + FRAME_BOTTOM_LEFT_CORNER, + FRAME_BOTTOM_RIGHT_CORNER, + FRAME_LEFT_EDGE, + FRAME_RIGHT_EDGE, + FRAME_TOP_EDGE, + FRAME_TOP_LEFT_CORNER, + FRAME_TOP_RIGHT_CORNER, + + // Window Maximized Border. + FRAME_MAXIMIZED_TOP_EDGE, + FRAME_MAXIMIZED_BOTTOM_EDGE, + + // 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; + SkColor title_color() const { return SK_ColorWHITE; } +}; + +class ActiveWindowResources : public WindowResources { + public: + ActiveWindowResources() { InitClass(); } + virtual ~ActiveWindowResources() { } + + // 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_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, + IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, + IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, + IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, + IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, + IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER, + IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE, + IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER, + IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER, + IDR_WINDOW_TOP_CENTER, IDR_WINDOW_BOTTOM_CENTER, + 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(ActiveWindowResources); +}; + +class InactiveWindowResources : public WindowResources { + public: + InactiveWindowResources() { InitClass(); } + virtual ~InactiveWindowResources() { } + + // 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_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, + IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, + IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, + IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, + IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, + IDR_DEWINDOW_BOTTOM_CENTER, IDR_DEWINDOW_BOTTOM_LEFT_CORNER, + IDR_DEWINDOW_BOTTOM_RIGHT_CORNER, IDR_DEWINDOW_LEFT_SIDE, + IDR_DEWINDOW_RIGHT_SIDE, IDR_DEWINDOW_TOP_CENTER, + IDR_DEWINDOW_TOP_LEFT_CORNER, IDR_DEWINDOW_TOP_RIGHT_CORNER, + IDR_DEWINDOW_TOP_CENTER, IDR_DEWINDOW_BOTTOM_CENTER, + 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(InactiveWindowResources); +}; + +class OTRActiveWindowResources : public WindowResources { + public: + OTRActiveWindowResources() { InitClass(); } + virtual ~OTRActiveWindowResources() { } + + // 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_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, + IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, + IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, + IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, + IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, + IDR_WINDOW_BOTTOM_CENTER_OTR, IDR_WINDOW_BOTTOM_LEFT_CORNER_OTR, + IDR_WINDOW_BOTTOM_RIGHT_CORNER_OTR, IDR_WINDOW_LEFT_SIDE_OTR, + IDR_WINDOW_RIGHT_SIDE_OTR, IDR_WINDOW_TOP_CENTER_OTR, + IDR_WINDOW_TOP_LEFT_CORNER_OTR, IDR_WINDOW_TOP_RIGHT_CORNER_OTR, + IDR_WINDOW_TOP_CENTER_OTR, IDR_WINDOW_BOTTOM_CENTER_OTR, + 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(OTRActiveWindowResources); +}; + +class OTRInactiveWindowResources : public WindowResources { + public: + OTRInactiveWindowResources() { InitClass(); } + virtual ~OTRInactiveWindowResources() { } + + // 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_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, + IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, + IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, + IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, + IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, + IDR_DEWINDOW_BOTTOM_CENTER_OTR, IDR_DEWINDOW_BOTTOM_LEFT_CORNER_OTR, + IDR_DEWINDOW_BOTTOM_RIGHT_CORNER_OTR, IDR_DEWINDOW_LEFT_SIDE_OTR, + IDR_DEWINDOW_RIGHT_SIDE_OTR, IDR_DEWINDOW_TOP_CENTER_OTR, + IDR_DEWINDOW_TOP_LEFT_CORNER_OTR, + IDR_DEWINDOW_TOP_RIGHT_CORNER_OTR, + IDR_DEWINDOW_TOP_CENTER_OTR, IDR_DEWINDOW_BOTTOM_CENTER_OTR, + 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(OTRInactiveWindowResources); +}; +// static +SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[]; +ChromeFont ActiveWindowResources::title_font_; +SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[]; +ChromeFont InactiveWindowResources::title_font_; +SkBitmap* OTRActiveWindowResources::standard_frame_bitmaps_[]; +ChromeFont OTRActiveWindowResources::title_font_; +SkBitmap* OTRInactiveWindowResources::standard_frame_bitmaps_[]; +ChromeFont OTRInactiveWindowResources::title_font_; + +WindowResources* OpaqueNonClientView::active_resources_ = NULL; +WindowResources* OpaqueNonClientView::inactive_resources_ = NULL; +WindowResources* OpaqueNonClientView::active_otr_resources_ = NULL; +WindowResources* OpaqueNonClientView::inactive_otr_resources_ = NULL; +SkBitmap OpaqueNonClientView::distributor_logo_; +static const int kWindowControlsTopOffset = 0; +static const int kWindowControlsRightOffset = 4; +static const int kWindowControlsTopZoomedOffset = 6; +static const int kWindowControlsRightZoomedOffset = 5; +static const int kWindowTopMarginZoomed = 1; +static const int kWindowIconLeftOffset = 5; +static const int kWindowIconTopOffset = 5; +static const int kTitleTopOffset = 6; +static const int kWindowIconTitleSpacing = 3; +static const int kTitleBottomSpacing = 6; +static const int kNoTitleTopSpacing = 8; +static const int kResizeAreaSize = 5; +static const int kResizeAreaNorthSize = 3; +static const int kResizeAreaCornerSize = 16; +static const int kWindowHorizontalBorderSize = 4; +static const int kWindowVerticalBorderSize = 4; +static const int kWindowIconSize = 16; +static const int kDistributorLogoHorizontalOffset = 7; +static const int kDistributorLogoVerticalOffset = 3; + /////////////////////////////////////////////////////////////////////////////// // OpaqueNonClientView, public: -OpaqueNonClientView::OpaqueNonClientView() { +OpaqueNonClientView::OpaqueNonClientView(OpaqueFrame* frame, bool is_otr) + : minimize_button_(new ChromeViews::Button), + maximize_button_(new ChromeViews::Button), + restore_button_(new ChromeViews::Button), + close_button_(new ChromeViews::Button), + frame_(frame) { + InitClass(); + if (is_otr) { + current_active_resources_ = active_otr_resources_; + current_inactive_resources_= inactive_otr_resources_; + } else { + current_active_resources_ = active_resources_; + current_inactive_resources_ = inactive_resources_; + } + + WindowResources* resources = current_active_resources_; + minimize_button_->SetImage( + ChromeViews::Button::BS_NORMAL, + resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON)); + minimize_button_->SetImage( + ChromeViews::Button::BS_HOT, + resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_H)); + minimize_button_->SetImage( + ChromeViews::Button::BS_PUSHED, + resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_P)); + minimize_button_->SetListener(this, -1); + AddChildView(minimize_button_); + + maximize_button_->SetImage( + ChromeViews::Button::BS_NORMAL, + resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON)); + maximize_button_->SetImage( + ChromeViews::Button::BS_HOT, + resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_H)); + maximize_button_->SetImage( + ChromeViews::Button::BS_PUSHED, + resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_P)); + maximize_button_->SetListener(this, -1); + AddChildView(maximize_button_); + + restore_button_->SetImage( + ChromeViews::Button::BS_NORMAL, + resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON)); + restore_button_->SetImage( + ChromeViews::Button::BS_HOT, + resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_H)); + restore_button_->SetImage( + ChromeViews::Button::BS_PUSHED, + resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_P)); + restore_button_->SetListener(this, -1); + AddChildView(restore_button_); + + close_button_->SetImage( + ChromeViews::Button::BS_NORMAL, + resources->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON)); + close_button_->SetImage( + ChromeViews::Button::BS_HOT, + resources->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON_H)); + close_button_->SetImage( + ChromeViews::Button::BS_PUSHED, + resources->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON_P)); + close_button_->SetListener(this, -1); + AddChildView(close_button_); } OpaqueNonClientView::~OpaqueNonClientView() { } /////////////////////////////////////////////////////////////////////////////// +// OpaqueNonClientView, ChromeViews::BaseButton::ButtonListener implementation: + +void OpaqueNonClientView::ButtonPressed(ChromeViews::BaseButton* sender) { + if (sender == minimize_button_) { + frame_->ExecuteSystemMenuCommand(SC_MINIMIZE); + } else if (sender == maximize_button_) { + frame_->ExecuteSystemMenuCommand(SC_MAXIMIZE); + } else if (sender == restore_button_) { + frame_->ExecuteSystemMenuCommand(SC_RESTORE); + } else if (sender == close_button_) { + frame_->ExecuteSystemMenuCommand(SC_CLOSE); + } +} + +/////////////////////////////////////////////////////////////////////////////// // OpaqueNonClientView, ChromeViews::NonClientView implementation: gfx::Rect OpaqueNonClientView::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 OpaqueNonClientView::CalculateWindowSizeForClientSize( int width, int height) const { - return gfx::Size(); + int top_margin = CalculateNonClientTopHeight(); + return gfx::Size(width + (2 * kWindowHorizontalBorderSize), + height + top_margin + kWindowVerticalBorderSize); } CPoint OpaqueNonClientView::GetSystemMenuPoint() const { - return CPoint(); + CPoint system_menu_point(icon_bounds_.x(), icon_bounds_.bottom()); + MapWindowPoints(frame_->GetHWND(), HWND_DESKTOP, &system_menu_point, 1); + return system_menu_point; } int OpaqueNonClientView::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; + + // Then see if the point is within any of the window controls. + close_button_->GetBounds(&bounds, APPLY_MIRRORING_TRANSFORMATION); + if (bounds.PtInRect(test_point)) + return HTCLOSE; + restore_button_->GetBounds(&bounds, APPLY_MIRRORING_TRANSFORMATION); + if (bounds.PtInRect(test_point)) + return HTMAXBUTTON; + maximize_button_->GetBounds(&bounds, APPLY_MIRRORING_TRANSFORMATION); + if (bounds.PtInRect(test_point)) + return HTMAXBUTTON; + minimize_button_->GetBounds(&bounds, APPLY_MIRRORING_TRANSFORMATION); + if (bounds.PtInRect(test_point)) + return HTMINBUTTON; + /* + system_menu_button_->GetBounds(&bounds, APPLY_MIRRORING_TRANSFORMATION); + if (bounds.PtInRect(test_point)) + return HTSYSMENU; + */ + + component = GetHTComponentForFrame( + point, + kResizeAreaSize, + kResizeAreaCornerSize, + kResizeAreaNorthSize, + frame_->window_delegate()->CanResize()); + if (component == HTNOWHERE) { + // Finally fall back to the caption. + GetBounds(&bounds, APPLY_MIRRORING_TRANSFORMATION); + if (bounds.PtInRect(test_point)) + component = HTCAPTION; + // Otherwise, the point is outside the window's bounds. + } + return component; } void OpaqueNonClientView::GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) { + DCHECK(window_mask); + + // Redefine the window visible region for the new size. + window_mask->moveTo(0, 3); + window_mask->lineTo(1, 1); + window_mask->lineTo(3, 0); + + window_mask->lineTo(SkIntToScalar(size.width() - 3), 0); + window_mask->lineTo(SkIntToScalar(size.width() - 1), 1); + window_mask->lineTo(SkIntToScalar(size.width() - 1), 3); + window_mask->lineTo(SkIntToScalar(size.width() - 0), 3); + + window_mask->lineTo(SkIntToScalar(size.width()), + SkIntToScalar(size.height())); + window_mask->lineTo(0, SkIntToScalar(size.height())); + window_mask->close(); } void OpaqueNonClientView::EnableClose(bool enable) { + close_button_->SetEnabled(enable); } /////////////////////////////////////////////////////////////////////////////// // OpaqueNonClientView, ChromeViews::View overrides: +void OpaqueNonClientView::Paint(ChromeCanvas* canvas) { + if (frame_->IsMaximized()) { + PaintMaximizedFrameBorder(canvas); + } else { + PaintFrameBorder(canvas); + } + PaintDistributorLogo(canvas); + PaintTitleBar(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 OpaqueNonClientView::Layout() { + LayoutWindowControls(); + LayoutDistributorLogo(); + LayoutTitleBar(); + LayoutClientView(); +} + +void OpaqueNonClientView::GetPreferredSize(CSize* out) { + DCHECK(out); + frame_->client_view()->GetPreferredSize(out); + out->cx += 2 * kWindowHorizontalBorderSize; + out->cy += CalculateNonClientTopHeight() + kWindowVerticalBorderSize; +} + +ChromeViews::View* OpaqueNonClientView::GetViewForPoint( + const CPoint& point, + bool can_create_floating) { + // We override this function because the ClientView can overlap the non - + // client view, making it impossible to click on the window controls. We need + // to ensure the window controls are checked _first_. + ChromeViews::View* views[] = { close_button_, restore_button_, + maximize_button_, minimize_button_ }; + for (int i = 0; i < arraysize(views); ++i) { + if (!views[i]->IsVisible()) + continue; + CRect bounds; + views[i]->GetBounds(&bounds); + if (bounds.PtInRect(point)) + return views[i]; + } + return View::GetViewForPoint(point, can_create_floating); +} + +void OpaqueNonClientView::DidChangeBounds(const CRect& previous, + const CRect& current) { + Layout(); } void OpaqueNonClientView::ViewHierarchyChanged(bool is_add, ChromeViews::View* parent, ChromeViews::View* child) { + if (is_add && child == this) { + DCHECK(GetViewContainer()); + DCHECK(frame_->client_view()->GetParent() != this); + AddChildView(frame_->client_view()); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// OpaqueNonClientView, private: + +void OpaqueNonClientView::SetWindowIcon(SkBitmap window_icon) { + +} + +int OpaqueNonClientView::CalculateNonClientTopHeight() const { + if (frame_->window_delegate()->ShouldShowWindowTitle()) { + return kTitleTopOffset + resources()->GetTitleFont().height() + + kTitleBottomSpacing; + } + return kNoTitleTopSpacing; } +void OpaqueNonClientView::PaintFrameBorder(ChromeCanvas* canvas) { + int width = GetWidth(); + int height = GetHeight(); + + SkBitmap* top_left_corner = + resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER); + SkBitmap* top_right_corner = + resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER); + SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); + SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE); + SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE); + SkBitmap* bottom_left_corner = + resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER); + SkBitmap* bottom_right_corner = + resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER); + SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE); + + // Top. + canvas->DrawBitmapInt(*top_left_corner, 0, 0); + canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, + width - top_right_corner->width(), top_edge->height()); + canvas->DrawBitmapInt(*top_right_corner, + width - top_right_corner->width(), 0); + + // Right. + int top_stack_height = top_right_corner->height(); + canvas->TileImageInt(*right_edge, width - right_edge->width(), + top_stack_height, right_edge->width(), + height - top_stack_height - + bottom_right_corner->height()); + + // Bottom. + canvas->DrawBitmapInt(*bottom_right_corner, + width - bottom_right_corner->width(), + height - bottom_right_corner->height()); + canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), + height - bottom_edge->height(), + width - bottom_left_corner->width() - + bottom_right_corner->width(), + bottom_edge->height()); + canvas->DrawBitmapInt(*bottom_left_corner, 0, + height - bottom_left_corner->height()); + + // Left. + top_stack_height = top_left_corner->height(); + canvas->TileImageInt(*left_edge, 0, top_stack_height, left_edge->width(), + height - top_stack_height - + bottom_left_corner->height()); +} + +void OpaqueNonClientView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) { + SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_MAXIMIZED_TOP_EDGE); + SkBitmap* bottom_edge = + resources()->GetPartBitmap(FRAME_MAXIMIZED_BOTTOM_EDGE); + canvas->TileImageInt(*top_edge, 0, 0, GetWidth(), top_edge->height()); + canvas->TileImageInt(*bottom_edge, 0, GetHeight() - bottom_edge->height(), + GetWidth(), bottom_edge->height()); +} + +void OpaqueNonClientView::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 OpaqueNonClientView::PaintTitleBar(ChromeCanvas* canvas) { + ChromeViews::WindowDelegate* d = frame_->window_delegate(); + if (d->ShouldShowWindowIcon()) { + canvas->DrawBitmapInt(d->GetWindowIcon(), icon_bounds_.x(), + icon_bounds_.y()); + } + if (d->ShouldShowWindowTitle()) { + canvas->DrawStringInt(d->GetWindowTitle(), + resources()->GetTitleFont(), + resources()->title_color(), title_bounds_.x(), + title_bounds_.y(), title_bounds_.width(), + title_bounds_.height()); + } +} + +void OpaqueNonClientView::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 OpaqueNonClientView::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 OpaqueNonClientView::LayoutWindowControls() { + CSize ps; + if (frame_->IsMaximized() || frame_->IsMinimized()) { + maximize_button_->SetVisible(false); + restore_button_->SetVisible(true); + } + + if (frame_->IsMaximized()) { + close_button_->GetPreferredSize(&ps); + close_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_BOTTOM); + close_button_->SetBounds( + GetWidth() - ps.cx - kWindowControlsRightZoomedOffset, + 0, ps.cx + kWindowControlsRightZoomedOffset, + ps.cy + kWindowControlsTopZoomedOffset); + + restore_button_->GetPreferredSize(&ps); + restore_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_BOTTOM); + restore_button_->SetBounds(close_button_->GetX() - ps.cx, 0, ps.cx, + ps.cy + kWindowControlsTopZoomedOffset); + + minimize_button_->GetPreferredSize(&ps); + minimize_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_BOTTOM); + minimize_button_->SetBounds(restore_button_->GetX() - ps.cx, 0, ps.cx, + ps.cy + kWindowControlsTopZoomedOffset); + } else if (frame_->IsMinimized()) { + close_button_->GetPreferredSize(&ps); + close_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_BOTTOM); + close_button_->SetBounds( + GetWidth() - ps.cx - kWindowControlsRightZoomedOffset, + 0, ps.cx + kWindowControlsRightZoomedOffset, + ps.cy + kWindowControlsTopZoomedOffset); + + restore_button_->GetPreferredSize(&ps); + restore_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_BOTTOM); + restore_button_->SetBounds(close_button_->GetX() - ps.cx, 0, ps.cx, + ps.cy + kWindowControlsTopZoomedOffset); + + minimize_button_->GetPreferredSize(&ps); + minimize_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_BOTTOM); + minimize_button_->SetBounds(restore_button_->GetX() - ps.cx, 0, ps.cx, + ps.cy + kWindowControlsTopZoomedOffset); + } else { + close_button_->GetPreferredSize(&ps); + close_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_TOP); + close_button_->SetBounds(GetWidth() - kWindowControlsRightOffset - ps.cx, + kWindowControlsTopOffset, ps.cx, ps.cy); + + restore_button_->SetVisible(false); + + maximize_button_->SetVisible(true); + maximize_button_->GetPreferredSize(&ps); + maximize_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_TOP); + maximize_button_->SetBounds(close_button_->GetX() - ps.cx, + kWindowControlsTopOffset, ps.cx, ps.cy); + + minimize_button_->GetPreferredSize(&ps); + minimize_button_->SetImageAlignment(ChromeViews::Button::ALIGN_LEFT, + ChromeViews::Button::ALIGN_TOP); + minimize_button_->SetBounds(maximize_button_->GetX() - ps.cx, + kWindowControlsTopOffset, ps.cx, ps.cy); + } +} + +void OpaqueNonClientView::LayoutDistributorLogo() { + int logo_w = distributor_logo_.width(); + int logo_h = distributor_logo_.height(); + + logo_bounds_.SetRect( + minimize_button_->GetX() - logo_w - kDistributorLogoHorizontalOffset, + kDistributorLogoVerticalOffset, logo_w, logo_h); +} + +void OpaqueNonClientView::LayoutTitleBar() { + int top_offset = frame_->IsMaximized() ? kWindowTopMarginZoomed : 0; + ChromeViews::WindowDelegate* d = frame_->window_delegate(); + + // Size the window icon, if visible. + if (d->ShouldShowWindowIcon()) { + icon_bounds_.SetRect(kWindowIconLeftOffset, kWindowIconLeftOffset, + kWindowIconSize, kWindowIconSize); + } else { + // Put the menu in the right place at least even if it is hidden so we + // can size the title based on its position. + icon_bounds_.SetRect(kWindowIconLeftOffset, kWindowIconTopOffset, 0, 0); + } + + // Size the title, if visible. + if (d->ShouldShowWindowTitle()) { + int spacing = d->ShouldShowWindowIcon() ? kWindowIconTitleSpacing : 0; + int title_right = minimize_button_->GetX(); + int title_left = icon_bounds_.right() + spacing; + title_bounds_.SetRect(title_left, kTitleTopOffset + top_offset, + std::max(0, static_cast<int>(title_right - icon_bounds_.right())), + resources()->GetTitleFont().height()); + } +} + +void OpaqueNonClientView::LayoutClientView() { + gfx::Rect client_bounds( + CalculateClientAreaBounds(GetWidth(), GetHeight())); + frame_->client_view()->SetBounds(client_bounds.ToRECT()); +} + +// static +void OpaqueNonClientView::InitClass() { + static bool initialized = false; + if (!initialized) { + active_resources_ = new ActiveWindowResources; + inactive_resources_ = new InactiveWindowResources; + active_otr_resources_ = new OTRActiveWindowResources; + inactive_otr_resources_ = new OTRInactiveWindowResources; + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + distributor_logo_ = *rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO_LIGHT); + + initialized = true; + } +} diff --git a/chrome/browser/views/frame/opaque_non_client_view.h b/chrome/browser/views/frame/opaque_non_client_view.h index 48c3e78..bf48c26 100644 --- a/chrome/browser/views/frame/opaque_non_client_view.h +++ b/chrome/browser/views/frame/opaque_non_client_view.h @@ -30,14 +30,26 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_OPAQUE_NON_CLIENT_VIEW_H_ #define CHROME_BROWSER_VIEWS_FRAME_OPAQUE_NON_CLIENT_VIEW_H_ +#include "chrome/browser/views/frame/opaque_frame.h" #include "chrome/views/non_client_view.h" +#include "chrome/views/button.h" -class OpaqueNonClientView : public ChromeViews::NonClientView { +class OpaqueFrame; +class WindowResources; + +class OpaqueNonClientView : public ChromeViews::NonClientView, + public ChromeViews::BaseButton::ButtonListener { public: - OpaqueNonClientView(); + // Constructs a non-client view for an OpaqueFrame. |is_otr| specifies if the + // frame was created "off-the-record" and as such different bitmaps should be + // used to render the frame. + OpaqueNonClientView(OpaqueFrame* frame, bool is_otr); virtual ~OpaqueNonClientView(); protected: + // Overridden from ChromeViews::BaseButton::ButtonListener: + virtual void ButtonPressed(ChromeViews::BaseButton* sender); + // Overridden from ChromeViews::NonClientView: virtual gfx::Rect CalculateClientAreaBounds(int width, int height) const; virtual gfx::Size CalculateWindowSizeForClientSize(int width, @@ -48,12 +60,75 @@ class OpaqueNonClientView : 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 ChromeViews::View* GetViewForPoint(const CPoint& point, + bool can_create_floating); + virtual void DidChangeBounds(const CRect& previous, const CRect& current); virtual void ViewHierarchyChanged(bool is_add, ChromeViews::View* parent, ChromeViews::View* child); private: + // Updates the system menu icon button. + void SetWindowIcon(SkBitmap window_icon); + + // 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 PaintFrameBorder(ChromeCanvas* canvas); + void PaintMaximizedFrameBorder(ChromeCanvas* canvas); + void PaintDistributorLogo(ChromeCanvas* canvas); + void PaintTitleBar(ChromeCanvas* canvas); + void PaintToolbarBackground(ChromeCanvas* canvas); + void PaintClientEdge(ChromeCanvas* canvas); + + // Layout various sub-components of this view. + void LayoutWindowControls(); + void LayoutDistributorLogo(); + void LayoutTitleBar(); + void LayoutClientView(); + + // Returns the set of resources to use to paint this view. + WindowResources* resources() const { + return frame_->is_active() ? current_active_resources_ + : current_inactive_resources_; + } + + // The layout rect of the title, if visible. + gfx::Rect title_bounds_; + + // The layout rect of the window icon, if visible. + gfx::Rect icon_bounds_; + + // The layout rect of the distributor logo, if visible. + gfx::Rect logo_bounds_; + + // Window controls. + ChromeViews::Button* minimize_button_; + ChromeViews::Button* maximize_button_; + ChromeViews::Button* restore_button_; + ChromeViews::Button* close_button_; + + // The frame that hosts this view. + OpaqueFrame* frame_; + + // The BrowserView hosted within this View. + + // The resources currently used to paint this view. + WindowResources* current_active_resources_; + WindowResources* current_inactive_resources_; + + static void InitClass(); + static SkBitmap distributor_logo_; + static WindowResources* active_resources_; + static WindowResources* inactive_resources_; + static WindowResources* active_otr_resources_; + static WindowResources* inactive_otr_resources_; + DISALLOW_EVIL_CONSTRUCTORS(OpaqueNonClientView); }; diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index 056cbfe..ec5e734 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -459,6 +459,16 @@ bool BrowserToolbarView::OnKeyReleased(const ChromeViews::KeyEvent& e) { return acc_focused_view_->OnKeyReleased(e); } +void BrowserToolbarView::GetPreferredSize(CSize* out) { + DCHECK(out); + static SkBitmap* bg_bitmap = NULL; + if (!bg_bitmap) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + bg_bitmap = rb.GetBitmapNamed(IDR_CONTENT_TOP_CENTER); + } + out->cx = 0; + out->cy = bg_bitmap->height(); +} void BrowserToolbarView::RunPageMenu(const CPoint& pt, HWND hwnd) { Menu::AnchorPoint anchor = Menu::TOPRIGHT; diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h index 6869a59..48f729e 100644 --- a/chrome/browser/views/toolbar_view.h +++ b/chrome/browser/views/toolbar_view.h @@ -77,6 +77,7 @@ class BrowserToolbarView : public ChromeViews::View, virtual void WillLoseFocus(); virtual bool OnKeyPressed(const ChromeViews::KeyEvent& e); virtual bool OnKeyReleased(const ChromeViews::KeyEvent& e); + virtual void GetPreferredSize(CSize* out); // Overridden from EncodingMenuControllerDelegate: virtual bool IsItemChecked(int id) const; diff --git a/chrome/views/client_view.cc b/chrome/views/client_view.cc index 89894e7..73986e5 100644 --- a/chrome/views/client_view.cc +++ b/chrome/views/client_view.cc @@ -38,7 +38,6 @@ namespace ChromeViews { ClientView::ClientView(Window* window, View* contents_view) : window_(window), contents_view_(contents_view) { - DCHECK(window && contents_view); } int ClientView::NonClientHitTest(const gfx::Point& point) { @@ -54,12 +53,16 @@ int ClientView::NonClientHitTest(const gfx::Point& point) { void ClientView::GetPreferredSize(CSize* out) { DCHECK(out); - contents_view_->GetPreferredSize(out); + // |contents_view_| is allowed to be NULL up until the point where this view + // is attached to a ViewContainer. + if (contents_view_) + contents_view_->GetPreferredSize(out); } void ClientView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { if (is_add && child == this) { DCHECK(GetViewContainer()); + DCHECK(contents_view_); // |contents_view_| must be valid now! AddChildView(contents_view_); } } @@ -69,7 +72,10 @@ void ClientView::DidChangeBounds(const CRect& previous, const CRect& current) { } void ClientView::Layout() { - contents_view_->SetBounds(0, 0, GetWidth(), GetHeight()); + // |contents_view_| is allowed to be NULL up until the point where this view + // is attached to a ViewContainer. + if (contents_view_) + contents_view_->SetBounds(0, 0, GetWidth(), GetHeight()); } }; // namespace ChromeViews
\ No newline at end of file diff --git a/chrome/views/client_view.h b/chrome/views/client_view.h index f83887b..c6f8fe3 100644 --- a/chrome/views/client_view.h +++ b/chrome/views/client_view.h @@ -49,9 +49,8 @@ class ClientView : public View { public: // Constructs a ClientView object for the specified window with the specified // contents. Since this object is created during the process of creating - // |window|, |contents_view| must be valid so we can determine the initial - // size of |window|. We call GetPreferredSize on |contents_view|, - // which should return something non-zero. + // |window|, |contents_view| must be valid if you want the initial size of + // the window to be based on |contents_view|'s preferred size. ClientView(Window* window, View* contents_view); virtual ~ClientView() {} @@ -86,7 +85,11 @@ class ClientView : public View { // Accessors for private data members. Window* window() const { return window_; } + void set_window(Window* window) { window_ = window; } View* contents_view() const { return contents_view_; } + void set_contents_view(View* contents_view) { + contents_view_ = contents_view; + } private: // The Window that hosts this ClientView. |