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

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

Issue 12313118: Refactor: Shelf Widget (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 9 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
OLDNEW
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/launcher.h" 5 #include "ash/launcher/launcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "ash/focus_cycler.h" 10 #include "ash/focus_cycler.h"
11 #include "ash/launcher/launcher_delegate.h" 11 #include "ash/launcher/launcher_delegate.h"
12 #include "ash/launcher/launcher_model.h" 12 #include "ash/launcher/launcher_model.h"
13 #include "ash/launcher/launcher_navigator.h" 13 #include "ash/launcher/launcher_navigator.h"
14 #include "ash/launcher/launcher_view.h" 14 #include "ash/launcher/launcher_view.h"
15 #include "ash/root_window_controller.h" 15 #include "ash/root_window_controller.h"
16 #include "ash/shelf/shelf_layout_manager.h"
17 #include "ash/shelf/shelf_widget.h"
16 #include "ash/shell.h" 18 #include "ash/shell.h"
17 #include "ash/shell_delegate.h" 19 #include "ash/shell_delegate.h"
18 #include "ash/shell_window_ids.h" 20 #include "ash/shell_window_ids.h"
19 #include "ash/wm/property_util.h" 21 #include "ash/wm/property_util.h"
20 #include "ash/wm/shelf_layout_manager.h"
21 #include "ash/wm/window_properties.h" 22 #include "ash/wm/window_properties.h"
22 #include "grit/ash_resources.h" 23 #include "grit/ash_resources.h"
23 #include "ui/aura/client/activation_client.h" 24 #include "ui/aura/client/activation_client.h"
24 #include "ui/aura/root_window.h" 25 #include "ui/aura/root_window.h"
25 #include "ui/aura/window.h" 26 #include "ui/aura/window.h"
26 #include "ui/aura/window_observer.h" 27 #include "ui/aura/window_observer.h"
27 #include "ui/base/resource/resource_bundle.h" 28 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/compositor/layer.h" 29 #include "ui/compositor/layer.h"
29 #include "ui/gfx/canvas.h" 30 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/image/image.h" 31 #include "ui/gfx/image/image.h"
31 #include "ui/gfx/image/image_skia_operations.h" 32 #include "ui/gfx/image/image_skia_operations.h"
32 #include "ui/gfx/skbitmap_operations.h" 33 #include "ui/gfx/skbitmap_operations.h"
33 #include "ui/views/accessible_pane_view.h" 34 #include "ui/views/accessible_pane_view.h"
34 #include "ui/views/widget/widget.h" 35 #include "ui/views/widget/widget.h"
35 #include "ui/views/widget/widget_delegate.h" 36 #include "ui/views/widget/widget_delegate.h"
36 37
37 namespace { 38 namespace {
38 // Size of black border at bottom (or side) of launcher. 39 // Size of black border at bottom (or side) of launcher.
39 const int kNumBlackPixels = 3; 40 const int kNumBlackPixels = 3;
40 // Alpha to paint dimming image with. 41 // Alpha to paint dimming image with.
41 const int kDimAlpha = 96; 42 const int kDimAlpha = 96;
42 } 43 }
43 44
44 namespace ash { 45 namespace ash {
45 46
46 // The contents view of the Widget. This view contains LauncherView and
47 // sizes it to the width of the widget minus the size of the status area.
48 class Launcher::DelegateView : public views::WidgetDelegate,
49 public views::AccessiblePaneView,
50 public internal::BackgroundAnimatorDelegate {
51 public:
52 explicit DelegateView(Launcher* launcher);
53 virtual ~DelegateView();
54
55 void set_focus_cycler(internal::FocusCycler* focus_cycler) {
56 focus_cycler_ = focus_cycler;
57 }
58 internal::FocusCycler* focus_cycler() {
59 return focus_cycler_;
60 }
61
62 // views::View overrides
63 virtual gfx::Size GetPreferredSize() OVERRIDE;
64 virtual void Layout() OVERRIDE;
65 virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE;
66
67 // views::WidgetDelegateView overrides:
68 virtual views::Widget* GetWidget() OVERRIDE {
69 return View::GetWidget();
70 }
71 virtual const views::Widget* GetWidget() const OVERRIDE {
72 return View::GetWidget();
73 }
74 virtual bool CanActivate() const OVERRIDE {
75 // Allow to activate as fallback.
76 if (launcher_->activating_as_fallback_)
77 return true;
78 // Allow to activate from the focus cycler.
79 if (focus_cycler_ && focus_cycler_->widget_activating() == GetWidget())
80 return true;
81 // Disallow activating in other cases, especially when using mouse.
82 return false;
83 }
84
85 // BackgroundAnimatorDelegate overrides:
86 virtual void UpdateBackground(int alpha) OVERRIDE;
87
88 private:
89 Launcher* launcher_;
90 internal::FocusCycler* focus_cycler_;
91 int alpha_;
92
93 DISALLOW_COPY_AND_ASSIGN(DelegateView);
94 };
95
96 // Class used to slightly dim shelf items when maximized and visible. It also
97 // makes sure the widget changes size to always be of the same size as the
98 // shelf.
99 class Launcher::DimmerView : public views::View,
100 public aura::WindowObserver {
101 public:
102 explicit DimmerView(Launcher* launcher)
103 : launcher_(launcher) {
104 launcher_->widget()->GetNativeWindow()->AddObserver(this);
105 }
106
107 virtual ~DimmerView() {
108 if (launcher_)
109 launcher_->widget()->GetNativeWindow()->RemoveObserver(this);
110 }
111
112 private:
113 // views::View overrides:
114 virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE {
115 ash::internal::ShelfLayoutManager* shelf = ash::GetRootWindowController(
116 GetWidget()->GetNativeView()->GetRootWindow())->shelf();
117 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
118 gfx::ImageSkia background_image =
119 *rb.GetImageSkiaNamed(IDR_AURA_LAUNCHER_DIMMING);
120 if (SHELF_ALIGNMENT_BOTTOM != launcher_->alignment_)
121 background_image = gfx::ImageSkiaOperations::CreateRotatedImage(
122 background_image,
123 shelf->SelectValueForShelfAlignment(
124 SkBitmapOperations::ROTATION_90_CW,
125 SkBitmapOperations::ROTATION_90_CW,
126 SkBitmapOperations::ROTATION_270_CW,
127 SkBitmapOperations::ROTATION_180_CW));
128
129 SkPaint paint;
130 paint.setAlpha(kDimAlpha);
131 canvas->DrawImageInt(
132 background_image,
133 0, 0, background_image.width(), background_image.height(),
134 0, 0, width(), height(),
135 false,
136 paint);
137 }
138
139 // aura::WindowObserver overrides:
140 virtual void OnWindowBoundsChanged(aura::Window* window,
141 const gfx::Rect& old_bounds,
142 const gfx::Rect& new_bounds) OVERRIDE {
143 CHECK_EQ(window, launcher_->widget()->GetNativeWindow());
144 GetWidget()->GetNativeWindow()->SetBounds(window->bounds());
145 }
146
147 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
148 CHECK_EQ(window, launcher_->widget()->GetNativeWindow());
149 launcher_->widget()->GetNativeWindow()->RemoveObserver(this);
150 launcher_ = NULL;
151 }
152
153 Launcher* launcher_;
154 DISALLOW_COPY_AND_ASSIGN(DimmerView);
155 };
156
157 Launcher::DelegateView::DelegateView(Launcher* launcher)
158 : launcher_(launcher),
159 focus_cycler_(NULL),
160 alpha_(0) {
161 // Allow the launcher to surrender the focus to another window upon
162 // navigation completion by the user.
163 set_allow_deactivate_on_esc(true);
164 }
165
166 Launcher::DelegateView::~DelegateView() {
167 }
168
169 gfx::Size Launcher::DelegateView::GetPreferredSize() {
170 return child_count() > 0 ? child_at(0)->GetPreferredSize() : gfx::Size();
171 }
172
173 void Launcher::DelegateView::Layout() {
174 if (child_count() == 0)
175 return;
176 View* launcher_view = child_at(0);
177
178 if (launcher_->alignment_ == SHELF_ALIGNMENT_BOTTOM ||
179 launcher_->alignment_ == SHELF_ALIGNMENT_TOP) {
180 int w = std::max(0, width() - launcher_->status_size_.width());
181 launcher_view->SetBounds(0, 0, w, height());
182 } else {
183 int h = std::max(0, height() - launcher_->status_size_.height());
184 launcher_view->SetBounds(0, 0, width(), h);
185 }
186 }
187
188 void Launcher::DelegateView::OnPaintBackground(gfx::Canvas* canvas) {
189 ash::internal::ShelfLayoutManager* shelf = ash::GetRootWindowController(
190 GetWidget()->GetNativeView()->GetRootWindow())->shelf();
191 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
192 gfx::ImageSkia launcher_background =
193 *rb.GetImageSkiaNamed(IDR_AURA_LAUNCHER_BACKGROUND);
194 if (launcher_->alignment_ != SHELF_ALIGNMENT_BOTTOM)
195 launcher_background = gfx::ImageSkiaOperations::CreateRotatedImage(
196 launcher_background,
197 shelf->SelectValueForShelfAlignment(
198 SkBitmapOperations::ROTATION_90_CW,
199 SkBitmapOperations::ROTATION_90_CW,
200 SkBitmapOperations::ROTATION_270_CW,
201 SkBitmapOperations::ROTATION_180_CW));
202
203 gfx::Rect black_rect = shelf->SelectValueForShelfAlignment(
204 gfx::Rect(0, height() - kNumBlackPixels, width(), kNumBlackPixels),
205 gfx::Rect(0, 0, kNumBlackPixels, height()),
206 gfx::Rect(width() - kNumBlackPixels, 0, kNumBlackPixels, height()),
207 gfx::Rect(0, 0, width(), kNumBlackPixels));
208
209 SkPaint paint;
210 paint.setAlpha(alpha_);
211 canvas->DrawImageInt(
212 launcher_background,
213 0, 0, launcher_background.width(), launcher_background.height(),
214 0, 0, width(), height(),
215 false,
216 paint);
217 canvas->FillRect(black_rect, SK_ColorBLACK);
218 }
219
220 void Launcher::DelegateView::UpdateBackground(int alpha) {
221 alpha_ = alpha;
222 SchedulePaint();
223 }
224
225 // Launcher --------------------------------------------------------------------
226
227 Launcher::Launcher(LauncherModel* launcher_model, 47 Launcher::Launcher(LauncherModel* launcher_model,
228 LauncherDelegate* launcher_delegate, 48 LauncherDelegate* launcher_delegate,
229 aura::Window* window_container, 49 ShelfWidget* shelf_widget)
230 internal::ShelfLayoutManager* shelf_layout_manager) 50 : launcher_view_(NULL),
231 : widget_(NULL),
232 window_container_(window_container),
233 delegate_view_(new DelegateView(this)),
234 launcher_view_(NULL),
235 alignment_(SHELF_ALIGNMENT_BOTTOM), 51 alignment_(SHELF_ALIGNMENT_BOTTOM),
236 delegate_(launcher_delegate), 52 delegate_(launcher_delegate),
237 background_animator_(delegate_view_, 0, kLauncherBackgroundAlpha), 53 shelf_widget_(shelf_widget) {
238 activating_as_fallback_(false) {
239 widget_.reset(new views::Widget);
240 views::Widget::InitParams params(
241 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
242 params.transparent = true;
243 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
244 params.parent = Shell::GetContainer(
245 window_container_->GetRootWindow(),
246 ash::internal::kShellWindowId_LauncherContainer);
247 launcher_view_ = new internal::LauncherView( 54 launcher_view_ = new internal::LauncherView(
248 launcher_model, delegate_, shelf_layout_manager); 55 launcher_model, delegate_, shelf_widget_->shelf_layout_manager());
249 launcher_view_->Init(); 56 launcher_view_->Init();
250 delegate_view_->AddChildView(launcher_view_); 57 shelf_widget_->GetContentsView()->AddChildView(launcher_view_);
251 params.delegate = delegate_view_; 58 shelf_widget_->GetNativeView()->SetName("LauncherView");
252 widget_->Init(params); 59 shelf_widget_->GetNativeView()->SetProperty(
253 widget_->GetNativeWindow()->SetName("LauncherWindow"); 60 internal::kStayInSameRootWindowKey, true);
254 // The launcher should not take focus when it is initially shown.
255 widget_->set_focus_on_creation(false);
256 widget_->SetContentsView(delegate_view_);
257 widget_->GetNativeView()->SetName("LauncherView");
258 widget_->GetNativeView()->SetProperty(internal::kStayInSameRootWindowKey,
259 true);
260
261 // SetBounds() has to be called after kStayInSameRootWindowKey is set.
262 gfx::Size pref =
263 static_cast<views::View*>(launcher_view_)->GetPreferredSize();
264 widget_->SetBounds(gfx::Rect(pref));
265
266 widget_->AddObserver(this);
267 } 61 }
268 62
269 Launcher::~Launcher() { 63 Launcher::~Launcher() {
Mr4D (OOO till 08-26) 2013/03/04 19:18:04 Since there isn't anything left you should possibl
tfarina 2013/03/04 19:19:58 why? no, keep the declaration in the header and th
270 widget_->RemoveObserver(this);
271 } 64 }
272 65
273 // static 66 // static
274 Launcher* Launcher::ForPrimaryDisplay() { 67 Launcher* Launcher::ForPrimaryDisplay() {
275 return internal::RootWindowController::ForLauncher( 68 return internal::RootWindowController::ForLauncher(
276 Shell::GetPrimaryRootWindow())->launcher(); 69 Shell::GetPrimaryRootWindow())->shelf()->launcher();
277 } 70 }
278 71
279 // static 72 // static
280 Launcher* Launcher::ForWindow(aura::Window* window) { 73 Launcher* Launcher::ForWindow(aura::Window* window) {
281 return internal::RootWindowController::ForLauncher(window)->launcher(); 74 return
282 } 75 internal::RootWindowController::ForLauncher(window)->shelf()->launcher();
283
284 void Launcher::SetFocusCycler(internal::FocusCycler* focus_cycler) {
285 delegate_view_->set_focus_cycler(focus_cycler);
286 if (focus_cycler)
287 focus_cycler->AddWidget(widget_.get());
288 }
289
290 internal::FocusCycler* Launcher::GetFocusCycler() {
291 return delegate_view_->focus_cycler();
292 } 76 }
293 77
294 void Launcher::SetAlignment(ShelfAlignment alignment) { 78 void Launcher::SetAlignment(ShelfAlignment alignment) {
295 alignment_ = alignment; 79 alignment_ = alignment;
296 delegate_view_->SchedulePaint();
297 launcher_view_->OnShelfAlignmentChanged(); 80 launcher_view_->OnShelfAlignmentChanged();
298 // ShelfLayoutManager will resize the launcher. 81 // ShelfLayoutManager will resize the launcher.
299 } 82 }
300 83
301 void Launcher::SetPaintsBackground(
302 bool value,
303 internal::BackgroundAnimator::ChangeType change_type) {
304 background_animator_.SetPaintsBackground(value, change_type);
305 }
306
307 void Launcher::SetDimsShelf(bool value) {
308 if (value == (dimmer_.get() != NULL))
309 return;
310
311 if (!value) {
312 dimmer_.reset();
313 return;
314 }
315
316 dimmer_.reset(new views::Widget);
317 views::Widget::InitParams params(
318 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
319 params.transparent = true;
320 params.can_activate = false;
321 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
322 params.parent = Shell::GetContainer(
323 window_container_->GetRootWindow(),
324 ash::internal::kShellWindowId_LauncherContainer);
325 params.accept_events = false;
326 dimmer_->Init(params);
327 dimmer_->GetNativeWindow()->SetName("LauncherDimmer");
328 dimmer_->SetBounds(widget_->GetWindowBoundsInScreen());
329 // The launcher should not take focus when it is initially shown.
330 dimmer_->set_focus_on_creation(false);
331 dimmer_->SetContentsView(new DimmerView(this));
332 dimmer_->GetNativeView()->SetName("LauncherDimmerView");
333 dimmer_->GetNativeView()->SetProperty(internal::kStayInSameRootWindowKey,
334 true);
335 dimmer_->Show();
336 }
337
338 bool Launcher::GetDimsShelf() const {
339 return dimmer_.get() && dimmer_->IsVisible();
340 }
341
342 void Launcher::SetStatusSize(const gfx::Size& size) {
343 if (status_size_ == size)
344 return;
345
346 status_size_ = size;
347 delegate_view_->Layout();
348 }
349
350 gfx::Rect Launcher::GetScreenBoundsOfItemIconForWindow(aura::Window* window) { 84 gfx::Rect Launcher::GetScreenBoundsOfItemIconForWindow(aura::Window* window) {
351 LauncherID id = delegate_->GetIDByWindow(window); 85 LauncherID id = delegate_->GetIDByWindow(window);
352 gfx::Rect bounds(launcher_view_->GetIdealBoundsOfItemIcon(id)); 86 gfx::Rect bounds(launcher_view_->GetIdealBoundsOfItemIcon(id));
353 if (bounds.IsEmpty()) 87 if (bounds.IsEmpty())
354 return bounds; 88 return bounds;
355 89
356 gfx::Point screen_origin; 90 gfx::Point screen_origin;
357 views::View::ConvertPointToScreen(launcher_view_, &screen_origin); 91 views::View::ConvertPointToScreen(launcher_view_, &screen_origin);
358 return gfx::Rect(screen_origin.x() + bounds.x(), 92 return gfx::Rect(screen_origin.x() + bounds.x(),
359 screen_origin.y() + bounds.y(), 93 screen_origin.y() + bounds.y(),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 126
393 void Launcher::ShowContextMenu(const gfx::Point& location) { 127 void Launcher::ShowContextMenu(const gfx::Point& location) {
394 launcher_view_->ShowContextMenu(location, false); 128 launcher_view_->ShowContextMenu(location, false);
395 } 129 }
396 130
397 bool Launcher::IsShowingOverflowBubble() const { 131 bool Launcher::IsShowingOverflowBubble() const {
398 return launcher_view_->IsShowingOverflowBubble(); 132 return launcher_view_->IsShowingOverflowBubble();
399 } 133 }
400 134
401 void Launcher::SetVisible(bool visible) const { 135 void Launcher::SetVisible(bool visible) const {
402 delegate_view_->SetVisible(visible); 136 launcher_view_->SetVisible(visible);
137 }
138
139 bool Launcher::visible() const {
140 return launcher_view_->visible();
403 } 141 }
404 142
405 views::View* Launcher::GetAppListButtonView() const { 143 views::View* Launcher::GetAppListButtonView() const {
406 return launcher_view_->GetAppListButtonView(); 144 return launcher_view_->GetAppListButtonView();
407 } 145 }
408 146
409 void Launcher::SetWidgetBounds(const gfx::Rect bounds) {
410 widget_->SetBounds(bounds);
411 if (dimmer_.get())
412 dimmer_->SetBounds(bounds);
413 }
414
415 void Launcher::SwitchToWindow(int window_index) { 147 void Launcher::SwitchToWindow(int window_index) {
416 LauncherModel* launcher_model = launcher_view_->model(); 148 LauncherModel* launcher_model = launcher_view_->model();
417 const LauncherItems& items = launcher_model->items(); 149 const LauncherItems& items = launcher_model->items();
418 int item_count = launcher_model->item_count(); 150 int item_count = launcher_model->item_count();
419 int indexes_left = window_index >= 0 ? window_index : item_count; 151 int indexes_left = window_index >= 0 ? window_index : item_count;
420 int found_index = -1; 152 int found_index = -1;
421 153
422 // Iterating until we have hit the index we are interested in which 154 // Iterating until we have hit the index we are interested in which
423 // is true once indexes_left becomes negative. 155 // is true once indexes_left becomes negative.
424 for (int i = 0; i < item_count && indexes_left >= 0; i++) { 156 for (int i = 0; i < item_count && indexes_left >= 0; i++) {
425 if (items[i].type != TYPE_APP_LIST && 157 if (items[i].type != TYPE_APP_LIST &&
426 items[i].type != TYPE_BROWSER_SHORTCUT) { 158 items[i].type != TYPE_BROWSER_SHORTCUT) {
427 found_index = i; 159 found_index = i;
428 indexes_left--; 160 indexes_left--;
429 } 161 }
430 } 162 }
431 163
432 // There are two ways how found_index can be valid: a.) the nth item was 164 // There are two ways how found_index can be valid: a.) the nth item was
433 // found (which is true when indexes_left is -1) or b.) the last item was 165 // found (which is true when indexes_left is -1) or b.) the last item was
434 // requested (which is true when index was passed in as a negative number). 166 // requested (which is true when index was passed in as a negative number).
435 if (found_index >= 0 && (indexes_left == -1 || window_index < 0) && 167 if (found_index >= 0 && (indexes_left == -1 || window_index < 0) &&
436 (items[found_index].status == ash::STATUS_RUNNING || 168 (items[found_index].status == ash::STATUS_RUNNING ||
437 items[found_index].status == ash::STATUS_CLOSED)) { 169 items[found_index].status == ash::STATUS_CLOSED)) {
438 // Then set this one as active. 170 // Then set this one as active.
439 ActivateLauncherItem(found_index); 171 ActivateLauncherItem(found_index);
440 } 172 }
441 } 173 }
442 174
443 void Launcher::OnWidgetActivationChanged(views::Widget* widget, bool active) {
444 activating_as_fallback_ = false;
445 if (active) {
446 delegate_view_->SetPaneFocusAndFocusDefault();
447 } else {
448 delegate_view_->GetFocusManager()->ClearFocus();
449 }
450 }
451
452 internal::LauncherView* Launcher::GetLauncherViewForTest() { 175 internal::LauncherView* Launcher::GetLauncherViewForTest() {
453 return launcher_view_; 176 return launcher_view_;
454 } 177 }
455 178
179 void Launcher::SetLauncherViewBounds(gfx::Rect bounds) {
180 if (launcher_view_)
181 launcher_view_->SetBoundsRect(bounds);
182 }
183
184 gfx::Rect Launcher::launcher_view_bounds() const {
185 if (launcher_view_)
186 return launcher_view_->bounds();
187 return gfx::Rect();
188 }
189
456 } // namespace ash 190 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698