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 |