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