1 // Copyright (c) 2012 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_CONTROLS_BUTTON_IMAGE_BUTTON_H_ 6 #define UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "ui/base/layout.h" 11 #include "ui/gfx/image/image_skia.h" 12 #include "ui/views/controls/button/custom_button.h" 13 14 namespace views { 15 16 class Painter; 17 18 // An image button. 19 20 // Note that this type of button is not focusable by default and will not be 21 // part of the focus chain. Call SetFocusable(true) to make it part of the 22 // focus chain. 23 24 class VIEWS_EXPORT ImageButton : public CustomButton { 25 public: 26 static const char kViewClassName[]; 27 28 enum HorizontalAlignment { 29 ALIGN_LEFT = 0, 30 ALIGN_CENTER, 31 ALIGN_RIGHT 32 }; 33 34 enum VerticalAlignment { 35 ALIGN_TOP = 0, 36 ALIGN_MIDDLE, 37 ALIGN_BOTTOM 38 }; 39 40 explicit ImageButton(ButtonListener* listener); 41 virtual ~ImageButton(); 42 43 // Returns the image for a given |state|. 44 virtual const gfx::ImageSkia& GetImage(ButtonState state) const; 45 46 // Set the image the button should use for the provided state. 47 virtual void SetImage(ButtonState state, const gfx::ImageSkia* image); 48 49 // Set the background details. 50 void SetBackground(SkColor color, 51 const gfx::ImageSkia* image, 52 const gfx::ImageSkia* mask); 53 54 // Sets how the image is laid out within the button's bounds. 55 void SetImageAlignment(HorizontalAlignment h_align, 56 VerticalAlignment v_align); 57 58 void SetFocusPainter(scoped_ptr<Painter> focus_painter); 59 60 // The minimum size of the contents (not including the border). The contents 61 // will be at least this size, but may be larger if the image itself is 62 // larger. minimum_image_size()63 const gfx::Size& minimum_image_size() const { return minimum_image_size_; } 64 void SetMinimumImageSize(const gfx::Size& size); 65 66 // Whether we should draw our images resources horizontally flipped. SetDrawImageMirrored(bool mirrored)67 void SetDrawImageMirrored(bool mirrored) { 68 draw_image_mirrored_ = mirrored; 69 } 70 71 // Overridden from View: 72 virtual gfx::Size GetPreferredSize() const OVERRIDE; 73 virtual const char* GetClassName() const OVERRIDE; 74 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 75 76 protected: 77 // Overridden from View: 78 virtual void OnFocus() OVERRIDE; 79 virtual void OnBlur() OVERRIDE; 80 81 // Returns the image to paint. This is invoked from paint and returns a value 82 // from images. 83 virtual gfx::ImageSkia GetImageToPaint(); 84 85 // Updates button background for |scale_factor|. 86 void UpdateButtonBackground(ui::ScaleFactor scale_factor); 87 focus_painter()88 Painter* focus_painter() { return focus_painter_.get(); } 89 90 // The images used to render the different states of this button. 91 gfx::ImageSkia images_[STATE_COUNT]; 92 93 gfx::ImageSkia background_image_; 94 95 private: 96 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, Basics); 97 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, ImagePositionWithBorder); 98 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, LeftAlignedMirrored); 99 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, RightAlignedMirrored); 100 101 // Returns the correct position of the image for painting. 102 gfx::Point ComputeImagePaintPosition(const gfx::ImageSkia& image); 103 104 // Image alignment. 105 HorizontalAlignment h_alignment_; 106 VerticalAlignment v_alignment_; 107 gfx::Size minimum_image_size_; 108 109 // Whether we draw our resources horizontally flipped. This can happen in the 110 // linux titlebar, where image resources were designed to be flipped so a 111 // small curved corner in the close button designed to fit into the frame 112 // resources. 113 bool draw_image_mirrored_; 114 115 scoped_ptr<Painter> focus_painter_; 116 117 DISALLOW_COPY_AND_ASSIGN(ImageButton); 118 }; 119 120 //////////////////////////////////////////////////////////////////////////////// 121 // 122 // ToggleImageButton 123 // 124 // A toggle-able ImageButton. It swaps out its graphics when toggled. 125 // 126 //////////////////////////////////////////////////////////////////////////////// 127 class VIEWS_EXPORT ToggleImageButton : public ImageButton { 128 public: 129 explicit ToggleImageButton(ButtonListener* listener); 130 virtual ~ToggleImageButton(); 131 132 // Change the toggled state. 133 void SetToggled(bool toggled); 134 135 // Like ImageButton::SetImage(), but to set the graphics used for the 136 // "has been toggled" state. Must be called for each button state 137 // before the button is toggled. 138 void SetToggledImage(ButtonState state, const gfx::ImageSkia* image); 139 140 // Set the tooltip text displayed when the button is toggled. 141 void SetToggledTooltipText(const base::string16& tooltip); 142 143 // Overridden from ImageButton: 144 virtual const gfx::ImageSkia& GetImage(ButtonState state) const OVERRIDE; 145 virtual void SetImage(ButtonState state, 146 const gfx::ImageSkia* image) OVERRIDE; 147 148 // Overridden from View: 149 virtual bool GetTooltipText(const gfx::Point& p, 150 base::string16* tooltip) const OVERRIDE; 151 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; 152 153 private: 154 // The parent class's images_ member is used for the current images, 155 // and this array is used to hold the alternative images. 156 // We swap between the two when toggling. 157 gfx::ImageSkia alternate_images_[STATE_COUNT]; 158 159 // True if the button is currently toggled. 160 bool toggled_; 161 162 // The parent class's tooltip_text_ is displayed when not toggled, and 163 // this one is shown when toggled. 164 base::string16 toggled_tooltip_text_; 165 166 DISALLOW_COPY_AND_ASSIGN(ToggleImageButton); 167 }; 168 169 } // namespace views 170 171 #endif // UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_ 172