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

Side by Side Diff: chrome/browser/views/browser_actions_container.cc

Issue 3076001: Cleanup: Remove pointless GetInsets() override. Simplify |container_size_| t... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 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) 2010 The Chromium Authors. All rights reserved. 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 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/browser_actions_container.h" 5 #include "chrome/browser/views/browser_actions_container.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "app/slide_animation.h" 9 #include "app/slide_animation.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 // The margin above the chevron. 72 // The margin above the chevron.
73 static const int kChevronTopMargin = 9; 73 static const int kChevronTopMargin = 9;
74 74
75 // The margin to the right of the chevron. 75 // The margin to the right of the chevron.
76 static const int kChevronRightMargin = 4; 76 static const int kChevronRightMargin = 4;
77 77
78 // Width for the resize area. 78 // Width for the resize area.
79 static const int kResizeAreaWidth = 4; 79 static const int kResizeAreaWidth = 4;
80 80
81 // Width of the drop indicator.
82 static const int kDropIndicatorWidth = 2;
83
84 // Color of the drop indicator.
85 static const SkColor kDropIndicatorColor = SK_ColorBLACK;
86
87 // The x offset for the drop indicator (how much we shift it by). 81 // The x offset for the drop indicator (how much we shift it by).
88 static const int kDropIndicatorOffsetLtr = 3; 82 static const int kDropIndicatorOffsetLtr = 3;
89 static const int kDropIndicatorOffsetRtl = 9; 83 static const int kDropIndicatorOffsetRtl = 9;
90 84
91 } // namespace. 85 } // namespace.
92 86
93 // Static. 87 // Static.
94 bool BrowserActionsContainer::disable_animations_during_testing_ = false; 88 bool BrowserActionsContainer::disable_animations_during_testing_ = false;
95 89
96 //////////////////////////////////////////////////////////////////////////////// 90 ////////////////////////////////////////////////////////////////////////////////
97 // BrowserActionButton 91 // BrowserActionButton
98 92
99 BrowserActionButton::BrowserActionButton(Extension* extension, 93 BrowserActionButton::BrowserActionButton(Extension* extension,
100 BrowserActionsContainer* panel) 94 BrowserActionsContainer* panel)
101 : ALLOW_THIS_IN_INITIALIZER_LIST(MenuButton(this, L"", NULL, false)), 95 : ALLOW_THIS_IN_INITIALIZER_LIST(
96 MenuButton(this, std::wstring(), NULL, false)),
102 browser_action_(extension->browser_action()), 97 browser_action_(extension->browser_action()),
103 extension_(extension), 98 extension_(extension),
104 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), 99 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
105 showing_context_menu_(false), 100 showing_context_menu_(false),
106 panel_(panel) { 101 panel_(panel) {
107 set_alignment(TextButton::ALIGN_CENTER); 102 set_alignment(TextButton::ALIGN_CENTER);
108 103
109 // No UpdateState() here because View hierarchy not setup yet. Our parent 104 // No UpdateState() here because View hierarchy not setup yet. Our parent
110 // should call UpdateState() after creation. 105 // should call UpdateState() after creation.
111 106
(...skipping 19 matching lines...) Expand all
131 126
132 void BrowserActionButton::Destroy() { 127 void BrowserActionButton::Destroy() {
133 if (showing_context_menu_) { 128 if (showing_context_menu_) {
134 context_menu_menu_->CancelMenu(); 129 context_menu_menu_->CancelMenu();
135 MessageLoop::current()->DeleteSoon(FROM_HERE, this); 130 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
136 } else { 131 } else {
137 delete this; 132 delete this;
138 } 133 }
139 } 134 }
140 135
141 gfx::Insets BrowserActionButton::GetInsets() const { 136 void BrowserActionButton::ButtonPressed(views::Button* sender,
142 static gfx::Insets zero_inset; 137 const views::Event& event) {
143 return zero_inset; 138 panel_->OnBrowserActionExecuted(this, false);
Finnur 2010/07/27 09:02:23 nit: Doesn't the style guide say you should docume
Peter Kasting 2010/07/27 18:24:43 The precise style guide text is: "When you pass i
Finnur 2010/07/27 20:13:17 OK
144 } 139 }
145 140
146 void BrowserActionButton::ButtonPressed(views::Button* sender, 141 void BrowserActionButton::OnImageLoaded(SkBitmap* image,
147 const views::Event& event) { 142 ExtensionResource resource,
148 panel_->OnBrowserActionExecuted(this, false); // inspect_with_devtools 143 int index) {
149 }
150
151 void BrowserActionButton::OnImageLoaded(
152 SkBitmap* image, ExtensionResource resource, int index) {
153 if (image) 144 if (image)
154 default_icon_ = *image; 145 default_icon_ = *image;
155 146
156 // Call back to UpdateState() because a more specific icon might have been set 147 // Call back to UpdateState() because a more specific icon might have been set
157 // while the load was outstanding. 148 // while the load was outstanding.
158 UpdateState(); 149 UpdateState();
159 } 150 }
160 151
161 void BrowserActionButton::UpdateState() { 152 void BrowserActionButton::UpdateState() {
162 int tab_id = panel_->GetCurrentTabId(); 153 int tab_id = panel_->GetCurrentTabId();
(...skipping 11 matching lines...) Expand all
174 if (name.empty()) 165 if (name.empty())
175 name = UTF8ToWide(extension()->name()); 166 name = UTF8ToWide(extension()->name());
176 SetTooltipText(name); 167 SetTooltipText(name);
177 SetAccessibleName(name); 168 SetAccessibleName(name);
178 GetParent()->SchedulePaint(); 169 GetParent()->SchedulePaint();
179 } 170 }
180 171
181 void BrowserActionButton::Observe(NotificationType type, 172 void BrowserActionButton::Observe(NotificationType type,
182 const NotificationSource& source, 173 const NotificationSource& source,
183 const NotificationDetails& details) { 174 const NotificationDetails& details) {
184 if (type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED) { 175 DCHECK(type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED);
185 UpdateState(); 176 UpdateState();
186 // The browser action may have become visible/hidden so we need to make 177 // The browser action may have become visible/hidden so we need to make
187 // sure the state gets updated. 178 // sure the state gets updated.
188 panel_->OnBrowserActionVisibilityChanged(); 179 panel_->OnBrowserActionVisibilityChanged();
189 } else {
190 NOTREACHED() << L"Received unexpected notification";
191 }
192 } 180 }
193 181
194 bool BrowserActionButton::IsPopup() { 182 bool BrowserActionButton::IsPopup() {
195 int tab_id = panel_->GetCurrentTabId(); 183 int tab_id = panel_->GetCurrentTabId();
196 if (tab_id < 0) { 184 DCHECK_GE(tab_id, 0);
197 NOTREACHED() << "Button is not on a specific tab.";
198 return false;
199 }
200 return browser_action_->HasPopup(tab_id); 185 return browser_action_->HasPopup(tab_id);
201 } 186 }
202 187
203 GURL BrowserActionButton::GetPopupUrl() { 188 GURL BrowserActionButton::GetPopupUrl() {
204 int tab_id = panel_->GetCurrentTabId(); 189 int tab_id = panel_->GetCurrentTabId();
205 if (tab_id < 0) { 190 DCHECK_GE(tab_id, 0);
206 NOTREACHED() << "Button is not on a specific tab.";
207 GURL empty_url;
208 return empty_url;
209 }
210 return browser_action_->GetPopupUrl(tab_id); 191 return browser_action_->GetPopupUrl(tab_id);
211 } 192 }
212 193
213 bool BrowserActionButton::Activate() { 194 bool BrowserActionButton::Activate() {
214 if (IsPopup()) { 195 if (!IsPopup())
215 panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|. 196 return true;
216 197
217 // TODO(erikkay): Run a nested modal loop while the mouse is down to 198 panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|.
218 // enable menu-like drag-select behavior.
219 199
220 // The return value of this method is returned via OnMousePressed. 200 // TODO(erikkay): Run a nested modal loop while the mouse is down to
221 // We need to return false here since we're handing off focus to another 201 // enable menu-like drag-select behavior.
222 // widget/view, and true will grab it right back and try to send events 202
223 // to us. 203 // The return value of this method is returned via OnMousePressed.
224 return false; 204 // We need to return false here since we're handing off focus to another
225 } 205 // widget/view, and true will grab it right back and try to send events
226 return true; 206 // to us.
207 return false;
227 } 208 }
228 209
229 bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) { 210 bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) {
230 if (e.IsRightMouseButton()) { 211 if (!e.IsRightMouseButton()) {
231 // Get the top left point of this button in screen coordinates. 212 return IsPopup() ?
232 gfx::Point point = gfx::Point(0, 0); 213 MenuButton::OnMousePressed(e) : TextButton::OnMousePressed(e);
233 ConvertPointToScreen(this, &point); 214 }
234 215
235 // Make the menu appear below the button. 216 // Get the top left point of this button in screen coordinates.
236 point.Offset(0, height()); 217 gfx::Point point = gfx::Point(0, 0);
218 ConvertPointToScreen(this, &point);
237 219
238 ShowContextMenu(point, true); 220 // Make the menu appear below the button.
239 return false; 221 point.Offset(0, height());
240 } else if (IsPopup()) { 222
241 return MenuButton::OnMousePressed(e); 223 ShowContextMenu(point, true);
242 } 224 return false;
243 return TextButton::OnMousePressed(e);
244 } 225 }
245 226
246 void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e, 227 void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e,
247 bool canceled) { 228 bool canceled) {
248 if (IsPopup() || showing_context_menu_) { 229 if (IsPopup() || showing_context_menu_) {
249 // TODO(erikkay) this never actually gets called (probably because of the 230 // TODO(erikkay) this never actually gets called (probably because of the
250 // loss of focus). 231 // loss of focus).
251 MenuButton::OnMouseReleased(e, canceled); 232 MenuButton::OnMouseReleased(e, canceled);
252 } else { 233 } else {
253 TextButton::OnMouseReleased(e, canceled); 234 TextButton::OnMouseReleased(e, canceled);
254 } 235 }
255 } 236 }
256 237
257 bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) { 238 bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) {
258 if (IsPopup()) 239 return IsPopup() ?
259 return MenuButton::OnKeyReleased(e); 240 MenuButton::OnKeyReleased(e) : TextButton::OnKeyReleased(e);
260 return TextButton::OnKeyReleased(e);
261 } 241 }
262 242
263 void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) { 243 void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) {
264 if (IsPopup() || showing_context_menu_) 244 if (IsPopup() || showing_context_menu_)
265 MenuButton::OnMouseExited(e); 245 MenuButton::OnMouseExited(e);
266 else 246 else
267 TextButton::OnMouseExited(e); 247 TextButton::OnMouseExited(e);
268 } 248 }
269 249
270 void BrowserActionButton::ShowContextMenu(const gfx::Point& p, 250 void BrowserActionButton::ShowContextMenu(const gfx::Point& p,
271 bool is_mouse_gesture) { 251 bool is_mouse_gesture) {
272 showing_context_menu_ = true; 252 showing_context_menu_ = true;
273 SetButtonPushed(); 253 SetButtonPushed();
274 254
275 // Reconstructs the menu every time because the menu's contents are dynamic. 255 // Reconstructs the menu every time because the menu's contents are dynamic.
276 context_menu_contents_ = new ExtensionContextMenuModel( 256 context_menu_contents_ =
277 extension(), panel_->browser(), panel_); 257 new ExtensionContextMenuModel(extension(), panel_->browser(), panel_);
278 context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get())); 258 context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
279 context_menu_menu_->RunContextMenuAt(p); 259 context_menu_menu_->RunContextMenuAt(p);
280 260
281 SetButtonNotPushed(); 261 SetButtonNotPushed();
282 showing_context_menu_ = false; 262 showing_context_menu_ = false;
283 } 263 }
284 264
285 void BrowserActionButton::SetButtonPushed() { 265 void BrowserActionButton::SetButtonPushed() {
286 SetState(views::CustomButton::BS_PUSHED); 266 SetState(views::CustomButton::BS_PUSHED);
287 menu_visible_ = true; 267 menu_visible_ = true;
(...skipping 27 matching lines...) Expand all
315 button_->Destroy(); 295 button_->Destroy();
316 } 296 }
317 297
318 gfx::Canvas* BrowserActionView::GetIconWithBadge() { 298 gfx::Canvas* BrowserActionView::GetIconWithBadge() {
319 int tab_id = panel_->GetCurrentTabId(); 299 int tab_id = panel_->GetCurrentTabId();
320 300
321 SkBitmap icon = button_->extension()->browser_action()->GetIcon(tab_id); 301 SkBitmap icon = button_->extension()->browser_action()->GetIcon(tab_id);
322 if (icon.isNull()) 302 if (icon.isNull())
323 icon = button_->default_icon(); 303 icon = button_->default_icon();
324 304
325 gfx::Canvas* canvas = 305 gfx::Canvas* canvas = new gfx::CanvasSkia(icon.width(), icon.height(), false);
326 new gfx::CanvasSkia(icon.width(), icon.height(), false);
327 canvas->DrawBitmapInt(icon, 0, 0); 306 canvas->DrawBitmapInt(icon, 0, 0);
328 307
329 if (tab_id >= 0) { 308 if (tab_id >= 0) {
330 gfx::Rect bounds = 309 gfx::Rect bounds(icon.width(), icon.height() + kControlVertOffset);
331 gfx::Rect(icon.width(), icon.height() + kControlVertOffset); 310 button_->extension()->browser_action()->PaintBadge(canvas, bounds, tab_id);
332 button_->extension()->browser_action()->PaintBadge(canvas,
333 bounds, tab_id);
334 } 311 }
335 312
336 return canvas; 313 return canvas;
337 } 314 }
338 315
339 bool BrowserActionView::GetAccessibleRole(AccessibilityTypes::Role* role) { 316 bool BrowserActionView::GetAccessibleRole(AccessibilityTypes::Role* role) {
340 DCHECK(role); 317 DCHECK(role);
341 *role = AccessibilityTypes::ROLE_GROUPING; 318 *role = AccessibilityTypes::ROLE_GROUPING;
342 return true; 319 return true;
343 } 320 }
344 321
345 void BrowserActionView::Layout() { 322 void BrowserActionView::Layout() {
346 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize); 323 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize);
347 } 324 }
348 325
349 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) { 326 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) {
350 View::PaintChildren(canvas); 327 View::PaintChildren(canvas);
351 ExtensionAction* action = button()->browser_action(); 328 ExtensionAction* action = button()->browser_action();
352 int tab_id = panel_->GetCurrentTabId(); 329 int tab_id = panel_->GetCurrentTabId();
353 if (tab_id < 0) 330 if (tab_id >= 0)
354 return; 331 action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id);
355
356 action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id);
357 } 332 }
358 333
359 //////////////////////////////////////////////////////////////////////////////// 334 ////////////////////////////////////////////////////////////////////////////////
360 // BrowserActionsContainer 335 // BrowserActionsContainer
361 336
362 BrowserActionsContainer::BrowserActionsContainer( 337 BrowserActionsContainer::BrowserActionsContainer(Browser* browser,
363 Browser* browser, View* owner_view) 338 View* owner_view)
364 : profile_(browser->profile()), 339 : profile_(browser->profile()),
365 browser_(browser), 340 browser_(browser),
366 owner_view_(owner_view), 341 owner_view_(owner_view),
367 popup_(NULL), 342 popup_(NULL),
368 popup_button_(NULL), 343 popup_button_(NULL),
369 model_(NULL), 344 model_(NULL),
370 chevron_(NULL), 345 chevron_(NULL),
371 overflow_menu_(NULL), 346 overflow_menu_(NULL),
372 suppress_chevron_(false), 347 suppress_chevron_(false),
373 resize_amount_(0), 348 resize_amount_(0),
374 animation_target_size_(0), 349 animation_target_size_(0),
375 drop_indicator_position_(-1), 350 drop_indicator_position_(-1),
376 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 351 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
377 ALLOW_THIS_IN_INITIALIZER_LIST(show_menu_task_factory_(this)) { 352 ALLOW_THIS_IN_INITIALIZER_LIST(show_menu_task_factory_(this)) {
378 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR); 353 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
379 354
380 if (profile_->GetExtensionsService()) { 355 if (profile_->GetExtensionsService()) {
381 model_ = profile_->GetExtensionsService()->toolbar_model(); 356 model_ = profile_->GetExtensionsService()->toolbar_model();
382 model_->AddObserver(this); 357 model_->AddObserver(this);
383 } 358 }
359
384 resize_animation_.reset(new SlideAnimation(this)); 360 resize_animation_.reset(new SlideAnimation(this));
385 resize_area_ = new views::ResizeArea(this); 361 resize_area_ = new views::ResizeArea(this);
386 resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR)); 362 resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR));
387 AddChildView(resize_area_); 363 AddChildView(resize_area_);
388 364
389 // TODO(glen): Come up with a new bitmap for the chevron. 365 // TODO(glen): Come up with a new bitmap for the chevron.
390 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 366 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
391 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS); 367 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS);
392 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false); 368 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false);
393 chevron_->SetVisible(false); 369 chevron_->SetVisible(false);
394 chevron_->SetIcon(*chevron_image); 370 chevron_->SetIcon(*chevron_image);
395 chevron_->SetAccessibleName( 371 chevron_->SetAccessibleName(
396 l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_CHEVRON)); 372 l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_CHEVRON));
397 // Chevron contains >> that should point left in LTR locales. 373 // Chevron contains >> that should point left in LTR locales.
398 chevron_->EnableCanvasFlippingForRTLUI(true); 374 chevron_->EnableCanvasFlippingForRTLUI(true);
399 AddChildView(chevron_); 375 AddChildView(chevron_);
400 376
401 if (!profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) { 377 if (model_ &&
378 !profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) {
402 // Migration code to the new VisibleIconCount pref. 379 // Migration code to the new VisibleIconCount pref.
403 // TODO(mpcomplete): remove this after users are upgraded to 5.0. 380 // TODO(mpcomplete): remove this after users are upgraded to 5.0.
404 int predefined_width = 381 int predefined_width =
405 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); 382 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth);
406 if (predefined_width != 0) { 383 if (predefined_width != 0) {
407 int icon_width = (kButtonSize + kBrowserActionButtonPadding); 384 model_->SetVisibleIconCount((predefined_width - WidthOfNonIconArea()) /
408 if (model_) { 385 (kButtonSize + kBrowserActionButtonPadding));
409 model_->SetVisibleIconCount(
410 (predefined_width - WidthOfNonIconArea()) / icon_width);
411 }
412 } 386 }
413 } 387 }
414
415 if (model_ && model_->extensions_initialized()) 388 if (model_ && model_->extensions_initialized())
416 SetContainerWidth(); 389 SetContainerWidth();
417 390
418 SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS)); 391 SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS));
419 } 392 }
420 393
421 BrowserActionsContainer::~BrowserActionsContainer() { 394 BrowserActionsContainer::~BrowserActionsContainer() {
422 if (model_) 395 if (model_)
423 model_->RemoveObserver(this); 396 model_->RemoveObserver(this);
424 StopShowFolderDropMenuTimer(); 397 StopShowFolderDropMenuTimer();
425 HidePopup(); 398 HidePopup();
426 DeleteBrowserActionViews(); 399 DeleteBrowserActionViews();
427 } 400 }
428 401
429 // Static. 402 // Static.
430 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) { 403 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) {
431 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0); 404 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0);
432 } 405 }
433 406
434 int BrowserActionsContainer::GetCurrentTabId() const { 407 int BrowserActionsContainer::GetCurrentTabId() const {
435 TabContents* tab_contents = browser_->GetSelectedTabContents(); 408 TabContents* tab_contents = browser_->GetSelectedTabContents();
436 if (!tab_contents) 409 return tab_contents ? tab_contents->controller().session_id().id() : -1;
437 return -1;
438
439 return tab_contents->controller().session_id().id();
440 } 410 }
441 411
442 BrowserActionView* BrowserActionsContainer::GetBrowserActionView( 412 BrowserActionView* BrowserActionsContainer::GetBrowserActionView(
443 ExtensionAction* action) { 413 ExtensionAction* action) {
444 for (BrowserActionViews::iterator iter = 414 for (BrowserActionViews::iterator iter = browser_action_views_.begin();
445 browser_action_views_.begin(); iter != browser_action_views_.end(); 415 iter != browser_action_views_.end(); ++iter) {
446 ++iter) {
447 if ((*iter)->button()->browser_action() == action) 416 if ((*iter)->button()->browser_action() == action)
448 return *iter; 417 return *iter;
449 } 418 }
450
451 return NULL; 419 return NULL;
452 } 420 }
453 421
454 void BrowserActionsContainer::RefreshBrowserActionViews() { 422 void BrowserActionsContainer::RefreshBrowserActionViews() {
455 for (size_t i = 0; i < browser_action_views_.size(); ++i) 423 for (size_t i = 0; i < browser_action_views_.size(); ++i)
456 browser_action_views_[i]->button()->UpdateState(); 424 browser_action_views_[i]->button()->UpdateState();
457 } 425 }
458 426
459 void BrowserActionsContainer::CloseOverflowMenu() {
460 if (overflow_menu_)
461 overflow_menu_->CancelMenu();
462 }
463
464 void BrowserActionsContainer::StopShowFolderDropMenuTimer() {
465 show_menu_task_factory_.RevokeAll();
466 }
467
468 void BrowserActionsContainer::StartShowFolderDropMenuTimer() {
469 int delay = View::GetMenuShowDelay();
470 MessageLoop::current()->PostDelayedTask(FROM_HERE,
471 show_menu_task_factory_.NewRunnableMethod(
472 &BrowserActionsContainer::ShowDropFolder),
473 delay);
474 }
475
476 void BrowserActionsContainer::ShowDropFolder() {
477 DCHECK(!overflow_menu_);
478 SetDropIndicator(-1);
479 overflow_menu_ = new BrowserActionOverflowMenuController(
480 this, chevron_, browser_action_views_, VisibleBrowserActions());
481 overflow_menu_->set_observer(this);
482 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true);
483 }
484
485 void BrowserActionsContainer::SetDropIndicator(int x_pos) {
486 if (drop_indicator_position_ != x_pos) {
487 drop_indicator_position_ = x_pos;
488 SchedulePaint();
489 }
490 }
491
492 void BrowserActionsContainer::CreateBrowserActionViews() { 427 void BrowserActionsContainer::CreateBrowserActionViews() {
493 DCHECK(browser_action_views_.empty()); 428 DCHECK(browser_action_views_.empty());
494 if (!model_) 429 if (!model_)
495 return; 430 return;
496 431
497 for (ExtensionList::iterator iter = model_->begin(); 432 for (ExtensionList::iterator iter = model_->begin(); iter != model_->end();
498 iter != model_->end(); ++iter) { 433 ++iter) {
499 if (!ShouldDisplayBrowserAction(*iter)) 434 if (!ShouldDisplayBrowserAction(*iter))
500 continue; 435 continue;
501 436
502 BrowserActionView* view = new BrowserActionView(*iter, this); 437 BrowserActionView* view = new BrowserActionView(*iter, this);
503 browser_action_views_.push_back(view); 438 browser_action_views_.push_back(view);
504 AddChildView(view); 439 AddChildView(view);
505 } 440 }
506 } 441 }
507 442
508 void BrowserActionsContainer::DeleteBrowserActionViews() { 443 void BrowserActionsContainer::DeleteBrowserActionViews() {
509 if (!browser_action_views_.empty()) { 444 if (!browser_action_views_.empty()) {
510 for (size_t i = 0; i < browser_action_views_.size(); ++i) 445 for (size_t i = 0; i < browser_action_views_.size(); ++i)
511 RemoveChildView(browser_action_views_[i]); 446 RemoveChildView(browser_action_views_[i]);
512 STLDeleteContainerPointers(browser_action_views_.begin(), 447 STLDeleteContainerPointers(browser_action_views_.begin(),
513 browser_action_views_.end()); 448 browser_action_views_.end());
514 browser_action_views_.clear(); 449 browser_action_views_.clear();
515 } 450 }
516 } 451 }
517 452
518 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { 453 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() {
519 SetVisible(browser_action_views_.size() > 0); 454 SetVisible(!browser_action_views_.empty());
520 owner_view_->Layout(); 455 owner_view_->Layout();
521 owner_view_->SchedulePaint(); 456 owner_view_->SchedulePaint();
522 } 457 }
523 458
524 void BrowserActionsContainer::HidePopup() { 459 size_t BrowserActionsContainer::VisibleBrowserActions() const {
525 if (popup_) 460 size_t visible_actions = 0;
526 popup_->Close(); 461 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
527 } 462 if (browser_action_views_[i]->IsVisible())
528 463 ++visible_actions;
529 void BrowserActionsContainer::TestExecuteBrowserAction(int index) { 464 }
530 BrowserActionButton* button = browser_action_views_[index]->button(); 465 return visible_actions;
531 OnBrowserActionExecuted(button, false); // |inspect_with_devtools|.
532 }
533
534 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
535 chevron_->SetVisible(icons < browser_action_views_.size());
536 container_size_.set_width(IconCountToWidth(icons));
537 Layout();
538 SchedulePaint();
539 } 466 }
540 467
541 void BrowserActionsContainer::OnBrowserActionExecuted( 468 void BrowserActionsContainer::OnBrowserActionExecuted(
542 BrowserActionButton* button, bool inspect_with_devtools) { 469 BrowserActionButton* button,
470 bool inspect_with_devtools) {
543 ExtensionAction* browser_action = button->browser_action(); 471 ExtensionAction* browser_action = button->browser_action();
544 472
545 // Popups just display. No notification to the extension. 473 // Popups just display. No notification to the extension.
546 // TODO(erikkay): should there be? 474 // TODO(erikkay): should there be?
547 if (button->IsPopup()) { 475 if (!button->IsPopup()) {
548 // If we're showing the same popup, just hide it and return. 476 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
549 bool same_showing = popup_ && button == popup_button_; 477 profile_, browser_action->extension_id(), browser_);
550
551 // Always hide the current popup, even if it's not the same.
552 // Only one popup should be visible at a time.
553 HidePopup();
554
555 if (same_showing)
556 return;
557
558 // We can get the execute event for browser actions that are not visible,
559 // since buttons can be activated from the overflow menu (chevron). In that
560 // case we show the popup as originating from the chevron.
561 View* reference_view = button->GetParent()->IsVisible() ? button : chevron_;
562 gfx::Point origin;
563 View::ConvertPointToScreen(reference_view, &origin);
564 gfx::Rect rect = reference_view->bounds();
565 rect.set_x(origin.x());
566 rect.set_y(origin.y());
567
568 gfx::NativeWindow frame_window =
569 browser_->window()->GetNativeHandle();
570 BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ?
571 BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
572
573 popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_,
574 browser_->profile(), frame_window, rect, arrow_location,
575 true, // Activate the popup window.
576 inspect_with_devtools,
577 ExtensionPopup::BUBBLE_CHROME,
578 this); // ExtensionPopupDelegate
Finnur 2010/07/27 09:02:23 nit: same question here (comment).
579 popup_button_ = button;
580 popup_button_->SetButtonPushed();
581
582 return; 478 return;
583 } 479 }
584 480
585 // Otherwise, we send the action to the extension. 481 // If we're showing the same popup, just hide it and return.
586 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( 482 bool same_showing = popup_ && button == popup_button_;
587 profile_, browser_action->extension_id(), browser_); 483
484 // Always hide the current popup, even if it's not the same.
485 // Only one popup should be visible at a time.
486 HidePopup();
487
488 if (same_showing)
489 return;
490
491 // We can get the execute event for browser actions that are not visible,
492 // since buttons can be activated from the overflow menu (chevron). In that
493 // case we show the popup as originating from the chevron.
494 View* reference_view = button->GetParent()->IsVisible() ? button : chevron_;
495 gfx::Point origin;
496 View::ConvertPointToScreen(reference_view, &origin);
497 gfx::Rect rect = reference_view->bounds();
498 rect.set_origin(origin);
499
500 gfx::NativeWindow frame_window = browser_->window()->GetNativeHandle();
501 BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ?
502 BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
503
504 popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_,
505 browser_->profile(), frame_window, rect, arrow_location, true,
506 inspect_with_devtools, ExtensionPopup::BUBBLE_CHROME, this);
Finnur 2010/07/27 09:02:23 nit: same question here (comments deleted).
507 popup_button_ = button;
508 popup_button_->SetButtonPushed();
588 } 509 }
589 510
590 gfx::Size BrowserActionsContainer::GetPreferredSize() { 511 gfx::Size BrowserActionsContainer::GetPreferredSize() {
591 if (browser_action_views_.empty()) 512 if (browser_action_views_.empty())
592 return gfx::Size(0, 0); 513 return gfx::Size(0, 0);
593 514
594 // We calculate the size of the view by taking the current width and 515 // We calculate the size of the view by taking the current width and
595 // subtracting resize_amount_ (the latter represents how far the user is 516 // subtracting resize_amount_ (the latter represents how far the user is
596 // resizing the view or, if animating the snapping, how far to animate it). 517 // resizing the view or, if animating the snapping, how far to animate it).
597 // But we also clamp it to a minimum size and the maximum size, so that the 518 // But we also clamp it to a minimum size and the maximum size, so that the
598 // container can never shrink too far or take up more space than it needs. In 519 // container can never shrink too far or take up more space than it needs. In
599 // other words: ContainerMinSize() < width() - resize < ClampTo(MAX). 520 // other words: ContainerMinSize() < width() - resize < ClampTo(MAX).
600 int width = std::max(ContainerMinSize(), 521 return gfx::Size(std::min(std::max(ContainerMinSize(),
601 container_size_.width() - resize_amount_); 522 container_width_ - resize_amount_), ClampToNearestIconCount(-1, false)),
602 int max_width = ClampToNearestIconCount(-1, false); // -1 gives max width. 523 kButtonSize);
Finnur 2010/07/27 09:02:23 I'm not a huge fan of this consolidation. The way
Peter Kasting 2010/07/27 18:24:43 I partly did this because the final form (after th
Finnur 2010/07/27 20:13:17 I think the last version (clamped_width) is a dece
603 width = std::min(width, max_width);
604
605 return gfx::Size(width, kButtonSize);
606 } 524 }
607 525
608 void BrowserActionsContainer::Layout() { 526 void BrowserActionsContainer::Layout() {
609 if (browser_action_views_.size() == 0) { 527 if (browser_action_views_.empty()) {
610 SetVisible(false); 528 SetVisible(false);
611 chevron_->SetVisible(false); 529 chevron_->SetVisible(false);
612 return; 530 return;
613 } else {
614 SetVisible(true);
615 } 531 }
616 532
533 SetVisible(true);
534
617 resize_area_->SetBounds(0, 0, kResizeAreaWidth, height()); 535 resize_area_->SetBounds(0, 0, kResizeAreaWidth, height());
618 int x = kResizeAreaWidth; 536 int x = kResizeAreaWidth;
619 537
620 x += base::i18n::IsRTL() ? kHorizontalPaddingRtl : kHorizontalPadding; 538 x += base::i18n::IsRTL() ? kHorizontalPaddingRtl : kHorizontalPadding;
621 539
622 // Calculate if all icons fit without showing the chevron. We need to know 540 // Calculate if all icons fit without showing the chevron. We need to know
623 // this beforehand, because showing the chevron will decrease the space that 541 // this beforehand, because showing the chevron will decrease the space that
624 // we have to draw the visible ones (ie. if one icon is visible and another 542 // we have to draw the visible ones (ie. if one icon is visible and another
625 // doesn't have enough room). 543 // doesn't have enough room).
626 int last_x_of_icons = x + 544 int last_x_of_icons = x +
627 (browser_action_views_.size() * kButtonSize) + 545 (browser_action_views_.size() * kButtonSize) +
628 ((browser_action_views_.size() - 1) * 546 ((browser_action_views_.size() - 1) *
629 kBrowserActionButtonPadding); 547 kBrowserActionButtonPadding);
630 548
631 gfx::Size sz = GetPreferredSize(); 549 gfx::Size sz = GetPreferredSize();
632 int max_x = sz.width() - kDividerHorizontalMargin - kChevronRightMargin; 550 int max_x = sz.width() - kDividerHorizontalMargin - kChevronRightMargin;
633 551
634 // If they don't all fit, show the chevron (unless suppressed). 552 // If they don't all fit, show the chevron (unless suppressed).
635 gfx::Size chevron_size;
636 if (last_x_of_icons >= max_x && !suppress_chevron_) { 553 if (last_x_of_icons >= max_x && !suppress_chevron_) {
637 chevron_->SetVisible(true); 554 chevron_->SetVisible(true);
638 chevron_size = chevron_->GetPreferredSize(); 555 gfx::Size chevron_size(chevron_->GetPreferredSize());
639 max_x -= chevron_size.width(); 556 max_x -= chevron_size.width();
640 chevron_->SetBounds(width() - chevron_size.width() - kChevronRightMargin, 557 chevron_->SetBounds(width() - chevron_size.width() - kChevronRightMargin,
641 kChevronTopMargin, 558 kChevronTopMargin,
642 chevron_size.width(), chevron_size.height()); 559 chevron_size.width(), chevron_size.height());
643 } else { 560 } else {
644 chevron_->SetVisible(false); 561 chevron_->SetVisible(false);
645 } 562 }
646 563
647 // Now draw the icons for the browser actions in the available space. 564 // Now draw the icons for the browser actions in the available space.
648 for (size_t i = 0; i < browser_action_views_.size(); ++i) { 565 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
(...skipping 14 matching lines...) Expand all
663 void BrowserActionsContainer::Paint(gfx::Canvas* canvas) { 580 void BrowserActionsContainer::Paint(gfx::Canvas* canvas) {
664 // The one-pixel themed vertical divider to the right of the browser actions. 581 // The one-pixel themed vertical divider to the right of the browser actions.
665 int x = base::i18n::IsRTL() ? 582 int x = base::i18n::IsRTL() ?
666 kDividerHorizontalMargin : (width() - kDividerHorizontalMargin); 583 kDividerHorizontalMargin : (width() - kDividerHorizontalMargin);
667 DetachableToolbarView::PaintVerticalDivider( 584 DetachableToolbarView::PaintVerticalDivider(
668 canvas, x, height(), kDividerVerticalPadding, 585 canvas, x, height(), kDividerVerticalPadding,
669 DetachableToolbarView::kEdgeDividerColor, 586 DetachableToolbarView::kEdgeDividerColor,
670 DetachableToolbarView::kMiddleDividerColor, 587 DetachableToolbarView::kMiddleDividerColor,
671 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); 588 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
672 589
673 // The two-pixel width drop indicator. 590 // TODO(sky/glen): Instead of using a drop indicator, animate the icons while
591 // dragging (like we do for tab dragging).
674 if (drop_indicator_position_ > -1) { 592 if (drop_indicator_position_ > -1) {
675 x = drop_indicator_position_; 593 // The two-pixel width drop indicator.
676 int y = kDividerVerticalPadding; 594 static const int kDropIndicatorWidth = 2;
Finnur 2010/07/27 09:02:23 Is this here because the other one was moved? Just
Peter Kasting 2010/07/27 18:24:43 Since it's only used here it seemed clearer to jus
677 gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2, 595 gfx::Rect indicator_bounds(
678 y, 596 drop_indicator_position_ - (kDropIndicatorWidth / 2),
679 kDropIndicatorWidth, 597 kDividerVerticalPadding, kDropIndicatorWidth,
680 height() - (2 * kDividerVerticalPadding)); 598 height() - (2 * kDividerVerticalPadding));
681 599
682 // TODO(sky/glen): make me pretty! 600 // Color of the drop indicator.
601 static const SkColor kDropIndicatorColor = SK_ColorBLACK;
683 canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(), 602 canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(),
684 indicator_bounds.y(), indicator_bounds.width(), 603 indicator_bounds.y(), indicator_bounds.width(),
685 indicator_bounds.height()); 604 indicator_bounds.height());
686 } 605 }
687 } 606 }
688 607
689 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add, 608 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add,
690 views::View* parent, 609 views::View* parent,
691 views::View* child) { 610 views::View* child) {
692 // No extensions (e.g., incognito). 611 // No extensions (e.g., incognito).
693 if (!model_) 612 if (!model_)
694 return; 613 return;
695 614
696 if (is_add && child == this) { 615 if (is_add && child == this) {
697 // Initial toolbar button creation and placement in the widget hierarchy. 616 // Initial toolbar button creation and placement in the widget hierarchy.
698 // We do this here instead of in the constructor because AddBrowserAction 617 // We do this here instead of in the constructor because AddBrowserAction
699 // calls Layout on the Toolbar, which needs this object to be constructed 618 // calls Layout on the Toolbar, which needs this object to be constructed
700 // before its Layout function is called. 619 // before its Layout function is called.
701 CreateBrowserActionViews(); 620 CreateBrowserActionViews();
702 } 621 }
703 } 622 }
704 623
705 bool BrowserActionsContainer::GetDropFormats( 624 bool BrowserActionsContainer::GetDropFormats(
706 int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats) { 625 int* formats,
626 std::set<OSExchangeData::CustomFormat>* custom_formats) {
707 custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat()); 627 custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat());
708 628
709 return true; 629 return true;
710 } 630 }
711 631
712 bool BrowserActionsContainer::AreDropTypesRequired() { 632 bool BrowserActionsContainer::AreDropTypesRequired() {
713 return true; 633 return true;
714 } 634 }
715 635
716 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { 636 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
717 BrowserActionDragData drop_data; 637 BrowserActionDragData drop_data;
718 if (!drop_data.Read(data)) 638 return drop_data.Read(data) ? drop_data.IsFromProfile(profile_) : false;
719 return false;
720 return drop_data.IsFromProfile(profile_);
721 } 639 }
722 640
723 void BrowserActionsContainer::OnDragEntered( 641 void BrowserActionsContainer::OnDragEntered(
724 const views::DropTargetEvent& event) { 642 const views::DropTargetEvent& event) {
725 } 643 }
726 644
727 int BrowserActionsContainer::OnDragUpdated( 645 int BrowserActionsContainer::OnDragUpdated(
728 const views::DropTargetEvent& event) { 646 const views::DropTargetEvent& event) {
729 // First check if we are above the chevron (overflow) menu. 647 // First check if we are above the chevron (overflow) menu.
730 if (GetViewForPoint(event.location()) == chevron_) { 648 if (GetViewForPoint(event.location()) == chevron_) {
731 if (show_menu_task_factory_.empty() && !overflow_menu_) 649 if (show_menu_task_factory_.empty() && !overflow_menu_)
732 StartShowFolderDropMenuTimer(); 650 StartShowFolderDropMenuTimer();
733 return DragDropTypes::DRAG_MOVE; 651 return DragDropTypes::DRAG_MOVE;
734 } else {
735 StopShowFolderDropMenuTimer();
736 } 652 }
653 StopShowFolderDropMenuTimer();
737 654
738 // Modifying the x value before clamping affects how far you have to drag to 655 // Modifying the x value before clamping affects how far you have to drag to
739 // get the drop indicator to shift to another position. Modifying after 656 // get the drop indicator to shift to another position. Modifying after
740 // clamping affects where the drop indicator is drawn. 657 // clamping affects where the drop indicator is drawn.
741 658
742 // We add half a button size so that when you drag a button to the right and 659 // We add half a button size so that when you drag a button to the right and
743 // you are half-way dragging across a button the drop indicator moves from the 660 // you are half-way dragging across a button the drop indicator moves from the
744 // left of that button to the right of that button. 661 // left of that button to the right of that button.
745 int x = event.x() + (kButtonSize / 2) + (2 * kBrowserActionButtonPadding); 662 int x = event.x() + (kButtonSize / 2) + (2 * kBrowserActionButtonPadding);
746 if (chevron_->IsVisible()) 663 if (chevron_->IsVisible())
(...skipping 21 matching lines...) Expand all
768 SchedulePaint(); 685 SchedulePaint();
769 } 686 }
770 687
771 int BrowserActionsContainer::OnPerformDrop( 688 int BrowserActionsContainer::OnPerformDrop(
772 const views::DropTargetEvent& event) { 689 const views::DropTargetEvent& event) {
773 BrowserActionDragData data; 690 BrowserActionDragData data;
774 if (!data.Read(event.GetData())) 691 if (!data.Read(event.GetData()))
775 return DragDropTypes::DRAG_NONE; 692 return DragDropTypes::DRAG_NONE;
776 693
777 // Make sure we have the same view as we started with. 694 // Make sure we have the same view as we started with.
778 DCHECK(browser_action_views_[data.index()]->button()->extension()->id() == 695 DCHECK_EQ(browser_action_views_[data.index()]->button()->extension()->id(),
779 data.id()); 696 data.id());
780 DCHECK(model_); 697 DCHECK(model_);
781 698
782 Extension* dragging =
783 browser_action_views_[data.index()]->button()->extension();
784
785 int target_x = drop_indicator_position_;
786
787 size_t i = 0; 699 size_t i = 0;
788 for (; i < browser_action_views_.size(); ++i) { 700 for (; i < browser_action_views_.size(); ++i) {
789 int view_x = 701 int view_x =
790 browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x(); 702 browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x();
791 if (!browser_action_views_[i]->IsVisible() || 703 if (!browser_action_views_[i]->IsVisible() ||
792 (base::i18n::IsRTL() ? view_x < target_x : view_x >= target_x)) { 704 (base::i18n::IsRTL() ? (view_x < drop_indicator_position_) :
705 (view_x >= drop_indicator_position_))) {
793 // We have reached the end of the visible icons or found one that has a 706 // We have reached the end of the visible icons or found one that has a
794 // higher x position than the drop point. 707 // higher x position than the drop point.
795 break; 708 break;
796 } 709 }
797 } 710 }
798 711
799 // |i| now points to the item to the right of the drop indicator*, which is 712 // |i| now points to the item to the right of the drop indicator*, which is
800 // correct when dragging an icon to the left. When dragging to the right, 713 // correct when dragging an icon to the left. When dragging to the right,
801 // however, we want the icon being dragged to get the index of the item to 714 // however, we want the icon being dragged to get the index of the item to
802 // the left of the drop indicator, so we subtract one. 715 // the left of the drop indicator, so we subtract one.
803 // * Well, it can also point to the end, but not when dragging to the left. :) 716 // * Well, it can also point to the end, but not when dragging to the left. :)
804 if (i > data.index()) 717 if (i > data.index())
805 --i; 718 --i;
806 719
807 if (profile_->IsOffTheRecord()) 720 if (profile_->IsOffTheRecord())
808 i = model_->IncognitoIndexToOriginal(i); 721 i = model_->IncognitoIndexToOriginal(i);
809 722
810 model_->MoveBrowserAction(dragging, i); 723 model_->MoveBrowserAction(
724 browser_action_views_[data.index()]->button()->extension(), i);
811 725
812 OnDragExited(); // Perform clean up after dragging. 726 OnDragExited(); // Perform clean up after dragging.
813 return DragDropTypes::DRAG_MOVE; 727 return DragDropTypes::DRAG_MOVE;
814 } 728 }
815 729
816 bool BrowserActionsContainer::GetAccessibleRole( 730 bool BrowserActionsContainer::GetAccessibleRole(
817 AccessibilityTypes::Role* role) { 731 AccessibilityTypes::Role* role) {
818 DCHECK(role); 732 DCHECK(role);
819 *role = AccessibilityTypes::ROLE_GROUPING; 733 *role = AccessibilityTypes::ROLE_GROUPING;
820 return true; 734 return true;
821 } 735 }
822 736
823 void BrowserActionsContainer::MoveBrowserAction(
824 const std::string& extension_id, size_t new_index) {
825 ExtensionsService* service = profile_->GetExtensionsService();
826 if (service) {
827 Extension* extension = service->GetExtensionById(extension_id, false);
828 model_->MoveBrowserAction(extension, new_index);
829 SchedulePaint();
830 }
831 }
832
833 void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) { 737 void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) {
834 if (source == chevron_) { 738 if (source == chevron_) {
835 overflow_menu_ = new BrowserActionOverflowMenuController( 739 overflow_menu_ = new BrowserActionOverflowMenuController(
836 this, chevron_, browser_action_views_, VisibleBrowserActions()); 740 this, chevron_, browser_action_views_, VisibleBrowserActions());
837 overflow_menu_->set_observer(this); 741 overflow_menu_->set_observer(this);
838 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), false); 742 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), false);
839 } 743 }
840 } 744 }
841 745
842 void BrowserActionsContainer::WriteDragData(View* sender, 746 void BrowserActionsContainer::WriteDragData(View* sender,
(...skipping 23 matching lines...) Expand all
866 const gfx::Point& p) { 770 const gfx::Point& p) {
867 return DragDropTypes::DRAG_MOVE; 771 return DragDropTypes::DRAG_MOVE;
868 } 772 }
869 773
870 bool BrowserActionsContainer::CanStartDrag(View* sender, 774 bool BrowserActionsContainer::CanStartDrag(View* sender,
871 const gfx::Point& press_pt, 775 const gfx::Point& press_pt,
872 const gfx::Point& p) { 776 const gfx::Point& p) {
873 return true; 777 return true;
874 } 778 }
875 779
876 int BrowserActionsContainer::ClampToNearestIconCount( 780 void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) {
877 int pixelWidth, bool allow_shrink_to_minimum) const { 781 if (!done_resizing) {
878 // Calculate the width of one icon. 782 resize_amount_ = resize_amount;
879 int icon_width = (kButtonSize + kBrowserActionButtonPadding); 783 OnBrowserActionVisibilityChanged();
784 } else {
785 // For details on why we do the following see the class comments in the
786 // header.
880 787
881 // Calculate pixel count for the area not used by the icons. 788 // Clamp lower limit to 0 and upper limit to the amount that allows enough
882 int extras = WidthOfNonIconArea(); 789 // room for all icons to show.
790 int new_width = std::max(0, container_width_ - resize_amount);
791 int max_width = ClampToNearestIconCount(-1, false);
792 new_width = std::min(new_width, max_width);
883 793
884 size_t icon_count = 0u; 794 // Up until now we've only been modifying the resize_amount, but now it is
885 if (pixelWidth >= 0) { 795 // time to set the container size to the size we have resized to, but then
886 // Caller wants to know how many icons fit within a given space so we start 796 // animate to the nearest icon count size (or down to min size if no icon).
887 // by subtracting the padding, resize area and dividers. 797 container_width_ = new_width;
888 int icon_area = pixelWidth - extras; 798 animation_target_size_ = ClampToNearestIconCount(new_width, true);
889 icon_area = std::max(0, icon_area); 799 resize_animation_->Reset();
800 resize_animation_->SetTweenType(Tween::EASE_OUT);
801 resize_animation_->Show();
802 }
803 }
890 804
891 // Make sure we never throw an icon into the chevron menu just because 805 void BrowserActionsContainer::AnimationProgressed(const Animation* animation) {
892 // there isn't enough enough space for the invisible padding around buttons. 806 DCHECK_EQ(resize_animation_.get(), animation);
893 icon_area += kBrowserActionButtonPadding - 1; 807 resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() *
808 (container_width_ - animation_target_size_));
809 OnBrowserActionVisibilityChanged();
810 }
894 811
895 // Count the number of icons that fit within that area. 812 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
896 icon_count = icon_area / icon_width; 813 container_width_ = animation_target_size_;
814 animation_target_size_ = 0;
815 resize_amount_ = 0;
816 OnBrowserActionVisibilityChanged();
817 suppress_chevron_ = false;
897 818
898 if (icon_count == 0 && allow_shrink_to_minimum) { 819 // Don't save the icon count in incognito because there may be fewer icons
899 extras = ContainerMinSize(); // Allow very narrow width if no icons. 820 // in that mode. The result is that the container in a normal window is always
900 } else if (icon_count > browser_action_views_.size()) { 821 // at least as wide as in an incognito window.
901 // No use allowing more than what we have. 822 if (!profile_->IsOffTheRecord())
902 icon_count = browser_action_views_.size(); 823 model_->SetVisibleIconCount(VisibleBrowserActions());
903 } 824 }
904 } else { 825
905 // A negative |pixels| count indicates caller wants to know the max width 826 void BrowserActionsContainer::NotifyMenuDeleted(
906 // that fits all icons; 827 BrowserActionOverflowMenuController* controller) {
907 icon_count = browser_action_views_.size(); 828 DCHECK(controller == overflow_menu_);
829 overflow_menu_ = NULL;
830 }
831
832 void BrowserActionsContainer::InspectPopup(ExtensionAction* action) {
833 OnBrowserActionExecuted(GetBrowserActionView(action)->button(), true);
834 }
835
836 void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) {
837 // ExtensionPopup is ref-counted, so we don't need to delete it.
838 DCHECK_EQ(popup_, popup);
839 popup_ = NULL;
840 popup_button_->SetButtonNotPushed();
841 popup_button_ = NULL;
842 }
843
844 void BrowserActionsContainer::MoveBrowserAction(const std::string& extension_id,
845 size_t new_index) {
846 ExtensionsService* service = profile_->GetExtensionsService();
847 if (service) {
848 Extension* extension = service->GetExtensionById(extension_id, false);
849 model_->MoveBrowserAction(extension, new_index);
850 SchedulePaint();
908 } 851 }
852 }
909 853
910 return extras + (icon_count * icon_width); 854 void BrowserActionsContainer::HidePopup() {
855 if (popup_)
856 popup_->Close();
857 }
858
859 void BrowserActionsContainer::TestExecuteBrowserAction(int index) {
860 BrowserActionButton* button = browser_action_views_[index]->button();
861 OnBrowserActionExecuted(button, false); // |inspect_with_devtools|.
862 }
863
864 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
865 chevron_->SetVisible(icons < browser_action_views_.size());
866 container_width_ = IconCountToWidth(icons);
867 Layout();
868 SchedulePaint();
911 } 869 }
912 870
913 void BrowserActionsContainer::BrowserActionAdded(Extension* extension, 871 void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
914 int index) { 872 int index) {
915 #if defined(DEBUG) 873 #if defined(DEBUG)
916 for (size_t i = 0; i < browser_action_views_.size(); ++i) { 874 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
917 DCHECK(browser_action_views_[i]->button()->extension() != extension) << 875 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
918 "Asked to add a browser action view for an extension that already " 876 "Asked to add a browser action view for an extension that already "
919 "exists."; 877 "exists.";
920 } 878 }
921 #endif 879 #endif
922 CloseOverflowMenu(); 880 CloseOverflowMenu();
923 881
924 if (!ShouldDisplayBrowserAction(extension)) 882 if (!ShouldDisplayBrowserAction(extension))
925 return; 883 return;
926 884
885 size_t visible_actions = VisibleBrowserActions();
886
887 // Add the new browser action to the vector and the view hierarchy.
927 if (profile_->IsOffTheRecord()) 888 if (profile_->IsOffTheRecord())
928 index = model_->OriginalIndexToIncognito(index); 889 index = model_->OriginalIndexToIncognito(index);
929 890
930 // Before we change anything, determine the number of visible browser actions.
931 size_t visible_actions = VisibleBrowserActions();
932
933 // Add the new browser action to the vector and the view hierarchy.
934 BrowserActionView* view = new BrowserActionView(extension, this); 891 BrowserActionView* view = new BrowserActionView(extension, this);
935 browser_action_views_.insert(browser_action_views_.begin() + index, view); 892 browser_action_views_.insert(browser_action_views_.begin() + index, view);
936 AddChildView(index, view); 893 AddChildView(index, view);
937 894
938 // If we are still initializing the container, don't bother animating. 895 // If we are still initializing the container, don't bother animating.
939 if (!model_->extensions_initialized()) 896 if (!model_->extensions_initialized())
940 return; 897 return;
941 898
942 // For details on why we do the following see the class comments in the 899 // For details on why we do the following see the class comments in the
943 // header. 900 // header.
(...skipping 14 matching lines...) Expand all
958 Animate(Tween::LINEAR, target_size); 915 Animate(Tween::LINEAR, target_size);
959 } 916 }
960 } 917 }
961 918
962 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) { 919 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) {
963 CloseOverflowMenu(); 920 CloseOverflowMenu();
964 921
965 if (popup_ && popup_->host()->extension() == extension) 922 if (popup_ && popup_->host()->extension() == extension)
966 HidePopup(); 923 HidePopup();
967 924
968 // Before we change anything, determine the number of visible browser
969 // actions.
970 size_t visible_actions = VisibleBrowserActions(); 925 size_t visible_actions = VisibleBrowserActions();
971 926 for (BrowserActionViews::iterator iter = browser_action_views_.begin();
972 for (BrowserActionViews::iterator iter = 927 iter != browser_action_views_.end(); ++iter) {
973 browser_action_views_.begin(); iter != browser_action_views_.end();
974 ++iter) {
975 if ((*iter)->button()->extension() == extension) { 928 if ((*iter)->button()->extension() == extension) {
976 RemoveChildView(*iter); 929 RemoveChildView(*iter);
977 delete *iter; 930 delete *iter;
978 browser_action_views_.erase(iter); 931 browser_action_views_.erase(iter);
979 932
980 // If the extension is being upgraded we don't want the bar to shrink 933 // If the extension is being upgraded we don't want the bar to shrink
981 // because the icon is just going to get re-added to the same location. 934 // because the icon is just going to get re-added to the same location.
982 if (extension->being_upgraded()) 935 if (extension->being_upgraded())
983 return; 936 return;
984 937
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 969 }
1017 970
1018 void BrowserActionsContainer::ModelLoaded() { 971 void BrowserActionsContainer::ModelLoaded() {
1019 SetContainerWidth(); 972 SetContainerWidth();
1020 } 973 }
1021 974
1022 void BrowserActionsContainer::SetContainerWidth() { 975 void BrowserActionsContainer::SetContainerWidth() {
1023 int visible_actions = model_->GetVisibleIconCount(); 976 int visible_actions = model_->GetVisibleIconCount();
1024 if (visible_actions < 0) // All icons should be visible. 977 if (visible_actions < 0) // All icons should be visible.
1025 visible_actions = model_->size(); 978 visible_actions = model_->size();
1026 else 979 chevron_->SetVisible(static_cast<size_t>(visible_actions) < model_->size());
1027 chevron_->SetVisible(true); 980 container_width_ = IconCountToWidth(visible_actions);
1028 container_size_ = gfx::Size(IconCountToWidth(visible_actions), kButtonSize); 981 }
982
983 void BrowserActionsContainer::CloseOverflowMenu() {
984 if (overflow_menu_)
985 overflow_menu_->CancelMenu();
986 }
987
988 void BrowserActionsContainer::StopShowFolderDropMenuTimer() {
989 show_menu_task_factory_.RevokeAll();
990 }
991
992 void BrowserActionsContainer::StartShowFolderDropMenuTimer() {
993 int delay = View::GetMenuShowDelay();
994 MessageLoop::current()->PostDelayedTask(FROM_HERE,
995 show_menu_task_factory_.NewRunnableMethod(
996 &BrowserActionsContainer::ShowDropFolder),
997 delay);
998 }
999
1000 void BrowserActionsContainer::ShowDropFolder() {
1001 DCHECK(!overflow_menu_);
1002 SetDropIndicator(-1);
1003 overflow_menu_ = new BrowserActionOverflowMenuController(
1004 this, chevron_, browser_action_views_, VisibleBrowserActions());
1005 overflow_menu_->set_observer(this);
1006 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true);
1007 }
1008
1009 void BrowserActionsContainer::SetDropIndicator(int x_pos) {
1010 if (drop_indicator_position_ != x_pos) {
1011 drop_indicator_position_ = x_pos;
1012 SchedulePaint();
1013 }
1014 }
1015
1016 int BrowserActionsContainer::ClampToNearestIconCount(
1017 int pixelWidth,
1018 bool allow_shrink_to_minimum) const {
1019 // Calculate the width of one icon.
1020 int icon_width = (kButtonSize + kBrowserActionButtonPadding);
1021
1022 // Calculate pixel count for the area not used by the icons.
1023 int extras = WidthOfNonIconArea();
1024
1025 size_t icon_count = 0u;
1026 if (pixelWidth >= 0) {
1027 // Caller wants to know how many icons fit within a given space so we start
1028 // by subtracting the padding, resize area and dividers.
1029 int icon_area = pixelWidth - extras;
1030 icon_area = std::max(0, icon_area);
1031
1032 // Make sure we never throw an icon into the chevron menu just because
1033 // there isn't enough enough space for the invisible padding around buttons.
1034 icon_area += kBrowserActionButtonPadding - 1;
1035
1036 // Count the number of icons that fit within that area.
1037 icon_count = icon_area / icon_width;
1038
1039 if (icon_count == 0 && allow_shrink_to_minimum) {
1040 extras = ContainerMinSize(); // Allow very narrow width if no icons.
1041 } else if (icon_count > browser_action_views_.size()) {
1042 // No use allowing more than what we have.
1043 icon_count = browser_action_views_.size();
1044 }
1045 } else {
1046 // A negative |pixels| count indicates caller wants to know the max width
1047 // that fits all icons;
1048 icon_count = browser_action_views_.size();
1049 }
1050
1051 return extras + (icon_count * icon_width);
1029 } 1052 }
1030 1053
1031 int BrowserActionsContainer::WidthOfNonIconArea() const { 1054 int BrowserActionsContainer::WidthOfNonIconArea() const {
1032 int chevron_size = (chevron_->IsVisible()) ? 1055 int chevron_size = (chevron_->IsVisible()) ?
1033 chevron_->GetPreferredSize().width() : 0; 1056 chevron_->GetPreferredSize().width() : 0;
1034 int padding = base::i18n::IsRTL() ? 1057 int padding = base::i18n::IsRTL() ?
1035 kHorizontalPaddingRtl : kHorizontalPadding; 1058 kHorizontalPaddingRtl : kHorizontalPadding;
1036 return kResizeAreaWidth + padding + chevron_size + kChevronRightMargin + 1059 return kResizeAreaWidth + padding + chevron_size + kChevronRightMargin +
1037 kDividerHorizontalMargin; 1060 kDividerHorizontalMargin;
1038 } 1061 }
(...skipping 19 matching lines...) Expand all
1058 resize_animation_->Reset(); 1081 resize_animation_->Reset();
1059 resize_animation_->SetTweenType(tween_type); 1082 resize_animation_->SetTweenType(tween_type);
1060 animation_target_size_ = target_size; 1083 animation_target_size_ = target_size;
1061 resize_animation_->Show(); 1084 resize_animation_->Show();
1062 } else { 1085 } else {
1063 animation_target_size_ = target_size; 1086 animation_target_size_ = target_size;
1064 AnimationEnded(resize_animation_.get()); 1087 AnimationEnded(resize_animation_.get());
1065 } 1088 }
1066 } 1089 }
1067 1090
1068 size_t BrowserActionsContainer::VisibleBrowserActions() const {
1069 size_t visible_actions = 0;
1070 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
1071 if (browser_action_views_[i]->IsVisible())
1072 ++visible_actions;
1073 }
1074
1075 return visible_actions;
1076 }
1077
1078 void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) {
1079 if (!done_resizing) {
1080 resize_amount_ = resize_amount;
1081 OnBrowserActionVisibilityChanged();
1082 } else {
1083 // For details on why we do the following see the class comments in the
1084 // header.
1085
1086 // Clamp lower limit to 0 and upper limit to the amount that allows enough
1087 // room for all icons to show.
1088 int new_width = std::max(0, container_size_.width() - resize_amount);
1089 int max_width = ClampToNearestIconCount(-1, false);
1090 new_width = std::min(new_width, max_width);
1091
1092 // Up until now we've only been modifying the resize_amount, but now it is
1093 // time to set the container size to the size we have resized to, but then
1094 // animate to the nearest icon count size (or down to min size if no icon).
1095 container_size_.set_width(new_width);
1096 animation_target_size_ = ClampToNearestIconCount(new_width, true);
1097 resize_animation_->Reset();
1098 resize_animation_->SetTweenType(Tween::EASE_OUT);
1099 resize_animation_->Show();
1100 }
1101 }
1102
1103 void BrowserActionsContainer::AnimationProgressed(const Animation* animation) {
1104 DCHECK(animation == resize_animation_.get());
1105
1106 double e = resize_animation_->GetCurrentValue();
1107 int difference = container_size_.width() - animation_target_size_;
1108
1109 resize_amount_ = static_cast<int>(e * difference);
1110
1111 OnBrowserActionVisibilityChanged();
1112 }
1113
1114 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
1115 container_size_.set_width(animation_target_size_);
1116 animation_target_size_ = 0;
1117 resize_amount_ = 0;
1118 OnBrowserActionVisibilityChanged();
1119 suppress_chevron_ = false;
1120
1121 // Don't save the icon count in incognito because there may be fewer icons
1122 // in that mode. The result is that the container in a normal window is always
1123 // at least as wide as in an incognito window.
1124 if (!profile_->IsOffTheRecord())
1125 model_->SetVisibleIconCount(VisibleBrowserActions());
1126 }
1127
1128 void BrowserActionsContainer::NotifyMenuDeleted(
1129 BrowserActionOverflowMenuController* controller) {
1130 DCHECK(controller == overflow_menu_);
1131 overflow_menu_ = NULL;
1132 }
1133
1134 void BrowserActionsContainer::InspectPopup(
1135 ExtensionAction* action) {
1136 OnBrowserActionExecuted(GetBrowserActionView(action)->button(),
1137 true); // |inspect_with_devtools|.
1138 }
1139
1140 void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) {
1141 // ExtensionPopup is ref-counted, so we don't need to delete it.
1142 DCHECK_EQ(popup_, popup);
1143 popup_ = NULL;
1144 popup_button_->SetButtonNotPushed();
1145 popup_button_ = NULL;
1146 }
1147
1148 bool BrowserActionsContainer::ShouldDisplayBrowserAction(Extension* extension) { 1091 bool BrowserActionsContainer::ShouldDisplayBrowserAction(Extension* extension) {
1149 // Only display incognito-enabled extensions while in incognito mode. 1092 // Only display incognito-enabled extensions while in incognito mode.
1150 return (!profile_->IsOffTheRecord() || 1093 return (!profile_->IsOffTheRecord() ||
1151 profile_->GetExtensionsService()->IsIncognitoEnabled(extension)); 1094 profile_->GetExtensionsService()->IsIncognitoEnabled(extension));
1152 } 1095 }
OLDNEW
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | chrome/browser/views/browser_actions_container_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698