• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "ash/wm/caption_buttons/frame_caption_button.h"
6 
7 #include "grit/ash_resources.h"
8 #include "ui/base/resource/resource_bundle.h"
9 #include "ui/gfx/animation/slide_animation.h"
10 #include "ui/gfx/canvas.h"
11 
12 namespace ash {
13 
14 namespace {
15 
16 // The duration of the crossfade animation when swapping the button's icon.
17 const int kCrossfadeDurationMs = 200;
18 
19 }  // namespace
20 
21 // static
22 const char FrameCaptionButton::kViewClassName[] = "FrameCaptionButton";
23 
FrameCaptionButton(views::ButtonListener * listener,CaptionButtonIcon icon)24 FrameCaptionButton::FrameCaptionButton(views::ButtonListener* listener,
25                                        CaptionButtonIcon icon)
26     : ImageButton(listener),
27       icon_(icon),
28       style_(STYLE_SHORT_RESTORED),
29       last_paint_scale_(1.0f),
30       animation_(new gfx::SlideAnimation(this)) {
31   animation_->Reset(1);
32   UpdateImages();
33 }
34 
~FrameCaptionButton()35 FrameCaptionButton::~FrameCaptionButton() {
36 }
37 
SetIcon(CaptionButtonIcon icon,Animate animate)38 void FrameCaptionButton::SetIcon(CaptionButtonIcon icon, Animate animate) {
39   if (icon_ == icon)
40     return;
41 
42   if (animate == ANIMATE_YES) {
43     gfx::Canvas canvas(size(), last_paint_scale_, false);
44     OnPaint(&canvas);
45     crossfade_image_ = gfx::ImageSkia(canvas.ExtractImageRep());
46 
47     icon_ = icon;
48     UpdateImages();
49 
50     animation_->Reset(0);
51     animation_->SetSlideDuration(kCrossfadeDurationMs);
52     animation_->Show();
53   } else {
54     animation_->Reset(1);
55     icon_ = icon;
56     UpdateImages();
57   }
58 }
59 
SetStyle(Style style)60 void FrameCaptionButton::SetStyle(Style style) {
61   if (style_ == style)
62     return;
63   animation_->Reset(1);
64   style_ = style;
65   UpdateImages();
66 }
67 
GetClassName() const68 const char* FrameCaptionButton::GetClassName() const {
69   return kViewClassName;
70 }
71 
OnPaint(gfx::Canvas * canvas)72 void FrameCaptionButton::OnPaint(gfx::Canvas* canvas) {
73   last_paint_scale_ = canvas->image_scale();
74   int alpha = static_cast<int>(animation_->GetCurrentValue() * 255);
75   int crossfade_alpha = 255 - alpha;
76   if (crossfade_alpha > 0 && !crossfade_image_.isNull()) {
77     gfx::Canvas composed_canvas(size(), last_paint_scale_, false);
78     SkPaint paint;
79     paint.setAlpha(crossfade_alpha);
80     paint.setXfermodeMode(SkXfermode::kPlus_Mode);
81     composed_canvas.DrawImageInt(crossfade_image_, 0, 0, paint);
82     paint.setAlpha(alpha);
83     ImageButton::OnPaint(&composed_canvas);
84 
85     canvas->DrawImageInt(
86         gfx::ImageSkia(composed_canvas.ExtractImageRep()), 0, 0);
87   } else {
88     ImageButton::OnPaint(canvas);
89   }
90 }
91 
OnGestureEvent(ui::GestureEvent * event)92 void FrameCaptionButton::OnGestureEvent(ui::GestureEvent* event) {
93   // ImageButton does not become pressed when the user drags off and then back
94   // onto the button. Make FrameCaptionButton pressed in this case because this
95   // behavior is more consistent with AlternateFrameSizeButton.
96   if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
97       event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
98     if (HitTestPoint(event->location())) {
99       SetState(STATE_PRESSED);
100       RequestFocus();
101       event->StopPropagation();
102     } else {
103       SetState(STATE_NORMAL);
104     }
105   } else if (event->type() == ui::ET_GESTURE_SCROLL_END) {
106     if (HitTestPoint(event->location())) {
107       SetState(STATE_HOVERED);
108       NotifyClick(*event);
109       event->StopPropagation();
110     }
111   }
112   ImageButton::OnGestureEvent(event);
113 }
114 
StateChanged()115 void FrameCaptionButton::StateChanged() {
116   if (state_ == STATE_HOVERED || state_ == STATE_PRESSED)
117     animation_->Reset(1);
118 }
119 
UpdateImages()120 void FrameCaptionButton::UpdateImages() {
121   switch (icon_) {
122     case CAPTION_BUTTON_ICON_MINIMIZE:
123       SetImages(IDR_AURA_WINDOW_MINIMIZE_SHORT,
124                 IDR_AURA_WINDOW_MINIMIZE_SHORT_H,
125                 IDR_AURA_WINDOW_MINIMIZE_SHORT_P);
126       break;
127    case CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE:
128    case CAPTION_BUTTON_ICON_LEFT_SNAPPED:
129    case CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
130      if (style_ == STYLE_SHORT_MAXIMIZED_OR_FULLSCREEN) {
131        SetImages(IDR_AURA_WINDOW_MAXIMIZED_RESTORE2,
132                  IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_H,
133                  IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_P);
134      } else if (style_ == STYLE_SHORT_RESTORED) {
135        SetImages(IDR_AURA_WINDOW_MAXIMIZED_RESTORE,
136                  IDR_AURA_WINDOW_MAXIMIZED_RESTORE_H,
137                  IDR_AURA_WINDOW_MAXIMIZED_RESTORE_P);
138      } else {
139        SetImages(IDR_AURA_WINDOW_MAXIMIZE,
140                  IDR_AURA_WINDOW_MAXIMIZE_H,
141                  IDR_AURA_WINDOW_MAXIMIZE_P);
142      }
143      break;
144    case CAPTION_BUTTON_ICON_CLOSE:
145      if (style_ == STYLE_SHORT_MAXIMIZED_OR_FULLSCREEN) {
146        SetImages(IDR_AURA_WINDOW_MAXIMIZED_CLOSE2,
147                  IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_H,
148                  IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_P);
149      } else if (style_ == STYLE_SHORT_RESTORED) {
150        SetImages(IDR_AURA_WINDOW_MAXIMIZED_CLOSE,
151                  IDR_AURA_WINDOW_MAXIMIZED_CLOSE_H,
152                  IDR_AURA_WINDOW_MAXIMIZED_CLOSE_P);
153      } else {
154        SetImages(IDR_AURA_WINDOW_CLOSE,
155                  IDR_AURA_WINDOW_CLOSE_H,
156                  IDR_AURA_WINDOW_CLOSE_P);
157      }
158      break;
159   }
160 
161   SchedulePaint();
162 }
163 
SetImages(int normal_image_id,int hot_image_id,int pushed_image_id)164 void FrameCaptionButton::SetImages(int normal_image_id,
165                                    int hot_image_id,
166                                    int pushed_image_id) {
167   ui::ResourceBundle& resource_bundle = ui::ResourceBundle::GetSharedInstance();
168   SetImage(STATE_NORMAL, resource_bundle.GetImageSkiaNamed(normal_image_id));
169   SetImage(STATE_HOVERED, resource_bundle.GetImageSkiaNamed(hot_image_id));
170   SetImage(STATE_PRESSED, resource_bundle.GetImageSkiaNamed(pushed_image_id));
171 }
172 
AnimationProgressed(const gfx::Animation * animation)173 void FrameCaptionButton::AnimationProgressed(const gfx::Animation* animation) {
174   SchedulePaint();
175 }
176 
177 }  // namespace ash
178