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

Side by Side Diff: ash/frame/caption_buttons/frame_caption_button_container_view.cc

Issue 343433009: Revert or Reland Window Control Animations for TouchView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 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 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> 8 #include <map>
9 9
10 #include "ash/ash_switches.h" 10 #include "ash/ash_switches.h"
11 #include "ash/frame/caption_buttons/frame_caption_button.h" 11 #include "ash/frame/caption_buttons/frame_caption_button.h"
12 #include "ash/frame/caption_buttons/frame_size_button.h" 12 #include "ash/frame/caption_buttons/frame_size_button.h"
13 #include "ash/metrics/user_metrics_recorder.h" 13 #include "ash/metrics/user_metrics_recorder.h"
14 #include "ash/shell.h" 14 #include "ash/shell.h"
15 #include "ash/wm/maximize_mode/maximize_mode_controller.h" 15 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
16 #include "grit/ui_strings.h" // Accessibility names 16 #include "grit/ui_strings.h" // Accessibility names
17 #include "ui/base/hit_test.h" 17 #include "ui/base/hit_test.h"
18 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/compositor/layer.h"
20 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 19 #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"
23 #include "ui/gfx/canvas.h" 20 #include "ui/gfx/canvas.h"
24 #include "ui/gfx/insets.h" 21 #include "ui/gfx/insets.h"
25 #include "ui/gfx/point.h" 22 #include "ui/gfx/point.h"
26 #include "ui/views/widget/widget.h" 23 #include "ui/views/widget/widget.h"
27 #include "ui/views/widget/widget_delegate.h" 24 #include "ui/views/widget/widget_delegate.h"
28 25
29 namespace ash { 26 namespace ash {
30 27
31 namespace { 28 namespace {
32 29
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 kAnimationDelayMs = 100;
38 const int kMinimizeSlideDurationMs = 500;
39 const int kSizeFadeDurationMs = 250;
40
41 // Converts |point| from |src| to |dst| and hittests against |dst|. 30 // Converts |point| from |src| to |dst| and hittests against |dst|.
42 bool ConvertPointToViewAndHitTest(const views::View* src, 31 bool ConvertPointToViewAndHitTest(const views::View* src,
43 const views::View* dst, 32 const views::View* dst,
44 const gfx::Point& point) { 33 const gfx::Point& point) {
45 gfx::Point converted(point); 34 gfx::Point converted(point);
46 views::View::ConvertPointToTarget(src, dst, &converted); 35 views::View::ConvertPointToTarget(src, dst, &converted);
47 return dst->HitTestPoint(converted); 36 return dst->HitTestPoint(converted);
48 } 37 }
49 38
50 } // namespace 39 } // namespace
51 40
52 // static 41 // static
53 const char FrameCaptionButtonContainerView::kViewClassName[] = 42 const char FrameCaptionButtonContainerView::kViewClassName[] =
54 "FrameCaptionButtonContainerView"; 43 "FrameCaptionButtonContainerView";
55 44
56 FrameCaptionButtonContainerView::FrameCaptionButtonContainerView( 45 FrameCaptionButtonContainerView::FrameCaptionButtonContainerView(
57 views::Widget* frame, 46 views::Widget* frame,
58 MinimizeAllowed minimize_allowed) 47 MinimizeAllowed minimize_allowed)
59 : frame_(frame), 48 : frame_(frame),
60 minimize_button_(NULL), 49 minimize_button_(NULL),
61 size_button_(NULL), 50 size_button_(NULL),
62 close_button_(NULL) { 51 close_button_(NULL) {
63 SetPaintToLayer(true);
64 SetFillsBoundsOpaquely(false);
65 set_layer_owner_delegate(this);
66
67 // Insert the buttons left to right. 52 // Insert the buttons left to right.
68 minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE); 53 minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE);
69 minimize_button_->SetAccessibleName( 54 minimize_button_->SetAccessibleName(
70 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE)); 55 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
71 minimize_button_->SetVisible(minimize_allowed == MINIMIZE_ALLOWED); 56 minimize_button_->SetVisible(minimize_allowed == MINIMIZE_ALLOWED);
72 AddChildView(minimize_button_); 57 AddChildView(minimize_button_);
73 58
74 size_button_ = new FrameSizeButton(this, frame, this); 59 size_button_ = new FrameSizeButton(this, frame, this);
75 size_button_->SetAccessibleName( 60 size_button_->SetAccessibleName(
76 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE)); 61 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 ConvertPointToViewAndHitTest(this, size_button_, point)) { 115 ConvertPointToViewAndHitTest(this, size_button_, point)) {
131 return HTMAXBUTTON; 116 return HTMAXBUTTON;
132 } else if (minimize_button_->visible() && 117 } else if (minimize_button_->visible() &&
133 ConvertPointToViewAndHitTest(this, minimize_button_, point)) { 118 ConvertPointToViewAndHitTest(this, minimize_button_, point)) {
134 return HTMINBUTTON; 119 return HTMINBUTTON;
135 } 120 }
136 return HTNOWHERE; 121 return HTNOWHERE;
137 } 122 }
138 123
139 void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility() { 124 void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility() {
140 bool visible = !Shell::GetInstance()->maximize_mode_controller()-> 125 size_button_->SetVisible(
126 !Shell::GetInstance()->maximize_mode_controller()->
141 IsMaximizeModeWindowManagerEnabled() && 127 IsMaximizeModeWindowManagerEnabled() &&
142 frame_->widget_delegate()->CanMaximize(); 128 frame_->widget_delegate()->CanMaximize());
143
144 // Turning visibility off prevents animations from rendering. Setting the
145 // size button visibility to false will occur after the animation.
146 if (visible) {
147 size_button_->SetVisible(true);
148 // Because we delay calling View::SetVisible(false) until the end of the
149 // animation, if SetVisible(true) is called mid-animation, the View still
150 // believes it is visible and will not update the target layer visibility.
151 size_button_->layer()->SetVisible(true);
152 }
153
154 ui::ScopedLayerAnimationSettings settings(
155 size_button_->layer()->GetAnimator());
156 settings.SetTransitionDuration(
157 base::TimeDelta::FromMilliseconds(kSizeFadeDurationMs));
158 settings.SetPreemptionStrategy(
159 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
160
161 if (visible) {
162 settings.SetTweenType(gfx::Tween::EASE_OUT);
163 // Delay fade in so that the minimize button has begun its sliding
164 // animation.
165 size_button_->layer()->GetAnimator()->SchedulePauseForProperties(
166 base::TimeDelta::FromMilliseconds(kAnimationDelayMs),
167 ui::LayerAnimationElement::OPACITY);
168 size_button_->layer()->SetOpacity(1.0f);
169 } else {
170 settings.SetTweenType(gfx::Tween::EASE_IN);
171 // Observer will call size_button_->SetVisible(false) upon completion of
172 // the animation.
173 // TODO(jonross): avoid the delayed SetVisible(false) call by acquring
174 // the size_button's layer before making it invisible. That layer can then
175 // be animated and deleted upon completion of the animation. See
176 // LayerOwner::RecreateLayer
177 settings.AddObserver(this);
178 size_button_->layer()->SetOpacity(0.0f);
179 size_button_->layer()->SetVisible(false);
180 }
181 } 129 }
182 130
183 gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() const { 131 gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() const {
184 int width = 0; 132 int width = 0;
185 for (int i = 0; i < child_count(); ++i) { 133 for (int i = 0; i < child_count(); ++i) {
186 const views::View* child = child_at(i); 134 const views::View* child = child_at(i);
187 if (child->visible()) 135 if (child->visible())
188 width += child_at(i)->GetPreferredSize().width(); 136 width += child_at(i)->GetPreferredSize().width();
189 } 137 }
190 return gfx::Size(width, close_button_->GetPreferredSize().height()); 138 return gfx::Size(width, close_button_->GetPreferredSize().height());
191 } 139 }
192 140
193 void FrameCaptionButtonContainerView::Layout() { 141 void FrameCaptionButtonContainerView::Layout() {
194 int x = width(); 142 int x = 0;
195 // Offsets the initial position of a child, so that buttons slide into the 143 for (int i = 0; i < child_count(); ++i) {
196 // place as other buttons are added/removed.
197 int offset_x = 0;
198 for (int i = child_count() - 1; i >= 0; --i) {
199 views::View* child = child_at(i); 144 views::View* child = child_at(i);
200 ui::LayerAnimator* child_animator = child->layer()->GetAnimator(); 145 if (!child->visible())
201 bool child_animating = child_animator->is_animating();
202 // The actual property visibility is not being animated, otherwise the
203 // view does not render.
204 bool child_animating_opacity = child_animator->
205 IsAnimatingProperty(ui::LayerAnimationElement::OPACITY);
206 bool child_target_visibility = child->layer()->GetTargetVisibility();
207
208 if (child_animating_opacity) {
209 if (child_target_visibility)
210 offset_x += child->width();
211 else
212 offset_x -= child->width();
213 }
214
215 if (!child->visible() || !child_target_visibility)
216 continue; 146 continue;
217 147
218 scoped_ptr<ui::ScopedLayerAnimationSettings> animation;
219 gfx::Size size = child->GetPreferredSize(); 148 gfx::Size size = child->GetPreferredSize();
220 x -= size.width();
221
222 // Animate the button if a previous button is currently animating
223 // its visibility.
224 if (offset_x != 0) {
225 if (!child_animating)
226 child->SetBounds(x + offset_x, 0, size.width(), size.height());
227 if (offset_x < 0) {
228 // Delay sliding to where the previous button was located.
229 child_animator->SchedulePauseForProperties(
230 base::TimeDelta::FromMilliseconds(kAnimationDelayMs),
231 ui::LayerAnimationElement::BOUNDS);
232 }
233
234 ui::ScopedLayerAnimationSettings* settings =
235 new ui::ScopedLayerAnimationSettings(child_animator);
236 settings->SetTransitionDuration(
237 base::TimeDelta::FromMilliseconds(kMinimizeSlideDurationMs));
238 settings->SetPreemptionStrategy(
239 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
240 settings->SetTweenType(gfx::Tween::EASE_OUT);
241 animation.reset(settings);
242 }
243 child->SetBounds(x, 0, size.width(), size.height()); 149 child->SetBounds(x, 0, size.width(), size.height());
150 x += size.width();
244 } 151 }
245 } 152 }
246 153
247 const char* FrameCaptionButtonContainerView::GetClassName() const { 154 const char* FrameCaptionButtonContainerView::GetClassName() const {
248 return kViewClassName; 155 return kViewClassName;
249 } 156 }
250 157
251 void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button, 158 void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button,
252 CaptionButtonIcon icon, 159 CaptionButtonIcon icon,
253 Animate animate) { 160 Animate animate) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 FrameCaptionButton* button = buttons[i]; 279 FrameCaptionButton* button = buttons[i];
373 views::Button::ButtonState new_state = views::Button::STATE_NORMAL; 280 views::Button::ButtonState new_state = views::Button::STATE_NORMAL;
374 if (button == to_hover) 281 if (button == to_hover)
375 new_state = views::Button::STATE_HOVERED; 282 new_state = views::Button::STATE_HOVERED;
376 else if (button == to_press) 283 else if (button == to_press)
377 new_state = views::Button::STATE_PRESSED; 284 new_state = views::Button::STATE_PRESSED;
378 button->SetState(new_state); 285 button->SetState(new_state);
379 } 286 }
380 } 287 }
381 288
382 void FrameCaptionButtonContainerView::OnImplicitAnimationsCompleted() {
383 // If there is another animation in the queue, the reverse animation was
384 // triggered before the completion of animating to invisible. Do not turn off
385 // the visibility so that the next animation may render.
386 if (!size_button_->layer()->GetAnimator()->is_animating() &&
387 !size_button_->layer()->GetTargetVisibility()) {
388 size_button_->SetVisible(false);
389 }
390 // TODO(jonross): currently we need to delay telling the parent about the
391 // size change from visibility. When the size changes this forces a relayout
392 // and we want to animate both the bounds of FrameCaptionButtonContainerView
393 // along with that of its children. However when the parent is currently
394 // having its bounds changed this leads to strange animations where this view
395 // renders outside of its parents. Create a more specific animation where
396 // height and y are immediately fixed, and where we only animate width and x.
397 PreferredSizeChanged();
398 }
399
400 void FrameCaptionButtonContainerView::OnLayerRecreated(ui::Layer* old_layer,
401 ui::Layer* new_layer) {
402 GetWidget()->UpdateRootLayers();
403 }
404
405 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds() 289 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds()
406 : icon_image_id(-1), 290 : icon_image_id(-1),
407 inactive_icon_image_id(-1), 291 inactive_icon_image_id(-1),
408 hovered_background_image_id(-1), 292 hovered_background_image_id(-1),
409 pressed_background_image_id(-1) { 293 pressed_background_image_id(-1) {
410 } 294 }
411 295
412 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds( 296 FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds(
413 int icon_id, 297 int icon_id,
414 int inactive_icon_id, 298 int inactive_icon_id,
415 int hovered_background_id, 299 int hovered_background_id,
416 int pressed_background_id) 300 int pressed_background_id)
417 : icon_image_id(icon_id), 301 : icon_image_id(icon_id),
418 inactive_icon_image_id(inactive_icon_id), 302 inactive_icon_image_id(inactive_icon_id),
419 hovered_background_image_id(hovered_background_id), 303 hovered_background_image_id(hovered_background_id),
420 pressed_background_image_id(pressed_background_id) { 304 pressed_background_image_id(pressed_background_id) {
421 } 305 }
422 306
423 FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() { 307 FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() {
424 } 308 }
425 309
426 } // namespace ash 310 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698