summaryrefslogtreecommitdiff
path: root/chromium/ash/shelf/shelf_view.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/shelf/shelf_view.h')
-rw-r--r--chromium/ash/shelf/shelf_view.h458
1 files changed, 458 insertions, 0 deletions
diff --git a/chromium/ash/shelf/shelf_view.h b/chromium/ash/shelf/shelf_view.h
new file mode 100644
index 00000000000..1f090e612a4
--- /dev/null
+++ b/chromium/ash/shelf/shelf_view.h
@@ -0,0 +1,458 @@
+// Copyright (c) 2012 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.
+
+#ifndef ASH_SHELF_SHELF_VIEW_H_
+#define ASH_SHELF_SHELF_VIEW_H_
+
+#include <utility>
+#include <vector>
+
+#include "ash/shelf/shelf_button_host.h"
+#include "ash/shelf/shelf_model_observer.h"
+#include "ash/wm/gestures/shelf_gesture_handler.h"
+#include "base/observer_list.h"
+#include "ui/app_list/views/app_list_drag_and_drop_host.h"
+#include "ui/views/animation/bounds_animator_observer.h"
+#include "ui/views/context_menu_controller.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/focus/focus_manager.h"
+#include "ui/views/view.h"
+
+namespace views {
+class BoundsAnimator;
+class MenuModelAdapter;
+class MenuRunner;
+class ViewModel;
+}
+
+namespace ash {
+
+namespace test {
+class ShelfViewTestAPI;
+}
+
+class ShelfDelegate;
+class ShelfIconObserver;
+class ShelfItemDelegateManager;
+class ShelfModel;
+struct LauncherItem;
+
+namespace internal {
+
+class DragImageView;
+class OverflowBubble;
+class OverflowButton;
+class ShelfButton;
+class ShelfLayoutManager;
+class ShelfTooltipManager;
+
+extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM;
+extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT;
+extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT;
+extern const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT;
+
+class ASH_EXPORT ShelfView : public views::View,
+ public ShelfModelObserver,
+ public views::ButtonListener,
+ public ShelfButtonHost,
+ public views::ContextMenuController,
+ public views::FocusTraversable,
+ public views::BoundsAnimatorObserver,
+ public app_list::ApplicationDragAndDropHost {
+ public:
+ ShelfView(ShelfModel* model,
+ ShelfDelegate* delegate,
+ ShelfLayoutManager* manager);
+ virtual ~ShelfView();
+
+ ShelfTooltipManager* tooltip_manager() { return tooltip_.get(); }
+
+ ShelfLayoutManager* shelf_layout_manager() { return layout_manager_; }
+
+ ShelfModel* model() { return model_; }
+
+ void Init();
+
+ void OnShelfAlignmentChanged();
+ void SchedulePaintForAllButtons();
+
+ // Returns the ideal bounds of the specified item, or an empty rect if id
+ // isn't know.
+ gfx::Rect GetIdealBoundsOfItemIcon(LauncherID id);
+
+ // Repositions the icon for the specified item by the midpoint of the window.
+ void UpdatePanelIconPosition(LauncherID id, const gfx::Point& midpoint);
+
+ void AddIconObserver(ShelfIconObserver* observer);
+ void RemoveIconObserver(ShelfIconObserver* observer);
+
+ // Returns true if we're showing a menu.
+ bool IsShowingMenu() const;
+
+ // Returns true if overflow bubble is shown.
+ bool IsShowingOverflowBubble() const;
+
+ // Sets owner overflow bubble instance from which this shelf view pops
+ // out as overflow.
+ void set_owner_overflow_bubble(OverflowBubble* owner) {
+ owner_overflow_bubble_ = owner;
+ }
+
+ views::View* GetAppListButtonView() const;
+
+ // Returns true if the mouse cursor exits the area for launcher tooltip.
+ // There are thin gaps between launcher buttons but the tooltip shouldn't hide
+ // in the gaps, but the tooltip should hide if the mouse moved totally outside
+ // of the buttons area.
+ bool ShouldHideTooltip(const gfx::Point& cursor_location);
+
+ // Returns rectangle bounding all visible launcher items. Used screen
+ // coordinate system.
+ gfx::Rect GetVisibleItemsBoundsInScreen();
+
+ // Overridden from FocusTraversable:
+ virtual views::FocusSearch* GetFocusSearch() OVERRIDE;
+ virtual FocusTraversable* GetFocusTraversableParent() OVERRIDE;
+ virtual View* GetFocusTraversableParentView() OVERRIDE;
+
+ // Overridden from app_list::ApplicationDragAndDropHost:
+ virtual void CreateDragIconProxy(
+ const gfx::Point& location_in_screen_coordinates,
+ const gfx::ImageSkia& icon,
+ views::View* replaced_view,
+ const gfx::Vector2d& cursor_offset_from_center,
+ float scale_factor) OVERRIDE;
+ virtual void UpdateDragIconProxy(
+ const gfx::Point& location_in_screen_coordinates) OVERRIDE;
+ virtual void DestroyDragIconProxy() OVERRIDE;
+ virtual bool StartDrag(
+ const std::string& app_id,
+ const gfx::Point& location_in_screen_coordinates) OVERRIDE;
+ virtual bool Drag(const gfx::Point& location_in_screen_coordinates) OVERRIDE;
+ virtual void EndDrag(bool cancel) OVERRIDE;
+
+ // Return the view model for test purposes.
+ const views::ViewModel* const view_model_for_test() const {
+ return view_model_.get();
+ }
+
+ private:
+ friend class ash::test::ShelfViewTestAPI;
+
+ class FadeOutAnimationDelegate;
+ class StartFadeAnimationDelegate;
+
+ struct IdealBounds {
+ gfx::Rect overflow_bounds;
+ };
+
+ enum RemovableState {
+ REMOVABLE, // Item can be removed when dragged away.
+ DRAGGABLE, // Item can be dragged, but will snap always back to origin.
+ NOT_REMOVABLE, // Item is fixed and can never be removed.
+ };
+
+ // Returns true when this ShelfView is used for Overflow Bubble.
+ // In this mode, it does not show app list, panel and overflow button.
+ // Note:
+ // * When Shelf can contain only one item (overflow button) due to very
+ // small resolution screen, overflow bubble can show app list and panel
+ // button.
+ bool is_overflow_mode() const { return overflow_mode_; }
+
+ bool dragging() const {
+ return drag_pointer_ != NONE;
+ }
+
+ // Sets the bounds of each view to its ideal bounds.
+ void LayoutToIdealBounds();
+
+ // Update all button's visibility in overflow.
+ void UpdateAllButtonsVisibilityInOverflowMode();
+
+ // Calculates the ideal bounds. The bounds of each button corresponding to an
+ // item in the model is set in |view_model_|.
+ void CalculateIdealBounds(IdealBounds* bounds);
+
+ // Returns the index of the last view whose max primary axis coordinate is
+ // less than |max_value|. Returns -1 if nothing fits, or there are no views.
+ int DetermineLastVisibleIndex(int max_value) const;
+
+ // Returns the index of the first panel whose min primary axis coordinate is
+ // at least |min_value|. Returns the index past the last panel if none fit.
+ int DetermineFirstVisiblePanelIndex(int min_value) const;
+
+ // Animates the bounds of each view to its ideal bounds.
+ void AnimateToIdealBounds();
+
+ // Creates the view used to represent |item|.
+ views::View* CreateViewForItem(const LauncherItem& item);
+
+ // Fades |view| from an opacity of 0 to 1. This is when adding a new item.
+ void FadeIn(views::View* view);
+
+ // Invoked when the pointer has moved enough to trigger a drag. Sets
+ // internal state in preparation for the drag.
+ void PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event);
+
+ // Invoked when the mouse is dragged. Updates the models as appropriate.
+ void ContinueDrag(const ui::LocatedEvent& event);
+
+ // Handles ripping off an item from the shelf. Returns true when the item got
+ // removed.
+ bool HandleRipOffDrag(const ui::LocatedEvent& event);
+
+ // Finalize the rip off dragging by either |cancel| the action or validating.
+ void FinalizeRipOffDrag(bool cancel);
+
+ // Check if an item can be ripped off or not.
+ RemovableState RemovableByRipOff(int index);
+
+ // Returns true if |typea| and |typeb| should be in the same drag range.
+ bool SameDragType(LauncherItemType typea, LauncherItemType typeb) const;
+
+ // Returns the range (in the model) the item at the specified index can be
+ // dragged to.
+ std::pair<int, int> GetDragRange(int index);
+
+ // If there is a drag operation in progress it's canceled. If |modified_index|
+ // is valid, the new position of the corresponding item is returned.
+ int CancelDrag(int modified_index);
+
+ // Returns rectangle bounds used for drag insertion.
+ // Note:
+ // * When overflow button is visible, returns bounds from first item
+ // to overflow button.
+ // * When overflow button is visible and one or more panel items exists,
+ // returns bounds from first item to last panel item.
+ // * In the overflow mode, returns only bubble's bounds.
+ gfx::Rect GetBoundsForDragInsertInScreen();
+
+ // Common setup done for all children.
+ void ConfigureChildView(views::View* view);
+
+ // Toggles the overflow menu.
+ void ToggleOverflowBubble();
+
+ // Update first launcher button's padding. This method adds padding to the
+ // first button to include the leading inset. It needs to be called once on
+ // button creation and every time when shelf alignment is changed.
+ void UpdateFirstButtonPadding();
+
+ // Invoked after the fading out animation for item deletion is ended.
+ void OnFadeOutAnimationEnded();
+
+ // Fade in last visible item.
+ void StartFadeInLastVisibleItem();
+
+ // Updates the visible range of overflow items in |overflow_view|.
+ void UpdateOverflowRange(ShelfView* overflow_view);
+
+ // Returns the launcher button size.
+ int GetButtonSize() const;
+
+ // Returns the button spacing.
+ int GetButtonSpacing() const;
+
+ // Overridden from views::View:
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
+ virtual FocusTraversable* GetPaneFocusTraversable() OVERRIDE;
+ virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+
+ // Overridden from ui::EventHandler:
+ virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
+
+ // Overridden from ShelfModelObserver:
+ virtual void ShelfItemAdded(int model_index) OVERRIDE;
+ virtual void ShelfItemRemoved(int model_index, LauncherID id) OVERRIDE;
+ virtual void ShelfItemChanged(int model_index,
+ const LauncherItem& old_item) OVERRIDE;
+ virtual void ShelfItemMoved(int start_index, int target_index) OVERRIDE;
+ virtual void ShelfStatusChanged() OVERRIDE;
+
+ // Overridden from ShelfButtonHost:
+ virtual void PointerPressedOnButton(views::View* view,
+ Pointer pointer,
+ const ui::LocatedEvent& event) OVERRIDE;
+ virtual void PointerDraggedOnButton(views::View* view,
+ Pointer pointer,
+ const ui::LocatedEvent& event) OVERRIDE;
+ virtual void PointerReleasedOnButton(views::View* view,
+ Pointer pointer,
+ bool canceled) OVERRIDE;
+ virtual void MouseMovedOverButton(views::View* view) OVERRIDE;
+ virtual void MouseEnteredButton(views::View* view) OVERRIDE;
+ virtual void MouseExitedButton(views::View* view) OVERRIDE;
+ virtual base::string16 GetAccessibleName(const views::View* view) OVERRIDE;
+
+ // Overridden from views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender,
+ const ui::Event& event) OVERRIDE;
+
+ // Show the list of all running items for this |item|. It will return true
+ // when the menu was shown and false if there were no possible items to
+ // choose from. |source| specifies the view which is responsible for showing
+ // the menu, and the bubble will point towards it.
+ // The |event_flags| are the flags of the event which triggered this menu.
+ bool ShowListMenuForView(const LauncherItem& item,
+ views::View* source,
+ const ui::Event& event);
+
+ // Overridden from views::ContextMenuController:
+ virtual void ShowContextMenuForView(views::View* source,
+ const gfx::Point& point,
+ ui::MenuSourceType source_type) OVERRIDE;
+
+ // Show either a context or normal click menu of given |menu_model_adapter|.
+ // If |context_menu| is set, the displayed menu is a context menu and not
+ // a menu listing one or more running applications.
+ // The |click_point| is only used for |context_menu|'s.
+ void ShowMenu(scoped_ptr<views::MenuModelAdapter> menu_model_adapter,
+ views::View* source,
+ const gfx::Point& click_point,
+ bool context_menu,
+ ui::MenuSourceType source_type);
+
+ // Overridden from views::BoundsAnimatorObserver:
+ virtual void OnBoundsAnimatorProgressed(
+ views::BoundsAnimator* animator) OVERRIDE;
+ virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE;
+
+ // Returns false if the click which closed the previous menu is the click
+ // which triggered this event.
+ bool IsUsableEvent(const ui::Event& event);
+
+ // Convenience accessor to model_->items().
+ const LauncherItem* LauncherItemForView(const views::View* view) const;
+
+ // Returns true if a tooltip should be shown for |view|.
+ bool ShouldShowTooltipForView(const views::View* view) const;
+
+ // Get the distance from the given |coordinate| to the closest point on this
+ // launcher/shelf.
+ int CalculateShelfDistance(const gfx::Point& coordinate) const;
+
+ // The model; owned by Launcher.
+ ShelfModel* model_;
+
+ // Delegate; owned by Launcher.
+ ShelfDelegate* delegate_;
+
+ // Used to manage the set of active launcher buttons. There is a view per
+ // item in |model_|.
+ scoped_ptr<views::ViewModel> view_model_;
+
+ // Index of first visible launcher item.
+ int first_visible_index_;
+
+ // Last index of a launcher button that is visible
+ // (does not go into overflow).
+ int last_visible_index_;
+
+ scoped_ptr<views::BoundsAnimator> bounds_animator_;
+
+ OverflowButton* overflow_button_;
+
+ scoped_ptr<OverflowBubble> overflow_bubble_;
+
+ OverflowBubble* owner_overflow_bubble_;
+
+ scoped_ptr<ShelfTooltipManager> tooltip_;
+
+ // Pointer device that initiated the current drag operation. If there is no
+ // current dragging operation, this is NONE.
+ Pointer drag_pointer_;
+
+ // The view being dragged. This is set immediately when the mouse is pressed.
+ // |dragging_| is set only if the mouse is dragged far enough.
+ views::View* drag_view_;
+
+ // X coordinate of the mouse down event in |drag_view_|s coordinates.
+ int drag_offset_;
+
+ // Index |drag_view_| was initially at.
+ int start_drag_index_;
+
+ // Used for the context menu of a particular item.
+ LauncherID context_menu_id_;
+
+ scoped_ptr<views::FocusSearch> focus_search_;
+
+ scoped_ptr<views::MenuRunner> launcher_menu_runner_;
+
+ ObserverList<ShelfIconObserver> observers_;
+
+ // Amount content is inset on the left edge (or top edge for vertical
+ // alignment).
+ int leading_inset_;
+
+ ShelfGestureHandler gesture_handler_;
+
+ // True when an item being inserted or removed in the model cancels a drag.
+ bool cancelling_drag_model_changed_;
+
+ // Index of the last hidden launcher item. If there are no hidden items this
+ // will be equal to last_visible_index_ + 1.
+ int last_hidden_index_;
+
+ // The timestamp of the event which closed the last menu - or 0.
+ base::TimeDelta closing_event_time_;
+
+ // When this object gets deleted while a menu is shown, this pointed
+ // element will be set to false.
+ bool* got_deleted_;
+
+ // True if a drag and drop operation created/pinned the item in the launcher
+ // and it needs to be deleted/unpinned again if the operation gets cancelled.
+ bool drag_and_drop_item_pinned_;
+
+ // The launcher item which is currently used for a drag and a drop operation
+ // or 0 otherwise.
+ LauncherID drag_and_drop_launcher_id_;
+
+ // The application ID of the application which we drag and drop.
+ std::string drag_and_drop_app_id_;
+
+ // The original launcher item's size before the dragging operation.
+ gfx::Size pre_drag_and_drop_size_;
+
+ // The image proxy for drag operations when a drag and drop host exists and
+ // the item can be dragged outside the app grid.
+ scoped_ptr<ash::internal::DragImageView> drag_image_;
+
+ // The cursor offset to the middle of the dragged item.
+ gfx::Vector2d drag_image_offset_;
+
+ // The view which gets replaced by our drag icon proxy.
+ views::View* drag_replaced_view_;
+
+ // True when the icon was dragged off the shelf.
+ bool dragged_off_shelf_;
+
+ // The rip off view when a snap back operation is underway.
+ views::View* snap_back_from_rip_off_view_;
+
+ // Holds ShelfItemDelegateManager.
+ ShelfItemDelegateManager* item_manager_;
+
+ // Holds ShelfLayoutManager.
+ ShelfLayoutManager* layout_manager_;
+
+ // True when this ShelfView is used for Overflow Bubble.
+ bool overflow_mode_;
+
+ // Holds a pointer to main ShelfView when a ShelfView is in overflow mode.
+ ShelfView* main_shelf_;
+
+ // True when ripped item from overflow bubble is entered into Shelf.
+ bool dragged_off_from_overflow_to_shelf_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShelfView);
+};
+
+} // namespace internal
+} // namespace ash
+
+#endif // ASH_SHELF_SHELF_VIEW_H_