001: /*******************************************************************************
002: * Copyright (c) 2000, 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.swt.layout;
011:
012: import org.eclipse.swt.*;
013: import org.eclipse.swt.widgets.*;
014:
015: /**
016: * Instances of this class are used to define the edges of a control
017: * within a <code>FormLayout</code>.
018: * <p>
019: * <code>FormAttachments</code> are set into the top, bottom, left,
020: * and right fields of the <code>FormData</code> for a control.
021: * For example:
022: * <pre>
023: * FormData data = new FormData();
024: * data.top = new FormAttachment(0,5);
025: * data.bottom = new FormAttachment(100,-5);
026: * data.left = new FormAttachment(0,5);
027: * data.right = new FormAttachment(100,-5);
028: * button.setLayoutData(data);
029: * </pre>
030: * </p>
031: * <p>
032: * A <code>FormAttachment</code> defines where to attach the side of
033: * a control by using the equation, y = ax + b. The "a" term represents
034: * a fraction of the parent composite's width (from the left) or height
035: * (from the top). It can be defined using a numerator and denominator,
036: * or just a percentage value. If a percentage is used, the denominator
037: * is set to 100. The "b" term in the equation represents an offset, in
038: * pixels, from the attachment position. For example:
039: * <pre>
040: * FormAttachment attach = new FormAttachment (20, -5);
041: * </pre>
042: * specifies that the side to which the <code>FormAttachment</code>
043: * object belongs will lie at 20% of the parent composite, minus 5 pixels.
044: * </p>
045: * <p>
046: * Control sides can also be attached to another control.
047: * For example:
048: * <pre>
049: * FormAttachment attach = new FormAttachment (button, 10);
050: * </pre>
051: * specifies that the side to which the <code>FormAttachment</code>
052: * object belongs will lie in the same position as the adjacent side of
053: * the <code>button</code> control, plus 10 pixels. The control side can
054: * also be attached to the opposite side of the specified control.
055: * For example:
056: * <pre>
057: * FormData data = new FormData ();
058: * data.left = new FormAttachment (button, 0, SWT.LEFT);
059: * </pre>
060: * specifies that the left side of the control will lie in the same position
061: * as the left side of the <code>button</code> control. The control can also
062: * be attached in a position that will center the control on the specified
063: * control. For example:
064: * <pre>
065: * data.left = new FormAttachment (button, 0, SWT.CENTER);
066: * </pre>
067: * specifies that the left side of the control will be positioned so that it is
068: * centered between the left and right sides of the <code>button</code> control.
069: * If the alignment is not specified, the default is to attach to the adjacent side.
070: * </p>
071: *
072: * @see FormLayout
073: * @see FormData
074: *
075: * @since 2.0
076: */
077: public final class FormAttachment {
078: /**
079: * numerator specifies the numerator of the "a" term in the
080: * equation, y = ax + b, which defines the attachment.
081: */
082: public int numerator;
083:
084: /**
085: * denominator specifies the denominator of the "a" term in the
086: * equation, y = ax + b, which defines the attachment.
087: *
088: * The default value is 100.
089: */
090: public int denominator = 100;
091:
092: /**
093: * offset specifies the offset, in pixels, of the control side
094: * from the attachment position.
095: * If the offset is positive, then the control side is offset
096: * to the right of or below the attachment position. If it is
097: * negative, then the control side is offset to the left of or
098: * above the attachment position.
099: *
100: * This is equivalent to the "b" term in the equation y = ax + b.
101: * The default value is 0.
102: */
103: public int offset;
104:
105: /**
106: * control specifies the control to which the control side is
107: * attached.
108: */
109: public Control control;
110:
111: /**
112: * alignment specifies the alignment of the control side that is
113: * attached to a control.
114: * <p>
115: * For top and bottom attachments, TOP, BOTTOM and CENTER are used. For left
116: * and right attachments, LEFT, RIGHT and CENTER are used. If any other case
117: * occurs, the default will be used instead.
118: * </p>
119: *
120: * <br>Possible values are: <ul>
121: * <li>TOP: Attach the side to the top side of the specified control.</li>
122: * <li>BOTTOM : Attach the side to the bottom side of the specified control.</li>
123: * <li>LEFT: Attach the side to the left side of the specified control.</li>
124: * <li>RIGHT: Attach the side to the right side of the specified control.</li>
125: * <li>CENTER: Attach the side at a position which will center the control on the specified control.</li>
126: * <li>DEFAULT: Attach the side to the adjacent side of the specified control.</li>
127: * </ul>
128: */
129: public int alignment;
130:
131: /**
132: * Constructs a new instance of this class.
133: * Since no numerator, denominator or offset is specified,
134: * the attachment is treated as a percentage of the form.
135: * The numerator is zero, the denominator is 100 and the
136: * offset is zero.
137: *
138: * @since 3.2
139: */
140: public FormAttachment() {
141: }
142:
143: /**
144: * Constructs a new instance of this class given a numerator
145: * Since no denominator or offset is specified, the default
146: * is to treat the numerator as a percentage of the form, with a
147: * denominator of 100. The offset is zero.
148: *
149: * @param numerator the percentage of the position
150: *
151: * @since 3.0
152: */
153: public FormAttachment(int numerator) {
154: this (numerator, 100, 0);
155: }
156:
157: /**
158: * Constructs a new instance of this class given a numerator
159: * and an offset. Since no denominator is specified, the default
160: * is to treat the numerator as a percentage of the form, with a
161: * denominator of 100.
162: *
163: * @param numerator the percentage of the position
164: * @param offset the offset of the side from the position
165: */
166: public FormAttachment(int numerator, int offset) {
167: this (numerator, 100, offset);
168: }
169:
170: /**
171: * Constructs a new instance of this class given a numerator
172: * and denominator and an offset. The position of the side is
173: * given by the fraction of the form defined by the numerator
174: * and denominator.
175: *
176: * @param numerator the numerator of the position
177: * @param denominator the denominator of the position
178: * @param offset the offset of the side from the position
179: */
180: public FormAttachment(int numerator, int denominator, int offset) {
181: if (denominator == 0)
182: SWT.error(SWT.ERROR_CANNOT_BE_ZERO);
183: this .numerator = numerator;
184: this .denominator = denominator;
185: this .offset = offset;
186: }
187:
188: /**
189: * Constructs a new instance of this class given a control.
190: * Since no alignment is specified, the default alignment is
191: * to attach the side to the adjacent side of the specified
192: * control. Since no offset is specified, an offset of 0 is
193: * used.
194: *
195: * @param control the control the side is attached to
196: */
197: public FormAttachment(Control control) {
198: this (control, 0, SWT.DEFAULT);
199: }
200:
201: /**
202: * Constructs a new instance of this class given a control
203: * and an offset. Since no alignment is specified, the default
204: * alignment is to attach the side to the adjacent side of the
205: * specified control.
206: *
207: * @param control the control the side is attached to
208: * @param offset the offset of the side from the control
209: */
210: public FormAttachment(Control control, int offset) {
211: this (control, offset, SWT.DEFAULT);
212: }
213:
214: /**
215: * Constructs a new instance of this class given a control,
216: * an offset and an alignment.
217: *
218: * @param control the control the side is attached to
219: * @param offset the offset of the side from the control
220: * @param alignment the alignment of the side to the control it is attached to
221: */
222: public FormAttachment(Control control, int offset, int alignment) {
223: this .control = control;
224: this .offset = offset;
225: this .alignment = alignment;
226: }
227:
228: FormAttachment divide(int value) {
229: return new FormAttachment(numerator, denominator * value,
230: offset / value);
231: }
232:
233: int gcd(int m, int n) {
234: int temp;
235: m = Math.abs(m);
236: n = Math.abs(n);
237: if (m < n) {
238: temp = m;
239: m = n;
240: n = temp;
241: }
242: while (n != 0) {
243: temp = m;
244: m = n;
245: n = temp % n;
246: }
247: return m;
248: }
249:
250: FormAttachment minus(FormAttachment attachment) {
251: FormAttachment solution = new FormAttachment();
252: solution.numerator = numerator * attachment.denominator
253: - denominator * attachment.numerator;
254: solution.denominator = denominator * attachment.denominator;
255: int gcd = gcd(solution.denominator, solution.numerator);
256: solution.numerator = solution.numerator / gcd;
257: solution.denominator = solution.denominator / gcd;
258: solution.offset = offset - attachment.offset;
259: return solution;
260: }
261:
262: FormAttachment minus(int value) {
263: return new FormAttachment(numerator, denominator, offset
264: - value);
265: }
266:
267: FormAttachment plus(FormAttachment attachment) {
268: FormAttachment solution = new FormAttachment();
269: solution.numerator = numerator * attachment.denominator
270: + denominator * attachment.numerator;
271: solution.denominator = denominator * attachment.denominator;
272: int gcd = gcd(solution.denominator, solution.numerator);
273: solution.numerator = solution.numerator / gcd;
274: solution.denominator = solution.denominator / gcd;
275: solution.offset = offset + attachment.offset;
276: return solution;
277: }
278:
279: FormAttachment plus(int value) {
280: return new FormAttachment(numerator, denominator, offset
281: + value);
282: }
283:
284: int solveX(int value) {
285: if (denominator == 0)
286: SWT.error(SWT.ERROR_CANNOT_BE_ZERO);
287: return ((numerator * value) / denominator) + offset;
288: }
289:
290: int solveY(int value) {
291: if (numerator == 0)
292: SWT.error(SWT.ERROR_CANNOT_BE_ZERO);
293: return (value - offset) * denominator / numerator;
294: }
295:
296: /**
297: * Returns a string containing a concise, human-readable
298: * description of the receiver.
299: *
300: * @return a string representation of the FormAttachment
301: */
302: public String toString() {
303: String string = control != null ? control.toString()
304: : numerator + "/" + denominator;
305: return "{y = ("
306: + string
307: + (offset >= 0 ? ")x + " + offset : ")x - " + (-offset))
308: + "}";
309: }
310:
311: }
|