OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/frame/caption_buttons/frame_caption_button_container_view.h" | 5 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <map> | |
flackr
2014/05/08 19:02:21
unused?
jonross
2014/05/08 21:15:40
Cpplint, used outside my changed.
| |
8 | 9 |
9 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
10 #include "ash/frame/caption_buttons/alternate_frame_size_button.h" | 11 #include "ash/frame/caption_buttons/alternate_frame_size_button.h" |
11 #include "ash/frame/caption_buttons/frame_caption_button.h" | 12 #include "ash/frame/caption_buttons/frame_caption_button.h" |
12 #include "ash/frame/caption_buttons/frame_maximize_button.h" | 13 #include "ash/frame/caption_buttons/frame_maximize_button.h" |
13 #include "ash/metrics/user_metrics_recorder.h" | 14 #include "ash/metrics/user_metrics_recorder.h" |
14 #include "ash/shell.h" | 15 #include "ash/shell.h" |
15 #include "grit/ui_strings.h" // Accessibility names | 16 #include "grit/ui_strings.h" // Accessibility names |
16 #include "ui/base/hit_test.h" | 17 #include "ui/base/hit_test.h" |
17 #include "ui/base/l10n/l10n_util.h" | 18 #include "ui/base/l10n/l10n_util.h" |
19 #include "ui/compositor/layer.h" | |
18 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 20 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
21 #include "ui/compositor/scoped_layer_animation_settings.h" | |
22 #include "ui/gfx/animation/tween.h" | |
19 #include "ui/gfx/canvas.h" | 23 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/insets.h" | 24 #include "ui/gfx/insets.h" |
21 #include "ui/gfx/point.h" | 25 #include "ui/gfx/point.h" |
22 #include "ui/views/widget/widget.h" | 26 #include "ui/views/widget/widget.h" |
23 #include "ui/views/widget/widget_delegate.h" | 27 #include "ui/views/widget/widget_delegate.h" |
24 | 28 |
25 namespace ash { | 29 namespace ash { |
26 | 30 |
27 namespace { | 31 namespace { |
28 | 32 |
33 // Visual design parameters for animating the transition to maximize mode. | |
34 // When the size button hides we delay sliding the minimize button into its | |
35 // location. Also used to delay showing the size button so that the minimize | |
36 // button slides out of that position. | |
37 const int kAnimationDelay = 100; | |
flackr
2014/05/08 19:02:21
Units?
jonross
2014/05/08 21:15:40
Done.
| |
38 const int kMinimizeSlideDuration = 500; | |
39 const int kSizeFadeDuration = 250; | |
40 | |
29 // Converts |point| from |src| to |dst| and hittests against |dst|. | 41 // Converts |point| from |src| to |dst| and hittests against |dst|. |
30 bool ConvertPointToViewAndHitTest(const views::View* src, | 42 bool ConvertPointToViewAndHitTest(const views::View* src, |
31 const views::View* dst, | 43 const views::View* dst, |
32 const gfx::Point& point) { | 44 const gfx::Point& point) { |
33 gfx::Point converted(point); | 45 gfx::Point converted(point); |
34 views::View::ConvertPointToTarget(src, dst, &converted); | 46 views::View::ConvertPointToTarget(src, dst, &converted); |
35 return dst->HitTestPoint(converted); | 47 return dst->HitTestPoint(converted); |
36 } | 48 } |
37 | 49 |
38 } // namespace | 50 } // namespace |
39 | 51 |
40 // static | 52 // static |
41 const char FrameCaptionButtonContainerView::kViewClassName[] = | 53 const char FrameCaptionButtonContainerView::kViewClassName[] = |
42 "FrameCaptionButtonContainerView"; | 54 "FrameCaptionButtonContainerView"; |
43 | 55 |
44 FrameCaptionButtonContainerView::FrameCaptionButtonContainerView( | 56 FrameCaptionButtonContainerView::FrameCaptionButtonContainerView( |
45 views::Widget* frame, | 57 views::Widget* frame, |
46 MinimizeAllowed minimize_allowed) | 58 MinimizeAllowed minimize_allowed) |
47 : frame_(frame), | 59 : frame_(frame), |
48 minimize_button_(NULL), | 60 minimize_button_(NULL), |
49 size_button_(NULL), | 61 size_button_(NULL), |
50 close_button_(NULL) { | 62 close_button_(NULL) { |
51 bool alternate_style = switches::UseAlternateFrameCaptionButtonStyle(); | 63 bool alternate_style = switches::UseAlternateFrameCaptionButtonStyle(); |
52 | 64 |
65 SetPaintToLayer(true); | |
66 SetFillsBoundsOpaquely(false); | |
67 | |
53 // Insert the buttons left to right. | 68 // Insert the buttons left to right. |
54 minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE); | 69 minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE); |
55 minimize_button_->SetAccessibleName( | 70 minimize_button_->SetAccessibleName( |
56 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE)); | 71 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE)); |
57 // Hide |minimize_button_| when using the non-alternate button style because | 72 // Hide |minimize_button_| when using the non-alternate button style because |
58 // |size_button_| is capable of minimizing in this case. | 73 // |size_button_| is capable of minimizing in this case. |
59 minimize_button_->SetVisible( | 74 minimize_button_->SetVisible( |
60 minimize_allowed == MINIMIZE_ALLOWED && | 75 minimize_allowed == MINIMIZE_ALLOWED && |
61 (alternate_style || !frame_->widget_delegate()->CanMaximize())); | 76 (alternate_style || !frame_->widget_delegate()->CanMaximize())); |
77 minimize_button_->SetPaintToLayer(true); | |
78 minimize_button_->SetFillsBoundsOpaquely(false); | |
62 AddChildView(minimize_button_); | 79 AddChildView(minimize_button_); |
63 | 80 |
64 if (alternate_style) | 81 if (alternate_style) |
65 size_button_ = new AlternateFrameSizeButton(this, frame, this); | 82 size_button_ = new AlternateFrameSizeButton(this, frame, this); |
66 else | 83 else |
67 size_button_ = new FrameMaximizeButton(this, frame); | 84 size_button_ = new FrameMaximizeButton(this, frame); |
68 size_button_->SetAccessibleName( | 85 size_button_->SetAccessibleName( |
69 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE)); | 86 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE)); |
87 size_button_->SetPaintToLayer(true); | |
88 size_button_->SetFillsBoundsOpaquely(false); | |
70 UpdateSizeButtonVisibility(false); | 89 UpdateSizeButtonVisibility(false); |
71 AddChildView(size_button_); | 90 AddChildView(size_button_); |
72 | 91 |
73 close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE); | 92 close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE); |
74 close_button_->SetAccessibleName( | 93 close_button_->SetAccessibleName( |
75 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); | 94 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE)); |
95 close_button_->SetPaintToLayer(true); | |
96 close_button_->SetFillsBoundsOpaquely(false); | |
76 AddChildView(close_button_); | 97 AddChildView(close_button_); |
77 } | 98 } |
78 | 99 |
79 FrameCaptionButtonContainerView::~FrameCaptionButtonContainerView() { | 100 FrameCaptionButtonContainerView::~FrameCaptionButtonContainerView() { |
80 } | 101 } |
81 | 102 |
82 FrameMaximizeButton* | 103 FrameMaximizeButton* |
83 FrameCaptionButtonContainerView::GetOldStyleSizeButton() { | 104 FrameCaptionButtonContainerView::GetOldStyleSizeButton() { |
84 return switches::UseAlternateFrameCaptionButtonStyle() ? | 105 return switches::UseAlternateFrameCaptionButtonStyle() ? |
85 NULL : static_cast<FrameMaximizeButton*>(size_button_); | 106 NULL : static_cast<FrameMaximizeButton*>(size_button_); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 } | 157 } |
137 | 158 |
138 void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility( | 159 void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility( |
139 bool force_hidden) { | 160 bool force_hidden) { |
140 // TODO(flackr): Refactor the Maximize Mode notifications. Currently | 161 // TODO(flackr): Refactor the Maximize Mode notifications. Currently |
141 // UpdateSizeButtonVisibilty requires a force_hidden parameter. This is | 162 // UpdateSizeButtonVisibilty requires a force_hidden parameter. This is |
142 // because Shell::IsMaximizeWindowManagerEnabled is still false at the | 163 // because Shell::IsMaximizeWindowManagerEnabled is still false at the |
143 // time when ShellObserver::OnMaximizeModeStarted is called. This prevents | 164 // time when ShellObserver::OnMaximizeModeStarted is called. This prevents |
144 // this method from performing that check, and instead relies on the calling | 165 // this method from performing that check, and instead relies on the calling |
145 // code to tell it to force being hidden. | 166 // code to tell it to force being hidden. |
146 size_button_->SetVisible( | 167 |
147 !force_hidden && frame_->widget_delegate()->CanMaximize()); | 168 bool visible = !force_hidden && frame_->widget_delegate()->CanMaximize(); |
169 | |
170 // Turning visibility off prevents animations from rendering. Setting the | |
171 // size button visibility to false will occur after the animation. | |
172 if (visible) | |
173 size_button_->SetVisible(visible); | |
174 | |
175 ui::ScopedLayerAnimationSettings settings( | |
176 size_button_->layer()->GetAnimator()); | |
177 settings.SetTransitionDuration( | |
178 base::TimeDelta::FromMilliseconds(kSizeFadeDuration)); | |
179 settings.SetPreemptionStrategy( | |
180 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
181 | |
182 if (visible) { | |
183 settings.SetTweenType(gfx::Tween::EASE_OUT); | |
184 // Delay fade in so that the minimize button has begun its sliding | |
185 // animation. For visual design. | |
186 size_button_->layer()->GetAnimator()->SchedulePauseForProperties( | |
187 base::TimeDelta::FromMilliseconds(kAnimationDelay), | |
188 ui::LayerAnimationElement::OPACITY); | |
189 size_button_->layer()->SetOpacity(1.0f); | |
190 } else { | |
191 settings.SetTweenType(gfx::Tween::EASE_IN); | |
192 settings.AddObserver(this); | |
flackr
2014/05/08 19:02:21
nit: comment this will SetVisible(false) when anim
jonross
2014/05/08 21:15:40
Done.
| |
193 size_button_->layer()->SetOpacity(0.0f); | |
flackr
2014/05/08 19:02:21
Also ->SetVisible(false);
jonross
2014/05/08 21:15:40
Done.
| |
194 } | |
148 } | 195 } |
149 | 196 |
150 gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() { | 197 gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() { |
151 int width = 0; | 198 int width = 0; |
152 for (int i = 0; i < child_count(); ++i) { | 199 for (int i = 0; i < child_count(); ++i) { |
153 views::View* child = child_at(i); | 200 views::View* child = child_at(i); |
154 if (child->visible()) | 201 if (child->visible()) |
155 width += child_at(i)->GetPreferredSize().width(); | 202 width += child_at(i)->GetPreferredSize().width(); |
156 } | 203 } |
157 return gfx::Size(width, close_button_->GetPreferredSize().height()); | 204 return gfx::Size(width, close_button_->GetPreferredSize().height()); |
158 } | 205 } |
159 | 206 |
160 void FrameCaptionButtonContainerView::Layout() { | 207 void FrameCaptionButtonContainerView::Layout() { |
161 int x = 0; | 208 scoped_ptr<ui::ScopedLayerAnimationSettings> animation; |
162 for (int i = 0; i < child_count(); ++i) { | 209 int x = width(); |
210 for (int i = child_count() - 1; i >= 0; --i) { | |
163 views::View* child = child_at(i); | 211 views::View* child = child_at(i); |
164 if (!child->visible()) | 212 if (!child->visible() || |
213 (child == size_button_ && child->layer()->GetTargetOpacity() == 0.0f)) | |
flackr
2014/05/08 19:02:21
GetTargetVisibility. Try to avoid making this spec
jonross
2014/05/08 21:15:40
Done.
| |
165 continue; | 214 continue; |
166 | 215 |
167 gfx::Size size = child->GetPreferredSize(); | 216 gfx::Size size = child->GetPreferredSize(); |
217 // Animate the minimize button if the size button is currently animating | |
218 // its visibility. | |
219 if (child == minimize_button_ && | |
220 size_button_->layer()->GetAnimator()->is_animating()) { | |
flackr
2014/05/08 19:02:21
This is awfully specific to the button that's goin
jonross
2014/05/08 21:15:40
Done.
| |
221 if (size_button_->layer()->GetTargetOpacity() == 1.0f) { | |
222 child->SetBounds(x, 0, size.width(), size.height()); | |
223 } else { | |
224 // Delay sliding to where the size button was located. For visual | |
225 // design. | |
226 child->layer()->GetAnimator()->SchedulePauseForProperties( | |
227 base::TimeDelta::FromMilliseconds(kAnimationDelay), | |
228 ui::LayerAnimationElement::BOUNDS); | |
229 } | |
230 | |
231 ui::ScopedLayerAnimationSettings* settings = | |
232 new ui::ScopedLayerAnimationSettings(child->layer()->GetAnimator()); | |
233 settings->SetTransitionDuration( | |
234 base::TimeDelta::FromMilliseconds(kMinimizeSlideDuration)); | |
235 settings->SetPreemptionStrategy( | |
236 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
237 settings->SetTweenType(gfx::Tween::EASE_OUT); | |
238 animation.reset(settings); | |
239 } | |
240 x -= size.width(); | |
168 child->SetBounds(x, 0, size.width(), size.height()); | 241 child->SetBounds(x, 0, size.width(), size.height()); |
169 x += size.width(); | |
170 } | 242 } |
171 } | 243 } |
172 | 244 |
173 const char* FrameCaptionButtonContainerView::GetClassName() const { | 245 const char* FrameCaptionButtonContainerView::GetClassName() const { |
174 return kViewClassName; | 246 return kViewClassName; |
175 } | 247 } |
176 | 248 |
177 void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button, | 249 void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button, |
178 CaptionButtonIcon icon, | 250 CaptionButtonIcon icon, |
179 Animate animate) { | 251 Animate animate) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 } | 283 } |
212 | 284 |
213 // Abort any animations of the button icons. | 285 // Abort any animations of the button icons. |
214 SetButtonsToNormal(ANIMATE_NO); | 286 SetButtonsToNormal(ANIMATE_NO); |
215 | 287 |
216 ash::UserMetricsAction action = | 288 ash::UserMetricsAction action = |
217 ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE; | 289 ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE; |
218 if (sender == minimize_button_) { | 290 if (sender == minimize_button_) { |
219 frame_->Minimize(); | 291 frame_->Minimize(); |
220 } else if (sender == size_button_) { | 292 } else if (sender == size_button_) { |
221 if (frame_->IsFullscreen()) { // Can be clicked in immersive fullscreen. | 293 if (frame_->IsFullscreen()) { // Can be clicked in immersive fullscreen. |
flackr
2014/05/08 19:02:21
Why two spaces before comment?
jonross
2014/05/08 21:15:40
cpplint marked this.
| |
222 frame_->SetFullscreen(false); | 294 frame_->SetFullscreen(false); |
223 action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_EXIT_FULLSCREEN; | 295 action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_EXIT_FULLSCREEN; |
224 } else if (frame_->IsMaximized()) { | 296 } else if (frame_->IsMaximized()) { |
225 frame_->Restore(); | 297 frame_->Restore(); |
226 action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE; | 298 action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE; |
227 } else { | 299 } else { |
228 frame_->Maximize(); | 300 frame_->Maximize(); |
229 action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE; | 301 action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE; |
230 } | 302 } |
231 } else if(sender == close_button_) { | 303 } else if (sender == close_button_) { |
232 frame_->Close(); | 304 frame_->Close(); |
233 action = ash::UMA_WINDOW_CLOSE_BUTTON_CLICK; | 305 action = ash::UMA_WINDOW_CLOSE_BUTTON_CLICK; |
234 } else { | 306 } else { |
235 return; | 307 return; |
236 } | 308 } |
237 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(action); | 309 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(action); |
238 } | 310 } |
239 | 311 |
240 bool FrameCaptionButtonContainerView::IsMinimizeButtonVisible() const { | 312 bool FrameCaptionButtonContainerView::IsMinimizeButtonVisible() const { |
241 return minimize_button_->visible(); | 313 return minimize_button_->visible(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 FrameCaptionButton* button = buttons[i]; | 370 FrameCaptionButton* button = buttons[i]; |
299 views::Button::ButtonState new_state = views::Button::STATE_NORMAL; | 371 views::Button::ButtonState new_state = views::Button::STATE_NORMAL; |
300 if (button == to_hover) | 372 if (button == to_hover) |
301 new_state = views::Button::STATE_HOVERED; | 373 new_state = views::Button::STATE_HOVERED; |
302 else if (button == to_press) | 374 else if (button == to_press) |
303 new_state = views::Button::STATE_PRESSED; | 375 new_state = views::Button::STATE_PRESSED; |
304 button->SetState(new_state); | 376 button->SetState(new_state); |
305 } | 377 } |
306 } | 378 } |
307 | 379 |
380 void FrameCaptionButtonContainerView::OnImplicitAnimationsCompleted() { | |
381 size_button_->SetVisible(false); | |
382 // TODO(jonross): currently we need to delay telling the parent about the | |
383 // size change from visibility. When the size changes this forces a relayout | |
384 // and we want to animate both the bounds of FrameCaptionButtonContainerView | |
385 // along with that of its children. However when the parent is currently | |
386 // having its bounds changed this leads to strange animations where this view | |
387 // renders outside of its parents. Create a more specific animation where | |
flackr
2014/05/08 19:02:21
Can we avoid this by animating Translate transform
| |
388 // height and y are immediately fixed, and where we only animate width and x. | |
389 PreferredSizeChanged(); | |
390 } | |
391 | |
308 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds() | 392 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds() |
309 : icon_image_id(-1), | 393 : icon_image_id(-1), |
310 inactive_icon_image_id(-1), | 394 inactive_icon_image_id(-1), |
311 hovered_background_image_id(-1), | 395 hovered_background_image_id(-1), |
312 pressed_background_image_id(-1) { | 396 pressed_background_image_id(-1) { |
313 } | 397 } |
314 | 398 |
315 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds( | 399 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds( |
316 int icon_id, | 400 int icon_id, |
317 int inactive_icon_id, | 401 int inactive_icon_id, |
318 int hovered_background_id, | 402 int hovered_background_id, |
319 int pressed_background_id) | 403 int pressed_background_id) |
320 : icon_image_id(icon_id), | 404 : icon_image_id(icon_id), |
321 inactive_icon_image_id(inactive_icon_id), | 405 inactive_icon_image_id(inactive_icon_id), |
322 hovered_background_image_id(hovered_background_id), | 406 hovered_background_image_id(hovered_background_id), |
323 pressed_background_image_id(pressed_background_id) { | 407 pressed_background_image_id(pressed_background_id) { |
324 } | 408 } |
325 | 409 |
326 FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() { | 410 FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() { |
327 } | 411 } |
328 | 412 |
329 } // namespace ash | 413 } // namespace ash |
OLD | NEW |