From 4303f91082840584199e9b79e99b6d0181ca3871 Mon Sep 17 00:00:00 2001 From: "ben@chromium.org" Date: Wed, 3 Feb 2010 00:37:48 +0000 Subject: Move ChromeBrowserView* -> BrowserView* and ChromeosBrowserView* -> chromeos::BrowserView* BUG=none TEST=none Review URL: http://codereview.chromium.org/569019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37914 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/chromeos/browser_view.cc | 502 ++++++++++++++++++++ chrome/browser/chromeos/browser_view.h | 131 ++++++ chrome/browser/chromeos/chromeos_browser_view.cc | 505 --------------------- chrome/browser/chromeos/chromeos_browser_view.h | 130 ------ chrome/browser/views/frame/browser_view.cc | 16 +- chrome/browser/views/frame/browser_view.h | 7 +- chrome/browser/views/frame/browser_view_layout.cc | 447 ++++++++++++++++++ chrome/browser/views/frame/browser_view_layout.h | 89 ++++ .../views/frame/browser_view_layout_manager.h | 32 -- .../frame/chrome_browser_view_layout_manager.cc | 451 ------------------ .../frame/chrome_browser_view_layout_manager.h | 80 ---- 11 files changed, 1181 insertions(+), 1209 deletions(-) create mode 100644 chrome/browser/chromeos/browser_view.cc create mode 100644 chrome/browser/chromeos/browser_view.h delete mode 100644 chrome/browser/chromeos/chromeos_browser_view.cc delete mode 100644 chrome/browser/chromeos/chromeos_browser_view.h create mode 100644 chrome/browser/views/frame/browser_view_layout.cc create mode 100644 chrome/browser/views/frame/browser_view_layout.h delete mode 100644 chrome/browser/views/frame/browser_view_layout_manager.h delete mode 100644 chrome/browser/views/frame/chrome_browser_view_layout_manager.cc delete mode 100644 chrome/browser/views/frame/chrome_browser_view_layout_manager.h (limited to 'chrome/browser') diff --git a/chrome/browser/chromeos/browser_view.cc b/chrome/browser/chromeos/browser_view.cc new file mode 100644 index 0000000..0e84b3c --- /dev/null +++ b/chrome/browser/chromeos/browser_view.cc @@ -0,0 +1,502 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/browser_view.h" + +#include +#include + +#include "app/gfx/canvas.h" +#include "app/menus/simple_menu_model.h" +#include "app/theme_provider.h" +#include "base/command_line.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/chromeos/browser_status_area_view.h" +#include "chrome/browser/chromeos/compact_location_bar_host.h" +#include "chrome/browser/chromeos/compact_navigation_bar.h" +#include "chrome/browser/chromeos/main_menu.h" +#include "chrome/browser/chromeos/panel_browser_view.h" +#include "chrome/browser/chromeos/status_area_button.h" +#include "chrome/browser/view_ids.h" +#include "chrome/browser/views/frame/browser_extender.h" +#include "chrome/browser/views/frame/browser_frame_gtk.h" +#include "chrome/browser/views/frame/browser_view.h" +#include "chrome/browser/views/frame/chrome_browser_view_layout_manager.h" +#include "chrome/browser/views/tabs/tab.h" +#include "chrome/browser/views/tabs/tab_overview_types.h" +#include "chrome/browser/views/tabs/tab_strip.h" +#include "chrome/browser/views/toolbar_view.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/x11_util.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "views/controls/button/button.h" +#include "views/controls/button/image_button.h" +#include "views/controls/menu/menu_2.h" +#include "views/window/hit_test.h" +#include "views/window/window.h" + +namespace { + +const char* kChromeOsWindowManagerName = "chromeos-wm"; +const int kCompactNavbarSpaceHeight = 3; + +// A space we insert between the tabstrip and the content in +// Compact mode. +class Spacer : public views::View { + SkBitmap* background_; + public: + explicit Spacer(SkBitmap* bitmap) : background_(bitmap) {} + + void Paint(gfx::Canvas* canvas) { + canvas->TileImageInt(*background_, 0, 0, width(), height()); + } + + private: + DISALLOW_COPY_AND_ASSIGN(Spacer); +}; + +// A chromeos implementation of Tab that shows the compact location bar. +class ChromeosTab : public Tab { + public: + ChromeosTab(TabStrip* tab_strip, chromeos::BrowserView* browser_view) + : Tab(tab_strip), + browser_view_(browser_view) { + } + virtual ~ChromeosTab() {} + + // Overridden from views::View. + virtual void OnMouseEntered(const views::MouseEvent& event) { + TabRenderer::OnMouseEntered(event); + browser_view_->ShowCompactLocationBarUnderSelectedTab(); + } + + private: + chromeos::BrowserView* browser_view_; + + DISALLOW_COPY_AND_ASSIGN(ChromeosTab); +}; + +// A Tabstrip that uses ChromeosTab as a Tab implementation. +class ChromeosTabStrip : public TabStrip { + public: + ChromeosTabStrip(TabStripModel* model, chromeos::BrowserView* browser_view) + : TabStrip(model), browser_view_(browser_view) { + } + virtual ~ChromeosTabStrip() {} + + protected: + // Overridden from TabStrip. + virtual Tab* CreateTab() { + return new ChromeosTab(this, browser_view_); + } + + private: + chromeos::BrowserView* browser_view_; + + DISALLOW_COPY_AND_ASSIGN(ChromeosTabStrip); +}; + +// View ID used only in ChromeOS. +enum ChromeOSViewIds { + // Start with the offset that is big enough to avoid possible + // collison. + VIEW_ID_MAIN_MENU = VIEW_ID_PREDEFINED_COUNT + 10000, + VIEW_ID_COMPACT_NAV_BAR, + VIEW_ID_STATUS_AREA, + VIEW_ID_SPACER, +}; + +} // namespace + +namespace chromeos { + +// LayoutManager for BrowserView, which layouts extra components such as +// main menu, stataus views. +class BrowserViewLayout : public ::BrowserViewLayout { + public: + BrowserViewLayout() : BrowserViewLayout() {} + virtual ~BrowserViewLayout() {} + + ////////////////////////////////////////////////////////////////////////////// + // BrowserViewLayout overrides: + + void Installed(views::View* host) { + main_menu_ = NULL; + compact_navigation_bar_ = NULL; + status_area_ = NULL; + spacer_ = NULL; + BrowserViewLayout::Installed(host); + } + + void ViewAdded(views::View* host, + views::View* view) { + BrowserViewLayout::ViewAdded(host, view); + switch (view->GetID()) { + case VIEW_ID_SPACER: + spacer_ = view; + break; + case VIEW_ID_MAIN_MENU: + main_menu_ = view; + break; + case VIEW_ID_STATUS_AREA: + status_area_ = static_cast(view); + break; + case VIEW_ID_COMPACT_NAV_BAR: + compact_navigation_bar_ = view; + break; + } + } + + virtual int LayoutTabStrip() { + if (!browser_view_->IsTabStripVisible()) { + tabstrip_->SetVisible(false); + tabstrip_->SetBounds(0, 0, 0, 0); + return 0; + } else { + gfx::Rect layout_bounds = + browser_view_->frame()->GetBoundsForTabStrip(tabstrip_); + gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); + tabstrip_->SetBackgroundOffset( + gfx::Point(layout_bounds.x() - toolbar_bounds.x(), + layout_bounds.y())); + gfx::Point tabstrip_origin = layout_bounds.origin(); + views::View::ConvertPointToView(browser_view_->GetParent(), browser_view_, + &tabstrip_origin); + layout_bounds.set_origin(tabstrip_origin); + tabstrip_->SetVisible(true); + tabstrip_->SetBounds(layout_bounds); + + int bottom = 0; + gfx::Rect tabstrip_bounds; + LayoutCompactNavigationBar( + layout_bounds, &tabstrip_bounds, &bottom); + tabstrip_->SetVisible(true); + tabstrip_->SetBounds(tabstrip_bounds); + return bottom; + } + } + + virtual bool IsPositionInWindowCaption(const gfx::Point& point) { + return BrowserViewLayout::IsPositionInWindowCaption(point) + && !IsPointInViewsInTitleArea(point); + } + + virtual int NonClientHitTest(const gfx::Point& point) { + gfx::Point point_in_browser_view_coords(point); + views::View::ConvertPointToView( + browser_view_->GetParent(), browser_view_, + &point_in_browser_view_coords); + if (IsPointInViewsInTitleArea(point_in_browser_view_coords)) { + return HTCLIENT; + } + return BrowserViewLayout::NonClientHitTest(point); + } + + private: + chromeos::BrowserView* chromeos_browser_view() { + return static_cast(browser_view_); + } + + // Test if the point is on one of views that are within the + // considered title bar area of client view. + bool IsPointInViewsInTitleArea(const gfx::Point& point) + const { + gfx::Point point_in_main_menu_coords(point); + views::View::ConvertPointToView(browser_view_, main_menu_, + &point_in_main_menu_coords); + if (main_menu_->HitTest(point_in_main_menu_coords)) + return true; + + gfx::Point point_in_status_area_coords(point); + views::View::ConvertPointToView(browser_view_, status_area_, + &point_in_status_area_coords); + if (status_area_->HitTest(point_in_status_area_coords)) + return true; + + if (compact_navigation_bar_->IsVisible()) { + gfx::Point point_in_cnb_coords(point); + views::View::ConvertPointToView(browser_view_, + compact_navigation_bar_, + &point_in_cnb_coords); + return compact_navigation_bar_->HitTest(point_in_cnb_coords); + } + return false; + } + + void LayoutCompactNavigationBar(const gfx::Rect& bounds, + gfx::Rect* tabstrip_bounds, + int* bottom) { + if (browser_view_->IsTabStripVisible()) { + *bottom = bounds.bottom(); + } else { + *bottom = 0; + } + // Skip if there is no space to layout, or if the browser is in + // fullscreen mode. + if (bounds.IsEmpty() || browser_view_->IsFullscreen()) { + main_menu_->SetVisible(false); + compact_navigation_bar_->SetVisible(false); + status_area_->SetVisible(false); + tabstrip_bounds->SetRect(bounds.x(), bounds.y(), + bounds.width(), bounds.height()); + return; + } else { + main_menu_->SetVisible(true); + compact_navigation_bar_->SetVisible( + chromeos_browser_view()->is_compact_style()); + status_area_->SetVisible(true); + } + + /* TODO(oshima): + * Disabling the ability to update location bar on re-layout bacause + * tabstrip state may not be in sync with the browser's state when + * new tab is added. We should decide when we know more about this + * feature. May be we should simply hide the location? + * Filed a bug: http://crbug.com/30612. + if (compact_navigation_bar_->IsVisible()) { + // Update the size and location of the compact location bar. + int index = browser_view()->browser()->selected_index(); + compact_location_bar_host_->Update(index, false); + } + */ + + // Layout main menu before tab strip. + gfx::Size main_menu_size = main_menu_->GetPreferredSize(); + + // TODO(oshima): Use 0 for x position for now as this is + // sufficient for chromeos where the window is always + // maximized. The correct value is + // OpaqueBrowserFrameView::NonClientBorderThickness() and we will + // consider exposing it once we settle on the UI. + main_menu_->SetBounds(0, bounds.y(), + main_menu_size.width(), bounds.height()); + + status_area_->Update(); + // Layout status area after tab strip. + gfx::Size status_size = status_area_->GetPreferredSize(); + status_area_->SetBounds(bounds.x() + bounds.width() - status_size.width(), + bounds.y(), status_size.width(), + status_size.height()); + int curx = bounds.x(); + int remaining_width = bounds.width() - status_size.width(); + + if (compact_navigation_bar_->IsVisible()) { + gfx::Size cnb_size = compact_navigation_bar_->GetPreferredSize(); + // Adjust the size of the compact nativation bar to avoid creating + // a fixed widget with its own gdk window. AutocompleteEditView + // expects the parent view to be transparent, but a fixed with + // its own window is not. + gfx::Rect cnb_bounds(curx, bounds.y(), cnb_size.width(), bounds.height()); + compact_navigation_bar_->SetBounds( + cnb_bounds.Intersect(browser_view_->GetVisibleBounds())); + curx += cnb_bounds.width(); + remaining_width -= cnb_bounds.width(); + + spacer_->SetVisible(true); + spacer_->SetBounds(0, *bottom, browser_view_->width(), + kCompactNavbarSpaceHeight); + *bottom += kCompactNavbarSpaceHeight; + } else { + spacer_->SetVisible(false); + } + // In case there is no space left. + remaining_width = std::max(0, remaining_width); + tabstrip_bounds->SetRect(curx, bounds.y(), + remaining_width, bounds.height()); + } + + + views::View* main_menu_; + chromeos::StatusAreaView* status_area_; + views::View* compact_navigation_bar_; + views::View* spacer_; + + DISALLOW_COPY_AND_ASSIGN(BrowserViewLayout); +}; + +BrowserView::BrowserView(Browser* browser) + : BrowserView(browser), + main_menu_(NULL), + status_area_(NULL), + compact_navigation_bar_(NULL), + // Standard style is default. + // TODO(oshima): Get this info from preference. + ui_style_(StandardStyle), + force_maximized_window_(false) { +} + +BrowserView::~BrowserView() { +} + +//////////////////////////////////////////////////////////////////////////////// +// BrowserView, ::BrowserView overrides: + +void BrowserView::Init() { + BrowserView::Init(); + main_menu_ = new views::ImageButton(this); + main_menu_->SetID(VIEW_ID_MAIN_MENU); + ThemeProvider* theme_provider = + frame()->GetThemeProviderForFrame(); + SkBitmap* image = theme_provider->GetBitmapNamed(IDR_MAIN_MENU_BUTTON); + main_menu_->SetImage(views::CustomButton::BS_NORMAL, image); + main_menu_->SetImage(views::CustomButton::BS_HOT, image); + main_menu_->SetImage(views::CustomButton::BS_PUSHED, image); + AddChildView(main_menu_); + + compact_location_bar_host_.reset( + new chromeos::CompactLocationBarHost(this)); + compact_navigation_bar_ = + new chromeos::CompactNavigationBar(this); + compact_navigation_bar_->SetID(VIEW_ID_COMPACT_NAV_BAR); + AddChildView(compact_navigation_bar_); + compact_navigation_bar_->Init(); + status_area_ = new BrowserStatusAreaView(this); + status_area_->SetID(VIEW_ID_STATUS_AREA); + AddChildView(status_area_); + status_area_->Init(); + ToolbarView* toolbar_view = GetToolbarView(); + toolbar_view->SetAppMenuModel(status_area_->CreateAppMenuModel(toolbar_view)); + + SkBitmap* theme_toolbar = theme_provider->GetBitmapNamed(IDR_THEME_TOOLBAR); + spacer_ = new Spacer(theme_toolbar); + spacer_->SetID(VIEW_ID_SPACER); + AddChildView(spacer_); + + InitSystemMenu(); + chromeos::MainMenu::ScheduleCreation(); + + // The ContextMenuController has to be set to a NonClientView but + // not to a NonClientFrameView because a TabStrip is not a child of + // a NonClientFrameView even though visually a TabStrip is over a + // NonClientFrameView. + BrowserFrameGtk* gtk_frame = static_cast(frame()); + gtk_frame->GetNonClientView()->SetContextMenuController(this); + + if (browser()->type() == Browser::TYPE_NORMAL) { + std::string wm_name; + bool wm_name_valid = x11_util::GetWindowManagerName(&wm_name); + // NOTE: On Chrome OS the wm and Chrome are started in parallel. This + // means it's possible for us not to be able to get the name of the window + // manager. We assume that when this happens we're on Chrome OS. + force_maximized_window_ = (!wm_name_valid || + wm_name == kChromeOsWindowManagerName || + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kChromeosFrame)); + } +} + +void BrowserView::Show() { + bool was_visible = frame()->GetWindow()->IsVisible(); + BrowserView::Show(); + if (!was_visible) { + TabOverviewTypes::instance()->SetWindowType( + GTK_WIDGET(frame()->GetWindow()->GetNativeWindow()), + TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL, + NULL); + } +} + +bool BrowserView::IsToolbarVisible() const { + if (is_compact_style()) + return false; + return BrowserView::IsToolbarVisible(); +} + +void BrowserView::SetFocusToLocationBar() { + if (compact_navigation_bar_->IsFocusable()) { + compact_navigation_bar_->FocusLocation(); + } else { + BrowserView::SetFocusToLocationBar(); + } +} + +void BrowserView::ToggleCompactNavigationBar() { + ui_style_ = static_cast((ui_style_ + 1) % 2); + compact_navigation_bar_->SetFocusable(is_compact_style()); + compact_location_bar_host_->SetEnabled(is_compact_style()); + Layout(); +} + +views::LayoutManager* BrowserView::CreateLayoutManager() const { + return new BrowserViewLayout(); +} + +TabStrip* BrowserView::CreateTabStrip( + TabStripModel* tab_strip_model) { + return new ChromeosTabStrip(tab_strip_model, this); +} + +// views::ButtonListener overrides. +void BrowserView::ButtonPressed(views::Button* sender, + const views::Event& event) { + chromeos::MainMenu::Show(browser()); +} + +// views::ContextMenuController overrides. +void BrowserView::ShowContextMenu(views::View* source, int x, int y, + bool is_mouse_gesture) { + system_menu_menu_->RunMenuAt(gfx::Point(x, y), views::Menu2::ALIGN_TOPLEFT); +} + +// StatusAreaHost overrides. +gfx::NativeWindow BrowserView::GetNativeWindow() const { + return GetWindow()->GetNativeWindow(); +} + +void BrowserView::OpenSystemOptionsDialog() const { + browser()->OpenSystemOptionsDialog(); +} + +bool BrowserView::IsButtonVisible(views::View* button_view) const { + if (button_view == status_area_->menu_view()) + return !IsToolbarVisible(); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// BrowserView public: + +void BrowserView::ShowCompactLocationBarUnderSelectedTab() { + if (!is_compact_style()) + return; + int index = browser()->selected_index(); + compact_location_bar_host_->Update(index, true); +} + +bool BrowserView::ShouldForceMaximizedWindow() const { + return force_maximized_window_; +} + +int BrowserView::GetMainMenuWidth() const { + return main_menu_->GetPreferredSize().width(); +} + +//////////////////////////////////////////////////////////////////////////////// +// BrowserView private: + +void BrowserView::InitSystemMenu() { + system_menu_contents_.reset(new menus::SimpleMenuModel(this)); + system_menu_contents_->AddItemWithStringId(IDC_RESTORE_TAB, + IDS_RESTORE_TAB); + system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); + system_menu_contents_->AddSeparator(); + system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER, + IDS_TASK_MANAGER); + system_menu_menu_.reset(new views::Menu2(system_menu_contents_.get())); +} + +} // namespace chromeos + +// static +BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { + // Create a browser view for chromeos. + BrowserView* view; + if (browser->type() & Browser::TYPE_POPUP) + view = new chromeos::PanelBrowserView(browser); + else + view = new chromeos::BrowserView(browser); + BrowserFrame::Create(view, browser->profile()); + return view; +} diff --git a/chrome/browser/chromeos/browser_view.h b/chrome/browser/chromeos/browser_view.h new file mode 100644 index 0000000..9d7b67b --- /dev/null +++ b/chrome/browser/chromeos/browser_view.h @@ -0,0 +1,131 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_BROWSER_VIEW_H_ +#define CHROME_BROWSER_CHROMEOS_BROWSER_VIEW_H_ + +#include "chrome/browser/chromeos/status_area_host.h" +#include "chrome/browser/views/frame/browser_view.h" + +class TabStripModel; + +namespace menus { +class SimpleMenuModel; +} // namespace menus + +namespace views { +class ImageButton; +class Menu2; +} // namespace views + +namespace chromeos { + +class BrowserStatusAreaView; +class CompactLocationBar; +class CompactLocationBarHost; +class CompactNavigationBar; +class StatusAreaButton; + +// chromeos::BrowserView adds ChromeOS specific controls and menus to a +// BrowserView created with Browser::TYPE_NORMAL. This extender adds controls +// to the title bar as follows: +// ____ __ __ +// [MainMenu] / \ \ \ [StatusArea] +// +// and adds the system context menu to the remaining arae of the titlebar. +class BrowserView : public BrowserView, + public views::ButtonListener, + public views::ContextMenuController, + public StatusAreaHost { + public: + // There are 3 ui styles, standard, compact and sidebar. + // Standard uses the same layout as chromium/chrome browser. + // Compact mode hides the omnibox/toolbar to save the vertical real estate, + // and uses QSB (compact nav bar) to launch/switch url. In sidebar mode, + // the tabstrip is moved to the side and the omnibox is moved on top of + // the tabstrip. + enum UIStyle { + StandardStyle, + CompactStyle, + SidebarStyle, + }; + + explicit BrowserView(Browser* browser); + virtual ~BrowserView(); + + // BrowserView overrides. + virtual void Init(); + virtual void Show(); + virtual bool IsToolbarVisible() const; + virtual void SetFocusToLocationBar(); + virtual void ToggleCompactNavigationBar(); + virtual views::LayoutManager* CreateLayoutManager() const; + virtual TabStrip* CreateTabStrip(TabStripModel* tab_strip_model); + + // views::ButtonListener overrides. + virtual void ButtonPressed(views::Button* sender, const views::Event& event); + + // views::ContextMenuController overrides. + virtual void ShowContextMenu(views::View* source, + int x, + int y, + bool is_mouse_gesture); + + // StatusAreaHost overrides. + virtual gfx::NativeWindow GetNativeWindow() const; + virtual void OpenSystemOptionsDialog() const; + virtual bool IsButtonVisible(views::View* button_view) const; + + // Shows the compact location bar under the selected tab. + void ShowCompactLocationBarUnderSelectedTab(); + + // The following methods are temporarily defined for refactroing, and + // will be removed soon. See BrowserExtender class for the description. + bool ShouldForceMaximizedWindow() const; + int GetMainMenuWidth() const; + + // Returns true if the ui style is in Compact mode. + bool is_compact_style() const { + return ui_style_ == CompactStyle; + } + + private: + void InitSystemMenu(); + + // Main menu button. + views::ImageButton* main_menu_; + + // Status Area view. + BrowserStatusAreaView* status_area_; + + // System menus. + scoped_ptr system_menu_contents_; + scoped_ptr system_menu_menu_; + + // CompactNavigationBar view. + chromeos::CompactNavigationBar* compact_navigation_bar_; + + // The current UI style of the browser. + UIStyle ui_style_; + + // CompactLocationBarHost. + scoped_ptr compact_location_bar_host_; + + // A flag to specify if the browser window should be maximized. + bool force_maximized_window_; + + // A spacer under the tap strip used when the compact navigation bar + // is active. + views::View* spacer_; + + // Menu button shown in status area when browser is in compact mode. + StatusAreaButton* menu_view_; + + DISALLOW_COPY_AND_ASSIGN(BrowserView); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_BROWSER_VIEW_H_ + diff --git a/chrome/browser/chromeos/chromeos_browser_view.cc b/chrome/browser/chromeos/chromeos_browser_view.cc deleted file mode 100644 index 861c393..0000000 --- a/chrome/browser/chromeos/chromeos_browser_view.cc +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/chromeos_browser_view.h" - -#include -#include - -#include "app/gfx/canvas.h" -#include "app/menus/simple_menu_model.h" -#include "app/theme_provider.h" -#include "base/command_line.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/chromeos/browser_status_area_view.h" -#include "chrome/browser/chromeos/compact_location_bar_host.h" -#include "chrome/browser/chromeos/compact_navigation_bar.h" -#include "chrome/browser/chromeos/main_menu.h" -#include "chrome/browser/chromeos/panel_browser_view.h" -#include "chrome/browser/chromeos/status_area_button.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/frame/browser_extender.h" -#include "chrome/browser/views/frame/browser_frame_gtk.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/frame/chrome_browser_view_layout_manager.h" -#include "chrome/browser/views/tabs/tab.h" -#include "chrome/browser/views/tabs/tab_overview_types.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/browser/views/toolbar_view.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/x11_util.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/controls/button/button.h" -#include "views/controls/button/image_button.h" -#include "views/controls/menu/menu_2.h" -#include "views/window/hit_test.h" -#include "views/window/window.h" - -namespace { - -const char* kChromeOsWindowManagerName = "chromeos-wm"; -const int kCompactNavbarSpaceHeight = 3; - -// A space we insert between the tabstrip and the content in -// Compact mode. -class Spacer : public views::View { - SkBitmap* background_; - public: - explicit Spacer(SkBitmap* bitmap) : background_(bitmap) {} - - void Paint(gfx::Canvas* canvas) { - canvas->TileImageInt(*background_, 0, 0, width(), height()); - } - - private: - DISALLOW_COPY_AND_ASSIGN(Spacer); -}; - -// A chromeos implementation of Tab that shows the compact location bar. -class ChromeosTab : public Tab { - public: - ChromeosTab(TabStrip* tab_strip, chromeos::ChromeosBrowserView* browser_view) - : Tab(tab_strip), - browser_view_(browser_view) { - } - virtual ~ChromeosTab() {} - - // Overridden from views::View. - virtual void OnMouseEntered(const views::MouseEvent& event) { - TabRenderer::OnMouseEntered(event); - browser_view_->ShowCompactLocationBarUnderSelectedTab(); - } - - private: - chromeos::ChromeosBrowserView* browser_view_; - - DISALLOW_COPY_AND_ASSIGN(ChromeosTab); -}; - -// A Tabstrip that uses ChromeosTab as a Tab implementation. -class ChromeosTabStrip : public TabStrip { - public: - ChromeosTabStrip(TabStripModel* model, - chromeos::ChromeosBrowserView* browser_view) - : TabStrip(model), browser_view_(browser_view) { - } - virtual ~ChromeosTabStrip() {} - - protected: - // Overridden from TabStrip. - virtual Tab* CreateTab() { - return new ChromeosTab(this, browser_view_); - } - - private: - chromeos::ChromeosBrowserView* browser_view_; - - DISALLOW_COPY_AND_ASSIGN(ChromeosTabStrip); -}; - -// View ID used only in ChromeOS. -enum ChromeOSViewIds { - // Start with the offset that is big enough to avoid possible - // collison. - VIEW_ID_MAIN_MENU = VIEW_ID_PREDEFINED_COUNT + 10000, - VIEW_ID_COMPACT_NAV_BAR, - VIEW_ID_STATUS_AREA, - VIEW_ID_SPACER, -}; - -// LayoutManager for ChromeosBrowserView, which layouts extra components such as -// main menu, stataus views. -class ChromeosBrowserViewLayoutManager : public ChromeBrowserViewLayoutManager { - public: - ChromeosBrowserViewLayoutManager() : ChromeBrowserViewLayoutManager() {} - virtual ~ChromeosBrowserViewLayoutManager() {} - - ////////////////////////////////////////////////////////////////////////////// - // ChromeBrowserViewLayoutManager overrides: - - void Installed(views::View* host) { - main_menu_ = NULL; - compact_navigation_bar_ = NULL; - status_area_ = NULL; - spacer_ = NULL; - ChromeBrowserViewLayoutManager::Installed(host); - } - - void ViewAdded(views::View* host, - views::View* view) { - ChromeBrowserViewLayoutManager::ViewAdded(host, view); - switch (view->GetID()) { - case VIEW_ID_SPACER: - spacer_ = view; - break; - case VIEW_ID_MAIN_MENU: - main_menu_ = view; - break; - case VIEW_ID_STATUS_AREA: - status_area_ = static_cast(view); - break; - case VIEW_ID_COMPACT_NAV_BAR: - compact_navigation_bar_ = view; - break; - } - } - - virtual int LayoutTabStrip() { - if (!browser_view_->IsTabStripVisible()) { - tabstrip_->SetVisible(false); - tabstrip_->SetBounds(0, 0, 0, 0); - return 0; - } else { - gfx::Rect layout_bounds = - browser_view_->frame()->GetBoundsForTabStrip(tabstrip_); - gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); - tabstrip_->SetBackgroundOffset( - gfx::Point(layout_bounds.x() - toolbar_bounds.x(), - layout_bounds.y())); - gfx::Point tabstrip_origin = layout_bounds.origin(); - views::View::ConvertPointToView(browser_view_->GetParent(), browser_view_, - &tabstrip_origin); - layout_bounds.set_origin(tabstrip_origin); - tabstrip_->SetVisible(true); - tabstrip_->SetBounds(layout_bounds); - - int bottom = 0; - gfx::Rect tabstrip_bounds; - LayoutCompactNavigationBar( - layout_bounds, &tabstrip_bounds, &bottom); - tabstrip_->SetVisible(true); - tabstrip_->SetBounds(tabstrip_bounds); - return bottom; - } - } - - virtual bool IsPositionInWindowCaption(const gfx::Point& point) { - return ChromeBrowserViewLayoutManager::IsPositionInWindowCaption(point) - && !IsPointInViewsInTitleArea(point); - } - - virtual int NonClientHitTest(const gfx::Point& point) { - gfx::Point point_in_browser_view_coords(point); - views::View::ConvertPointToView( - browser_view_->GetParent(), browser_view_, - &point_in_browser_view_coords); - if (IsPointInViewsInTitleArea(point_in_browser_view_coords)) { - return HTCLIENT; - } - return ChromeBrowserViewLayoutManager::NonClientHitTest(point); - } - - private: - chromeos::ChromeosBrowserView* chromeos_browser_view() { - return static_cast(browser_view_); - } - - // Test if the point is on one of views that are within the - // considered title bar area of client view. - bool IsPointInViewsInTitleArea(const gfx::Point& point) - const { - gfx::Point point_in_main_menu_coords(point); - views::View::ConvertPointToView(browser_view_, main_menu_, - &point_in_main_menu_coords); - if (main_menu_->HitTest(point_in_main_menu_coords)) - return true; - - gfx::Point point_in_status_area_coords(point); - views::View::ConvertPointToView(browser_view_, status_area_, - &point_in_status_area_coords); - if (status_area_->HitTest(point_in_status_area_coords)) - return true; - - if (compact_navigation_bar_->IsVisible()) { - gfx::Point point_in_cnb_coords(point); - views::View::ConvertPointToView(browser_view_, - compact_navigation_bar_, - &point_in_cnb_coords); - return compact_navigation_bar_->HitTest(point_in_cnb_coords); - } - return false; - } - - void LayoutCompactNavigationBar(const gfx::Rect& bounds, - gfx::Rect* tabstrip_bounds, - int* bottom) { - if (browser_view_->IsTabStripVisible()) { - *bottom = bounds.bottom(); - } else { - *bottom = 0; - } - // Skip if there is no space to layout, or if the browser is in - // fullscreen mode. - if (bounds.IsEmpty() || browser_view_->IsFullscreen()) { - main_menu_->SetVisible(false); - compact_navigation_bar_->SetVisible(false); - status_area_->SetVisible(false); - tabstrip_bounds->SetRect(bounds.x(), bounds.y(), - bounds.width(), bounds.height()); - return; - } else { - main_menu_->SetVisible(true); - compact_navigation_bar_->SetVisible( - chromeos_browser_view()->is_compact_style()); - status_area_->SetVisible(true); - } - - /* TODO(oshima): - * Disabling the ability to update location bar on re-layout bacause - * tabstrip state may not be in sync with the browser's state when - * new tab is added. We should decide when we know more about this - * feature. May be we should simply hide the location? - * Filed a bug: http://crbug.com/30612. - if (compact_navigation_bar_->IsVisible()) { - // Update the size and location of the compact location bar. - int index = browser_view()->browser()->selected_index(); - compact_location_bar_host_->Update(index, false); - } - */ - - // Layout main menu before tab strip. - gfx::Size main_menu_size = main_menu_->GetPreferredSize(); - - // TODO(oshima): Use 0 for x position for now as this is - // sufficient for chromeos where the window is always - // maximized. The correct value is - // OpaqueBrowserFrameView::NonClientBorderThickness() and we will - // consider exposing it once we settle on the UI. - main_menu_->SetBounds(0, bounds.y(), - main_menu_size.width(), bounds.height()); - - status_area_->Update(); - // Layout status area after tab strip. - gfx::Size status_size = status_area_->GetPreferredSize(); - status_area_->SetBounds(bounds.x() + bounds.width() - status_size.width(), - bounds.y(), status_size.width(), - status_size.height()); - int curx = bounds.x(); - int remaining_width = bounds.width() - status_size.width(); - - if (compact_navigation_bar_->IsVisible()) { - gfx::Size cnb_size = compact_navigation_bar_->GetPreferredSize(); - // Adjust the size of the compact nativation bar to avoid creating - // a fixed widget with its own gdk window. AutocompleteEditView - // expects the parent view to be transparent, but a fixed with - // its own window is not. - gfx::Rect cnb_bounds(curx, bounds.y(), cnb_size.width(), bounds.height()); - compact_navigation_bar_->SetBounds( - cnb_bounds.Intersect(browser_view_->GetVisibleBounds())); - curx += cnb_bounds.width(); - remaining_width -= cnb_bounds.width(); - - spacer_->SetVisible(true); - spacer_->SetBounds(0, *bottom, browser_view_->width(), - kCompactNavbarSpaceHeight); - *bottom += kCompactNavbarSpaceHeight; - } else { - spacer_->SetVisible(false); - } - // In case there is no space left. - remaining_width = std::max(0, remaining_width); - tabstrip_bounds->SetRect(curx, bounds.y(), - remaining_width, bounds.height()); - } - - - views::View* main_menu_; - chromeos::StatusAreaView* status_area_; - views::View* compact_navigation_bar_; - views::View* spacer_; - - DISALLOW_COPY_AND_ASSIGN(ChromeosBrowserViewLayoutManager); -}; - -} // namespace - -namespace chromeos { - -ChromeosBrowserView::ChromeosBrowserView(Browser* browser) - : BrowserView(browser), - main_menu_(NULL), - status_area_(NULL), - compact_navigation_bar_(NULL), - // Standard style is default. - // TODO(oshima): Get this info from preference. - ui_style_(StandardStyle), - force_maximized_window_(false) { -} - -ChromeosBrowserView::~ChromeosBrowserView() { -} - -//////////////////////////////////////////////////////////////////////////////// -// ChromeosBrowserView, ChromeBrowserView overrides: - -void ChromeosBrowserView::Init() { - BrowserView::Init(); - main_menu_ = new views::ImageButton(this); - main_menu_->SetID(VIEW_ID_MAIN_MENU); - ThemeProvider* theme_provider = - frame()->GetThemeProviderForFrame(); - SkBitmap* image = theme_provider->GetBitmapNamed(IDR_MAIN_MENU_BUTTON); - main_menu_->SetImage(views::CustomButton::BS_NORMAL, image); - main_menu_->SetImage(views::CustomButton::BS_HOT, image); - main_menu_->SetImage(views::CustomButton::BS_PUSHED, image); - AddChildView(main_menu_); - - compact_location_bar_host_.reset( - new chromeos::CompactLocationBarHost(this)); - compact_navigation_bar_ = - new chromeos::CompactNavigationBar(this); - compact_navigation_bar_->SetID(VIEW_ID_COMPACT_NAV_BAR); - AddChildView(compact_navigation_bar_); - compact_navigation_bar_->Init(); - status_area_ = new BrowserStatusAreaView(this); - status_area_->SetID(VIEW_ID_STATUS_AREA); - AddChildView(status_area_); - status_area_->Init(); - ToolbarView* toolbar_view = GetToolbarView(); - toolbar_view->SetAppMenuModel(status_area_->CreateAppMenuModel(toolbar_view)); - - SkBitmap* theme_toolbar = theme_provider->GetBitmapNamed(IDR_THEME_TOOLBAR); - spacer_ = new Spacer(theme_toolbar); - spacer_->SetID(VIEW_ID_SPACER); - AddChildView(spacer_); - - InitSystemMenu(); - chromeos::MainMenu::ScheduleCreation(); - - // The ContextMenuController has to be set to a NonClientView but - // not to a NonClientFrameView because a TabStrip is not a child of - // a NonClientFrameView even though visually a TabStrip is over a - // NonClientFrameView. - BrowserFrameGtk* gtk_frame = static_cast(frame()); - gtk_frame->GetNonClientView()->SetContextMenuController(this); - - if (browser()->type() == Browser::TYPE_NORMAL) { - std::string wm_name; - bool wm_name_valid = x11_util::GetWindowManagerName(&wm_name); - // NOTE: On Chrome OS the wm and Chrome are started in parallel. This - // means it's possible for us not to be able to get the name of the window - // manager. We assume that when this happens we're on Chrome OS. - force_maximized_window_ = (!wm_name_valid || - wm_name == kChromeOsWindowManagerName || - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kChromeosFrame)); - } -} - -void ChromeosBrowserView::Show() { - bool was_visible = frame()->GetWindow()->IsVisible(); - BrowserView::Show(); - if (!was_visible) { - TabOverviewTypes::instance()->SetWindowType( - GTK_WIDGET(frame()->GetWindow()->GetNativeWindow()), - TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL, - NULL); - } -} - -bool ChromeosBrowserView::IsToolbarVisible() const { - if (is_compact_style()) - return false; - return BrowserView::IsToolbarVisible(); -} - -void ChromeosBrowserView::SetFocusToLocationBar() { - if (compact_navigation_bar_->IsFocusable()) { - compact_navigation_bar_->FocusLocation(); - } else { - BrowserView::SetFocusToLocationBar(); - } -} - -void ChromeosBrowserView::ToggleCompactNavigationBar() { - ui_style_ = static_cast((ui_style_ + 1) % 2); - compact_navigation_bar_->SetFocusable(is_compact_style()); - compact_location_bar_host_->SetEnabled(is_compact_style()); - Layout(); -} - -views::LayoutManager* ChromeosBrowserView::CreateLayoutManager() const { - return new ChromeosBrowserViewLayoutManager(); -} - -TabStrip* ChromeosBrowserView::CreateTabStrip( - TabStripModel* tab_strip_model) { - return new ChromeosTabStrip(tab_strip_model, this); -} - -// views::ButtonListener overrides. -void ChromeosBrowserView::ButtonPressed(views::Button* sender, - const views::Event& event) { - chromeos::MainMenu::Show(browser()); -} - -// views::ContextMenuController overrides. -void ChromeosBrowserView::ShowContextMenu(views::View* source, - int x, - int y, - bool is_mouse_gesture) { - system_menu_menu_->RunMenuAt(gfx::Point(x, y), views::Menu2::ALIGN_TOPLEFT); -} - -// StatusAreaHost overrides. -gfx::NativeWindow ChromeosBrowserView::GetNativeWindow() const { - return GetWindow()->GetNativeWindow(); -} - -void ChromeosBrowserView::OpenSystemOptionsDialog() const { - browser()->OpenSystemOptionsDialog(); -} - -bool ChromeosBrowserView::IsButtonVisible(views::View* button_view) const { - if (button_view == status_area_->menu_view()) - return !IsToolbarVisible(); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// ChromeosBrowserView public: - -void ChromeosBrowserView::ShowCompactLocationBarUnderSelectedTab() { - if (!is_compact_style()) - return; - int index = browser()->selected_index(); - compact_location_bar_host_->Update(index, true); -} - -bool ChromeosBrowserView::ShouldForceMaximizedWindow() const { - return force_maximized_window_; -} - -int ChromeosBrowserView::GetMainMenuWidth() const { - return main_menu_->GetPreferredSize().width(); -} - -//////////////////////////////////////////////////////////////////////////////// -// ChromeosBrowserView private: - -void ChromeosBrowserView::InitSystemMenu() { - system_menu_contents_.reset(new menus::SimpleMenuModel(this)); - system_menu_contents_->AddItemWithStringId(IDC_RESTORE_TAB, - IDS_RESTORE_TAB); - system_menu_contents_->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); - system_menu_contents_->AddSeparator(); - system_menu_contents_->AddItemWithStringId(IDC_TASK_MANAGER, - IDS_TASK_MANAGER); - system_menu_menu_.reset(new views::Menu2(system_menu_contents_.get())); -} - -} // namespace chromeos - -// static -BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { - // Create a browser view for chromeos. - BrowserView* view; - if (browser->type() & Browser::TYPE_POPUP) - view = new chromeos::PanelBrowserView(browser); - else - view = new chromeos::ChromeosBrowserView(browser); - BrowserFrame::Create(view, browser->profile()); - return view; -} diff --git a/chrome/browser/chromeos/chromeos_browser_view.h b/chrome/browser/chromeos/chromeos_browser_view.h deleted file mode 100644 index 2000674..0000000 --- a/chrome/browser/chromeos/chromeos_browser_view.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_CHROMEOS_BROWSER_VIEW_H_ -#define CHROME_BROWSER_CHROMEOS_CHROMEOS_BROWSER_VIEW_H_ - -#include "chrome/browser/chromeos/status_area_host.h" -#include "chrome/browser/views/frame/browser_view.h" - -class TabStripModel; - -namespace menus { -class SimpleMenuModel; -} // namespace menus - -namespace views { -class ImageButton; -class Menu2; -} // namespace views - -namespace chromeos { - -class BrowserStatusAreaView; -class CompactLocationBar; -class CompactLocationBarHost; -class CompactNavigationBar; -class StatusAreaButton; - -// ChromeosBrowserView adds ChromeOS specific controls and menus to a -// BrowserView created with Browser::TYPE_NORMAL. This extender adds -// controls to the title bar as follows: -// ____ __ __ -// [MainMenu] / \ \ \ [StatusArea] -// -// and adds the system context menu to the remaining arae of the titlebar. -class ChromeosBrowserView : public BrowserView, - public views::ButtonListener, - public views::ContextMenuController, - public StatusAreaHost { - public: - // There are 3 ui styles, standard, compact and sidebar. - // Standard uses the same layout as chromium/chrome browser. - // Compact mode hides the omnibox/toolbar to save the vertical real estate, - // and uses QSB (compact nav bar) to launch/switch url. In sidebar mode, - // the tabstrip is moved to the side and the omnibox is moved on top of - // the tabstrip. - enum UIStyle { - StandardStyle, - CompactStyle, - SidebarStyle, - }; - - explicit ChromeosBrowserView(Browser* browser); - virtual ~ChromeosBrowserView(); - - // BrowserView overrides. - virtual void Init(); - virtual void Show(); - virtual bool IsToolbarVisible() const; - virtual void SetFocusToLocationBar(); - virtual void ToggleCompactNavigationBar(); - virtual views::LayoutManager* CreateLayoutManager() const; - virtual TabStrip* CreateTabStrip(TabStripModel* tab_strip_model); - - // views::ButtonListener overrides. - virtual void ButtonPressed(views::Button* sender, const views::Event& event); - - // views::ContextMenuController overrides. - virtual void ShowContextMenu(views::View* source, - int x, - int y, - bool is_mouse_gesture); - - // StatusAreaHost overrides. - virtual gfx::NativeWindow GetNativeWindow() const; - virtual void OpenSystemOptionsDialog() const; - virtual bool IsButtonVisible(views::View* button_view) const; - - // Shows the compact location bar under the selected tab. - void ShowCompactLocationBarUnderSelectedTab(); - - // The following methods are temporarily defined for refactroing, and - // will be removed soon. See BrowserExtender class for the description. - bool ShouldForceMaximizedWindow() const; - int GetMainMenuWidth() const; - - // Returns true if the ui style is in Compact mode. - bool is_compact_style() const { - return ui_style_ == CompactStyle; - } - - private: - void InitSystemMenu(); - - // Main menu button. - views::ImageButton* main_menu_; - - // Status Area view. - BrowserStatusAreaView* status_area_; - - // System menus. - scoped_ptr system_menu_contents_; - scoped_ptr system_menu_menu_; - - // CompactNavigationBar view. - chromeos::CompactNavigationBar* compact_navigation_bar_; - - // The current UI style of the browser. - UIStyle ui_style_; - - // CompactLocationBarHost. - scoped_ptr compact_location_bar_host_; - - // A flag to specify if the browser window should be maximized. - bool force_maximized_window_; - - // A spacer under the tap strip used when the compact navigation bar - // is active. - views::View* spacer_; - - // Menu button shown in status area when browser is in compact mode. - StatusAreaButton* menu_view_; - - DISALLOW_COPY_AND_ASSIGN(ChromeosBrowserView); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_CHROMEOS_BROWSER_VIEW_H_ diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index e02d3d5..5eb03d3 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -38,7 +38,7 @@ #include "chrome/browser/views/chrome_views_delegate.h" #include "chrome/browser/views/download_shelf_view.h" #include "chrome/browser/views/extensions/extension_shelf.h" -#include "chrome/browser/views/frame/chrome_browser_view_layout_manager.h" +#include "chrome/browser/views/frame/browser_view_layout.h" #include "chrome/browser/views/frame/browser_extender.h" #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/fullscreen_exit_bubble.h" @@ -524,7 +524,7 @@ bool BrowserView::ShouldFindBarBlendWithBookmarksBar() const { } gfx::Rect BrowserView::GetFindBarBoundingBox() const { - return GetBrowserViewLayoutManager()->GetFindBarBoundingBox(); + return GetBrowserViewLayout()->GetFindBarBoundingBox(); } int BrowserView::GetTabStripHeight() const { @@ -658,7 +658,7 @@ void BrowserView::DetachBrowserBubble(BrowserBubble* bubble) { } bool BrowserView::IsPositionInWindowCaption(const gfx::Point& point) { - return GetBrowserViewLayoutManager()->IsPositionInWindowCaption(point); + return GetBrowserViewLayout()->IsPositionInWindowCaption(point); } /////////////////////////////////////////////////////////////////////////////// @@ -1532,11 +1532,11 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) { } #endif - return GetBrowserViewLayoutManager()->NonClientHitTest(point); + return GetBrowserViewLayout()->NonClientHitTest(point); } gfx::Size BrowserView::GetMinimumSize() { - return GetBrowserViewLayoutManager()->GetMinimumSize(); + return GetBrowserViewLayout()->GetMinimumSize(); } /////////////////////////////////////////////////////////////////////////////// @@ -1590,7 +1590,7 @@ void BrowserView::SetAccessibleName(const std::wstring& name) { } views::LayoutManager* BrowserView::CreateLayoutManager() const { - return new ChromeBrowserViewLayoutManager(); + return new BrowserViewLayout; } TabStrip* BrowserView::CreateTabStrip(TabStripModel* model) { @@ -1692,8 +1692,8 @@ void BrowserView::InitSystemMenu() { } #endif -BrowserViewLayoutManager* BrowserView::GetBrowserViewLayoutManager() const { - return static_cast(GetLayoutManager()); +BrowserViewLayout* BrowserView::GetBrowserViewLayout() const { + return static_cast(GetLayoutManager()); } void BrowserView::LayoutStatusBubble(int top) { diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 516e9bf..32b4491 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -36,7 +36,7 @@ class BookmarkBarView; class Browser; class BrowserBubble; class BrowserExtender; -class BrowserViewLayoutManager; +class BrowserViewLayout; class DownloadShelfView; class EncodingMenuModel; class ExtensionShelf; @@ -388,8 +388,9 @@ class BrowserView : public BrowserWindow, // Creates the system menu. void InitSystemMenu(); #endif - // Returns the BrowserViewLayoutManager. - BrowserViewLayoutManager* GetBrowserViewLayoutManager() const; + + // Returns the BrowserViewLayout. + BrowserViewLayout* GetBrowserViewLayout() const; // Prepare to show the Bookmark Bar for the specified TabContents. Returns // true if the Bookmark Bar can be shown (i.e. it's supported for this diff --git a/chrome/browser/views/frame/browser_view_layout.cc b/chrome/browser/views/frame/browser_view_layout.cc new file mode 100644 index 0000000..e2c5ae1 --- /dev/null +++ b/chrome/browser/views/frame/browser_view_layout.cc @@ -0,0 +1,447 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/frame/browser_view_layout.h" + +#include "app/gfx/scrollbar_size.h" +#include "chrome/browser/find_bar.h" +#include "chrome/browser/find_bar_controller.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/extensions/extension_shelf.h" +#include "chrome/browser/views/frame/browser_extender.h" +#include "chrome/browser/views/frame/browser_frame.h" +#include "chrome/browser/views/frame/browser_view.h" +#include "chrome/browser/views/tabs/tab_strip.h" +#include "chrome/browser/views/toolbar_view.h" +#include "views/window/window.h" + +#if defined(OS_LINUX) +#include "views/window/hit_test.h" +#endif + +namespace { + +// The visible height of the shadow above the tabs. Clicks in this area are +// treated as clicks to the frame, rather than clicks to the tab. +const int kTabShadowSize = 2; +// The vertical overlap between the TabStrip and the Toolbar. +const int kToolbarTabStripVerticalOverlap = 3; +// An offset distance between certain toolbars and the toolbar that preceded +// them in layout. +const int kSeparationLineHeight = 1; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// BrowserViewLayout, public: + +BrowserViewLayout::BrowserViewLayout() + : tabstrip_(NULL), + toolbar_(NULL), + contents_split_(NULL), + contents_container_(NULL), + infobar_container_(NULL), + download_shelf_(NULL), + extension_shelf_(NULL), + active_bookmark_bar_(NULL), + browser_view_(NULL), + find_bar_y_(0) { +} + +gfx::Size BrowserViewLayout::GetMinimumSize() { + // TODO(noname): In theory the tabstrip width should probably be + // (OTR + tabstrip + caption buttons) width. + gfx::Size tabstrip_size( + browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ? + tabstrip_->GetMinimumSize() : gfx::Size()); + gfx::Size toolbar_size( + (browser()->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || + browser()->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) ? + toolbar_->GetMinimumSize() : gfx::Size()); + if (tabstrip_size.height() && toolbar_size.height()) + toolbar_size.Enlarge(0, -kToolbarTabStripVerticalOverlap); + gfx::Size bookmark_bar_size; + if (active_bookmark_bar_ && + browser()->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR)) { + bookmark_bar_size = active_bookmark_bar_->GetMinimumSize(); + bookmark_bar_size.Enlarge( + 0, + -kSeparationLineHeight - + active_bookmark_bar_->GetToolbarOverlap(true)); + } + gfx::Size contents_size(contents_split_->GetMinimumSize()); + + int min_height = tabstrip_size.height() + toolbar_size.height() + + bookmark_bar_size.height() + contents_size.height(); + int widths[] = { tabstrip_size.width(), toolbar_size.width(), + bookmark_bar_size.width(), contents_size.width() }; + int min_width = *std::max_element(&widths[0], &widths[arraysize(widths)]); + return gfx::Size(min_width, min_height); +} + +gfx::Rect BrowserViewLayout::GetFindBarBoundingBox() const { + // This function returns the area the Find Bar can be laid out + // within. This basically implies the "user-perceived content + // area" of the browser window excluding the vertical + // scrollbar. This is not quite so straightforward as positioning + // based on the TabContentsContainer since the BookmarkBarView may + // be visible but not persistent (in the New Tab case) and we + // position the Find Bar over the top of it in that case since the + // BookmarkBarView is not _visually_ connected to the Toolbar. + + // First determine the bounding box of the content area in Widget + // coordinates. + gfx::Rect bounding_box(contents_container_->bounds()); + + gfx::Point topleft; + views::View::ConvertPointToWidget(contents_container_, &topleft); + bounding_box.set_origin(topleft); + + // Adjust the position and size of the bounding box by the find bar offset + // calculated during the last Layout. + int height_delta = find_bar_y_ - bounding_box.y(); + bounding_box.set_y(find_bar_y_); + bounding_box.set_height(std::max(0, bounding_box.height() + height_delta)); + + // Finally decrease the width of the bounding box by the width of + // the vertical scroll bar. + int scrollbar_width = gfx::scrollbar_size(); + bounding_box.set_width(std::max(0, bounding_box.width() - scrollbar_width)); + if (browser_view_->UILayoutIsRightToLeft()) + bounding_box.set_x(bounding_box.x() + scrollbar_width); + + return bounding_box; +} + +bool BrowserViewLayout::IsPositionInWindowCaption( + const gfx::Point& point) { + gfx::Point tabstrip_point(point); + views::View::ConvertPointToView(browser_view_, tabstrip_, &tabstrip_point); + return tabstrip_->IsPositionInWindowCaption(tabstrip_point); +} + +int BrowserViewLayout::NonClientHitTest( + const gfx::Point& point) { + // Since the TabStrip only renders in some parts of the top of the window, + // the un-obscured area is considered to be part of the non-client caption + // area of the window. So we need to treat hit-tests in these regions as + // hit-tests of the titlebar. + + views::View* parent = browser_view_->GetParent(); + + gfx::Point point_in_browser_view_coords(point); + views::View::ConvertPointToView( + parent, browser_view_, &point_in_browser_view_coords); + + // Determine if the TabStrip exists and is capable of being clicked on. We + // might be a popup window without a TabStrip. + if (browser_view_->IsTabStripVisible()) { + + // See if the mouse pointer is within the bounds of the TabStrip. + gfx::Point point_in_tabstrip_coords(point); + views::View::ConvertPointToView(parent, tabstrip_, + &point_in_tabstrip_coords); + if (tabstrip_->HitTest(point_in_tabstrip_coords)) { + if (tabstrip_->IsPositionInWindowCaption(point_in_tabstrip_coords)) + return HTCAPTION; + return HTCLIENT; + } + + // The top few pixels of the TabStrip are a drop-shadow - as we're pretty + // starved of dragable area, let's give it to window dragging (this also + // makes sense visually). + if (!browser_view_->IsMaximized() && + (point_in_browser_view_coords.y() < + (tabstrip_->y() + kTabShadowSize))) { + // We return HTNOWHERE as this is a signal to our containing + // NonClientView that it should figure out what the correct hit-test + // code is given the mouse position... + return HTNOWHERE; + } + } + + // If the point's y coordinate is below the top of the toolbar and otherwise + // within the bounds of this view, the point is considered to be within the + // client area. + gfx::Rect bv_bounds = browser_view_->bounds(); + bv_bounds.Offset(0, toolbar_->y()); + bv_bounds.set_height(bv_bounds.height() - toolbar_->y()); + if (bv_bounds.Contains(point)) + return HTCLIENT; + + // If the point's y coordinate is above the top of the toolbar, but not in + // the tabstrip (per previous checking in this function), then we consider it + // in the window caption (e.g. the area to the right of the tabstrip + // underneath the window controls). However, note that we DO NOT return + // HTCAPTION here, because when the window is maximized the window controls + // will fall into this space (since the BrowserView is sized to entire size + // of the window at that point), and the HTCAPTION value will cause the + // window controls not to work. So we return HTNOWHERE so that the caller + // will hit-test the window controls before finally falling back to + // HTCAPTION. + bv_bounds = browser_view_->bounds(); + bv_bounds.set_height(toolbar_->y()); + if (bv_bounds.Contains(point)) + return HTNOWHERE; + + // If the point is somewhere else, delegate to the default implementation. + return browser_view_->views::ClientView::NonClientHitTest(point); +} + +////////////////////////////////////////////////////////////////////////////// +// BrowserViewLayout, views::LayoutManager implementation: + +void BrowserViewLayout::Installed(views::View* host) { + toolbar_ = NULL; + contents_split_ = NULL; + contents_container_ = NULL; + infobar_container_ = NULL; + download_shelf_ = NULL; + extension_shelf_ = NULL; + active_bookmark_bar_ = NULL; + tabstrip_ = NULL; + browser_view_ = static_cast(host); +} + +void BrowserViewLayout::Uninstalled(views::View* host) {} + +void BrowserViewLayout::ViewAdded(views::View* host, views::View* view) { + switch (view->GetID()) { + case VIEW_ID_CONTENTS_SPLIT: + contents_split_ = view; + contents_container_ = contents_split_->GetChildViewAt(0); + break; + case VIEW_ID_INFO_BAR_CONTAINER: + infobar_container_ = view; + break; + case VIEW_ID_DOWNLOAD_SHELF: + download_shelf_ = static_cast(view); + break; + case VIEW_ID_DEV_EXTENSION_SHELF: + extension_shelf_ = static_cast(view); + break; + case VIEW_ID_BOOKMARK_BAR: + active_bookmark_bar_ = static_cast(view); + break; + case VIEW_ID_TOOLBAR: + toolbar_ = static_cast(view); + break; + case VIEW_ID_TAB_STRIP: + tabstrip_ = static_cast(view); + break; + } +} + +void BrowserViewLayout::ViewRemoved(views::View* host, views::View* view) { + switch (view->GetID()) { + case VIEW_ID_BOOKMARK_BAR: + active_bookmark_bar_ = NULL; + break; + } +} + +void BrowserViewLayout::Layout(views::View* host) { + int top = LayoutTabStrip(); + top = LayoutToolbar(top); + top = LayoutBookmarkAndInfoBars(top); + int bottom = LayoutExtensionAndDownloadShelves(); + LayoutTabContents(top, bottom); + // This must be done _after_ we lay out the TabContents since this + // code calls back into us to find the bounding box the find bar + // must be laid out within, and that code depends on the + // TabContentsContainer's bounds being up to date. + if (browser()->HasFindBarController()) { + browser()->GetFindBarController()->find_bar()->MoveWindowIfNecessary( + gfx::Rect(), true); + } + // Align status bubble with the bottom of the contents_container. + browser_view_->LayoutStatusBubble( + top + contents_container_->bounds().height()); + browser_view_->SchedulePaint(); +} + +// Return the preferred size which is the size required to give each +// children their respective preferred size. +gfx::Size BrowserViewLayout::GetPreferredSize(views::View* host) { + return gfx::Size(); +} + +////////////////////////////////////////////////////////////////////////////// +// BrowserViewLayout, private: + +int BrowserViewLayout::LayoutTabStrip() { + if (!browser_view_->IsTabStripVisible()) { + tabstrip_->SetVisible(false); + tabstrip_->SetBounds(0, 0, 0, 0); + return 0; + } else { + gfx::Rect layout_bounds = + browser_view_->frame()->GetBoundsForTabStrip(tabstrip_); + gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); + tabstrip_->SetBackgroundOffset( + gfx::Point(layout_bounds.x() - toolbar_bounds.x(), layout_bounds.y())); + + gfx::Point tabstrip_origin = layout_bounds.origin(); + views::View::ConvertPointToView(browser_view_->GetParent(), browser_view_, + &tabstrip_origin); + layout_bounds.set_origin(tabstrip_origin); + tabstrip_->SetVisible(true); + tabstrip_->SetBounds(layout_bounds); + return layout_bounds.bottom(); + } +} + +int BrowserViewLayout::LayoutToolbar(int top) { + int browser_view_width = browser_view_->width(); + bool visible = browser_view_->IsToolbarVisible(); + toolbar_->location_bar()->SetFocusable(visible); + int y = top - + ((visible && browser_view_->IsTabStripVisible()) + ? kToolbarTabStripVerticalOverlap : 0); + int height = visible ? toolbar_->GetPreferredSize().height() : 0; + toolbar_->SetVisible(visible); + toolbar_->SetBounds(0, y, browser_view_width, height); + return y + height; +} + +int BrowserViewLayout::LayoutBookmarkAndInfoBars(int top) { + find_bar_y_ = top + browser_view_->y() - 1; + if (active_bookmark_bar_) { + // If we're showing the Bookmark bar in detached style, then we + // need to show any Info bar _above_ the Bookmark bar, since the + // Bookmark bar is styled to look like it's part of the page. + if (active_bookmark_bar_->IsDetached()) + return LayoutTopBar(LayoutInfoBar(top)); + // Otherwise, Bookmark bar first, Info bar second. + top = LayoutTopBar(top); + } + find_bar_y_ = top + browser_view_->y() - 1; + return LayoutInfoBar(top); +} + +int BrowserViewLayout::LayoutTopBar(int top) { + // This method lays out the the bookmark bar, and, if required, + // the extension shelf by its side. The bookmark bar appears on + // the right of the extension shelf. If there are too many + // bookmark items and extension toolstrips to fit in the single + // bar, some compromises are made as follows: 1. The bookmark bar + // is shrunk till it reaches the minimum width. 2. After reaching + // the minimum width, the bookmark bar width is kept fixed - the + // extension shelf bar width is reduced. + DCHECK(active_bookmark_bar_); + int y = top, x = 0; + if (!browser_view_->IsBookmarkBarVisible()) { + active_bookmark_bar_->SetVisible(false); + active_bookmark_bar_->SetBounds(0, y, browser_view_->width(), 0); + if (extension_shelf_->IsOnTop()) + extension_shelf_->SetVisible(false); + return y; + } + + int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height(); + y -= kSeparationLineHeight + ( + active_bookmark_bar_->IsDetached() ? + 0 : active_bookmark_bar_->GetToolbarOverlap(false)); + + if (extension_shelf_->IsOnTop()) { + if (!active_bookmark_bar_->IsDetached()) { + int extension_shelf_width = + extension_shelf_->GetPreferredSize().width(); + int bookmark_bar_given_width = + browser_view_->width() - extension_shelf_width; + int minimum_allowed_bookmark_bar_width = + active_bookmark_bar_->GetMinimumSize().width(); + if (bookmark_bar_given_width < minimum_allowed_bookmark_bar_width) { + // The bookmark bar cannot compromise on its width any more. The + // extension shelf needs to shrink now. + extension_shelf_width = + browser_view_->width() - minimum_allowed_bookmark_bar_width; + } + extension_shelf_->SetVisible(true); + extension_shelf_->SetBounds(x, y, extension_shelf_width, + bookmark_bar_height); + x += extension_shelf_width; + } else { + // TODO(sidchat): For detached style bookmark bar, set the extensions + // shelf in a better position. Issue = 20741. + extension_shelf_->SetVisible(false); + } + } + + active_bookmark_bar_->SetVisible(true); + active_bookmark_bar_->SetBounds(x, y, + browser_view_->width() - x, + bookmark_bar_height); + return y + bookmark_bar_height; +} + +int BrowserViewLayout::LayoutInfoBar(int top) { + bool visible = browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR); + int height = visible ? infobar_container_->GetPreferredSize().height() : 0; + infobar_container_->SetVisible(visible); + infobar_container_->SetBounds(0, top, browser_view_->width(), height); + return top + height; +} + +// Layout the TabContents container, between the coordinates |top| and +// |bottom|. +void BrowserViewLayout::LayoutTabContents(int top, int bottom) { + contents_split_->SetBounds(0, top, browser_view_->width(), bottom - top); +} + +int BrowserViewLayout::LayoutExtensionAndDownloadShelves() { + // If we're showing the Extension bar in detached style, then we + // need to show Download shelf _above_ the Extension bar, since + // the Extension bar is styled to look like it's part of the page. + // + // TODO(Oshima): confirm this comment. + int bottom = browser_view_->height(); + if (extension_shelf_) { + if (extension_shelf_->IsDetached()) { + bottom = LayoutDownloadShelf(bottom); + return LayoutExtensionShelf(bottom); + } + // Otherwise, Extension shelf first, Download shelf second. + bottom = LayoutExtensionShelf(bottom); + } + return LayoutDownloadShelf(bottom); +} + +int BrowserViewLayout::LayoutDownloadShelf(int bottom) { + // Re-layout the shelf either if it is visible or if it's close animation + // is currently running. + if (browser_view_->IsDownloadShelfVisible() || + (download_shelf_ && download_shelf_->IsClosing())) { + bool visible = browser()->SupportsWindowFeature( + Browser::FEATURE_DOWNLOADSHELF); + DCHECK(download_shelf_); + int height = visible ? download_shelf_->GetPreferredSize().height() : 0; + download_shelf_->SetVisible(visible); + download_shelf_->SetBounds(0, bottom - height, + browser_view_->width(), height); + download_shelf_->Layout(); + bottom -= height; + } + return bottom; +} + +int BrowserViewLayout::LayoutExtensionShelf(int bottom) { + if (!extension_shelf_ || extension_shelf_->IsOnTop()) + return bottom; + + if (extension_shelf_) { + bool visible = browser()->SupportsWindowFeature( + Browser::FEATURE_EXTENSIONSHELF); + int height = + visible ? extension_shelf_->GetPreferredSize().height() : 0; + extension_shelf_->SetVisible(visible); + extension_shelf_->SetBounds(0, bottom - height, + browser_view_->width(), height); + extension_shelf_->Layout(); + bottom -= height; + } + return bottom; +} diff --git a/chrome/browser/views/frame/browser_view_layout.h b/chrome/browser/views/frame/browser_view_layout.h new file mode 100644 index 0000000..33333fa --- /dev/null +++ b/chrome/browser/views/frame/browser_view_layout.h @@ -0,0 +1,89 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ +#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ + +#include "chrome/browser/views/frame/browser_view.h" +#include "views/layout_manager.h" + +// The layout manager used in chrome browser. +class BrowserViewLayout : public views::LayoutManager { + public: + BrowserViewLayout(); + virtual ~BrowserViewLayout() {} + + // Returns the minimum size of the browser view. + virtual gfx::Size GetMinimumSize(); + + // Returns the bounding box for the find bar. + virtual gfx::Rect GetFindBarBoundingBox() const; + + // Returns true if the specified point(BrowserView coordinates) is in + // in the window caption area of the browser window. + virtual bool IsPositionInWindowCaption(const gfx::Point& point); + + // Tests to see if the specified |point| (in nonclient view's coordinates) + // is within the views managed by the laymanager. Returns one of + // HitTestCompat enum defined in views/window/hit_test.h. + // See also ClientView::NonClientHitTest. + virtual int NonClientHitTest(const gfx::Point& point); + + // views::LayoutManager overrides: + virtual void Installed(views::View* host); + virtual void Uninstalled(views::View* host); + virtual void ViewAdded(views::View* host, views::View* view); + virtual void ViewRemoved(views::View* host, views::View* view); + virtual void Layout(views::View* host); + virtual gfx::Size GetPreferredSize(views::View* host); + + protected: + Browser* browser() { + return browser_view_->browser(); + } + + // Layout the TabStrip, returns the coordinate of the bottom of the TabStrip, + // for laying out subsequent controls. + virtual 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 LayoutTopBar(int top); + int LayoutInfoBar(int top); + + // Layout the TabContents container, between the coordinates |top| and + // |bottom|. + void LayoutTabContents(int top, int bottom); + int LayoutExtensionAndDownloadShelves(); + + // Layout the Download Shelf, returns the coordinate of the top of the + // control, for laying out the previous control. + int LayoutDownloadShelf(int bottom); + + // Layout the Extension Shelf, returns the coordinate of the top of the + // control, for laying out the previous control. + int LayoutExtensionShelf(int bottom); + + // Child views that the layout manager manages. + TabStrip* tabstrip_; + ToolbarView* toolbar_; + views::View* contents_split_; + views::View* contents_container_; + views::View* infobar_container_; + DownloadShelfView* download_shelf_; + ExtensionShelf* extension_shelf_; + BookmarkBarView* active_bookmark_bar_; + + BrowserView* browser_view_; + + // The distance the FindBar is from the top of the window, in pixels. + int find_bar_y_; + + DISALLOW_COPY_AND_ASSIGN(BrowserViewLayout); +}; + +#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ + diff --git a/chrome/browser/views/frame/browser_view_layout_manager.h b/chrome/browser/views/frame/browser_view_layout_manager.h deleted file mode 100644 index f39b877..0000000 --- a/chrome/browser/views/frame/browser_view_layout_manager.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_MANAGER_H_ -#define CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_MANAGER_H_ - -#include "base/gfx/size.h" -#include "views/layout_manager.h" - -// An extended LayoutManager to layout components in -// BrowserView. -class BrowserViewLayoutManager : public views::LayoutManager { - public: - // Returns the minimum size of the browser view. - virtual gfx::Size GetMinimumSize() = 0; - - // Returns the bounding box for the find bar. - virtual gfx::Rect GetFindBarBoundingBox() const = 0; - - // Returns true if the specified point(BrowserView coordinates) is in - // in the window caption area of the browser window. - virtual bool IsPositionInWindowCaption(const gfx::Point& point) = 0; - - // Tests to see if the specified |point| (in nonclient view's coordinates) - // is within the views managed by the laymanager. Returns one of - // HitTestCompat enum defined in views/window/hit_test.h. - // See also ClientView::NonClientHitTest. - virtual int NonClientHitTest(const gfx::Point& point) = 0; -}; - -#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_MANAGER_H_ diff --git a/chrome/browser/views/frame/chrome_browser_view_layout_manager.cc b/chrome/browser/views/frame/chrome_browser_view_layout_manager.cc deleted file mode 100644 index 8994f75..0000000 --- a/chrome/browser/views/frame/chrome_browser_view_layout_manager.cc +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/views/frame/chrome_browser_view_layout_manager.h" - -#include "app/gfx/scrollbar_size.h" -#include "chrome/browser/find_bar.h" -#include "chrome/browser/find_bar_controller.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/extensions/extension_shelf.h" -#include "chrome/browser/views/frame/browser_extender.h" -#include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/browser/views/frame/browser_view.h" -#include "chrome/browser/views/tabs/tab_strip.h" -#include "chrome/browser/views/toolbar_view.h" -#include "views/window/window.h" - -#if defined(OS_LINUX) -#include "views/window/hit_test.h" -#endif - -// The visible height of the shadow above the tabs. Clicks in this area are -// treated as clicks to the frame, rather than clicks to the tab. -static const int kTabShadowSize = 2; -// The vertical overlap between the TabStrip and the Toolbar. -static const int kToolbarTabStripVerticalOverlap = 3; -// An offset distance between certain toolbars and the toolbar that preceded -// them in layout. -static const int kSeparationLineHeight = 1; - -ChromeBrowserViewLayoutManager::ChromeBrowserViewLayoutManager() - : tabstrip_(NULL), - toolbar_(NULL), - contents_split_(NULL), - contents_container_(NULL), - infobar_container_(NULL), - download_shelf_(NULL), - extension_shelf_(NULL), - active_bookmark_bar_(NULL), - browser_view_(NULL), - find_bar_y_(0) { -} - -////////////////////////////////////////////////////////////////////////////// -// Overridden from LayoutManager. - -void ChromeBrowserViewLayoutManager::Installed(views::View* host) { - toolbar_ = NULL; - contents_split_ = NULL; - contents_container_ = NULL; - infobar_container_ = NULL; - download_shelf_ = NULL; - extension_shelf_ = NULL; - active_bookmark_bar_ = NULL; - tabstrip_ = NULL; - browser_view_ = static_cast(host); -} - -void ChromeBrowserViewLayoutManager::Uninstalled(views::View* host) {} - -void ChromeBrowserViewLayoutManager::ViewAdded(views::View* host, - views::View* view) { - switch (view->GetID()) { - case VIEW_ID_CONTENTS_SPLIT: - contents_split_ = view; - contents_container_ = contents_split_->GetChildViewAt(0); - break; - case VIEW_ID_INFO_BAR_CONTAINER: - infobar_container_ = view; - break; - case VIEW_ID_DOWNLOAD_SHELF: - download_shelf_ = static_cast(view); - break; - case VIEW_ID_DEV_EXTENSION_SHELF: - extension_shelf_ = static_cast(view); - break; - case VIEW_ID_BOOKMARK_BAR: - active_bookmark_bar_ = static_cast(view); - break; - case VIEW_ID_TOOLBAR: - toolbar_ = static_cast(view); - break; - case VIEW_ID_TAB_STRIP: - tabstrip_ = static_cast(view); - break; - } -} - -void ChromeBrowserViewLayoutManager::ViewRemoved(views::View* host, - views::View* view) { - switch (view->GetID()) { - case VIEW_ID_BOOKMARK_BAR: - active_bookmark_bar_ = NULL; - break; - } -} - -void ChromeBrowserViewLayoutManager::Layout(views::View* host) { - int top = LayoutTabStrip(); - top = LayoutToolbar(top); - top = LayoutBookmarkAndInfoBars(top); - int bottom = LayoutExtensionAndDownloadShelves(); - LayoutTabContents(top, bottom); - // This must be done _after_ we lay out the TabContents since this - // code calls back into us to find the bounding box the find bar - // must be laid out within, and that code depends on the - // TabContentsContainer's bounds being up to date. - if (browser()->HasFindBarController()) { - browser()->GetFindBarController()->find_bar()->MoveWindowIfNecessary( - gfx::Rect(), true); - } - // Align status bubble with the bottom of the contents_container. - browser_view_->LayoutStatusBubble( - top + contents_container_->bounds().height()); - browser_view_->SchedulePaint(); -} - -// Return the preferred size which is the size required to give each -// children their respective preferred size. -gfx::Size ChromeBrowserViewLayoutManager::GetPreferredSize(views::View* host) { - return gfx::Size(); -} - -////////////////////////////////////////////////////////////////////////////// -// Overridden from BrowserViewLayoutManager. - -gfx::Size ChromeBrowserViewLayoutManager::GetMinimumSize() { - // TODO(noname): In theory the tabstrip width should probably be - // (OTR + tabstrip + caption buttons) width. - gfx::Size tabstrip_size( - browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ? - tabstrip_->GetMinimumSize() : gfx::Size()); - gfx::Size toolbar_size( - (browser()->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || - browser()->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)) ? - toolbar_->GetMinimumSize() : gfx::Size()); - if (tabstrip_size.height() && toolbar_size.height()) - toolbar_size.Enlarge(0, -kToolbarTabStripVerticalOverlap); - gfx::Size bookmark_bar_size; - if (active_bookmark_bar_ && - browser()->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR)) { - bookmark_bar_size = active_bookmark_bar_->GetMinimumSize(); - bookmark_bar_size.Enlarge( - 0, - -kSeparationLineHeight - - active_bookmark_bar_->GetToolbarOverlap(true)); - } - gfx::Size contents_size(contents_split_->GetMinimumSize()); - - int min_height = tabstrip_size.height() + toolbar_size.height() + - bookmark_bar_size.height() + contents_size.height(); - int widths[] = { tabstrip_size.width(), toolbar_size.width(), - bookmark_bar_size.width(), contents_size.width() }; - int min_width = *std::max_element(&widths[0], &widths[arraysize(widths)]); - return gfx::Size(min_width, min_height); -} - -gfx::Rect ChromeBrowserViewLayoutManager::GetFindBarBoundingBox() const { - // This function returns the area the Find Bar can be laid out - // within. This basically implies the "user-perceived content - // area" of the browser window excluding the vertical - // scrollbar. This is not quite so straightforward as positioning - // based on the TabContentsContainer since the BookmarkBarView may - // be visible but not persistent (in the New Tab case) and we - // position the Find Bar over the top of it in that case since the - // BookmarkBarView is not _visually_ connected to the Toolbar. - - // First determine the bounding box of the content area in Widget - // coordinates. - gfx::Rect bounding_box(contents_container_->bounds()); - - gfx::Point topleft; - views::View::ConvertPointToWidget(contents_container_, &topleft); - bounding_box.set_origin(topleft); - - // Adjust the position and size of the bounding box by the find bar offset - // calculated during the last Layout. - int height_delta = find_bar_y_ - bounding_box.y(); - bounding_box.set_y(find_bar_y_); - bounding_box.set_height(std::max(0, bounding_box.height() + height_delta)); - - // Finally decrease the width of the bounding box by the width of - // the vertical scroll bar. - int scrollbar_width = gfx::scrollbar_size(); - bounding_box.set_width(std::max(0, bounding_box.width() - scrollbar_width)); - if (browser_view_->UILayoutIsRightToLeft()) - bounding_box.set_x(bounding_box.x() + scrollbar_width); - - return bounding_box; -} - -bool ChromeBrowserViewLayoutManager::IsPositionInWindowCaption( - const gfx::Point& point) { - gfx::Point tabstrip_point(point); - views::View::ConvertPointToView(browser_view_, tabstrip_, &tabstrip_point); - return tabstrip_->IsPositionInWindowCaption(tabstrip_point); -} - -int ChromeBrowserViewLayoutManager::NonClientHitTest( - const gfx::Point& point) { - // Since the TabStrip only renders in some parts of the top of the window, - // the un-obscured area is considered to be part of the non-client caption - // area of the window. So we need to treat hit-tests in these regions as - // hit-tests of the titlebar. - - views::View* parent = browser_view_->GetParent(); - - gfx::Point point_in_browser_view_coords(point); - views::View::ConvertPointToView( - parent, browser_view_, &point_in_browser_view_coords); - - // Determine if the TabStrip exists and is capable of being clicked on. We - // might be a popup window without a TabStrip. - if (browser_view_->IsTabStripVisible()) { - - // See if the mouse pointer is within the bounds of the TabStrip. - gfx::Point point_in_tabstrip_coords(point); - views::View::ConvertPointToView(parent, tabstrip_, - &point_in_tabstrip_coords); - if (tabstrip_->HitTest(point_in_tabstrip_coords)) { - if (tabstrip_->IsPositionInWindowCaption(point_in_tabstrip_coords)) - return HTCAPTION; - return HTCLIENT; - } - - // The top few pixels of the TabStrip are a drop-shadow - as we're pretty - // starved of dragable area, let's give it to window dragging (this also - // makes sense visually). - if (!browser_view_->IsMaximized() && - (point_in_browser_view_coords.y() < - (tabstrip_->y() + kTabShadowSize))) { - // We return HTNOWHERE as this is a signal to our containing - // NonClientView that it should figure out what the correct hit-test - // code is given the mouse position... - return HTNOWHERE; - } - } - - // If the point's y coordinate is below the top of the toolbar and otherwise - // within the bounds of this view, the point is considered to be within the - // client area. - gfx::Rect bv_bounds = browser_view_->bounds(); - bv_bounds.Offset(0, toolbar_->y()); - bv_bounds.set_height(bv_bounds.height() - toolbar_->y()); - if (bv_bounds.Contains(point)) - return HTCLIENT; - - // If the point's y coordinate is above the top of the toolbar, but not in - // the tabstrip (per previous checking in this function), then we consider it - // in the window caption (e.g. the area to the right of the tabstrip - // underneath the window controls). However, note that we DO NOT return - // HTCAPTION here, because when the window is maximized the window controls - // will fall into this space (since the BrowserView is sized to entire size - // of the window at that point), and the HTCAPTION value will cause the - // window controls not to work. So we return HTNOWHERE so that the caller - // will hit-test the window controls before finally falling back to - // HTCAPTION. - bv_bounds = browser_view_->bounds(); - bv_bounds.set_height(toolbar_->y()); - if (bv_bounds.Contains(point)) - return HTNOWHERE; - - // If the point is somewhere else, delegate to the default implementation. - return browser_view_->views::ClientView::NonClientHitTest(point); -} - -////////////////////////////////////////////////////////////////////////////// -// Overridden from ChromeBrowserViewLayoutManager, private: - -int ChromeBrowserViewLayoutManager::LayoutTabStrip() { - if (!browser_view_->IsTabStripVisible()) { - tabstrip_->SetVisible(false); - tabstrip_->SetBounds(0, 0, 0, 0); - return 0; - } else { - gfx::Rect layout_bounds = - browser_view_->frame()->GetBoundsForTabStrip(tabstrip_); - gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); - tabstrip_->SetBackgroundOffset( - gfx::Point(layout_bounds.x() - toolbar_bounds.x(), layout_bounds.y())); - - gfx::Point tabstrip_origin = layout_bounds.origin(); - views::View::ConvertPointToView(browser_view_->GetParent(), browser_view_, - &tabstrip_origin); - layout_bounds.set_origin(tabstrip_origin); - tabstrip_->SetVisible(true); - tabstrip_->SetBounds(layout_bounds); - return layout_bounds.bottom(); - } -} - -// Layout the following controls, starting at |top|, returns the coordinate -// of the bottom of the control, for laying out the next control. -int ChromeBrowserViewLayoutManager::LayoutToolbar(int top) { - int browser_view_width = browser_view_->width(); - bool visible = browser_view_->IsToolbarVisible(); - toolbar_->location_bar()->SetFocusable(visible); - int y = top - - ((visible && browser_view_->IsTabStripVisible()) - ? kToolbarTabStripVerticalOverlap : 0); - int height = visible ? toolbar_->GetPreferredSize().height() : 0; - toolbar_->SetVisible(visible); - toolbar_->SetBounds(0, y, browser_view_width, height); - return y + height; -} - -int ChromeBrowserViewLayoutManager::LayoutBookmarkAndInfoBars(int top) { - find_bar_y_ = top + browser_view_->y() - 1; - if (active_bookmark_bar_) { - // If we're showing the Bookmark bar in detached style, then we - // need to show any Info bar _above_ the Bookmark bar, since the - // Bookmark bar is styled to look like it's part of the page. - if (active_bookmark_bar_->IsDetached()) - return LayoutTopBar(LayoutInfoBar(top)); - // Otherwise, Bookmark bar first, Info bar second. - top = LayoutTopBar(top); - } - find_bar_y_ = top + browser_view_->y() - 1; - return LayoutInfoBar(top); -} - -int ChromeBrowserViewLayoutManager::LayoutTopBar(int top) { - // This method lays out the the bookmark bar, and, if required, - // the extension shelf by its side. The bookmark bar appears on - // the right of the extension shelf. If there are too many - // bookmark items and extension toolstrips to fit in the single - // bar, some compromises are made as follows: 1. The bookmark bar - // is shrunk till it reaches the minimum width. 2. After reaching - // the minimum width, the bookmark bar width is kept fixed - the - // extension shelf bar width is reduced. - DCHECK(active_bookmark_bar_); - int y = top, x = 0; - if (!browser_view_->IsBookmarkBarVisible()) { - active_bookmark_bar_->SetVisible(false); - active_bookmark_bar_->SetBounds(0, y, browser_view_->width(), 0); - if (extension_shelf_->IsOnTop()) - extension_shelf_->SetVisible(false); - return y; - } - - int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height(); - y -= kSeparationLineHeight + ( - active_bookmark_bar_->IsDetached() ? - 0 : active_bookmark_bar_->GetToolbarOverlap(false)); - - if (extension_shelf_->IsOnTop()) { - if (!active_bookmark_bar_->IsDetached()) { - int extension_shelf_width = - extension_shelf_->GetPreferredSize().width(); - int bookmark_bar_given_width = - browser_view_->width() - extension_shelf_width; - int minimum_allowed_bookmark_bar_width = - active_bookmark_bar_->GetMinimumSize().width(); - if (bookmark_bar_given_width < minimum_allowed_bookmark_bar_width) { - // The bookmark bar cannot compromise on its width any more. The - // extension shelf needs to shrink now. - extension_shelf_width = - browser_view_->width() - minimum_allowed_bookmark_bar_width; - } - extension_shelf_->SetVisible(true); - extension_shelf_->SetBounds(x, y, extension_shelf_width, - bookmark_bar_height); - x += extension_shelf_width; - } else { - // TODO(sidchat): For detached style bookmark bar, set the extensions - // shelf in a better position. Issue = 20741. - extension_shelf_->SetVisible(false); - } - } - - active_bookmark_bar_->SetVisible(true); - active_bookmark_bar_->SetBounds(x, y, - browser_view_->width() - x, - bookmark_bar_height); - return y + bookmark_bar_height; -} - -int ChromeBrowserViewLayoutManager::LayoutInfoBar(int top) { - bool visible = browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR); - int height = visible ? infobar_container_->GetPreferredSize().height() : 0; - infobar_container_->SetVisible(visible); - infobar_container_->SetBounds(0, top, browser_view_->width(), height); - return top + height; -} - -// Layout the TabContents container, between the coordinates |top| and -// |bottom|. -void ChromeBrowserViewLayoutManager::LayoutTabContents(int top, int bottom) { - contents_split_->SetBounds(0, top, browser_view_->width(), bottom - top); -} - -int ChromeBrowserViewLayoutManager::LayoutExtensionAndDownloadShelves() { - // If we're showing the Extension bar in detached style, then we - // need to show Download shelf _above_ the Extension bar, since - // the Extension bar is styled to look like it's part of the page. - // - // TODO(Oshima): confirm this comment. - int bottom = browser_view_->height(); - if (extension_shelf_) { - if (extension_shelf_->IsDetached()) { - bottom = LayoutDownloadShelf(bottom); - return LayoutExtensionShelf(bottom); - } - // Otherwise, Extension shelf first, Download shelf second. - bottom = LayoutExtensionShelf(bottom); - } - return LayoutDownloadShelf(bottom); -} - -// Layout the Download Shelf, returns the coordinate of the top of the -// control, for laying out the previous control. -int ChromeBrowserViewLayoutManager::LayoutDownloadShelf(int bottom) { - // Re-layout the shelf either if it is visible or if it's close animation - // is currently running. - if (browser_view_->IsDownloadShelfVisible() || - (download_shelf_ && download_shelf_->IsClosing())) { - bool visible = browser()->SupportsWindowFeature( - Browser::FEATURE_DOWNLOADSHELF); - DCHECK(download_shelf_); - int height = visible ? download_shelf_->GetPreferredSize().height() : 0; - download_shelf_->SetVisible(visible); - download_shelf_->SetBounds(0, bottom - height, - browser_view_->width(), height); - download_shelf_->Layout(); - bottom -= height; - } - return bottom; -} - -// Layout the Extension Shelf, returns the coordinate of the top of the -// control, for laying out the previous control. -int ChromeBrowserViewLayoutManager::LayoutExtensionShelf(int bottom) { - if (!extension_shelf_ || extension_shelf_->IsOnTop()) - return bottom; - - if (extension_shelf_) { - bool visible = browser()->SupportsWindowFeature( - Browser::FEATURE_EXTENSIONSHELF); - int height = - visible ? extension_shelf_->GetPreferredSize().height() : 0; - extension_shelf_->SetVisible(visible); - extension_shelf_->SetBounds(0, bottom - height, - browser_view_->width(), height); - extension_shelf_->Layout(); - bottom -= height; - } - return bottom; -} diff --git a/chrome/browser/views/frame/chrome_browser_view_layout_manager.h b/chrome/browser/views/frame/chrome_browser_view_layout_manager.h deleted file mode 100644 index 19334a4..0000000 --- a/chrome/browser/views/frame/chrome_browser_view_layout_manager.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_VIEWS_FRAME_CHROME_BROWSER_VIEW_LAYOUT_MANAGER_H_ -#define CHROME_BROWSER_VIEWS_FRAME_CHROME_BROWSER_VIEW_LAYOUT_MANAGER_H_ - -#include "chrome/browser/views/frame/browser_view_layout_manager.h" -#include "chrome/browser/views/frame/browser_view.h" - -// The layout manager used in chrome browser. -class ChromeBrowserViewLayoutManager : public BrowserViewLayoutManager { - public: - ChromeBrowserViewLayoutManager(); - virtual ~ChromeBrowserViewLayoutManager() {} - - ////////////////////////////////////////////////////////////////////////////// - // Overridden from LayoutManager. - virtual void Installed(views::View* host); - virtual void Uninstalled(views::View* host); - virtual void ViewAdded(views::View* host, views::View* view); - virtual void ViewRemoved(views::View* host, views::View* view); - virtual void Layout(views::View* host); - virtual gfx::Size GetPreferredSize(views::View* host); - - ////////////////////////////////////////////////////////////////////////////// - // Overridden from BrowserLayoutManager. - virtual gfx::Size GetMinimumSize(); - virtual gfx::Rect GetFindBarBoundingBox() const; - virtual bool IsPositionInWindowCaption(const gfx::Point& point); - virtual int NonClientHitTest(const gfx::Point& point); - - protected: - Browser* browser() { - return browser_view_->browser(); - } - - // Layout the TabStrip, returns the coordinate of the bottom of the TabStrip, - // for laying out subsequent controls. - virtual 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 LayoutTopBar(int top); - int LayoutInfoBar(int top); - - // Layout the TabContents container, between the coordinates |top| and - // |bottom|. - void LayoutTabContents(int top, int bottom); - int LayoutExtensionAndDownloadShelves(); - - // Layout the Download Shelf, returns the coordinate of the top of the - // control, for laying out the previous control. - int LayoutDownloadShelf(int bottom); - - // Layout the Extension Shelf, returns the coordinate of the top of the - // control, for laying out the previous control. - int LayoutExtensionShelf(int bottom); - - // Child views that the layout manager manages. - TabStrip* tabstrip_; - ToolbarView* toolbar_; - views::View* contents_split_; - views::View* contents_container_; - views::View* infobar_container_; - DownloadShelfView* download_shelf_; - ExtensionShelf* extension_shelf_; - BookmarkBarView* active_bookmark_bar_; - - BrowserView* browser_view_; - - // The distance the FindBar is from the top of the window, in pixels. - int find_bar_y_; - - DISALLOW_COPY_AND_ASSIGN(ChromeBrowserViewLayoutManager); -}; - -#endif // CHROME_BROWSER_VIEWS_FRAME_CHROME_BROWSER_VIEW_LAYOUT_MANAGER_H_ -- cgit v1.1