1 /** 2 * Module for space and dimension manipulation. 3 * 4 * Authors: 5 * Jacob Jensen 6 * License: 7 * https://github.com/PoisonEngine/poison-ui/blob/master/LICENSE 8 */ 9 module poison.ui.space; 10 11 import poison.core : Point, Size, Edge, Location, EventObserver, ChangeEventArgs; 12 13 /// A wrapper around a space. 14 class Space : EventObserver { 15 private: 16 /// The position. 17 Point _position; 18 19 /// The size. 20 Size _size; 21 22 /// The margin. 23 Edge _margin; 24 25 /// The padding. 26 Edge _padding; 27 28 public: 29 /** 30 * Creates a new space. 31 * Params: 32 * position = The position. 33 * size = The size. 34 */ 35 this(Point position, Size size) { 36 assert(position !is null); 37 assert(size !is null); 38 39 _position = position; 40 _size = size; 41 42 _margin = new Edge(0,0,0,0); 43 _padding = new Edge(0,0,0,0); 44 } 45 46 @property { 47 /// Gets the position of the space. 48 Point position() { return _position; } 49 50 /// Sets the position of the space. 51 void position(Point newPosition) { 52 auto oldPosition = _position; 53 _position = newPosition; 54 55 fireEvent("position", new ChangeEventArgs!Point(oldPosition, _position)); 56 } 57 58 /// Gets the x coordinate of the space. 59 ptrdiff_t x() { return _position.x; } 60 61 /// Gets the y coordinate of the space. 62 ptrdiff_t y() { return _position.y; } 63 64 /// Gets the size of the space. 65 Size size() { return _size; } 66 67 /// Sets the size of the space. 68 void size(Size newSize) { 69 auto oldSize = _size; 70 _size = newSize; 71 72 fireEvent("size", new ChangeEventArgs!Size(oldSize, _size)); 73 } 74 75 /// Gets the width of the space. 76 size_t width() { return _size.width; } 77 78 /// Gets the height of the space. 79 size_t height() { return _size.height; } 80 81 /// Gets the margin of the space. 82 Edge margin() { return _margin; } 83 84 /// Sets the margin of the space. 85 void margin(Edge newMargin) { 86 auto oldMargin = _margin; 87 _margin = newMargin; 88 89 fireEvent("margin", new ChangeEventArgs!Edge(oldMargin, _margin)); 90 } 91 92 /// Gets the top margin of the space. 93 ptrdiff_t topMargin() { return _margin.top; } 94 95 /// Gets the right margin of the space. 96 ptrdiff_t rightMargin() { return _margin.right; } 97 98 /// Gets the bottom margin of the space. 99 ptrdiff_t bottomMargin() { return _margin.bottom; } 100 101 /// Gets the left margin of the space. 102 ptrdiff_t leftMargin() { return _margin.left; } 103 104 /// Gets the padding of the space. 105 Edge padding() { return _padding; } 106 107 /// Sets the padding of the space. 108 void padding(Edge newPadding) { 109 auto oldPadding = _padding; 110 _padding = newPadding; 111 112 fireEvent("padding", new ChangeEventArgs!Edge(oldPadding, _padding)); 113 } 114 } 115 116 /** 117 * Moves the space to another space. 118 * Params: 119 * target = The target of the space. 120 */ 121 void moveTo(Location location)(Space target) { 122 assert(target !is null); 123 124 auto newX = target.x; 125 auto newY = target.y; 126 127 static if (location == Location.northWest) { 128 newX -= width + target.marginLeft; 129 newY -= height + target.marginTop; 130 } 131 else static if (location == Location.north) { 132 newY -= height + target.marginTop; 133 } 134 else static if (location == Location.northEast) { 135 newX += target.width + target.marginRight; 136 newY -= height + target.marginTop; 137 } 138 else static if (location == Location.east) { 139 newX += target.width + target.marginRight; 140 } 141 else static if (location == Location.southEast) { 142 newX += target.width + target.marginRight; 143 newY += target.height + target.marginBottom; 144 } 145 else static if (location == Location.south) { 146 newY += target.height + target.marginBottom; 147 } 148 else static if (location == Location.southWest) { 149 newX -= width + target.marginLeft; 150 newY += target.height + target.marginBottom; 151 } 152 else static if (location == Location.west) { 153 newX -= width + target.marginLeft; 154 } 155 else { 156 static assert(0); 157 } 158 159 position = new Point(newX, newY); 160 } 161 162 /** 163 * Moves the space into another space. 164 * Params: 165 * target = The space to move the space into. 166 */ 167 void moveIn(Location location)(Space target) { 168 assert(target !is null); 169 170 auto newX = target.x; 171 auto newY = target.y; 172 173 static if (location == Location.northWest) { 174 newX += target.paddingLeft; 175 newY += target.paddingTop; 176 } 177 else static if (location == Location.north) { 178 newX += (target.width / 2) - (width / 2); 179 newY += target.paddingTop; 180 } 181 else static if (location == Location.northEast) { 182 newX += target.width - (target.paddingRight + width); 183 } 184 else static if (location == Location.east) { 185 newX += target.width - (target.paddingRight + width); 186 newY += (target.height / 2) - (height / 2); 187 } 188 else static if (location == Location.southEast) { 189 newX += target.width - (target.paddingRight + width); 190 newY += targer.height - (target.paddingBottom + height); 191 } 192 else static if (location == Location.south) { 193 newX += (targer.width / 2) - (width / 2); 194 newY += targer.height - (target.paddingBottom + height); 195 } 196 else static if (location == Location.southWest) { 197 newX += target.paddingLeft; 198 newY += target.height - (target.paddingBottom + height); 199 } 200 else static if (location == Location.west) { 201 newX += target.paddingLeft; 202 newY += (target.height / 2) - (height / 2); 203 } 204 else { 205 static assert(0); 206 } 207 208 position = new Point(newX, newY); 209 } 210 211 /** 212 * Centers the x coordinate of the space relative to another space. 213 * Params: 214 * target = The target to be relative to. 215 */ 216 void centerX(Space target) { 217 position = new Point((target.width / 2) - (width / 2), y); 218 } 219 220 /** 221 * Centers the y coordinate of the space relative to another space. 222 * Params: 223 * target = The target to be relative to. 224 */ 225 void centerY(Space target) { 226 position = new Point(x, (target.height / 2) - (height / 2)); 227 } 228 229 /** 230 * Centers the space relative to another space. 231 * Params: 232 * target = The target to be relative to. 233 */ 234 void center(Space target) { 235 position = new Point((target.width / 2) - (width / 2), (target.height / 2) - (height / 2)); 236 } 237 238 void moveX(ptrdiff_t amount) { 239 position = new Point(x + amount, y); 240 } 241 242 void moveY(ptrdiff_t amount) { 243 position = new Point(x, y + amount); 244 } 245 246 /** 247 * Checks whether the space intersects with a point. 248 * Params: 249 * p = The point to check for intersection with. 250 * Returns: 251 * If the space intersects with the point. 252 */ 253 bool intersect(Point p) { 254 return (p.x > this.x) && 255 (p.x < (this.x + this.width)) && 256 (p.y > this.y) && 257 (p.y < (this.y + this.height)); 258 } 259 260 /** 261 * Checks whether the space intersects with another space. 262 * Params: 263 * target = The space to check for intersection with. 264 * Returns: 265 * True if the two spaces intersects. 266 */ 267 bool intersect(Space target) { 268 return(target.x < this.x + this.width) && 269 (this.x < (target.x + target.width)) && 270 (target.y < this.y + this.height) && 271 (this.y < target.y + target.height); 272 } 273 }