OLD | NEW |
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/extensions/extension_shelf.h" | 5 #include "chrome/browser/extensions/extension_shelf.h" |
6 | 6 |
7 #include "app/resource_bundle.h" | 7 #include "app/resource_bundle.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "chrome/browser/browser.h" | 10 #include "chrome/browser/browser.h" |
11 #include "chrome/browser/extensions/extension_process_manager.h" | 11 #include "chrome/browser/extensions/extension_process_manager.h" |
12 #include "chrome/browser/extensions/extension_view.h" | 12 #include "chrome/browser/extensions/extension_view.h" |
13 #include "chrome/browser/extensions/extensions_service.h" | 13 #include "chrome/browser/extensions/extensions_service.h" |
14 #include "chrome/browser/profile.h" | 14 #include "chrome/browser/profile.h" |
15 #include "chrome/common/extensions/extension.h" | 15 #include "chrome/common/extensions/extension.h" |
16 #include "chrome/common/notification_service.h" | 16 #include "chrome/common/notification_service.h" |
17 #include "skia/ext/skia_utils.h" | 17 #include "skia/ext/skia_utils.h" |
18 #include "views/controls/label.h" | 18 #include "views/controls/label.h" |
| 19 #include "views/screen.h" |
| 20 #include "views/widget/root_view.h" |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // Margins around the content. | 24 // Margins around the content. |
23 static const int kTopMargin = 2; | 25 static const int kTopMargin = 2; |
24 static const int kBottomMargin = 2; | 26 static const int kBottomMargin = 2; |
25 static const int kLeftMargin = 0; | 27 static const int kLeftMargin = 0; |
26 static const int kRightMargin = 0; | 28 static const int kRightMargin = 0; |
27 | 29 |
28 // Padding on left and right side of an extension toolstrip. | 30 // Padding on left and right side of an extension toolstrip. |
(...skipping 16 matching lines...) Expand all Loading... |
45 SkColorSetARGB(200, 255, 255, 255); | 47 SkColorSetARGB(200, 255, 255, 255); |
46 | 48 |
47 // Handle padding | 49 // Handle padding |
48 static const int kHandlePadding = 4; | 50 static const int kHandlePadding = 4; |
49 | 51 |
50 // TODO(erikkay) convert back to a gradient when Glen figures out the | 52 // TODO(erikkay) convert back to a gradient when Glen figures out the |
51 // specs. | 53 // specs. |
52 // static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); | 54 // static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); |
53 // static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248); | 55 // static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248); |
54 | 56 |
| 57 // Delays for showing and hiding the shelf handle. |
| 58 static const int kHideDelayMs = 500; |
| 59 |
55 } // namespace | 60 } // namespace |
56 | 61 |
57 | 62 |
58 // A small handle that is used for dragging or otherwise interacting with an | 63 // A small handle that is used for dragging or otherwise interacting with an |
59 // extension toolstrip. | 64 // extension toolstrip. |
60 class ExtensionShelfHandle : public views::View { | 65 class ExtensionShelfHandle : public views::View { |
61 public: | 66 public: |
62 explicit ExtensionShelfHandle(ExtensionShelf* shelf); | 67 explicit ExtensionShelfHandle(ExtensionShelf* shelf); |
63 | 68 |
64 // The ExtensionView that the handle is attached to. | 69 // The ExtensionView that the handle is attached to. |
65 void SetExtensionView(ExtensionView* v); | 70 void SetExtensionView(ExtensionView* v); |
66 | 71 |
67 // View | 72 // View |
68 virtual void Paint(gfx::Canvas* canvas); | 73 virtual void Paint(gfx::Canvas* canvas); |
69 virtual gfx::Size GetPreferredSize(); | 74 virtual gfx::Size GetPreferredSize(); |
70 virtual void Layout(); | 75 virtual void Layout(); |
71 virtual void OnMouseEntered(const views::MouseEvent& event); | 76 virtual void OnMouseEntered(const views::MouseEvent& event); |
72 virtual void OnMouseExited(const views::MouseEvent& event); | 77 virtual void OnMouseExited(const views::MouseEvent& event); |
| 78 virtual bool OnMousePressed(const views::MouseEvent& event); |
| 79 virtual bool OnMouseDragged(const views::MouseEvent& event); |
| 80 virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled); |
| 81 virtual bool IsFocusable() const { return true; } |
73 | 82 |
74 private: | 83 private: |
75 ExtensionShelf* shelf_; | 84 ExtensionShelf* shelf_; |
76 ExtensionView* extension_view_; | 85 ExtensionView* extension_view_; |
77 views::Label* title_; | 86 scoped_ptr<views::Label> title_; |
| 87 bool dragging_; |
| 88 gfx::Point initial_drag_location_; |
78 | 89 |
79 DISALLOW_COPY_AND_ASSIGN(ExtensionShelfHandle); | 90 DISALLOW_COPY_AND_ASSIGN(ExtensionShelfHandle); |
80 }; | 91 }; |
81 | 92 |
82 ExtensionShelfHandle::ExtensionShelfHandle(ExtensionShelf* shelf) | 93 ExtensionShelfHandle::ExtensionShelfHandle(ExtensionShelf* shelf) |
83 : shelf_(shelf), extension_view_(NULL) { | 94 : shelf_(shelf), extension_view_(NULL), dragging_(false) { |
84 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 95 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
85 title_ = new views::Label(L"", rb.GetFont(ResourceBundle::BaseFont)); | |
86 | 96 |
87 // Set enabled to false so we get the events. | 97 // |title_| isn't actually put in the view hierarchy. We just use it |
88 title_->SetEnabled(false); | 98 // to draw in place. The reason for this is so that we can properly handle |
89 | 99 // the various mouse events necessary for hovering and dragging. |
90 // Set the colors afterwards so that the label doesn't get a disabled | 100 title_.reset(new views::Label(L"", rb.GetFont(ResourceBundle::BaseFont))); |
91 // color. | |
92 title_->SetColor(kHandleTextColor); | 101 title_->SetColor(kHandleTextColor); |
93 title_->SetDrawHighlighted(true); | 102 title_->SetDrawHighlighted(true); |
94 title_->SetHighlightColor(kHandleTextHighlightColor); | 103 title_->SetHighlightColor(kHandleTextHighlightColor); |
95 title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100); | 104 title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100); |
96 title_->SizeToPreferredSize(); | 105 title_->SizeToPreferredSize(); |
97 AddChildView(title_); | |
98 } | 106 } |
99 | 107 |
100 void ExtensionShelfHandle::SetExtensionView(ExtensionView* v) { | 108 void ExtensionShelfHandle::SetExtensionView(ExtensionView* v) { |
| 109 DCHECK(v->extension()); |
101 extension_view_ = v; | 110 extension_view_ = v; |
| 111 if (!extension_view_->extension()) |
| 112 return; |
102 title_->SetText(UTF8ToWide(extension_view_->extension()->name())); | 113 title_->SetText(UTF8ToWide(extension_view_->extension()->name())); |
103 title_->SizeToPreferredSize(); | 114 title_->SizeToPreferredSize(); |
104 SizeToPreferredSize(); | 115 SizeToPreferredSize(); |
105 } | 116 } |
106 | 117 |
107 void ExtensionShelfHandle::Paint(gfx::Canvas* canvas) { | 118 void ExtensionShelfHandle::Paint(gfx::Canvas* canvas) { |
108 canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); | 119 canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); |
109 canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); | 120 canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); |
110 canvas->FillRectInt(kBorderColor, 0, 0, 1, height() - 1); | 121 canvas->FillRectInt(kBorderColor, 0, 0, 1, height() - 1); |
111 canvas->FillRectInt(kBorderColor, width() - 1, 0, 1, height() - 1); | 122 canvas->FillRectInt(kBorderColor, width() - 1, 0, 1, height() - 1); |
112 int ext_width = extension_view_->width() + kToolstripPadding + | 123 int ext_width = extension_view_->width() + kToolstripPadding + |
113 kToolstripDividerWidth; | 124 kToolstripDividerWidth; |
114 if (ext_width < width()) { | 125 if (ext_width < width()) { |
115 canvas->FillRectInt(kBorderColor, ext_width, height() - 1, | 126 canvas->FillRectInt(kBorderColor, ext_width, height() - 1, |
116 width() - ext_width, 1); | 127 width() - ext_width, 1); |
117 } | 128 } |
| 129 |
| 130 // Draw the title using a Label as a stamp. |
| 131 // See constructor for comment about this. |
| 132 title_->ProcessPaint(canvas); |
| 133 |
| 134 if (dragging_) { |
| 135 // when we're dragging, draw the bottom border. |
| 136 canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); |
| 137 } |
118 } | 138 } |
119 | 139 |
120 gfx::Size ExtensionShelfHandle::GetPreferredSize() { | 140 gfx::Size ExtensionShelfHandle::GetPreferredSize() { |
121 gfx::Size sz = title_->GetPreferredSize(); | 141 gfx::Size sz = title_->GetPreferredSize(); |
| 142 if (extension_view_) { |
| 143 int width = std::max(extension_view_->width() + 2, sz.width()); |
| 144 sz.set_width(width); |
| 145 } |
122 sz.Enlarge(kHandlePadding * 2, kHandlePadding * 2); | 146 sz.Enlarge(kHandlePadding * 2, kHandlePadding * 2); |
| 147 if (dragging_) { |
| 148 gfx::Size extension_size = extension_view_->GetPreferredSize(); |
| 149 sz.Enlarge(0, extension_size.height() + 2); |
| 150 } |
123 return sz; | 151 return sz; |
124 } | 152 } |
125 | 153 |
126 void ExtensionShelfHandle::Layout() { | 154 void ExtensionShelfHandle::Layout() { |
| 155 if (dragging_) { |
| 156 int y = title_->bounds().bottom() + kHandlePadding + 1; |
| 157 extension_view_->SetBounds(1, |
| 158 y, |
| 159 extension_view_->width(), |
| 160 extension_view_->height()); |
| 161 } |
127 } | 162 } |
128 | 163 |
129 void ExtensionShelfHandle::OnMouseEntered(const views::MouseEvent& event) { | 164 void ExtensionShelfHandle::OnMouseEntered(const views::MouseEvent& event) { |
130 DCHECK(extension_view_); | 165 DCHECK(extension_view_); |
131 shelf_->OnExtensionMouseEvent(extension_view_); | 166 shelf_->OnExtensionMouseEvent(extension_view_); |
132 } | 167 } |
133 | 168 |
134 void ExtensionShelfHandle::OnMouseExited(const views::MouseEvent& event) { | 169 void ExtensionShelfHandle::OnMouseExited(const views::MouseEvent& event) { |
135 DCHECK(extension_view_); | 170 DCHECK(extension_view_); |
136 shelf_->OnExtensionMouseLeave(extension_view_); | 171 shelf_->OnExtensionMouseLeave(extension_view_); |
137 } | 172 } |
138 | 173 |
| 174 bool ExtensionShelfHandle::OnMousePressed(const views::MouseEvent& event) { |
| 175 initial_drag_location_ = event.location(); |
| 176 return true; |
| 177 } |
| 178 |
| 179 bool ExtensionShelfHandle::OnMouseDragged(const views::MouseEvent& event) { |
| 180 if (!dragging_) { |
| 181 int y_delta = abs(initial_drag_location_.y() - event.location().y()); |
| 182 if (y_delta > GetVerticalDragThreshold()) { |
| 183 dragging_ = true; |
| 184 shelf_->DragExtension(); |
| 185 } |
| 186 } else { |
| 187 // When freely dragging a window, you can really only trust the |
| 188 // actual screen point. Coordinate conversions, just don't work. |
| 189 gfx::Point screen = views::Screen::GetCursorScreenPoint(); |
| 190 |
| 191 // However, the handle is actually a child of the browser window |
| 192 // so we need to convert it back to local coordinates. |
| 193 gfx::Point origin(0, 0); |
| 194 views::View::ConvertPointToScreen(shelf_->GetRootView(), &origin); |
| 195 screen.set_x(screen.x() - origin.x() - initial_drag_location_.x()); |
| 196 screen.set_y(screen.y() - origin.y() - initial_drag_location_.y()); |
| 197 shelf_->DragHandleTo(screen); |
| 198 } |
| 199 return true; |
| 200 } |
| 201 |
| 202 void ExtensionShelfHandle::OnMouseReleased(const views::MouseEvent& event, |
| 203 bool canceled) { |
| 204 if (dragging_) { |
| 205 views::View::OnMouseReleased(event, canceled); |
| 206 dragging_ = false; |
| 207 shelf_->DropExtension(event.location(), canceled); |
| 208 } |
| 209 } |
139 | 210 |
140 //////////////////////////////////////////////// | 211 //////////////////////////////////////////////// |
141 | 212 |
142 ExtensionShelf::ExtensionShelf(Browser* browser) | 213 ExtensionShelf::ExtensionShelf(Browser* browser) |
143 : browser_(browser), | 214 : browser_(browser), |
144 handle_(NULL), | 215 handle_(NULL), |
145 handle_visible_(false), | 216 handle_visible_(false), |
146 current_handle_view_(NULL), | 217 current_handle_view_(NULL), |
147 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)) { | 218 ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)), |
| 219 drag_placeholder_view_(NULL) { |
148 // Watch extensions loaded and unloaded notifications. | 220 // Watch extensions loaded and unloaded notifications. |
149 registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, | 221 registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, |
150 NotificationService::AllSources()); | 222 NotificationService::AllSources()); |
151 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, | 223 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, |
152 NotificationService::AllSources()); | 224 NotificationService::AllSources()); |
153 | 225 |
154 // Add any already-loaded extensions now, since we missed the notification for | 226 // Add any already-loaded extensions now, since we missed the notification for |
155 // those. | 227 // those. |
156 ExtensionsService* service = browser_->profile()->GetExtensionsService(); | 228 ExtensionsService* service = browser_->profile()->GetExtensionsService(); |
157 if (service) { // This can be null in unit tests. | 229 if (service) { // This can be null in unit tests. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 ExtensionView* child = static_cast<ExtensionView*>(GetChildViewAt(i)); | 318 ExtensionView* child = static_cast<ExtensionView*>(GetChildViewAt(i)); |
247 if (event.x() > (child->x() + child->width() + kToolstripPadding)) | 319 if (event.x() > (child->x() + child->width() + kToolstripPadding)) |
248 continue; | 320 continue; |
249 current_handle_view_ = child; | 321 current_handle_view_ = child; |
250 ShowShelfHandle(); | 322 ShowShelfHandle(); |
251 break; | 323 break; |
252 } | 324 } |
253 } | 325 } |
254 | 326 |
255 void ExtensionShelf::OnMouseExited(const views::MouseEvent& event) { | 327 void ExtensionShelf::OnMouseExited(const views::MouseEvent& event) { |
256 HideShelfHandle(100); | 328 HideShelfHandle(kHideDelayMs); |
257 } | 329 } |
258 | 330 |
259 void ExtensionShelf::Observe(NotificationType type, | 331 void ExtensionShelf::Observe(NotificationType type, |
260 const NotificationSource& source, | 332 const NotificationSource& source, |
261 const NotificationDetails& details) { | 333 const NotificationDetails& details) { |
262 switch (type.value) { | 334 switch (type.value) { |
263 case NotificationType::EXTENSIONS_LOADED: { | 335 case NotificationType::EXTENSIONS_LOADED: { |
264 const ExtensionList* extensions = Details<ExtensionList>(details).ptr(); | 336 const ExtensionList* extensions = Details<ExtensionList>(details).ptr(); |
265 AddExtensionViews(extensions); | 337 AddExtensionViews(extensions); |
266 break; | 338 break; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 PreferredSizeChanged(); | 397 PreferredSizeChanged(); |
326 } | 398 } |
327 return removed_toolstrip; | 399 return removed_toolstrip; |
328 } | 400 } |
329 | 401 |
330 bool ExtensionShelf::HasExtensionViews() { | 402 bool ExtensionShelf::HasExtensionViews() { |
331 return GetChildViewCount() > 0; | 403 return GetChildViewCount() > 0; |
332 } | 404 } |
333 | 405 |
334 void ExtensionShelf::OnExtensionMouseEvent(ExtensionView* view) { | 406 void ExtensionShelf::OnExtensionMouseEvent(ExtensionView* view) { |
| 407 // Ignore these events when dragging. |
| 408 if (drag_placeholder_view_) |
| 409 return; |
335 if (view != current_handle_view_) { | 410 if (view != current_handle_view_) { |
336 current_handle_view_ = view; | 411 current_handle_view_ = view; |
337 } | 412 } |
338 ShowShelfHandle(); | 413 ShowShelfHandle(); |
339 } | 414 } |
340 | 415 |
341 void ExtensionShelf::OnExtensionMouseLeave(ExtensionView* view) { | 416 void ExtensionShelf::OnExtensionMouseLeave(ExtensionView* view) { |
| 417 // Ignore these events when dragging. |
| 418 if (drag_placeholder_view_) |
| 419 return; |
342 if (view == current_handle_view_) { | 420 if (view == current_handle_view_) { |
343 HideShelfHandle(100); | 421 HideShelfHandle(kHideDelayMs); |
344 } | 422 } |
345 } | 423 } |
346 | 424 |
347 void ExtensionShelf::BubbleBrowserWindowMoved(BrowserBubble* bubble) { | 425 void ExtensionShelf::BubbleBrowserWindowMoved(BrowserBubble* bubble) { |
348 HideShelfHandle(0); | 426 HideShelfHandle(0); |
349 } | 427 } |
350 | 428 |
351 void ExtensionShelf::BubbleBrowserWindowClosed(BrowserBubble* bubble) { | 429 void ExtensionShelf::BubbleBrowserWindowClosed(BrowserBubble* bubble) { |
352 // We'll be going away shortly, so no need to do any other teardown here. | 430 // We'll be going away shortly, so no need to do any other teardown here. |
353 HideShelfHandle(0); | 431 HideShelfHandle(0); |
354 } | 432 } |
355 | 433 |
| 434 void ExtensionShelf::DragExtension() { |
| 435 // Construct a placeholder view to replace the view. |
| 436 // TODO(erikkay) the placeholder should draw a dimmed version of the |
| 437 // extension view |
| 438 int index = GetChildIndex(current_handle_view_); |
| 439 drag_placeholder_view_ = new View(); |
| 440 drag_placeholder_view_->SetBounds(current_handle_view_->bounds()); |
| 441 AddChildView(index, drag_placeholder_view_); |
| 442 |
| 443 // Now move the view into the handle's widget. |
| 444 ExtensionShelfHandle* handle_view = |
| 445 static_cast<ExtensionShelfHandle*>(GetHandle()->view()); |
| 446 handle_view->AddChildView(current_handle_view_); |
| 447 handle_view->SizeToPreferredSize(); |
| 448 handle_->ResizeToView(); |
| 449 handle_view->Layout(); |
| 450 handle_->DetachFromBrowser(); |
| 451 SchedulePaint(); |
| 452 } |
| 453 |
| 454 void ExtensionShelf::DropExtension(const gfx::Point& pt, bool cancel) { |
| 455 handle_->AttachToBrowser(); |
| 456 |
| 457 // Replace the placeholder view with the original. |
| 458 int index = GetChildIndex(drag_placeholder_view_); |
| 459 AddChildView(index, current_handle_view_); |
| 460 current_handle_view_->SetBounds(drag_placeholder_view_->bounds()); |
| 461 RemoveChildView(drag_placeholder_view_); |
| 462 delete drag_placeholder_view_; |
| 463 drag_placeholder_view_ = NULL; |
| 464 |
| 465 ExtensionShelfHandle* handle_view = |
| 466 static_cast<ExtensionShelfHandle*>(GetHandle()->view()); |
| 467 handle_view->SizeToPreferredSize(); |
| 468 handle_view->Layout(); |
| 469 handle_->ResizeToView(); |
| 470 LayoutShelfHandle(); |
| 471 SchedulePaint(); |
| 472 } |
| 473 |
| 474 void ExtensionShelf::DragHandleTo(const gfx::Point& pt) { |
| 475 handle_->MoveTo(pt.x(), pt.y()); |
| 476 } |
| 477 |
356 void ExtensionShelf::InitBackground(gfx::Canvas* canvas, | 478 void ExtensionShelf::InitBackground(gfx::Canvas* canvas, |
357 const SkRect& subset) { | 479 const SkRect& subset) { |
358 if (!background_.empty()) | 480 if (!background_.empty()) |
359 return; | 481 return; |
360 | 482 |
361 const SkBitmap& background = canvas->getDevice()->accessBitmap(false); | 483 const SkBitmap& background = canvas->getDevice()->accessBitmap(false); |
362 | 484 |
363 // Extract the correct subset of the toolstrip background into a bitmap. We | 485 // Extract the correct subset of the toolstrip background into a bitmap. We |
364 // must use a temporary here because extractSubset() returns a bitmap that | 486 // must use a temporary here because extractSubset() returns a bitmap that |
365 // references pixels in the original one and we want to actually make a copy | 487 // references pixels in the original one and we want to actually make a copy |
(...skipping 16 matching lines...) Expand all Loading... |
382 temp.copyTo(&background_, temp.config()); | 504 temp.copyTo(&background_, temp.config()); |
383 DCHECK(background_.readyToDraw()); | 505 DCHECK(background_.readyToDraw()); |
384 | 506 |
385 // Tell all extension views about the new background | 507 // Tell all extension views about the new background |
386 int count = GetChildViewCount(); | 508 int count = GetChildViewCount(); |
387 for (int i = 0; i < count; ++i) | 509 for (int i = 0; i < count; ++i) |
388 static_cast<ExtensionView*>(GetChildViewAt(i))->SetBackground(background_); | 510 static_cast<ExtensionView*>(GetChildViewAt(i))->SetBackground(background_); |
389 } | 511 } |
390 | 512 |
391 void ExtensionShelf::ShowShelfHandle() { | 513 void ExtensionShelf::ShowShelfHandle() { |
| 514 if (drag_placeholder_view_) |
| 515 return; |
392 if (!timer_factory_.empty()) | 516 if (!timer_factory_.empty()) |
393 timer_factory_.RevokeAll(); | 517 timer_factory_.RevokeAll(); |
394 if (handle_visible_) { | 518 if (handle_visible_) { |
395 // The contents may have changed, even though the handle is still visible. | 519 // The contents may have changed, even though the handle is still visible. |
396 LayoutShelfHandle(); | 520 LayoutShelfHandle(); |
397 return; | 521 return; |
398 } | 522 } |
399 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 523 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
400 timer_factory_.NewRunnableMethod(&ExtensionShelf::DoShowShelfHandle), | 524 timer_factory_.NewRunnableMethod(&ExtensionShelf::DoShowShelfHandle), |
401 1000); | 525 1000); |
402 } | 526 } |
403 | 527 |
404 void ExtensionShelf::DoShowShelfHandle() { | 528 void ExtensionShelf::DoShowShelfHandle() { |
405 if (!handle_visible_) { | 529 if (!handle_visible_) { |
406 handle_visible_ = true; | 530 handle_visible_ = true; |
407 LayoutShelfHandle(); | 531 LayoutShelfHandle(); |
408 handle_->Show(); | 532 handle_->Show(); |
409 } | 533 } |
410 } | 534 } |
411 | 535 |
412 void ExtensionShelf::HideShelfHandle(int delay_ms) { | 536 void ExtensionShelf::HideShelfHandle(int delay_ms) { |
| 537 if (drag_placeholder_view_) |
| 538 return; |
413 if (!timer_factory_.empty()) | 539 if (!timer_factory_.empty()) |
414 timer_factory_.RevokeAll(); | 540 timer_factory_.RevokeAll(); |
415 if (!handle_visible_) | 541 if (!handle_visible_) |
416 return; | 542 return; |
417 if (delay_ms) { | 543 if (delay_ms) { |
418 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 544 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
419 timer_factory_.NewRunnableMethod(&ExtensionShelf::DoHideShelfHandle), | 545 timer_factory_.NewRunnableMethod(&ExtensionShelf::DoHideShelfHandle), |
420 delay_ms); | 546 delay_ms); |
421 } else { | 547 } else { |
422 DoHideShelfHandle(); | 548 DoHideShelfHandle(); |
423 } | 549 } |
424 } | 550 } |
425 | 551 |
426 void ExtensionShelf::DoHideShelfHandle() { | 552 void ExtensionShelf::DoHideShelfHandle() { |
427 if (handle_visible_) { | 553 if (handle_visible_) { |
428 handle_visible_ = false; | 554 handle_visible_ = false; |
429 handle_->Hide(); | 555 handle_->Hide(); |
430 // TODO(erikkay) with this enabled, I get an odd crash shortly after hide. | 556 handle_->DetachFromBrowser(); |
431 //handle_.reset(NULL); | 557 handle_.reset(NULL); |
432 current_handle_view_ = NULL; | 558 current_handle_view_ = NULL; |
433 } | 559 } |
434 } | 560 } |
435 | 561 |
436 void ExtensionShelf::LayoutShelfHandle() { | 562 void ExtensionShelf::LayoutShelfHandle() { |
437 if (current_handle_view_) { | 563 if (current_handle_view_) { |
438 GetHandle(); // ensure that the handle exists since we delete on hide | 564 GetHandle(); // ensure that the handle exists since we delete on hide |
439 ExtensionShelfHandle* handle_view = | 565 ExtensionShelfHandle* handle_view = |
440 static_cast<ExtensionShelfHandle*>(GetHandle()->view()); | 566 static_cast<ExtensionShelfHandle*>(GetHandle()->view()); |
441 handle_view->SetExtensionView(current_handle_view_); | 567 handle_view->SetExtensionView(current_handle_view_); |
442 int width = std::max(current_handle_view_->width(), handle_view->width()); | 568 int width = std::max(current_handle_view_->width(), handle_view->width()); |
443 gfx::Point origin(-kToolstripPadding, | 569 gfx::Point origin(-kToolstripPadding, |
444 -(handle_view->height() + kToolstripPadding - 1)); | 570 -(handle_view->height() + kToolstripPadding - 1)); |
445 views::View::ConvertPointToWidget(current_handle_view_, &origin); | 571 views::View::ConvertPointToWidget(current_handle_view_, &origin); |
446 handle_view->SetBounds(0, 0, width, handle_view->height()); | 572 handle_view->SetBounds(0, 0, width, handle_view->height()); |
447 handle_->SetBounds(origin.x(), origin.y(), | 573 handle_->SetBounds(origin.x(), origin.y(), |
448 width, handle_view->height()); | 574 width, handle_view->height()); |
449 } | 575 } |
450 } | 576 } |
OLD | NEW |