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

Side by Side Diff: ash/shelf/shelf_widget.cc

Issue 2190773003: [ABANDONED] Simplify ash shelf dimmer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Restore an EventHandler object; fix behavior tests. Created 4 years, 4 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
« no previous file with comments | « ash/shelf/shelf_widget.h ('k') | ui/views/widget/drop_helper.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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/shelf/shelf_widget.h" 5 #include "ash/shelf/shelf_widget.h"
6 6
7 #include "ash/aura/wm_shelf_aura.h" 7 #include "ash/aura/wm_shelf_aura.h"
8 #include "ash/aura/wm_window_aura.h" 8 #include "ash/aura/wm_window_aura.h"
9 #include "ash/common/ash_switches.h"
10 #include "ash/common/focus_cycler.h" 9 #include "ash/common/focus_cycler.h"
11 #include "ash/common/material_design/material_design_controller.h" 10 #include "ash/common/material_design/material_design_controller.h"
12 #include "ash/common/session/session_state_delegate.h" 11 #include "ash/common/session/session_state_delegate.h"
13 #include "ash/common/shelf/shelf_constants.h" 12 #include "ash/common/shelf/shelf_constants.h"
14 #include "ash/common/shelf/shelf_delegate.h" 13 #include "ash/common/shelf/shelf_delegate.h"
15 #include "ash/common/shelf/shelf_model.h"
16 #include "ash/common/shelf/wm_shelf_util.h" 14 #include "ash/common/shelf/wm_shelf_util.h"
17 #include "ash/common/shell_window_ids.h"
18 #include "ash/common/system/status_area_widget.h" 15 #include "ash/common/system/status_area_widget.h"
19 #include "ash/common/system/tray/system_tray_delegate.h" 16 #include "ash/common/system/tray/system_tray_delegate.h"
17 #include "ash/common/wm_lookup.h"
20 #include "ash/common/wm_root_window_controller.h" 18 #include "ash/common/wm_root_window_controller.h"
21 #include "ash/common/wm_shell.h" 19 #include "ash/common/wm_shell.h"
22 #include "ash/shelf/shelf.h" 20 #include "ash/shelf/shelf.h"
23 #include "ash/shelf/shelf_layout_manager.h" 21 #include "ash/shelf/shelf_layout_manager.h"
24 #include "ash/shelf/shelf_util.h"
25 #include "ash/shelf/shelf_view.h"
26 #include "ash/shell.h" 22 #include "ash/shell.h"
27 #include "ash/wm/status_area_layout_manager.h" 23 #include "ash/wm/status_area_layout_manager.h"
28 #include "ash/wm/window_properties.h"
29 #include "ash/wm/workspace_controller.h" 24 #include "ash/wm/workspace_controller.h"
30 #include "grit/ash_resources.h" 25 #include "grit/ash_resources.h"
31 #include "ui/aura/window.h" 26 #include "ui/aura/window.h"
32 #include "ui/aura/window_event_dispatcher.h"
33 #include "ui/aura/window_observer.h"
34 #include "ui/base/resource/resource_bundle.h" 27 #include "ui/base/resource/resource_bundle.h"
35 #include "ui/compositor/layer.h" 28 #include "ui/compositor/layer.h"
36 #include "ui/compositor/scoped_layer_animation_settings.h" 29 #include "ui/compositor/scoped_layer_animation_settings.h"
37 #include "ui/events/event_constants.h"
38 #include "ui/gfx/canvas.h" 30 #include "ui/gfx/canvas.h"
39 #include "ui/gfx/image/image.h" 31 #include "ui/gfx/image/image.h"
40 #include "ui/gfx/image/image_skia_operations.h" 32 #include "ui/gfx/image/image_skia_operations.h"
41 #include "ui/gfx/skbitmap_operations.h" 33 #include "ui/gfx/skbitmap_operations.h"
42 #include "ui/views/accessible_pane_view.h" 34 #include "ui/views/accessible_pane_view.h"
35 #include "ui/events/event_handler.h"
43 #include "ui/views/layout/fill_layout.h" 36 #include "ui/views/layout/fill_layout.h"
37 #include "ui/views/pointer_watcher.h"
44 #include "ui/views/widget/widget.h" 38 #include "ui/views/widget/widget.h"
45 #include "ui/views/widget/widget_delegate.h" 39 #include "ui/views/widget/widget_delegate.h"
46 #include "ui/wm/core/coordinate_conversion.h"
47 #include "ui/wm/core/easy_resize_window_targeter.h" 40 #include "ui/wm/core/easy_resize_window_targeter.h"
48 #include "ui/wm/public/activation_client.h"
49 41
50 namespace ash { 42 namespace ash {
51 43
52 namespace { 44 namespace {
53 // Size of black border at bottom (or side) of shelf. 45 // Size of black border at bottom (or side) of shelf.
54 const int kNumBlackPixels = 3; 46 const int kNumBlackPixels = 3;
55 // Alpha to paint dimming image with.
56 const int kDimAlpha = 128;
57 47
58 // The time to dim and un-dim. 48 // The time to dim and un-dim, and the opacities used for dimming.
59 const int kTimeToDimMs = 3000; // Slow in dimming. 49 const int kTimeToDimMs = 3000; // Slow in dimming.
60 const int kTimeToUnDimMs = 200; // Fast in activating. 50 const int kTimeToUnDimMs = 200; // Fast in activating.
61 51 const float kDimOpactiy = 0.25f;
62 // Class used to slightly dim shelf items when maximized and visible. 52 const float kUnDimOpactiy = 0.0f;
63 class DimmerView : public views::View,
64 public views::WidgetDelegate,
65 BackgroundAnimatorDelegate {
66 public:
67 // If |disable_dimming_animations_for_test| is set, all alpha animations will
68 // be performed instantly.
69 DimmerView(ShelfWidget* shelf_widget,
70 bool disable_dimming_animations_for_test);
71 ~DimmerView() override;
72
73 // Called by |DimmerEventFilter| when the mouse |hovered| state changes.
74 void SetHovered(bool hovered);
75
76 // Force the dimmer to be undimmed.
77 void ForceUndimming(bool force);
78
79 // views::WidgetDelegate overrides:
80 views::Widget* GetWidget() override { return View::GetWidget(); }
81 const views::Widget* GetWidget() const override { return View::GetWidget(); }
82
83 // BackgroundAnimatorDelegate overrides:
84 void UpdateBackground(int alpha) override {
85 alpha_ = alpha;
86 SchedulePaint();
87 }
88
89 // views::View overrides:
90 void OnPaintBackground(gfx::Canvas* canvas) override;
91
92 // A function to test the current alpha used.
93 int get_dimming_alpha_for_test() { return alpha_; }
94
95 private:
96 // This class monitors mouse events to see if it is on top of the shelf.
97 class DimmerEventFilter : public ui::EventHandler {
98 public:
99 explicit DimmerEventFilter(DimmerView* owner);
100 ~DimmerEventFilter() override;
101
102 // Overridden from ui::EventHandler:
103 void OnMouseEvent(ui::MouseEvent* event) override;
104 void OnTouchEvent(ui::TouchEvent* event) override;
105
106 private:
107 // The owning class.
108 DimmerView* owner_;
109
110 // TRUE if the mouse is inside the shelf.
111 bool mouse_inside_;
112
113 // TRUE if a touch event is inside the shelf.
114 bool touch_inside_;
115
116 DISALLOW_COPY_AND_ASSIGN(DimmerEventFilter);
117 };
118
119 // The owning shelf widget.
120 ShelfWidget* shelf_;
121
122 // The alpha to use for covering the shelf.
123 int alpha_;
124
125 // True if the event filter claims that we should not be dimmed.
126 bool is_hovered_;
127
128 // True if someone forces us not to be dimmed (e.g. a menu is open).
129 bool force_hovered_;
130
131 // True if animations should be suppressed for a test.
132 bool disable_dimming_animations_for_test_;
133
134 // The animator for the background transitions.
135 BackgroundAnimator background_animator_;
136
137 // Notification of entering / exiting of the shelf area by mouse.
138 std::unique_ptr<DimmerEventFilter> event_filter_;
139
140 DISALLOW_COPY_AND_ASSIGN(DimmerView);
141 };
142
143 DimmerView::DimmerView(ShelfWidget* shelf_widget,
144 bool disable_dimming_animations_for_test)
145 : shelf_(shelf_widget),
146 alpha_(kDimAlpha),
147 is_hovered_(false),
148 force_hovered_(false),
149 disable_dimming_animations_for_test_(disable_dimming_animations_for_test),
150 background_animator_(this, 0, kDimAlpha) {
151 event_filter_.reset(new DimmerEventFilter(this));
152 // Make sure it is undimmed at the beginning and then fire off the dimming
153 // animation.
154 background_animator_.SetPaintsBackground(false, BACKGROUND_CHANGE_IMMEDIATE);
155 SetHovered(false);
156 }
157
158 DimmerView::~DimmerView() {}
159
160 void DimmerView::SetHovered(bool hovered) {
161 // Remember the hovered state so that we can correct the state once a
162 // possible force state has disappeared.
163 is_hovered_ = hovered;
164 // Undimm also if we were forced to by e.g. an open menu.
165 hovered |= force_hovered_;
166 background_animator_.SetDuration(hovered ? kTimeToUnDimMs : kTimeToDimMs);
167 background_animator_.SetPaintsBackground(!hovered,
168 disable_dimming_animations_for_test_
169 ? BACKGROUND_CHANGE_IMMEDIATE
170 : BACKGROUND_CHANGE_ANIMATE);
171 }
172
173 void DimmerView::ForceUndimming(bool force) {
174 bool previous = force_hovered_;
175 force_hovered_ = force;
176 // If the forced change does change the result we apply the change.
177 if (is_hovered_ || force_hovered_ != is_hovered_ || previous)
178 SetHovered(is_hovered_);
179 }
180
181 void DimmerView::OnPaintBackground(gfx::Canvas* canvas) {
182 SkPaint paint;
183 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
184 gfx::ImageSkia shelf_background =
185 *rb->GetImageNamed(IDR_ASH_SHELF_DIMMING).ToImageSkia();
186
187 if (!IsHorizontalAlignment(shelf_->GetAlignment())) {
188 shelf_background = gfx::ImageSkiaOperations::CreateRotatedImage(
189 shelf_background, shelf_->GetAlignment() == SHELF_ALIGNMENT_LEFT
190 ? SkBitmapOperations::ROTATION_90_CW
191 : SkBitmapOperations::ROTATION_270_CW);
192 }
193 paint.setAlpha(alpha_);
194 canvas->DrawImageInt(shelf_background, 0, 0, shelf_background.width(),
195 shelf_background.height(), 0, 0, width(), height(),
196 false, paint);
197 }
198
199 DimmerView::DimmerEventFilter::DimmerEventFilter(DimmerView* owner)
200 : owner_(owner), mouse_inside_(false), touch_inside_(false) {
201 Shell::GetInstance()->AddPreTargetHandler(this);
202 }
203
204 DimmerView::DimmerEventFilter::~DimmerEventFilter() {
205 Shell::GetInstance()->RemovePreTargetHandler(this);
206 }
207
208 void DimmerView::DimmerEventFilter::OnMouseEvent(ui::MouseEvent* event) {
209 if (event->type() != ui::ET_MOUSE_MOVED &&
210 event->type() != ui::ET_MOUSE_DRAGGED)
211 return;
212
213 gfx::Point screen_point(event->location());
214 ::wm::ConvertPointToScreen(static_cast<aura::Window*>(event->target()),
215 &screen_point);
216 bool inside = owner_->GetBoundsInScreen().Contains(screen_point);
217 if (mouse_inside_ || touch_inside_ != inside || touch_inside_)
218 owner_->SetHovered(inside || touch_inside_);
219 mouse_inside_ = inside;
220 }
221
222 void DimmerView::DimmerEventFilter::OnTouchEvent(ui::TouchEvent* event) {
223 bool touch_inside = false;
224 if (event->type() != ui::ET_TOUCH_RELEASED &&
225 event->type() != ui::ET_TOUCH_CANCELLED) {
226 gfx::Point screen_point(event->location());
227 ::wm::ConvertPointToScreen(static_cast<aura::Window*>(event->target()),
228 &screen_point);
229 touch_inside = owner_->GetBoundsInScreen().Contains(screen_point);
230 }
231
232 if (mouse_inside_ || touch_inside_ != mouse_inside_ || touch_inside)
233 owner_->SetHovered(mouse_inside_ || touch_inside);
234 touch_inside_ = touch_inside;
235 }
236 53
237 // ShelfWindowTargeter makes it easier to resize windows with the mouse when the 54 // ShelfWindowTargeter makes it easier to resize windows with the mouse when the
238 // window-edge slightly overlaps with the shelf edge. The targeter also makes it 55 // window-edge slightly overlaps with the shelf edge. The targeter also makes it
239 // easier to drag the shelf out with touch while it is hidden. 56 // easier to drag the shelf out with touch while it is hidden.
240 class ShelfWindowTargeter : public ::wm::EasyResizeWindowTargeter, 57 class ShelfWindowTargeter : public ::wm::EasyResizeWindowTargeter,
241 public ShelfLayoutManagerObserver { 58 public ShelfLayoutManagerObserver {
242 public: 59 public:
243 ShelfWindowTargeter(aura::Window* container, ShelfLayoutManager* shelf) 60 ShelfWindowTargeter(aura::Window* container, ShelfLayoutManager* shelf)
244 : ::wm::EasyResizeWindowTargeter(container, gfx::Insets(), gfx::Insets()), 61 : ::wm::EasyResizeWindowTargeter(container, gfx::Insets(), gfx::Insets()),
245 shelf_(shelf) { 62 shelf_(shelf) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 102
286 set_mouse_extend(mouse_insets); 103 set_mouse_extend(mouse_insets);
287 set_touch_extend(touch_insets); 104 set_touch_extend(touch_insets);
288 } 105 }
289 106
290 ShelfLayoutManager* shelf_; 107 ShelfLayoutManager* shelf_;
291 108
292 DISALLOW_COPY_AND_ASSIGN(ShelfWindowTargeter); 109 DISALLOW_COPY_AND_ASSIGN(ShelfWindowTargeter);
293 }; 110 };
294 111
112 class ShelfDimmer : public ui::EventHandler, public views::PointerWatcher {
113 public:
114 explicit ShelfDimmer(ShelfWidget* shelf) : shelf_widget_(shelf) {
115 // TODO(msw): Need to do the same for the status area widget...
116 WmWindow* window = WmLookup::Get()->GetWindowForWidget(shelf_widget_);
117 window->AddLimitedPreTargetHandler(this);
118 window = WmLookup::Get()->GetWindowForWidget(shelf_widget_->status_area_widg et());
119 window->AddLimitedPreTargetHandler(this);
120 WmShell::Get()->AddPointerWatcher(this);
121 }
122
123 ~ShelfDimmer() override {
124 // TODO(msw): Remove the pre-target handler(s)...
125 WmWindow* window = WmLookup::Get()->GetWindowForWidget(shelf_widget_);
126 window->RemoveLimitedPreTargetHandler(this);
127 window = WmLookup::Get()->GetWindowForWidget(shelf_widget_->status_area_widg et());
128 window->RemoveLimitedPreTargetHandler(this);
129 WmShell::Get()->RemovePointerWatcher(this);
130 }
131
132 // ui::EventHandler:
133 void OnMouseEvent(ui::MouseEvent* event) override {
134 LOG(ERROR) << "MSW ShelfDimmer OnMouseEvent " << event->name();
135 shelf_widget_->SetDimsShelf(
136 event->type() == ui::ET_MOUSE_EXITED ||
137 (event->type() == ui::ET_MOUSE_RELEASED &&
138 !shelf_widget_->GetRootView()->bounds().Contains(event->location())));
139 }
140 void OnTouchEvent(ui::TouchEvent* event) override {
141 LOG(ERROR) << "MSW ShelfDimmer OnTouchEvent " << event->name();
142 if (event->type() != ui::ET_TOUCH_PRESSED)
143 shelf_widget_->SetDimsShelf(event->type() != ui::ET_TOUCH_MOVED);
144 }
145
146 // views::PointerWatcher:
147 void OnMousePressed(const ui::MouseEvent& event,
148 const gfx::Point& location_in_screen,
149 views::Widget* target) override {}
150 void OnTouchPressed(const ui::TouchEvent& event,
151 const gfx::Point& location_in_screen,
152 views::Widget* target) override {
153 LOG(ERROR) << "MSW ShelfDimmer::OnTouchPressed " << event.name();
154 shelf_widget_->SetDimsShelf(
155 !shelf_widget_->GetWindowBoundsInScreen().Contains(location_in_screen));
156 }
157
158 private:
159 ShelfWidget* shelf_widget_;
160
161 DISALLOW_COPY_AND_ASSIGN(ShelfDimmer);
162 };
163
295 } // namespace 164 } // namespace
296 165
297 // The contents view of the Shelf. This view contains ShelfView and 166 // The contents view of the Shelf. This view contains ShelfView and
298 // sizes it to the width of the shelf minus the size of the status area. 167 // sizes it to the width of the shelf minus the size of the status area.
299 class ShelfWidget::DelegateView : public views::WidgetDelegate, 168 class ShelfWidget::DelegateView : public views::WidgetDelegate,
300 public views::AccessiblePaneView, 169 public views::AccessiblePaneView,
301 public BackgroundAnimatorDelegate, 170 public BackgroundAnimatorDelegate {
302 public aura::WindowObserver {
303 public: 171 public:
304 explicit DelegateView(ShelfWidget* shelf); 172 explicit DelegateView(ShelfWidget* shelf);
305 ~DelegateView() override; 173 ~DelegateView() override;
306 174
307 void set_focus_cycler(FocusCycler* focus_cycler) { 175 void set_focus_cycler(FocusCycler* cycler) { focus_cycler_ = cycler; }
308 focus_cycler_ = focus_cycler;
309 }
310 FocusCycler* focus_cycler() { return focus_cycler_; } 176 FocusCycler* focus_cycler() { return focus_cycler_; }
311 177
312 ui::Layer* opaque_background() { return &opaque_background_; } 178 ui::Layer* opaque_background() { return &opaque_background_; }
313 ui::Layer* opaque_foreground() { return &opaque_foreground_; } 179 ui::Layer* opaque_foreground() { return &opaque_foreground_; }
314 180
315 // Set if the shelf area is dimmed (eg when a window is maximized). 181 // Set if the shelf is dimmed (eg. when a window is maximized).
316 void SetDimmed(bool dimmed); 182 void SetDimmed(bool dimmed);
317 bool GetDimmed() const; 183
184 // Used to initialize or shutdown the dimmer.
185 void set_dimmer(std::unique_ptr<ShelfDimmer> dimmer) {
186 shelf_dimmer_ = std::move(dimmer);
187 }
318 188
319 void SetParentLayer(ui::Layer* layer); 189 void SetParentLayer(ui::Layer* layer);
320 190
321 // views::View overrides: 191 // views::View overrides:
322 void OnPaintBackground(gfx::Canvas* canvas) override; 192 void OnPaintBackground(gfx::Canvas* canvas) override;
323 193
324 // views::WidgetDelegateView overrides: 194 // views::WidgetDelegateView overrides:
325 views::Widget* GetWidget() override { return View::GetWidget(); } 195 views::Widget* GetWidget() override { return View::GetWidget(); }
326 const views::Widget* GetWidget() const override { return View::GetWidget(); } 196 const views::Widget* GetWidget() const override { return View::GetWidget(); }
327 197
328 bool CanActivate() const override; 198 bool CanActivate() const override;
329 void ReorderChildLayers(ui::Layer* parent_layer) override; 199 void ReorderChildLayers(ui::Layer* parent_layer) override;
330 // This will be called when the parent local bounds change. 200 // This will be called when the parent local bounds change.
331 void OnBoundsChanged(const gfx::Rect& old_bounds) override; 201 void OnBoundsChanged(const gfx::Rect& old_bounds) override;
332 202
333 // aura::WindowObserver overrides:
334 // This will be called when the shelf itself changes its absolute position.
335 // Since the |dimmer_| panel needs to be placed in screen coordinates it needs
336 // to be repositioned. The difference to the OnBoundsChanged call above is
337 // that this gets also triggered when the shelf only moves.
338 void OnWindowBoundsChanged(aura::Window* window,
339 const gfx::Rect& old_bounds,
340 const gfx::Rect& new_bounds) override;
341
342 // BackgroundAnimatorDelegate overrides: 203 // BackgroundAnimatorDelegate overrides:
343 void UpdateBackground(int alpha) override; 204 void UpdateBackground(int alpha) override;
344 205
345 // Force the shelf to be presented in an undimmed state. 206 // Force the shelf to be presented in an undimmed state.
346 void ForceUndimming(bool force); 207 void ForceUndimming(bool force);
347 208
348 // A function to test the current alpha used by the dimming bar. If there is 209 // Set the shelf dimming |opacity| over the |animation_time_ms| duration.
349 // no dimmer active, the function will return -1. 210 void SetShelfDimming(float opacity, int animation_time_ms);
350 int GetDimmingAlphaForTest();
351
352 // A function to test the bounds of the dimming bar. Returns gfx::Rect() if
353 // the dimmer is inactive.
354 gfx::Rect GetDimmerBoundsForTest();
355
356 // Disable dimming animations for running tests. This needs to be called
357 // prior to the creation of of the |dimmer_|.
358 void disable_dimming_animations_for_test() {
359 disable_dimming_animations_for_test_ = true;
360 }
361 211
362 private: 212 private:
363 ShelfWidget* shelf_; 213 ShelfWidget* shelf_;
364 std::unique_ptr<views::Widget> dimmer_; 214 FocusCycler* focus_cycler_ = nullptr;
365 FocusCycler* focus_cycler_; 215 int alpha_ = 0;
366 int alpha_; 216 // A black background shown when a maximized window is visible.
367 // A black background layer which is shown when a maximized window is visible.
368 ui::Layer opaque_background_; 217 ui::Layer opaque_background_;
369 // A black foreground layer which is shown while transitioning between users. 218 // A black foreground shown during user transitions; also used to dim shelf
370 // Note: Since the back- and foreground layers have different functions they 219 // items when a maximized window is visible and the shelf is not hovered.
371 // can be used simultaneously - so no repurposing possible.
372 ui::Layer opaque_foreground_; 220 ui::Layer opaque_foreground_;
373 221
374 // The view which does the dimming. 222 std::unique_ptr<ShelfDimmer> shelf_dimmer_;
375 DimmerView* dimmer_view_; 223 bool force_dimmer_off_ = false;
376 224 float stored_dimmer_opacity_ = 0.0f;
377 // True if dimming animations should be turned off.
378 bool disable_dimming_animations_for_test_;
379 225
380 DISALLOW_COPY_AND_ASSIGN(DelegateView); 226 DISALLOW_COPY_AND_ASSIGN(DelegateView);
381 }; 227 };
382 228
383 ShelfWidget::DelegateView::DelegateView(ShelfWidget* shelf) 229 ShelfWidget::DelegateView::DelegateView(ShelfWidget* shelf)
384 : shelf_(shelf), 230 : shelf_(shelf),
385 focus_cycler_(NULL),
386 alpha_(0),
387 opaque_background_(ui::LAYER_SOLID_COLOR), 231 opaque_background_(ui::LAYER_SOLID_COLOR),
388 opaque_foreground_(ui::LAYER_SOLID_COLOR), 232 opaque_foreground_(ui::LAYER_SOLID_COLOR) {
389 dimmer_view_(NULL),
390 disable_dimming_animations_for_test_(false) {
391 SetLayoutManager(new views::FillLayout()); 233 SetLayoutManager(new views::FillLayout());
392 set_allow_deactivate_on_esc(true); 234 set_allow_deactivate_on_esc(true);
393 opaque_background_.SetColor(SK_ColorBLACK); 235 opaque_background_.SetColor(SK_ColorBLACK);
394 opaque_background_.SetBounds(GetLocalBounds()); 236 opaque_background_.SetBounds(GetLocalBounds());
395 opaque_background_.SetOpacity(0.0f); 237 opaque_background_.SetOpacity(0.0f);
396 opaque_foreground_.SetColor(SK_ColorBLACK); 238 opaque_foreground_.SetColor(SK_ColorBLACK);
397 opaque_foreground_.SetBounds(GetLocalBounds()); 239 opaque_foreground_.SetBounds(GetLocalBounds());
398 opaque_foreground_.SetOpacity(0.0f); 240 opaque_foreground_.SetOpacity(0.0f);
399 } 241 }
400 242
401 ShelfWidget::DelegateView::~DelegateView() { 243 ShelfWidget::DelegateView::~DelegateView() {}
402 // Make sure that the dimmer goes away since it might have set an observer.
403 SetDimmed(false);
404 }
405 244
406 void ShelfWidget::DelegateView::SetDimmed(bool value) { 245 void ShelfWidget::DelegateView::SetDimmed(bool dimmed) {
407 if (value == (dimmer_.get() != NULL)) 246 if (force_dimmer_off_)
408 return; 247 stored_dimmer_opacity_ = dimmed ? kDimOpactiy : kUnDimOpactiy;
409 248 else if (dimmed)
410 if (value) { 249 SetShelfDimming(kDimOpactiy, kTimeToDimMs);
411 dimmer_.reset(new views::Widget); 250 else
412 views::Widget::InitParams params( 251 SetShelfDimming(kUnDimOpactiy, kTimeToUnDimMs);
413 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
414 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
415 params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
416 params.accept_events = false;
417 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
418 params.parent = shelf_->GetNativeView();
419 dimmer_->Init(params);
420 dimmer_->GetNativeWindow()->SetName("ShelfDimmer");
421 dimmer_->SetBounds(shelf_->GetWindowBoundsInScreen());
422 // The shelf should not take focus when it is initially shown.
423 dimmer_->set_focus_on_creation(false);
424 dimmer_view_ = new DimmerView(shelf_, disable_dimming_animations_for_test_);
425 dimmer_->SetContentsView(dimmer_view_);
426 dimmer_->GetNativeView()->SetName("ShelfDimmerView");
427 dimmer_->Show();
428 shelf_->GetNativeView()->AddObserver(this);
429 } else {
430 // Some unit tests will come here with a destroyed window.
431 if (shelf_->GetNativeView())
432 shelf_->GetNativeView()->RemoveObserver(this);
433 dimmer_view_ = NULL;
434 dimmer_.reset(NULL);
435 }
436 }
437
438 bool ShelfWidget::DelegateView::GetDimmed() const {
439 return dimmer_.get() && dimmer_->IsVisible();
440 } 252 }
441 253
442 void ShelfWidget::DelegateView::SetParentLayer(ui::Layer* layer) { 254 void ShelfWidget::DelegateView::SetParentLayer(ui::Layer* layer) {
443 layer->Add(&opaque_background_); 255 layer->Add(&opaque_background_);
444 layer->Add(&opaque_foreground_); 256 layer->Add(&opaque_foreground_);
445 ReorderLayers(); 257 ReorderLayers();
446 } 258 }
447 259
448 void ShelfWidget::DelegateView::OnPaintBackground(gfx::Canvas* canvas) { 260 void ShelfWidget::DelegateView::OnPaintBackground(gfx::Canvas* canvas) {
449 if (MaterialDesignController::IsShelfMaterial()) { 261 if (MaterialDesignController::IsShelfMaterial()) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 329
518 void ShelfWidget::DelegateView::ReorderChildLayers(ui::Layer* parent_layer) { 330 void ShelfWidget::DelegateView::ReorderChildLayers(ui::Layer* parent_layer) {
519 views::View::ReorderChildLayers(parent_layer); 331 views::View::ReorderChildLayers(parent_layer);
520 parent_layer->StackAtBottom(&opaque_background_); 332 parent_layer->StackAtBottom(&opaque_background_);
521 parent_layer->StackAtTop(&opaque_foreground_); 333 parent_layer->StackAtTop(&opaque_foreground_);
522 } 334 }
523 335
524 void ShelfWidget::DelegateView::OnBoundsChanged(const gfx::Rect& old_bounds) { 336 void ShelfWidget::DelegateView::OnBoundsChanged(const gfx::Rect& old_bounds) {
525 opaque_background_.SetBounds(GetLocalBounds()); 337 opaque_background_.SetBounds(GetLocalBounds());
526 opaque_foreground_.SetBounds(GetLocalBounds()); 338 opaque_foreground_.SetBounds(GetLocalBounds());
527 if (dimmer_)
528 dimmer_->SetBounds(GetBoundsInScreen());
529 }
530
531 void ShelfWidget::DelegateView::OnWindowBoundsChanged(
532 aura::Window* window,
533 const gfx::Rect& old_bounds,
534 const gfx::Rect& new_bounds) {
535 // Coming here the shelf got repositioned and since the |dimmer_| is placed
536 // in screen coordinates and not relative to the parent it needs to be
537 // repositioned accordingly.
538 dimmer_->SetBounds(GetBoundsInScreen());
539 }
540
541 void ShelfWidget::DelegateView::ForceUndimming(bool force) {
542 if (GetDimmed())
543 dimmer_view_->ForceUndimming(force);
544 }
545
546 int ShelfWidget::DelegateView::GetDimmingAlphaForTest() {
547 if (GetDimmed())
548 return dimmer_view_->get_dimming_alpha_for_test();
549 return -1;
550 }
551
552 gfx::Rect ShelfWidget::DelegateView::GetDimmerBoundsForTest() {
553 if (GetDimmed())
554 return dimmer_view_->GetBoundsInScreen();
555 return gfx::Rect();
556 } 339 }
557 340
558 void ShelfWidget::DelegateView::UpdateBackground(int alpha) { 341 void ShelfWidget::DelegateView::UpdateBackground(int alpha) {
559 alpha_ = alpha; 342 alpha_ = alpha;
560 SchedulePaint(); 343 SchedulePaint();
561 } 344 }
562 345
346 void ShelfWidget::DelegateView::ForceUndimming(bool force) {
347 force_dimmer_off_ = force;
348 if (force)
349 stored_dimmer_opacity_ = opaque_foreground_.opacity();
350 opaque_foreground_.SetOpacity(force ? kUnDimOpactiy : stored_dimmer_opacity_);
351 }
352
353 void ShelfWidget::DelegateView::SetShelfDimming(float opacity,
354 int animation_time_ms) {
355 if (opaque_foreground_.GetTargetOpacity() == opacity)
356 return;
357
358 std::unique_ptr<ui::ScopedLayerAnimationSettings> opaque_foreground_animation;
359 opaque_foreground_animation.reset(
360 new ui::ScopedLayerAnimationSettings(opaque_foreground_.GetAnimator()));
361 opaque_foreground_animation->SetTransitionDuration(
362 base::TimeDelta::FromMilliseconds(animation_time_ms));
363 opaque_foreground_animation->SetPreemptionStrategy(
364 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
365
366 opaque_foreground_.SetOpacity(opacity);
367 }
368
563 ShelfWidget::ShelfWidget(WmWindow* wm_shelf_container, 369 ShelfWidget::ShelfWidget(WmWindow* wm_shelf_container,
564 WmWindow* wm_status_container, 370 WmWindow* wm_status_container,
565 WmShelfAura* wm_shelf_aura, 371 WmShelfAura* wm_shelf_aura,
566 WorkspaceController* workspace_controller) 372 WorkspaceController* workspace_controller)
567 : delegate_view_(new DelegateView(this)), 373 : delegate_view_(new DelegateView(this)),
568 background_animator_(delegate_view_, 374 background_animator_(delegate_view_,
569 0, 375 0,
570 GetShelfConstant(SHELF_BACKGROUND_ALPHA)), 376 GetShelfConstant(SHELF_BACKGROUND_ALPHA)),
571 activating_as_fallback_(false) { 377 activating_as_fallback_(false) {
572 views::Widget::InitParams params( 378 views::Widget::InitParams params(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 aura::Window* status_container = 410 aura::Window* status_container =
605 WmWindowAura::GetAuraWindow(wm_status_container); 411 WmWindowAura::GetAuraWindow(wm_status_container);
606 status_container->SetLayoutManager( 412 status_container->SetLayoutManager(
607 new StatusAreaLayoutManager(status_container, this)); 413 new StatusAreaLayoutManager(status_container, this));
608 414
609 shelf_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( 415 shelf_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
610 new ShelfWindowTargeter(shelf_container, shelf_layout_manager_))); 416 new ShelfWindowTargeter(shelf_container, shelf_layout_manager_)));
611 status_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( 417 status_container->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
612 new ShelfWindowTargeter(status_container, shelf_layout_manager_))); 418 new ShelfWindowTargeter(status_container, shelf_layout_manager_)));
613 419
420 delegate_view_->set_dimmer(base::MakeUnique<ShelfDimmer>(this));
421
614 views::Widget::AddObserver(this); 422 views::Widget::AddObserver(this);
615 } 423 }
616 424
617 ShelfWidget::~ShelfWidget() { 425 ShelfWidget::~ShelfWidget() {
618 // Must call Shutdown() before destruction. 426 // Must call Shutdown() before destruction.
619 DCHECK(!status_area_widget_); 427 DCHECK(!status_area_widget_);
620 WmShell::Get()->focus_cycler()->RemoveWidget(this); 428 WmShell::Get()->focus_cycler()->RemoveWidget(this);
621 SetFocusCycler(nullptr); 429 SetFocusCycler(nullptr);
622 RemoveObserver(this); 430 RemoveObserver(this);
623 } 431 }
(...skipping 11 matching lines...) Expand all
635 opaque_background_animation->SetTransitionDuration( 443 opaque_background_animation->SetTransitionDuration(
636 base::TimeDelta::FromMilliseconds(kTimeToSwitchBackgroundMs)); 444 base::TimeDelta::FromMilliseconds(kTimeToSwitchBackgroundMs));
637 } 445 }
638 opaque_background->SetOpacity(target_opacity); 446 opaque_background->SetOpacity(target_opacity);
639 447
640 // TODO(mukai): use ui::Layer on both opaque_background and normal background 448 // TODO(mukai): use ui::Layer on both opaque_background and normal background
641 // retire background_animator_ at all. It would be simpler. 449 // retire background_animator_ at all. It would be simpler.
642 // See also DockedBackgroundWidget::SetPaintsBackground. 450 // See also DockedBackgroundWidget::SetPaintsBackground.
643 background_animator_.SetPaintsBackground( 451 background_animator_.SetPaintsBackground(
644 background_type != SHELF_BACKGROUND_DEFAULT, change_type); 452 background_type != SHELF_BACKGROUND_DEFAULT, change_type);
453
454 // Start or stop dimming as appropriate.
455 LOG(ERROR) << "MSW SetPaintsBackground this:" << this << " max:" << (backgroun d_type == SHELF_BACKGROUND_MAXIMIZED);
456 SetDimsShelf(background_type == SHELF_BACKGROUND_MAXIMIZED);
645 } 457 }
646 458
647 ShelfBackgroundType ShelfWidget::GetBackgroundType() const { 459 ShelfBackgroundType ShelfWidget::GetBackgroundType() const {
648 if (delegate_view_->opaque_background()->GetTargetOpacity() == 1.0f) 460 if (delegate_view_->opaque_background()->GetTargetOpacity() == 1.0f)
649 return SHELF_BACKGROUND_MAXIMIZED; 461 return SHELF_BACKGROUND_MAXIMIZED;
650 if (background_animator_.paints_background()) 462 if (background_animator_.paints_background())
651 return SHELF_BACKGROUND_OVERLAP; 463 return SHELF_BACKGROUND_OVERLAP;
652 464
653 return SHELF_BACKGROUND_DEFAULT; 465 return SHELF_BACKGROUND_DEFAULT;
654 } 466 }
655 467
656 void ShelfWidget::HideShelfBehindBlackBar(bool hide, int animation_time_ms) { 468 void ShelfWidget::HideShelfBehindBlackBar(bool hide, int animation_time_ms) {
657 if (IsShelfHiddenBehindBlackBar() == hide) 469 delegate_view_->SetShelfDimming(hide ? 1.0f : 0.0f, animation_time_ms);
658 return;
659
660 ui::Layer* opaque_foreground = delegate_view_->opaque_foreground();
661 float target_opacity = hide ? 1.0f : 0.0f;
662 std::unique_ptr<ui::ScopedLayerAnimationSettings> opaque_foreground_animation;
663 opaque_foreground_animation.reset(
664 new ui::ScopedLayerAnimationSettings(opaque_foreground->GetAnimator()));
665 opaque_foreground_animation->SetTransitionDuration(
666 base::TimeDelta::FromMilliseconds(animation_time_ms));
667 opaque_foreground_animation->SetPreemptionStrategy(
668 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
669
670 opaque_foreground->SetOpacity(target_opacity);
671 } 470 }
672 471
673 bool ShelfWidget::IsShelfHiddenBehindBlackBar() const { 472 bool ShelfWidget::IsShelfHiddenBehindBlackBar() const {
674 return delegate_view_->opaque_foreground()->GetTargetOpacity() != 0.0f; 473 return delegate_view_->opaque_foreground()->GetTargetOpacity() == 1.0f;
675 } 474 }
676 475
677 // static 476 // static
678 bool ShelfWidget::ShelfAlignmentAllowed() { 477 bool ShelfWidget::ShelfAlignmentAllowed() {
679 if (WmShell::Get()->system_tray_delegate()->IsUserSupervised()) 478 if (WmShell::Get()->system_tray_delegate()->IsUserSupervised())
680 return false; 479 return false;
681 480
682 LoginStatus login_status = 481 LoginStatus login_status =
683 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus(); 482 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus();
684 483
(...skipping 20 matching lines...) Expand all
705 // TODO(msw): This should not be called before |shelf_| is created. 504 // TODO(msw): This should not be called before |shelf_| is created.
706 return shelf_ ? shelf_->alignment() : SHELF_ALIGNMENT_BOTTOM_LOCKED; 505 return shelf_ ? shelf_->alignment() : SHELF_ALIGNMENT_BOTTOM_LOCKED;
707 } 506 }
708 507
709 void ShelfWidget::OnShelfAlignmentChanged() { 508 void ShelfWidget::OnShelfAlignmentChanged() {
710 status_area_widget_->SetShelfAlignment(GetAlignment()); 509 status_area_widget_->SetShelfAlignment(GetAlignment());
711 delegate_view_->SchedulePaint(); 510 delegate_view_->SchedulePaint();
712 } 511 }
713 512
714 void ShelfWidget::SetDimsShelf(bool dimming) { 513 void ShelfWidget::SetDimsShelf(bool dimming) {
514 LOG(ERROR) << "MSW SetDimsShelf A " << dimming;
515 // The shelf can only be dimmed when shown and the background is maximized.
516 dimming &= (GetBackgroundType() == SHELF_BACKGROUND_MAXIMIZED && shelf_ &&
517 shelf_->auto_hide_behavior() == SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
518
519 // Dimming is not possible nor useful when hidden behind a black bar.
520 if (IsShelfHiddenBehindBlackBar() || GetDimsShelf() == dimming)
521 return;
522
715 delegate_view_->SetDimmed(dimming); 523 delegate_view_->SetDimmed(dimming);
716 // Repaint all children, allowing updates to reflect dimmed state eg: 524 // Repaint all children, allowing updates to reflect dimmed state eg:
717 // status area background, app list button and overflow button. 525 // status area background, app list button and overflow button.
718 if (shelf_) 526 if (shelf_)
719 shelf_->SchedulePaint(); 527 shelf_->SchedulePaint();
720 status_area_widget_->SchedulePaint(); 528 status_area_widget_->SchedulePaint();
721 } 529 }
722 530
723 bool ShelfWidget::GetDimsShelf() const { 531 bool ShelfWidget::GetDimsShelf() const {
724 return delegate_view_->GetDimmed(); 532 return delegate_view_->opaque_foreground()->GetTargetOpacity() == kDimOpactiy;
725 } 533 }
726 534
727 void ShelfWidget::CreateShelf(WmShelfAura* wm_shelf_aura) { 535 void ShelfWidget::CreateShelf(WmShelfAura* wm_shelf_aura) {
728 DCHECK(!shelf_); 536 DCHECK(!shelf_);
729 537
730 shelf_.reset(new Shelf(WmShell::Get()->shelf_model(), wm_shelf_aura, this)); 538 shelf_.reset(new Shelf(WmShell::Get()->shelf_model(), wm_shelf_aura, this));
731 // Must be initialized before the delegate is notified because the delegate 539 // Must be initialized before the delegate is notified because the delegate
732 // may try to access the WmShelf. 540 // may try to access the WmShelf.
733 wm_shelf_aura->SetShelf(shelf_.get()); 541 wm_shelf_aura->SetShelf(shelf_.get());
734 WmShell::Get()->shelf_delegate()->OnShelfCreated(shelf_.get()); 542 WmShell::Get()->shelf_delegate()->OnShelfCreated(shelf_.get());
(...skipping 22 matching lines...) Expand all
757 delegate_view_->set_focus_cycler(focus_cycler); 565 delegate_view_->set_focus_cycler(focus_cycler);
758 if (focus_cycler) 566 if (focus_cycler)
759 focus_cycler->AddWidget(this); 567 focus_cycler->AddWidget(this);
760 } 568 }
761 569
762 FocusCycler* ShelfWidget::GetFocusCycler() { 570 FocusCycler* ShelfWidget::GetFocusCycler() {
763 return delegate_view_->focus_cycler(); 571 return delegate_view_->focus_cycler();
764 } 572 }
765 573
766 void ShelfWidget::Shutdown() { 574 void ShelfWidget::Shutdown() {
575 delegate_view_->set_dimmer(nullptr);
576
767 // Shutting down the status area widget may cause some widgets (e.g. bubbles) 577 // Shutting down the status area widget may cause some widgets (e.g. bubbles)
768 // to close, so uninstall the ShelfLayoutManager event filters first. Don't 578 // to close, so uninstall the ShelfLayoutManager event filters first. Don't
769 // reset the pointer until later because other widgets (e.g. app list) may 579 // reset the pointer until later because other widgets (e.g. app list) may
770 // access it later in shutdown. 580 // access it later in shutdown.
771 if (shelf_layout_manager_) 581 if (shelf_layout_manager_)
772 shelf_layout_manager_->PrepareForShutdown(); 582 shelf_layout_manager_->PrepareForShutdown();
773 583
774 if (status_area_widget_) { 584 if (status_area_widget_) {
775 WmShell::Get()->focus_cycler()->RemoveWidget(status_area_widget_); 585 WmShell::Get()->focus_cycler()->RemoveWidget(status_area_widget_);
776 status_area_widget_->Shutdown(); 586 status_area_widget_->Shutdown();
777 status_area_widget_ = nullptr; 587 status_area_widget_ = nullptr;
778 } 588 }
779 } 589 }
780 590
781 void ShelfWidget::ForceUndimming(bool force) { 591 void ShelfWidget::ForceUndimming(bool force) {
782 delegate_view_->ForceUndimming(force); 592 delegate_view_->ForceUndimming(force);
783 } 593 }
784 594
785 void ShelfWidget::OnWidgetActivationChanged(views::Widget* widget, 595 void ShelfWidget::OnWidgetActivationChanged(views::Widget* widget,
786 bool active) { 596 bool active) {
787 activating_as_fallback_ = false; 597 activating_as_fallback_ = false;
788 if (active) 598 if (active)
789 delegate_view_->SetPaneFocusAndFocusDefault(); 599 delegate_view_->SetPaneFocusAndFocusDefault();
790 else 600 else
791 delegate_view_->GetFocusManager()->ClearFocus(); 601 delegate_view_->GetFocusManager()->ClearFocus();
792 } 602 }
793 603
794 int ShelfWidget::GetDimmingAlphaForTest() {
795 if (delegate_view_)
796 return delegate_view_->GetDimmingAlphaForTest();
797 return -1;
798 }
799
800 gfx::Rect ShelfWidget::GetDimmerBoundsForTest() {
801 if (delegate_view_)
802 return delegate_view_->GetDimmerBoundsForTest();
803 return gfx::Rect();
804 }
805
806 void ShelfWidget::DisableDimmingAnimationsForTest() {
807 DCHECK(delegate_view_);
808 return delegate_view_->disable_dimming_animations_for_test();
809 }
810
811 void ShelfWidget::WillDeleteShelfLayoutManager() { 604 void ShelfWidget::WillDeleteShelfLayoutManager() {
812 shelf_layout_manager_->RemoveObserver(this); 605 shelf_layout_manager_->RemoveObserver(this);
813 shelf_layout_manager_ = NULL; 606 shelf_layout_manager_ = NULL;
814 } 607 }
815 608
609 void ShelfWidget::OnDragEnter() {
610 LOG(ERROR) << "MSW ShelfWidget::OnDragEnter";
611 SetDimsShelf(false);
612 }
613
614 void ShelfWidget::OnDragExit() {
615 LOG(ERROR) << "MSW ShelfWidget::OnDragExit";
616 SetDimsShelf(true);
617 }
618
816 void ShelfWidget::OnMouseEvent(ui::MouseEvent* event) { 619 void ShelfWidget::OnMouseEvent(ui::MouseEvent* event) {
817 Widget::OnMouseEvent(event); 620 Widget::OnMouseEvent(event);
818 if (Shell::GetInstance()->in_mus() && shelf_layout_manager_) 621 if (Shell::GetInstance()->in_mus() && shelf_layout_manager_)
819 shelf_layout_manager_->UpdateAutoHideForMouseEvent(event); 622 shelf_layout_manager_->UpdateAutoHideForMouseEvent(event);
820 } 623 }
821 624
822 void ShelfWidget::OnGestureEvent(ui::GestureEvent* event) { 625 void ShelfWidget::OnGestureEvent(ui::GestureEvent* event) {
823 Widget::OnGestureEvent(event); 626 Widget::OnGestureEvent(event);
824 if (Shell::GetInstance()->in_mus() && shelf_layout_manager_) 627 if (Shell::GetInstance()->in_mus() && shelf_layout_manager_)
825 shelf_layout_manager_->UpdateAutoHideForGestureEvent(event); 628 shelf_layout_manager_->UpdateAutoHideForGestureEvent(event);
826 } 629 }
827 630
828 } // namespace ash 631 } // namespace ash
OLDNEW
« no previous file with comments | « ash/shelf/shelf_widget.h ('k') | ui/views/widget/drop_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698