- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / controls / image_view.cc
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 #include "ui/views/controls/image_view.h"
6
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"
13
14 namespace views {
15
16 ImageView::ImageView()
17     : image_size_set_(false),
18       horiz_alignment_(CENTER),
19       vert_alignment_(CENTER),
20       interactive_(true) {
21 }
22
23 ImageView::~ImageView() {
24 }
25
26 void ImageView::SetImage(const gfx::ImageSkia& img) {
27   gfx::Size pref_size(GetPreferredSize());
28   image_ = img;
29   if (pref_size != GetPreferredSize())
30     PreferredSizeChanged();
31   SchedulePaint();
32 }
33
34 void ImageView::SetImage(const gfx::ImageSkia* image_skia) {
35   if (image_skia) {
36     SetImage(*image_skia);
37   } else {
38     gfx::ImageSkia t;
39     SetImage(t);
40   }
41 }
42
43 const gfx::ImageSkia& ImageView::GetImage() {
44   return image_;
45 }
46
47 void ImageView::SetImageSize(const gfx::Size& image_size) {
48   image_size_set_ = true;
49   image_size_ = image_size;
50   PreferredSizeChanged();
51 }
52
53 bool ImageView::GetImageSize(gfx::Size* image_size) {
54   DCHECK(image_size);
55   if (image_size_set_)
56     *image_size = image_size_;
57   return image_size_set_;
58 }
59
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);
64 }
65
66 void ImageView::ResetImageSize() {
67   image_size_set_ = false;
68 }
69
70 gfx::Size ImageView::GetPreferredSize() {
71   gfx::Insets insets = GetInsets();
72   if (image_size_set_) {
73     gfx::Size image_size;
74     GetImageSize(&image_size);
75     image_size.Enlarge(insets.width(), insets.height());
76     return image_size;
77   }
78   return gfx::Size(image_.width() + insets.width(),
79                    image_.height() + insets.height());
80 }
81
82 gfx::Point ImageView::ComputeImageOrigin(const gfx::Size& image_size) const {
83   gfx::Insets insets = GetInsets();
84
85   int x;
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;
98   }
99
100   int y;
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;
106   }
107
108   return gfx::Point(x, y);
109 }
110
111 void ImageView::OnPaint(gfx::Canvas* canvas) {
112   View::OnPaint(canvas);
113
114   if (image_.isNull())
115     return;
116
117   gfx::Rect image_bounds(GetImageBounds());
118   if (image_bounds.IsEmpty())
119     return;
120
121   if (image_bounds.size() != gfx::Size(image_.width(), image_.height())) {
122     // Resize case
123     SkPaint paint;
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);
128   } else {
129     canvas->DrawImageInt(image_, image_bounds.x(), image_bounds.y());
130   }
131 }
132
133 void ImageView::GetAccessibleState(ui::AccessibleViewState* state) {
134   state->role = ui::AccessibilityTypes::ROLE_GRAPHIC;
135   state->name = tooltip_text_;
136 }
137
138 void ImageView::SetHorizontalAlignment(Alignment ha) {
139   if (ha != horiz_alignment_) {
140     horiz_alignment_ = ha;
141     SchedulePaint();
142   }
143 }
144
145 ImageView::Alignment ImageView::GetHorizontalAlignment() const {
146   return horiz_alignment_;
147 }
148
149 void ImageView::SetVerticalAlignment(Alignment va) {
150   if (va != vert_alignment_) {
151     vert_alignment_ = va;
152     SchedulePaint();
153   }
154 }
155
156 ImageView::Alignment ImageView::GetVerticalAlignment() const {
157   return vert_alignment_;
158 }
159
160 void ImageView::SetTooltipText(const string16& tooltip) {
161   tooltip_text_ = tooltip;
162 }
163
164 string16 ImageView::GetTooltipText() const {
165   return tooltip_text_;
166 }
167
168 bool ImageView::GetTooltipText(const gfx::Point& p, string16* tooltip) const {
169   if (tooltip_text_.empty())
170     return false;
171
172   *tooltip = GetTooltipText();
173   return true;
174 }
175
176 bool ImageView::HitTestRect(const gfx::Rect& rect) const {
177   return interactive_ ? View::HitTestRect(rect) : false;
178 }
179
180 }  // namespace views