diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-26 04:06:43 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-26 04:06:43 +0000 |
commit | f075fe0a20acba35df51e93e635db8f0b0d89d7b (patch) | |
tree | 68cc0fe76b8897b1f6162f176f1ba62a227929e1 /chrome/browser/views/frame | |
parent | 62cdc5bf2d94c02ef33ebff1ede7e0cde31c7285 (diff) | |
download | chromium_src-f075fe0a20acba35df51e93e635db8f0b0d89d7b.zip chromium_src-f075fe0a20acba35df51e93e635db8f0b0d89d7b.tar.gz chromium_src-f075fe0a20acba35df51e93e635db8f0b0d89d7b.tar.bz2 |
Reland r45520. This adds a new browser type: EXTENSION_APP that
has a larger titlebar and a big icon, along with a tabstrip,
but no titlebar.
Review URL: http://codereview.chromium.org/1774003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45566 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/frame')
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 49 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 29 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view_layout.cc | 56 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view_layout.h | 5 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_browser_frame_view.cc | 27 |
5 files changed, 156 insertions, 10 deletions
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 614659e..eb9620d 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -98,6 +98,10 @@ static int explicit_show_state = -1; // How round the 'new tab' style bookmarks bar is. static const int kNewtabBarRoundness = 5; + +// The maximum width of the big title shown for extension app windows. +static const int kExtensionAppTitleMaxWidth = 150; + // ------------ // Returned from BrowserView::GetClassName. @@ -384,6 +388,8 @@ BrowserView::BrowserView(Browser* browser) frame_(NULL), browser_(browser), active_bookmark_bar_(NULL), + extension_app_icon_(NULL), + extension_app_title_(NULL), tabstrip_(NULL), toolbar_(NULL), infobar_container_(NULL), @@ -398,7 +404,8 @@ BrowserView::BrowserView(Browser* browser) #endif extension_shelf_(NULL), last_focused_view_storage_id_( - views::ViewStorage::GetSharedInstance()->CreateStorageID()) { + views::ViewStorage::GetSharedInstance()->CreateStorageID()), + extension_app_icon_loader_(this) { browser_->tabstrip_model()->AddObserver(this); } @@ -1639,8 +1646,42 @@ void BrowserView::Init() { LoadAccelerators(); SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); + if (browser_->extension_app()) { + extension_app_icon_ = new views::ImageView(); + extension_app_icon_->SetID(VIEW_ID_EXTENSION_APP_ICON); + AddChildView(extension_app_icon_); + + extension_app_title_ = new views::Label(); + extension_app_title_->SetFont( + extension_app_title_->font().DeriveFont(1, gfx::Font::BOLD)); + extension_app_title_->SetColor(SK_ColorWHITE); + extension_app_title_->SetID(VIEW_ID_EXTENSION_APP_TITLE); + AddChildView(extension_app_title_); + + extension_app_icon_loader_.LoadImage( + browser_->extension_app(), + browser_->extension_app()->GetIconPath( + Extension::EXTENSION_ICON_MEDIUM), + gfx::Size(Extension::EXTENSION_ICON_SMALL, + Extension::EXTENSION_ICON_SMALL), + ImageLoadingTracker::CACHE); + + extension_app_title_->SetText( + UTF8ToWide(browser_->extension_app()->name())); + extension_app_title_->SizeToPreferredSize(); + + if (extension_app_title_->width() > kExtensionAppTitleMaxWidth) { + extension_app_title_->SetBounds(extension_app_title_->x(), + extension_app_title_->y(), + kExtensionAppTitleMaxWidth, + extension_app_title_->height()); + } + } + tabstrip_ = CreateTabStrip(browser_->tabstrip_model()); tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP)); + if (browser_->extension_app() && tabstrip_->AsTabStrip()) + tabstrip_->AsTabStrip()->set_new_tab_button_enabled(false); AddChildView(tabstrip_); frame_->TabStripCreated(tabstrip_); @@ -1719,6 +1760,12 @@ void BrowserView::InitSystemMenu() { } #endif +void BrowserView::OnImageLoaded(SkBitmap* image, ExtensionResource resource, + int index) { + if (image) + extension_app_icon_->SetImage(*image); +} + BrowserViewLayout* BrowserView::GetBrowserViewLayout() const { return static_cast<BrowserViewLayout*>(GetLayoutManager()); } diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 79f9858..10292bf 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -15,6 +15,7 @@ #include "build/build_config.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" +#include "chrome/browser/extensions/image_loading_tracker.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/views/frame/browser_bubble_host.h" #include "chrome/browser/views/frame/browser_frame.h" @@ -23,6 +24,8 @@ #include "chrome/browser/views/tabs/base_tab_strip.h" #include "chrome/browser/views/unhandled_keyboard_event_handler.h" #include "gfx/native_widget_types.h" +#include "views/controls/image_view.h" +#include "views/controls/label.h" #include "views/window/client_view.h" #include "views/window/window_delegate.h" @@ -81,7 +84,8 @@ class BrowserView : public BrowserBubbleHost, public menus::SimpleMenuModel::Delegate, public views::WindowDelegate, public views::ClientView, - public InfoBarContainer::Delegate { + public InfoBarContainer::Delegate, + public ImageLoadingTracker::Observer { public: // The browser view's class name. static const char kViewClassName[]; @@ -145,6 +149,14 @@ class BrowserView : public BrowserBubbleHost, // offset of IDR_THEME_TOOLBAR. gfx::Rect GetTabStripBounds() const; + // Accessor for the big icon used with TYPE_EXTENSION_APP, or NULL if this + // browser isn't TYPE_EXTENSION_APP. + views::ImageView* extension_app_icon() const { return extension_app_icon_; } + + // Accessor for the big title used with TYPE_EXTENSION_APP, or NULL if this + // browser isn't TYPE_EXTENSION_APP. + views::Label* extension_app_title() const { return extension_app_title_; } + // Accessor for the TabStrip. BaseTabStrip* tabstrip() const { return tabstrip_; } @@ -241,6 +253,10 @@ class BrowserView : public BrowserBubbleHost, BrowserExtender* browser_extender() const { return browser_extender_.get(); } + // Overriden from ImageLoadingTracker::Observer. + virtual void OnImageLoaded(SkBitmap* image, ExtensionResource resource, + int index); + // Overridden from BrowserWindow: virtual void Show(); virtual void SetBounds(const gfx::Rect& bounds); @@ -486,6 +502,14 @@ class BrowserView : public BrowserBubbleHost, // or is bookmark_bar_view_ if the bookmark bar is showing. views::View* active_bookmark_bar_; + // The big icon in the top-left if this browser is TYPE_EXTENSION_APP, or + // NULL otherwise. + views::ImageView* extension_app_icon_; + + // The big title text in the top-left if this browser is TYPE_EXTENSION_APP, + // or NULL otherwise. + views::Label* extension_app_title_; + // The TabStrip. BaseTabStrip* tabstrip_; @@ -576,6 +600,9 @@ class BrowserView : public BrowserBubbleHost, scoped_ptr<AccessibleWidgetHelper> accessible_widget_helper_; #endif + // Loads extension_app_icon_ asynchronously on the file thread. + ImageLoadingTracker extension_app_icon_loader_; + DISALLOW_COPY_AND_ASSIGN(BrowserView); }; diff --git a/chrome/browser/views/frame/browser_view_layout.cc b/chrome/browser/views/frame/browser_view_layout.cc index 2b0f2e0..505a913 100644 --- a/chrome/browser/views/frame/browser_view_layout.cc +++ b/chrome/browser/views/frame/browser_view_layout.cc @@ -36,6 +36,11 @@ const int kBrowserViewTabStripHorizontalOverlap = 4; // An offset distance between certain toolbars and the toolbar that preceded // them in layout. const int kSeparationLineHeight = 1; +// Spacing between extension app icon and title. +const int kExtensionAppIconTitleSpacing = 4; +// We don't actually display the toolbar in extension app mode, but this is the +// height of the spacing where it usually goes. +const int kExtensionAppToolbarHeight = 7; } // namespace @@ -43,7 +48,9 @@ const int kSeparationLineHeight = 1; // BrowserViewLayout, public: BrowserViewLayout::BrowserViewLayout() - : tabstrip_(NULL), + : extension_app_icon_(NULL), + extension_app_title_(NULL), + tabstrip_(NULL), toolbar_(NULL), contents_split_(NULL), contents_container_(NULL), @@ -206,6 +213,8 @@ void BrowserViewLayout::Installed(views::View* host) { extension_shelf_ = NULL; active_bookmark_bar_ = NULL; tabstrip_ = NULL; + extension_app_icon_ = NULL; + extension_app_title_ = NULL; browser_view_ = static_cast<BrowserView*>(host); } @@ -235,6 +244,12 @@ void BrowserViewLayout::ViewAdded(views::View* host, views::View* view) { case VIEW_ID_TAB_STRIP: tabstrip_ = static_cast<BaseTabStrip*>(view); break; + case VIEW_ID_EXTENSION_APP_ICON: + extension_app_icon_ = static_cast<views::ImageView*>(view); + break; + case VIEW_ID_EXTENSION_APP_TITLE: + extension_app_title_ = static_cast<views::Label*>(view); + break; } } @@ -248,6 +263,7 @@ void BrowserViewLayout::ViewRemoved(views::View* host, views::View* view) { void BrowserViewLayout::Layout(views::View* host) { vertical_layout_rect_ = browser_view_->GetLocalBounds(true); + LayoutExtensionAppIconAndTitle(); int top = LayoutTabStrip(); top = LayoutToolbar(top); top = LayoutBookmarkAndInfoBars(top); @@ -276,6 +292,26 @@ gfx::Size BrowserViewLayout::GetPreferredSize(views::View* host) { ////////////////////////////////////////////////////////////////////////////// // BrowserViewLayout, private: +void BrowserViewLayout::LayoutExtensionAppIconAndTitle() { + if (browser_view_->browser()->type() != Browser::TYPE_EXTENSION_APP) + return; + + extension_app_icon_->SetVisible(true); + extension_app_icon_->SetBounds(0, 0, Extension::EXTENSION_ICON_SMALL, + Extension::EXTENSION_ICON_SMALL); + + extension_app_title_->SetVisible(true); + + // Position the title vertically centered with the icon and slightly to its + // right. + extension_app_title_->SetX( + extension_app_icon_->x() + extension_app_icon_->width() + + kExtensionAppIconTitleSpacing); + extension_app_title_->SetY( + extension_app_icon_->y() + + ((extension_app_icon_->height() - extension_app_title_->height()) / 2)); +} + int BrowserViewLayout::LayoutTabStrip() { if (!browser_view_->IsTabStripVisible()) { tabstrip_->SetVisible(false); @@ -314,8 +350,22 @@ int BrowserViewLayout::LayoutToolbar(int top) { ((visible && browser_view_->IsTabStripVisible()) ? kToolbarTabStripVerticalOverlap : 0); } - int height = visible ? toolbar_->GetPreferredSize().height() : 0; - toolbar_->SetVisible(visible); + int height = 0; + if (visible) { + if (browser_view_->browser()->type() == Browser::TYPE_EXTENSION_APP) { + // TODO(aa): Find a more sensible way to handle this. We want + // OpaqueBroserFrame to continue to paint the area where the toolstrip + // would be, but we don't actually want a toolbar in this case. + toolbar_->SetVisible(false); + height = kExtensionAppToolbarHeight; + } else { + toolbar_->SetVisible(true); + height = toolbar_->GetPreferredSize().height(); + } + } else { + toolbar_->SetVisible(false); + } + toolbar_->SetBounds(vertical_layout_rect_.x(), y, browser_view_width, height); return y + height; } diff --git a/chrome/browser/views/frame/browser_view_layout.h b/chrome/browser/views/frame/browser_view_layout.h index 068d8302..6dc3624 100644 --- a/chrome/browser/views/frame/browser_view_layout.h +++ b/chrome/browser/views/frame/browser_view_layout.h @@ -47,6 +47,9 @@ class BrowserViewLayout : public views::LayoutManager { // for laying out subsequent controls. virtual int LayoutTabStrip(); + // Layout the big icon and title in the top left of extension app windows. + void LayoutExtensionAppIconAndTitle(); + // 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); @@ -68,6 +71,8 @@ class BrowserViewLayout : public views::LayoutManager { int LayoutExtensionShelf(int bottom); // Child views that the layout manager manages. + views::ImageView* extension_app_icon_; + views::Label* extension_app_title_; BaseTabStrip* tabstrip_; ToolbarView* toolbar_; views::View* contents_split_; diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc index c91cb51..af74018 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc @@ -95,6 +95,8 @@ const int kNewTabCaptionMaximizedSpacing = 16; // How far to indent the tabstrip from the left side of the screen when there // is no OTR icon. const int kTabStripIndent = 1; +// Spacing between extension app icon/title and tab strip. +const int kExtensionAppTabStripLeftSpacing = 10; } /////////////////////////////////////////////////////////////////////////////// @@ -195,10 +197,27 @@ gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip( int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_avatar_icon_->bounds().right() + kOTRSideSpacing) : NonClientBorderThickness() + kTabStripIndent; + + int tabstrip_y = NonClientTopBorderHeight(); + if (!frame_->GetWindow()->IsMaximized() && + !frame_->GetWindow()->IsFullscreen()) { + tabstrip_y += kNonClientRestoredExtraThickness; + } + int tabstrip_width = minimize_button_->x() - tabstrip_x - (frame_->GetWindow()->IsMaximized() ? kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); - return gfx::Rect(tabstrip_x, NonClientTopBorderHeight(), + + if (browser_view_->browser()->type() == Browser::TYPE_EXTENSION_APP) { + int tabstrip_offset = browser_view_->extension_app_title()->x() + + browser_view_->extension_app_title()->width() + + kExtensionAppTabStripLeftSpacing; + + tabstrip_x += tabstrip_offset; + tabstrip_width -= tabstrip_offset; + } + + return gfx::Rect(tabstrip_x, tabstrip_y, std::max(0, tabstrip_width), tabstrip->GetPreferredHeight()); } @@ -431,9 +450,7 @@ int OpaqueBrowserFrameView::NonClientTopBorderHeight() const { if (browser_view_->IsTabStripVisible() && window->IsMaximized()) return FrameBorderThickness() - kTabstripTopShadowThickness; - return FrameBorderThickness() + - ((window->IsMaximized() || window->IsFullscreen()) ? - 0 : kNonClientRestoredExtraThickness); + return FrameBorderThickness(); } int OpaqueBrowserFrameView::CaptionButtonY() const { @@ -815,7 +832,7 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { client_area_top += browser_view_->GetToolbarBounds().y() + std::min(tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height(), toolbar_bounds.height()); - } else { + } else if (!browser_view_->IsTabStripVisible()) { // The toolbar isn't going to draw a client edge for us, so draw one // ourselves. SkBitmap* top_left = tp->GetBitmapNamed(IDR_APP_TOP_LEFT); |