Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/views/tab_contents/tab_contents_view_views.h" | |
| 6 | |
| 7 #include "base/string_util.h" | |
| 8 #include "build/build_config.h" | |
| 9 #include "chrome/browser/download/download_shelf.h" | |
| 10 #include "chrome/browser/renderer_host/render_view_host.h" | |
| 11 #include "chrome/browser/renderer_host/render_view_host_factory.h" | |
| 12 #include "chrome/browser/renderer_host/render_widget_host_view_views.h" | |
| 13 #include "chrome/browser/tab_contents/interstitial_page.h" | |
| 14 #include "chrome/browser/tab_contents/tab_contents.h" | |
| 15 #include "chrome/browser/tab_contents/tab_contents_delegate.h" | |
| 16 #include "chrome/browser/views/sad_tab_view.h" | |
| 17 #include "chrome/browser/views/tab_contents/render_view_context_menu_views.h" | |
| 18 #include "gfx/canvas_skia_paint.h" | |
| 19 #include "gfx/point.h" | |
| 20 #include "gfx/rect.h" | |
| 21 #include "gfx/size.h" | |
| 22 #include "views/controls/native/native_view_host.h" | |
| 23 #include "views/fill_layout.h" | |
| 24 #include "views/focus/focus_manager.h" | |
| 25 #include "views/focus/view_storage.h" | |
| 26 #include "views/screen.h" | |
| 27 #include "views/widget/widget.h" | |
| 28 | |
| 29 using WebKit::WebDragOperation; | |
| 30 using WebKit::WebDragOperationsMask; | |
| 31 using WebKit::WebInputEvent; | |
| 32 | |
| 33 #if !defined(TOUCH_UI) | |
| 34 #error should not be possible to build this without TOUCH_UI on | |
| 35 #endif | |
|
oshima
2010/11/08 20:59:38
do you really this? If there is good reason, then
Alex Nicolaou
2010/11/12 04:05:00
Removed. Seemed like a harmless check to me.
| |
| 36 | |
| 37 // static | |
| 38 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { | |
| 39 return new TabContentsViewViews(tab_contents); | |
| 40 } | |
| 41 | |
| 42 TabContentsViewViews::TabContentsViewViews(TabContents* tab_contents) | |
| 43 : TabContentsView(tab_contents), | |
| 44 sad_tab_(NULL), | |
| 45 ignore_next_char_event_(false) { | |
| 46 last_focused_view_storage_id_ = | |
| 47 views::ViewStorage::GetSharedInstance()->CreateStorageID(); | |
| 48 SetLayoutManager(new views::FillLayout()); | |
| 49 } | |
| 50 | |
| 51 TabContentsViewViews::~TabContentsViewViews() { | |
| 52 // Make sure to remove any stored view we may still have in the ViewStorage. | |
| 53 // | |
| 54 // It is possible the view went away before us, so we only do this if the | |
| 55 // view is registered. | |
| 56 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); | |
| 57 if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) | |
| 58 view_storage->RemoveView(last_focused_view_storage_id_); | |
| 59 } | |
| 60 | |
| 61 void TabContentsViewViews::AttachConstrainedWindow( | |
| 62 ConstrainedWindowGtk* constrained_window) { | |
| 63 // TODO(anicolao): reimplement all dialogs as DOMUI | |
| 64 NOTIMPLEMENTED(); | |
| 65 } | |
| 66 | |
| 67 void TabContentsViewViews::RemoveConstrainedWindow( | |
| 68 ConstrainedWindowGtk* constrained_window) { | |
| 69 // TODO(anicolao): reimplement all dialogs as DOMUI | |
| 70 NOTIMPLEMENTED(); | |
| 71 } | |
| 72 | |
| 73 void TabContentsViewViews::CreateView(const gfx::Size& initial_size) { | |
| 74 SetBounds(gfx::Rect(bounds().origin(), initial_size)); | |
| 75 } | |
| 76 | |
| 77 RenderWidgetHostView* TabContentsViewViews::CreateViewForWidget( | |
| 78 RenderWidgetHost* render_widget_host) { | |
| 79 if (render_widget_host->view()) { | |
| 80 // During testing, the view will already be set up in most cases to the | |
| 81 // test view, so we don't want to clobber it with a real one. To verify that | |
| 82 // this actually is happening (and somebody isn't accidentally creating the | |
| 83 // view twice), we check for the RVH Factory, which will be set when we're | |
| 84 // making special ones (which go along with the special views). | |
| 85 DCHECK(RenderViewHostFactory::has_factory()); | |
| 86 return render_widget_host->view(); | |
| 87 } | |
| 88 | |
| 89 // If we were showing sad tab, remove it now. | |
| 90 if (sad_tab_ != NULL) { | |
| 91 RemoveChildView(sad_tab_); | |
| 92 AddChildView(new views::View()); | |
| 93 sad_tab_ = NULL; | |
| 94 } | |
| 95 | |
| 96 RenderWidgetHostViewViews* view = | |
| 97 new RenderWidgetHostViewViews(render_widget_host); | |
| 98 AddChildView(view); | |
| 99 view->Show(); | |
| 100 view->InitAsChild(); | |
| 101 | |
| 102 // TODO(anicolao): implement drag'n'drop hooks if needed | |
| 103 | |
| 104 return view; | |
| 105 } | |
| 106 | |
| 107 gfx::NativeView TabContentsViewViews::GetNativeView() const { | |
| 108 return GetWidget()->GetNativeView(); | |
| 109 } | |
| 110 | |
| 111 gfx::NativeView TabContentsViewViews::GetContentNativeView() const { | |
| 112 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | |
| 113 if (!rwhv) | |
| 114 return NULL; | |
| 115 return rwhv->GetNativeView(); | |
| 116 } | |
| 117 | |
| 118 gfx::NativeWindow TabContentsViewViews::GetTopLevelNativeWindow() const { | |
| 119 GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); | |
| 120 return window ? GTK_WINDOW(window) : NULL; | |
| 121 } | |
| 122 | |
| 123 void TabContentsViewViews::GetContainerBounds(gfx::Rect* out) const { | |
| 124 *out = bounds(); | |
| 125 } | |
| 126 | |
| 127 void TabContentsViewViews::StartDragging(const WebDropData& drop_data, | |
| 128 WebDragOperationsMask ops, | |
| 129 const SkBitmap& image, | |
| 130 const gfx::Point& image_offset) { | |
| 131 // TODO(anicolao): implement dragging | |
| 132 } | |
| 133 | |
| 134 void TabContentsViewViews::SetPageTitle(const std::wstring& title) { | |
| 135 // TODO(anicolao): figure out if there's anything useful to do here | |
| 136 } | |
| 137 | |
| 138 void TabContentsViewViews::OnTabCrashed() { | |
| 139 } | |
| 140 | |
| 141 void TabContentsViewViews::SizeContents(const gfx::Size& size) { | |
| 142 WasSized(size); | |
| 143 | |
| 144 // We need to send this immediately. | |
| 145 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | |
| 146 if (rwhv) | |
| 147 rwhv->SetSize(size); | |
| 148 } | |
| 149 | |
| 150 void TabContentsViewViews::Focus() { | |
| 151 if (tab_contents()->interstitial_page()) { | |
| 152 tab_contents()->interstitial_page()->Focus(); | |
| 153 return; | |
| 154 } | |
| 155 | |
| 156 if (tab_contents()->is_crashed() && sad_tab_ != NULL) { | |
| 157 sad_tab_->RequestFocus(); | |
| 158 return; | |
| 159 } | |
| 160 | |
| 161 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | |
| 162 gtk_widget_grab_focus(rwhv ? rwhv->GetNativeView() : GetNativeView()); | |
| 163 } | |
| 164 | |
| 165 void TabContentsViewViews::SetInitialFocus() { | |
| 166 if (tab_contents()->FocusLocationBarByDefault()) | |
| 167 tab_contents()->SetFocusToLocationBar(false); | |
| 168 else | |
| 169 Focus(); | |
| 170 } | |
| 171 | |
| 172 void TabContentsViewViews::StoreFocus() { | |
| 173 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); | |
| 174 | |
| 175 if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) | |
| 176 view_storage->RemoveView(last_focused_view_storage_id_); | |
| 177 | |
| 178 views::FocusManager* focus_manager = | |
| 179 views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); | |
| 180 if (focus_manager) { | |
| 181 // |focus_manager| can be NULL if the tab has been detached but still | |
| 182 // exists. | |
| 183 views::View* focused_view = focus_manager->GetFocusedView(); | |
| 184 if (focused_view) | |
| 185 view_storage->StoreView(last_focused_view_storage_id_, focused_view); | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 void TabContentsViewViews::RestoreFocus() { | |
| 190 views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance(); | |
| 191 views::View* last_focused_view = | |
| 192 view_storage->RetrieveView(last_focused_view_storage_id_); | |
| 193 if (!last_focused_view) { | |
| 194 SetInitialFocus(); | |
| 195 } else { | |
| 196 views::FocusManager* focus_manager = | |
| 197 views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); | |
| 198 | |
| 199 // If you hit this DCHECK, please report it to Jay (jcampan). | |
| 200 DCHECK(focus_manager != NULL) << "No focus manager when restoring focus."; | |
| 201 | |
| 202 if (last_focused_view->IsFocusableInRootView() && focus_manager && | |
| 203 focus_manager->ContainsView(last_focused_view)) { | |
| 204 last_focused_view->RequestFocus(); | |
| 205 } else { | |
| 206 // The focused view may not belong to the same window hierarchy (e.g. | |
| 207 // if the location bar was focused and the tab is dragged out), or it may | |
| 208 // no longer be focusable (e.g. if the location bar was focused and then | |
| 209 // we switched to fullscreen mode). In that case we default to the | |
| 210 // default focus. | |
| 211 SetInitialFocus(); | |
| 212 } | |
| 213 view_storage->RemoveView(last_focused_view_storage_id_); | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 void TabContentsViewViews::Paint(gfx::Canvas* canvas) { | |
| 218 } | |
| 219 | |
| 220 void TabContentsViewViews::UpdateDragCursor(WebDragOperation operation) { | |
| 221 NOTIMPLEMENTED(); // not even clear a drag cursor will make sense for touch | |
|
brettw
2010/11/08 21:44:06
Please check your comments that they begin with ca
Alex Nicolaou
2010/11/12 04:05:00
Done.
| |
| 222 // TODO(anicolao): implement dragging | |
| 223 } | |
| 224 | |
| 225 void TabContentsViewViews::GotFocus() { | |
| 226 if (tab_contents()->delegate()) | |
| 227 tab_contents()->delegate()->TabContentsFocused(tab_contents()); | |
| 228 } | |
| 229 | |
| 230 void TabContentsViewViews::TakeFocus(bool reverse) { | |
| 231 if (tab_contents()->delegate() && | |
| 232 !tab_contents()->delegate()->TakeFocus(reverse)) { | |
| 233 | |
| 234 views::FocusManager* focus_manager = | |
| 235 views::FocusManager::GetFocusManagerForNativeView(GetNativeView()); | |
| 236 | |
| 237 // We may not have a focus manager if the tab has been switched before this | |
| 238 // message arrived. | |
| 239 if (focus_manager) | |
| 240 focus_manager->AdvanceFocus(reverse); | |
| 241 } | |
| 242 } | |
| 243 | |
| 244 void TabContentsViewViews::VisibilityChanged(views::View *, bool is_visible) { | |
| 245 if (is_visible) { | |
| 246 WasShown(); | |
| 247 } else { | |
| 248 WasHidden(); | |
| 249 } | |
| 250 } | |
| 251 | |
| 252 void TabContentsViewViews::ShowContextMenu(const ContextMenuParams& params) { | |
| 253 // Allow delegates to handle the context menu operation first. | |
| 254 if (tab_contents()->delegate()->HandleContextMenu(params)) | |
| 255 return; | |
| 256 | |
| 257 // TODO(anicolao): implement context menus for touch | |
| 258 NOTIMPLEMENTED(); | |
| 259 } | |
| 260 | |
| 261 void TabContentsViewViews::ShowPopupMenu(const gfx::Rect& bounds, | |
| 262 int item_height, | |
| 263 double item_font_size, | |
| 264 int selected_item, | |
| 265 const std::vector<WebMenuItem>& items, | |
| 266 bool right_aligned) { | |
| 267 // External popup menus are only used on Mac. | |
| 268 NOTREACHED(); | |
| 269 } | |
| 270 | |
| 271 void TabContentsViewViews::WasHidden() { | |
| 272 tab_contents()->HideContents(); | |
| 273 } | |
| 274 | |
| 275 void TabContentsViewViews::WasShown() { | |
| 276 tab_contents()->ShowContents(); | |
| 277 } | |
| 278 | |
| 279 void TabContentsViewViews::WasSized(const gfx::Size& size) { | |
| 280 // We have to check that the RenderWidgetHostView is the proper size. | |
| 281 // It can be wrong in cases where the renderer has died and the host | |
| 282 // view needed to be recreated. | |
| 283 bool needs_resize = size != size_; | |
| 284 | |
| 285 if (needs_resize) { | |
| 286 size_ = size; | |
| 287 if (tab_contents()->interstitial_page()) | |
| 288 tab_contents()->interstitial_page()->SetSize(size); | |
| 289 } | |
| 290 | |
| 291 RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); | |
| 292 if (rwhv && rwhv->GetViewBounds().size() != size) | |
| 293 rwhv->SetSize(size); | |
| 294 | |
| 295 if (needs_resize) | |
| 296 SetFloatingPosition(size); | |
| 297 } | |
| 298 | |
| 299 void TabContentsViewViews::SetFloatingPosition(const gfx::Size& size) { | |
| 300 // TODO(anicolao): rework this once we have DOMUI views for dialogs | |
| 301 SetBounds(x(), y(), size.width(), size.height()); | |
| 302 } | |
| OLD | NEW |