OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef UI_AURA_SHELL_IMAGE_GRID_H_ | |
6 #define UI_AURA_SHELL_IMAGE_GRID_H_ | |
7 #pragma once | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/gtest_prod_util.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "ui/aura_shell/aura_shell_export.h" | |
13 #include "ui/gfx/compositor/layer.h" | |
14 #include "ui/gfx/compositor/layer_delegate.h" | |
15 #include "ui/gfx/rect.h" | |
16 #include "ui/gfx/size.h" | |
17 | |
18 namespace gfx { | |
19 class Image; | |
20 } // namespace gfx | |
21 | |
22 namespace aura_shell { | |
23 namespace internal { | |
24 | |
25 // An ImageGrid is a 3x3 array of ui::Layers, each containing an image. | |
26 // | |
27 // As the grid is resized, its images fill the requested space: | |
28 // - corner images are not scaled | |
29 // - top and bottom images are scaled horizontally | |
30 // - left and right images are scaled vertically | |
31 // - the center image is scaled in both directions | |
32 // | |
33 // If one of the non-center images is smaller than the largest images in its | |
34 // row or column, it will be aligned with the outside of the grid. For | |
35 // example, given 4x4 top-left and top-right images and a 1x2 top images: | |
36 // | |
37 // +--------+---------------------+--------+ | |
38 // | | top | | | |
39 // | top- +---------------------+ top- + | |
40 // | left | | right | | |
41 // +----+---+ +---+----+ | |
42 // | | | | | |
43 // ... | |
44 // | |
45 // This may seem odd at first, but it lets ImageGrid be used to draw shadows | |
46 // with curved corners that extend inwards beyond a window's borders. In the | |
47 // below example, the top-left corner image is overlaid on top of the window's | |
48 // top-left corner: | |
49 // | |
50 // +---------+----------------------- | |
51 // | ..xxx|XXXXXXXXXXXXXXXXXX | |
52 // | .xXXXXX|XXXXXXXXXXXXXXXXXX_____ | |
53 // | .xXX | ^ window's top edge | |
54 // | .xXX | | |
55 // +---------+ | |
56 // | xXX| | |
57 // | xXX|< window's left edge | |
58 // | xXX| | |
59 // ... | |
60 // | |
61 class AURA_SHELL_EXPORT ImageGrid { | |
62 public: | |
63 // Helper class for use by tests. | |
64 class TestAPI { | |
65 public: | |
66 TestAPI(ImageGrid* grid) : grid_(grid) {} | |
67 ui::Layer* top_left_layer() const { return grid_->top_left_layer_.get(); } | |
68 ui::Layer* top_layer() const { return grid_->top_layer_.get(); } | |
69 ui::Layer* top_right_layer() const { return grid_->top_right_layer_.get(); } | |
70 ui::Layer* left_layer() const { return grid_->left_layer_.get(); } | |
71 ui::Layer* center_layer() const { return grid_->center_layer_.get(); } | |
72 ui::Layer* right_layer() const { return grid_->right_layer_.get(); } | |
73 ui::Layer* bottom_left_layer() const { | |
74 return grid_->bottom_left_layer_.get(); | |
75 } | |
76 ui::Layer* bottom_layer() const { return grid_->bottom_layer_.get(); } | |
77 ui::Layer* bottom_right_layer() const { | |
78 return grid_->bottom_right_layer_.get(); | |
79 } | |
80 | |
81 gfx::Rect top_left_clip_rect() const { | |
82 return grid_->top_left_painter_->clip_rect_; | |
83 } | |
84 gfx::Rect top_right_clip_rect() const { | |
85 return grid_->top_right_painter_->clip_rect_; | |
86 } | |
87 gfx::Rect bottom_left_clip_rect() const { | |
88 return grid_->bottom_left_painter_->clip_rect_; | |
89 } | |
90 gfx::Rect bottom_right_clip_rect() const { | |
91 return grid_->bottom_right_painter_->clip_rect_; | |
92 } | |
93 | |
94 // Returns |layer|'s bounds after applying the layer's current transform. | |
95 gfx::Rect GetTransformedLayerBounds(const ui::Layer& layer); | |
96 | |
97 private: | |
98 ImageGrid* grid_; // not owned | |
99 | |
100 DISALLOW_COPY_AND_ASSIGN(TestAPI); | |
101 }; | |
102 | |
103 ImageGrid(); | |
104 ~ImageGrid(); | |
105 | |
106 ui::Layer* layer() { return layer_.get(); } | |
107 int top_image_height() const { return top_image_height_; } | |
108 int bottom_image_height() const { return bottom_image_height_; } | |
109 int left_image_width() const { return left_image_width_; } | |
110 int right_image_width() const { return right_image_width_; } | |
111 | |
112 // Initializes the grid to display the passed-in images (any of which can be | |
113 // NULL). Ownership of the images remains with the caller. | |
114 void Init(const gfx::Image* top_left_image, | |
115 const gfx::Image* top_image, | |
116 const gfx::Image* top_right_image, | |
117 const gfx::Image* left_image, | |
118 const gfx::Image* center_image, | |
119 const gfx::Image* right_image, | |
120 const gfx::Image* bottom_left_image, | |
121 const gfx::Image* bottom_image, | |
122 const gfx::Image* bottom_right_image); | |
123 | |
124 void SetSize(const gfx::Size& size); | |
125 | |
126 private: | |
127 // Delegate responsible for painting a specific image on a layer. | |
128 class ImagePainter : public ui::LayerDelegate { | |
129 public: | |
130 ImagePainter(const gfx::Image* image) : image_(image) {} | |
131 virtual ~ImagePainter() {} | |
132 | |
133 // Clips |layer| to |clip_rect|. Triggers a repaint if the clipping | |
134 // rectangle has changed. An empty rectangle disables clipping. | |
135 void SetClipRect(const gfx::Rect& clip_rect, ui::Layer* layer); | |
136 | |
137 // ui::LayerDelegate implementation: | |
138 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE; | |
139 | |
140 private: | |
141 friend class TestAPI; | |
142 | |
143 const gfx::Image* image_; // not owned | |
144 | |
145 gfx::Rect clip_rect_; | |
146 | |
147 DISALLOW_COPY_AND_ASSIGN(ImagePainter); | |
148 }; | |
149 | |
150 // Returns the dimensions of |image| if non-NULL or gfx::Size(0, 0) otherwise. | |
151 static gfx::Size GetImageSize(const gfx::Image* image); | |
152 | |
153 // Returns true if |layer|'s bounds don't fit within |size|. | |
154 static bool LayerExceedsSize(const ui::Layer* layer, const gfx::Size& size); | |
155 | |
156 // Initializes |layer_ptr| and |painter_ptr| to display |image|. | |
157 // Also adds the passed-in layer to |layer_|. | |
158 void InitImage(const gfx::Image* image, | |
159 scoped_ptr<ui::Layer>* layer_ptr, | |
160 scoped_ptr<ImagePainter>* painter_ptr); | |
161 | |
162 // Layer that contains all of the image layers. | |
163 scoped_ptr<ui::Layer> layer_; | |
164 | |
165 // The grid's dimensions. | |
166 gfx::Size size_; | |
167 | |
168 // Heights and widths of the images displayed by |top_layer_|, | |
169 // |bottom_layer_|, |left_layer_|, and |right_layer_|. | |
170 int top_image_height_; | |
171 int bottom_image_height_; | |
172 int left_image_width_; | |
173 int right_image_width_; | |
174 | |
175 // Heights of the tallest images in the top and bottom rows and the widest | |
176 // images in the left and right columns. | |
177 int top_row_height_; | |
178 int bottom_row_height_; | |
179 int left_column_width_; | |
180 int right_column_width_; | |
181 | |
182 // Layers used to display the various images. Children of |layer_|. | |
183 // Positions for which no images were supplied are NULL. | |
184 scoped_ptr<ui::Layer> top_left_layer_; | |
185 scoped_ptr<ui::Layer> top_layer_; | |
186 scoped_ptr<ui::Layer> top_right_layer_; | |
187 scoped_ptr<ui::Layer> left_layer_; | |
188 scoped_ptr<ui::Layer> center_layer_; | |
189 scoped_ptr<ui::Layer> right_layer_; | |
190 scoped_ptr<ui::Layer> bottom_left_layer_; | |
191 scoped_ptr<ui::Layer> bottom_layer_; | |
192 scoped_ptr<ui::Layer> bottom_right_layer_; | |
193 | |
194 // Delegates responsible for painting the above layers. | |
195 // Positions for which no images were supplied are NULL. | |
196 scoped_ptr<ImagePainter> top_left_painter_; | |
197 scoped_ptr<ImagePainter> top_painter_; | |
198 scoped_ptr<ImagePainter> top_right_painter_; | |
199 scoped_ptr<ImagePainter> left_painter_; | |
200 scoped_ptr<ImagePainter> center_painter_; | |
201 scoped_ptr<ImagePainter> right_painter_; | |
202 scoped_ptr<ImagePainter> bottom_left_painter_; | |
203 scoped_ptr<ImagePainter> bottom_painter_; | |
204 scoped_ptr<ImagePainter> bottom_right_painter_; | |
205 | |
206 DISALLOW_COPY_AND_ASSIGN(ImageGrid); | |
207 }; | |
208 | |
209 } // namespace internal | |
210 } // namespace aura_shell | |
211 | |
212 #endif // UI_AURA_SHELL_IMAGE_GRID_H_ | |
OLD | NEW |