summaryrefslogtreecommitdiffstats
path: root/ash/launcher/launcher_view.h
blob: 50f7cd6f4c4b39dd70438b978c1c7f6c1261e584 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// 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_LAUNCHER_LAUNCHER_VIEW_H_
#define ASH_LAUNCHER_LAUNCHER_VIEW_H_
#pragma once

#include <utility>
#include <vector>

#include "ash/launcher/launcher_button_host.h"
#include "ash/launcher/launcher_model_observer.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"

namespace views {
class BoundsAnimator;
class ImageButton;
class MenuRunner;
}

namespace ash {

class LauncherDelegate;
struct LauncherItem;
class LauncherModel;
class ViewModel;

namespace internal {

class LauncherButton;

class ASH_EXPORT LauncherView : public views::View,
                                public LauncherModelObserver,
                                public views::ButtonListener,
                                public LauncherButtonHost,
                                public views::ContextMenuController {
 public:
  // Use the api in this class for testing only.
  class ASH_EXPORT TestAPI {
   public:
    explicit TestAPI(LauncherView* launcher_view)
        : launcher_view_(launcher_view) {
    }
    // Number of icons displayed.
    int GetButtonCount();
    // Retrieve the button at |index|.
    LauncherButton* GetButton(int index);

   private:
    LauncherView* launcher_view_;

    DISALLOW_COPY_AND_ASSIGN(TestAPI);
  };

  LauncherView(LauncherModel* model, LauncherDelegate* delegate);
  virtual ~LauncherView();

  void Init();

  // Returns the ideal bounds of the specified item, or an empty rect if id
  // isn't know.
  gfx::Rect GetIdealBoundsOfItemIcon(LauncherID id);

 private:
  class FadeOutAnimationDelegate;
  class StartFadeAnimationDelegate;

  struct IdealBounds {
    gfx::Rect overflow_bounds;
  };

  // Sets the bounds of each view to its ideal bounds.
  void LayoutToIdealBounds();

  // 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 x-coordinate is less than
  // |max_x|. Returns -1 if nothing fits, or there are no views.
  int DetermineLastVisibleIndex(int max_x);

  // 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 mouse has moved enough to trigger a drag. Sets internal
  // state in preparation for the drag.
  void PrepareForDrag(const views::MouseEvent& event);

  // Invoked when the mouse is dragged. Updates the models as appropriate.
  void ContinueDrag(const views::MouseEvent& event);

  // 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.
  void CancelDrag(views::View* deleted_view);

  // Common setup done for all children.
  void ConfigureChildView(views::View* view);

  // Returns the items whose icons are not shown because they don't fit.
  void GetOverflowItems(std::vector<LauncherItem>* items);

  // Shows the overflow menu.
  void ShowOverflowMenu();

  // Overridden from views::View:
  virtual gfx::Size GetPreferredSize() OVERRIDE;
  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;

  // Overridden from LauncherModelObserver:
  virtual void LauncherItemAdded(int model_index) OVERRIDE;
  virtual void LauncherItemRemoved(int model_index, LauncherID id) OVERRIDE;
  virtual void LauncherItemChanged(int model_index,
                                   const ash::LauncherItem& old_item) OVERRIDE;
  virtual void LauncherItemMoved(int start_index, int target_index) OVERRIDE;
  virtual void LauncherItemWillChange(int index) OVERRIDE;

  // Overridden from LauncherButtonHost:
  virtual void MousePressedOnButton(views::View* view,
                                    const views::MouseEvent& event) OVERRIDE;
  virtual void MouseDraggedOnButton(views::View* view,
                                    const views::MouseEvent& event) OVERRIDE;
  virtual void MouseReleasedOnButton(views::View* view,
                                     bool canceled) OVERRIDE;
  virtual void MouseExitedButton(views::View* view) OVERRIDE;
  virtual string16 GetAccessibleName(const views::View* view) OVERRIDE;

  // Overriden from views::ButtonListener:
  virtual void ButtonPressed(views::Button* sender,
                             const views::Event& event) OVERRIDE;

  // Overriden from views::ContextMenuController:
  virtual void ShowContextMenuForView(views::View* source,
                                      const gfx::Point& point) OVERRIDE;

  // The model; owned by Launcher.
  LauncherModel* model_;

  // Delegate; owned by Launcher.
  LauncherDelegate* delegate_;

  // Used to manage the set of active launcher buttons. There is a view per
  // item in |model_|.
  scoped_ptr<ViewModel> view_model_;

  scoped_ptr<views::BoundsAnimator> bounds_animator_;

  views::ImageButton* overflow_button_;

  // Are we dragging? This is only set if the mouse is dragged far enough to
  // trigger a drag.
  bool dragging_;

  // 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_;

#if !defined(OS_MACOSX)
  scoped_ptr<views::MenuRunner> overflow_menu_runner_;

  scoped_ptr<views::MenuRunner> launcher_menu_runner_;
#endif

  DISALLOW_COPY_AND_ASSIGN(LauncherView);
};

}  // namespace internal
}  // namespace ash

#endif  // ASH_LAUNCHER_LAUNCHER_VIEW_H_