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

Side by Side Diff: chrome/browser/views/extensions/extension_shelf.cc

Issue 203004: sliding animation for moles (Closed)
Patch Set: review feedback Created 11 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/views/extensions/extension_shelf.h" 5 #include "chrome/browser/views/extensions/extension_shelf.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "app/resource_bundle.h" 9 #include "app/resource_bundle.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 gfx::Size GetPreferredSize() { return size(); } 105 gfx::Size GetPreferredSize() { return size(); }
106 106
107 private: 107 private:
108 DISALLOW_COPY_AND_ASSIGN(PlaceholderView); 108 DISALLOW_COPY_AND_ASSIGN(PlaceholderView);
109 }; 109 };
110 110
111 // A wrapper class for the ExtensionHost displayed as a toolstrip. 111 // A wrapper class for the ExtensionHost displayed as a toolstrip.
112 // The class itself also acts as the View for the handle of the toolstrip 112 // The class itself also acts as the View for the handle of the toolstrip
113 // it represents. 113 // it represents.
114 class ExtensionShelf::Toolstrip : public views::View, 114 class ExtensionShelf::Toolstrip : public views::View,
115 public BrowserBubble::Delegate { 115 public BrowserBubble::Delegate,
116 public AnimationDelegate {
116 public: 117 public:
117 Toolstrip(ExtensionShelf* shelf, ExtensionHost* host, 118 Toolstrip(ExtensionShelf* shelf, ExtensionHost* host,
118 const Extension::ToolstripInfo& info); 119 const Extension::ToolstripInfo& info);
119 virtual ~Toolstrip(); 120 virtual ~Toolstrip();
120 121
122 // Convenience to calculate just the size of the handle.
123 gfx::Size GetHandlePreferredSize();
124
121 // View 125 // View
122 virtual void Paint(gfx::Canvas* canvas); 126 virtual void Paint(gfx::Canvas* canvas);
123 virtual gfx::Size GetPreferredSize(); 127 virtual gfx::Size GetPreferredSize();
124 virtual void Layout(); 128 virtual void Layout();
125 virtual void OnMouseEntered(const views::MouseEvent& event); 129 virtual void OnMouseEntered(const views::MouseEvent& event);
126 virtual void OnMouseExited(const views::MouseEvent& event); 130 virtual void OnMouseExited(const views::MouseEvent& event);
127 virtual bool OnMousePressed(const views::MouseEvent& event); 131 virtual bool OnMousePressed(const views::MouseEvent& event);
128 virtual bool OnMouseDragged(const views::MouseEvent& event); 132 virtual bool OnMouseDragged(const views::MouseEvent& event);
129 virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); 133 virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
130 virtual bool IsFocusable() const { return true; } 134 virtual bool IsFocusable() const { return true; }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 void StopHandleTimer(); 178 void StopHandleTimer();
175 179
176 // Expand / Collapse 180 // Expand / Collapse
177 void Expand(int height, const GURL& url); 181 void Expand(int height, const GURL& url);
178 void Collapse(const GURL& url); 182 void Collapse(const GURL& url);
179 183
180 // BrowserBubble::Delegate 184 // BrowserBubble::Delegate
181 virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble); 185 virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble);
182 virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble); 186 virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble);
183 187
188 // AnimationDelegate
189 virtual void AnimationProgressed(const Animation* animation);
190 virtual void AnimationEnded(const Animation* animation);
191
184 private: 192 private:
185 // The actual renderer that this toolstrip contains. 193 // The actual renderer that this toolstrip contains.
186 ExtensionHost* host_; 194 ExtensionHost* host_;
187 195
188 // Manifest definition of this toolstrip. 196 // Manifest definition of this toolstrip.
189 Extension::ToolstripInfo info_; 197 Extension::ToolstripInfo info_;
190 198
191 // The handle is a BrowserBubble so that it can exist as an independent, 199 // The handle is a BrowserBubble so that it can exist as an independent,
192 // floating window. It also acts as the container for the ExtensionView when 200 // floating window. It also acts as the container for the ExtensionView when
193 // it's being dragged. 201 // it's being dragged.
194 scoped_ptr<BrowserBubble> handle_; 202 scoped_ptr<BrowserBubble> handle_;
195 203
196 // Used for drawing the name of the extension in the handle. 204 // Used for drawing the name of the extension in the handle.
197 scoped_ptr<views::Label> title_; 205 scoped_ptr<views::Label> title_;
198 206
199 // Pointer back to the containing shelf. 207 // Pointer back to the containing shelf.
200 ExtensionShelf* shelf_; 208 ExtensionShelf* shelf_;
201 209
202 // When dragging, a placeholder view is put into the shelf to hold space 210 // When dragging, a placeholder view is put into the shelf to hold space
203 // for the ExtensionView. This view is parent owned when it's in the view 211 // for the ExtensionView. This view is parent owned when it's in the view
204 // hierarchy, so there's no ownership issues here. 212 // hierarchy, so there's no ownership issues here.
205 PlaceholderView* placeholder_view_; 213 PlaceholderView* placeholder_view_;
206 214
207 // Current state of the toolstrip, currently can't both be expanded and 215 // Current state of the toolstrip, currently can't both be expanded and
208 // dragging. 216 // dragging.
209 // TODO(erikkay) Support dragging while expanded. 217 // TODO(erikkay) Support dragging while expanded.
210 bool dragging_; 218 bool dragging_;
211 bool expanded_; 219 bool expanded_;
212 220
221 // The target expanded height of the toolstrip (used for animation).
222 int expanded_height_;
223
213 // If dragging, where did the drag start from. 224 // If dragging, where did the drag start from.
214 gfx::Point initial_drag_location_; 225 gfx::Point initial_drag_location_;
215 226
216 // Timers for tracking mouse hovering. 227 // Timers for tracking mouse hovering.
217 ScopedRunnableMethodFactory<ExtensionShelf::Toolstrip> timer_factory_; 228 ScopedRunnableMethodFactory<ExtensionShelf::Toolstrip> timer_factory_;
218 229
230 // Animate opening and closing the mole.
231 scoped_ptr<SlideAnimation> mole_animation_;
232
219 DISALLOW_COPY_AND_ASSIGN(Toolstrip); 233 DISALLOW_COPY_AND_ASSIGN(Toolstrip);
220 }; 234 };
221 235
222 ExtensionShelf::Toolstrip::Toolstrip(ExtensionShelf* shelf, 236 ExtensionShelf::Toolstrip::Toolstrip(ExtensionShelf* shelf,
223 ExtensionHost* host, 237 ExtensionHost* host,
224 const Extension::ToolstripInfo& info) 238 const Extension::ToolstripInfo& info)
225 : host_(host), 239 : host_(host),
226 info_(info), 240 info_(info),
227 shelf_(shelf), 241 shelf_(shelf),
228 placeholder_view_(NULL), 242 placeholder_view_(NULL),
229 dragging_(false), 243 dragging_(false),
230 expanded_(false), 244 expanded_(false),
231 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)) { 245 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)) {
232 DCHECK(host->view()); 246 DCHECK(host->view());
233 // We're owned by shelf_, not the bubble that we get inserted in and out of. 247 // We're owned by shelf_, not the bubble that we get inserted in and out of.
234 SetParentOwned(false); 248 SetParentOwned(false);
235 249
250 mole_animation_.reset(new SlideAnimation(this));
251
236 std::wstring name = UTF8ToWide(host_->extension()->name()); 252 std::wstring name = UTF8ToWide(host_->extension()->name());
237 // |title_| isn't actually put in the view hierarchy. We just use it 253 // |title_| isn't actually put in the view hierarchy. We just use it
238 // to draw in place. The reason for this is so that we can properly handle 254 // to draw in place. The reason for this is so that we can properly handle
239 // the various mouse events necessary for hovering and dragging. 255 // the various mouse events necessary for hovering and dragging.
240 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 256 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
241 title_.reset(new views::Label(name, rb.GetFont(ResourceBundle::BaseFont))); 257 title_.reset(new views::Label(name, rb.GetFont(ResourceBundle::BaseFont)));
242 title_->SetColor(kHandleTextColor); 258 title_->SetColor(kHandleTextColor);
243 title_->SetDrawHighlighted(true); 259 title_->SetDrawHighlighted(true);
244 title_->SetHighlightColor(kHandleTextHighlightColor); 260 title_->SetHighlightColor(kHandleTextHighlightColor);
245 title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100); 261 title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100);
(...skipping 22 matching lines...) Expand all
268 // Draw the title using a Label as a stamp. 284 // Draw the title using a Label as a stamp.
269 // See constructor for comment about this. 285 // See constructor for comment about this.
270 title_->ProcessPaint(canvas); 286 title_->ProcessPaint(canvas);
271 287
272 if (dragging_) { 288 if (dragging_) {
273 // when we're dragging, draw the bottom border. 289 // when we're dragging, draw the bottom border.
274 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); 290 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1);
275 } 291 }
276 } 292 }
277 293
278 gfx::Size ExtensionShelf::Toolstrip::GetPreferredSize() { 294 gfx::Size ExtensionShelf::Toolstrip::GetHandlePreferredSize() {
279 gfx::Size sz = title_->GetPreferredSize(); 295 gfx::Size sz = title_->GetPreferredSize();
280 sz.set_width(std::max(view()->width(), sz.width())); 296 sz.set_width(std::max(view()->width(), sz.width()));
281 if (!expanded_) 297 if (!expanded_)
282 sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2); 298 sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2);
299 return sz;
300 }
301
302 gfx::Size ExtensionShelf::Toolstrip::GetPreferredSize() {
303 gfx::Size sz = GetHandlePreferredSize();
283 if (dragging_ || expanded_) { 304 if (dragging_ || expanded_) {
284 gfx::Size extension_size = view()->GetPreferredSize(); 305 gfx::Size extension_size = view()->GetPreferredSize();
285 sz.Enlarge(0, extension_size.height() + 2); 306 sz.Enlarge(0, extension_size.height() + 2);
286 } 307 }
287 return sz; 308 return sz;
288 } 309 }
289 310
290 void ExtensionShelf::Toolstrip::Layout() { 311 void ExtensionShelf::Toolstrip::Layout() {
291 if (dragging_ || expanded_) { 312 if (dragging_ || expanded_) {
292 int y = title_->bounds().bottom() + kHandlePadding + 1; 313 int y = title_->bounds().bottom() + kHandlePadding + 1;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 handle_->set_delegate(this); 398 handle_->set_delegate(this);
378 LayoutHandle(); 399 LayoutHandle();
379 } 400 }
380 return handle_.get(); 401 return handle_.get();
381 } 402 }
382 403
383 void ExtensionShelf::Toolstrip::LayoutHandle() { 404 void ExtensionShelf::Toolstrip::LayoutHandle() {
384 if (!handle_.get()) 405 if (!handle_.get())
385 return; 406 return;
386 407
408 int handle_height;
409 if (mole_animation_->IsAnimating()) {
410 // We only want to animate the body of the mole window. When we're
411 // expanding, this is everything except for the handle. When we're
412 // collapsing, this is everything except for the handle and the toolstrip.
413 // We subtract this amount from the target height, figure out the step in
414 // the animation from the rest, and then add it back in.
415 int handle_offset = shelf_->height();
416 if (!mole_animation_->IsShowing())
417 handle_offset += GetPreferredSize().height();
418 else
419 handle_offset += GetHandlePreferredSize().height();
420 int h = expanded_height_ - handle_offset;
421 handle_height = static_cast<int>(h * mole_animation_->GetCurrentValue());
422 handle_height += handle_offset;
423 } else {
424 handle_height = height();
425 }
426
427 // Now figure out where to place the handle on the screen. Since it's a top-
428 // level widget, we need to do some coordinate conversion to get this right.
387 int handle_width = std::max(view()->width(), width()); 429 int handle_width = std::max(view()->width(), width());
388 gfx::Point origin(-kToolstripPadding, -(height() + kToolstripPadding - 1)); 430 gfx::Point origin(-kToolstripPadding,
389 if (expanded_) { 431 -(handle_height + kToolstripPadding - 1));
390 origin.set_y(GetShelfView()->height() - height()); 432 if (expanded_ || mole_animation_->IsAnimating()) {
433 origin.set_y(GetShelfView()->height() - handle_height);
391 views::View::ConvertPointToView(GetShelfView(), shelf_->GetRootView(), 434 views::View::ConvertPointToView(GetShelfView(), shelf_->GetRootView(),
392 &origin); 435 &origin);
393 } else { 436 } else {
394 views::View::ConvertPointToWidget(view(), &origin); 437 views::View::ConvertPointToWidget(view(), &origin);
395 } 438 }
396 SetBounds(0, 0, handle_width, height()); 439 SetBounds(0, 0, handle_width, height());
397 handle_->SetBounds(origin.x(), origin.y(), handle_width, height()); 440 handle_->SetBounds(origin.x(), origin.y(), handle_width, handle_height);
398 handle_->ResizeToView();
399 } 441 }
400 442
401 void ExtensionShelf::Toolstrip::ChildPreferredSizeChanged(View* child) { 443 void ExtensionShelf::Toolstrip::ChildPreferredSizeChanged(View* child) {
402 if (child == view()) { 444 if (child == view()) {
403 child->SizeToPreferredSize(); 445 child->SizeToPreferredSize();
404 Layout(); 446 Layout();
447 LayoutHandle();
405 if (expanded_) { 448 if (expanded_) {
406 LayoutHandle();
407 placeholder_view_->SetWidth(child->width()); 449 placeholder_view_->SetWidth(child->width());
408 shelf_->Layout(); 450 shelf_->Layout();
409 } 451 }
410 } 452 }
411 } 453 }
412 454
413 void ExtensionShelf::Toolstrip::BubbleBrowserWindowMoved( 455 void ExtensionShelf::Toolstrip::BubbleBrowserWindowMoved(
414 BrowserBubble* bubble) { 456 BrowserBubble* bubble) {
415 HideShelfHandle(0); 457 HideShelfHandle(0);
416 } 458 }
417 459
418 void ExtensionShelf::Toolstrip::BubbleBrowserWindowClosing( 460 void ExtensionShelf::Toolstrip::BubbleBrowserWindowClosing(
419 BrowserBubble* bubble) { 461 BrowserBubble* bubble) {
420 DoHideShelfHandle(); 462 DoHideShelfHandle();
421 } 463 }
422 464
465 void ExtensionShelf::Toolstrip::AnimationProgressed(
466 const Animation* animation) {
467 LayoutHandle();
468 }
469
470 void ExtensionShelf::Toolstrip::AnimationEnded(const Animation* animation) {
471 LayoutHandle();
472 if (!expanded_) {
473 // Must use the delay due to bug 18248.
474 HideShelfHandle(kHideDelayMs * 2);
475 AttachToShelf(false);
476 }
477 }
478
423 void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) { 479 void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) {
424 DCHECK(handle_.get()); 480 DCHECK(handle_.get());
425 DCHECK(!placeholder_view_); 481 DCHECK(!placeholder_view_);
426 if (browserDetach && handle_->attached()) 482 if (browserDetach && handle_->attached())
427 handle_->DetachFromBrowser(); 483 handle_->DetachFromBrowser();
428 484
429 // Construct a placeholder view to replace the view. 485 // Construct a placeholder view to replace the view.
430 placeholder_view_ = new PlaceholderView(); 486 placeholder_view_ = new PlaceholderView();
431 placeholder_view_->SetBounds(view()->bounds()); 487 placeholder_view_->SetBounds(view()->bounds());
432 shelf_->AddChildView(placeholder_view_); 488 shelf_->AddChildView(placeholder_view_);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 expanded_ = true; 547 expanded_ = true;
492 view()->set_is_toolstrip(!expanded_); 548 view()->set_is_toolstrip(!expanded_);
493 549
494 bool navigate = (!url.is_empty() && url != host_->GetURL()); 550 bool navigate = (!url.is_empty() && url != host_->GetURL());
495 if (navigate) 551 if (navigate)
496 host_->NavigateToURL(url); 552 host_->NavigateToURL(url);
497 553
498 StopHandleTimer(); 554 StopHandleTimer();
499 DetachFromShelf(false); 555 DetachFromShelf(false);
500 556
557 mole_animation_->Show();
558
501 gfx::Size extension_size = view()->GetPreferredSize(); 559 gfx::Size extension_size = view()->GetPreferredSize();
502 extension_size.set_height(height); 560 extension_size.set_height(height);
503 view()->SetPreferredSize(extension_size); 561 view()->SetPreferredSize(extension_size);
504 LayoutHandle(); 562 expanded_height_ = GetPreferredSize().height();
505 563
506 // This is to prevent flickering as the page loads and lays out. 564 // This is to prevent flickering as the page loads and lays out.
507 // Once the navigation is finished, ExtensionView will wind up setting 565 // Once the navigation is finished, ExtensionView will wind up setting
508 // visibility to true. 566 // visibility to true.
509 if (navigate) 567 if (navigate)
510 view()->SetVisible(false); 568 view()->SetVisible(false);
511 } 569 }
512 570
513 void ExtensionShelf::Toolstrip::Collapse(const GURL& url) { 571 void ExtensionShelf::Toolstrip::Collapse(const GURL& url) {
514 DCHECK(expanded_); 572 DCHECK(expanded_);
515 expanded_ = false; 573 expanded_ = false;
516 view()->set_is_toolstrip(!expanded_); 574 view()->set_is_toolstrip(!expanded_);
517 575
576 mole_animation_->Hide();
577
518 gfx::Size extension_size = view()->GetPreferredSize(); 578 gfx::Size extension_size = view()->GetPreferredSize();
519 extension_size.set_height(kToolstripHeight); 579 extension_size.set_height(kToolstripHeight);
520 view()->SetPreferredSize(extension_size); 580 view()->SetPreferredSize(extension_size);
521 AttachToShelf(false);
522 581
523 if (!url.is_empty() && url != host_->GetURL()) { 582 if (!url.is_empty() && url != host_->GetURL()) {
524 host_->NavigateToURL(url); 583 host_->NavigateToURL(url);
525 584
526 // This is to prevent flickering as the page loads and lays out. 585 // This is to prevent flickering as the page loads and lays out.
527 // Once the navigation is finished, ExtensionView will wind up setting 586 // Once the navigation is finished, ExtensionView will wind up setting
528 // visibility to true. 587 // visibility to true.
529 view()->SetVisible(false); 588 view()->SetVisible(false);
530 } 589 }
531
532 // Must use the delay due to bug 18248.
533 HideShelfHandle(kHideDelayMs);
534 } 590 }
535 591
536 void ExtensionShelf::Toolstrip::ShowShelfHandle() { 592 void ExtensionShelf::Toolstrip::ShowShelfHandle() {
537 StopHandleTimer(); 593 StopHandleTimer();
538 if (handle_visible()) 594 if (handle_visible())
539 return; 595 return;
540 MessageLoop::current()->PostDelayedTask(FROM_HERE, 596 MessageLoop::current()->PostDelayedTask(FROM_HERE,
541 timer_factory_.NewRunnableMethod( 597 timer_factory_.NewRunnableMethod(
542 &ExtensionShelf::Toolstrip::DoShowShelfHandle), 598 &ExtensionShelf::Toolstrip::DoShowShelfHandle),
543 1000); 599 1000);
544 } 600 }
545 601
546 void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) { 602 void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) {
547 StopHandleTimer(); 603 StopHandleTimer();
548 if (!handle_visible() || dragging_ || expanded_) 604 if (!handle_visible() || dragging_ || expanded_ ||
605 mole_animation_->IsAnimating()) {
549 return; 606 return;
607 }
550 if (delay_ms) { 608 if (delay_ms) {
551 MessageLoop::current()->PostDelayedTask(FROM_HERE, 609 MessageLoop::current()->PostDelayedTask(FROM_HERE,
552 timer_factory_.NewRunnableMethod( 610 timer_factory_.NewRunnableMethod(
553 &ExtensionShelf::Toolstrip::DoHideShelfHandle), 611 &ExtensionShelf::Toolstrip::DoHideShelfHandle),
554 delay_ms); 612 delay_ms);
555 } else { 613 } else {
556 DoHideShelfHandle(); 614 DoHideShelfHandle();
557 } 615 }
558 } 616 }
559 617
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 1075
1018 bool ExtensionShelf::IsAlwaysShown() { 1076 bool ExtensionShelf::IsAlwaysShown() {
1019 Profile* profile = browser_->profile(); 1077 Profile* profile = browser_->profile();
1020 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf); 1078 return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf);
1021 } 1079 }
1022 1080
1023 bool ExtensionShelf::OnNewTabPage() { 1081 bool ExtensionShelf::OnNewTabPage() {
1024 return (browser_ && browser_->GetSelectedTabContents() && 1082 return (browser_ && browser_->GetSelectedTabContents() &&
1025 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible()); 1083 browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible());
1026 } 1084 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698