summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views
diff options
context:
space:
mode:
authorbeng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-04 18:39:13 +0000
committerbeng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-04 18:39:13 +0000
commit0d6ac82ec35133d4be884c54a1e48a371570272f (patch)
tree77c54ba70f3c35a59add3b19556acd12632897b5 /chrome/browser/views
parent3fa4bad7827a6c725e3e8868d63ddee0d4b67b2d (diff)
downloadchromium_src-0d6ac82ec35133d4be884c54a1e48a371570272f.zip
chromium_src-0d6ac82ec35133d4be884c54a1e48a371570272f.tar.gz
chromium_src-0d6ac82ec35133d4be884c54a1e48a371570272f.tar.bz2
Bring up the new frame (opaque version for XP only, for now).
I've hidden this frame behind a command line switch (--magic_browzR) so as not to destabilize the main browser UI any further. Note that running with this switch is likely buggy, incomplete, crashy, etc. In order to make this work without disrupting a lot of existing code, I've had to make another BrowserView class (temporary) - BrowserView2. This also has to be a BrowserWindow implementor since that's the interface Browser uses to communicate with the UI. BrowserView2 and OpaqueNonClientView are the major new files in this CL, but BrowserView2 is pretty similar to BrowserView. OpaqueNonClientView is the view that renders the titlebar/borders/etc. It's layout/painting routines are a bit simpler than XPFrame's! B=1031854 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@329 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views')
-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
10 files changed, 1686 insertions, 10 deletions
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;