Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(821)

Side by Side Diff: ash/launcher/overflow_bubble.cc

Issue 23534023: ash: Minor cleanup, move more files from launcher to shelf. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/launcher/overflow_bubble.h ('k') | ash/launcher/overflow_button.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/launcher/overflow_bubble.h"
6
7 #include <algorithm>
8
9 #include "ash/launcher/launcher_types.h"
10 #include "ash/launcher/launcher_view.h"
11 #include "ash/root_window_controller.h"
12 #include "ash/shelf/shelf_layout_manager.h"
13 #include "ash/shelf/shelf_widget.h"
14 #include "ash/shell.h"
15 #include "ash/system/tray/system_tray.h"
16 #include "ui/aura/root_window.h"
17 #include "ui/gfx/insets.h"
18 #include "ui/gfx/screen.h"
19 #include "ui/views/bubble/bubble_delegate.h"
20 #include "ui/views/bubble/bubble_frame_view.h"
21 #include "ui/views/widget/widget.h"
22
23 namespace ash {
24 namespace internal {
25
26 namespace {
27
28 // Max bubble size to screen size ratio.
29 const float kMaxBubbleSizeToScreenRatio = 0.5f;
30
31 // Inner padding in pixels for launcher view inside bubble.
32 const int kPadding = 2;
33
34 // Padding space in pixels between LauncherView's left/top edge to its contents.
35 const int kLauncherViewLeadingInset = 8;
36
37 ////////////////////////////////////////////////////////////////////////////////
38 // OverflowBubbleView
39 // OverflowBubbleView hosts a LauncherView to display overflown items.
40
41 class OverflowBubbleView : public views::BubbleDelegateView {
42 public:
43 OverflowBubbleView();
44 virtual ~OverflowBubbleView();
45
46 void InitOverflowBubble(views::View* anchor, LauncherView* launcher_view);
47
48 private:
49 bool IsHorizontalAlignment() const {
50 return GetShelfLayoutManagerForLauncher()->IsHorizontalAlignment();
51 }
52
53 const gfx::Size GetContentsSize() const {
54 return static_cast<views::View*>(launcher_view_)->GetPreferredSize();
55 }
56
57 // Gets arrow location based on shelf alignment.
58 views::BubbleBorder::Arrow GetBubbleArrow() const {
59 return GetShelfLayoutManagerForLauncher()->SelectValueForShelfAlignment(
60 views::BubbleBorder::BOTTOM_LEFT,
61 views::BubbleBorder::LEFT_TOP,
62 views::BubbleBorder::RIGHT_TOP,
63 views::BubbleBorder::TOP_LEFT);
64 }
65
66 void ScrollByXOffset(int x_offset);
67 void ScrollByYOffset(int y_offset);
68
69 // views::View overrides:
70 virtual gfx::Size GetPreferredSize() OVERRIDE;
71 virtual void Layout() OVERRIDE;
72 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
73 virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE;
74
75 // ui::EventHandler overrides:
76 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE;
77
78 // views::BubbleDelegate overrides:
79 virtual gfx::Rect GetBubbleBounds() OVERRIDE;
80
81 ShelfLayoutManager* GetShelfLayoutManagerForLauncher() const {
82 return ShelfLayoutManager::ForLauncher(
83 anchor_view()->GetWidget()->GetNativeView());
84 }
85
86 LauncherView* launcher_view_; // Owned by views hierarchy.
87 gfx::Vector2d scroll_offset_;
88
89 DISALLOW_COPY_AND_ASSIGN(OverflowBubbleView);
90 };
91
92 OverflowBubbleView::OverflowBubbleView()
93 : launcher_view_(NULL) {
94 }
95
96 OverflowBubbleView::~OverflowBubbleView() {
97 }
98
99 void OverflowBubbleView::InitOverflowBubble(views::View* anchor,
100 LauncherView* launcher_view) {
101 // set_anchor_view needs to be called before GetShelfLayoutManagerForLauncher
102 // can be called.
103 set_anchor_view(anchor);
104 set_arrow(GetBubbleArrow());
105 set_background(NULL);
106 set_color(SkColorSetARGB(kLauncherBackgroundAlpha, 0, 0, 0));
107 set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding));
108 set_move_with_anchor(true);
109
110 // Makes bubble view has a layer and clip its children layers.
111 SetPaintToLayer(true);
112 SetFillsBoundsOpaquely(false);
113 layer()->SetMasksToBounds(true);
114
115 launcher_view_ = launcher_view;
116 AddChildView(launcher_view_);
117
118 views::BubbleDelegateView::CreateBubble(this);
119 }
120
121 void OverflowBubbleView::ScrollByXOffset(int x_offset) {
122 const gfx::Rect visible_bounds(GetContentsBounds());
123 const gfx::Size contents_size(GetContentsSize());
124
125 int x = std::min(contents_size.width() - visible_bounds.width(),
126 std::max(0, scroll_offset_.x() + x_offset));
127 scroll_offset_.set_x(x);
128 }
129
130 void OverflowBubbleView::ScrollByYOffset(int y_offset) {
131 const gfx::Rect visible_bounds(GetContentsBounds());
132 const gfx::Size contents_size(GetContentsSize());
133
134 int y = std::min(contents_size.height() - visible_bounds.height(),
135 std::max(0, scroll_offset_.y() + y_offset));
136 scroll_offset_.set_y(y);
137 }
138
139 gfx::Size OverflowBubbleView::GetPreferredSize() {
140 gfx::Size preferred_size = GetContentsSize();
141
142 const gfx::Rect monitor_rect = Shell::GetScreen()->GetDisplayNearestPoint(
143 GetAnchorRect().CenterPoint()).work_area();
144 if (!monitor_rect.IsEmpty()) {
145 if (IsHorizontalAlignment()) {
146 preferred_size.set_width(std::min(
147 preferred_size.width(),
148 static_cast<int>(monitor_rect.width() *
149 kMaxBubbleSizeToScreenRatio)));
150 } else {
151 preferred_size.set_height(std::min(
152 preferred_size.height(),
153 static_cast<int>(monitor_rect.height() *
154 kMaxBubbleSizeToScreenRatio)));
155 }
156 }
157
158 return preferred_size;
159 }
160
161 void OverflowBubbleView::Layout() {
162 launcher_view_->SetBoundsRect(gfx::Rect(
163 gfx::PointAtOffsetFromOrigin(-scroll_offset_), GetContentsSize()));
164 }
165
166 void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) {
167 // Ensures |launch_view_| is still visible.
168 ScrollByXOffset(0);
169 ScrollByYOffset(0);
170 Layout();
171
172 SizeToContents();
173 }
174
175 bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) {
176 // The MouseWheelEvent was changed to support both X and Y offsets
177 // recently, but the behavior of this function was retained to continue
178 // using Y offsets only. Might be good to simply scroll in both
179 // directions as in OverflowBubbleView::OnScrollEvent.
180 if (IsHorizontalAlignment())
181 ScrollByXOffset(-event.y_offset());
182 else
183 ScrollByYOffset(-event.y_offset());
184 Layout();
185
186 return true;
187 }
188
189 void OverflowBubbleView::OnScrollEvent(ui::ScrollEvent* event) {
190 ScrollByXOffset(-event->x_offset());
191 ScrollByYOffset(-event->y_offset());
192 Layout();
193 event->SetHandled();
194 }
195
196 gfx::Rect OverflowBubbleView::GetBubbleBounds() {
197 views::BubbleBorder* border = GetBubbleFrameView()->bubble_border();
198 gfx::Insets bubble_insets = border->GetInsets();
199
200 const int border_size =
201 views::BubbleBorder::is_arrow_on_horizontal(arrow()) ?
202 bubble_insets.left() : bubble_insets.top();
203 const int arrow_offset = border_size + kPadding + kLauncherViewLeadingInset +
204 ShelfLayoutManager::GetPreferredShelfSize() / 2;
205
206 const gfx::Size content_size = GetPreferredSize();
207 border->set_arrow_offset(arrow_offset);
208
209 const gfx::Rect anchor_rect = GetAnchorRect();
210 gfx::Rect bubble_rect = GetBubbleFrameView()->GetUpdatedWindowBounds(
211 anchor_rect,
212 content_size,
213 false);
214
215 gfx::Rect monitor_rect = Shell::GetScreen()->GetDisplayNearestPoint(
216 anchor_rect.CenterPoint()).work_area();
217
218 int offset = 0;
219 if (views::BubbleBorder::is_arrow_on_horizontal(arrow())) {
220 if (bubble_rect.x() < monitor_rect.x())
221 offset = monitor_rect.x() - bubble_rect.x();
222 else if (bubble_rect.right() > monitor_rect.right())
223 offset = monitor_rect.right() - bubble_rect.right();
224
225 bubble_rect.Offset(offset, 0);
226 border->set_arrow_offset(anchor_rect.CenterPoint().x() - bubble_rect.x());
227 } else {
228 if (bubble_rect.y() < monitor_rect.y())
229 offset = monitor_rect.y() - bubble_rect.y();
230 else if (bubble_rect.bottom() > monitor_rect.bottom())
231 offset = monitor_rect.bottom() - bubble_rect.bottom();
232
233 bubble_rect.Offset(0, offset);
234 border->set_arrow_offset(anchor_rect.CenterPoint().y() - bubble_rect.y());
235 }
236
237 GetBubbleFrameView()->SchedulePaint();
238 return bubble_rect;
239 }
240
241 } // namespace
242
243 OverflowBubble::OverflowBubble()
244 : bubble_(NULL),
245 launcher_view_(NULL) {
246 }
247
248 OverflowBubble::~OverflowBubble() {
249 Hide();
250 }
251
252 void OverflowBubble::Show(views::View* anchor, LauncherView* launcher_view) {
253 Hide();
254
255 OverflowBubbleView* bubble_view = new OverflowBubbleView();
256 bubble_view->InitOverflowBubble(anchor, launcher_view);
257 launcher_view_ = launcher_view;
258
259 bubble_ = bubble_view;
260 RootWindowController::ForWindow(anchor->GetWidget()->GetNativeView())->
261 GetSystemTray()->InitializeBubbleAnimations(bubble_->GetWidget());
262 bubble_->GetWidget()->AddObserver(this);
263 bubble_->GetWidget()->Show();
264 }
265
266 void OverflowBubble::Hide() {
267 if (!IsShowing())
268 return;
269
270 bubble_->GetWidget()->RemoveObserver(this);
271 bubble_->GetWidget()->Close();
272 bubble_ = NULL;
273 launcher_view_ = NULL;
274 }
275
276 void OverflowBubble::OnWidgetDestroying(views::Widget* widget) {
277 DCHECK(widget == bubble_->GetWidget());
278 bubble_ = NULL;
279 launcher_view_ = NULL;
280 ShelfLayoutManager::ForLauncher(
281 widget->GetNativeView())->shelf_widget()->launcher()->SchedulePaint();
282 }
283
284 } // namespace internal
285 } // namespace ash
OLDNEW
« no previous file with comments | « ash/launcher/overflow_bubble.h ('k') | ash/launcher/overflow_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698