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 #ifndef UI_VIEWS_WINDOW_FRAME_CAPTION_BUTTON_H_
6 #define UI_VIEWS_WINDOW_FRAME_CAPTION_BUTTON_H_
7 
8 #include <memory>
9 
10 #include "base/macros.h"
11 #include "ui/gfx/image/image_skia.h"
12 #include "ui/views/controls/button/button.h"
13 #include "ui/views/controls/focus_ring.h"
14 #include "ui/views/views_export.h"
15 #include "ui/views/window/caption_button_types.h"
16 
17 namespace gfx {
18 class SlideAnimation;
19 struct VectorIcon;
20 }  // namespace gfx
21 
22 namespace views {
23 
24 // Base class for the window caption buttons (minimize, maximize, restore,
25 // close).
26 class VIEWS_EXPORT FrameCaptionButton : public views::Button {
27  public:
28   enum Animate { ANIMATE_YES, ANIMATE_NO };
29 
30   static const char kViewClassName[];
31 
32   FrameCaptionButton(PressedCallback callback,
33                      CaptionButtonIcon icon,
34                      int hit_test_type);
35   ~FrameCaptionButton() override;
36 
37   // Gets the color to use for a frame caption button.
38   static SkColor GetButtonColor(SkColor background_color);
39 
40   // Gets the alpha ratio for the colors of inactive frame caption buttons.
41   static float GetInactiveButtonColorAlphaRatio();
42 
43   // Sets the image to use to paint the button. If |animate| is ANIMATE_YES,
44   // the button crossfades to the new visuals. If the image matches the one
45   // currently used by the button and |animate| is ANIMATE_NO, the crossfade
46   // animation is progressed to the end.
47   void SetImage(CaptionButtonIcon icon,
48                 Animate animate,
49                 const gfx::VectorIcon& icon_image);
50 
51   // Returns true if the button is crossfading to new visuals set in
52   // SetImage().
53   bool IsAnimatingImageSwap() const;
54 
55   // Sets the alpha to use for painting. Used to animate visibility changes.
56   void SetAlpha(int alpha);
57 
58   // views::Button:
59   const char* GetClassName() const override;
60   void OnGestureEvent(ui::GestureEvent* event) override;
61   views::PaintInfo::ScaleType GetPaintScaleType() const override;
62   std::unique_ptr<views::InkDrop> CreateInkDrop() override;
63   std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
64 
65   void SetBackgroundColor(SkColor background_color);
66 
set_paint_as_active(bool paint_as_active)67   void set_paint_as_active(bool paint_as_active) {
68     paint_as_active_ = paint_as_active;
69   }
70 
paint_as_active()71   bool paint_as_active() const { return paint_as_active_; }
72 
set_ink_drop_corner_radius(int ink_drop_corner_radius)73   void set_ink_drop_corner_radius(int ink_drop_corner_radius) {
74     ink_drop_corner_radius_ = ink_drop_corner_radius;
75   }
ink_drop_corner_radius()76   int ink_drop_corner_radius() const { return ink_drop_corner_radius_; }
77 
icon()78   CaptionButtonIcon icon() const { return icon_; }
79 
icon_image()80   const gfx::ImageSkia& icon_image() const { return icon_image_; }
81 
icon_definition_for_test()82   const gfx::VectorIcon* icon_definition_for_test() const {
83     return icon_definition_;
84   }
85 
86  protected:
87   // views::Button override:
88   void PaintButtonContents(gfx::Canvas* canvas) override;
89 
90  private:
91   class HighlightPathGenerator;
92 
93   // Determines what alpha to use for the icon based on animation and
94   // active state.
95   int GetAlphaForIcon(int base_alpha) const;
96 
97   // Returns the amount by which the inkdrop ripple and mask should be insetted
98   // from the button size in order to achieve a circular inkdrop with a size
99   // equals to kInkDropHighlightSize.
100   gfx::Insets GetInkdropInsets(const gfx::Size& button_size) const;
101 
102   void UpdateInkDropBaseColor();
103 
104   // The button's current icon.
105   CaptionButtonIcon icon_;
106 
107   // The current background color.
108   SkColor background_color_;
109 
110   // Whether the button should be painted as active.
111   bool paint_as_active_;
112 
113   // Current alpha to use for painting.
114   int alpha_;
115 
116   // Radius of the ink drop highlight and mask.
117   int ink_drop_corner_radius_;
118 
119   // The image id (kept for the purposes of testing) and image used to paint the
120   // button's icon.
121   const gfx::VectorIcon* icon_definition_ = nullptr;
122   gfx::ImageSkia icon_image_;
123 
124   // The icon image to crossfade from.
125   gfx::ImageSkia crossfade_icon_image_;
126 
127   // Crossfade animation started when the button's images are changed by
128   // SetImage().
129   std::unique_ptr<gfx::SlideAnimation> swap_images_animation_;
130 
131   DISALLOW_COPY_AND_ASSIGN(FrameCaptionButton);
132 };
133 
134 }  // namespace views
135 
136 #endif  // UI_VIEWS_WINDOW_FRAME_CAPTION_BUTTON_H_
137