OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include "ash/launcher/overflow_bubble.h" | 5 #include "ash/launcher/overflow_bubble.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ash/launcher/launcher_types.h" | 9 #include "ash/launcher/launcher_types.h" |
10 #include "ash/launcher/launcher_view.h" | 10 #include "ash/launcher/launcher_view.h" |
11 #include "ash/system/tray/system_tray.h" | 11 #include "ash/system/tray/system_tray.h" |
12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
| 13 #include "ash/wm/shelf_layout_manager.h" |
13 #include "ui/gfx/insets.h" | 14 #include "ui/gfx/insets.h" |
14 #include "ui/gfx/screen.h" | 15 #include "ui/gfx/screen.h" |
15 #include "ui/views/bubble/bubble_delegate.h" | 16 #include "ui/views/bubble/bubble_delegate.h" |
16 #include "ui/views/bubble/bubble_frame_view.h" | 17 #include "ui/views/bubble/bubble_frame_view.h" |
17 #include "ui/views/widget/widget.h" | 18 #include "ui/views/widget/widget.h" |
18 | 19 |
19 namespace ash { | 20 namespace ash { |
20 namespace internal { | 21 namespace internal { |
21 | 22 |
22 namespace { | 23 namespace { |
23 | 24 |
24 // Max bubble size to screen size ratio. | 25 // Max bubble size to screen size ratio. |
25 const float kMaxBubbleSizeToScreenRatio = 0.5f; | 26 const float kMaxBubbleSizeToScreenRatio = 0.5f; |
26 | 27 |
27 // Inner padding in pixels for launcher view inside bubble. | 28 // Inner padding in pixels for launcher view inside bubble. |
28 const int kPadding = 2; | 29 const int kPadding = 2; |
29 | 30 |
30 // Padding space in pixels between LauncherView's left/top edge to its contents. | 31 // Padding space in pixels between LauncherView's left/top edge to its contents. |
31 const int kLauncherViewLeadingInset = 8; | 32 const int kLauncherViewLeadingInset = 8; |
32 | 33 |
33 // Gets arrow location based on shelf alignment. | |
34 views::BubbleBorder::ArrowLocation GetBubbleArrowLocation( | |
35 ShelfAlignment shelf_alignment) { | |
36 switch (shelf_alignment) { | |
37 case ash::SHELF_ALIGNMENT_BOTTOM: | |
38 return views::BubbleBorder::BOTTOM_LEFT; | |
39 case ash::SHELF_ALIGNMENT_LEFT: | |
40 return views::BubbleBorder::LEFT_TOP; | |
41 case ash::SHELF_ALIGNMENT_RIGHT: | |
42 return views::BubbleBorder::RIGHT_TOP; | |
43 default: | |
44 NOTREACHED() << "Unknown shelf alignment " << shelf_alignment; | |
45 return views::BubbleBorder::BOTTOM_LEFT; | |
46 } | |
47 } | |
48 | |
49 //////////////////////////////////////////////////////////////////////////////// | 34 //////////////////////////////////////////////////////////////////////////////// |
50 // OverflowBubbleView | 35 // OverflowBubbleView |
51 // OverflowBubbleView hosts a LauncherView to display overflown items. | 36 // OverflowBubbleView hosts a LauncherView to display overflown items. |
52 | 37 |
53 class OverflowBubbleView : public views::BubbleDelegateView { | 38 class OverflowBubbleView : public views::BubbleDelegateView { |
54 public: | 39 public: |
55 OverflowBubbleView(); | 40 OverflowBubbleView(); |
56 virtual ~OverflowBubbleView(); | 41 virtual ~OverflowBubbleView(); |
57 | 42 |
58 void InitOverflowBubble(LauncherDelegate* delegate, | 43 void InitOverflowBubble(LauncherDelegate* delegate, |
59 LauncherModel* model, | 44 LauncherModel* model, |
60 views::View* anchor, | 45 views::View* anchor, |
61 ShelfAlignment shelf_alignment, | |
62 int overflow_start_index); | 46 int overflow_start_index); |
63 | 47 |
64 private: | 48 private: |
65 bool is_horizontal_alignment() const { | 49 bool IsHorizontalAlignment() const { |
66 return shelf_alignment_ == SHELF_ALIGNMENT_BOTTOM; | 50 return GetShelfLayoutManagerForLauncher()->IsHorizontalAlignment(); |
67 } | 51 } |
68 | 52 |
69 const gfx::Size GetContentsSize() const { | 53 const gfx::Size GetContentsSize() const { |
70 return static_cast<views::View*>(launcher_view_)->GetPreferredSize(); | 54 return static_cast<views::View*>(launcher_view_)->GetPreferredSize(); |
71 } | 55 } |
72 | 56 |
| 57 // Gets arrow location based on shelf alignment. |
| 58 views::BubbleBorder::ArrowLocation GetBubbleArrowLocation() const { |
| 59 return GetShelfLayoutManagerForLauncher()->SelectValueForShelfAlignment( |
| 60 views::BubbleBorder::BOTTOM_LEFT, |
| 61 views::BubbleBorder::LEFT_TOP, |
| 62 views::BubbleBorder::RIGHT_TOP); |
| 63 } |
| 64 |
73 void ScrollByXOffset(int x_offset); | 65 void ScrollByXOffset(int x_offset); |
74 void ScrollByYOffset(int y_offset); | 66 void ScrollByYOffset(int y_offset); |
75 | 67 |
76 // views::View overrides: | 68 // views::View overrides: |
77 virtual gfx::Size GetPreferredSize() OVERRIDE; | 69 virtual gfx::Size GetPreferredSize() OVERRIDE; |
78 virtual void Layout() OVERRIDE; | 70 virtual void Layout() OVERRIDE; |
79 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; | 71 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; |
80 virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE; | 72 virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE; |
81 | 73 |
82 // ui::EventHandler overrides: | 74 // ui::EventHandler overrides: |
83 virtual ui::EventResult OnScrollEvent(ui::ScrollEvent* event) OVERRIDE; | 75 virtual ui::EventResult OnScrollEvent(ui::ScrollEvent* event) OVERRIDE; |
84 | 76 |
85 // views::BubbleDelegate overrides: | 77 // views::BubbleDelegate overrides: |
86 virtual gfx::Rect GetBubbleBounds() OVERRIDE; | 78 virtual gfx::Rect GetBubbleBounds() OVERRIDE; |
87 | 79 |
88 ShelfAlignment shelf_alignment_; | 80 ShelfLayoutManager* GetShelfLayoutManagerForLauncher() const { |
| 81 return ShelfLayoutManager::ForLauncher( |
| 82 anchor_view()->GetWidget()->GetNativeView()); |
| 83 } |
| 84 |
89 LauncherView* launcher_view_; // Owned by views hierarchy. | 85 LauncherView* launcher_view_; // Owned by views hierarchy. |
90 gfx::Vector2d scroll_offset_; | 86 gfx::Vector2d scroll_offset_; |
91 | 87 |
92 DISALLOW_COPY_AND_ASSIGN(OverflowBubbleView); | 88 DISALLOW_COPY_AND_ASSIGN(OverflowBubbleView); |
93 }; | 89 }; |
94 | 90 |
95 OverflowBubbleView::OverflowBubbleView() | 91 OverflowBubbleView::OverflowBubbleView() |
96 : shelf_alignment_(SHELF_ALIGNMENT_BOTTOM), | 92 : launcher_view_(NULL) { |
97 launcher_view_(NULL) { | |
98 } | 93 } |
99 | 94 |
100 OverflowBubbleView::~OverflowBubbleView() { | 95 OverflowBubbleView::~OverflowBubbleView() { |
101 } | 96 } |
102 | 97 |
103 void OverflowBubbleView::InitOverflowBubble(LauncherDelegate* delegate, | 98 void OverflowBubbleView::InitOverflowBubble(LauncherDelegate* delegate, |
104 LauncherModel* model, | 99 LauncherModel* model, |
105 views::View* anchor, | 100 views::View* anchor, |
106 ShelfAlignment shelf_alignment, | |
107 int overflow_start_index) { | 101 int overflow_start_index) { |
108 shelf_alignment_ = shelf_alignment; | |
109 | |
110 // Makes bubble view has a layer and clip its children layers. | 102 // Makes bubble view has a layer and clip its children layers. |
111 SetPaintToLayer(true); | 103 SetPaintToLayer(true); |
112 SetFillsBoundsOpaquely(false); | 104 SetFillsBoundsOpaquely(false); |
113 layer()->SetMasksToBounds(true); | 105 layer()->SetMasksToBounds(true); |
| 106 ShelfAlignment shelf_alignment = GetShelfLayoutManagerForLauncher()-> |
| 107 GetAlignment(); |
114 | 108 |
115 launcher_view_ = new LauncherView(model, delegate, NULL); | 109 launcher_view_ = new LauncherView(model, delegate, NULL); |
116 launcher_view_->set_first_visible_index(overflow_start_index); | 110 launcher_view_->set_first_visible_index(overflow_start_index); |
117 launcher_view_->set_leading_inset(kLauncherViewLeadingInset); | 111 launcher_view_->set_leading_inset(kLauncherViewLeadingInset); |
118 launcher_view_->Init(); | 112 launcher_view_->Init(); |
119 launcher_view_->SetAlignment(shelf_alignment); | 113 launcher_view_->SetAlignment(shelf_alignment); |
120 AddChildView(launcher_view_); | 114 AddChildView(launcher_view_); |
121 | 115 |
122 set_anchor_view(anchor); | 116 set_anchor_view(anchor); |
123 set_arrow_location(GetBubbleArrowLocation(shelf_alignment)); | 117 set_arrow_location(GetBubbleArrowLocation()); |
124 set_background(NULL); | 118 set_background(NULL); |
125 set_color(SkColorSetARGB(kLauncherBackgroundAlpha, 0, 0, 0)); | 119 set_color(SkColorSetARGB(kLauncherBackgroundAlpha, 0, 0, 0)); |
126 set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding)); | 120 set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding)); |
127 set_move_with_anchor(true); | 121 set_move_with_anchor(true); |
128 views::BubbleDelegateView::CreateBubble(this); | 122 views::BubbleDelegateView::CreateBubble(this); |
129 } | 123 } |
130 | 124 |
131 void OverflowBubbleView::ScrollByXOffset(int x_offset) { | 125 void OverflowBubbleView::ScrollByXOffset(int x_offset) { |
132 const gfx::Rect visible_bounds(GetContentsBounds()); | 126 const gfx::Rect visible_bounds(GetContentsBounds()); |
133 const gfx::Size contents_size(GetContentsSize()); | 127 const gfx::Size contents_size(GetContentsSize()); |
(...skipping 11 matching lines...) Expand all Loading... |
145 std::max(0, scroll_offset_.y() + y_offset)); | 139 std::max(0, scroll_offset_.y() + y_offset)); |
146 scroll_offset_.set_y(y); | 140 scroll_offset_.set_y(y); |
147 } | 141 } |
148 | 142 |
149 gfx::Size OverflowBubbleView::GetPreferredSize() { | 143 gfx::Size OverflowBubbleView::GetPreferredSize() { |
150 gfx::Size preferred_size = GetContentsSize(); | 144 gfx::Size preferred_size = GetContentsSize(); |
151 | 145 |
152 const gfx::Rect monitor_rect = Shell::GetScreen()->GetDisplayNearestPoint( | 146 const gfx::Rect monitor_rect = Shell::GetScreen()->GetDisplayNearestPoint( |
153 GetAnchorRect().CenterPoint()).work_area(); | 147 GetAnchorRect().CenterPoint()).work_area(); |
154 if (!monitor_rect.IsEmpty()) { | 148 if (!monitor_rect.IsEmpty()) { |
155 if (is_horizontal_alignment()) { | 149 if (IsHorizontalAlignment()) { |
156 preferred_size.set_width(std::min( | 150 preferred_size.set_width(std::min( |
157 preferred_size.width(), | 151 preferred_size.width(), |
158 static_cast<int>(monitor_rect.width() * | 152 static_cast<int>(monitor_rect.width() * |
159 kMaxBubbleSizeToScreenRatio))); | 153 kMaxBubbleSizeToScreenRatio))); |
160 } else { | 154 } else { |
161 preferred_size.set_height(std::min( | 155 preferred_size.set_height(std::min( |
162 preferred_size.height(), | 156 preferred_size.height(), |
163 static_cast<int>(monitor_rect.height() * | 157 static_cast<int>(monitor_rect.height() * |
164 kMaxBubbleSizeToScreenRatio))); | 158 kMaxBubbleSizeToScreenRatio))); |
165 } | 159 } |
(...skipping 10 matching lines...) Expand all Loading... |
176 void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) { | 170 void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) { |
177 // Ensures |launch_view_| is still visible. | 171 // Ensures |launch_view_| is still visible. |
178 ScrollByXOffset(0); | 172 ScrollByXOffset(0); |
179 ScrollByYOffset(0); | 173 ScrollByYOffset(0); |
180 Layout(); | 174 Layout(); |
181 | 175 |
182 SizeToContents(); | 176 SizeToContents(); |
183 } | 177 } |
184 | 178 |
185 bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) { | 179 bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) { |
186 if (is_horizontal_alignment()) | 180 if (IsHorizontalAlignment()) |
187 ScrollByXOffset(-event.offset()); | 181 ScrollByXOffset(-event.offset()); |
188 else | 182 else |
189 ScrollByYOffset(-event.offset()); | 183 ScrollByYOffset(-event.offset()); |
190 Layout(); | 184 Layout(); |
191 | 185 |
192 return true; | 186 return true; |
193 } | 187 } |
194 | 188 |
195 ui::EventResult OverflowBubbleView::OnScrollEvent(ui::ScrollEvent* event) { | 189 ui::EventResult OverflowBubbleView::OnScrollEvent(ui::ScrollEvent* event) { |
196 ScrollByXOffset(-event->x_offset()); | 190 ScrollByXOffset(-event->x_offset()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 : bubble_(NULL) { | 244 : bubble_(NULL) { |
251 } | 245 } |
252 | 246 |
253 OverflowBubble::~OverflowBubble() { | 247 OverflowBubble::~OverflowBubble() { |
254 Hide(); | 248 Hide(); |
255 } | 249 } |
256 | 250 |
257 void OverflowBubble::Show(LauncherDelegate* delegate, | 251 void OverflowBubble::Show(LauncherDelegate* delegate, |
258 LauncherModel* model, | 252 LauncherModel* model, |
259 views::View* anchor, | 253 views::View* anchor, |
260 ShelfAlignment shelf_alignment, | |
261 int overflow_start_index) { | 254 int overflow_start_index) { |
262 Hide(); | 255 Hide(); |
263 | 256 |
264 OverflowBubbleView* bubble_view = new OverflowBubbleView(); | 257 OverflowBubbleView* bubble_view = new OverflowBubbleView(); |
265 bubble_view->InitOverflowBubble(delegate, | 258 bubble_view->InitOverflowBubble(delegate, |
266 model, | 259 model, |
267 anchor, | 260 anchor, |
268 shelf_alignment, | |
269 overflow_start_index); | 261 overflow_start_index); |
270 | 262 |
271 bubble_ = bubble_view; | 263 bubble_ = bubble_view; |
272 ash::Shell::GetInstance()->system_tray()->InitializeBubbleAnimations( | 264 ash::Shell::GetInstance()->system_tray()->InitializeBubbleAnimations( |
273 bubble_->GetWidget()); | 265 bubble_->GetWidget()); |
274 bubble_->GetWidget()->AddObserver(this); | 266 bubble_->GetWidget()->AddObserver(this); |
275 bubble_->GetWidget()->Show(); | 267 bubble_->GetWidget()->Show(); |
276 } | 268 } |
277 | 269 |
278 void OverflowBubble::Hide() { | 270 void OverflowBubble::Hide() { |
279 if (!IsShowing()) | 271 if (!IsShowing()) |
280 return; | 272 return; |
281 | 273 |
282 bubble_->GetWidget()->RemoveObserver(this); | 274 bubble_->GetWidget()->RemoveObserver(this); |
283 bubble_->GetWidget()->Close(); | 275 bubble_->GetWidget()->Close(); |
284 bubble_ = NULL; | 276 bubble_ = NULL; |
285 } | 277 } |
286 | 278 |
287 void OverflowBubble::OnWidgetClosing(views::Widget* widget) { | 279 void OverflowBubble::OnWidgetClosing(views::Widget* widget) { |
288 DCHECK(widget == bubble_->GetWidget()); | 280 DCHECK(widget == bubble_->GetWidget()); |
289 bubble_ = NULL; | 281 bubble_ = NULL; |
290 } | 282 } |
291 | 283 |
292 } // namespace internal | 284 } // namespace internal |
293 } // namespace ash | 285 } // namespace ash |
OLD | NEW |