| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ui/views/toolbar/browser_actions_container.h" | 5 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "chrome/grit/generated_resources.h" | 27 #include "chrome/grit/generated_resources.h" |
| 28 #include "extensions/common/feature_switch.h" | 28 #include "extensions/common/feature_switch.h" |
| 29 #include "grit/theme_resources.h" | 29 #include "grit/theme_resources.h" |
| 30 #include "third_party/skia/include/core/SkColor.h" | 30 #include "third_party/skia/include/core/SkColor.h" |
| 31 #include "ui/accessibility/ax_view_state.h" | 31 #include "ui/accessibility/ax_view_state.h" |
| 32 #include "ui/base/dragdrop/drag_utils.h" | 32 #include "ui/base/dragdrop/drag_utils.h" |
| 33 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
| 34 #include "ui/base/material_design/material_design_controller.h" | 34 #include "ui/base/material_design/material_design_controller.h" |
| 35 #include "ui/base/nine_image_painter_factory.h" | 35 #include "ui/base/nine_image_painter_factory.h" |
| 36 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
| 37 #include "ui/base/theme_provider.h" | |
| 38 #include "ui/gfx/canvas.h" | 37 #include "ui/gfx/canvas.h" |
| 39 #include "ui/gfx/geometry/rect.h" | 38 #include "ui/gfx/geometry/rect.h" |
| 40 #include "ui/resources/grit/ui_resources.h" | 39 #include "ui/resources/grit/ui_resources.h" |
| 41 #include "ui/views/bubble/bubble_dialog_delegate.h" | 40 #include "ui/views/bubble/bubble_dialog_delegate.h" |
| 42 #include "ui/views/controls/resize_area.h" | 41 #include "ui/views/controls/resize_area.h" |
| 43 #include "ui/views/painter.h" | 42 #include "ui/views/painter.h" |
| 44 #include "ui/views/widget/widget.h" | 43 #include "ui/views/widget/widget.h" |
| 45 | 44 |
| 46 namespace { | 45 namespace { |
| 47 | 46 |
| 48 // Horizontal spacing before the chevron (if visible). | |
| 49 // TODO(tdanderson): In material design, the chevron should have the same size | |
| 50 // and vertical spacing as the other action buttons. | |
| 51 int GetChevronSpacing() { | |
| 52 return GetLayoutConstant(TOOLBAR_STANDARD_SPACING) - 2; | |
| 53 } | |
| 54 | |
| 55 // Returns the ToolbarView for the given |browser|. | 47 // Returns the ToolbarView for the given |browser|. |
| 56 ToolbarView* GetToolbarView(Browser* browser) { | 48 ToolbarView* GetToolbarView(Browser* browser) { |
| 57 return BrowserView::GetBrowserViewForBrowser(browser)->toolbar(); | 49 return BrowserView::GetBrowserViewForBrowser(browser)->toolbar(); |
| 58 } | 50 } |
| 59 | 51 |
| 60 } // namespace | 52 } // namespace |
| 61 | 53 |
| 62 //////////////////////////////////////////////////////////////////////////////// | 54 //////////////////////////////////////////////////////////////////////////////// |
| 63 // BrowserActionsContainer::DropPosition | 55 // BrowserActionsContainer::DropPosition |
| 64 | 56 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 84 Browser* browser, | 76 Browser* browser, |
| 85 BrowserActionsContainer* main_container) | 77 BrowserActionsContainer* main_container) |
| 86 : toolbar_actions_bar_(new ToolbarActionsBar( | 78 : toolbar_actions_bar_(new ToolbarActionsBar( |
| 87 this, | 79 this, |
| 88 browser, | 80 browser, |
| 89 main_container ? | 81 main_container ? |
| 90 main_container->toolbar_actions_bar_.get() : nullptr)), | 82 main_container->toolbar_actions_bar_.get() : nullptr)), |
| 91 browser_(browser), | 83 browser_(browser), |
| 92 main_container_(main_container), | 84 main_container_(main_container), |
| 93 resize_area_(NULL), | 85 resize_area_(NULL), |
| 94 chevron_(NULL), | |
| 95 suppress_chevron_(false), | |
| 96 added_to_view_(false), | 86 added_to_view_(false), |
| 97 resize_starting_width_(-1), | 87 resize_starting_width_(-1), |
| 98 resize_amount_(0), | 88 resize_amount_(0), |
| 99 animation_target_size_(0), | 89 animation_target_size_(0), |
| 100 active_bubble_(nullptr) { | 90 active_bubble_(nullptr) { |
| 101 set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR); | 91 set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR); |
| 102 | 92 |
| 103 bool overflow_experiment = | 93 if (!ShownInsideMenu()) { |
| 104 extensions::FeatureSwitch::extension_action_redesign()->IsEnabled(); | |
| 105 DCHECK(!in_overflow_mode() || overflow_experiment); | |
| 106 | |
| 107 if (!in_overflow_mode()) { | |
| 108 resize_animation_.reset(new gfx::SlideAnimation(this)); | 94 resize_animation_.reset(new gfx::SlideAnimation(this)); |
| 109 resize_area_ = new views::ResizeArea(this); | 95 resize_area_ = new views::ResizeArea(this); |
| 110 AddChildView(resize_area_); | 96 AddChildView(resize_area_); |
| 111 | 97 |
| 112 // 'Main' mode doesn't need a chevron overflow when overflow is shown inside | 98 const int kInfoImages[] = IMAGE_GRID(IDR_TOOLBAR_ACTION_HIGHLIGHT); |
| 113 // the Chrome menu. | 99 info_highlight_painter_.reset( |
| 114 if (!overflow_experiment) { | 100 views::Painter::CreateImageGridPainter(kInfoImages)); |
| 115 // Since the ChevronMenuButton holds a raw pointer to us, we need to | 101 const int kWarningImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); |
| 116 // ensure it doesn't outlive us. Having it owned by the view hierarchy as | 102 warning_highlight_painter_.reset( |
| 117 // a child will suffice. | 103 views::Painter::CreateImageGridPainter(kWarningImages)); |
| 118 chevron_ = new ChevronMenuButton(this); | |
| 119 chevron_->EnableCanvasFlippingForRTLUI(true); | |
| 120 chevron_->SetAccessibleName( | |
| 121 l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS_CHEVRON)); | |
| 122 chevron_->SetVisible(false); | |
| 123 AddChildView(chevron_); | |
| 124 } | |
| 125 } | 104 } |
| 126 } | 105 } |
| 127 | 106 |
| 128 BrowserActionsContainer::~BrowserActionsContainer() { | 107 BrowserActionsContainer::~BrowserActionsContainer() { |
| 129 if (active_bubble_) | 108 if (active_bubble_) |
| 130 active_bubble_->GetWidget()->Close(); | 109 active_bubble_->GetWidget()->Close(); |
| 131 // We should synchronously receive the OnWidgetClosing() event, so we should | 110 // We should synchronously receive the OnWidgetClosing() event, so we should |
| 132 // always have cleared the active bubble by now. | 111 // always have cleared the active bubble by now. |
| 133 DCHECK(!active_bubble_); | 112 DCHECK(!active_bubble_); |
| 134 | 113 |
| 135 toolbar_actions_bar_->DeleteActions(); | 114 toolbar_actions_bar_->DeleteActions(); |
| 136 // All views should be removed as part of ToolbarActionsBar::DeleteActions(). | 115 // All views should be removed as part of ToolbarActionsBar::DeleteActions(). |
| 137 DCHECK(toolbar_action_views_.empty()); | 116 DCHECK(toolbar_action_views_.empty()); |
| 138 } | 117 } |
| 139 | 118 |
| 140 void BrowserActionsContainer::Init() { | |
| 141 LoadImages(); | |
| 142 } | |
| 143 | |
| 144 std::string BrowserActionsContainer::GetIdAt(size_t index) const { | 119 std::string BrowserActionsContainer::GetIdAt(size_t index) const { |
| 145 return toolbar_action_views_[index]->view_controller()->GetId(); | 120 return toolbar_action_views_[index]->view_controller()->GetId(); |
| 146 } | 121 } |
| 147 | 122 |
| 148 ToolbarActionView* BrowserActionsContainer::GetViewForId( | 123 ToolbarActionView* BrowserActionsContainer::GetViewForId( |
| 149 const std::string& id) { | 124 const std::string& id) { |
| 150 for (ToolbarActionView* view : toolbar_action_views_) { | 125 for (ToolbarActionView* view : toolbar_action_views_) { |
| 151 if (view->view_controller()->GetId() == id) | 126 if (view->view_controller()->GetId() == id) |
| 152 return view; | 127 return view; |
| 153 } | 128 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 168 } | 143 } |
| 169 | 144 |
| 170 size_t BrowserActionsContainer::VisibleBrowserActionsAfterAnimation() const { | 145 size_t BrowserActionsContainer::VisibleBrowserActionsAfterAnimation() const { |
| 171 if (!animating()) | 146 if (!animating()) |
| 172 return VisibleBrowserActions(); | 147 return VisibleBrowserActions(); |
| 173 | 148 |
| 174 return toolbar_actions_bar_->WidthToIconCount(animation_target_size_); | 149 return toolbar_actions_bar_->WidthToIconCount(animation_target_size_); |
| 175 } | 150 } |
| 176 | 151 |
| 177 bool BrowserActionsContainer::ShownInsideMenu() const { | 152 bool BrowserActionsContainer::ShownInsideMenu() const { |
| 178 return in_overflow_mode(); | 153 return main_container_ != nullptr; |
| 179 } | 154 } |
| 180 | 155 |
| 181 void BrowserActionsContainer::OnToolbarActionViewDragDone() { | 156 void BrowserActionsContainer::OnToolbarActionViewDragDone() { |
| 182 toolbar_actions_bar_->OnDragEnded(); | 157 toolbar_actions_bar_->OnDragEnded(); |
| 183 } | 158 } |
| 184 | 159 |
| 185 views::MenuButton* BrowserActionsContainer::GetOverflowReferenceView() { | 160 views::MenuButton* BrowserActionsContainer::GetOverflowReferenceView() { |
| 186 // With traditional overflow, the reference is the chevron. With the redesign, | 161 return static_cast<views::MenuButton*>( |
| 187 // we use the app menu instead. | 162 GetToolbarView(browser_)->app_menu_button()); |
| 188 return chevron_ ? static_cast<views::MenuButton*>(chevron_) | |
| 189 : static_cast<views::MenuButton*>( | |
| 190 GetToolbarView(browser_)->app_menu_button()); | |
| 191 } | 163 } |
| 192 | 164 |
| 193 void BrowserActionsContainer::AddViewForAction( | 165 void BrowserActionsContainer::AddViewForAction( |
| 194 ToolbarActionViewController* view_controller, | 166 ToolbarActionViewController* view_controller, |
| 195 size_t index) { | 167 size_t index) { |
| 196 if (chevron_) | |
| 197 chevron_->CloseMenu(); | |
| 198 | |
| 199 ToolbarActionView* view = new ToolbarActionView(view_controller, this); | 168 ToolbarActionView* view = new ToolbarActionView(view_controller, this); |
| 200 toolbar_action_views_.insert(toolbar_action_views_.begin() + index, view); | 169 toolbar_action_views_.insert(toolbar_action_views_.begin() + index, view); |
| 201 AddChildViewAt(view, index); | 170 AddChildViewAt(view, index); |
| 202 } | 171 } |
| 203 | 172 |
| 204 void BrowserActionsContainer::RemoveViewForAction( | 173 void BrowserActionsContainer::RemoveViewForAction( |
| 205 ToolbarActionViewController* action) { | 174 ToolbarActionViewController* action) { |
| 206 if (chevron_) | |
| 207 chevron_->CloseMenu(); | |
| 208 | |
| 209 for (ToolbarActionViews::iterator iter = toolbar_action_views_.begin(); | 175 for (ToolbarActionViews::iterator iter = toolbar_action_views_.begin(); |
| 210 iter != toolbar_action_views_.end(); ++iter) { | 176 iter != toolbar_action_views_.end(); ++iter) { |
| 211 if ((*iter)->view_controller() == action) { | 177 if ((*iter)->view_controller() == action) { |
| 212 delete *iter; | 178 delete *iter; |
| 213 toolbar_action_views_.erase(iter); | 179 toolbar_action_views_.erase(iter); |
| 214 break; | 180 break; |
| 215 } | 181 } |
| 216 } | 182 } |
| 217 } | 183 } |
| 218 | 184 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 246 std::swap(toolbar_action_views_[i], toolbar_action_views_[j]); | 212 std::swap(toolbar_action_views_[i], toolbar_action_views_[j]); |
| 247 // Also move the view in the child views vector. | 213 // Also move the view in the child views vector. |
| 248 ReorderChildView(toolbar_action_views_[i], i); | 214 ReorderChildView(toolbar_action_views_[i], i); |
| 249 } | 215 } |
| 250 } | 216 } |
| 251 } | 217 } |
| 252 | 218 |
| 253 Layout(); | 219 Layout(); |
| 254 } | 220 } |
| 255 | 221 |
| 256 void BrowserActionsContainer::ResizeAndAnimate( | 222 void BrowserActionsContainer::ResizeAndAnimate(gfx::Tween::Type tween_type, |
| 257 gfx::Tween::Type tween_type, | 223 int target_width, |
| 258 int target_width, | 224 bool /*suppress_chevron*/) { |
| 259 bool suppress_chevron) { | |
| 260 if (resize_animation_ && !toolbar_actions_bar_->suppress_animation()) { | 225 if (resize_animation_ && !toolbar_actions_bar_->suppress_animation()) { |
| 261 if (!in_overflow_mode()) { | 226 if (!ShownInsideMenu()) { |
| 262 // Make sure we don't try to animate to wider than the allowed width. | 227 // Make sure we don't try to animate to wider than the allowed width. |
| 263 int max_width = GetToolbarView(browser_)->GetMaxBrowserActionsWidth(); | 228 int max_width = GetToolbarView(browser_)->GetMaxBrowserActionsWidth(); |
| 264 if (target_width > max_width) | 229 if (target_width > max_width) |
| 265 target_width = GetWidthForMaxWidth(max_width); | 230 target_width = GetWidthForMaxWidth(max_width); |
| 266 } | 231 } |
| 267 // Animate! We have to set the animation_target_size_ after calling Reset(), | 232 // Animate! We have to set the animation_target_size_ after calling Reset(), |
| 268 // because that could end up calling AnimationEnded which clears the value. | 233 // because that could end up calling AnimationEnded which clears the value. |
| 269 resize_animation_->Reset(); | 234 resize_animation_->Reset(); |
| 270 resize_starting_width_ = width(); | 235 resize_starting_width_ = width(); |
| 271 suppress_chevron_ = suppress_chevron; | |
| 272 resize_animation_->SetTweenType(tween_type); | 236 resize_animation_->SetTweenType(tween_type); |
| 273 animation_target_size_ = target_width; | 237 animation_target_size_ = target_width; |
| 274 resize_animation_->Show(); | 238 resize_animation_->Show(); |
| 275 } else { | 239 } else { |
| 276 animation_target_size_ = target_width; | 240 animation_target_size_ = target_width; |
| 277 AnimationEnded(resize_animation_.get()); | 241 AnimationEnded(resize_animation_.get()); |
| 278 } | 242 } |
| 279 } | 243 } |
| 280 | 244 |
| 281 void BrowserActionsContainer::SetChevronVisibility(bool visible) { | 245 void BrowserActionsContainer::SetChevronVisibility(bool visible) {} |
| 282 if (chevron_) | |
| 283 chevron_->SetVisible(visible); | |
| 284 } | |
| 285 | 246 |
| 286 int BrowserActionsContainer::GetWidth(GetWidthTime get_width_time) const { | 247 int BrowserActionsContainer::GetWidth(GetWidthTime get_width_time) const { |
| 287 return get_width_time == GET_WIDTH_AFTER_ANIMATION && | 248 return get_width_time == GET_WIDTH_AFTER_ANIMATION && |
| 288 animation_target_size_ > 0 | 249 animation_target_size_ > 0 |
| 289 ? animation_target_size_ | 250 ? animation_target_size_ |
| 290 : width(); | 251 : width(); |
| 291 } | 252 } |
| 292 | 253 |
| 293 bool BrowserActionsContainer::IsAnimating() const { | 254 bool BrowserActionsContainer::IsAnimating() const { |
| 294 return animating(); | 255 return animating(); |
| 295 } | 256 } |
| 296 | 257 |
| 297 void BrowserActionsContainer::StopAnimating() { | 258 void BrowserActionsContainer::StopAnimating() { |
| 298 animation_target_size_ = width(); | 259 animation_target_size_ = width(); |
| 299 resize_animation_->Reset(); | 260 resize_animation_->Reset(); |
| 300 } | 261 } |
| 301 | 262 |
| 302 int BrowserActionsContainer::GetChevronWidth() const { | 263 int BrowserActionsContainer::GetChevronWidth() const { |
| 303 return chevron_ ? | 264 return 0; |
| 304 chevron_->GetPreferredSize().width() + GetChevronSpacing() : 0; | |
| 305 } | 265 } |
| 306 | 266 |
| 307 void BrowserActionsContainer::ShowToolbarActionBubble( | 267 void BrowserActionsContainer::ShowToolbarActionBubble( |
| 308 std::unique_ptr<ToolbarActionsBarBubbleDelegate> controller) { | 268 std::unique_ptr<ToolbarActionsBarBubbleDelegate> controller) { |
| 309 // The container shouldn't be asked to show a bubble if it's animating. | 269 // The container shouldn't be asked to show a bubble if it's animating. |
| 310 DCHECK(!animating()); | 270 DCHECK(!animating()); |
| 311 DCHECK(!active_bubble_); | 271 DCHECK(!active_bubble_); |
| 312 | 272 |
| 313 views::View* anchor_view = nullptr; | 273 views::View* anchor_view = nullptr; |
| 314 if (!controller->GetAnchorActionId().empty()) { | 274 if (!controller->GetAnchorActionId().empty()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 // show nothing). | 309 // show nothing). |
| 350 if (max_width < toolbar_actions_bar_->GetMinimumWidth()) | 310 if (max_width < toolbar_actions_bar_->GetMinimumWidth()) |
| 351 return 0; | 311 return 0; |
| 352 preferred_width = toolbar_actions_bar_->IconCountToWidth( | 312 preferred_width = toolbar_actions_bar_->IconCountToWidth( |
| 353 toolbar_actions_bar_->WidthToIconCount(max_width)); | 313 toolbar_actions_bar_->WidthToIconCount(max_width)); |
| 354 } | 314 } |
| 355 return preferred_width; | 315 return preferred_width; |
| 356 } | 316 } |
| 357 | 317 |
| 358 gfx::Size BrowserActionsContainer::GetPreferredSize() const { | 318 gfx::Size BrowserActionsContainer::GetPreferredSize() const { |
| 359 if (in_overflow_mode()) | 319 if (ShownInsideMenu()) |
| 360 return toolbar_actions_bar_->GetPreferredSize(); | 320 return toolbar_actions_bar_->GetPreferredSize(); |
| 361 | 321 |
| 362 // If there are no actions to show, then don't show the container at all. | 322 // If there are no actions to show, then don't show the container at all. |
| 363 if (toolbar_action_views_.empty()) | 323 if (toolbar_action_views_.empty()) |
| 364 return gfx::Size(); | 324 return gfx::Size(); |
| 365 | 325 |
| 366 // When resizing, preferred width is the starting width - resize amount. | 326 // When resizing, preferred width is the starting width - resize amount. |
| 367 // Otherwise, use the normal preferred width. | 327 // Otherwise, use the normal preferred width. |
| 368 int preferred_width = resize_starting_width_ == -1 ? | 328 int preferred_width = resize_starting_width_ == -1 ? |
| 369 toolbar_actions_bar_->GetPreferredSize().width() : | 329 toolbar_actions_bar_->GetPreferredSize().width() : |
| 370 resize_starting_width_ - resize_amount_; | 330 resize_starting_width_ - resize_amount_; |
| 371 // In either case, clamp it within the max/min bounds. | 331 // In either case, clamp it within the max/min bounds. |
| 372 preferred_width = std::min( | 332 preferred_width = std::min( |
| 373 std::max(toolbar_actions_bar_->GetMinimumWidth(), preferred_width), | 333 std::max(toolbar_actions_bar_->GetMinimumWidth(), preferred_width), |
| 374 toolbar_actions_bar_->GetMaximumWidth()); | 334 toolbar_actions_bar_->GetMaximumWidth()); |
| 375 return gfx::Size(preferred_width, ToolbarActionsBar::IconHeight()); | 335 return gfx::Size(preferred_width, ToolbarActionsBar::IconHeight()); |
| 376 } | 336 } |
| 377 | 337 |
| 378 int BrowserActionsContainer::GetHeightForWidth(int width) const { | 338 int BrowserActionsContainer::GetHeightForWidth(int width) const { |
| 379 if (in_overflow_mode()) | 339 if (ShownInsideMenu()) |
| 380 toolbar_actions_bar_->SetOverflowRowWidth(width); | 340 toolbar_actions_bar_->SetOverflowRowWidth(width); |
| 381 return GetPreferredSize().height(); | 341 return GetPreferredSize().height(); |
| 382 } | 342 } |
| 383 | 343 |
| 384 gfx::Size BrowserActionsContainer::GetMinimumSize() const { | 344 gfx::Size BrowserActionsContainer::GetMinimumSize() const { |
| 385 return gfx::Size(toolbar_actions_bar_->GetMinimumWidth(), | 345 return gfx::Size(toolbar_actions_bar_->GetMinimumWidth(), |
| 386 ToolbarActionsBar::IconHeight()); | 346 ToolbarActionsBar::IconHeight()); |
| 387 } | 347 } |
| 388 | 348 |
| 389 void BrowserActionsContainer::Layout() { | 349 void BrowserActionsContainer::Layout() { |
| 390 if (toolbar_actions_bar_->suppress_layout()) | 350 if (toolbar_actions_bar_->suppress_layout()) |
| 391 return; | 351 return; |
| 392 | 352 |
| 393 if (toolbar_action_views_.empty()) { | 353 if (toolbar_action_views_.empty()) { |
| 394 SetVisible(false); | 354 SetVisible(false); |
| 395 return; | 355 return; |
| 396 } | 356 } |
| 397 | 357 |
| 398 SetVisible(true); | 358 SetVisible(true); |
| 399 if (resize_area_) | 359 if (resize_area_) |
| 400 resize_area_->SetBounds(0, 0, platform_settings().item_spacing, height()); | 360 resize_area_->SetBounds(0, 0, platform_settings().item_spacing, height()); |
| 401 | 361 |
| 402 // The range of visible icons, from start_index (inclusive) to end_index | 362 // The range of visible icons, from start_index (inclusive) to end_index |
| 403 // (exclusive). | 363 // (exclusive). |
| 404 size_t start_index = toolbar_actions_bar_->GetStartIndexInBounds(); | 364 size_t start_index = toolbar_actions_bar_->GetStartIndexInBounds(); |
| 405 size_t end_index = toolbar_actions_bar_->GetEndIndexInBounds(); | 365 size_t end_index = toolbar_actions_bar_->GetEndIndexInBounds(); |
| 406 | 366 |
| 407 // If the icons don't all fit, show the chevron (unless suppressed). | |
| 408 if (chevron_ && !suppress_chevron_ && toolbar_actions_bar_->NeedsOverflow()) { | |
| 409 chevron_->SetVisible(true); | |
| 410 gfx::Size chevron_size(chevron_->GetPreferredSize()); | |
| 411 chevron_->SetBounds( | |
| 412 width() - GetLayoutConstant(TOOLBAR_STANDARD_SPACING) - | |
| 413 chevron_size.width(), | |
| 414 0, | |
| 415 chevron_size.width(), | |
| 416 chevron_size.height()); | |
| 417 } else if (chevron_) { | |
| 418 chevron_->SetVisible(false); | |
| 419 } | |
| 420 | |
| 421 // Now draw the icons for the actions in the available space. Once all the | 367 // Now draw the icons for the actions in the available space. Once all the |
| 422 // variables are in place, the layout works equally well for the main and | 368 // variables are in place, the layout works equally well for the main and |
| 423 // overflow container. | 369 // overflow container. |
| 424 for (size_t i = 0u; i < toolbar_action_views_.size(); ++i) { | 370 for (size_t i = 0u; i < toolbar_action_views_.size(); ++i) { |
| 425 ToolbarActionView* view = toolbar_action_views_[i]; | 371 ToolbarActionView* view = toolbar_action_views_[i]; |
| 426 if (i < start_index || i >= end_index) { | 372 if (i < start_index || i >= end_index) { |
| 427 view->SetVisible(false); | 373 view->SetVisible(false); |
| 428 } else { | 374 } else { |
| 429 view->SetBoundsRect(toolbar_actions_bar_->GetFrameForIndex(i)); | 375 view->SetBoundsRect(toolbar_actions_bar_->GetFrameForIndex(i)); |
| 430 view->SetVisible(true); | 376 view->SetVisible(true); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 461 int offset_into_icon_area = | 407 int offset_into_icon_area = |
| 462 GetMirroredXInView(event.x()) - | 408 GetMirroredXInView(event.x()) - |
| 463 GetLayoutConstant(TOOLBAR_STANDARD_SPACING); | 409 GetLayoutConstant(TOOLBAR_STANDARD_SPACING); |
| 464 | 410 |
| 465 // Next, figure out what row we're on. This only matters for overflow mode, | 411 // Next, figure out what row we're on. This only matters for overflow mode, |
| 466 // but the calculation is the same for both. | 412 // but the calculation is the same for both. |
| 467 row_index = event.y() / ToolbarActionsBar::IconHeight(); | 413 row_index = event.y() / ToolbarActionsBar::IconHeight(); |
| 468 | 414 |
| 469 // Sanity check - we should never be on a different row in the main | 415 // Sanity check - we should never be on a different row in the main |
| 470 // container. | 416 // container. |
| 471 DCHECK(in_overflow_mode() || row_index == 0); | 417 DCHECK(ShownInsideMenu() || row_index == 0); |
| 472 | 418 |
| 473 // Next, we determine which icon to place the indicator in front of. We want | 419 // Next, we determine which icon to place the indicator in front of. We want |
| 474 // to place the indicator in front of icon n when the cursor is between the | 420 // to place the indicator in front of icon n when the cursor is between the |
| 475 // midpoints of icons (n - 1) and n. To do this we take the offset into the | 421 // midpoints of icons (n - 1) and n. To do this we take the offset into the |
| 476 // icon area and transform it as follows: | 422 // icon area and transform it as follows: |
| 477 // | 423 // |
| 478 // Real icon area: | 424 // Real icon area: |
| 479 // 0 a * b c | 425 // 0 a * b c |
| 480 // | | | | | 426 // | | | | |
| 481 // |[IC|ON] [IC|ON] [IC|ON] | 427 // |[IC|ON] [IC|ON] [IC|ON] |
| 482 // We want to be before icon 0 for 0 < x <= a, icon 1 for a < x <= b, etc. | 428 // We want to be before icon 0 for 0 < x <= a, icon 1 for a < x <= b, etc. |
| 483 // Here the "*" represents the offset into the icon area, and since it's | 429 // Here the "*" represents the offset into the icon area, and since it's |
| 484 // between a and b, we want to return "1". | 430 // between a and b, we want to return "1". |
| 485 // | 431 // |
| 486 // Transformed "icon area": | 432 // Transformed "icon area": |
| 487 // 0 a * b c | 433 // 0 a * b c |
| 488 // | | | | | 434 // | | | | |
| 489 // |[ICON] |[ICON] |[ICON] | | 435 // |[ICON] |[ICON] |[ICON] | |
| 490 // If we shift both our offset and our divider points later by half an icon | 436 // If we shift both our offset and our divider points later by half an icon |
| 491 // plus one spacing unit, then it becomes very easy to calculate how many | 437 // plus one spacing unit, then it becomes very easy to calculate how many |
| 492 // divider points we've passed, because they're the multiples of "one icon | 438 // divider points we've passed, because they're the multiples of "one icon |
| 493 // plus padding". | 439 // plus padding". |
| 494 int before_icon_unclamped = | 440 int before_icon_unclamped = |
| 495 (offset_into_icon_area + (ToolbarActionsBar::IconWidth(false) / 2) + | 441 (offset_into_icon_area + (ToolbarActionsBar::IconWidth(false) / 2) + |
| 496 platform_settings().item_spacing) / ToolbarActionsBar::IconWidth(true); | 442 platform_settings().item_spacing) / ToolbarActionsBar::IconWidth(true); |
| 497 | 443 |
| 498 // We need to figure out how many icons are visible on the relevant row. | 444 // We need to figure out how many icons are visible on the relevant row. |
| 499 // In the main container, this will just be the visible actions. | 445 // In the main container, this will just be the visible actions. |
| 500 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); | 446 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); |
| 501 if (in_overflow_mode()) { | 447 if (ShownInsideMenu()) { |
| 502 int icons_per_row = platform_settings().icons_per_overflow_menu_row; | 448 int icons_per_row = platform_settings().icons_per_overflow_menu_row; |
| 503 // If this is the final row of the overflow, then this is the remainder of | 449 // If this is the final row of the overflow, then this is the remainder of |
| 504 // visible icons. Otherwise, it's a full row (kIconsPerRow). | 450 // visible icons. Otherwise, it's a full row (kIconsPerRow). |
| 505 visible_icons_on_row = | 451 visible_icons_on_row = |
| 506 row_index == | 452 row_index == |
| 507 static_cast<size_t>(visible_icons_on_row / icons_per_row) ? | 453 static_cast<size_t>(visible_icons_on_row / icons_per_row) ? |
| 508 visible_icons_on_row % icons_per_row : icons_per_row; | 454 visible_icons_on_row % icons_per_row : icons_per_row; |
| 509 } | 455 } |
| 510 | 456 |
| 511 // Because the user can drag outside the container bounds, we need to clamp | 457 // Because the user can drag outside the container bounds, we need to clamp |
| (...skipping 24 matching lines...) Expand all Loading... |
| 536 BrowserActionDragData data; | 482 BrowserActionDragData data; |
| 537 if (!data.Read(event.data())) | 483 if (!data.Read(event.data())) |
| 538 return ui::DragDropTypes::DRAG_NONE; | 484 return ui::DragDropTypes::DRAG_NONE; |
| 539 | 485 |
| 540 // Make sure we have the same view as we started with. | 486 // Make sure we have the same view as we started with. |
| 541 DCHECK_EQ(GetIdAt(data.index()), data.id()); | 487 DCHECK_EQ(GetIdAt(data.index()), data.id()); |
| 542 | 488 |
| 543 size_t i = drop_position_->row * | 489 size_t i = drop_position_->row * |
| 544 platform_settings().icons_per_overflow_menu_row + | 490 platform_settings().icons_per_overflow_menu_row + |
| 545 drop_position_->icon_in_row; | 491 drop_position_->icon_in_row; |
| 546 if (in_overflow_mode()) | 492 if (ShownInsideMenu()) |
| 547 i += main_container_->VisibleBrowserActionsAfterAnimation(); | 493 i += main_container_->VisibleBrowserActionsAfterAnimation(); |
| 548 // |i| now points to the item to the right of the drop indicator*, which is | 494 // |i| now points to the item to the right of the drop indicator*, which is |
| 549 // correct when dragging an icon to the left. When dragging to the right, | 495 // correct when dragging an icon to the left. When dragging to the right, |
| 550 // however, we want the icon being dragged to get the index of the item to | 496 // however, we want the icon being dragged to get the index of the item to |
| 551 // the left of the drop indicator, so we subtract one. | 497 // the left of the drop indicator, so we subtract one. |
| 552 // * Well, it can also point to the end, but not when dragging to the left. :) | 498 // * Well, it can also point to the end, but not when dragging to the left. :) |
| 553 if (i > data.index()) | 499 if (i > data.index()) |
| 554 --i; | 500 --i; |
| 555 | 501 |
| 556 ToolbarActionsBar::DragType drag_type = ToolbarActionsBar::DRAG_TO_SAME; | 502 ToolbarActionsBar::DragType drag_type = ToolbarActionsBar::DRAG_TO_SAME; |
| 557 if (!toolbar_action_views_[data.index()]->visible()) | 503 if (!toolbar_action_views_[data.index()]->visible()) |
| 558 drag_type = in_overflow_mode() ? ToolbarActionsBar::DRAG_TO_OVERFLOW : | 504 drag_type = ShownInsideMenu() ? ToolbarActionsBar::DRAG_TO_OVERFLOW : |
| 559 ToolbarActionsBar::DRAG_TO_MAIN; | 505 ToolbarActionsBar::DRAG_TO_MAIN; |
| 560 | 506 |
| 561 toolbar_actions_bar_->OnDragDrop(data.index(), i, drag_type); | 507 toolbar_actions_bar_->OnDragDrop(data.index(), i, drag_type); |
| 562 | 508 |
| 563 OnDragExited(); // Perform clean up after dragging. | 509 OnDragExited(); // Perform clean up after dragging. |
| 564 return ui::DragDropTypes::DRAG_MOVE; | 510 return ui::DragDropTypes::DRAG_MOVE; |
| 565 } | 511 } |
| 566 | 512 |
| 567 void BrowserActionsContainer::GetAccessibleState( | 513 void BrowserActionsContainer::GetAccessibleState( |
| 568 ui::AXViewState* state) { | 514 ui::AXViewState* state) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 | 591 |
| 646 void BrowserActionsContainer::AnimationCanceled( | 592 void BrowserActionsContainer::AnimationCanceled( |
| 647 const gfx::Animation* animation) { | 593 const gfx::Animation* animation) { |
| 648 AnimationEnded(animation); | 594 AnimationEnded(animation); |
| 649 } | 595 } |
| 650 | 596 |
| 651 void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) { | 597 void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) { |
| 652 animation_target_size_ = 0; | 598 animation_target_size_ = 0; |
| 653 resize_amount_ = 0; | 599 resize_amount_ = 0; |
| 654 resize_starting_width_ = -1; | 600 resize_starting_width_ = -1; |
| 655 suppress_chevron_ = false; | |
| 656 parent()->Layout(); | 601 parent()->Layout(); |
| 657 | 602 |
| 658 toolbar_actions_bar_->OnAnimationEnded(); | 603 toolbar_actions_bar_->OnAnimationEnded(); |
| 659 } | 604 } |
| 660 | 605 |
| 661 content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { | 606 content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { |
| 662 return browser_->tab_strip_model()->GetActiveWebContents(); | 607 return browser_->tab_strip_model()->GetActiveWebContents(); |
| 663 } | 608 } |
| 664 | 609 |
| 665 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) { | 610 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) { |
| 666 // If the views haven't been initialized yet, wait for the next call to | 611 // If the views haven't been initialized yet, wait for the next call to |
| 667 // paint (one will be triggered by entering highlight mode). | 612 // paint (one will be triggered by entering highlight mode). |
| 668 if (toolbar_actions_bar_->is_highlighting() && | 613 if (toolbar_actions_bar_->is_highlighting() && |
| 669 !toolbar_action_views_.empty() && !in_overflow_mode()) { | 614 !toolbar_action_views_.empty() && !ShownInsideMenu()) { |
| 670 ToolbarActionsModel::HighlightType highlight_type = | 615 ToolbarActionsModel::HighlightType highlight_type = |
| 671 toolbar_actions_bar_->highlight_type(); | 616 toolbar_actions_bar_->highlight_type(); |
| 672 views::Painter* painter = | 617 views::Painter* painter = |
| 673 highlight_type == ToolbarActionsModel::HIGHLIGHT_INFO | 618 highlight_type == ToolbarActionsModel::HIGHLIGHT_INFO |
| 674 ? info_highlight_painter_.get() | 619 ? info_highlight_painter_.get() |
| 675 : warning_highlight_painter_.get(); | 620 : warning_highlight_painter_.get(); |
| 676 views::Painter::PaintPainterAt(canvas, painter, GetLocalBounds()); | 621 views::Painter::PaintPainterAt(canvas, painter, GetLocalBounds()); |
| 677 } | 622 } |
| 678 | 623 |
| 679 // TODO(sky/glen): Instead of using a drop indicator, animate the icons while | 624 // TODO(sky/glen): Instead of using a drop indicator, animate the icons while |
| (...skipping 23 matching lines...) Expand all Loading... |
| 703 kDropIndicatorWidth, | 648 kDropIndicatorWidth, |
| 704 row_height); | 649 row_height); |
| 705 indicator_bounds.set_x(GetMirroredXForRect(indicator_bounds)); | 650 indicator_bounds.set_x(GetMirroredXForRect(indicator_bounds)); |
| 706 | 651 |
| 707 // Color of the drop indicator. | 652 // Color of the drop indicator. |
| 708 static const SkColor kDropIndicatorColor = SK_ColorBLACK; | 653 static const SkColor kDropIndicatorColor = SK_ColorBLACK; |
| 709 canvas->FillRect(indicator_bounds, kDropIndicatorColor); | 654 canvas->FillRect(indicator_bounds, kDropIndicatorColor); |
| 710 } | 655 } |
| 711 } | 656 } |
| 712 | 657 |
| 713 void BrowserActionsContainer::OnThemeChanged() { | |
| 714 LoadImages(); | |
| 715 } | |
| 716 | |
| 717 void BrowserActionsContainer::ViewHierarchyChanged( | 658 void BrowserActionsContainer::ViewHierarchyChanged( |
| 718 const ViewHierarchyChangedDetails& details) { | 659 const ViewHierarchyChangedDetails& details) { |
| 719 if (!toolbar_actions_bar_->enabled()) | 660 if (!toolbar_actions_bar_->enabled()) |
| 720 return; | 661 return; |
| 721 | 662 |
| 722 if (details.is_add && details.child == this) { | 663 if (details.is_add && details.child == this) { |
| 723 // Initial toolbar button creation and placement in the widget hierarchy. | 664 // Initial toolbar button creation and placement in the widget hierarchy. |
| 724 // We do this here instead of in the constructor because adding views | 665 // We do this here instead of in the constructor because adding views |
| 725 // calls Layout on the Toolbar, which needs this object to be constructed | 666 // calls Layout on the Toolbar, which needs this object to be constructed |
| 726 // before its Layout function is called. | 667 // before its Layout function is called. |
| 727 toolbar_actions_bar_->CreateActions(); | 668 toolbar_actions_bar_->CreateActions(); |
| 728 | 669 |
| 729 added_to_view_ = true; | 670 added_to_view_ = true; |
| 730 } | 671 } |
| 731 } | 672 } |
| 732 | 673 |
| 733 void BrowserActionsContainer::LoadImages() { | |
| 734 if (in_overflow_mode()) | |
| 735 return; // Overflow mode has neither a chevron nor highlighting. | |
| 736 | |
| 737 const ui::ThemeProvider* tp = GetThemeProvider(); | |
| 738 if (tp && chevron_) { | |
| 739 chevron_->SetImage(views::Button::STATE_NORMAL, | |
| 740 *tp->GetImageSkiaNamed(IDR_BROWSER_ACTIONS_OVERFLOW)); | |
| 741 } | |
| 742 | |
| 743 const int kInfoImages[] = IMAGE_GRID(IDR_TOOLBAR_ACTION_HIGHLIGHT); | |
| 744 info_highlight_painter_.reset( | |
| 745 views::Painter::CreateImageGridPainter(kInfoImages)); | |
| 746 const int kWarningImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); | |
| 747 warning_highlight_painter_.reset( | |
| 748 views::Painter::CreateImageGridPainter(kWarningImages)); | |
| 749 } | |
| 750 | |
| 751 void BrowserActionsContainer::ClearActiveBubble(views::Widget* widget) { | 674 void BrowserActionsContainer::ClearActiveBubble(views::Widget* widget) { |
| 752 DCHECK(active_bubble_); | 675 DCHECK(active_bubble_); |
| 753 DCHECK_EQ(active_bubble_->GetWidget(), widget); | 676 DCHECK_EQ(active_bubble_->GetWidget(), widget); |
| 754 widget->RemoveObserver(this); | 677 widget->RemoveObserver(this); |
| 755 active_bubble_ = nullptr; | 678 active_bubble_ = nullptr; |
| 756 toolbar_actions_bar_->OnBubbleClosed(); | 679 toolbar_actions_bar_->OnBubbleClosed(); |
| 757 } | 680 } |
| OLD | NEW |