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/image_view.h"
7 #include "base/logging.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "third_party/skia/include/core/SkPaint.h"
10 #include "ui/base/accessibility/accessible_view_state.h"
11 #include "ui/gfx/canvas.h"
12 #include "ui/gfx/insets.h"
16 ImageView::ImageView()
17 : image_size_set_(false),
18 horiz_alignment_(CENTER),
19 vert_alignment_(CENTER),
23 ImageView::~ImageView() {
26 void ImageView::SetImage(const gfx::ImageSkia& img) {
27 gfx::Size pref_size(GetPreferredSize());
29 if (pref_size != GetPreferredSize())
30 PreferredSizeChanged();
34 void ImageView::SetImage(const gfx::ImageSkia* image_skia) {
36 SetImage(*image_skia);
43 const gfx::ImageSkia& ImageView::GetImage() {
47 void ImageView::SetImageSize(const gfx::Size& image_size) {
48 image_size_set_ = true;
49 image_size_ = image_size;
50 PreferredSizeChanged();
53 bool ImageView::GetImageSize(gfx::Size* image_size) {
56 *image_size = image_size_;
57 return image_size_set_;
60 gfx::Rect ImageView::GetImageBounds() const {
61 gfx::Size image_size(image_size_set_ ?
62 image_size_ : gfx::Size(image_.width(), image_.height()));
63 return gfx::Rect(ComputeImageOrigin(image_size), image_size);
66 void ImageView::ResetImageSize() {
67 image_size_set_ = false;
70 gfx::Size ImageView::GetPreferredSize() {
71 gfx::Insets insets = GetInsets();
72 if (image_size_set_) {
74 GetImageSize(&image_size);
75 image_size.Enlarge(insets.width(), insets.height());
78 return gfx::Size(image_.width() + insets.width(),
79 image_.height() + insets.height());
82 gfx::Point ImageView::ComputeImageOrigin(const gfx::Size& image_size) const {
83 gfx::Insets insets = GetInsets();
86 // In order to properly handle alignment of images in RTL locales, we need
87 // to flip the meaning of trailing and leading. For example, if the
88 // horizontal alignment is set to trailing, then we'll use left alignment for
89 // the image instead of right alignment if the UI layout is RTL.
90 Alignment actual_horiz_alignment = horiz_alignment_;
91 if (base::i18n::IsRTL() && (horiz_alignment_ != CENTER))
92 actual_horiz_alignment = (horiz_alignment_ == LEADING) ? TRAILING : LEADING;
93 switch (actual_horiz_alignment) {
94 case LEADING: x = insets.left(); break;
95 case TRAILING: x = width() - insets.right() - image_size.width(); break;
96 case CENTER: x = (width() - image_size.width()) / 2; break;
97 default: NOTREACHED(); x = 0; break;
101 switch (vert_alignment_) {
102 case LEADING: y = insets.top(); break;
103 case TRAILING: y = height() - insets.bottom() - image_size.height(); break;
104 case CENTER: y = (height() - image_size.height()) / 2; break;
105 default: NOTREACHED(); y = 0; break;
108 return gfx::Point(x, y);
111 void ImageView::OnPaint(gfx::Canvas* canvas) {
112 View::OnPaint(canvas);
117 gfx::Rect image_bounds(GetImageBounds());
118 if (image_bounds.IsEmpty())
121 if (image_bounds.size() != gfx::Size(image_.width(), image_.height())) {
124 paint.setFilterBitmap(true);
125 canvas->DrawImageInt(image_, 0, 0, image_.width(), image_.height(),
126 image_bounds.x(), image_bounds.y(), image_bounds.width(),
127 image_bounds.height(), true, paint);
129 canvas->DrawImageInt(image_, image_bounds.x(), image_bounds.y());
133 void ImageView::GetAccessibleState(ui::AccessibleViewState* state) {
134 state->role = ui::AccessibilityTypes::ROLE_GRAPHIC;
135 state->name = tooltip_text_;
138 void ImageView::SetHorizontalAlignment(Alignment ha) {
139 if (ha != horiz_alignment_) {
140 horiz_alignment_ = ha;
145 ImageView::Alignment ImageView::GetHorizontalAlignment() const {
146 return horiz_alignment_;
149 void ImageView::SetVerticalAlignment(Alignment va) {
150 if (va != vert_alignment_) {
151 vert_alignment_ = va;
156 ImageView::Alignment ImageView::GetVerticalAlignment() const {
157 return vert_alignment_;
160 void ImageView::SetTooltipText(const string16& tooltip) {
161 tooltip_text_ = tooltip;
164 string16 ImageView::GetTooltipText() const {
165 return tooltip_text_;
168 bool ImageView::GetTooltipText(const gfx::Point& p, string16* tooltip) const {
169 if (tooltip_text_.empty())
172 *tooltip = GetTooltipText();
176 bool ImageView::HitTestRect(const gfx::Rect& rect) const {
177 return interactive_ ? View::HitTestRect(rect) : false;