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