OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/aura_shell/image_grid.h" | 5 #include "ui/aura_shell/image_grid.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ui/gfx/canvas.h" | 9 #include "ui/gfx/canvas.h" |
10 #include "ui/gfx/image/image.h" | 10 #include "ui/gfx/image/image.h" |
11 #include "ui/gfx/transform.h" | 11 #include "ui/gfx/transform.h" |
12 #include "third_party/skia/include/core/SkColor.h" | 12 #include "third_party/skia/include/core/SkColor.h" |
13 #include "third_party/skia/include/core/SkXfermode.h" | 13 #include "third_party/skia/include/core/SkXfermode.h" |
14 | 14 |
15 using std::max; | 15 using std::max; |
| 16 using std::min; |
16 | 17 |
17 namespace aura_shell { | 18 namespace aura_shell { |
18 namespace internal { | 19 namespace internal { |
19 | 20 |
20 gfx::Rect ImageGrid::TestAPI::GetTransformedLayerBounds( | 21 gfx::Rect ImageGrid::TestAPI::GetTransformedLayerBounds( |
21 const ui::Layer& layer) { | 22 const ui::Layer& layer) { |
22 gfx::Rect bounds = layer.bounds(); | 23 gfx::Rect bounds = layer.bounds(); |
23 layer.transform().TransformRect(&bounds); | 24 layer.transform().TransformRect(&bounds); |
24 return bounds; | 25 return bounds; |
25 } | 26 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 size_ = size; | 86 size_ = size; |
86 | 87 |
87 gfx::Rect updated_bounds = layer_->bounds(); | 88 gfx::Rect updated_bounds = layer_->bounds(); |
88 updated_bounds.set_size(size); | 89 updated_bounds.set_size(size); |
89 layer_->SetBounds(updated_bounds); | 90 layer_->SetBounds(updated_bounds); |
90 | 91 |
91 float center_width = size.width() - left_column_width_ - right_column_width_; | 92 float center_width = size.width() - left_column_width_ - right_column_width_; |
92 float center_height = size.height() - top_row_height_ - bottom_row_height_; | 93 float center_height = size.height() - top_row_height_ - bottom_row_height_; |
93 | 94 |
94 if (top_layer_.get()) { | 95 if (top_layer_.get()) { |
95 ui::Transform transform; | 96 if (center_width > 0) { |
96 transform.SetScaleX(center_width / top_layer_->bounds().width()); | 97 ui::Transform transform; |
97 transform.ConcatTranslate(left_column_width_, 0); | 98 transform.SetScaleX(center_width / top_layer_->bounds().width()); |
98 top_layer_->SetTransform(transform); | 99 transform.ConcatTranslate(left_column_width_, 0); |
| 100 top_layer_->SetTransform(transform); |
| 101 } |
| 102 top_layer_->SetVisible(center_width > 0); |
99 } | 103 } |
100 if (bottom_layer_.get()) { | 104 if (bottom_layer_.get()) { |
101 ui::Transform transform; | 105 if (center_width > 0) { |
102 transform.SetScaleX(center_width / bottom_layer_->bounds().width()); | 106 ui::Transform transform; |
103 transform.ConcatTranslate( | 107 transform.SetScaleX(center_width / bottom_layer_->bounds().width()); |
104 left_column_width_, size.height() - bottom_layer_->bounds().height()); | 108 transform.ConcatTranslate( |
105 bottom_layer_->SetTransform(transform); | 109 left_column_width_, size.height() - bottom_layer_->bounds().height()); |
| 110 bottom_layer_->SetTransform(transform); |
| 111 } |
| 112 bottom_layer_->SetVisible(center_width > 0); |
106 } | 113 } |
107 if (left_layer_.get()) { | 114 if (left_layer_.get()) { |
108 ui::Transform transform; | 115 if (center_height > 0) { |
109 transform.SetScaleY(center_height / left_layer_->bounds().height()); | 116 ui::Transform transform; |
110 transform.ConcatTranslate(0, top_row_height_); | 117 transform.SetScaleY(center_height / left_layer_->bounds().height()); |
111 left_layer_->SetTransform(transform); | 118 transform.ConcatTranslate(0, top_row_height_); |
| 119 left_layer_->SetTransform(transform); |
| 120 } |
| 121 left_layer_->SetVisible(center_height > 0); |
112 } | 122 } |
113 if (right_layer_.get()) { | 123 if (right_layer_.get()) { |
114 ui::Transform transform; | 124 if (center_height > 0) { |
115 transform.SetScaleY(center_height / right_layer_->bounds().height()); | 125 ui::Transform transform; |
116 transform.ConcatTranslate( | 126 transform.SetScaleY(center_height / right_layer_->bounds().height()); |
117 size.width() - right_layer_->bounds().width(), top_row_height_); | 127 transform.ConcatTranslate( |
118 right_layer_->SetTransform(transform); | 128 size.width() - right_layer_->bounds().width(), top_row_height_); |
| 129 right_layer_->SetTransform(transform); |
| 130 } |
| 131 right_layer_->SetVisible(center_height > 0); |
119 } | 132 } |
120 | 133 |
| 134 // Calculate the available amount of space for corner images on all sides of |
| 135 // the grid. If the images don't fit, we need to clip them. |
| 136 const int left = min(left_column_width_, size_.width() / 2); |
| 137 const int right = min(right_column_width_, size_.width() - left); |
| 138 const int top = min(top_row_height_, size_.height() / 2); |
| 139 const int bottom = min(bottom_row_height_, size_.height() - top); |
| 140 |
121 if (top_left_layer_.get()) { | 141 if (top_left_layer_.get()) { |
122 // No transformation needed; it should be at (0, 0) and unscaled. | 142 // No transformation needed; it should be at (0, 0) and unscaled. |
| 143 top_left_painter_->SetClipRect( |
| 144 LayerExceedsSize(top_left_layer_.get(), gfx::Size(left, top)) ? |
| 145 gfx::Rect(gfx::Rect(0, 0, left, top)) : |
| 146 gfx::Rect(), |
| 147 top_left_layer_.get()); |
123 } | 148 } |
124 if (top_right_layer_.get()) { | 149 if (top_right_layer_.get()) { |
125 ui::Transform transform; | 150 ui::Transform transform; |
126 transform.SetTranslateX(size.width() - top_right_layer_->bounds().width()); | 151 transform.SetTranslateX(size.width() - top_right_layer_->bounds().width()); |
127 top_right_layer_->SetTransform(transform); | 152 top_right_layer_->SetTransform(transform); |
| 153 top_right_painter_->SetClipRect( |
| 154 LayerExceedsSize(top_right_layer_.get(), gfx::Size(right, top)) ? |
| 155 gfx::Rect(top_right_layer_->bounds().width() - right, 0, |
| 156 right, top) : |
| 157 gfx::Rect(), |
| 158 top_right_layer_.get()); |
128 } | 159 } |
129 if (bottom_left_layer_.get()) { | 160 if (bottom_left_layer_.get()) { |
130 ui::Transform transform; | 161 ui::Transform transform; |
131 transform.SetTranslateY( | 162 transform.SetTranslateY( |
132 size.height() - bottom_left_layer_->bounds().height()); | 163 size.height() - bottom_left_layer_->bounds().height()); |
133 bottom_left_layer_->SetTransform(transform); | 164 bottom_left_layer_->SetTransform(transform); |
| 165 bottom_left_painter_->SetClipRect( |
| 166 LayerExceedsSize(bottom_left_layer_.get(), gfx::Size(left, bottom)) ? |
| 167 gfx::Rect(0, bottom_left_layer_->bounds().height() - bottom, |
| 168 left, bottom) : |
| 169 gfx::Rect(), |
| 170 bottom_left_layer_.get()); |
134 } | 171 } |
135 if (bottom_right_layer_.get()) { | 172 if (bottom_right_layer_.get()) { |
136 ui::Transform transform; | 173 ui::Transform transform; |
137 transform.SetTranslate( | 174 transform.SetTranslate( |
138 size.width() - bottom_right_layer_->bounds().width(), | 175 size.width() - bottom_right_layer_->bounds().width(), |
139 size.height() - bottom_right_layer_->bounds().height()); | 176 size.height() - bottom_right_layer_->bounds().height()); |
140 bottom_right_layer_->SetTransform(transform); | 177 bottom_right_layer_->SetTransform(transform); |
| 178 bottom_right_painter_->SetClipRect( |
| 179 LayerExceedsSize(bottom_right_layer_.get(), gfx::Size(right, bottom)) ? |
| 180 gfx::Rect(bottom_right_layer_->bounds().width() - right, |
| 181 bottom_right_layer_->bounds().height() - bottom, |
| 182 right, bottom) : |
| 183 gfx::Rect(), |
| 184 bottom_right_layer_.get()); |
141 } | 185 } |
142 | 186 |
143 if (center_layer_.get()) { | 187 if (center_layer_.get()) { |
144 ui::Transform transform; | 188 if (center_width > 0 && center_height > 0) { |
145 transform.SetScale(center_width / center_layer_->bounds().width(), | 189 ui::Transform transform; |
146 center_height / center_layer_->bounds().height()); | 190 transform.SetScale(center_width / center_layer_->bounds().width(), |
147 transform.ConcatTranslate(left_column_width_, top_row_height_); | 191 center_height / center_layer_->bounds().height()); |
148 center_layer_->SetTransform(transform); | 192 transform.ConcatTranslate(left_column_width_, top_row_height_); |
| 193 center_layer_->SetTransform(transform); |
| 194 } |
| 195 center_layer_->SetVisible(center_width > 0 && center_height > 0); |
| 196 } |
| 197 } |
| 198 |
| 199 void ImageGrid::ImagePainter::SetClipRect(const gfx::Rect& clip_rect, |
| 200 ui::Layer* layer) { |
| 201 if (clip_rect != clip_rect_) { |
| 202 clip_rect_ = clip_rect; |
| 203 layer->ScheduleDraw(); |
149 } | 204 } |
150 } | 205 } |
151 | 206 |
152 void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) { | 207 void ImageGrid::ImagePainter::OnPaintLayer(gfx::Canvas* canvas) { |
| 208 if (!clip_rect_.IsEmpty()) |
| 209 canvas->ClipRect(clip_rect_); |
153 canvas->DrawBitmapInt(*(image_->ToSkBitmap()), 0, 0); | 210 canvas->DrawBitmapInt(*(image_->ToSkBitmap()), 0, 0); |
154 } | 211 } |
155 | 212 |
156 // static | 213 // static |
157 gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) { | 214 gfx::Size ImageGrid::GetImageSize(const gfx::Image* image) { |
158 return image ? | 215 return image ? |
159 gfx::Size(image->ToSkBitmap()->width(), image->ToSkBitmap()->height()) : | 216 gfx::Size(image->ToSkBitmap()->width(), image->ToSkBitmap()->height()) : |
160 gfx::Size(); | 217 gfx::Size(); |
161 } | 218 } |
162 | 219 |
| 220 // static |
| 221 bool ImageGrid::LayerExceedsSize(const ui::Layer* layer, |
| 222 const gfx::Size& size) { |
| 223 return layer->bounds().width() > size.width() || |
| 224 layer->bounds().height() > size.height(); |
| 225 } |
| 226 |
163 void ImageGrid::InitImage(const gfx::Image* image, | 227 void ImageGrid::InitImage(const gfx::Image* image, |
164 scoped_ptr<ui::Layer>* layer_ptr, | 228 scoped_ptr<ui::Layer>* layer_ptr, |
165 scoped_ptr<ImagePainter>* painter_ptr) { | 229 scoped_ptr<ImagePainter>* painter_ptr) { |
166 if (!image) | 230 if (!image) |
167 return; | 231 return; |
168 | 232 |
169 layer_ptr->reset(new ui::Layer(ui::Layer::LAYER_HAS_TEXTURE)); | 233 layer_ptr->reset(new ui::Layer(ui::Layer::LAYER_HAS_TEXTURE)); |
170 | 234 |
171 const gfx::Size size = GetImageSize(image); | 235 const gfx::Size size = GetImageSize(image); |
172 layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height())); | 236 layer_ptr->get()->SetBounds(gfx::Rect(0, 0, size.width(), size.height())); |
173 | 237 |
174 painter_ptr->reset(new ImagePainter(image)); | 238 painter_ptr->reset(new ImagePainter(image)); |
175 layer_ptr->get()->set_delegate(painter_ptr->get()); | 239 layer_ptr->get()->set_delegate(painter_ptr->get()); |
176 layer_ptr->get()->SetFillsBoundsOpaquely(false); | 240 layer_ptr->get()->SetFillsBoundsOpaquely(false); |
177 layer_ptr->get()->SetVisible(true); | 241 layer_ptr->get()->SetVisible(true); |
178 layer_->Add(layer_ptr->get()); | 242 layer_->Add(layer_ptr->get()); |
179 } | 243 } |
180 | 244 |
181 } // namespace internal | 245 } // namespace internal |
182 } // namespace aura_shell | 246 } // namespace aura_shell |
OLD | NEW |