Index: chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc |
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 0000000000000000000000000000000000000000..10d3daf781ee161041729eced20d17d1fdf3dac6 |
--- /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()); |
+} |