Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |