comparison dwtx/jface/util/Geometry.d @ 4:c87617952847

some JFace modules
author Frank Benoit <benoit@tionex.de>
date Fri, 28 Mar 2008 17:08:33 +0100
parents
children da5ad8eedf5d
comparison
equal deleted inserted replaced
3:6518c18a01f7 4:c87617952847
1 /*******************************************************************************
2 * Copyright (c) 2004, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.jface.util.Geometry;
14
15 import dwt.DWT;
16 import dwt.graphics.Point;
17 import dwt.graphics.Rectangle;
18 import dwt.widgets.Control;
19
20 import dwt.dwthelper.utils;
21 import dwt.dwthelper.Integer;
22
23 /**
24 * Contains static methods for performing simple geometric operations
25 * on the DWT geometry classes.
26 *
27 * @since 3.0
28 */
29 public class Geometry {
30
31 /**
32 * Prevent this class from being instantiated.
33 *
34 * @since 3.0
35 */
36 private this() {
37 //This is not instantiated
38 }
39
40 /**
41 * Returns the square of the distance between two points.
42 * <p>This is preferred over the real distance when searching
43 * for the closest point, since it avoids square roots.</p>
44 *
45 * @param p1 first endpoint
46 * @param p2 second endpoint
47 * @return the square of the distance between the two points
48 *
49 * @since 3.0
50 */
51 public static int distanceSquared(Point p1, Point p2) {
52 int term1 = p1.x - p2.x;
53 int term2 = p1.y - p2.y;
54 return term1 * term1 + term2 * term2;
55 }
56
57 /**
58 * Returns the magnitude of the given 2d vector (represented as a Point)
59 *
60 * @param p point representing the 2d vector whose magnitude is being computed
61 * @return the magnitude of the given 2d vector
62 * @since 3.0
63 */
64 public static double magnitude(Point p) {
65 return Math.sqrt( cast(real) magnitudeSquared(p));
66 }
67
68 /**
69 * Returns the square of the magnitude of the given 2-space vector (represented
70 * using a point)
71 *
72 * @param p the point whose magnitude is being computed
73 * @return the square of the magnitude of the given vector
74 * @since 3.0
75 */
76 public static int magnitudeSquared(Point p) {
77 return p.x * p.x + p.y * p.y;
78 }
79
80 /**
81 * Returns the dot product of the given vectors (expressed as Points)
82 *
83 * @param p1 the first vector
84 * @param p2 the second vector
85 * @return the dot product of the two vectors
86 * @since 3.0
87 */
88 public static int dotProduct(Point p1, Point p2) {
89 return p1.x * p2.x + p1.y * p2.y;
90 }
91
92 /**
93 * Returns a new point whose coordinates are the minimum of the coordinates of the
94 * given points
95 *
96 * @param p1 a Point
97 * @param p2 a Point
98 * @return a new point whose coordinates are the minimum of the coordinates of the
99 * given points
100 * @since 3.0
101 */
102 public static Point min(Point p1, Point p2) {
103 return new Point(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y));
104 }
105
106 /**
107 * Returns a new point whose coordinates are the maximum of the coordinates
108 * of the given points
109 * @param p1 a Point
110 * @param p2 a Point
111 * @return point a new point whose coordinates are the maximum of the coordinates
112 * @since 3.0
113 */
114 public static Point max(Point p1, Point p2) {
115 return new Point(Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));
116 }
117
118 /**
119 * Returns a vector in the given direction with the given
120 * magnitude. Directions are given using DWT direction constants, and
121 * the resulting vector is in the screen's coordinate system. That is,
122 * the vector (0, 1) is down and the vector (1, 0) is right.
123 *
124 * @param distance magnitude of the vector
125 * @param direction one of DWT.TOP, DWT.BOTTOM, DWT.LEFT, or DWT.RIGHT
126 * @return a point representing a vector in the given direction with the given magnitude
127 * @since 3.0
128 */
129 public static Point getDirectionVector(int distance, int direction) {
130 switch (direction) {
131 case DWT.TOP:
132 return new Point(0, -distance);
133 case DWT.BOTTOM:
134 return new Point(0, distance);
135 case DWT.LEFT:
136 return new Point(-distance, 0);
137 case DWT.RIGHT:
138 return new Point(distance, 0);
139 }
140
141 return new Point(0, 0);
142 }
143
144 /**
145 * Returns the point in the center of the given rectangle.
146 *
147 * @param rect rectangle being computed
148 * @return a Point at the center of the given rectangle.
149 * @since 3.0
150 */
151 public static Point centerPoint(Rectangle rect) {
152 return new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
153 }
154
155 /**
156 * Returns a copy of the given point
157 *
158 * @param toCopy point to copy
159 * @return a copy of the given point
160 */
161 public static Point copy(Point toCopy) {
162 return new Point(toCopy.x, toCopy.y);
163 }
164
165 /**
166 * Sets result equal to toCopy
167 *
168 * @param result object that will be modified
169 * @param toCopy object that will be copied
170 * @since 3.1
171 */
172 public static void set(Point result, Point toCopy) {
173 result.x = toCopy.x;
174 result.y = toCopy.y;
175 }
176
177 /**
178 * Sets result equal to toCopy
179 *
180 * @param result object that will be modified
181 * @param toCopy object that will be copied
182 * @since 3.1
183 */
184 public static void set(Rectangle result, Rectangle toCopy) {
185 result.x = toCopy.x;
186 result.y = toCopy.y;
187 result.width = toCopy.width;
188 result.height = toCopy.height;
189 }
190
191 /**
192 * <p>Returns a new difference Rectangle whose x, y, width, and height are equal to the difference of the corresponding
193 * attributes from the given rectangles</p>
194 *
195 * <p></p>
196 * <b>Example: Compute the margins for a given Composite, and apply those same margins to a new GridLayout</b>
197 *
198 * <code><pre>
199 * // Compute the client area, in the coordinate system of the input composite's parent
200 * Rectangle clientArea = Display.getCurrent().map(inputComposite,
201 * inputComposite.getParent(), inputComposite.getClientArea());
202 *
203 * // Compute the margins for a given Composite by subtracting the client area from the composite's bounds
204 * Rectangle margins = Geometry.subtract(inputComposite.getBounds(), clientArea);
205 *
206 * // Now apply these margins to a new GridLayout
207 * GridLayout layout = GridLayoutFactory.fillDefaults().margins(margins).create();
208 * </pre></code>
209 *
210 * @param rect1 first rectangle
211 * @param rect2 rectangle to subtract
212 * @return the difference between the two rectangles (computed as rect1 - rect2)
213 * @since 3.3
214 */
215 public static Rectangle subtract(Rectangle rect1, Rectangle rect2) {
216 return new Rectangle(rect1.x - rect2.x, rect1.y - rect2.y, rect1.width - rect2.width, rect1.height - rect2.height);
217 }
218
219 /**
220 * <p>Returns a new Rectangle whose x, y, width, and height is the sum of the x, y, width, and height values of
221 * both rectangles respectively.</p>
222 *
223 * @param rect1 first rectangle to add
224 * @param rect2 second rectangle to add
225 * @return a new rectangle whose x, y, height, and width attributes are the sum of the corresponding attributes from
226 * the arguments.
227 * @since 3.3
228 */
229 public static Rectangle add(Rectangle rect1, Rectangle rect2) {
230 return new Rectangle(rect1.x + rect2.x, rect1.y + rect2.y,
231 rect1.width + rect2.width, rect1.height + rect2.height);
232 }
233
234 /**
235 * Adds two points as 2d vectors. Returns a new point whose coordinates are
236 * the sum of the original two points.
237 *
238 * @param point1 the first point (not null)
239 * @param point2 the second point (not null)
240 * @return a new point whose coordinates are the sum of the given points
241 * @since 3.0
242 */
243 public static Point add(Point point1, Point point2) {
244 return new Point(point1.x + point2.x, point1.y + point2.y);
245 }
246
247 /**
248 * Divides both coordinates of the given point by the given scalar.
249 *
250 * @since 3.1
251 *
252 * @param toDivide point to divide
253 * @param scalar denominator
254 * @return a new Point whose coordinates are equal to the original point divided by the scalar
255 */
256 public static Point divide(Point toDivide, int scalar) {
257 return new Point(toDivide.x / scalar, toDivide.y / scalar);
258 }
259
260
261 /**
262 * Performs vector subtraction on two points. Returns a new point equal to
263 * (point1 - point2).
264 *
265 * @param point1 initial point
266 * @param point2 vector to subtract
267 * @return the difference (point1 - point2)
268 * @since 3.0
269 */
270 public static Point subtract(Point point1, Point point2) {
271 return new Point(point1.x - point2.x, point1.y - point2.y);
272 }
273
274 /**
275 * Swaps the X and Y coordinates of the given point.
276 *
277 * @param toFlip modifies this point
278 * @since 3.1
279 */
280 public static void flipXY(Point toFlip) {
281 int temp = toFlip.x;
282 toFlip.x = toFlip.y;
283 toFlip.y = temp;
284 }
285
286 /**
287 * Swaps the X and Y coordinates of the given rectangle, along with the height and width.
288 *
289 * @param toFlip modifies this rectangle
290 * @since 3.1
291 */
292 public static void flipXY(Rectangle toFlip) {
293 int temp = toFlip.x;
294 toFlip.x = toFlip.y;
295 toFlip.y = temp;
296
297 temp = toFlip.width;
298 toFlip.width = toFlip.height;
299 toFlip.height = temp;
300 }
301
302 /**
303 * Returns the height or width of the given rectangle.
304 *
305 * @param toMeasure rectangle to measure
306 * @param width returns the width if true, and the height if false
307 * @return the width or height of the given rectangle
308 * @since 3.0
309 */
310 public static int getDimension(Rectangle toMeasure, bool width) {
311 if (width) {
312 return toMeasure.width;
313 }
314 return toMeasure.height;
315 }
316
317 /**
318 * Returns the x or y coordinates of the given point.
319 *
320 * @param toMeasure point being measured
321 * @param width if true, returns x. Otherwise, returns y.
322 * @return the x or y coordinate
323 * @since 3.1
324 */
325 public static int getCoordinate(Point toMeasure, bool width) {
326 return width ? toMeasure.x : toMeasure.y;
327 }
328
329 /**
330 * Returns the x or y coordinates of the given rectangle.
331 *
332 * @param toMeasure rectangle being measured
333 * @param width if true, returns x. Otherwise, returns y.
334 * @return the x or y coordinate
335 * @since 3.1
336 */
337 public static int getCoordinate(Rectangle toMeasure, bool width) {
338 return width ? toMeasure.x : toMeasure.y;
339 }
340
341 /**
342 * Sets one dimension of the given rectangle. Modifies the given rectangle.
343 *
344 * @param toSet rectangle to modify
345 * @param width if true, the width is modified. If false, the height is modified.
346 * @param newCoordinate new value of the width or height
347 * @since 3.1
348 */
349 public static void setDimension(Rectangle toSet, bool width, int newCoordinate) {
350 if (width) {
351 toSet.width = newCoordinate;
352 } else {
353 toSet.height = newCoordinate;
354 }
355 }
356
357 /**
358 * Sets one coordinate of the given rectangle. Modifies the given rectangle.
359 *
360 * @param toSet rectangle to modify
361 * @param width if true, the x coordinate is modified. If false, the y coordinate is modified.
362 * @param newCoordinate new value of the x or y coordinates
363 * @since 3.1
364 */
365 public static void setCoordinate(Rectangle toSet, bool width, int newCoordinate) {
366 if (width) {
367 toSet.x = newCoordinate;
368 } else {
369 toSet.y = newCoordinate;
370 }
371 }
372
373 /**
374 * Sets one coordinate of the given point. Modifies the given point.
375 *
376 * @param toSet point to modify
377 * @param width if true, the x coordinate is modified. If false, the y coordinate is modified.
378 * @param newCoordinate new value of the x or y coordinates
379 * @since 3.1
380 */
381 public static void setCoordinate(Point toSet, bool width, int newCoordinate) {
382 if (width) {
383 toSet.x = newCoordinate;
384 } else {
385 toSet.y = newCoordinate;
386 }
387 }
388
389 /**
390 * Returns the distance of the given point from a particular side of the given rectangle.
391 * Returns negative values for points outside the rectangle.
392 *
393 * @param rectangle a bounding rectangle
394 * @param testPoint a point to test
395 * @param edgeOfInterest side of the rectangle to test against
396 * @return the distance of the given point from the given edge of the rectangle
397 * @since 3.0
398 */
399 public static int getDistanceFromEdge(Rectangle rectangle, Point testPoint,
400 int edgeOfInterest) {
401 switch (edgeOfInterest) {
402 case DWT.TOP:
403 return testPoint.y - rectangle.y;
404 case DWT.BOTTOM:
405 return rectangle.y + rectangle.height - testPoint.y;
406 case DWT.LEFT:
407 return testPoint.x - rectangle.x;
408 case DWT.RIGHT:
409 return rectangle.x + rectangle.width - testPoint.x;
410 }
411
412 return 0;
413 }
414
415 /**
416 * Extrudes the given edge inward by the given distance. That is, if one side of the rectangle
417 * was sliced off with a given thickness, this returns the rectangle that forms the slice. Note
418 * that the returned rectangle will be inside the given rectangle if size > 0.
419 *
420 * @param toExtrude the rectangle to extrude. The resulting rectangle will share three sides
421 * with this rectangle.
422 * @param size distance to extrude. A negative size will extrude outwards (that is, the resulting
423 * rectangle will overlap the original iff this is positive).
424 * @param orientation the side to extrude. One of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM. The
425 * resulting rectangle will always share this side with the original rectangle.
426 * @return a rectangle formed by extruding the given side of the rectangle by the given distance.
427 * @since 3.0
428 */
429 public static Rectangle getExtrudedEdge(Rectangle toExtrude, int size,
430 int orientation) {
431 Rectangle bounds = new Rectangle(toExtrude.x, toExtrude.y,
432 toExtrude.width, toExtrude.height);
433
434 if (!isHorizontal(orientation)) {
435 bounds.width = size;
436 } else {
437 bounds.height = size;
438 }
439
440 switch (orientation) {
441 case DWT.RIGHT:
442 bounds.x = toExtrude.x + toExtrude.width - bounds.width;
443 break;
444 case DWT.BOTTOM:
445 bounds.y = toExtrude.y + toExtrude.height - bounds.height;
446 break;
447 }
448
449 normalize(bounds);
450
451 return bounds;
452 }
453
454 /**
455 * Returns the opposite of the given direction. That is, returns DWT.LEFT if
456 * given DWT.RIGHT and visa-versa.
457 *
458 * @param swtDirectionConstant one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM
459 * @return one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM
460 * @since 3.0
461 */
462 public static int getOppositeSide(int swtDirectionConstant) {
463 switch (swtDirectionConstant) {
464 case DWT.TOP:
465 return DWT.BOTTOM;
466 case DWT.BOTTOM:
467 return DWT.TOP;
468 case DWT.LEFT:
469 return DWT.RIGHT;
470 case DWT.RIGHT:
471 return DWT.LEFT;
472 }
473
474 return swtDirectionConstant;
475 }
476
477 /**
478 * Converts the given bool into an DWT orientation constant.
479 *
480 * @param horizontal if true, returns DWT.HORIZONTAL. If false, returns DWT.VERTICAL
481 * @return DWT.HORIZONTAL or DWT.VERTICAL.
482 * @since 3.0
483 */
484 public static int getSwtHorizontalOrVerticalConstant(bool horizontal) {
485 if (horizontal) {
486 return DWT.HORIZONTAL;
487 }
488 return DWT.VERTICAL;
489 }
490
491 /**
492 * Returns true iff the given DWT side constant corresponds to a horizontal side
493 * of a rectangle. That is, returns true for the top and bottom but false for the
494 * left and right.
495 *
496 * @param swtSideConstant one of DWT.TOP, DWT.BOTTOM, DWT.LEFT, or DWT.RIGHT
497 * @return true iff the given side is horizontal.
498 * @since 3.0
499 */
500 public static bool isHorizontal(int swtSideConstant) {
501 return !(swtSideConstant is DWT.LEFT || swtSideConstant is DWT.RIGHT);
502 }
503
504 /**
505 * Moves the given rectangle by the given delta.
506 *
507 * @param rect rectangle to move (will be modified)
508 * @param delta direction vector to move the rectangle by
509 * @since 3.0
510 */
511 public static void moveRectangle(Rectangle rect, Point delta) {
512 rect.x += delta.x;
513 rect.y += delta.y;
514 }
515
516 /**
517 * Moves each edge of the given rectangle outward by the given amount. Negative values
518 * cause the rectangle to contract. Does not allow the rectangle's width or height to be
519 * reduced below zero.
520 *
521 * @param rect normalized rectangle to modify
522 * @param differenceRect difference rectangle to be added to rect
523 * @since 3.3
524 */
525 public static void expand(Rectangle rect, Rectangle differenceRect) {
526 rect.x += differenceRect.x;
527 rect.y += differenceRect.y;
528 rect.height = Math.max(0, rect.height + differenceRect.height);
529 rect.width = Math.max(0, rect.width + differenceRect.width);
530 }
531
532 /**
533 * <p>Returns a rectangle which, when added to another rectangle, will expand each side
534 * by the given number of units.</p>
535 *
536 * <p>This is commonly used to store margin sizes. For example:</p>
537 *
538 * <code><pre>
539 * // Expands the left, right, top, and bottom
540 * // of the given control by 10, 5, 1, and 15 units respectively
541 *
542 * Rectangle margins = Geometry.createDifferenceRect(10,5,1,15);
543 * Rectangle bounds = someControl.getBounds();
544 * someControl.setBounds(Geometry.add(bounds, margins));
545 * </pre></code>
546 *
547 * @param left distance to expand the left side (negative values move the edge inward)
548 * @param right distance to expand the right side (negative values move the edge inward)
549 * @param top distance to expand the top (negative values move the edge inward)
550 * @param bottom distance to expand the bottom (negative values move the edge inward)
551 *
552 * @return a difference rectangle that, when added to another rectangle, will cause each
553 * side to expand by the given number of units
554 * @since 3.3
555 */
556 public static Rectangle createDiffRectangle(int left, int right, int top, int bottom) {
557 return new Rectangle(-left, -top, left + right, top + bottom);
558 }
559
560 /**
561 * Moves each edge of the given rectangle outward by the given amount. Negative values
562 * cause the rectangle to contract. Does not allow the rectangle's width or height to be
563 * reduced below zero.
564 *
565 * @param rect normalized rectangle to modify
566 * @param left distance to move the left edge outward (negative values move the edge inward)
567 * @param right distance to move the right edge outward (negative values move the edge inward)
568 * @param top distance to move the top edge outward (negative values move the edge inward)
569 * @param bottom distance to move the bottom edge outward (negative values move the edge inward)
570 * @since 3.1
571 */
572 public static void expand(Rectangle rect, int left, int right, int top, int bottom) {
573 rect.x -= left;
574 rect.width = Math.max(0, rect.width + left + right);
575 rect.y -= top;
576 rect.height = Math.max(0, rect.height + top + bottom);
577 }
578
579 /**
580 * Normalizes the given rectangle. That is, any rectangle with
581 * negative width or height becomes a rectangle with positive
582 * width or height that extends to the upper-left of the original
583 * rectangle.
584 *
585 * @param rect rectangle to modify
586 * @since 3.0
587 */
588 public static void normalize(Rectangle rect) {
589 if (rect.width < 0) {
590 rect.width = -rect.width;
591 rect.x -= rect.width;
592 }
593
594 if (rect.height < 0) {
595 rect.height = -rect.height;
596 rect.y -= rect.height;
597 }
598 }
599
600 /**
601 * Converts the given rectangle from display coordinates to the local coordinate system
602 * of the given object into display coordinates.
603 *
604 * @param coordinateSystem local coordinate system being converted to
605 * @param toConvert rectangle to convert
606 * @return a rectangle in control coordinates
607 * @since 3.0
608 */
609 public static Rectangle toControl(Control coordinateSystem,
610 Rectangle toConvert) {
611 return(coordinateSystem.getDisplay().map
612 (null,coordinateSystem,toConvert));
613 }
614
615 /**
616 * Converts the given rectangle from the local coordinate system of the given object
617 * into display coordinates.
618 *
619 * @param coordinateSystem local coordinate system being converted from
620 * @param toConvert rectangle to convert
621 * @return a rectangle in display coordinates
622 * @since 3.0
623 */
624 public static Rectangle toDisplay(Control coordinateSystem,
625 Rectangle toConvert) {
626 return(coordinateSystem.getDisplay().map
627 (coordinateSystem,null,toConvert));
628
629 }
630
631 /**
632 * Determines where the given point lies with respect to the given rectangle.
633 * Returns a combination of DWT.LEFT, DWT.RIGHT, DWT.TOP, and DWT.BOTTOM, combined
634 * with bitwise or (for example, returns DWT.TOP | DWT.LEFT if the point is to the
635 * upper-left of the rectangle). Returns 0 if the point lies within the rectangle.
636 * Positions are in screen coordinates (ie: a point is to the upper-left of the
637 * rectangle if its x and y coordinates are smaller than any point in the rectangle)
638 *
639 * @param boundary normalized boundary rectangle
640 * @param toTest point whose relative position to the rectangle is being computed
641 * @return one of DWT.LEFT | DWT.TOP, DWT.TOP, DWT.RIGHT | DWT.TOP, DWT.LEFT, 0,
642 * DWT.RIGHT, DWT.LEFT | DWT.BOTTOM, DWT.BOTTOM, DWT.RIGHT | DWT.BOTTOM
643 * @since 3.0
644 */
645 public static int getRelativePosition(Rectangle boundary, Point toTest) {
646 int result = 0;
647
648 if (toTest.x < boundary.x) {
649 result |= DWT.LEFT;
650 } else if (toTest.x >= boundary.x + boundary.width) {
651 result |= DWT.RIGHT;
652 }
653
654 if (toTest.y < boundary.y) {
655 result |= DWT.TOP;
656 } else if (toTest.y >= boundary.y + boundary.height) {
657 result |= DWT.BOTTOM;
658 }
659
660 return result;
661 }
662
663 /**
664 * Returns the distance from the point to the nearest edge of the given
665 * rectangle. Returns negative values if the point lies outside the rectangle.
666 *
667 * @param boundary rectangle to test
668 * @param toTest point to test
669 * @return the distance between the given point and the nearest edge of the rectangle.
670 * Returns positive values for points inside the rectangle and negative values for points
671 * outside the rectangle.
672 * @since 3.1
673 */
674 public static int getDistanceFrom(Rectangle boundary, Point toTest) {
675 int side = getClosestSide(boundary, toTest);
676 return getDistanceFromEdge(boundary, toTest, side);
677 }
678
679 /**
680 * Returns the edge of the given rectangle is closest to the given
681 * point.
682 *
683 * @param boundary rectangle to test
684 * @param toTest point to compare
685 * @return one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM
686 *
687 * @since 3.0
688 */
689 public static int getClosestSide(Rectangle boundary, Point toTest) {
690 int[] sides = [ DWT.LEFT, DWT.RIGHT, DWT.TOP, DWT.BOTTOM ];
691
692 int closestSide = DWT.LEFT;
693 int closestDistance = Integer.MAX_VALUE;
694
695 for (int idx = 0; idx < sides.length; idx++) {
696 int side = sides[idx];
697
698 int distance = getDistanceFromEdge(boundary, toTest, side);
699
700 if (distance < closestDistance) {
701 closestDistance = distance;
702 closestSide = side;
703 }
704 }
705
706 return closestSide;
707 }
708
709 /**
710 * Returns a copy of the given rectangle
711 *
712 * @param toCopy rectangle to copy
713 * @return a copy of the given rectangle
714 * @since 3.0
715 */
716 public static Rectangle copy(Rectangle toCopy) {
717 return new Rectangle(toCopy.x, toCopy.y, toCopy.width, toCopy.height);
718 }
719
720 /**
721 * Returns the size of the rectangle, as a Point
722 *
723 * @param rectangle rectangle whose size is being computed
724 * @return the size of the given rectangle
725 * @since 3.0
726 */
727 public static Point getSize(Rectangle rectangle) {
728 return new Point(rectangle.width, rectangle.height);
729 }
730
731 /**
732 * Sets the size of the given rectangle to the given size
733 *
734 * @param rectangle rectangle to modify
735 * @param newSize new size of the rectangle
736 * @since 3.0
737 */
738 public static void setSize(Rectangle rectangle, Point newSize) {
739 rectangle.width = newSize.x;
740 rectangle.height = newSize.y;
741 }
742
743 /**
744 * Sets the x,y position of the given rectangle. For a normalized
745 * rectangle (a rectangle with positive width and height), this will
746 * be the upper-left corner of the rectangle.
747 *
748 * @param rectangle rectangle to modify
749 * @param newSize new size of the rectangle
750 *
751 * @since 3.0
752 */
753 public static void setLocation(Rectangle rectangle, Point newSize) {
754 rectangle.width = newSize.x;
755 rectangle.height = newSize.y;
756 }
757
758 /**
759 * Returns the x,y position of the given rectangle. For normalized rectangles
760 * (rectangles with positive width and height), this is the upper-left
761 * corner of the rectangle.
762 *
763 * @param toQuery rectangle to query
764 * @return a Point containing the x,y position of the rectangle
765 *
766 * @since 3.0
767 */
768 public static Point getLocation(Rectangle toQuery) {
769 return new Point(toQuery.x, toQuery.y);
770 }
771
772 /**
773 * Returns a new rectangle with the given position and dimensions, expressed
774 * as points.
775 *
776 * @param position the (x,y) position of the rectangle
777 * @param size the size of the new rectangle, where (x,y) -> (width, height)
778 * @return a new Rectangle with the given position and size
779 *
780 * @since 3.0
781 */
782 public static Rectangle createRectangle(Point position, Point size) {
783 return new Rectangle(position.x, position.y, size.x, size.y);
784 }
785
786 /**
787 * Repositions the 'inner' rectangle to lie completely within the bounds of the 'outer'
788 * rectangle if possible. One use for this is to ensure that, when setting a control's bounds,
789 * that they will always lie within its parent's client area (to avoid clipping).
790 *
791 * @param inner The 'inner' rectangle to be repositioned (should be smaller than the 'outer' rectangle)
792 * @param outer The 'outer' rectangle
793 */
794 public static void moveInside(Rectangle inner, Rectangle outer) {
795 // adjust X
796 if (inner.x < outer.x) {
797 inner.x = outer.x;
798 }
799 if ((inner.x + inner.width) > (outer.x + outer.width)) {
800 inner.x -= (inner.x + inner.width) - (outer.x + outer.width);
801 }
802
803 // Adjust Y
804 if (inner.y < outer.y) {
805 inner.y = outer.y;
806 }
807 if ((inner.y + inner.height) > (outer.y + outer.height)) {
808 inner.y -= (inner.y + inner.height) - (outer.y + outer.height);
809 }
810 }
811
812 }