diff options
author | anicolao@chromium.org <anicolao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-24 19:14:57 +0000 |
---|---|---|
committer | anicolao@chromium.org <anicolao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-24 19:14:57 +0000 |
commit | 602627ccfcedd1183fa558a89ade93e9b8c4416a (patch) | |
tree | e6e1818199d874b9d735de2c4dff49b549ec10bc /chrome/browser/ui | |
parent | 23214631f9f132f7f08c8e13f2137b7334dd6aea (diff) | |
download | chromium_src-602627ccfcedd1183fa558a89ade93e9b8c4416a.zip chromium_src-602627ccfcedd1183fa558a89ade93e9b8c4416a.tar.gz chromium_src-602627ccfcedd1183fa558a89ade93e9b8c4416a.tar.bz2 |
Replace TabContentsViewGtk with TabContentsViewViews as part of the ongoing
effort to eliminate GTK for TOUCH_UI.
BUG=none
TEST=manually tested
Review URL: http://codereview.chromium.org/4319003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67291 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui')
3 files changed, 465 insertions, 2 deletions
diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_container.cc b/chrome/browser/ui/views/tab_contents/tab_contents_container.cc index eed5ea2..9ab6078 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_container.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_container.cc @@ -12,6 +12,13 @@ #include "chrome/browser/views/tab_contents/native_tab_contents_container.h" #include "chrome/common/notification_service.h" +#if defined(TOUCH_UI) +#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.h" +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" +#include "views/border.h" +#include "views/fill_layout.h" +#endif + //////////////////////////////////////////////////////////////////////////////// // TabContentsContainer, public: @@ -29,29 +36,46 @@ TabContentsContainer::~TabContentsContainer() { void TabContentsContainer::ChangeTabContents(TabContents* contents) { if (tab_contents_) { +#if !defined(TOUCH_UI) native_container_->DetachContents(tab_contents_); +#endif tab_contents_->WasHidden(); RemoveObservers(); } +#if !defined(TOUCH_UI) TabContents* old_contents = tab_contents_; +#endif tab_contents_ = contents; // When detaching the last tab of the browser ChangeTabContents is invoked // with NULL. Don't attempt to do anything in that case. if (tab_contents_) { +#if defined(TOUCH_UI) + views::View *v = static_cast<TabContentsViewViews*>(contents->view()); + // Guard against re-adding ourselves, which happens because the NULL + // value is ignored by the pre-existing if() above. + if (v->GetParent() != this) { + AddChildView(v); + SetLayoutManager(new views::FillLayout()); + Layout(); + } +#else RenderWidgetHostViewChanged( old_contents ? old_contents->GetRenderWidgetHostView() : NULL, tab_contents_->GetRenderWidgetHostView()); native_container_->AttachContents(tab_contents_); +#endif AddObservers(); } } void TabContentsContainer::TabContentsFocused(TabContents* tab_contents) { - native_container_->TabContentsFocused(tab_contents); + if (native_container_) + native_container_->TabContentsFocused(tab_contents); } void TabContentsContainer::SetFastResize(bool fast_resize) { - native_container_->SetFastResize(fast_resize); + if (native_container_) + native_container_->SetFastResize(fast_resize); } //////////////////////////////////////////////////////////////////////////////// @@ -76,12 +100,16 @@ void TabContentsContainer::Observe(NotificationType type, // TabContentsContainer, View overrides: void TabContentsContainer::Layout() { +#if defined(TOUCH_UI) + views::View::Layout(); +#else if (native_container_) { if (reserved_area_delegate_) reserved_area_delegate_->UpdateReservedContentsRect(this); native_container_->GetView()->SetBounds(0, 0, width(), height()); native_container_->GetView()->Layout(); } +#endif } AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() { @@ -91,10 +119,14 @@ AccessibilityTypes::Role TabContentsContainer::GetAccessibleRole() { void TabContentsContainer::ViewHierarchyChanged(bool is_add, views::View* parent, views::View* child) { +#if defined(TOUCH_UI) + views::View::ViewHierarchyChanged(is_add, parent, child); +#else if (is_add && child == this) { native_container_ = NativeTabContentsContainer::CreateNativeContainer(this); AddChildView(native_container_->GetView()); } +#endif } //////////////////////////////////////////////////////////////////////////////// @@ -119,11 +151,15 @@ void TabContentsContainer::RemoveObservers() { void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host, RenderViewHost* new_host) { +#if defined(TOUCH_UI) + NOTIMPLEMENTED(); // TODO(anicolao) +#else if (new_host) { RenderWidgetHostViewChanged( old_host ? old_host->view() : NULL, new_host->view()); } native_container_->RenderViewHostChanged(old_host, new_host); +#endif } void TabContentsContainer::TabContentsDestroyed(TabContents* contents) { diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc new file mode 100644 index 0000000..10d3daf --- /dev/null +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc @@ -0,0 +1,299 @@ +// 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/ui/views/tab_contents/tab_contents_view_views.h" + +#include "base/string_util.h" +#include "build/build_config.h" +#include "chrome/browser/download/download_shelf.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_factory.h" +#include "chrome/browser/renderer_host/render_widget_host_view_views.h" +#include "chrome/browser/tab_contents/interstitial_page.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_delegate.h" +#include "chrome/browser/views/sad_tab_view.h" +#include "chrome/browser/views/tab_contents/render_view_context_menu_views.h" +#include "gfx/canvas_skia_paint.h" +#include "gfx/point.h" +#include "gfx/rect.h" +#include "gfx/size.h" +#include "views/controls/native/native_view_host.h" +#include "views/fill_layout.h" +#include "views/focus/focus_manager.h" +#include "views/focus/view_storage.h" +#include "views/screen.h" +#include "views/widget/widget.h" + +using WebKit::WebDragOperation; +using WebKit::WebDragOperationsMask; +using WebKit::WebInputEvent; + +// static +TabContentsView* TabContentsView::Create(TabContents* tab_contents) { + return new TabContentsViewViews(tab_contents); +} + +TabContentsViewViews::TabContentsViewViews(TabContents* tab_contents) + : TabContentsView(tab_contents), + sad_tab_(NULL), + ignore_next_char_event_(false) { + last_focused_view_storage_id_ = + views::ViewStorage::GetSharedInstance()->CreateStorageID(); + SetLayoutManager(new views::FillLayout()); +} + +TabContentsViewViews::~TabContentsViewViews() { + // Make sure to remove any stored view we may still have in the ViewStorage. + // + // It is possible the view went away before us, so we only do this if the + // view is registered. + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) + view_storage->RemoveView(last_focused_view_storage_id_); +} + +void TabContentsViewViews::AttachConstrainedWindow( + ConstrainedWindowGtk* constrained_window) { + // TODO(anicolao): reimplement all dialogs as DOMUI + NOTIMPLEMENTED(); +} + +void TabContentsViewViews::RemoveConstrainedWindow( + ConstrainedWindowGtk* constrained_window) { + // TODO(anicolao): reimplement all dialogs as DOMUI + NOTIMPLEMENTED(); +} + +void TabContentsViewViews::CreateView(const gfx::Size& initial_size) { + SetBounds(gfx::Rect(bounds().origin(), initial_size)); +} + +RenderWidgetHostView* TabContentsViewViews::CreateViewForWidget( + RenderWidgetHost* render_widget_host) { + if (render_widget_host->view()) { + // During testing, the view will already be set up in most cases to the + // test view, so we don't want to clobber it with a real one. To verify that + // this actually is happening (and somebody isn't accidentally creating the + // view twice), we check for the RVH Factory, which will be set when we're + // making special ones (which go along with the special views). + DCHECK(RenderViewHostFactory::has_factory()); + return render_widget_host->view(); + } + + // If we were showing sad tab, remove it now. + if (sad_tab_ != NULL) { + RemoveChildView(sad_tab_); + AddChildView(new views::View()); + sad_tab_ = NULL; + } + + RenderWidgetHostViewViews* view = + new RenderWidgetHostViewViews(render_widget_host); + AddChildView(view); + view->Show(); + view->InitAsChild(); + + // TODO(anicolao): implement drag'n'drop hooks if needed + + return view; +} + +gfx::NativeView TabContentsViewViews::GetNativeView() const { + return GetWidget()->GetNativeView(); +} + +gfx::NativeView TabContentsViewViews::GetContentNativeView() const { + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + if (!rwhv) + return NULL; + return rwhv->GetNativeView(); +} + +gfx::NativeWindow TabContentsViewViews::GetTopLevelNativeWindow() const { + GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); + return window ? GTK_WINDOW(window) : NULL; +} + +void TabContentsViewViews::GetContainerBounds(gfx::Rect* out) const { + *out = bounds(); +} + +void TabContentsViewViews::StartDragging(const WebDropData& drop_data, + WebDragOperationsMask ops, + const SkBitmap& image, + const gfx::Point& image_offset) { + // TODO(anicolao): implement dragging +} + +void TabContentsViewViews::SetPageTitle(const std::wstring& title) { + // TODO(anicolao): figure out if there's anything useful to do here +} + +void TabContentsViewViews::OnTabCrashed() { +} + +void TabContentsViewViews::SizeContents(const gfx::Size& size) { + WasSized(size); + + // We need to send this immediately. + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + if (rwhv) + rwhv->SetSize(size); +} + +void TabContentsViewViews::Focus() { + if (tab_contents()->interstitial_page()) { + tab_contents()->interstitial_page()->Focus(); + return; + } + + if (tab_contents()->is_crashed() && sad_tab_ != NULL) { + sad_tab_->RequestFocus(); + return; + } + + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + gtk_widget_grab_focus(rwhv ? rwhv->GetNativeView() : GetNativeView()); +} + +void TabContentsViewViews::SetInitialFocus() { + if (tab_contents()->FocusLocationBarByDefault()) + tab_contents()->SetFocusToLocationBar(false); + else + Focus(); +} + +void TabContentsViewViews::StoreFocus() { + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + + if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) + view_storage->RemoveView(last_focused_view_storage_id_); + + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); + if (focus_manager) { + // |focus_manager| can be NULL if the tab has been detached but still + // exists. + views::View* focused_view = focus_manager->GetFocusedView(); + if (focused_view) + view_storage->StoreView(last_focused_view_storage_id_, focused_view); + } +} + +void TabContentsViewViews::RestoreFocus() { + views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); + views::View* last_focused_view = + view_storage->RetrieveView(last_focused_view_storage_id_); + if (!last_focused_view) { + SetInitialFocus(); + } else { + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); + + // If you hit this DCHECK, please report it to Jay (jcampan). + DCHECK(focus_manager != NULL) << "No focus manager when restoring focus."; + + if (last_focused_view->IsFocusableInRootView() && focus_manager && + focus_manager->ContainsView(last_focused_view)) { + last_focused_view->RequestFocus(); + } else { + // The focused view may not belong to the same window hierarchy (e.g. + // if the location bar was focused and the tab is dragged out), or it may + // no longer be focusable (e.g. if the location bar was focused and then + // we switched to fullscreen mode). In that case we default to the + // default focus. + SetInitialFocus(); + } + view_storage->RemoveView(last_focused_view_storage_id_); + } +} + +void TabContentsViewViews::Paint(gfx::Canvas* canvas) { +} + +void TabContentsViewViews::UpdateDragCursor(WebDragOperation operation) { + NOTIMPLEMENTED(); + // It's not even clear a drag cursor will make sense for touch. + // TODO(anicolao): implement dragging +} + +void TabContentsViewViews::GotFocus() { + if (tab_contents()->delegate()) + tab_contents()->delegate()->TabContentsFocused(tab_contents()); +} + +void TabContentsViewViews::TakeFocus(bool reverse) { + if (tab_contents()->delegate() && + !tab_contents()->delegate()->TakeFocus(reverse)) { + + views::FocusManager* focus_manager = + views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); + + // We may not have a focus manager if the tab has been switched before this + // message arrived. + if (focus_manager) + focus_manager->AdvanceFocus(reverse); + } +} + +void TabContentsViewViews::VisibilityChanged(views::View *, bool is_visible) { + if (is_visible) { + WasShown(); + } else { + WasHidden(); + } +} + +void TabContentsViewViews::ShowContextMenu(const ContextMenuParams& params) { + // Allow delegates to handle the context menu operation first. + if (tab_contents()->delegate()->HandleContextMenu(params)) + return; + + // TODO(anicolao): implement context menus for touch + NOTIMPLEMENTED(); +} + +void TabContentsViewViews::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned) { + // External popup menus are only used on Mac. + NOTREACHED(); +} + +void TabContentsViewViews::WasHidden() { + tab_contents()->HideContents(); +} + +void TabContentsViewViews::WasShown() { + tab_contents()->ShowContents(); +} + +void TabContentsViewViews::WasSized(const gfx::Size& size) { + // We have to check that the RenderWidgetHostView is the proper size. + // It can be wrong in cases where the renderer has died and the host + // view needed to be recreated. + bool needs_resize = size != size_; + + if (needs_resize) { + size_ = size; + if (tab_contents()->interstitial_page()) + tab_contents()->interstitial_page()->SetSize(size); + } + + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); + if (rwhv && rwhv->GetViewBounds().size() != size) + rwhv->SetSize(size); + + if (needs_resize) + SetFloatingPosition(size); +} + +void TabContentsViewViews::SetFloatingPosition(const gfx::Size& size) { + // TODO(anicolao): rework this once we have DOMUI views for dialogs + SetBounds(x(), y(), size.width(), size.height()); +} diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h new file mode 100644 index 0000000..dfb7ed7 --- /dev/null +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h @@ -0,0 +1,128 @@ +// 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_TAB_CONTENTS_TAB_CONTENTS_VIEW_VIEWS_H_ +#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_VIEWS_H_ +#pragma once + +#include <vector> + +#include "base/scoped_ptr.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "gfx/size.h" +#include "views/view.h" + +class ConstrainedWindowGtk; +typedef struct _GtkFloatingContainer GtkFloatingContainer; +class RenderViewContextMenuViews; +class SadTabView; +class SkBitmap; +class TabContentsDragSource; +class WebDragDestGtk; + +namespace gfx { +class Point; +} // namespace gfx + +namespace views { +class NativeViewHost; +} // namespace views + +// Views-specific implementation of the TabContentsView for the touch UI. +class TabContentsViewViews : public TabContentsView, public views::View { + public: + // The corresponding TabContents is passed in the constructor, and manages our + // lifetime. This doesn't need to be the case, but is this way currently + // because that's what was easiest when they were split. + explicit TabContentsViewViews(TabContents* tab_contents); + virtual ~TabContentsViewViews(); + + // Unlike Windows, ConstrainedWindows need to collaborate with the + // TabContentsViewViews to position the dialogs. + void AttachConstrainedWindow(ConstrainedWindowGtk* constrained_window); + void RemoveConstrainedWindow(ConstrainedWindowGtk* constrained_window); + + // TabContentsView implementation + virtual void CreateView(const gfx::Size& initial_size); + virtual RenderWidgetHostView* CreateViewForWidget( + RenderWidgetHost* render_widget_host); + virtual gfx::NativeView GetNativeView() const; + virtual gfx::NativeView GetContentNativeView() const; + virtual gfx::NativeWindow GetTopLevelNativeWindow() const; + virtual void GetContainerBounds(gfx::Rect* out) const; + virtual void SetPageTitle(const std::wstring& title); + virtual void OnTabCrashed(); + virtual void SizeContents(const gfx::Size& size); + virtual void Focus(); + virtual void SetInitialFocus(); + virtual void StoreFocus(); + virtual void RestoreFocus(); + + // views::View implementation + virtual void Paint(gfx::Canvas* canvas); + + // Backend implementation of RenderViewHostDelegate::View. + virtual void ShowContextMenu(const ContextMenuParams& params); + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned); + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask ops_allowed, + const SkBitmap& image, + const gfx::Point& image_offset); + virtual void UpdateDragCursor(WebKit::WebDragOperation operation); + virtual void GotFocus(); + virtual void TakeFocus(bool reverse); + virtual void VisibilityChanged(views::View *, bool is_visible); + + private: + // Signal handlers ----------------------------------------------------------- + + // Handles notifying the TabContents and other operations when the window was + // shown or hidden. + void WasHidden(); + void WasShown(); + + // Handles resizing of the contents. This will notify the RenderWidgetHostView + // of the change, reposition popups, and the find in page bar. + void WasSized(const gfx::Size& size); + + // For any floating views (ConstrainedDialogs) this function centers them + // within this view. It's called whem a ConstrainedDialog is attached and + // when this view is resized. + void SetFloatingPosition(const gfx::Size& size); + + // Used to render the sad tab. This will be non-NULL only when the sad tab is + // visible. + SadTabView* sad_tab_; + + // Whether to ignore the next CHAR keyboard event. + bool ignore_next_char_event_; + + // The id used in the ViewStorage to store the last focused view. + int last_focused_view_storage_id_; + + // The context menu. Callbacks are asynchronous so we need to keep it around. + scoped_ptr<RenderViewContextMenuViews> context_menu_; + + // Handle drags from this TabContentsView. + // TODO(anicolao): figure out what's needed for drag'n'drop + + // The event for the last mouse down we handled. We need this for drags. + GdkEventButton last_mouse_down_; + + // Current size. See comment in WidgetGtk as to why this is cached. + gfx::Size size_; + + // Each individual UI for constrained dialogs currently displayed. The + // objects in this vector are owned by the TabContents, not the view. + std::vector<ConstrainedWindowGtk*> constrained_windows_; + + DISALLOW_COPY_AND_ASSIGN(TabContentsViewViews); +}; + +#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_VIEW_VIEWS_H_ |