001: /*******************************************************************************
002: * Copyright (c) 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.ui.internal;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014: import java.util.List;
015:
016: import org.eclipse.swt.SWT;
017: import org.eclipse.swt.custom.CBanner;
018: import org.eclipse.swt.events.ControlEvent;
019: import org.eclipse.swt.events.ControlListener;
020: import org.eclipse.swt.graphics.Point;
021: import org.eclipse.swt.graphics.Rectangle;
022: import org.eclipse.swt.widgets.Composite;
023: import org.eclipse.swt.widgets.Control;
024: import org.eclipse.swt.widgets.CoolBar;
025: import org.eclipse.swt.widgets.CoolItem;
026: import org.eclipse.swt.widgets.Label;
027: import org.eclipse.swt.widgets.Layout;
028: import org.eclipse.ui.internal.layout.TrimCommonUIHandle;
029:
030: /**
031: * This layout implements the handling necessary to support the positioning of
032: * all of the 'trim' elements defined for the workbench.
033: * <p>
034: * NOTE: This class is a part of a 'work in progress' and should not be used
035: * without consulting the Platform UI group. No guarantees are made as to the
036: * stability of the API.
037: * </p>
038: *
039: * @since 3.2
040: *
041: */
042: public class WorkbenchLayout extends Layout {
043: private static int defaultMargin = 5;
044:
045: /**
046: * This is a convenience class that caches information for a single 'tiled'
047: * line of trim.
048: *
049: * @since 3.2
050: *
051: */
052: private class TrimLine {
053: /**
054: * Teh list of controls in this trim line
055: */
056: List controls = new ArrayList();
057:
058: /**
059: * A cache of the previously computed sizes of each trim control
060: */
061: List computedSizes = new ArrayList();
062:
063: /**
064: * In horizontal terms this is the 'height' of the tallest control.
065: */
066: int minorMax = 0;
067:
068: /**
069: * The number of controls in the line that want to 'grab' extra space.
070: * Any unused space in a trim line is shared equally among these
071: * controls
072: */
073: int resizableCount = 0;
074:
075: /**
076: * The amount of unused space in the line
077: */
078: int extraSpace = 0;
079: }
080:
081: /**
082: * This layout is used to capture the CBanner's calls to 'computeSize' for
083: * the left trim (which is used to determine the height of the CBanner) so
084: * that it will compute its own height to be the max of either the left or
085: * the right control.
086: * <p>
087: * NOTE: This class is expected to be removed once the CBanner mods are in.
088: * </p>
089: *
090: * @since 3.2
091: *
092: */
093: private class LeftBannerLayout extends Layout {
094:
095: /*
096: * (non-Javadoc)
097: *
098: * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite,
099: * int, int, boolean)
100: */
101: protected Point computeSize(Composite composite, int wHint,
102: int hHint, boolean flushCache) {
103: // 'topMax' is the maximum height of both the left and
104: // the right side
105: return new Point(wHint, WorkbenchLayout.this .topMax);
106: }
107:
108: /*
109: * (non-Javadoc)
110: *
111: * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
112: * boolean)
113: */
114: protected void layout(Composite composite, boolean flushCache) {
115: }
116:
117: }
118:
119: // Trim area 'ids'
120: public static final String TRIMID_CMD_PRIMARY = "Command Primary"; //$NON-NLS-1$
121:
122: public static final String TRIMID_CMD_SECONDARY = "Command Secondary"; //$NON-NLS-1$
123:
124: public static final String TRIMID_VERTICAL1 = "vertical1"; //$NON-NLS-1$
125:
126: public static final String TRIMID_VERTICAL2 = "vertical2"; //$NON-NLS-1$
127:
128: public static final String TRIMID_STATUS = "Status"; //$NON-NLS-1$
129:
130: public static final String TRIMID_CENTER = "Center"; //$NON-NLS-1$
131:
132: // 'CBanner' info
133: public CBanner banner;
134:
135: private int topMax;
136:
137: // 'Center' composite
138: public Composite centerComposite;
139:
140: // inter-element spacing
141: private int spacing = 0;
142:
143: // Trim Areas
144: private TrimArea cmdPrimaryTrimArea;
145:
146: private TrimArea cmdSecondaryTrimArea;
147:
148: private TrimArea leftTrimArea;
149:
150: private TrimArea rightTrimArea;
151:
152: private TrimArea bottomTrimArea;
153:
154: // Drag handle info
155: private int horizontalHandleSize = -1;
156:
157: private int verticalHandleSize = -1;
158:
159: private List dragHandles;
160:
161: // statics used in the layout
162: private static Composite layoutComposite;
163:
164: private static Rectangle clientRect;
165:
166: /**
167: * Construct a new layout. This defines the trim areas that trim can be
168: * placed into.
169: */
170: public WorkbenchLayout() {
171: super ();
172:
173: // Add the trim areas into the layout
174: cmdPrimaryTrimArea = new TrimArea(TRIMID_CMD_PRIMARY, SWT.TOP,
175: defaultMargin);
176: cmdSecondaryTrimArea = new TrimArea(TRIMID_CMD_SECONDARY,
177: SWT.TOP, defaultMargin);
178: leftTrimArea = new TrimArea(TRIMID_VERTICAL1, SWT.LEFT,
179: defaultMargin);
180: rightTrimArea = new TrimArea(TRIMID_VERTICAL2, SWT.RIGHT,
181: defaultMargin);
182: bottomTrimArea = new TrimArea(TRIMID_STATUS, SWT.BOTTOM,
183: defaultMargin);
184:
185: // init the list that has the drag handle cache
186: dragHandles = new ArrayList();
187: }
188:
189: /**
190: * Create the CBanner control used to control the horizontal span of the
191: * primary and secondary command areas.
192: *
193: * @param workbenchComposite
194: * The workbench acting as the parent of the CBanner
195: */
196: public void createCBanner(Composite workbenchComposite) {
197: banner = new CBanner(workbenchComposite, SWT.NONE);
198: banner.setSimple(false);
199: banner.setRightWidth(175);
200: banner.setLocation(0, 0);
201:
202: // Create the left composite and override its 'computeSize'
203: // to delegate to the 'primary' command trim area
204: Composite bannerLeft = new Composite(banner, SWT.NONE) {
205: /*
206: * (non-Javadoc)
207: *
208: * @see org.eclipse.swt.widgets.Composite#computeSize(int, int,
209: * boolean)
210: */
211: public Point computeSize(int wHint, int hHint,
212: boolean changed) {
213: // If we're doing a 'real' workbench layout then delegate to the
214: // appropriate trim area
215: if (WorkbenchLayout.layoutComposite != null) {
216: return WorkbenchLayout.this .computeSize(
217: TRIMID_CMD_PRIMARY, wHint);
218: }
219:
220: return super .computeSize(wHint, hHint, changed);
221: }
222: };
223: bannerLeft.setLayout(new LeftBannerLayout());
224: bannerLeft.setBackground(workbenchComposite.getDisplay()
225: .getSystemColor(SWT.COLOR_DARK_BLUE));
226: banner.setLeft(bannerLeft);
227:
228: // Create the right hand part of the CBanner
229: Composite bannerRight = new Composite(banner, SWT.NONE) {
230: /*
231: * (non-Javadoc)
232: *
233: * @see org.eclipse.swt.widgets.Composite#computeSize(int, int,
234: * boolean)
235: */
236: public Point computeSize(int wHint, int hHint,
237: boolean changed) {
238: // If we're doing a 'real' workbench layout then delegate to the
239: // appropriate trim area
240: if (WorkbenchLayout.layoutComposite != null) {
241: return WorkbenchLayout.this .computeSize(
242: TRIMID_CMD_SECONDARY, wHint);
243: }
244:
245: return super .computeSize(wHint, hHint, changed);
246: }
247: };
248: bannerRight.setBackground(workbenchComposite.getDisplay()
249: .getSystemColor(SWT.COLOR_DARK_BLUE));
250: banner.setRight(bannerRight);
251:
252: // If the right banner control changes size it's because
253: // the 'swoop' moved.
254: bannerRight.addControlListener(new ControlListener() {
255: public void controlMoved(ControlEvent e) {
256: }
257:
258: public void controlResized(ControlEvent e) {
259: Composite leftComp = (Composite) e.widget;
260: leftComp.getShell().layout(true);
261: }
262: });
263:
264: // Place the CBanner on the 'bottom' of the z-order
265: banner.moveBelow(null);
266: }
267:
268: /*
269: * (non-Javadoc)
270: *
271: * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite,
272: * int, int, boolean)
273: *
274: * Note that this is arbitrary since the we're a top level shell (so
275: * computeSize won't be called.
276: */
277: protected Point computeSize(Composite composite, int wHint,
278: int hHint, boolean flushCache) {
279: Point size = new Point(wHint, hHint);
280: if (size.x == SWT.DEFAULT) {
281: size.x = 300;
282: }
283: if (size.y == SWT.DEFAULT) {
284: size.y = 300;
285: }
286: return size;
287: }
288:
289: /*
290: * (non-Javadoc)
291: *
292: * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
293: * boolean)
294: *
295: * TODO: Supply a full description of the layout mechanicsS
296: */
297: protected void layout(Composite composite, boolean flushCache) {
298: layoutComposite = composite;
299: clientRect = composite.getClientArea();
300:
301: // reset all the drag handles to be invisible
302: resetDragHandles();
303:
304: // Compute the proper size for each trim area
305: // Do Top Right, Top Left, Left, Right then Bottom so the math works out
306: if (useCBanner()) {
307: banner.moveBelow(null);
308:
309: // NOTE: calling 'computeSize' here will, in turn, call the
310: // 'computeSize' for the left/right areas, each with the
311: // 'correct' width hint...
312: Point bannerSize = banner.computeSize(clientRect.width,
313: SWT.DEFAULT);
314:
315: // set the amount of space used by the 'cmd' areas for use later
316: topMax = bannerSize.y;
317:
318: banner.setSize(bannerSize);
319: } else {
320: Point c1Size = computeSize(TRIMID_CMD_PRIMARY,
321: clientRect.width);
322: Point c2Size = computeSize(TRIMID_CMD_SECONDARY,
323: clientRect.width);
324:
325: // set the amount of space used by the 'cmd' areas for use later
326: topMax = c1Size.y + c2Size.y;
327: }
328:
329: // Now do the vertical areas; their 'major' is whatever is left
330: // vertically once the top areas have been computed
331: Point v1Size = computeSize(TRIMID_VERTICAL1, clientRect.height
332: - topMax);
333: Point v2Size = computeSize(TRIMID_VERTICAL2, clientRect.height
334: - topMax);
335:
336: // Finally, the status area's 'major' is whatever is left over
337: // horizontally once the vertical areas have been computed.
338: computeSize(TRIMID_STATUS, clientRect.width
339: - (v1Size.x + v2Size.x));
340:
341: // Now, layout the trim within each area
342: // Command primary area
343: if (useCBanner()) {
344: Point leftLoc = banner.getLeft().getLocation();
345: cmdPrimaryTrimArea.areaBounds.x = leftLoc.x;
346: cmdPrimaryTrimArea.areaBounds.y = leftLoc.y;
347: } else {
348: cmdPrimaryTrimArea.areaBounds.x = 0;
349: cmdPrimaryTrimArea.areaBounds.y = 0;
350: }
351: layoutTrim(cmdPrimaryTrimArea, cmdPrimaryTrimArea.areaBounds);
352:
353: // Command secondary area
354: if (useCBanner()) {
355: Point rightLoc = banner.getRight().getLocation();
356: cmdSecondaryTrimArea.areaBounds.x = rightLoc.x;
357: cmdSecondaryTrimArea.areaBounds.y = rightLoc.y;
358: } else {
359: cmdSecondaryTrimArea.areaBounds.x = 0;
360: cmdSecondaryTrimArea.areaBounds.y = cmdPrimaryTrimArea.areaBounds.height;
361: }
362: layoutTrim(cmdSecondaryTrimArea,
363: cmdSecondaryTrimArea.areaBounds);
364:
365: leftTrimArea.areaBounds.x = 0;
366: leftTrimArea.areaBounds.y = topMax;
367: layoutTrim(leftTrimArea, leftTrimArea.areaBounds);
368:
369: rightTrimArea.areaBounds.x = clientRect.width
370: - rightTrimArea.areaBounds.width;
371: rightTrimArea.areaBounds.y = topMax;
372: layoutTrim(rightTrimArea, rightTrimArea.areaBounds);
373:
374: bottomTrimArea.areaBounds.x = leftTrimArea.areaBounds.width;
375: bottomTrimArea.areaBounds.y = clientRect.height
376: - bottomTrimArea.areaBounds.height;
377: layoutTrim(bottomTrimArea, bottomTrimArea.areaBounds);
378:
379: // Set the center control's bounds to fill the space remaining
380: // after the trim has been arranged
381: layoutCenter();
382: }
383:
384: /**
385: * Indicates whether or not the layout should use the CBanner or tile the
386: * primary and secondary trim areas one above the other.
387: *
388: * @return <code>true</code> iff the layout should use the CBanner.
389: */
390: private boolean useCBanner() {
391: return (banner != null && banner.getVisible());
392: }
393:
394: /**
395: * @param areaId
396: * The identifier for the TrimArea to return
397: * @return The TrimArea that matches the given areaId
398: */
399: private TrimArea getTrimArea(String areaId) {
400: if (TRIMID_CMD_PRIMARY.equals(areaId)) {
401: return cmdPrimaryTrimArea;
402: }
403: if (TRIMID_CMD_SECONDARY.equals(areaId)) {
404: return cmdSecondaryTrimArea;
405: }
406: if (TRIMID_VERTICAL1.equals(areaId)) {
407: return leftTrimArea;
408: }
409: if (TRIMID_VERTICAL2.equals(areaId)) {
410: return rightTrimArea;
411: }
412: if (TRIMID_STATUS.equals(areaId)) {
413: return bottomTrimArea;
414: }
415:
416: return null;
417: }
418:
419: /**
420: * @param areaId
421: * The TrimArea that we want to get the controls for
422: * @return The list of controls whose TrimLayoutData's areaId matches the
423: * given areaId parameter
424: */
425: private List getTrimContents(String areaId) {
426: List trimContents = new ArrayList();
427: Control[] children = layoutComposite.getChildren();
428: for (int i = 0; i < children.length; i++) {
429: // Skip any disposed or invisible widgets
430: if (children[i].isDisposed() || !children[i].getVisible()) {
431: continue;
432: }
433:
434: // Only accept children that want to be layed out in a particular
435: // trim area
436: if (children[i].getLayoutData() instanceof TrimLayoutData) {
437: TrimLayoutData tlData = (TrimLayoutData) children[i]
438: .getLayoutData();
439: if (tlData.areaId.equals(areaId)) {
440: trimContents.add(children[i]);
441: }
442: }
443: }
444:
445: return trimContents;
446: }
447:
448: /**
449: * Lays out the center composite once the outer trim areas have all been
450: * done.
451: */
452: private void layoutCenter() {
453: if (centerComposite != null) {
454: // The center is the 'inner' bounding box of the other trim areas
455: Rectangle areaBounds = new Rectangle(
456: leftTrimArea.areaBounds.x
457: + leftTrimArea.areaBounds.width,
458: topMax,
459: clientRect.width
460: - (leftTrimArea.areaBounds.width + rightTrimArea.areaBounds.width),
461: clientRect.height
462: - (topMax + bottomTrimArea.areaBounds.height));
463:
464: centerComposite.setBounds(areaBounds);
465: }
466: }
467:
468: /**
469: * Computes the size of a trim area given the length of its major dimension.
470: * Depending on whether the trim area is horizontal or vertical one of the
471: * two value will always match the supplied 'majorHint' ('x' if it's
472: * horizontal).
473: * <p>
474: * Effectively, this computes the length of the minor dimension by tiling
475: * the trim area's controls into multiple lines based on the length of the
476: * major dimension.
477: * </p>
478: *
479: * @param areaId
480: * The area id to compute the size for
481: * @param majorHint
482: * The length of the major dimension
483: *
484: * @return The computed size
485: */
486: private Point computeSize(String areaId, int majorHint) {
487: TrimArea trimArea = getTrimArea(areaId);
488: boolean horizontal = trimArea.orientation == SWT.TOP
489: || trimArea.orientation == SWT.BOTTOM;
490:
491: // Gather up all the controls for this area and tile them out
492: trimArea.trimContents = getTrimContents(trimArea.areaId);
493:
494: // Split the controls list into a list of TrimLines that each fit into
495: // the trim area
496: trimArea.trimLines = computeWrappedTrim(trimArea, majorHint);
497:
498: // Now, calculate the max between the default and the contents
499: int minorMax = 0;
500: for (Iterator iter = trimArea.trimLines.iterator(); iter
501: .hasNext();) {
502: TrimLine curLine = (TrimLine) iter.next();
503: minorMax += curLine.minorMax;
504: }
505: minorMax = Math.max(minorMax, trimArea.defaultMinor);
506:
507: // Store the size in the area'a cache...
508: Point computedSize = new Point(0, 0);
509: if (horizontal) {
510: computedSize.x = trimArea.areaBounds.width = majorHint;
511: computedSize.y = trimArea.areaBounds.height = minorMax;
512: } else {
513: computedSize.x = trimArea.areaBounds.width = minorMax;
514: computedSize.y = trimArea.areaBounds.height = majorHint;
515: }
516:
517: // ...and return it
518: return computedSize;
519: }
520:
521: /**
522: * This is where the information required to lay the controls belonging to a
523: * particular trim area out.
524: * <p>
525: * Tile the controls in the trim area into one or more lines. Each line is
526: * guaranteed to take up less than or equal to the 'majorHint' in the major
527: * dimension. The result is a complete cache of the information needed to
528: * lay the controls in the trim area out.
529: * </p>
530: *
531: * @param trimArea The trim area to create the cache info for
532: * @param majorHint The length of the major dimension
533: *
534: * @return A List of <code>TrimLine</code> elements
535: */
536: private List computeWrappedTrim(TrimArea trimArea, int majorHint) {
537: boolean horizontal = trimArea.orientation == SWT.TOP
538: || trimArea.orientation == SWT.BOTTOM;
539: // Return a list of 'lines' to tile the control into...
540: List lines = new ArrayList();
541: TrimLine curLine = new TrimLine();
542: lines.add(curLine);
543: curLine.minorMax = trimArea.defaultMinor;
544:
545: // Init the tilePos to force a 'new' line
546: int tilePos = 0;
547: for (Iterator iter = trimArea.trimContents.iterator(); iter
548: .hasNext();) {
549: Control control = (Control) iter.next();
550: TrimLayoutData td = (TrimLayoutData) control
551: .getLayoutData();
552:
553: Point prefSize;
554: if (horizontal) {
555: //prefSize = control.computeSize(majorHint, SWT.DEFAULT);
556: prefSize = control
557: .computeSize(SWT.DEFAULT, SWT.DEFAULT);
558: } else {
559: prefSize = control.computeSize(SWT.DEFAULT, majorHint);
560: }
561:
562: // Will this control fit onto the current line?
563: int curTileSize = horizontal ? prefSize.x : prefSize.y;
564:
565: // every control except the first one needs to include the 'spacing'
566: // in the calc
567: if (curLine.controls.size() > 0) {
568: curTileSize += spacing;
569: }
570:
571: // If the control can be re-positioned then we have to add a drag
572: // handle to it
573: // we have to include the space that it'll occupy in the calcs
574: if (td.listener != null) {
575: curTileSize += horizontal ? horizontalHandleSize
576: : verticalHandleSize;
577: }
578:
579: // Place the control into the 'current' line if it'll fit (or if
580: // it's the
581: // -first- control (this handles the case where a control is too
582: // large to
583: // fit into the current TrimArea's 'major' size.
584: if ((tilePos + curTileSize) <= majorHint
585: || curLine.controls.size() == 0) {
586: curLine.controls.add(control);
587:
588: // Cache the maximum amount of 'minor' space needed
589: int minorSize = horizontal ? prefSize.y : prefSize.x;
590: if (minorSize > curLine.minorMax) {
591: curLine.minorMax = minorSize;
592: }
593:
594: tilePos += curTileSize;
595: } else {
596: // Remember how much space was left on the current line
597: curLine.extraSpace = majorHint - tilePos;
598:
599: // We need a new line...
600: curLine = new TrimLine();
601: lines.add(curLine);
602:
603: curLine.controls.add(control);
604:
605: // Cache the maximum amount of 'minor' space needed
606: int minorSize = horizontal ? prefSize.y : prefSize.x;
607: if (minorSize > curLine.minorMax) {
608: curLine.minorMax = minorSize;
609: }
610:
611: tilePos = curTileSize;
612: }
613:
614: // Count how many 'resizable' controls there are
615: if ((td.flags & TrimLayoutData.GROWABLE) != 0) {
616: curLine.resizableCount++;
617: }
618: }
619:
620: // Remember how much space was left on the current line
621: curLine.extraSpace = majorHint - tilePos;
622:
623: return lines;
624: }
625:
626: private void layoutTrim(TrimArea trimArea, Rectangle areaBounds) {
627: boolean horizontal = trimArea.orientation == SWT.TOP
628: || trimArea.orientation == SWT.BOTTOM;
629:
630: // How much space do we have to 'tile' into?
631: int areaMajor = horizontal ? areaBounds.width
632: : areaBounds.height;
633:
634: // Get the tiled 'List of Lists' for the trim
635: List tileAreas = trimArea.trimLines;
636:
637: // Tile each 'line' into the trim
638: int tilePosMinor = horizontal ? areaBounds.y : areaBounds.x;
639: for (Iterator areaIter = tileAreas.iterator(); areaIter
640: .hasNext();) {
641: TrimLine curLine = (TrimLine) areaIter.next();
642:
643: // Compute how much space to give to 'resizable' controls. Note that
644: // we can end up computing -negative- 'extraSpace' values if the
645: // control's
646: // preferred 'major' size is actually > the 'major' size for the
647: // trim area
648: int resizePadding = 0;
649: if (curLine.resizableCount > 0 && curLine.extraSpace > 0) {
650: resizePadding = curLine.extraSpace
651: / curLine.resizableCount;
652: }
653:
654: // Tile each line
655: int tilePosMajor = horizontal ? areaBounds.x : areaBounds.y;
656: for (Iterator iter = curLine.controls.iterator(); iter
657: .hasNext();) {
658: Control control = (Control) iter.next();
659: TrimLayoutData td = (TrimLayoutData) control
660: .getLayoutData();
661: Point prefSize = control.computeSize(SWT.DEFAULT,
662: SWT.DEFAULT);
663:
664: int major = horizontal ? prefSize.x : prefSize.y;
665: int minor = horizontal ? prefSize.y : prefSize.x;
666:
667: // Ensure that controls that are too wide for the area get
668: // 'clipped'
669: if (major > areaMajor) {
670: major = areaMajor;
671: }
672:
673: // If desired, extend the 'minor' size of the control to fill
674: // the area
675: if ((td.flags & TrimLayoutData.GRAB_EXCESS_MINOR) != 0) {
676: minor = curLine.minorMax;
677: }
678:
679: // If desired, extend the 'major' size of the control to fill
680: // the area
681: if ((td.flags & TrimLayoutData.GROWABLE) != 0) {
682: major += resizePadding;
683: }
684:
685: // If we have to show a drag handle then do it here
686: if (td.listener != null && createHandles()) {
687: TrimCommonUIHandle handle = getDragHandle(trimArea.orientation);
688: // handle.setControl(control);
689:
690: if (horizontal) {
691: handle.setBounds(tilePosMajor, tilePosMinor,
692: getHandleSize(true), curLine.minorMax);
693: } else {
694: handle.setBounds(tilePosMinor, tilePosMajor,
695: curLine.minorMax, getHandleSize(false));
696: }
697:
698: tilePosMajor += horizontal ? getHandleSize(true)
699: : getHandleSize(false);
700: }
701:
702: // Now, lay out the actual control
703: switch (trimArea.orientation) {
704: case SWT.TOP:
705: control.setBounds(tilePosMajor, tilePosMinor,
706: major, minor);
707: break;
708: case SWT.LEFT:
709: control.setBounds(tilePosMinor, tilePosMajor,
710: minor, major);
711: break;
712: case SWT.RIGHT:
713: // Here we want to tile the control to the RIGHT edge
714: int rightEdge = tilePosMinor + curLine.minorMax;
715: control.setBounds(rightEdge - minor, tilePosMajor,
716: minor, major);
717: break;
718: case SWT.BOTTOM:
719: // Here we want to tile the control to the RIGHT edge
720: int bottomEdge = tilePosMinor + curLine.minorMax;
721: control.setBounds(tilePosMajor, bottomEdge - minor,
722: major, minor);
723: break;
724: }
725:
726: // Ensure that the control is above the trim control
727: tilePosMajor += major + spacing;
728: }
729: tilePosMinor += curLine.minorMax;
730: tilePosMajor = horizontal ? areaBounds.x : areaBounds.y;
731: }
732: }
733:
734: /**
735: * HACK>>>Remove if found in the wild...
736: * @return
737: */
738: private boolean createHandles() {
739: return false;
740: }
741:
742: private void resetDragHandles() {
743: for (Iterator iter = dragHandles.iterator(); iter.hasNext();) {
744: // TrimCommonUIHandle handle = (TrimCommonUIHandle) iter.next();
745: // handle.setControl(null);
746: }
747: }
748:
749: private TrimCommonUIHandle getDragHandle(int orientation) {
750: // boolean horizontal = orientation == SWT.TOP
751: // || orientation == SWT.BOTTOM;
752:
753: for (Iterator iter = dragHandles.iterator(); iter.hasNext();) {
754: TrimCommonUIHandle handle = (TrimCommonUIHandle) iter
755: .next();
756: // if (handle.toDrag == null && handle.horizontal == horizontal)
757: return handle;
758: }
759:
760: // If we get here then we haven't found a new drag handle so create one
761: System.out.println("new Handle"); //$NON-NLS-1$
762: // TrimCommonUIHandle newHandle = new
763: // TrimCommonUIHandle(layoutComposite,
764: // horizontal);
765: // dragHandles.add(newHandle);
766: // return newHandle;
767: return null;
768: }
769:
770: /**
771: * Return the SWT side that the trim area is on
772: *
773: * @param areaId The id of the area to get the orientation of
774: *
775: * @return The SWT side corresponding that the given area
776: */
777: public static int getOrientation(String areaId) {
778: if (TRIMID_CMD_PRIMARY.equals(areaId)) {
779: return SWT.TOP;
780: }
781: if (TRIMID_CMD_SECONDARY.equals(areaId)) {
782: return SWT.TOP;
783: }
784: if (TRIMID_VERTICAL1.equals(areaId)) {
785: return SWT.LEFT;
786: }
787: if (TRIMID_VERTICAL2.equals(areaId)) {
788: return SWT.RIGHT;
789: }
790: if (TRIMID_STATUS.equals(areaId)) {
791: return SWT.BOTTOM;
792: }
793:
794: return SWT.NONE;
795: }
796:
797: /**
798: * Calculate a size for the handle that will be large enough to show the
799: * CoolBar's drag affordance.
800: *
801: * @return The size that the handle has to be, based on the orientation
802: */
803: private int getHandleSize(boolean horizontal) {
804: // Do we already have a 'cached' value?
805: if (horizontal && horizontalHandleSize != -1) {
806: return horizontalHandleSize;
807: }
808:
809: if (!horizontal && verticalHandleSize != -1) {
810: return verticalHandleSize;
811: }
812:
813: // Must be the first time, calculate the value
814: CoolBar bar = new CoolBar(layoutComposite,
815: horizontal ? SWT.HORIZONTAL : SWT.VERTICAL);
816:
817: CoolItem item = new CoolItem(bar, SWT.NONE);
818:
819: Label ctrl = new Label(bar, SWT.PUSH);
820: ctrl.setText("Button 1"); //$NON-NLS-1$
821: Point size = ctrl.computeSize(SWT.DEFAULT, SWT.DEFAULT);
822:
823: Point ps = item.computeSize(size.x, size.y);
824: item.setPreferredSize(ps);
825: item.setControl(ctrl);
826:
827: bar.pack();
828:
829: // OK, now the difference between the location of the CB and the
830: // location of the
831: Point bl = ctrl.getLocation();
832: Point cl = bar.getLocation();
833:
834: // Toss them now...
835: ctrl.dispose();
836: item.dispose();
837: bar.dispose();
838:
839: // The 'size' is the difference between the start of teh CoolBar and
840: // start of its first control
841: int length;
842: if (horizontal) {
843: length = bl.x - cl.x;
844: horizontalHandleSize = length;
845: } else {
846: length = bl.y - cl.y;
847: verticalHandleSize = length;
848: }
849:
850: return length;
851: }
852:
853: }
|