summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/browser_actions_container.h
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-22 22:00:09 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-22 22:00:09 +0000
commitbd5a00a743c92290ec01d6ea603a5fd96098093e (patch)
treee2db07ba7b8f7e75911e5dede215bb9551216450 /chrome/browser/views/browser_actions_container.h
parenta26b7d4950c1e684ab1620674a335ff3a27eda5c (diff)
downloadchromium_src-bd5a00a743c92290ec01d6ea603a5fd96098093e.zip
chromium_src-bd5a00a743c92290ec01d6ea603a5fd96098093e.tar.gz
chromium_src-bd5a00a743c92290ec01d6ea603a5fd96098093e.tar.bz2
Resize and overflow for browser actions (part 1).
This changelist implements the following: - A resize gripper and chevron in the browser action container - Overflow when icons don't fit - Snap to multiple of icon size (no excess pixels) - Animation when resizing container / adding&removing icons (disable, enable). - Persists the last width of the browser action container. Known issues: - No menu (yes, the chevron button doesn't do anything yet). BUG=32101 TEST=Install and uninstall browser actions & make sure install bubble appears in the right location. Make sure browser action container does not expand if chevron is showing when you add browser action. Make sure container loses chevron when no overflow occurs. Make sure browser action icons never disappear due to shrinking when you release the mouse (when resizing). Make sure snapping works. Review URL: http://codereview.chromium.org/553039 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36905 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/browser_actions_container.h')
-rw-r--r--chrome/browser/views/browser_actions_container.h159
1 files changed, 145 insertions, 14 deletions
diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h
index 7a6daf3..d2b87a4 100644
--- a/chrome/browser/views/browser_actions_container.h
+++ b/chrome/browser/views/browser_actions_container.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,13 +14,17 @@
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "views/controls/button/menu_button.h"
+#include "views/controls/menu/view_menu_delegate.h"
+#include "views/controls/resize_gripper.h"
#include "views/view.h"
class BrowserActionsContainer;
class Extension;
class ExtensionAction;
class ExtensionPopup;
+class PrefService;
class Profile;
+class SlideAnimation;
class ToolbarView;
////////////////////////////////////////////////////////////////////////////////
@@ -132,26 +136,103 @@ class BrowserActionView : public views::View {
BrowserActionButton* button_;
};
-
////////////////////////////////////////////////////////////////////////////////
//
// The BrowserActionsContainer is a container view, responsible for drawing the
-// icons that represent browser actions (extensions that add icons to the
-// toolbar).
+// browser action icons (extensions that add icons to the toolbar).
+//
+// The BrowserActionsContainer (when it contains one or more icons) consists of
+// the following elements, numbered as seen below the line:
+//
+// || _ Icon _ Icon _ Icon _ [chevron] _ | _
+// -----------------------------------------
+// 1 2 3 4 5 6 7 8
+//
+// 1) The ResizeGripper view.
+// 2) Padding (kHorizontalPadding).
+// 3) The browser action icon button (BrowserActionView).
+// 4) Padding to visually separate icons from one another
+// (kBrowserActionButtonPadding). Not included if only one icon visible.
+// 5) The chevron menu (MenuButton), shown when there is not enough room to show
+// all the icons.
+// 6) Padding (kDividerHorizontalMargin).
+// 7) A thin vertical divider drawn during Paint to create visual separation for
+// the container from the Page and Wrench menus.
+// 8) Padding (kChevronRightMargin).
+//
+// The BrowserActionsContainer follows a few rules, in terms of user experience:
+//
+// 1) The container can never grow beyond the space needed to show all icons
+// (hereby referred to as the max width).
+// 2) The container can never shrink below the space needed to show just the
+// resize gripper and the chevron (ignoring the case where there are no icons to
+// show, in which case the container won't be visible anyway).
+// 3) The container snaps into place (to the pixel count that fits the visible
+// icons) to make sure there is no wasted space at the edges of the container.
+// 4) If the user adds or removes icons (read: installs/uninstalls browser
+// actions) we grow and shrink the container as needed - but ONLY if the
+// container was at max width to begin with.
+// 5) If the container is NOT at max width (has an overflow menu), we respect
+// that size when adding and removing icons and DON'T grow/shrink the container.
+// This means that new icons (which always appear at the far right) will show up
+// in the overflow menu. The install bubble for extensions points to the chevron
+// menu in this case.
+//
+// Resizing the BrowserActionsContainer:
+//
+// The ResizeGripper view sends OnResize messages to the BrowserActionsContainer
+// class as the user drags the gripper. This modifies the value for
+// |resize_amount_|. That indicates to the container that a resize is in
+// progress and is used to calculate the size in GetPreferredSize(), though
+// that function never exceeds the defined minimum and maximum size of the
+// container.
+//
+// When the user releases the mouse (ends the resize), we calculate a target
+// size for the container (animation_target_size_), clamp that value to the
+// containers min and max and then animate from the *current* position (that the
+// user has dragged the view to) to the target size.
+//
+// Animating the BrowserActionsContainer:
+//
+// Animations are used when snapping the container to a value that fits all
+// visible icons. This can be triggered when the user finishes resizing the
+// container or when Browser Actions are added/removed.
+//
+// We always animate from the current width (container_size_.width()) to the
+// target size (animation_target_size_), using |resize_amount| to keep track of
+// the animation progress.
+//
+// NOTE: When adding Browser Actions to a maximum width container (no overflow)
+// we make sure to suppress the chevron menu if it wasn't visible. This is
+// because we won't have enough space to show the new Browser Action until the
+// animation ends and we don't want the chevron to flash into view while we are
+// growing the container.
//
////////////////////////////////////////////////////////////////////////////////
-class BrowserActionsContainer : public views::View,
- public NotificationObserver,
- public BrowserBubble::Delegate {
+class BrowserActionsContainer
+ : public views::View,
+ public NotificationObserver,
+ public BrowserBubble::Delegate,
+ public views::ViewMenuDelegate,
+ public views::ResizeGripper::ResizeGripperDelegate,
+ public AnimationDelegate {
public:
BrowserActionsContainer(Profile* profile, ToolbarView* toolbar);
virtual ~BrowserActionsContainer();
+ static void RegisterUserPrefs(PrefService* prefs);
+
// Get the number of browser actions being displayed.
- int num_browser_actions() { return browser_action_views_.size(); }
+ int num_browser_actions() const { return browser_action_views_.size(); }
+
+ // Whether we are performing resize animation on the container.
+ bool animating() const { return animation_target_size_ > 0; }
+
+ // Returns the chevron, if any.
+ const views::View* chevron() const { return chevron_; }
// Returns the current tab's ID, or -1 if there is no current tab.
- int GetCurrentTabId();
+ int GetCurrentTabId() const;
// Get a particular browser action view.
BrowserActionView* GetBrowserActionViewAt(int index) {
@@ -176,6 +257,10 @@ class BrowserActionsContainer : public views::View,
// Overridden from views::View:
virtual gfx::Size GetPreferredSize();
virtual void Layout();
+ virtual void Paint(gfx::Canvas* canvas);
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,
@@ -189,11 +274,15 @@ class BrowserActionsContainer : public views::View,
virtual void BubbleLostFocus(BrowserBubble* bubble,
gfx::NativeView focused_view);
- // Get clipped width required to precisely fit the browser action icons
- // given a tentative available width. The minimum size it returns is not
- // zero, but depends on the minimum number of icons that have to be there
- // by default irrespective of the available space to draw them.
- int GetClippedPreferredWidth(int available_width);
+ // Overridden from views::ViewMenuDelegate:
+ virtual void RunMenu(View* source, const gfx::Point& pt);
+
+ // Overridden from ResizeGripper::ResizeGripperDelegate:
+ virtual void OnResize(int resize_amount, bool done_resizing);
+
+ // Overridden from AnimationDelegate:
+ virtual void AnimationProgressed(const Animation* animation);
+ virtual void AnimationEnded(const Animation* animation);
// Hide the current popup.
void HidePopup();
@@ -214,6 +303,24 @@ class BrowserActionsContainer : public views::View,
// no such view.
void RemoveBrowserAction(Extension* extension);
+ // Takes a width in pixels, calculates how many icons fit within that space
+ // (up to the maximum number of icons in our vector) and shaves off the
+ // excess pixels.
+ int ClampToNearestIconCount(int pixels) const;
+
+ // Calculates the width of the container area NOT used to show the icons (the
+ // controls to the left and to the right of the icons).
+ int WidthOfNonIconArea() const;
+
+ // Given a number of |icons| return the amount of pixels needed to draw it,
+ // including the controls (chevron if visible and resize gripper).
+ int IconCountToWidth(int icons) const;
+
+ // Returns the absolute minimum size you can shrink the container down to and
+ // still show it. We account for the chevron and the resize gripper, but not
+ // all the padding that we normally show if there are icons.
+ int ContainerMinSize() const;
+
// The vector of browser actions (icons/image buttons for each action).
std::vector<BrowserActionView*> browser_action_views_;
@@ -231,6 +338,30 @@ class BrowserActionsContainer : public views::View,
// from browser_action_views_).
BrowserActionButton* popup_button_;
+ // The current size of the container.
+ gfx::Size container_size_;
+
+ // The resize gripper for the container.
+ views::ResizeGripper* resize_gripper_;
+
+ // The chevron for accessing the overflow items.
+ views::MenuButton* chevron_;
+
+ // The animation that happens when the container snaps to place.
+ scoped_ptr<SlideAnimation> resize_animation_;
+
+ // Don't show the chevron while animating.
+ bool suppress_chevron_;
+
+ // This is used while the user is resizing (and when the animations are in
+ // progress) to know how wide the delta is between the current state and what
+ // we should draw.
+ int resize_amount_;
+
+ // Keeps track of the absolute pixel width the container should have when we
+ // are done animating.
+ int animation_target_size_;
+
ScopedRunnableMethodFactory<BrowserActionsContainer> task_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainer);