Source Code Cross Referenced for CellLayout.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » internal » layout » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui workbench » org.eclipse.ui.internal.layout 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.ui.internal.layout;
011:
012:        import java.util.ArrayList;
013:        import java.util.List;
014:
015:        import org.eclipse.swt.SWT;
016:        import org.eclipse.swt.graphics.Point;
017:        import org.eclipse.swt.graphics.Rectangle;
018:        import org.eclipse.swt.widgets.Composite;
019:        import org.eclipse.swt.widgets.Control;
020:        import org.eclipse.swt.widgets.Layout;
021:
022:        /**
023:         * <p>Instance of this class lay out the control children of a <code>Composite</code>
024:         * in a grid, using a simple set of rules and a simple API. This class is 
025:         * intended to be more predictable than <code>GridLayout</code> and easier to use than
026:         * <code>FormLayout</code>, while retaining most of the power of both.</p>
027:         * 
028:         * <p>The power of a <code>CellLayout</code> lies in the ability to control
029:         * the size and resizing properties of each row and column. Unlike other layout
030:         * classes, complex layouts can be created without attaching any layout data to
031:         * individual controls in the layout. </p>
032:         * 
033:         * <p>The various subclasses of <code>IColumnInfo</code> 
034:         * can be used to create columns with fixed width, columns whose width is computed
035:         * from child controls, or width that grows in proportion to the size of other
036:         * columns. Layouts can be given a default <code>IColumnInfo</code> that will
037:         * be used to set the size of any column whose properties have not been explicitly
038:         * set. This is useful for creating layouts where most or all columns have the
039:         * same properties. Similarly, the subclasses of <code>IRowInfo</code> can be used to
040:         * control the height of individual rows.</p>
041:         * 
042:         * <p>For a finer grain of control, <code>CellData</code> objects can be attached
043:         * to individual controls in the layout. These objects serve a similar function as
044:         * <code>GridData</code> objects serve for <code>GridLayout</code>. They allow
045:         * controls to span multiple rows or columns, set the justification of the control
046:         * within its cell, and allow the user to override the preferred size of the control.
047:         * </p> 
048:         * 
049:         * <p>In many cases, it is not necessary to attach any layout data to controls in
050:         * the layout, since the controls can be arranged based on the properties of rows
051:         * and columns. However, layout data may be attached to individual controls to
052:         * allow them to span multiple columns or to control their justification within
053:         * their cell. 
054:         * </p>
055:         * 
056:         * <p>All the <code>set</code> methods in this class return <code>this</code>, allowing
057:         * a layout to be created and initialized in a single line of code. For example: </p>
058:         * 
059:         * <code>
060:         * Composite myControl = new Composite(parent, SWT.NONE);
061:         * myControl.setLayout(new CellLayout(2).setMargins(10,10).setSpacing(5,5));
062:         * </code>
063:         * 
064:         * @since 3.0
065:         */
066:        public class CellLayout extends Layout {
067:
068:            /**
069:             * Object used to compute the height of rows whose properties have not been
070:             * explicitly set.
071:             */
072:            private Row defaultRowSettings = new Row(false);
073:
074:            /**
075:             * Object used to compute the width of columns whose properties have not been
076:             * explicitly set.
077:             */
078:            private Row defaultColSettings = new Row(true);
079:
080:            /**
081:             * horizontalSpacing specifies the number of pixels between the right
082:             * edge of one cell and the left edge of its neighbouring cell to
083:             * the right.
084:             *
085:             * The default value is 5.
086:             */
087:            int horizontalSpacing = 5;
088:
089:            /**
090:             * verticalSpacing specifies the number of pixels between the bottom
091:             * edge of one cell and the top edge of its neighbouring cell underneath.
092:             *
093:             * The default value is 5.
094:             */
095:            int verticalSpacing = 5;
096:
097:            /**
098:             * marginWidth specifies the number of pixels of horizontal margin
099:             * that will be placed along the left and right edges of the layout.
100:             *
101:             * The default value is 0.
102:             */
103:            public int marginWidth = 5;
104:
105:            /**
106:             * marginHeight specifies the number of pixels of vertical margin
107:             * that will be placed along the top and bottom edges of the layout.
108:             *
109:             * The default value is 0.
110:             */
111:            public int marginHeight = 5;
112:
113:            /**
114:             * Number of columns in this layout, or 0 indicating that the whole layout
115:             * should be on a single row.
116:             */
117:            private int numCols;
118:
119:            /**
120:             * List of IColumnInfo. The nth object is used to compute the width of the
121:             * nth column, or null indicating that the default column should be used.
122:             */
123:            private List cols;
124:
125:            /**
126:             * List of RowInfo. The nth object is used to compute the height of the
127:             * nth row, or null indicating that the default row should be used.
128:             */
129:            private List rows = new ArrayList(16);
130:
131:            // Cached information 
132:            private GridInfo gridInfo = new GridInfo();
133:
134:            private int[] cachedRowMin = null;
135:
136:            private int[] cachedColMin = null;
137:
138:            public static int cacheMisses;
139:
140:            public static int cacheHits;
141:
142:            private LayoutCache cache = new LayoutCache();
143:
144:            // End of cached control sizes
145:
146:            /**
147:             * Creates the layout
148:             * 
149:             * @param numCols the number of columns in this layout, 
150:             * or 0 indicating that the whole layout should be on one row.
151:             */
152:            public CellLayout(int numCols) {
153:                super ();
154:                this .numCols = numCols;
155:                cols = new ArrayList(numCols == 0 ? 3 : numCols);
156:            }
157:
158:            /**
159:             * Sets the amount empty space between cells
160:             * 
161:             * @param newSpacing a point (x,y) corresponding to the number of pixels of
162:             * empty space between adjacent columns and rows respectively
163:             */
164:            public CellLayout setSpacing(int horizontalSpacing,
165:                    int verticalSpacing) {
166:                this .horizontalSpacing = horizontalSpacing;
167:                this .verticalSpacing = verticalSpacing;
168:
169:                return this ;
170:            }
171:
172:            /**
173:             * Sets the amount empty space between cells
174:             * 
175:             * @param newSpacing a point (x,y) corresponding to the number of pixels of
176:             * empty space between adjacent columns and rows respectively
177:             */
178:            public CellLayout setSpacing(Point newSpacing) {
179:                horizontalSpacing = newSpacing.x;
180:                verticalSpacing = newSpacing.y;
181:                return this ;
182:            }
183:
184:            /**
185:             * Returns the amount of empty space between adjacent cells
186:             * 
187:             * @return a point (x,y) corresponding to the number of pixels of empty
188:             * space between adjacent columns and rows respectively
189:             */
190:            public Point getSpacing() {
191:                return new Point(horizontalSpacing, verticalSpacing);
192:            }
193:
194:            /**
195:             * Sets the size of the margin around the outside of the layout. 
196:             * 
197:             * @param marginWidth the size of the margin around the top and 
198:             * bottom of the layout
199:             * @param marginHeight the size of the margin on the left and right
200:             * of the layout.
201:             */
202:            public CellLayout setMargins(int marginWidth, int marginHeight) {
203:                this .marginWidth = marginWidth;
204:                this .marginHeight = marginHeight;
205:                return this ;
206:            }
207:
208:            /**
209:             * Sets the size of the margin around the outside of the layout.
210:             * 
211:             * @param newMargins point indicating the size of the horizontal and vertical
212:             * margins, in pixels.
213:             */
214:            public CellLayout setMargins(Point newMargins) {
215:                marginWidth = newMargins.x;
216:                marginHeight = newMargins.y;
217:                return this ;
218:            }
219:
220:            /**
221:             * Returns the size of the margins around the outside of the layout.
222:             * 
223:             * @return the size of the outer margins, in pixels.
224:             */
225:            public Point getMargins() {
226:                return new Point(marginWidth, marginHeight);
227:            }
228:
229:            /**
230:             * Sets the default column settings. All columns will use these settings unless
231:             * they have been explicitly assigned custom settings by setColumn.
232:             * 
233:             * @param info the properties of all default columns
234:             * @see setColumn
235:             */
236:            public CellLayout setDefaultColumn(Row info) {
237:                defaultColSettings = info;
238:                return this ;
239:            }
240:
241:            /**
242:             * Sets the column info for the given column number (the leftmost column is column 0).
243:             * This replaces any existing info for the column. Note that more than one column
244:             * are allowed to share the same IColumnInfo instance if they have identical properties.
245:             * 
246:             * @param colNum the column number to modify
247:             * @param info the properties of the column, or null if this column should use the
248:             * default properties 
249:             */
250:            public CellLayout setColumn(int colNum, Row info) {
251:                while (cols.size() <= colNum) {
252:                    cols.add(null);
253:                }
254:
255:                cols.set(colNum, info);
256:
257:                return this ;
258:            }
259:
260:            /**
261:             * Sets the default row settings for this layout. Unless this is overridden
262:             * for an individual row, all rows will use the default settings.
263:             * 
264:             * @param info the row info object that should be used to set the size
265:             * of rows, by default.
266:             */
267:            public CellLayout setDefaultRow(Row info) {
268:                defaultRowSettings = info;
269:
270:                return this ;
271:            }
272:
273:            /**
274:             * Sets the row info for the given rows. The topmost row is row 0. Multiple
275:             * rows are allowed to share the same RowInfo instance.
276:             * 
277:             * @param rowNum the row number to set
278:             * @param info the row info that will control the sizing of the given row,
279:             * or null if the row should use the default settings for this layout.
280:             */
281:            public CellLayout setRow(int rowNum, Row info) {
282:                while (rows.size() <= rowNum) {
283:                    rows.add(null);
284:                }
285:
286:                rows.set(rowNum, info);
287:
288:                return this ;
289:            }
290:
291:            /**
292:             * Returns the row info that controls the size of the given row. Will return
293:             * the default row settings for this layout if no custom row info has been
294:             * assigned to the row.
295:             * 
296:             * @param rowNum
297:             * @return
298:             */
299:            private Row getRow(int rowNum, boolean isHorizontal) {
300:                if (isHorizontal) {
301:                    if (rowNum >= rows.size()) {
302:                        return defaultRowSettings;
303:                    }
304:
305:                    Row result = (Row) rows.get(rowNum);
306:
307:                    if (result == null) {
308:                        result = defaultRowSettings;
309:                    }
310:
311:                    return result;
312:                } else {
313:                    if (rowNum >= cols.size()) {
314:                        return defaultColSettings;
315:                    }
316:
317:                    Row result = (Row) cols.get(rowNum);
318:
319:                    if (result == null) {
320:                        result = defaultColSettings;
321:                    }
322:
323:                    return result;
324:                }
325:            }
326:
327:            /**
328:             * Initializes the gridInfo object.
329:             * 
330:             * @param children controls that are being layed out
331:             */
332:            private void initGrid(Control[] children) {
333:                cache.setControls(children);
334:                gridInfo.initGrid(children, this );
335:                cachedRowMin = null;
336:                cachedColMin = null;
337:            }
338:
339:            /* (non-Javadoc)
340:             * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean)
341:             */
342:            protected Point computeSize(Composite composite, int wHint,
343:                    int hHint, boolean flushCache) {
344:                Control[] children = composite.getChildren();
345:                initGrid(children);
346:
347:                if (flushCache) {
348:                    cache.flush();
349:                }
350:
351:                // Determine the amount of whitespace (area that cannot be used by controls)
352:                Point emptySpace = totalEmptySpace();
353:
354:                int[] heightConstraints = computeConstraints(true);
355:
356:                int width;
357:                if (wHint == SWT.DEFAULT) {
358:                    width = preferredSize(heightConstraints, false);
359:                } else {
360:                    width = wHint - emptySpace.x;
361:                }
362:
363:                int height = hHint;
364:                if (hHint == SWT.DEFAULT) {
365:                    height = preferredSize(computeSizes(heightConstraints,
366:                            width, false), true);
367:                } else {
368:                    height = hHint - emptySpace.y;
369:                }
370:
371:                Point preferredSize = new Point(width + emptySpace.x, height
372:                        + emptySpace.y);
373:
374:                // At this point we know the layout's preferred size. Now adjust it
375:                // if we're smaller than the minimum possible size for the composite.
376:
377:                // If exactly one dimension of our preferred size is smaller than
378:                // the minimum size of our composite, then set that dimension to
379:                // the minimum size and recompute the other dimension (for example,
380:                // increasing the width to match a shell's minimum width may reduce
381:                // the height allocated for a wrapping text widget). There is no
382:                // point in doing this if both dimensions are smaller than the
383:                // composite's minimum size, since we're already smaller than
384:                // we need to be.
385:                Point minimumSize = CellLayoutUtil
386:                        .computeMinimumSize(composite);
387:
388:                boolean wider = (preferredSize.x >= minimumSize.x);
389:                boolean taller = (preferredSize.y >= minimumSize.y);
390:
391:                if (wider) {
392:                    if (taller) {
393:                        // If we're larger in both dimensions, don't adjust the minimum
394:                        // size.
395:                        return preferredSize;
396:                    } else {
397:                        // If our preferred height is smaller than the minimum height,
398:                        // recompute the preferred width using the minimum height
399:                        return computeSize(composite, wHint, minimumSize.y,
400:                                false);
401:                    }
402:                } else {
403:                    if (taller) {
404:                        // If our preferred width is smaller than the minimum width,
405:                        // recompute the preferred height using the minimum width
406:                        return computeSize(composite, minimumSize.x, hHint,
407:                                false);
408:                    } else {
409:                        // If both dimensions are smaller than the minimum size,
410:                        // use the minimum size as our preferred size.
411:                        return minimumSize;
412:                    }
413:                }
414:            }
415:
416:            int[] computeSizes(int[] constraints, int availableSpace,
417:                    boolean computingRows) {
418:                int[] result = computeMinSizes(constraints, computingRows);
419:
420:                int totalFixed = sumOfSizes(result);
421:                int denominator = getResizeDenominator(computingRows);
422:                int numRows = gridInfo.getNumRows(computingRows);
423:
424:                if (totalFixed < availableSpace) {
425:                    int remaining = availableSpace - totalFixed;
426:
427:                    for (int idx = 0; idx < numRows && denominator > 0; idx++) {
428:                        Row row = getRow(idx, computingRows);
429:
430:                        if (row.grows) {
431:                            int greed = row.size;
432:                            int amount = remaining * greed / denominator;
433:
434:                            result[idx] += amount;
435:                            remaining -= amount;
436:                            denominator -= greed;
437:                        }
438:                    }
439:                }
440:
441:                return result;
442:            }
443:
444:            /**
445:             * Computes one dimension of the preferred size of the layout.
446:             * 
447:             * @param hint contains the result if already known, or SWT.DEFAULT if it needs to be computed
448:             * @param constraints contains constraints along the other dimension, or SWT.DEFAULT if none. For
449:             * example, if we are computing the preferred row sizes, this would be an array of known column sizes.
450:             * @param computingRows if true, this method returns the height (pixels). Otherwise, it returns the
451:             * width (pixels).
452:             */
453:            int preferredSize(int[] constraints, boolean computingRows) {
454:                int[] fixedSizes = computeMinSizes(constraints, computingRows);
455:
456:                return sumOfSizes(fixedSizes)
457:                        + getDynamicSize(constraints, fixedSizes, computingRows);
458:            }
459:
460:            /**
461:             * Computes the sum of all integers in the given array. If any of the entries are SWT.DEFAULT,
462:             * the result is SWT.DEFAULT. 
463:             */
464:            static int sumOfSizes(int[] input) {
465:                return sumOfSizes(input, 0, input.length);
466:            }
467:
468:            static int sumOfSizes(int[] input, int start, int length) {
469:                int sum = 0;
470:                for (int idx = start; idx < start + length; idx++) {
471:                    int next = input[idx];
472:
473:                    if (next == SWT.DEFAULT) {
474:                        return SWT.DEFAULT;
475:                    }
476:
477:                    sum += next;
478:                }
479:
480:                return sum;
481:            }
482:
483:            /**
484:             * Returns the preferred dynamic width of the layout 
485:             * 
486:             * @param constraints
487:             * @param fixedSizes
488:             * @param computingRows
489:             * @return
490:             */
491:            int getDynamicSize(int[] constraints, int[] fixedSizes,
492:                    boolean computingRows) {
493:                int result = 0;
494:                int numerator = getResizeDenominator(computingRows);
495:
496:                // If no resizable columns, return
497:                if (numerator == 0) {
498:                    return 0;
499:                }
500:
501:                int rowSpacing = computingRows ? verticalSpacing
502:                        : horizontalSpacing;
503:                int colSpacing = computingRows ? horizontalSpacing
504:                        : verticalSpacing;
505:
506:                int numControls = gridInfo.controls.length;
507:                for (int idx = 0; idx < numControls; idx++) {
508:                    int controlRowStart = gridInfo.getStartPos(idx,
509:                            computingRows);
510:                    int controlRowSpan = getSpan(idx, computingRows);
511:                    int controlColStart = gridInfo.getStartPos(idx,
512:                            !computingRows);
513:                    int controlColSpan = getSpan(idx, !computingRows);
514:
515:                    int denominator = getGrowthRatio(controlRowStart,
516:                            controlRowSpan, computingRows);
517:
518:                    if (denominator > 0) {
519:
520:                        int widthHint = sumOfSizes(constraints,
521:                                controlColStart, controlColSpan);
522:                        if (widthHint != SWT.DEFAULT) {
523:                            widthHint += colSpacing * (controlColSpan - 1);
524:                        }
525:
526:                        // Compute the total control size
527:                        int controlSize = computeControlSize(idx, widthHint,
528:                                computingRows);
529:
530:                        // Subtract the amount that overlaps fixed-size columns
531:                        controlSize -= sumOfSizes(fixedSizes, controlRowStart,
532:                                controlRowSpan);
533:
534:                        // Subtract the amount that overlaps spacing between cells
535:                        controlSize -= (rowSpacing * (controlRowSpan - 1));
536:
537:                        result = Math.max(result, controlSize * numerator
538:                                / denominator);
539:                    }
540:                }
541:
542:                return result;
543:            }
544:
545:            /**
546:             * Computes one dimension of a control's size
547:             * 
548:             * @param control the index of the control being computed
549:             * @param constraint the other dimension of the control's size, or SWT.DEFAULT if unknown
550:             * @param computingHeight if true, this method returns a height. Else it returns a width
551:             * @return the preferred height or width of the control, in pixels
552:             */
553:            int computeControlSize(int control, int constraint,
554:                    boolean computingHeight) {
555:                CellData data = gridInfo.getCellData(control);
556:
557:                // If we're looking for the preferred size of the control (without hints)
558:                if (constraint == SWT.DEFAULT) {
559:                    Point result = data.computeSize(cache.getCache(control),
560:                            SWT.DEFAULT, SWT.DEFAULT);
561:
562:                    // Return result
563:                    if (computingHeight) {
564:                        return result.y;
565:                    }
566:                    return result.x;
567:                }
568:
569:                // Compute a height
570:                if (computingHeight) {
571:                    return data.computeSize(cache.getCache(control),
572:                            constraint, SWT.DEFAULT).y;
573:                }
574:
575:                return data.computeSize(cache.getCache(control), SWT.DEFAULT,
576:                        constraint).x;
577:            }
578:
579:            /**
580:             * Returns the relative amount that a control starting on the given row and spanning
581:             * the given length will contribute 
582:             * 
583:             * @param start
584:             * @param length
585:             * @param computingRows
586:             * @return
587:             */
588:            int getGrowthRatio(int start, int length, boolean computingRows) {
589:                boolean willGrow = false;
590:                int sum = 0;
591:
592:                int end = start + length;
593:                for (int idx = start; idx < end; idx++) {
594:                    Row row = getRow(idx, computingRows);
595:
596:                    if (row.largerThanChildren && row.grows) {
597:                        willGrow = true;
598:                    }
599:
600:                    sum += row.size;
601:                }
602:
603:                if (!willGrow) {
604:                    return 0;
605:                }
606:
607:                return sum;
608:            }
609:
610:            int[] computeMinSizes(int[] constraints, boolean computingRows) {
611:                // We cache the result of this function since it might be called more than once
612:                // for a single size computation
613:                int[] result = computingRows ? cachedRowMin : cachedColMin;
614:
615:                if (result == null) {
616:                    int columnSpacing;
617:                    int rowSpacing;
618:
619:                    if (computingRows) {
620:                        columnSpacing = horizontalSpacing;
621:                        rowSpacing = verticalSpacing;
622:                    } else {
623:                        columnSpacing = verticalSpacing;
624:                        rowSpacing = horizontalSpacing;
625:                    }
626:
627:                    int rowCount = gridInfo.getNumRows(computingRows);
628:                    result = new int[rowCount];
629:                    int colCount = gridInfo.getNumRows(!computingRows);
630:                    int[] rowControls = new int[colCount];
631:
632:                    int lastGrowingRow = -1;
633:
634:                    for (int idx = 0; idx < rowCount; idx++) {
635:                        Row row = getRow(idx, computingRows);
636:
637:                        if (row.grows) {
638:                            // There is no minimum size for growing rows
639:                            lastGrowingRow = idx;
640:                            result[idx] = 0;
641:                        } else {
642:                            result[idx] = row.size;
643:
644:                            if (row.largerThanChildren) {
645:                                // Determine which controls are in this row
646:                                gridInfo
647:                                        .getRow(rowControls, idx, computingRows);
648:
649:                                for (int colIdx = 0; colIdx < rowControls.length; colIdx++) {
650:                                    int control = rowControls[colIdx];
651:
652:                                    // The getRow method will insert -1 into empty cells... skip these.
653:                                    if (control != -1) {
654:                                        int controlStart = gridInfo
655:                                                .getStartPos(control,
656:                                                        computingRows);
657:                                        int controlSpan = getSpan(control,
658:                                                computingRows);
659:
660:                                        // If the control ends on this row and does not span any growing rows
661:                                        if (controlStart + controlSpan - 1 == idx
662:                                                && controlStart > lastGrowingRow) {
663:                                            int controlColStart = gridInfo
664:                                                    .getStartPos(control,
665:                                                            !computingRows);
666:                                            int controlColSpan = getSpan(
667:                                                    control, !computingRows);
668:                                            int controlRowSpan = getSpan(
669:                                                    control, computingRows);
670:
671:                                            // Compute the width constraint for this control
672:                                            int spannedWidth = sumOfSizes(
673:                                                    constraints,
674:                                                    controlColStart,
675:                                                    controlColSpan);
676:                                            if (spannedWidth != SWT.DEFAULT) {
677:                                                spannedWidth += (columnSpacing * (controlSpan - 1));
678:                                            }
679:
680:                                            int controlHeight = computeControlSize(
681:                                                    control, spannedWidth,
682:                                                    computingRows);
683:
684:                                            // Determine how much of the control spans already allocated columns
685:                                            int allocatedHeight = sumOfSizes(
686:                                                    result, controlColStart,
687:                                                    controlRowSpan - 1)
688:                                                    + (rowSpacing * (controlRowSpan - 1));
689:
690:                                            result[idx] = Math.max(result[idx],
691:                                                    controlHeight
692:                                                            - allocatedHeight);
693:                                        }
694:                                    }
695:                                }
696:                            }
697:                        }
698:                    }
699:                }
700:
701:                // Cache this result
702:                if (computingRows) {
703:                    cachedRowMin = result;
704:                } else {
705:                    cachedColMin = result;
706:                }
707:
708:                return result;
709:            }
710:
711:            /**
712:             * Returns the height constraints that should be used when computing column widths. Requires initGrid
713:             * to have been called first.
714:             * 
715:             * @param result Will contain the height constraint for row i in the ith position of the array, 
716:             * or SWT.DEFAULT if there is no constraint on that row.
717:             */
718:            private int[] computeConstraints(boolean horizontal) {
719:                // Initialize the height constraints for each row (basically, these will always be SWT.DEFAULT,
720:                // except for rows of type FixedRow, which have a constant height).
721:                int numRows = gridInfo.getNumRows(horizontal);
722:                int[] result = new int[numRows];
723:
724:                for (int idx = 0; idx < numRows; idx++) {
725:                    Row row = getRow(idx, horizontal);
726:
727:                    if (!(row.grows || row.largerThanChildren)) {
728:                        result[idx] = row.size;
729:                    } else {
730:                        result[idx] = SWT.DEFAULT;
731:                    }
732:                }
733:
734:                return result;
735:            }
736:
737:            /**
738:             * Computes the total greediness of all rows
739:             * 
740:             * @return the total greediness of all rows
741:             */
742:            private int getResizeDenominator(boolean horizontal) {
743:                int result = 0;
744:                int numRows = gridInfo.getNumRows(horizontal);
745:
746:                for (int idx = 0; idx < numRows; idx++) {
747:                    Row row = getRow(idx, horizontal);
748:
749:                    if (row.grows) {
750:                        result += row.size;
751:                    }
752:                }
753:
754:                return result;
755:            }
756:
757:            //	/**
758:            //	 * Computes the total fixed height of all rows
759:            //	 * 
760:            //	 * @param widthConstraints array where the nth entry indicates the known width of the
761:            //	 * nth column, or SWT.DEFAULT if the width is still unknown
762:            //	 * 
763:            //	 * @return the total fixed height for all rows
764:            //	 */
765:            //	private int getMinimumSize(int[] constraints, boolean horizontal) {
766:            //		Control[] controls = new Control[gridInfo.getRows()];
767:            //		int result = 0;
768:            //		int numRows = gridInfo.getRows();
769:            //		
770:            //		for (int idx = 0; idx < numRows; idx++) {
771:            //			result += getRow(idx).getFixedHeight(gridInfo, widthConstraints, idx);
772:            //		}		
773:            //		
774:            //		return result;
775:            //	}
776:
777:            protected int getSpan(int controlId, boolean isRow) {
778:                CellData data = gridInfo.getCellData(controlId);
779:
780:                if (isRow) {
781:                    return data.verticalSpan;
782:                }
783:                return data.horizontalSpan;
784:            }
785:
786:            /**
787:             * Returns the total space that will be required for margins and spacing between and
788:             * around cells. initGrid(...) must have been called first.
789:             * 
790:             * @return
791:             */
792:            private Point totalEmptySpace() {
793:                int numRows = gridInfo.getRows();
794:
795:                return new Point((2 * marginWidth)
796:                        + ((gridInfo.getCols() - 1) * horizontalSpacing),
797:                        (2 * marginHeight) + ((numRows - 1) * verticalSpacing));
798:            }
799:
800:            /**
801:             * Returns the absolute positions of each row, given the start position, row sizes, 
802:             * and row spacing 
803:             * 
804:             * @param startPos position of the initial row
805:             * @param sizes array of row sizes (pixels)
806:             * @param spacing space between each row (pixels)
807:             * @return array of row positions. The result size is sizes.length + 1. The last entry is
808:             * the position of the end of the layout.
809:             */
810:            private static int[] computeRowPositions(int startPos, int[] sizes,
811:                    int spacing) {
812:                int[] result = new int[sizes.length + 1];
813:
814:                result[0] = startPos;
815:                for (int idx = 0; idx < sizes.length; idx++) {
816:                    result[idx + 1] = result[idx] + sizes[idx] + spacing;
817:                }
818:
819:                return result;
820:            }
821:
822:            /* (non-Javadoc)
823:             * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean)
824:             */
825:            protected void layout(Composite composite, boolean flushCache) {
826:                Control[] children = composite.getChildren();
827:
828:                // If there are no children then this is a NO-OP
829:                if (children.length == 0)
830:                    return;
831:
832:                initGrid(children);
833:
834:                if (flushCache) {
835:                    cache.flush();
836:                }
837:
838:                Point emptySpace = totalEmptySpace();
839:
840:                // Compute the area actually available for controls (once the margins and spacing is removed)
841:                int availableWidth = composite.getClientArea().width
842:                        - emptySpace.x;
843:                int availableHeight = composite.getClientArea().height
844:                        - emptySpace.y;
845:
846:                int[] heights = computeConstraints(true);
847:                int[] widths = new int[gridInfo.getCols()];
848:
849:                // Compute the actual column widths
850:                widths = computeSizes(heights, availableWidth, false);
851:
852:                // Compute the actual row heights (based on the actual column widths)
853:                heights = computeSizes(widths, availableHeight, true);
854:
855:                Rectangle currentCell = new Rectangle(0, 0, 0, 0);
856:
857:                int[] starty = computeRowPositions(composite.getClientArea().y
858:                        + marginHeight, heights, verticalSpacing);
859:                int[] startx = computeRowPositions(composite.getClientArea().x
860:                        + marginWidth, widths, horizontalSpacing);
861:
862:                int numChildren = gridInfo.controls.length;
863:                for (int controlId = 0; controlId < numChildren; controlId++) {
864:                    CellData data = gridInfo.getCellData(controlId);
865:
866:                    int row = gridInfo.controlRow[controlId];
867:                    int col = gridInfo.controlCol[controlId];
868:
869:                    currentCell.x = startx[col];
870:                    currentCell.width = startx[col + data.horizontalSpan]
871:                            - currentCell.x - horizontalSpacing;
872:
873:                    currentCell.y = starty[row];
874:                    currentCell.height = starty[row + data.verticalSpan]
875:                            - currentCell.y - verticalSpacing;
876:
877:                    data
878:                            .positionControl(cache.getCache(controlId),
879:                                    currentCell);
880:                }
881:            }
882:
883:            /**
884:             * @return
885:             */
886:            public int getColumns() {
887:                return numCols;
888:            }
889:
890:            public boolean canGrow(Composite composite, boolean horizontally) {
891:                initGrid(composite.getChildren());
892:
893:                int numRows = gridInfo.getNumRows(horizontally);
894:
895:                for (int idx = 0; idx < numRows; idx++) {
896:                    Row row = getRow(idx, horizontally);
897:
898:                    if (row.grows) {
899:                        return true;
900:                    }
901:                }
902:
903:                return false;
904:
905:            }
906:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.