Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: ui/views/corewm/image_grid.cc

Issue 194843004: Move files from ui/views/corewm to ui/wm/core (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/corewm/image_grid.h ('k') | ui/views/corewm/image_grid_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/corewm/image_grid.h"
6
7 #include <algorithm>
8
9 #include "third_party/skia/include/core/SkColor.h"
10 #include "third_party/skia/include/core/SkXfermode.h"
11 #include "ui/compositor/dip_util.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/image/image.h"
14 #include "ui/gfx/rect.h"
15 #include "ui/gfx/rect_conversions.h"
16 #include "ui/gfx/size.h"
17 #include "ui/gfx/size_conversions.h"
18 #include "ui/gfx/transform.h"
19
20 using std::max;
21 using std::min;
22
23 namespace views {
24 namespace corewm {
25
26 gfx::RectF ImageGrid::TestAPI::GetTransformedLayerBounds(
27 const ui::Layer& layer) {
28 gfx::RectF bounds = layer.bounds();
29 layer.transform().TransformRect(&bounds);
30 return bounds;
31 }
32
33 ImageGrid::ImageGrid()
34 : layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)),
35 top_image_height_(0),
36 bottom_image_height_(0),
37 left_image_width_(0),
38 right_image_width_(0),
39 base_top_row_height_(0),
40 base_bottom_row_height_(0),
41 base_left_column_width_(0),
42 base_right_column_width_(0) {
43 }
44
45 ImageGrid::~ImageGrid() {
46 }
47
48 void ImageGrid::SetImages(const gfx::Image* top_left_image,
49 const gfx::Image* top_image,
50 const gfx::Image* top_right_image,
51 const gfx::Image* left_image,
52 const gfx::Image* center_image,
53 const gfx::Image* right_image,
54 const gfx::Image* bottom_left_image,
55 const gfx::Image* bottom_image,
56 const gfx::Image* bottom_right_image) {
57 SetImage(top_left_image, &top_left_layer_, &top_left_painter_);
58 SetImage(top_image, &top_layer_, &top_painter_);
59 SetImage(top_right_image, &top_right_layer_, &top_right_painter_);
60 SetImage(left_image, &left_layer_, &left_painter_);
61 SetImage(center_image, &center_layer_, &center_painter_);
62 SetImage(right_image, &right_layer_, &right_painter_);
63 SetImage(bottom_left_image, &bottom_left_layer_, &bottom_left_painter_);
64 SetImage(bottom_image, &bottom_layer_, &bottom_painter_);
65 SetImage(bottom_right_image, &bottom_right_layer_, &bottom_right_painter_);
66
67 top_image_height_ = GetImageSize(top_image).height();
68 bottom_image_height_ = GetImageSize(bottom_image).height();
69 left_image_width_ = GetImageSize(left_image).width();
70 right_image_width_ = GetImageSize(right_image).width();
71
72 base_top_row_height_ = max(GetImageSize(top_left_image).height(),
73 max(GetImageSize(top_image).height(),
74 GetImageSize(top_right_image).height()));
75 base_bottom_row_height_ = max(GetImageSize(bottom_left_image).height(),
76 max(GetImageSize(bottom_image).height(),
77 GetImageSize(bottom_right_image).height()));
78 base_left_column_width_ = max(GetImageSize(top_left_image).width(),
79 max(GetImageSize(left_image).width(),
80 GetImageSize(bottom_left_image).width()));
81 base_right_column_width_ = max(GetImageSize(top_right_image).width(),
82 max(GetImageSize(right_image).width(),
83 GetImageSize(bottom_right_image).width()));
84
85 // Invalidate previous |size_| so calls to SetSize() will recompute it.
86 size_.SetSize(0, 0);
87 }
88
89 void ImageGrid::SetSize(const gfx::Size& size) {
90 if (size_ == size)
91 return;
92
93 size_ = size;
94
95 gfx::Rect updated_bounds = layer_->bounds();
96 updated_bounds.set_size(size);
97 layer_->SetBounds(updated_bounds);
98
99 // Calculate the available amount of space for corner images on all sides of
100 // the grid. If the images don't fit, we need to clip them.
101 const int left = min(base_left_column_width_, size_.width() / 2);
102 const int right = min(base_right_column_width_, size_.width() - left);
103 const int top = min(base_top_row_height_, size_.height() / 2);
104 const int bottom = min(base_bottom_row_height_, size_.height() - top);
105
106 // The remaining space goes to the center image.
107 int center_width = std::max(size.width() - left - right, 0);
108 int center_height = std::max(size.height() - top - bottom, 0);
109
110 // At non-integer scale factors, the ratio of dimensions in DIP is not
111 // necessarily the same as the ratio in physical pixels due to rounding. Set
112 // the transform on each of the layers based on dimensions in pixels.
113 gfx::Size center_size_in_pixels = gfx::ToFlooredSize(gfx::ScaleSize(
114 gfx::Size(center_width, center_height), layer_->device_scale_factor()));
115
116 if (top_layer_.get()) {
117 if (center_width > 0) {
118 gfx::Transform transform;
119 transform.Translate(left, 0);
120 ScaleWidth(center_size_in_pixels, top_layer_.get(), transform);
121 top_layer_->SetTransform(transform);
122 }
123 top_layer_->SetVisible(center_width > 0);
124 }
125 if (bottom_layer_.get()) {
126 if (center_width > 0) {
127 gfx::Transform transform;
128 transform.Translate(
129 left, size.height() - bottom_layer_->bounds().height());
130 ScaleWidth(center_size_in_pixels, bottom_layer_.get(), transform);
131 bottom_layer_->SetTransform(transform);
132 }
133 bottom_layer_->SetVisible(center_width > 0);
134 }
135 if (left_layer_.get()) {
136 if (center_height > 0) {
137 gfx::Transform transform;
138 transform.Translate(0, top);
139 ScaleHeight(center_size_in_pixels, left_layer_.get(), transform);
140 left_layer_->SetTransform(transform);
141 }
142 left_layer_->SetVisible(center_height > 0);
143 }
144 if (right_layer_.get()) {
145 if (center_height > 0) {
146 gfx::Transform transform;
147 transform.Translate(
148 size.width() - right_layer_->bounds().width(), top);
149 ScaleHeight(center_size_in_pixels, right_layer_.get(), transform);
150 right_layer_->SetTransform(transform);
151 }
152 right_layer_->SetVisible(center_height > 0);
153 }
154
155 if (top_left_layer_.get()) {
156 // No transformation needed; it should be at (0, 0) and unscaled.
157 top_left_painter_->SetClipRect(
158 LayerExceedsSize(top_left_layer_.get(), gfx::Size(left, top)) ?
159 gfx::Rect(gfx::Rect(0, 0, left, top)) :
160 gfx::Rect(),
161 top_left_layer_.get());
162 }
163 if (top_right_layer_.get()) {
164 gfx::Transform transform;
165 transform.Translate(size.width() - top_right_layer_->bounds().width(), 0.0);
166 top_right_layer_->SetTransform(transform);
167 top_right_painter_->SetClipRect(
168 LayerExceedsSize(top_right_layer_.get(), gfx::Size(right, top)) ?
169 gfx::Rect(top_right_layer_->bounds().width() - right, 0,
170 right, top) :
171 gfx::Rect(),
172 top_right_layer_.get());
173 }
174 if (bottom_left_layer_.get()) {
175 gfx::Transform transform;
176 transform.Translate(
177 0.0, size.height() - bottom_left_layer_->bounds().height());
178 bottom_left_layer_->SetTransform(transform);
179 bottom_left_painter_->SetClipRect(
180 LayerExceedsSize(bottom_left_layer_.get(), gfx::Size(left, bottom)) ?
181 gfx::Rect(0, bottom_left_layer_->bounds().height() - bottom,
182 left, bottom) :
183 gfx::Rect(),
184 bottom_left_layer_.get());
185 }
186 if (bottom_right_layer_.get()) {
187 gfx::Transform transform;
188 transform.Translate(
189 size.width() - bottom_right_layer_->bounds().width(),
190 size.height() - bottom_right_layer_->bounds().height());
191 bottom_right_layer_->SetTransform(transform);
192 bottom_right_painter_->SetClipRect(
193 LayerExceedsSize(bottom_right_layer_.get(), gfx::Size(right, bottom)) ?
194 gfx::Rect(bottom_right_layer_->bounds().width() - right,
195 bottom_right_layer_->bounds().height() - bottom,
196 right, bottom) :
197 gfx::Rect(),
198 bottom_right_layer_.get());
199 }
200
201 if (center_layer_.get()) {
202 if (center_width > 0 && center_height > 0) {
203 gfx::Transform transform;
204 transform.Translate(left, top);
205 transform.Scale(center_width / center_layer_->bounds().width(),
206 center_height / center_layer_->bounds().height());
207 center_layer_->SetTransform(transform);
208 }
209 center_layer_->SetVisible(center_width > 0 && center_height > 0);
210 }
211 }
212
213 void ImageGrid::SetContentBounds(const gfx::Rect& content_bounds) {
214
215 SetSize(gfx::Size(
216 content_bounds.width() + left_image_width_ + right_image_width_,
217 content_bounds.height() + top_image_height_ +
218 bottom_image_height_));
219 layer_->SetBounds(
220 gfx::Rect(content_bounds.x() - left_image_width_,
221 content_bounds.y() - top_image_height_,
222 layer_->bounds().width(),
223 layer_->bounds().height()));
224 }
225
226 void ImageGrid::ImagePainter::SetClipRect(const gfx::Rect& clip_rect,
227 ui::Layer* layer) {
228 if (clip_rect != clip_rect_) {
229 clip_rect_ = clip_rect;
230 layer->SchedulePaint(layer->bounds());
231 }
232 }
233
234 void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) {
235 if (!clip_rect_.IsEmpty())
236 canvas->ClipRect(clip_rect_);
237 canvas->DrawImageInt(*(image_->ToImageSkia()), 0, 0);
238 }
239
240 void ImageGrid::ImagePainter::OnDeviceScaleFactorChanged(
241 float device_scale_factor) {
242 // Redrawing will take care of scale factor change.
243 }
244
245 base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() {
246 return base::Closure();
247 }
248
249 // static
250 gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) {
251 return image ?
252 gfx::Size(image->ToImageSkia()->width(), image->ToImageSkia()->height()) :
253 gfx::Size();
254 }
255
256 // static
257 bool ImageGrid::LayerExceedsSize(const ui::Layer* layer,
258 const gfx::Size& size) {
259 return layer->bounds().width() > size.width() ||
260 layer->bounds().height() > size.height();
261 }
262
263 void ImageGrid::SetImage(const gfx::Image* image,
264 scoped_ptr<ui::Layer>* layer_ptr,
265 scoped_ptr<ImagePainter>* painter_ptr) {
266 // Clean out old layers and painters.
267 if (layer_ptr->get())
268 layer_->Remove(layer_ptr->get());
269 layer_ptr->reset();
270 painter_ptr->reset();
271
272 // If we're not using an image, we're done.
273 if (!image)
274 return;
275
276 // Set up the new layer and painter.
277 layer_ptr->reset(new ui::Layer(ui::LAYER_TEXTURED));
278
279 const gfx::Size size = GetImageSize(image);
280 layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height()));
281
282 painter_ptr->reset(new ImagePainter(image));
283 layer_ptr->get()->set_delegate(painter_ptr->get());
284 layer_ptr->get()->SetFillsBoundsOpaquely(false);
285 layer_ptr->get()->SetVisible(true);
286 layer_->Add(layer_ptr->get());
287 }
288
289 void ImageGrid::ScaleWidth(gfx::Size center,
290 ui::Layer* layer,
291 gfx::Transform& transform) {
292 int layer_width = ConvertSizeToPixel(layer,
293 layer->bounds().size()).width();
294 float scale = static_cast<float>(center.width()) / layer_width;
295 transform.Scale(scale, 1.0);
296 }
297
298 void ImageGrid::ScaleHeight(gfx::Size center,
299 ui::Layer* layer,
300 gfx::Transform& transform) {
301 int layer_height = ConvertSizeToPixel(layer,
302 layer->bounds().size()).height();
303 float scale = static_cast<float>(center.height()) / layer_height;
304 transform.Scale(1.0, scale);
305 }
306
307 } // namespace corewm
308 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/corewm/image_grid.h ('k') | ui/views/corewm/image_grid_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698