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