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 // Set an |image| to draw on top of the normal / hot / pushed image. 55 // Pass NULL for no image. 56 void SetOverlayImage(const gfx::ImageSkia* image); 57 58 // Sets how the image is laid out within the button's bounds. 59 void SetImageAlignment(HorizontalAlignment h_align, 60 VerticalAlignment v_align); 61 62 void SetFocusPainter(scoped_ptr<Painter> focus_painter); 63 64 // Sets preferred size, so it could be correctly positioned in layout even if 65 // it is NULL. SetPreferredSize(const gfx::Size & preferred_size)66 void SetPreferredSize(const gfx::Size& preferred_size) { 67 preferred_size_ = preferred_size; 68 } 69 70 // Whether we should draw our images resources horizontally flipped. SetDrawImageMirrored(bool mirrored)71 void SetDrawImageMirrored(bool mirrored) { 72 draw_image_mirrored_ = mirrored; 73 } 74 75 // Overridden from View: 76 virtual gfx::Size GetPreferredSize() OVERRIDE; 77 virtual const char* GetClassName() const OVERRIDE; 78 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 79 80 protected: 81 // Overridden from View: 82 virtual void OnFocus() OVERRIDE; 83 virtual void OnBlur() OVERRIDE; 84 85 // Returns the image to paint. This is invoked from paint and returns a value 86 // from images. 87 virtual gfx::ImageSkia GetImageToPaint(); 88 89 // Updates button background for |scale_factor|. 90 void UpdateButtonBackground(ui::ScaleFactor scale_factor); 91 focus_painter()92 Painter* focus_painter() { return focus_painter_.get(); } 93 94 // The images used to render the different states of this button. 95 gfx::ImageSkia images_[STATE_COUNT]; 96 97 gfx::ImageSkia background_image_; 98 99 // Image to draw on top of normal / hot / pushed image. Usually empty. 100 gfx::ImageSkia overlay_image_; 101 102 private: 103 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, Basics); 104 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, ImagePositionWithBorder); 105 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, LeftAlignedMirrored); 106 FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, RightAlignedMirrored); 107 108 // Returns the correct position of the image for painting. 109 gfx::Point ComputeImagePaintPosition(const gfx::ImageSkia& image); 110 111 // Image alignment. 112 HorizontalAlignment h_alignment_; 113 VerticalAlignment v_alignment_; 114 gfx::Size preferred_size_; 115 116 // Whether we draw our resources horizontally flipped. This can happen in the 117 // linux titlebar, where image resources were designed to be flipped so a 118 // small curved corner in the close button designed to fit into the frame 119 // resources. 120 bool draw_image_mirrored_; 121 122 scoped_ptr<Painter> focus_painter_; 123 124 DISALLOW_COPY_AND_ASSIGN(ImageButton); 125 }; 126 127 //////////////////////////////////////////////////////////////////////////////// 128 // 129 // ToggleImageButton 130 // 131 // A toggle-able ImageButton. It swaps out its graphics when toggled. 132 // 133 //////////////////////////////////////////////////////////////////////////////// 134 class VIEWS_EXPORT ToggleImageButton : public ImageButton { 135 public: 136 explicit ToggleImageButton(ButtonListener* listener); 137 virtual ~ToggleImageButton(); 138 139 // Change the toggled state. 140 void SetToggled(bool toggled); 141 142 // Like ImageButton::SetImage(), but to set the graphics used for the 143 // "has been toggled" state. Must be called for each button state 144 // before the button is toggled. 145 void SetToggledImage(ButtonState state, const gfx::ImageSkia* image); 146 147 // Set the tooltip text displayed when the button is toggled. 148 void SetToggledTooltipText(const string16& tooltip); 149 150 // Overridden from ImageButton: 151 virtual const gfx::ImageSkia& GetImage(ButtonState state) const OVERRIDE; 152 virtual void SetImage(ButtonState state, 153 const gfx::ImageSkia* image) OVERRIDE; 154 155 // Overridden from View: 156 virtual bool GetTooltipText(const gfx::Point& p, 157 string16* tooltip) const OVERRIDE; 158 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; 159 160 private: 161 // The parent class's images_ member is used for the current images, 162 // and this array is used to hold the alternative images. 163 // We swap between the two when toggling. 164 gfx::ImageSkia alternate_images_[STATE_COUNT]; 165 166 // True if the button is currently toggled. 167 bool toggled_; 168 169 // The parent class's tooltip_text_ is displayed when not toggled, and 170 // this one is shown when toggled. 171 string16 toggled_tooltip_text_; 172 173 DISALLOW_COPY_AND_ASSIGN(ToggleImageButton); 174 }; 175 176 } // namespace views 177 178 #endif // UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_ 179