Demonstrate the basic functionality of the File System
[chromium-blink-merge.git] / ui / views / controls / button / image_button.cc
blobecbd4a1072443854e379004fe4214be65fd1846b
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.
5 #include "ui/views/controls/button/image_button.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/accessibility/ax_view_state.h"
9 #include "ui/gfx/animation/throb_animation.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/gfx/image/image_skia_operations.h"
12 #include "ui/gfx/scoped_canvas.h"
13 #include "ui/views/painter.h"
14 #include "ui/views/widget/widget.h"
16 namespace views {
18 static const int kDefaultWidth = 16; // Default button width if no theme.
19 static const int kDefaultHeight = 14; // Default button height if no theme.
21 const char ImageButton::kViewClassName[] = "ImageButton";
23 ////////////////////////////////////////////////////////////////////////////////
24 // ImageButton, public:
26 ImageButton::ImageButton(ButtonListener* listener)
27 : CustomButton(listener),
28 h_alignment_(ALIGN_LEFT),
29 v_alignment_(ALIGN_TOP),
30 preferred_size_(kDefaultWidth, kDefaultHeight),
31 draw_image_mirrored_(false),
32 focus_painter_(Painter::CreateDashedFocusPainter()) {
33 // By default, we request that the gfx::Canvas passed to our View::OnPaint()
34 // implementation is flipped horizontally so that the button's images are
35 // mirrored when the UI directionality is right-to-left.
36 EnableCanvasFlippingForRTLUI(true);
39 ImageButton::~ImageButton() {
42 const gfx::ImageSkia& ImageButton::GetImage(ButtonState state) const {
43 return images_[state];
46 void ImageButton::SetImage(ButtonState state, const gfx::ImageSkia* image) {
47 images_[state] = image ? *image : gfx::ImageSkia();
48 PreferredSizeChanged();
51 void ImageButton::SetBackground(SkColor color,
52 const gfx::ImageSkia* image,
53 const gfx::ImageSkia* mask) {
54 if (image == NULL || mask == NULL) {
55 background_image_ = gfx::ImageSkia();
56 return;
59 background_image_ = gfx::ImageSkiaOperations::CreateButtonBackground(color,
60 *image, *mask);
63 void ImageButton::SetImageAlignment(HorizontalAlignment h_align,
64 VerticalAlignment v_align) {
65 h_alignment_ = h_align;
66 v_alignment_ = v_align;
67 SchedulePaint();
70 void ImageButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
71 focus_painter_ = focus_painter.Pass();
74 ////////////////////////////////////////////////////////////////////////////////
75 // ImageButton, View overrides:
77 gfx::Size ImageButton::GetPreferredSize() const {
78 gfx::Size size = preferred_size_;
79 if (!images_[STATE_NORMAL].isNull()) {
80 size = gfx::Size(images_[STATE_NORMAL].width(),
81 images_[STATE_NORMAL].height());
84 gfx::Insets insets = GetInsets();
85 size.Enlarge(insets.width(), insets.height());
86 return size;
89 const char* ImageButton::GetClassName() const {
90 return kViewClassName;
93 void ImageButton::OnPaint(gfx::Canvas* canvas) {
94 // Call the base class first to paint any background/borders.
95 View::OnPaint(canvas);
97 gfx::ImageSkia img = GetImageToPaint();
99 if (!img.isNull()) {
100 gfx::ScopedCanvas scoped(canvas);
101 if (draw_image_mirrored_) {
102 canvas->Translate(gfx::Vector2d(width(), 0));
103 canvas->Scale(-1, 1);
106 gfx::Point position = ComputeImagePaintPosition(img);
107 if (!background_image_.isNull())
108 canvas->DrawImageInt(background_image_, position.x(), position.y());
110 canvas->DrawImageInt(img, position.x(), position.y());
113 Painter::PaintFocusPainter(this, canvas, focus_painter());
116 ////////////////////////////////////////////////////////////////////////////////
117 // ImageButton, protected:
119 void ImageButton::OnFocus() {
120 View::OnFocus();
121 if (focus_painter_.get())
122 SchedulePaint();
125 void ImageButton::OnBlur() {
126 View::OnBlur();
127 if (focus_painter_.get())
128 SchedulePaint();
131 gfx::ImageSkia ImageButton::GetImageToPaint() {
132 gfx::ImageSkia img;
134 if (!images_[STATE_HOVERED].isNull() && hover_animation_->is_animating()) {
135 img = gfx::ImageSkiaOperations::CreateBlendedImage(images_[STATE_NORMAL],
136 images_[STATE_HOVERED], hover_animation_->GetCurrentValue());
137 } else {
138 img = images_[state_];
141 return !img.isNull() ? img : images_[STATE_NORMAL];
144 ////////////////////////////////////////////////////////////////////////////////
145 // ImageButton, private:
147 gfx::Point ImageButton::ComputeImagePaintPosition(const gfx::ImageSkia& image) {
148 int x = 0, y = 0;
149 gfx::Rect rect = GetContentsBounds();
151 HorizontalAlignment h_alignment = h_alignment_;
152 if (draw_image_mirrored_) {
153 if (h_alignment == ALIGN_RIGHT)
154 h_alignment = ALIGN_LEFT;
155 else if (h_alignment == ALIGN_LEFT)
156 h_alignment = ALIGN_RIGHT;
159 if (h_alignment == ALIGN_CENTER)
160 x = (rect.width() - image.width()) / 2;
161 else if (h_alignment == ALIGN_RIGHT)
162 x = rect.width() - image.width();
164 if (v_alignment_ == ALIGN_MIDDLE)
165 y = (rect.height() - image.height()) / 2;
166 else if (v_alignment_ == ALIGN_BOTTOM)
167 y = rect.height() - image.height();
169 x += rect.x();
170 y += rect.y();
172 return gfx::Point(x, y);
175 ////////////////////////////////////////////////////////////////////////////////
176 // ToggleImageButton, public:
178 ToggleImageButton::ToggleImageButton(ButtonListener* listener)
179 : ImageButton(listener),
180 toggled_(false) {
183 ToggleImageButton::~ToggleImageButton() {
186 void ToggleImageButton::SetToggled(bool toggled) {
187 if (toggled == toggled_)
188 return;
190 for (int i = 0; i < STATE_COUNT; ++i) {
191 gfx::ImageSkia temp = images_[i];
192 images_[i] = alternate_images_[i];
193 alternate_images_[i] = temp;
195 toggled_ = toggled;
196 SchedulePaint();
198 NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
201 void ToggleImageButton::SetToggledImage(ButtonState state,
202 const gfx::ImageSkia* image) {
203 if (toggled_) {
204 images_[state] = image ? *image : gfx::ImageSkia();
205 if (state_ == state)
206 SchedulePaint();
207 } else {
208 alternate_images_[state] = image ? *image : gfx::ImageSkia();
212 void ToggleImageButton::SetToggledTooltipText(const base::string16& tooltip) {
213 toggled_tooltip_text_ = tooltip;
216 ////////////////////////////////////////////////////////////////////////////////
217 // ToggleImageButton, ImageButton overrides:
219 const gfx::ImageSkia& ToggleImageButton::GetImage(ButtonState state) const {
220 if (toggled_)
221 return alternate_images_[state];
222 return images_[state];
225 void ToggleImageButton::SetImage(ButtonState state,
226 const gfx::ImageSkia* image) {
227 if (toggled_) {
228 alternate_images_[state] = image ? *image : gfx::ImageSkia();
229 } else {
230 images_[state] = image ? *image : gfx::ImageSkia();
231 if (state_ == state)
232 SchedulePaint();
234 PreferredSizeChanged();
237 ////////////////////////////////////////////////////////////////////////////////
238 // ToggleImageButton, View overrides:
240 bool ToggleImageButton::GetTooltipText(const gfx::Point& p,
241 base::string16* tooltip) const {
242 if (!toggled_ || toggled_tooltip_text_.empty())
243 return Button::GetTooltipText(p, tooltip);
245 *tooltip = toggled_tooltip_text_;
246 return true;
249 void ToggleImageButton::GetAccessibleState(ui::AXViewState* state) {
250 ImageButton::GetAccessibleState(state);
251 GetTooltipText(gfx::Point(), &state->name);
254 } // namespace views