summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/views/frame/browser_frame.h27
-rw-r--r--chrome/browser/views/frame/browser_view2.cc489
-rw-r--r--chrome/browser/views/frame/browser_view2.h195
-rw-r--r--chrome/browser/views/frame/browser_window_factory.cc36
-rw-r--r--chrome/browser/views/frame/opaque_frame.cc24
-rw-r--r--chrome/browser/views/frame/opaque_frame.h24
-rw-r--r--chrome/browser/views/frame/opaque_non_client_view.cc811
-rw-r--r--chrome/browser/views/frame/opaque_non_client_view.h79
-rw-r--r--chrome/browser/views/toolbar_view.cc10
-rw-r--r--chrome/browser/views/toolbar_view.h1
-rw-r--r--chrome/views/client_view.cc12
-rw-r--r--chrome/views/client_view.h9
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.