| 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 #ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTIONS_CONTAINER_H_ | 5 #ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTIONS_CONTAINER_H_ |
| 6 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTIONS_CONTAINER_H_ | 6 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTIONS_CONTAINER_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/observer_list.h" | 13 #include "base/observer_list.h" |
| 14 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" | 14 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" |
| 15 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_delegate.h" | 15 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_delegate.h" |
| 16 #include "chrome/browser/ui/views/toolbar/chevron_menu_button.h" | |
| 17 #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" | 16 #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" |
| 18 #include "ui/gfx/animation/animation_delegate.h" | 17 #include "ui/gfx/animation/animation_delegate.h" |
| 19 #include "ui/gfx/animation/slide_animation.h" | 18 #include "ui/gfx/animation/slide_animation.h" |
| 20 #include "ui/gfx/animation/tween.h" | 19 #include "ui/gfx/animation/tween.h" |
| 21 #include "ui/views/controls/resize_area_delegate.h" | 20 #include "ui/views/controls/resize_area_delegate.h" |
| 22 #include "ui/views/drag_controller.h" | 21 #include "ui/views/drag_controller.h" |
| 23 #include "ui/views/view.h" | 22 #include "ui/views/view.h" |
| 24 #include "ui/views/widget/widget_observer.h" | 23 #include "ui/views/widget/widget_observer.h" |
| 25 | 24 |
| 26 class ExtensionPopup; | 25 class ExtensionPopup; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 46 // BrowserActionContainer, but in 'overflow' mode the container is effectively | 45 // BrowserActionContainer, but in 'overflow' mode the container is effectively |
| 47 // just an overflow for the 'main' toolbar (shows only the icons that the main | 46 // just an overflow for the 'main' toolbar (shows only the icons that the main |
| 48 // toolbar does not) and as such does not have an overflow itself. The overflow | 47 // toolbar does not) and as such does not have an overflow itself. The overflow |
| 49 // container also does not support resizing. Since the main container only shows | 48 // container also does not support resizing. Since the main container only shows |
| 50 // icons in the Chrome toolbar, it is limited to a single row of icons. The | 49 // icons in the Chrome toolbar, it is limited to a single row of icons. The |
| 51 // overflow container, however, is allowed to display icons in multiple rows. | 50 // overflow container, however, is allowed to display icons in multiple rows. |
| 52 // | 51 // |
| 53 // The main container is placed flush against the omnibox and hot dog menu, | 52 // The main container is placed flush against the omnibox and hot dog menu, |
| 54 // whereas the overflow container is placed within the hot dog menu. The | 53 // whereas the overflow container is placed within the hot dog menu. The |
| 55 // layout is similar to this: | 54 // layout is similar to this: |
| 56 // rI_I_IcCs | 55 // rI_I_Is |
| 57 // Where the letters are as follows: | 56 // Where the letters are as follows: |
| 58 // r: An invisible resize area. This is | 57 // r: An invisible resize area. This is |
| 59 // GetLayoutConstant(TOOLBAR_STANDARD_SPACING) pixels wide and directly | 58 // GetLayoutConstant(TOOLBAR_STANDARD_SPACING) pixels wide and directly |
| 60 // adjacent to the omnibox. Only shown for the main container. | 59 // adjacent to the omnibox. Only shown for the main container. |
| 61 // I: An icon. In material design this has a width of 28. Otherwise it is as | 60 // I: An icon. In material design this has a width of 28. Otherwise it is as |
| 62 // wide as the IDR_BROWSER_ACTION image. | 61 // wide as the IDR_BROWSER_ACTION image. |
| 63 // _: ToolbarActionsBar::PlatformSettings::item_spacing pixels of empty space. | 62 // _: ToolbarActionsBar::PlatformSettings::item_spacing pixels of empty space. |
| 64 // c: GetChevronSpacing() pixels of empty space. Only present if C is present. | |
| 65 // C: An optional chevron, as wide as the IDR_BROWSER_ACTIONS_OVERFLOW image, | |
| 66 // and visible only when both of the following statements are true: | |
| 67 // - The container is set to a width smaller than needed to show all icons. | |
| 68 // - There is no other container in 'overflow' mode to handle the | |
| 69 // non-visible icons for this container. | |
| 70 // s: GetLayoutConstant(TOOLBAR_STANDARD_SPACING) pixels of empty space | 63 // s: GetLayoutConstant(TOOLBAR_STANDARD_SPACING) pixels of empty space |
| 71 // (before the app menu). | 64 // (before the app menu). |
| 72 // The reason the container contains the trailing space "s", rather than having | 65 // The reason the container contains the trailing space "s", rather than having |
| 73 // it be handled by the parent view, is so that when the chevron is invisible | 66 // it be handled by the parent view, is so that when the user starts |
| 74 // and the user starts dragging an icon around, we have the space to draw the | 67 // dragging an icon around, we have the space to draw the ultimate drop |
| 75 // ultimate drop indicator. (Otherwise, we'd be trying to draw it into the | 68 // indicator. (Otherwise, we'd be trying to draw it into the padding beyond our |
| 76 // padding beyond our right edge, and it wouldn't appear.) | 69 // right edge, and it wouldn't appear.) |
| 77 // | 70 // |
| 78 // The BrowserActionsContainer in 'main' mode follows a few rules, in terms of | 71 // The BrowserActionsContainer in 'main' mode follows a few rules, in terms of |
| 79 // user experience: | 72 // user experience: |
| 80 // | 73 // |
| 81 // 1) The container can never grow beyond the space needed to show all icons | 74 // 1) The container can never grow beyond the space needed to show all icons |
| 82 // (hereby referred to as the max width). | 75 // (hereby referred to as the max width). |
| 83 // 2) The container can never shrink below the space needed to show just the | 76 // 2) The container can never shrink below the space needed to show just the |
| 84 // initial padding and the chevron (ignoring the case where there are no icons | 77 // initial padding (ignoring the case where there are no icons to show, in which |
| 85 // to show, in which case the container won't be visible anyway). | 78 // case the container won't be visible anyway). |
| 86 // 3) The container snaps into place (to the pixel count that fits the visible | 79 // 3) The container snaps into place (to the pixel count that fits the visible |
| 87 // icons) to make sure there is no wasted space at the edges of the container. | 80 // icons) to make sure there is no wasted space at the edges of the container. |
| 88 // 4) If the user adds or removes icons (read: installs/uninstalls browser | 81 // 4) If the user adds or removes icons (read: installs/uninstalls browser |
| 89 // actions) we grow and shrink the container as needed - but ONLY if the | 82 // actions) we grow and shrink the container as needed - but ONLY if the |
| 90 // container was at max width to begin with. | 83 // container was at max width to begin with. |
| 91 // 5) If the container is NOT at max width (has an overflow menu), we respect | 84 // 5) If the container is NOT at max width (has an overflow menu), we respect |
| 92 // that size when adding and removing icons and DON'T grow/shrink the container. | 85 // that size when adding and removing icons and DON'T grow/shrink the container. |
| 93 // This means that new icons (which always appear at the far right) will show up | 86 // This means that new icons (which always appear at the far right) will show up |
| 94 // in the overflow. The install bubble for extensions points to the chevron | 87 // in the overflow. |
| 95 // menu in this case. | |
| 96 // | 88 // |
| 97 // Resizing the BrowserActionsContainer: | 89 // Resizing the BrowserActionsContainer: |
| 98 // | 90 // |
| 99 // The ResizeArea view sends OnResize messages to the BrowserActionsContainer | 91 // The ResizeArea view sends OnResize messages to the BrowserActionsContainer |
| 100 // class as the user drags it. This modifies the value for |resize_amount_|. | 92 // class as the user drags it. This modifies the value for |resize_amount_|. |
| 101 // That indicates to the container that a resize is in progress and is used to | 93 // That indicates to the container that a resize is in progress and is used to |
| 102 // calculate the size in GetPreferredSize(), though that function never exceeds | 94 // calculate the size in GetPreferredSize(), though that function never exceeds |
| 103 // the defined minimum and maximum size of the container. | 95 // the defined minimum and maximum size of the container. |
| 104 // | 96 // |
| 105 // When the user releases the mouse (ends the resize), we calculate a target | 97 // When the user releases the mouse (ends the resize), we calculate a target |
| 106 // size for the container (animation_target_size_), clamp that value to the | 98 // size for the container (animation_target_size_), clamp that value to the |
| 107 // containers min and max and then animate from the *current* position (that the | 99 // containers min and max and then animate from the *current* position (that the |
| 108 // user has dragged the view to) to the target size. | 100 // user has dragged the view to) to the target size. |
| 109 // | 101 // |
| 110 // Animating the BrowserActionsContainer: | 102 // Animating the BrowserActionsContainer: |
| 111 // | 103 // |
| 112 // Animations are used when snapping the container to a value that fits all | 104 // Animations are used when snapping the container to a value that fits all |
| 113 // visible icons. This can be triggered when the user finishes resizing the | 105 // visible icons. This can be triggered when the user finishes resizing the |
| 114 // container or when Browser Actions are added/removed. | 106 // container or when Browser Actions are added/removed. |
| 115 // | 107 // |
| 116 // We always animate from the current width (container_width_) to the target | 108 // We always animate from the current width (container_width_) to the target |
| 117 // size (animation_target_size_), using |resize_amount| to keep track of the | 109 // size (animation_target_size_), using |resize_amount| to keep track of the |
| 118 // animation progress. | 110 // animation progress. |
| 119 // | 111 // |
| 120 // NOTE: When adding Browser Actions to a maximum width container (no overflow) | |
| 121 // we make sure to suppress the chevron menu if it wasn't visible. This is | |
| 122 // because we won't have enough space to show the new Browser Action until the | |
| 123 // animation ends and we don't want the chevron to flash into view while we are | |
| 124 // growing the container. | |
| 125 // | |
| 126 //////////////////////////////////////////////////////////////////////////////// | 112 //////////////////////////////////////////////////////////////////////////////// |
| 127 class BrowserActionsContainer : public views::View, | 113 class BrowserActionsContainer : public views::View, |
| 128 public ToolbarActionsBarDelegate, | 114 public ToolbarActionsBarDelegate, |
| 129 public views::ResizeAreaDelegate, | 115 public views::ResizeAreaDelegate, |
| 130 public gfx::AnimationDelegate, | 116 public gfx::AnimationDelegate, |
| 131 public ToolbarActionView::Delegate, | 117 public ToolbarActionView::Delegate, |
| 132 public views::WidgetObserver { | 118 public views::WidgetObserver { |
| 133 public: | 119 public: |
| 134 // Constructs a BrowserActionContainer for a particular |browser| object. For | 120 // Constructs a BrowserActionContainer for a particular |browser| object. For |
| 135 // documentation of |main_container|, see class comments. | 121 // documentation of |main_container|, see class comments. |
| 136 BrowserActionsContainer(Browser* browser, | 122 BrowserActionsContainer(Browser* browser, |
| 137 BrowserActionsContainer* main_container); | 123 BrowserActionsContainer* main_container); |
| 138 ~BrowserActionsContainer() override; | 124 ~BrowserActionsContainer() override; |
| 139 | 125 |
| 140 void Init(); | |
| 141 | |
| 142 // Get the number of toolbar actions being displayed. | 126 // Get the number of toolbar actions being displayed. |
| 143 size_t num_toolbar_actions() const { return toolbar_action_views_.size(); } | 127 size_t num_toolbar_actions() const { return toolbar_action_views_.size(); } |
| 144 | 128 |
| 145 // Returns the chevron, if any. | |
| 146 views::View* chevron() { return chevron_; } | |
| 147 const views::View* chevron() const { return chevron_; } | |
| 148 | |
| 149 // Returns the browser this container is associated with. | 129 // Returns the browser this container is associated with. |
| 150 Browser* browser() const { return browser_; } | 130 Browser* browser() const { return browser_; } |
| 151 | 131 |
| 152 ToolbarActionsBar* toolbar_actions_bar() { | 132 ToolbarActionsBar* toolbar_actions_bar() { |
| 153 return toolbar_actions_bar_.get(); | 133 return toolbar_actions_bar_.get(); |
| 154 } | 134 } |
| 155 | 135 |
| 156 // Get a particular toolbar action view. | 136 // Get a particular toolbar action view. |
| 157 ToolbarActionView* GetToolbarActionViewAt(int index) { | 137 ToolbarActionView* GetToolbarActionViewAt(int index) { |
| 158 return toolbar_action_views_[index]; | 138 return toolbar_action_views_[index]; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 int GetChevronWidth() const override; | 221 int GetChevronWidth() const override; |
| 242 void ShowToolbarActionBubble( | 222 void ShowToolbarActionBubble( |
| 243 std::unique_ptr<ToolbarActionsBarBubbleDelegate> controller) override; | 223 std::unique_ptr<ToolbarActionsBarBubbleDelegate> controller) override; |
| 244 | 224 |
| 245 // views::WidgetObserver: | 225 // views::WidgetObserver: |
| 246 void OnWidgetClosing(views::Widget* widget) override; | 226 void OnWidgetClosing(views::Widget* widget) override; |
| 247 void OnWidgetDestroying(views::Widget* widget) override; | 227 void OnWidgetDestroying(views::Widget* widget) override; |
| 248 | 228 |
| 249 views::BubbleDialogDelegateView* active_bubble() { return active_bubble_; } | 229 views::BubbleDialogDelegateView* active_bubble() { return active_bubble_; } |
| 250 | 230 |
| 251 ChevronMenuButton* chevron_for_testing() { return chevron_; } | |
| 252 | |
| 253 protected: | 231 protected: |
| 254 // Overridden from views::View: | 232 // Overridden from views::View: |
| 255 void ViewHierarchyChanged( | 233 void ViewHierarchyChanged( |
| 256 const ViewHierarchyChangedDetails& details) override; | 234 const ViewHierarchyChangedDetails& details) override; |
| 257 void OnPaint(gfx::Canvas* canvas) override; | 235 void OnPaint(gfx::Canvas* canvas) override; |
| 258 void OnThemeChanged() override; | |
| 259 | 236 |
| 260 private: | 237 private: |
| 261 // A struct representing the position at which an action will be dropped. | 238 // A struct representing the position at which an action will be dropped. |
| 262 struct DropPosition; | 239 struct DropPosition; |
| 263 | 240 |
| 264 typedef std::vector<ToolbarActionView*> ToolbarActionViews; | 241 typedef std::vector<ToolbarActionView*> ToolbarActionViews; |
| 265 | 242 |
| 266 void LoadImages(); | |
| 267 | |
| 268 // Clears the |active_bubble_|, and unregisters the container as an observer. | 243 // Clears the |active_bubble_|, and unregisters the container as an observer. |
| 269 void ClearActiveBubble(views::Widget* widget); | 244 void ClearActiveBubble(views::Widget* widget); |
| 270 | 245 |
| 271 const ToolbarActionsBar::PlatformSettings& platform_settings() const { | 246 const ToolbarActionsBar::PlatformSettings& platform_settings() const { |
| 272 return toolbar_actions_bar_->platform_settings(); | 247 return toolbar_actions_bar_->platform_settings(); |
| 273 } | 248 } |
| 274 | 249 |
| 275 // Whether this container is in overflow mode (as opposed to in 'main' | |
| 276 // mode). See class comments for details on the difference. | |
| 277 bool in_overflow_mode() const { return main_container_ != NULL; } | |
| 278 | |
| 279 // The controlling ToolbarActionsBar, which handles most non-view logic. | 250 // The controlling ToolbarActionsBar, which handles most non-view logic. |
| 280 std::unique_ptr<ToolbarActionsBar> toolbar_actions_bar_; | 251 std::unique_ptr<ToolbarActionsBar> toolbar_actions_bar_; |
| 281 | 252 |
| 282 // The vector of toolbar actions (icons/image buttons for each action). | 253 // The vector of toolbar actions (icons/image buttons for each action). |
| 283 ToolbarActionViews toolbar_action_views_; | 254 ToolbarActionViews toolbar_action_views_; |
| 284 | 255 |
| 285 // The Browser object the container is associated with. | 256 // The Browser object the container is associated with. |
| 286 Browser* browser_; | 257 Browser* browser_; |
| 287 | 258 |
| 288 // The main container we are serving as overflow for, or NULL if this | 259 // The main container we are serving as overflow for, or NULL if this |
| 289 // class is the the main container. See class comments for details on | 260 // class is the the main container. See class comments for details on |
| 290 // the difference between main and overflow. | 261 // the difference between main and overflow. |
| 291 BrowserActionsContainer* main_container_; | 262 BrowserActionsContainer* main_container_; |
| 292 | 263 |
| 293 // The resize area for the container. | 264 // The resize area for the container. |
| 294 views::ResizeArea* resize_area_; | 265 views::ResizeArea* resize_area_; |
| 295 | 266 |
| 296 // The chevron for accessing the overflow items. Can be NULL when in overflow | |
| 297 // mode or if the toolbar is permanently suppressing the chevron menu. | |
| 298 ChevronMenuButton* chevron_; | |
| 299 | |
| 300 // The painter used when we are highlighting a subset of extensions. | 267 // The painter used when we are highlighting a subset of extensions. |
| 301 std::unique_ptr<views::Painter> info_highlight_painter_; | 268 std::unique_ptr<views::Painter> info_highlight_painter_; |
| 302 std::unique_ptr<views::Painter> warning_highlight_painter_; | 269 std::unique_ptr<views::Painter> warning_highlight_painter_; |
| 303 | 270 |
| 304 // The animation that happens when the container snaps to place. | 271 // The animation that happens when the container snaps to place. |
| 305 std::unique_ptr<gfx::SlideAnimation> resize_animation_; | 272 std::unique_ptr<gfx::SlideAnimation> resize_animation_; |
| 306 | 273 |
| 307 // Don't show the chevron while animating. | |
| 308 bool suppress_chevron_; | |
| 309 | |
| 310 // True if the container has been added to the parent view. | 274 // True if the container has been added to the parent view. |
| 311 bool added_to_view_; | 275 bool added_to_view_; |
| 312 | 276 |
| 313 // When the container is resizing, this is the width at which it started. | 277 // When the container is resizing, this is the width at which it started. |
| 314 // If the container is not resizing, -1. | 278 // If the container is not resizing, -1. |
| 315 int resize_starting_width_; | 279 int resize_starting_width_; |
| 316 | 280 |
| 317 // This is used while the user is resizing (and when the animations are in | 281 // This is used while the user is resizing (and when the animations are in |
| 318 // progress) to know how wide the delta is between the current state and what | 282 // progress) to know how wide the delta is between the current state and what |
| 319 // we should draw. | 283 // we should draw. |
| 320 int resize_amount_; | 284 int resize_amount_; |
| 321 | 285 |
| 322 // Keeps track of the absolute pixel width the container should have when we | 286 // Keeps track of the absolute pixel width the container should have when we |
| 323 // are done animating. | 287 // are done animating. |
| 324 int animation_target_size_; | 288 int animation_target_size_; |
| 325 | 289 |
| 326 // The DropPosition for the current drag-and-drop operation, or NULL if there | 290 // The DropPosition for the current drag-and-drop operation, or NULL if there |
| 327 // is none. | 291 // is none. |
| 328 std::unique_ptr<DropPosition> drop_position_; | 292 std::unique_ptr<DropPosition> drop_position_; |
| 329 | 293 |
| 330 // The extension bubble that is actively showing, if any. | 294 // The extension bubble that is actively showing, if any. |
| 331 views::BubbleDialogDelegateView* active_bubble_; | 295 views::BubbleDialogDelegateView* active_bubble_; |
| 332 | 296 |
| 333 DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer); | 297 DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer); |
| 334 }; | 298 }; |
| 335 | 299 |
| 336 #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTIONS_CONTAINER_H_ | 300 #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTIONS_CONTAINER_H_ |
| OLD | NEW |