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