Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: chrome/browser/ui/views/search_view_controller.cc

Issue 10787028: Converts SearchViewController to use live NTP content instead of placeholder (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/search_view_controller.h" 5 #include "chrome/browser/ui/views/search_view_controller.h"
6 6
7 #include "chrome/browser/ui/search/search_model.h" 7 #include "chrome/browser/ui/search/search_model.h"
8 #include "chrome/browser/ui/search/search_tab_helper.h" 8 #include "chrome/browser/ui/search/search_tab_helper.h"
9 #include "chrome/browser/ui/search/search_types.h" 9 #include "chrome/browser/ui/search/search_types.h"
10 #include "chrome/browser/ui/search/search_ui.h" 10 #include "chrome/browser/ui/search/search_ui.h"
11 #include "chrome/browser/ui/tab_contents/tab_contents.h" 11 #include "chrome/browser/ui/tab_contents/tab_contents.h"
12 #include "chrome/browser/ui/views/frame/contents_container.h" 12 #include "chrome/browser/ui/views/frame/contents_container.h"
13 #include "chrome/browser/ui/views/location_bar/location_bar_container.h" 13 #include "chrome/browser/ui/views/location_bar/location_bar_container.h"
14 #include "chrome/browser/ui/webui/instant_ui.h" 14 #include "chrome/browser/ui/webui/instant_ui.h"
15 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/notification_source.h"
18 #include "content/public/browser/notification_types.h"
15 #include "grit/theme_resources.h" 19 #include "grit/theme_resources.h"
16 #include "ui/compositor/layer.h" 20 #include "ui/compositor/layer.h"
17 #include "ui/compositor/scoped_layer_animation_settings.h" 21 #include "ui/compositor/scoped_layer_animation_settings.h"
18 #include "ui/base/resource/resource_bundle.h" 22 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas.h" 23 #include "ui/gfx/canvas.h"
24 #include "ui/views/controls/webview/webview.h"
20 #include "ui/views/layout/fill_layout.h" 25 #include "ui/views/layout/fill_layout.h"
21 #include "ui/views/layout/layout_manager.h" 26 #include "ui/views/layout/layout_manager.h"
22 27
28 #if defined(USE_AURA)
29 #include "ui/aura/window.h"
30 #endif
31
23 namespace { 32 namespace {
24 33
25 // SearchContainerView --------------------------------------------------------- 34 // SearchContainerView ---------------------------------------------------------
26 35
27 // SearchContainerView contains the |ntp_view_| and 36 // SearchContainerView contains the |ntp_view_| and
28 // |omnibox_popup_view_parent_|. |ntp_view_| is given the full size and 37 // |omnibox_popup_view_parent_|. |ntp_view_| is given the full size and
29 // the |omnibox_popup_view_parent_| is gives its preferred height. 38 // the |omnibox_popup_view_parent_| is gives its preferred height.
30 class SearchContainerView : public views::View { 39 class SearchContainerView : public views::View {
31 public: 40 public:
32 SearchContainerView(views::View* ntp_view, 41 SearchContainerView(views::View* ntp_view,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 143
135 // views::LayoutManager overrides: 144 // views::LayoutManager overrides:
136 virtual void Layout(views::View* host) OVERRIDE { 145 virtual void Layout(views::View* host) OVERRIDE {
137 gfx::Size logo_pref = logo_view_->GetPreferredSize(); 146 gfx::Size logo_pref = logo_view_->GetPreferredSize();
138 logo_view_->SetBounds( 147 logo_view_->SetBounds(
139 (host->width() - logo_pref.width()) / 2, 148 (host->width() - logo_pref.width()) / 2,
140 chrome::search::kOmniboxYPosition - 20 - logo_pref.height(), 149 chrome::search::kOmniboxYPosition - 20 - logo_pref.height(),
141 logo_pref.width(), 150 logo_pref.width(),
142 logo_pref.height()); 151 logo_pref.height());
143 152
144 gfx::Size content_pref(content_view_->GetPreferredSize()); 153 int content_y = chrome::search::kOmniboxYPosition + 50;
145 int content_y = std::max(chrome::search::kOmniboxYPosition + 50, 154 content_view_->SetBounds(0,
146 host->height() - content_pref.height() - 50); 155 content_y,
147 content_view_->SetBounds((host->width() - content_pref.width()) / 2, 156 host->width(),
148 content_y, content_pref.width(), 157 host->height() - content_y);
149 content_pref.height());
150 } 158 }
151 159
152 virtual gfx::Size GetPreferredSize(views::View* host) OVERRIDE { 160 virtual gfx::Size GetPreferredSize(views::View* host) OVERRIDE {
153 // Preferred size doesn't matter for the NTPView. 161 // Preferred size doesn't matter for the NTPView.
154 return gfx::Size(); 162 return gfx::Size();
155 } 163 }
156 164
157 private: 165 private:
158 views::View* logo_view_; 166 views::View* logo_view_;
159 views::View* content_view_; 167 views::View* content_view_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 parent()->Layout(); 217 parent()->Layout();
210 if (child_visible_ != child->visible()) { 218 if (child_visible_ != child->visible()) {
211 child_visible_ = child->visible(); 219 child_visible_ = child->visible();
212 search_view_controller_->PopupVisibilityChanged(); 220 search_view_controller_->PopupVisibilityChanged();
213 } 221 }
214 } 222 }
215 223
216 // SearchViewController -------------------------------------------------------- 224 // SearchViewController --------------------------------------------------------
217 225
218 SearchViewController::SearchViewController( 226 SearchViewController::SearchViewController(
227 chrome::search::SearchModel* search_model,
228 content::BrowserContext* browser_context,
219 ContentsContainer* contents_container) 229 ContentsContainer* contents_container)
220 : contents_container_(contents_container), 230 : search_model_(search_model),
231 browser_context_(browser_context),
232 contents_container_(contents_container),
221 location_bar_container_(NULL), 233 location_bar_container_(NULL),
222 state_(STATE_NOT_VISIBLE), 234 state_(STATE_NOT_VISIBLE),
223 tab_(NULL),
224 search_container_(NULL), 235 search_container_(NULL),
225 ntp_view_(NULL), 236 ntp_view_(NULL),
226 logo_view_(NULL), 237 logo_view_(NULL),
227 content_view_(NULL), 238 content_view_(NULL),
228 omnibox_popup_view_parent_(NULL) { 239 omnibox_popup_view_parent_(NULL) {
240 search_model_->AddObserver(this);
229 omnibox_popup_view_parent_ = new OmniboxPopupViewParent(this); 241 omnibox_popup_view_parent_ = new OmniboxPopupViewParent(this);
242 registrar_.Add(this,
243 content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
244 content::NotificationService::AllSources());
230 } 245 }
231 246
232 SearchViewController::~SearchViewController() { 247 SearchViewController::~SearchViewController() {
233 if (search_model()) 248 search_model_->RemoveObserver(this);
234 search_model()->RemoveObserver(this);
235 249
236 // If the |omnibox_popup_view_| isn't parented, delete it. Otherwise it'll be 250 // If the |omnibox_popup_view_| isn't parented, delete it. Otherwise it'll be
237 // deleted by its parent. 251 // deleted by its parent.
238 if (!omnibox_popup_view_parent_->parent()) 252 if (!omnibox_popup_view_parent_->parent())
239 delete omnibox_popup_view_parent_; 253 delete omnibox_popup_view_parent_;
240 } 254 }
241 255
242 views::View* SearchViewController::omnibox_popup_view_parent() { 256 views::View* SearchViewController::omnibox_popup_view_parent() {
243 return omnibox_popup_view_parent_; 257 return omnibox_popup_view_parent_;
244 } 258 }
245 259
246 void SearchViewController::SetTabContents(TabContents* tab) { 260 void SearchViewController::SetTabContents(TabContents* tab_contents) {
247 if (tab_ == tab)
dhollowa 2012/07/20 00:34:09 I pulled this logic out because this class should
sky 2012/07/20 15:58:13 This code needs to run at a specific time. The ord
248 return;
249
250 if (search_model())
251 search_model()->RemoveObserver(this);
252 tab_ = tab;
253 if (search_model())
254 search_model()->AddObserver(this);
255
256 UpdateState();
257 } 261 }
258 262
259 void SearchViewController::StackAtTop() { 263 void SearchViewController::StackAtTop() {
260 #if defined(USE_AURA) 264 #if defined(USE_AURA)
261 if (search_container_) { 265 if (search_container_) {
262 StackViewsLayerAtTop(search_container_); 266 StackViewsLayerAtTop(search_container_);
263 StackViewsLayerAtTop(ntp_view_); 267 StackViewsLayerAtTop(ntp_view_);
264 StackViewsLayerAtTop(logo_view_); 268 StackViewsLayerAtTop(logo_view_);
265 StackViewsLayerAtTop(content_view_); 269 if (content_view_ && content_view_->web_contents()) {
270 ntp_view_->layer()->StackAtTop(
271 content_view_->web_contents()->GetNativeView()->layer());
272 }
266 } 273 }
267 #else 274 #else
268 NOTIMPLEMENTED(); 275 NOTIMPLEMENTED();
269 #endif 276 #endif
270 location_bar_container_->StackAtTop(); 277 location_bar_container_->StackAtTop();
271 } 278 }
272 279
273 void SearchViewController::InstantReady() { 280 void SearchViewController::InstantReady() {
274 } 281 }
275 282
276 void SearchViewController::ModeChanged(const chrome::search::Mode& mode) { 283 void SearchViewController::ModeChanged(const chrome::search::Mode& mode) {
277 UpdateState(); 284 UpdateState();
278 } 285 }
279 286
280 void SearchViewController::OnImplicitAnimationsCompleted() { 287 void SearchViewController::OnImplicitAnimationsCompleted() {
281 DCHECK_EQ(STATE_ANIMATING, state_); 288 DCHECK_EQ(STATE_ANIMATING, state_);
282 state_ = STATE_SEARCH; 289 state_ = STATE_SEARCH;
283 ntp_view_->SetVisible(false); 290 ntp_view_->SetVisible(false);
284 // While |ntp_view_| was fading out, location bar was animating from the 291 // While |ntp_view_| was fading out, location bar was animating from the
285 // middle of the NTP page to the top toolbar, at the same rate. 292 // middle of the NTP page to the top toolbar, at the same rate.
286 // Suggestions need to be aligned with the final location of the location bar. 293 // Suggestions need to be aligned with the final location of the location bar.
287 // So if omnibox popup view (InlineOmniboxPopupView) is visible, force a 294 // So if omnibox popup view (InlineOmniboxPopupView) is visible, force a
288 // re-layout of its children (i.e. the suggestions) to align with the location 295 // re-layout of its children (i.e. the suggestions) to align with the location
289 // bar's final bounds. 296 // bar's final bounds.
290 if (omnibox_popup_view_parent_->is_child_visible()) 297 if (omnibox_popup_view_parent_->is_child_visible())
291 omnibox_popup_view_parent_->child_at(0)->Layout(); 298 omnibox_popup_view_parent_->child_at(0)->Layout();
292 } 299 }
293 300
294 void SearchViewController::UpdateState() { 301 void SearchViewController::UpdateState() {
295 if (!search_model()) {
296 DestroyViews();
297 return;
298 }
299 State new_state = STATE_NOT_VISIBLE; 302 State new_state = STATE_NOT_VISIBLE;
300 switch (search_model()->mode().mode) { 303 switch (search_model_->mode().mode) {
301 case chrome::search::Mode::MODE_DEFAULT: 304 case chrome::search::Mode::MODE_DEFAULT:
302 break; 305 break;
303 306
304 case chrome::search::Mode::MODE_NTP: 307 case chrome::search::Mode::MODE_NTP:
305 new_state = STATE_NTP; 308 new_state = STATE_NTP;
306 break; 309 break;
307 310
308 case chrome::search::Mode::MODE_SEARCH: 311 case chrome::search::Mode::MODE_SEARCH:
309 if (search_model()->mode().animate && state_ == STATE_NTP) { 312 if (search_model_->mode().animate && state_ == STATE_NTP) {
310 new_state = STATE_ANIMATING; 313 new_state = STATE_ANIMATING;
311 } else { 314 } else {
312 // Only enter into MODE_SEARCH if the omnibox is visible. 315 // Only enter into MODE_SEARCH if the omnibox is visible.
313 if (omnibox_popup_view_parent_->is_child_visible()) 316 if (omnibox_popup_view_parent_->is_child_visible())
314 new_state = STATE_SEARCH; 317 new_state = STATE_SEARCH;
315 else 318 else
316 new_state = STATE_NOT_VISIBLE; 319 new_state = STATE_NOT_VISIBLE;
317 } 320 }
318 break; 321 break;
319 } 322 }
320 SetState(new_state); 323 SetState(new_state);
321 } 324 }
322 325
323 void SearchViewController::SetState(State state) { 326 void SearchViewController::SetState(State state) {
324 if (state_ == state) 327 if (state_ == state)
325 return; 328 return;
326 329
327 State old_state = state_; 330 State old_state = state_;
328 state_ = state; 331 state_ = state;
329 switch (state_) { 332 switch (state_) {
330 case STATE_NOT_VISIBLE: 333 case STATE_NOT_VISIBLE:
331 DestroyViews(); 334 DestroyViews();
332 break; 335 break;
333 336
334 case STATE_NTP: 337 case STATE_NTP:
335 DestroyViews(); 338 DestroyViews();
336 CreateViews(); 339 CreateViews();
340 content_view_->LoadInitialURL(GURL(chrome::kChromeUINewTabURL));
337 break; 341 break;
338 342
339 case STATE_ANIMATING: 343 case STATE_ANIMATING:
340 // Should only animate from the ntp. 344 // Should only animate from the ntp.
341 DCHECK_EQ(STATE_NTP, old_state); 345 DCHECK_EQ(STATE_NTP, old_state);
342 StartAnimation(); 346 StartAnimation();
343 break; 347 break;
344 348
345 case STATE_SEARCH: 349 case STATE_SEARCH:
346 DestroyViews(); 350 DestroyViews();
(...skipping 23 matching lines...) Expand all
370 settings.SetTransitionDuration( 374 settings.SetTransitionDuration(
371 base::TimeDelta::FromMilliseconds(135 * factor)); 375 base::TimeDelta::FromMilliseconds(135 * factor));
372 settings.SetTweenType(ui::Tween::EASE_IN_OUT); 376 settings.SetTweenType(ui::Tween::EASE_IN_OUT);
373 gfx::Rect bounds(logo_layer->bounds()); 377 gfx::Rect bounds(logo_layer->bounds());
374 bounds.set_y(bounds.y() - 100); 378 bounds.set_y(bounds.y() - 100);
375 logo_layer->SetBounds(bounds); 379 logo_layer->SetBounds(bounds);
376 logo_layer->SetOpacity(0.0f); 380 logo_layer->SetOpacity(0.0f);
377 } 381 }
378 382
379 { 383 {
380 ui::Layer* content_layer = content_view_->layer(); 384 ui::Layer* content_layer =
385 content_view_->web_contents()->GetNativeView()->layer();
381 ui::ScopedLayerAnimationSettings settings(content_layer->GetAnimator()); 386 ui::ScopedLayerAnimationSettings settings(content_layer->GetAnimator());
382 settings.SetTransitionDuration( 387 settings.SetTransitionDuration(
383 base::TimeDelta::FromMilliseconds(180 * factor)); 388 base::TimeDelta::FromMilliseconds(180 * factor));
384 settings.SetTweenType(ui::Tween::LINEAR); 389 settings.SetTweenType(ui::Tween::LINEAR);
385 gfx::Rect bounds(content_layer->bounds()); 390 gfx::Rect bounds(content_layer->bounds());
386 bounds.set_y(bounds.y() - 250); 391 bounds.set_y(bounds.y() - 250);
387 content_layer->SetBounds(bounds); 392 content_layer->SetBounds(bounds);
388 content_layer->SetOpacity(0.0f); 393 content_layer->SetOpacity(0.0f);
389 } 394 }
390 } 395 }
391 396
392 void SearchViewController::CreateViews() { 397 void SearchViewController::CreateViews() {
393 DCHECK(!ntp_view_); 398 DCHECK(!ntp_view_);
394 399
395 ntp_view_ = new views::View; 400 ntp_view_ = new views::View;
396 ntp_view_->set_background(new NTPViewBackground); 401 ntp_view_->set_background(new NTPViewBackground);
397 ntp_view_->SetPaintToLayer(true); 402 ntp_view_->SetPaintToLayer(true);
398 ntp_view_->layer()->SetMasksToBounds(true); 403 ntp_view_->layer()->SetMasksToBounds(true);
399 404
400 logo_view_ = new views::View; 405 logo_view_ = new views::View;
401 logo_view_->SetLayoutManager( 406 logo_view_->SetLayoutManager(
402 new FixedSizeLayoutManager(gfx::Size(300, 200))); 407 new FixedSizeLayoutManager(gfx::Size(300, 200)));
403 logo_view_->set_background( 408 logo_view_->set_background(
404 views::Background::CreateSolidBackground(SK_ColorRED)); 409 views::Background::CreateSolidBackground(SK_ColorRED));
405 logo_view_->SetPaintToLayer(true); 410 logo_view_->SetPaintToLayer(true);
406 logo_view_->SetFillsBoundsOpaquely(false); 411 logo_view_->SetFillsBoundsOpaquely(false);
407 412
408 // TODO: replace with WebContents for NTP. 413 content_view_ = new views::WebView(browser_context_);
409 content_view_ = new views::View;
410 content_view_->SetLayoutManager(
411 new FixedSizeLayoutManager(gfx::Size(400, 200)));
412 content_view_->set_background(
413 views::Background::CreateSolidBackground(SK_ColorBLUE));
414 content_view_->SetPaintToLayer(true);
415 content_view_->SetFillsBoundsOpaquely(false); 414 content_view_->SetFillsBoundsOpaquely(false);
416 415
417 ntp_view_->SetLayoutManager( 416 ntp_view_->SetLayoutManager(
418 new NTPViewLayoutManager(logo_view_, content_view_)); 417 new NTPViewLayoutManager(logo_view_, content_view_));
418 ntp_view_->AddChildView(logo_view_);
419 ntp_view_->AddChildView(content_view_);
419 420
420 search_container_ = 421 search_container_ =
421 new SearchContainerView(ntp_view_, omnibox_popup_view_parent_); 422 new SearchContainerView(ntp_view_, omnibox_popup_view_parent_);
422 search_container_->SetPaintToLayer(true); 423 search_container_->SetPaintToLayer(true);
423 search_container_->SetLayoutManager(new views::FillLayout); 424 search_container_->SetLayoutManager(new views::FillLayout);
424 search_container_->layer()->SetMasksToBounds(true); 425 search_container_->layer()->SetMasksToBounds(true);
425 426
426 ntp_view_->AddChildView(logo_view_);
427 ntp_view_->AddChildView(content_view_);
428
429 contents_container_->SetOverlay(search_container_); 427 contents_container_->SetOverlay(search_container_);
430 } 428 }
431 429
432 void SearchViewController::DestroyViews() { 430 void SearchViewController::DestroyViews() {
433 if (!search_container_) 431 if (!search_container_)
434 return; 432 return;
435 433
436 // We persist the parent of the omnibox so that we don't have to inject a new 434 // We persist the parent of the omnibox so that we don't have to inject a new
437 // parent into ToolbarView. 435 // parent into ToolbarView.
438 omnibox_popup_view_parent_->parent()->RemoveChildView( 436 omnibox_popup_view_parent_->parent()->RemoveChildView(
439 omnibox_popup_view_parent_); 437 omnibox_popup_view_parent_);
440 438
441 contents_container_->SetOverlay(NULL); 439 contents_container_->SetOverlay(NULL);
442 delete search_container_; 440 delete search_container_;
443 search_container_ = ntp_view_ = NULL; 441 search_container_ = NULL;
444 content_view_ = logo_view_ = NULL; 442 ntp_view_ = NULL;
443 logo_view_ = NULL;
444 content_view_ = NULL;
445 445
446 state_ = STATE_NOT_VISIBLE; 446 state_ = STATE_NOT_VISIBLE;
447 } 447 }
448 448
449 void SearchViewController::PopupVisibilityChanged() { 449 void SearchViewController::PopupVisibilityChanged() {
450 // Don't do anything while animating if the child is visible. Otherwise we'll 450 // Don't do anything while animating if the child is visible. Otherwise we'll
451 // prematurely cancel the animation. 451 // prematurely cancel the animation.
452 if (state_ != STATE_ANIMATING || 452 if (state_ != STATE_ANIMATING ||
453 !omnibox_popup_view_parent_->is_child_visible()) { 453 !omnibox_popup_view_parent_->is_child_visible()) {
454 UpdateState(); 454 UpdateState();
455 } 455 }
456 } 456 }
457 457
458 chrome::search::SearchModel* SearchViewController::search_model() { 458 void SearchViewController::Observe(
459 return tab_ ? tab_->search_tab_helper()->model() : NULL; 459 int type,
460 } 460 const content::NotificationSource& source,
461 const content::NotificationDetails& details) {
462 DCHECK_EQ(type, content::NOTIFICATION_WEB_CONTENTS_CONNECTED);
dhollowa 2012/07/20 00:34:09 sky, what I'm seeing is that during launch, when t
sky 2012/07/20 15:58:13 At the time this class is created everything shoul
463 if (!content_view_)
464 return;
465
466 registrar_.Remove(this,
467 content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
468 content::NotificationService::AllSources());
469 content_view_->SetWebContents(NULL);
470 content_view_->LoadInitialURL(GURL(chrome::kChromeUINewTabURL));
471 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698