Source Code Cross Referenced for LayoutManager.java in  » 6.0-JDK-Modules » j2me » javax » microedition » lcdui » 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 » 6.0 JDK Modules » j2me » javax.microedition.lcdui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package javax.microedition.lcdui;
0028:
0029:        import com.sun.midp.log.Logging;
0030:        import com.sun.midp.log.LogChannels;
0031:        import com.sun.midp.configurator.Constants;
0032:
0033:        /**
0034:         * Layout management class for <code>Form</code>.
0035:         * See DisplayableLF.java for naming convention.
0036:         */
0037:        class LayoutManager {
0038:
0039:            // Required test: multiple/simultaneous forms with different layout
0040:
0041:            /**
0042:             * Singleton design pattern. Obtain access using instance() method.
0043:             */
0044:            LayoutManager() {
0045:                sizingBox = new int[3]; // x,y,width
0046:            }
0047:
0048:            /**
0049:             * Do layout.
0050:             * SYNC NOTE: caller must hold LCDUILock around a call to this method
0051:             *
0052:             * @param layoutMode one of <code>FULL_LAYOUT</code> or 
0053:             *                   <code>UPDATE_LAYOUT</code>
0054:             * @param numOfLFs number of elements in the calling form
0055:             * @param itemLFs reference to the items array of the calling form
0056:             * @param inp_viewportWidth width of the screen area available for the form
0057:             * @param inp_viewportHeight height of the screen area available 
0058:             * for the form
0059:             * @param viewable area needed for the content of the form
0060:             */
0061:            void lLayout(int layoutMode, ItemLFImpl[] itemLFs, int numOfLFs,
0062:                    int inp_viewportWidth, int inp_viewportHeight,
0063:                    int[] viewable) {
0064:
0065:                viewportWidth = inp_viewportWidth;
0066:                viewportHeight = inp_viewportHeight;
0067:
0068:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0069:                    Logging
0070:                            .report(
0071:                                    Logging.INFORMATION,
0072:                                    LogChannels.LC_HIGHUI_FORM_LAYOUT,
0073:                                    "\n<<<<<<<<<< Doing "
0074:                                            + (layoutMode == FULL_LAYOUT ? "FULL_LAYOUT"
0075:                                                    : "UPDATE_LAYOUT")
0076:                                            + "... >>>>>>>>>>");
0077:                }
0078:
0079:                if (layoutMode == FULL_LAYOUT) {
0080:                    // first Layout
0081:                    updateBlock(0, 0, true, itemLFs, numOfLFs, viewable);
0082:                } else {
0083:                    // UPDATE_LAYOUT
0084:                    // most of the time only one or two items are updated at a time.
0085:                    // here we find the minimum items that needs a re-layout, and
0086:                    // calling layout for them
0087:
0088:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0089:                        Logging.report(Logging.INFORMATION,
0090:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0091:                                "UPDATE_LAYOUT - START");
0092:                    }
0093:                    // loop on all the items, and find which item needs an update
0094:                    // If more than one Item needs update, they both will update,
0095:                    // in their layout order.
0096:
0097:                    // * we keep a "moving anchor" to use when we identify
0098:                    // an invalid Item. This anchor is always at the beginning 
0099:                    // of the row above the current Item checked, or at the 
0100:                    // beginning of the row of the current Item, in case there
0101:                    // was an explicit line break.
0102:
0103:                    int anchorIndex = 0;
0104:
0105:                    // this index is needed to identify new lines to be set as 
0106:                    // anchors later.
0107:                    int newLineIndex = 0;
0108:
0109:                    // find where to start the layout. It should be at the beginning
0110:                    // of the line above the invalid item, or of the same line
0111:                    // in case the line break is explicit.
0112:
0113:                    // We loop on all the Items to find the first invalid, while
0114:                    // keeping the anchorIndex up do date. When calling "updateBlock",
0115:                    // the index will jump directly to the next block, because we laid
0116:                    // out all the Items in that block.
0117:
0118:                    for (int index = 0; index < numOfLFs; index++) {
0119:
0120:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0121:                            Logging
0122:                                    .report(
0123:                                            Logging.INFORMATION,
0124:                                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0125:                                            "\n["
0126:                                                    + itemLFs[index]
0127:                                                    + "]"
0128:                                                    + "BEFORE: index: "
0129:                                                    + index
0130:                                                    + "\t["
0131:                                                    + itemLFs[index].bounds[X]
0132:                                                    + ","
0133:                                                    + itemLFs[index].bounds[Y]
0134:                                                    + ","
0135:                                                    + itemLFs[index].bounds[WIDTH]
0136:                                                    + ","
0137:                                                    + itemLFs[index].bounds[HEIGHT]
0138:                                                    + "]\t newLine?"
0139:                                                    + itemLFs[index].isNewLine
0140:                                                    + " lineHeight="
0141:                                                    + itemLFs[index].rowHeight
0142:                                                    + "\t actualBoundsInvalid["
0143:                                                    + itemLFs[index].actualBoundsInvalid[X]
0144:                                                    + ","
0145:                                                    + itemLFs[index].actualBoundsInvalid[Y]
0146:                                                    + ","
0147:                                                    + itemLFs[index].actualBoundsInvalid[WIDTH]
0148:                                                    + ","
0149:                                                    + itemLFs[index].actualBoundsInvalid[HEIGHT]
0150:                                                    + "]\t ** viewable: "
0151:                                                    + index + "\t["
0152:                                                    + viewportWidth + ","
0153:                                                    + viewable[HEIGHT] + "]");
0154:                        }
0155:
0156:                        if (itemLFs[index].actualBoundsInvalid[WIDTH]
0157:                                || itemLFs[index].actualBoundsInvalid[X]) {
0158:
0159:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0160:                                Logging.report(Logging.INFORMATION,
0161:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0162:                                        "> WIDTH or X is invalid!");
0163:                            }
0164:
0165:                            // if width is changed, than we have to do a layout two 
0166:                            // a block of Items. So it covers the height as well call
0167:                            // layout block. The index will jump to the first item on
0168:                            // the next block.
0169:
0170:                            // return the last item on the block:
0171:                            index = updateBlock(anchorIndex, index, false,
0172:                                    itemLFs, numOfLFs, viewable);
0173:
0174:                            // set the anchor on the next item, if there is one.
0175:                            // if (i+1) is larger than the length of itemLFs, the for
0176:                            // loop will end anyway so we don't have to check it here.
0177:
0178:                            anchorIndex = index + 1;
0179:
0180:                        } else if (itemLFs[index].actualBoundsInvalid[HEIGHT]) {
0181:
0182:                            // item current height
0183:                            int h = itemLFs[index].bounds[HEIGHT];
0184:
0185:                            // item preferred height
0186:                            int ph = itemLFs[index]
0187:                                    .lGetAdornedPreferredHeight(itemLFs[index].bounds[WIDTH]);
0188:
0189:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0190:                                Logging.report(Logging.INFORMATION,
0191:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0192:                                        "> HEIGHT is invalid  from:" + h
0193:                                                + " to:" + ph);
0194:                            }
0195:                            if (h != ph) {
0196:                                itemLFs[index].lSetSize(
0197:                                        itemLFs[index].bounds[WIDTH], ph);
0198:                                itemLFs[index].rowHeight += (ph - h);
0199:
0200:                                // NOTE: We should check whole row height, 
0201:                                // instead of just this item.
0202:
0203:                                itemLFs[index].actualBoundsInvalid[HEIGHT] = false;
0204:
0205:                                if (numOfLFs > index + 1) {
0206:
0207:                                    itemLFs[index + 1].actualBoundsInvalid[Y] = true;
0208:
0209:                                    // NOTE: We should calculate new LineHeight,
0210:                                    // instead of just Item Height
0211:
0212:                                    updateVertically(index + 1, itemLFs,
0213:                                            numOfLFs, viewable);
0214:                                } else {
0215:                                    // only need to update the viewable
0216:                                    viewable[HEIGHT] += (ph - h);
0217:                                }
0218:                            }
0219:
0220:                        } else if (itemLFs[index].actualBoundsInvalid[Y]) {
0221:
0222:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0223:                                Logging.report(Logging.INFORMATION,
0224:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0225:                                        "> *only* Y is invalid for #" + index);
0226:                            }
0227:
0228:                            updateVertically(index, itemLFs, numOfLFs, viewable);
0229:
0230:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0231:                                Logging.report(Logging.INFORMATION,
0232:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0233:                                        "> Y - done");
0234:                            }
0235:
0236:                        } else {
0237:
0238:                            // current item is valid.
0239:
0240:                            // check if i can be a new anchor point 
0241:                            // (has an explicit line break before it, 
0242:                            // or after the previous Item).
0243:                            if (itemLFs[index].isNewLine) {
0244:
0245:                                if (itemLFs[index].equateNLB()
0246:                                        || ((index > 0) && (itemLFs[index - 1]
0247:                                                .equateNLA()))) {
0248:                                    // explicit newline
0249:                                    anchorIndex = index;
0250:                                    newLineIndex = index;
0251:                                } else {
0252:                                    // implicit newline
0253:
0254:                                    // we can move the anchor to the next line:
0255:                                    // set the anchorIndex to be the old newLineIndex
0256:                                    // (which is the first item on the row above the
0257:                                    // current item).
0258:                                    anchorIndex = newLineIndex;
0259:
0260:                                    // set i as the first in its line
0261:                                    newLineIndex = index;
0262:                                }
0263:
0264:                            }
0265:
0266:                        }
0267:
0268:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0269:                            Logging
0270:                                    .report(
0271:                                            Logging.INFORMATION,
0272:                                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0273:                                            "AFTER: index: "
0274:                                                    + index
0275:                                                    + "\t["
0276:                                                    + itemLFs[index].bounds[X]
0277:                                                    + ","
0278:                                                    + itemLFs[index].bounds[Y]
0279:                                                    + ","
0280:                                                    + itemLFs[index].bounds[WIDTH]
0281:                                                    + ","
0282:                                                    + itemLFs[index].bounds[HEIGHT]
0283:                                                    + "]\t newLine?"
0284:                                                    + itemLFs[index].isNewLine
0285:                                                    + " lineHeight="
0286:                                                    + itemLFs[index].rowHeight
0287:                                                    + "\t actualBoundsInvalid["
0288:                                                    + itemLFs[index].actualBoundsInvalid[X]
0289:                                                    + ","
0290:                                                    + itemLFs[index].actualBoundsInvalid[Y]
0291:                                                    + ","
0292:                                                    + itemLFs[index].actualBoundsInvalid[WIDTH]
0293:                                                    + ","
0294:                                                    + itemLFs[index].actualBoundsInvalid[HEIGHT]
0295:                                                    + "]\t ** viewable: "
0296:                                                    + index + "\t["
0297:                                                    + viewportWidth + ","
0298:                                                    + viewable[HEIGHT] + "]");
0299:                        }
0300:                    } // for loop    
0301:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0302:                        Logging.report(Logging.INFORMATION,
0303:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0304:                                "UPDATE_LAYOUT - DONE");
0305:                    }
0306:                }
0307:
0308:                // correct viewable area if required
0309:
0310:                // if there are no items in the form just reset viewable[HEIGHT]
0311:                if (numOfLFs == 0) {
0312:                    viewable[HEIGHT] = 0;
0313:                }
0314:            }
0315:
0316:            /**
0317:             * Used both to do a full layout or just update a layout.
0318:             *
0319:             * assumptions: startIndex<=invalidIndex
0320:             * 
0321:             * @param startIndex The index to start the layout. Should start a row.
0322:             * @param invalidIndex The index causing the re-layout, should
0323:             *        be equal or greater than startIndex
0324:             * @param fullLayout if <code>true</code>, does a full layout and ignores
0325:             *                   the rest of the parameters sent to this method.
0326:             * @param itemLFs reference to the items array of the calling form
0327:             * @param numOfLFs number of elements in the calling form
0328:             * @param viewable area needed for the content of the form
0329:             *
0330:             * @return the index of the last <code>Item</code> laid out
0331:             */
0332:            private int updateBlock(int startIndex, int invalidIndex,
0333:                    boolean fullLayout, ItemLFImpl[] itemLFs, int numOfLFs,
0334:                    int[] viewable) {
0335:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0336:                    Logging.report(Logging.INFORMATION,
0337:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0338:                            "\n - updateBlock(START=" + startIndex
0339:                                    + ", INVALID=" + invalidIndex
0340:                                    + ", Full Layout=" + fullLayout + ") {");
0341:                }
0342:
0343:                // SYNC NOTE: layout() is always called from within a hold
0344:                // on LCDUILock
0345:
0346:                int oldWidth = viewable[WIDTH];
0347:                int oldHeight = viewable[HEIGHT];
0348:
0349:                // If we don't have any Items, just return
0350:                if (numOfLFs == 0) {
0351:
0352:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0353:                        Logging.report(Logging.INFORMATION,
0354:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0355:                                " we don't have any Items, just return }");
0356:                    }
0357:
0358:                    return 0;
0359:                }
0360:
0361:                int rowStart;
0362:
0363:                if (fullLayout) {
0364:                    // The index of the first Item in the horizontal row
0365:                    rowStart = 0;
0366:                } else {
0367:                    rowStart = startIndex;
0368:                }
0369:
0370:                // The sizingBox starts out life with the size of the viewport, 
0371:                // but gets whittled down as each Item gets laid out and occupies 
0372:                // space in it. It effectively keeps a running total of what space
0373:                // is available due to the Items which have already been laid out
0374:
0375:                // We only allow space for the traversal indicator if we
0376:                // have more than one item - because we only draw the traversal
0377:                // indicator if we have more than one item to traverse to.
0378:                // LF's width is set to the maximum allowable width,
0379:                // while view's height is initialized with initial padding and
0380:                // and grows when new row is added.
0381:                sizingBox[X] = 0;
0382:                sizingBox[Y] = 0;
0383:                sizingBox[WIDTH] = viewportWidth;
0384:                viewable[WIDTH] = viewportWidth;
0385:
0386:                if (fullLayout) {
0387:                    viewable[HEIGHT] = 0;
0388:                } else if (numOfLFs > 1 && startIndex > 0) {
0389:                    sizingBox[Y] = itemLFs[startIndex - 1].bounds[Y]
0390:                            + itemLFs[startIndex - 1].rowHeight;
0391:
0392:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0393:                        Logging.report(Logging.INFORMATION,
0394:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0395:                                "sizingBox[Y]=" + sizingBox[Y]);
0396:                    }
0397:                }
0398:
0399:                // A running variable which maintains the height of the
0400:                // tallest item on a line
0401:                int lineHeight = 0;
0402:                int pW, pH;
0403:                int curAlignment = Item.LAYOUT_LEFT;
0404:
0405:                // We loop through the Items starting in startIndex, until we reach
0406:                // the end of the block, and return the index of the next block,
0407:                // or just finishing the for loop if this is the last block.
0408:                for (int index = startIndex; index < numOfLFs; index++) {
0409:
0410:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0411:                        Logging.report(Logging.INFORMATION,
0412:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0413:                                "..\n\tFOR LOOP: startIndex=" + startIndex
0414:                                        + " index=[" + index
0415:                                        + "] invalidIndex=" + invalidIndex);
0416:                    }
0417:
0418:                    // If the Item can be shrunken, get its minimum width,
0419:                    // and its preferred if it is not
0420:                    if (itemLFs[index].shouldHShrink()) {
0421:                        pW = itemLFs[index].lGetAdornedMinimumWidth();
0422:                    } else {
0423:                        if (itemLFs[index].lGetLockedWidth() != -1) {
0424:                            pW = itemLFs[index].lGetLockedWidth();
0425:                        } else {
0426:                            // if height is locked default preferred width
0427:                            // will be used, otherwise width will be calculated
0428:                            // based on lockedHeight
0429:                            pW = itemLFs[index]
0430:                                    .lGetAdornedPreferredWidth(itemLFs[index]
0431:                                            .lGetLockedHeight());
0432:
0433:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0434:                                Logging.report(Logging.INFORMATION,
0435:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0436:                                        " no shrink - locked w - pW=" + pW
0437:                                                + " viewable[width]="
0438:                                                + viewable[WIDTH]);
0439:                            }
0440:                        }
0441:                    }
0442:
0443:                    // We have a notion of the maximum allowable width an Item can
0444:                    // have, so we enforce it first here:
0445:
0446:                    if (!Constants.SCROLLS_HORIZONTAL && (pW > viewable[WIDTH])) {
0447:                        pW = viewable[WIDTH];
0448:                    }
0449:
0450:                    // We use a separate boolean here to check for each case of
0451:                    // requiring a new line (rather than the if() from hell)
0452:                    boolean newLine = (index > 0
0453:                            && itemLFs[index - 1].equateNLA()
0454:                            || itemLFs[index].equateNLB() ||
0455:                    // no room for this item on the same row
0456:                    pW > sizingBox[WIDTH]);
0457:
0458:                    if (isImplicitLineBreak(curAlignment, index, itemLFs)) {
0459:                        curAlignment = itemLFs[index].getLayout()
0460:                                & LAYOUT_HMASK;
0461:                        newLine = true;
0462:                    }
0463:
0464:                    // We linebreak if there is an existing row;
0465:                    // possible only when there is more than 1 item
0466:                    if (newLine && (lineHeight > 0)) {
0467:                        // index > 0, as the calculation of newLine guarantee
0468:
0469:                        //
0470:                        // ** NEW LINE **
0471:                        //
0472:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0473:                            Logging.report(Logging.INFORMATION,
0474:                                    LogChannels.LC_HIGHUI_FORM_LAYOUT,
0475:                                    "   --new line--");
0476:                        }
0477:
0478:                        // First, handle current row's layout directives
0479:
0480:                        try {
0481:
0482:                            // used for layout update
0483:                            // int oldRowHeight = itemLFs[index-1].rowHeight; 
0484:                            boolean wasNewLine = itemLFs[index].isNewLine;
0485:
0486:                            // now it's certainly first in line
0487:                            itemLFs[index].isNewLine = true;
0488:
0489:                            // layout items in previous row
0490:                            lineHeight = layoutRowHorizontal(rowStart,
0491:                                    index - 1, sizingBox[WIDTH], lineHeight,
0492:                                    itemLFs);
0493:                            layoutRowVertical(rowStart, index - 1, lineHeight,
0494:                                    itemLFs, numOfLFs);
0495:
0496:                            if (fullLayout) {
0497:
0498:                                if (numOfLFs > 1) {
0499:                                    viewable[HEIGHT] += lineHeight;
0500:                                } else {
0501:                                    viewable[HEIGHT] += lineHeight + 1;
0502:                                }
0503:
0504:                            } else { // UPDATE_LAYOUT
0505:
0506:                                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0507:                                    Logging.report(Logging.INFORMATION,
0508:                                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0509:                                            "** 1 ** row height=" + lineHeight);
0510:                                }
0511:
0512:                                // cases: 
0513:                                // 1. this item was first in row already
0514:                                //  > than update layout wouldn't be called for the
0515:                                //  > row above it unless there was a change in that
0516:                                //  > row.
0517:                                //  > Therefore we can finish the loop, and just update
0518:                                //  > the Y coordinates for the rest of the Items.
0519:
0520:                                if (wasNewLine && index > invalidIndex) {
0521:                                    // we can call updateVertically by returning
0522:                                    // index-1 and marking next Y as invalid.
0523:                                    itemLFs[index].actualBoundsInvalid[Y] = true;
0524:
0525:                                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0526:                                        Logging
0527:                                                .report(
0528:                                                        Logging.INFORMATION,
0529:                                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0530:                                                        " returning index-1 and "
0531:                                                                + "marking next Y as invalid. }");
0532:                                    }
0533:
0534:                                    return (index - 1);
0535:                                    // (some Items after it may still be invalid, 
0536:                                    // so the calling method will continue the layout).
0537:
0538:                                }
0539:
0540:                                // 2. this item wasn't first on its row
0541:                                //  > then we should continue a regular layout.
0542:
0543:                                if (!wasNewLine) {
0544:                                    itemLFs[index].actualBoundsInvalid[X] = true;
0545:                                }
0546:                            }
0547:
0548:                        } catch (Throwable t) {
0549:                            Display.handleThrowable(t);
0550:                        }
0551:
0552:                        // Then, reset the sizingBox, lineHeight, and rowStart
0553:                        sizingBox[X] = 0;
0554:                        if (fullLayout) {
0555:                            sizingBox[Y] = viewable[HEIGHT];
0556:                        } else {
0557:                            sizingBox[Y] = itemLFs[index - 1].bounds[Y]
0558:                                    + itemLFs[index - 1].rowHeight;
0559:                            if (numOfLFs <= 1) {
0560:                                sizingBox[Y] += 1;
0561:                            }
0562:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0563:                                Logging.report(Logging.INFORMATION,
0564:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0565:                                        "** 2 **   sizingBox[Y]="
0566:                                                + sizingBox[Y]);
0567:                            }
0568:                        }
0569:
0570:                        sizingBox[WIDTH] = viewportWidth;
0571:
0572:                        lineHeight = 0;
0573:                        rowStart = index;
0574:
0575:                        itemLFs[index].isNewLine = true;
0576:
0577:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0578:                            Logging.report(Logging.INFORMATION,
0579:                                    LogChannels.LC_HIGHUI_FORM_LAYOUT,
0580:                                    "  (new line end)");
0581:                        }
0582:                        //
0583:                        // ** NEW LINE - END **
0584:                        //
0585:
0586:                    } else {
0587:
0588:                        // keep isNewLine flag up to date
0589:
0590:                        if (index == 0 || newLine) {
0591:                            itemLFs[index].isNewLine = true;
0592:                        } else {
0593:
0594:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0595:                                Logging
0596:                                        .report(
0597:                                                Logging.INFORMATION,
0598:                                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0599:                                                "** "
0600:                                                        + index
0601:                                                        + " is not a new line **");
0602:                            }
0603:
0604:                            // this is not a new line
0605:                            itemLFs[index].isNewLine = false;
0606:                        }
0607:
0608:                    }
0609:
0610:                    pH = getItemHeight(index, pW, itemLFs);
0611:
0612:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0613:                        Logging.report(Logging.INFORMATION,
0614:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0615:                                " updateBlock.. pH = " + pH);
0616:                    }
0617:
0618:                    // If the Item is changing size, set the flag so that callPaint()
0619:                    // will call the Item's sizeChanged() method before painting
0620:
0621:                    if (oldWidth != viewportWidth
0622:                            || oldHeight != viewportHeight
0623:                            || itemLFs[index].bounds[WIDTH] != pW
0624:                            || itemLFs[index].bounds[HEIGHT] != pH) {
0625:                        itemLFs[index].sizeChanged = true;
0626:                    }
0627:
0628:                    if (!fullLayout && (index > invalidIndex)) {
0629:
0630:                        // if we've reached the end of the block (explicit linebreak)
0631:                        // than we can safely return
0632:                        if (itemLFs[index].equateNLB()
0633:                                || ((index > 0) && (itemLFs[index - 1]
0634:                                        .equateNLA()))) {
0635:
0636:                            // we can stop the loop, returning the last Item laid out
0637:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0638:                                Logging.report(Logging.INFORMATION,
0639:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0640:                                        "** stop layout, explicit lb **\n}");
0641:                            }
0642:                            itemLFs[index].actualBoundsInvalid[Y] = true;
0643:                            return (index - 1);
0644:
0645:                            // identify more occasions where only Y will change
0646:                        } else if (itemLFs[index].bounds[X] == sizingBox[X]
0647:                                &&
0648:                                // itemLFs[index].bounds[Y] == sizingBox[Y] &&
0649:                                itemLFs[index].bounds[WIDTH] == pW
0650:                                && itemLFs[index].bounds[HEIGHT] == pH) {
0651:
0652:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0653:                                Logging.report(Logging.INFORMATION,
0654:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0655:                                        "\n** no need to layout **\n}");
0656:                            }
0657:
0658:                            itemLFs[index].actualBoundsInvalid[X] = false;
0659:                            // notice the "true": (only the Y coordinate is invalid)
0660:                            itemLFs[index].actualBoundsInvalid[Y] = true;
0661:                            itemLFs[index].actualBoundsInvalid[WIDTH] = false;
0662:                            itemLFs[index].actualBoundsInvalid[HEIGHT] = false;
0663:
0664:                            return (index - 1);
0665:                        }
0666:                    }
0667:
0668:                    // We assign bounds to the item, which is its pixel location,
0669:                    // width, and height in coordinates which represent offsets
0670:                    // of the viewport origin (that is, are in the viewport
0671:                    // coordinate space)
0672:                    itemLFs[index].lSetSize(pW, pH);
0673:                    itemLFs[index].lSetLocation(sizingBox[X], sizingBox[Y]);
0674:
0675:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0676:                        Logging.report(Logging.INFORMATION,
0677:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0678:                                "[F] index (" + index + " lineHeight == "
0679:                                        + lineHeight + ") set height to:" + pH);
0680:                    }
0681:
0682:                    itemLFs[index].actualBoundsInvalid[X] = false;
0683:                    itemLFs[index].actualBoundsInvalid[Y] = false;
0684:                    itemLFs[index].actualBoundsInvalid[WIDTH] = false;
0685:                    itemLFs[index].actualBoundsInvalid[HEIGHT] = false;
0686:
0687:                    // If this Item is currently the tallest on the line, its
0688:                    // height becomes our prevailing lineheight
0689:                    if (pH > lineHeight) {
0690:                        lineHeight = pH;
0691:                    }
0692:
0693:                    // We whittle down the sizingBox by the Item's dimensions,
0694:                    // effectively maintaining how much space is left for the
0695:                    // remaining Items, if the item has some positive width
0696:                    if (pW > 0) {
0697:                        sizingBox[WIDTH] -= pW;
0698:                        // we know that item fits on this row but padding
0699:                        // might not fit
0700:                        if (sizingBox[WIDTH] < 0) {
0701:                            sizingBox[WIDTH] = 0;
0702:                        }
0703:                        sizingBox[X] += pW;
0704:                    }
0705:
0706:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0707:                        Logging.report(Logging.INFORMATION,
0708:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0709:                                "\t\tindex: " + index + "\t["
0710:                                        + itemLFs[index].bounds[X] + ","
0711:                                        + itemLFs[index].bounds[Y] + ","
0712:                                        + itemLFs[index].bounds[WIDTH] + ","
0713:                                        + itemLFs[index].bounds[HEIGHT] + "]");
0714:                    }
0715:                } // for
0716:
0717:                // Before we quit, layout the last row we did in the loop
0718:                try {
0719:
0720:                    int oldRowHeight = itemLFs[rowStart].rowHeight;
0721:
0722:                    lineHeight = layoutRowHorizontal(rowStart, numOfLFs - 1,
0723:                            sizingBox[WIDTH], lineHeight, itemLFs);
0724:
0725:                    int rowY = itemLFs[rowStart].bounds[Y];
0726:
0727:                    layoutRowVertical(rowStart, numOfLFs - 1, lineHeight,
0728:                            itemLFs, numOfLFs);
0729:
0730:                    viewable[HEIGHT] = rowY + lineHeight;
0731:
0732:                } catch (Throwable t) {
0733:                    Display.handleThrowable(t);
0734:                }
0735:
0736:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0737:                    Logging.report(Logging.INFORMATION,
0738:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0739:                            " returning invalidIndex:" + invalidIndex + " }");
0740:                }
0741:
0742:                return invalidIndex;
0743:            }
0744:
0745:            /**
0746:             * Calculating how many pixels should the <pre>startIndex<> item move up
0747:             * or down, and loop from this item until the end, adding the delta
0748:             * to all these items.
0749:             * We know where this startIndex should be, we know where it is
0750:             * now, so we can know how much to move everything.
0751:             *
0752:             * The viewable height is updated accordingly.
0753:             *
0754:             * @param startIndex the index of the first item that should move
0755:             *                   up or down. It should be first in its row, 
0756:             *                   and the Item before it should be laid out 
0757:             *                   correctly, with rowHeight set up.
0758:             * @param itemLFs reference to the items array of the calling form
0759:             * @param numOfLFs number of elements in the calling form
0760:             * @param viewable area needed for the content of the form
0761:             */
0762:            private void updateVertically(int startIndex, ItemLFImpl[] itemLFs,
0763:                    int numOfLFs, int[] viewable) {
0764:
0765:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0766:                    Logging.report(Logging.INFORMATION,
0767:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0768:                            "### in updateVertically for #" + startIndex
0769:                                    + ".\t");
0770:                }
0771:
0772:                int deltaY = 0;
0773:                int newY = 0;
0774:                // loop on all the items, starting with this one, 
0775:                // updating their Y, and unmark their flag
0776:                if (startIndex == 0) {
0777:                    newY = 0;
0778:
0779:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0780:                        Logging.report(Logging.INFORMATION,
0781:                                LogChannels.LC_HIGHUI_FORM_LAYOUT, "newY="
0782:                                        + newY);
0783:                    }
0784:
0785:                } else {
0786:                    newY = itemLFs[startIndex - 1].bounds[Y]
0787:                            + itemLFs[startIndex - 1].rowHeight;
0788:
0789:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0790:                        Logging.report(Logging.INFORMATION,
0791:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0792:                                " itemLFs[si-1].bounds[Y]="
0793:                                        + itemLFs[startIndex - 1].bounds[Y]
0794:                                        + " itemLFs[si-1].rowHeight="
0795:                                        + itemLFs[startIndex - 1].rowHeight);
0796:                    }
0797:                }
0798:
0799:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0800:                    Logging.report(Logging.INFORMATION,
0801:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0802:                            ">>> CustomItemLFImpl -- lRepaint()"
0803:                                    + " itemLFs[si].bounds[Y]="
0804:                                    + itemLFs[startIndex].bounds[Y] + " newY="
0805:                                    + newY);
0806:                }
0807:
0808:                deltaY = newY - itemLFs[startIndex].bounds[Y];
0809:
0810:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0811:                    Logging.report(Logging.INFORMATION,
0812:                            LogChannels.LC_HIGHUI_FORM_LAYOUT, " delta= "
0813:                                    + deltaY);
0814:                }
0815:
0816:                if (deltaY == 0) {
0817:                    itemLFs[startIndex].actualBoundsInvalid[Y] = false;
0818:                    return;
0819:                }
0820:
0821:                for (int i = startIndex; i < numOfLFs; i++) {
0822:                    itemLFs[i].lMove(0, deltaY);
0823:                }
0824:
0825:                itemLFs[startIndex].actualBoundsInvalid[Y] = false;
0826:
0827:                // update viewable height        
0828:                viewable[HEIGHT] += deltaY;
0829:            }
0830:
0831:            /**
0832:             * After the contents of a row have been determined, layout the
0833:             * items on that row, taking into account the individual items'
0834:             * horizontally oriented layout directives.
0835:             *
0836:             * @param rowStart the index of the first row element
0837:             * @param rowEnd the index of the last row element
0838:             * @param hSpace the amount of empty space in pixels in this row before 
0839:             *               inflation
0840:             * @param rowHeight the old row height
0841:             * @param itemLFs reference to the items array of the calling form
0842:             *
0843:             * @return the new rowHeight for this row after all of the inflations
0844:             */
0845:            private int layoutRowHorizontal(int rowStart, int rowEnd,
0846:                    int hSpace, int rowHeight, ItemLFImpl[] itemLFs) {
0847:                // SYNC NOTE: protected by the lock around calls to layout()
0848:
0849:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0850:                    Logging.report(Logging.INFORMATION,
0851:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0852:                            "[F] layoutRowHorizontal -- rowStart=" + rowStart
0853:                                    + " rowEnd=" + rowEnd + " hSpace=" + hSpace
0854:                                    + " rowHeight=" + rowHeight);
0855:                }
0856:
0857:                hSpace = inflateHShrinkables(rowStart, rowEnd, hSpace, itemLFs);
0858:                hSpace = inflateHExpandables(rowStart, rowEnd, hSpace, itemLFs);
0859:
0860:                // if any of the items were inflated we have to recalculate
0861:                // the new row height for this row
0862:                rowHeight = 0;
0863:                for (int i = rowStart; i <= rowEnd; i++) {
0864:                    if (rowHeight < itemLFs[i].bounds[HEIGHT]) {
0865:                        rowHeight = itemLFs[i].bounds[HEIGHT];
0866:                    }
0867:                }
0868:
0869:                if (hSpace == 0) {
0870:
0871:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0872:                        Logging.report(Logging.INFORMATION,
0873:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0874:                                "[F] layoutRowHorizontal -- done -- "
0875:                                        + "(hSpace == 0) -- returning "
0876:                                        + rowHeight);
0877:                    }
0878:                    return rowHeight;
0879:                }
0880:
0881:                int curAlignment = getCurHorAlignment(itemLFs, rowStart);
0882:
0883:                switch (curAlignment) {
0884:                case Item.LAYOUT_CENTER:
0885:                    hSpace = hSpace / 2;
0886:                    /* fall through */
0887:                case Item.LAYOUT_RIGHT:
0888:                    for (; rowStart <= rowEnd; rowStart++) {
0889:                        itemLFs[rowEnd].lMove(hSpace, 0);
0890:                    }
0891:                    break;
0892:
0893:                case Item.LAYOUT_LEFT:
0894:                default:
0895:                    break;
0896:                }
0897:
0898:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0899:                    Logging.report(Logging.INFORMATION,
0900:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0901:                            "[F] layoutRowHorizontal -- done "
0902:                                    + "-- returning " + rowHeight);
0903:                }
0904:
0905:                return rowHeight;
0906:
0907:            }
0908:
0909:            /**
0910:             * Gets the current horizontal alignment of the item. If Item's
0911:             * horizontal layout bits are not set its current horizontal
0912:             * alignment is the same as of the previous Item.
0913:             * 
0914:             * @param itemLFs reference to the items array of the calling form
0915:             * @param index the index of an item in the itemLFs array which 
0916:             *        current horizontal alignment needs to be found out
0917:             * @return currentl horizontal alignment of an Item with passed in 
0918:             *         index
0919:             */
0920:            private int getCurHorAlignment(ItemLFImpl[] itemLFs, int index) {
0921:                for (int hAlign, i = index; i >= 0; i--) {
0922:                    hAlign = itemLFs[i].getLayout() & LAYOUT_HMASK;
0923:
0924:                    if (hAlign == 0) {
0925:                        continue;
0926:                    }
0927:                    return hAlign;
0928:                }
0929:
0930:                // default layout is LAYOUT_LEFT
0931:                return Item.LAYOUT_LEFT;
0932:            }
0933:
0934:            /**
0935:             * Inflate all the horizontally 'shrinkable' items on a row.
0936:             *
0937:             * @param rowStart the index of the first row element
0938:             * @param rowEnd the index of the last row element
0939:             * @param space the amount of empty space left in pixels in this row
0940:             * @param itemLFs reference to the items array of the calling form
0941:             *
0942:             * @return the amount of empty space on this row after shinkage
0943:             */
0944:            private int inflateHShrinkables(int rowStart, int rowEnd,
0945:                    int space, ItemLFImpl[] itemLFs) {
0946:                // SYNC NOTE: protected by the lock around calls to layout()
0947:
0948:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0949:                    Logging.report(Logging.INFORMATION,
0950:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
0951:                            "[F] inflateHShrinkables -- rowStart=" + rowStart
0952:                                    + " rowEnd=" + rowEnd + " space=" + space);
0953:                }
0954:
0955:                if (space == 0) {
0956:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0957:                        Logging.report(Logging.INFORMATION,
0958:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
0959:                                "[F] inflateHShrinkables -- returning "
0960:                                        + "(space == 0)");
0961:                    }
0962:                    return 0;
0963:                }
0964:
0965:                // To inflate shrinkables, we make a first pass gathering
0966:                // the smallest proportion (the baseline)
0967:                int baseline = Integer.MAX_VALUE;
0968:                int pW, prop = 0;
0969:
0970:                for (int i = rowStart; i <= rowEnd; i++) {
0971:                    if (itemLFs[i].shouldHShrink()) {
0972:                        pW = itemLFs[i].lGetLockedWidth();
0973:                        if (pW == -1) {
0974:                            pW = itemLFs[i]
0975:                                    .lGetAdornedPreferredWidth(itemLFs[i]
0976:                                            .lGetLockedHeight());
0977:                        }
0978:                        prop = pW - itemLFs[i].lGetAdornedMinimumWidth();
0979:                        if (prop > 0 && prop < baseline) {
0980:                            baseline = prop;
0981:                        }
0982:                    }
0983:                }
0984:
0985:                // If there are no shrinkables, return
0986:                if (baseline == Integer.MAX_VALUE) {
0987:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0988:                        Logging
0989:                                .report(
0990:                                        Logging.INFORMATION,
0991:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
0992:                                        "[F] inflateHShrinkables -- returning "
0993:                                                + "(baseline == Integer.MAX_VALUE) space == "
0994:                                                + space);
0995:                    }
0996:                    return space;
0997:                }
0998:
0999:                prop = 0;
1000:
1001:                // Now we loop again, adding up all the proportions so
1002:                // we can find the adder
1003:                for (int i = rowStart; i <= rowEnd; i++) {
1004:                    if (itemLFs[i].shouldHShrink()) {
1005:                        pW = itemLFs[i].lGetLockedWidth();
1006:                        if (pW == -1) {
1007:                            pW = itemLFs[i]
1008:                                    .lGetAdornedPreferredWidth(itemLFs[i]
1009:                                            .lGetLockedHeight());
1010:                        }
1011:                        prop += ((pW - itemLFs[i].lGetAdornedMinimumWidth()) / baseline);
1012:                    }
1013:                }
1014:
1015:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1016:                    Logging.report(Logging.INFORMATION,
1017:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
1018:                            "[F] inflateHShrinkables -- prop == " + prop);
1019:                }
1020:
1021:                // Now we compute the adder, and add it to each of the
1022:                // shrinkables, times its proportion
1023:                int adder = space / prop;
1024:
1025:                for (int i = rowStart; i <= rowEnd; i++) {
1026:                    if (itemLFs[i].shouldHShrink()) {
1027:
1028:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1029:                            Logging.report(Logging.INFORMATION,
1030:                                    LogChannels.LC_HIGHUI_FORM_LAYOUT,
1031:                                    "### item " + i + " before shrinking is:"
1032:                                            + itemLFs[i].bounds[WIDTH]);
1033:                        }
1034:
1035:                        pW = itemLFs[i].lGetLockedWidth();
1036:                        if (pW == -1) {
1037:                            pW = itemLFs[i]
1038:                                    .lGetAdornedPreferredWidth(itemLFs[i]
1039:                                            .lGetLockedHeight());
1040:                        }
1041:                        space = pW - itemLFs[i].lGetAdornedMinimumWidth();
1042:
1043:                        // The proportionate amount of space to add
1044:                        prop = adder * (space / baseline);
1045:
1046:                        // We only enlarge the item to its preferred width at
1047:                        // a maximum
1048:                        if (space > prop) {
1049:                            space = prop;
1050:                        }
1051:                        itemLFs[i].lSetSize(itemLFs[i].bounds[WIDTH] + space,
1052:                                getItemHeight(i, itemLFs[i].bounds[WIDTH]
1053:                                        + space, itemLFs));
1054:
1055:                        // Now we have to shift the rest of the elements on the line
1056:                        for (int j = i + 1; j <= rowEnd; j++) {
1057:                            itemLFs[j].lMove(space, 0);
1058:                        }
1059:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1060:                            Logging.report(Logging.INFORMATION,
1061:                                    LogChannels.LC_HIGHUI_FORM_LAYOUT,
1062:                                    "### item " + i + " shrank to:"
1063:                                            + itemLFs[i].bounds[WIDTH]);
1064:                        }
1065:                    }
1066:                }
1067:
1068:                space = viewportWidth
1069:                        - (itemLFs[rowEnd].bounds[X] + itemLFs[rowEnd].bounds[WIDTH]);
1070:
1071:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1072:                    Logging.report(Logging.INFORMATION,
1073:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
1074:                            "[F] inflateHShrinkables -- "
1075:                                    + "returning (end). space == " + space);
1076:                }
1077:
1078:                return space;
1079:            }
1080:
1081:            /**
1082:             * Inflate all the horizontally 'expandable' items on a row.
1083:             *
1084:             * @param rowStart the index of the first row element
1085:             * @param rowEnd the index of the last row element
1086:             * @param space the amount of empty space on this row
1087:             * @param itemLFs reference to the items array of the calling form
1088:             *
1089:             * @return the amount of empty space after expansion
1090:             */
1091:            private int inflateHExpandables(int rowStart, int rowEnd,
1092:                    int space, ItemLFImpl[] itemLFs) {
1093:                // SYNC NOTE: protected by the lock around calls to layout()
1094:
1095:                if (space == 0) {
1096:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1097:                        Logging.report(Logging.INFORMATION,
1098:                                LogChannels.LC_HIGHUI_FORM_LAYOUT,
1099:                                "[F] inflateHExpandables -- "
1100:                                        + "returning (space == 0)");
1101:                    }
1102:                    return 0;
1103:                }
1104:
1105:                int numExp = 0;
1106:                // We first loop through and count the expandables
1107:                for (int i = rowStart; i <= rowEnd; i++) {
1108:                    if (itemLFs[i].shouldHExpand()) {
1109:                        numExp++;
1110:                    }
1111:                }
1112:
1113:                if (numExp == 0 || space < numExp) {
1114:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1115:                        Logging
1116:                                .report(
1117:                                        Logging.INFORMATION,
1118:                                        LogChannels.LC_HIGHUI_FORM_LAYOUT,
1119:                                        "[F] inflateHExpandables -- returning "
1120:                                                + "(numExp == 0 || space < numExp) space = "
1121:                                                + space);
1122:                    }
1123:                    return space;
1124:                }
1125:
1126:                space = space / numExp;
1127:
1128:                // We then add the same amount to each Expandable
1129:                for (int i = rowStart; i <= rowEnd; i++) {
1130:                    if (itemLFs[i].shouldHExpand()) {
1131:                        itemLFs[i].lSetSize(itemLFs[i].bounds[WIDTH] + space,
1132:                                getItemHeight(i, itemLFs[i].bounds[WIDTH]
1133:                                        + space, itemLFs));
1134:
1135:                        // We right shift each subsequent item on the row
1136:                        for (int j = i + 1; j <= rowEnd; j++) {
1137:                            itemLFs[j].lMove(space, 0);
1138:                        }
1139:                    }
1140:                }
1141:
1142:                space = viewportWidth
1143:                        - (itemLFs[rowEnd].bounds[X] + itemLFs[rowEnd].bounds[WIDTH]);
1144:
1145:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1146:                    Logging.report(Logging.INFORMATION,
1147:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
1148:                            "[F] inflateHExpandables -- "
1149:                                    + "returning (end) space = " + space);
1150:                }
1151:
1152:                return space;
1153:            }
1154:
1155:            /**
1156:             * After the contents of a row have been determined, layout the
1157:             * items on that row, taking into account the individual items'
1158:             * vertically oriented layout directives.
1159:             *
1160:             * @param rowStart the index of the first row element
1161:             * @param rowEnd the index of the last row element
1162:             * @param itemLFs reference to the items array of the calling form
1163:             * @param lineHeight the overall height in pixels of the line
1164:             * @param numOfLFs number of elements in the calling form
1165:             */
1166:            private void layoutRowVertical(int rowStart, int rowEnd,
1167:                    int lineHeight, ItemLFImpl[] itemLFs, int numOfLFs) {
1168:                // SYNC NOTE: protected by the lock around calls to layout()
1169:
1170:                int space = 0;
1171:                int pH = 0;
1172:
1173:                for (int i = rowStart; i <= rowEnd; i++) {
1174:
1175:                    // set the row height
1176:                    itemLFs[i].rowHeight = lineHeight;
1177:
1178:                    // Items that have the LAYOUT_VSHRINK  directive are expanded 
1179:                    // to their preferred height or to the height of the row, 
1180:                    // whichever is smaller. Items that are still shorter than 
1181:                    // the row height and that have the LAYOUT_VEXPAND directive 
1182:                    // will expand to the height of the row.
1183:                    if (itemLFs[i].shouldVExpand()) {
1184:                        itemLFs[i].lSetSize(itemLFs[i].bounds[WIDTH],
1185:                                lineHeight);
1186:
1187:                    } else if (itemLFs[i].shouldVShrink()) {
1188:                        pH = itemLFs[i].lGetLockedHeight();
1189:                        if (pH == -1) {
1190:                            pH = itemLFs[i]
1191:                                    .lGetAdornedPreferredHeight(itemLFs[i].bounds[WIDTH]);
1192:                        }
1193:                        if (pH > lineHeight) {
1194:                            pH = lineHeight;
1195:                        }
1196:                        itemLFs[i].lSetSize(itemLFs[i].bounds[WIDTH], pH);
1197:                    }
1198:
1199:                    // initially the items are aligned at the top so we simply
1200:                    // add on to the height
1201:                    switch (itemLFs[i].getLayout() & LAYOUT_VMASK) {
1202:                    case Item.LAYOUT_VCENTER:
1203:                        space = lineHeight - itemLFs[i].bounds[HEIGHT];
1204:                        if (space > 0) {
1205:                            itemLFs[i].lMove(0, space / 2);
1206:                        }
1207:                        break;
1208:                    case Item.LAYOUT_TOP:
1209:                        // it's already there...
1210:                        break;
1211:                    case Item.LAYOUT_BOTTOM:
1212:                        // the layout algorithm must align the Items along the bottom
1213:                        // if there is no vertical directive specified.
1214:                    default:
1215:                        space = lineHeight - itemLFs[i].bounds[HEIGHT];
1216:                        if (space > 0) {
1217:                            itemLFs[i].lMove(0, space);
1218:                        }
1219:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1220:                            Logging.report(Logging.INFORMATION,
1221:                                    LogChannels.LC_HIGHUI_FORM_LAYOUT,
1222:                                    "Default V layout -- space = " + space
1223:                                            + " itemLFs[i].Y = "
1224:                                            + itemLFs[i].bounds[Y]);
1225:                        }
1226:                    }
1227:                }
1228:
1229:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1230:                    Logging.report(Logging.INFORMATION,
1231:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
1232:                            "[F] layoutRowVertical -- done");
1233:                }
1234:
1235:            }
1236:
1237:            /**
1238:             * This method checks if we need a new line due to change in 
1239:             * horizontal alignment. If horizontal alignment is not set on 
1240:             * <code>Item</code> with index thisItem then current horizontal 
1241:             * alignment is not changed and no row break is needed.
1242:             *
1243:             * @param curAlignment current horizontal alignment until this Item
1244:             * @param thisItem index of the <code>Item</code> from which to start 
1245:             *                 the scan
1246:             * @param itemLFs reference to the items array of the calling form
1247:             *
1248:             * @return <code>true</code> if a new line is needed
1249:             */
1250:            private boolean isImplicitLineBreak(int curAlignment, int this Item,
1251:                    ItemLFImpl[] itemLFs) {
1252:
1253:                if (this Item == 0) {
1254:                    return false;
1255:                }
1256:
1257:                int hAlign = itemLFs[this Item].getLayout() & LAYOUT_HMASK;
1258:
1259:                // alignment is not changed
1260:                if (hAlign == 0) {
1261:                    return false;
1262:                }
1263:
1264:                return (hAlign != curAlignment);
1265:            }
1266:
1267:            /**
1268:             * Get item's height based on the width.
1269:             *
1270:             * @param index the index of the item which height is being calculated 
1271:             * @param pW the width set for the item
1272:             * @param itemLFs reference to the items array of the calling form
1273:             *
1274:             * @return the height of the item
1275:             */
1276:            private int getItemHeight(int index, int pW, ItemLFImpl[] itemLFs) {
1277:                // SYNC NOTE: protected by the lock around calls to layout()
1278:
1279:                int pH;
1280:
1281:                // If the Item can be shrunken, we use its minimum height,
1282:                // and its preferred height if it is not
1283:                if (itemLFs[index].shouldVShrink()) {
1284:                    pH = itemLFs[index].lGetAdornedMinimumHeight();
1285:                } else {
1286:                    pH = itemLFs[index].lGetLockedHeight();
1287:                    if (pH == -1) {
1288:                        pH = itemLFs[index].lGetAdornedPreferredHeight(pW);
1289:                    }
1290:                }
1291:
1292:                // If we can't scroll vertically, clip the item's height
1293:                // if it can't fit in the view. We would also enforce a
1294:                // notion of a "maximum vertical height" here if we had one
1295:                if (!Constants.SCROLLS_VERTICAL && pH > viewportHeight) {
1296:                    pH = viewportHeight;
1297:                }
1298:
1299:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1300:                    Logging.report(Logging.INFORMATION,
1301:                            LogChannels.LC_HIGHUI_FORM_LAYOUT,
1302:                            " LayoutManager- getItemHeight(" + index + "," + pW
1303:                                    + ") returns " + pH);
1304:                }
1305:
1306:                return pH;
1307:            }
1308:
1309:            /**
1310:             * Singleton design pattern: obtain access to the single instance of
1311:             * this class using this method.
1312:             *
1313:             * @return Single instance of LayoutManager
1314:             */
1315:            static LayoutManager instance() {
1316:                return singleInstance;
1317:            }
1318:
1319:            /** 
1320:             * A bit mask to capture the horizontal layout directive of an item.
1321:             */
1322:            static final int LAYOUT_HMASK = 0x03;
1323:
1324:            /** 
1325:             * A bit mask to capture the vertical layout directive of an item. 
1326:             */
1327:            static final int LAYOUT_VMASK = 0x30;
1328:
1329:            /**
1330:             * 'sizingBox' is a [x,y,w,h] array used for dynamic sizing of 
1331:             * <code>Item</code>s during the layout. It starts with the size of the 
1332:             * viewport, but can shrink or grow according to the <code>Item</code> 
1333:             * it tries to lay out.
1334:             *
1335:             * It is used by layoutBlock and layoutRow.
1336:             */
1337:            private int[] sizingBox;
1338:
1339:            /** Do a full layout. */
1340:            final static int FULL_LAYOUT = -1;
1341:
1342:            /** Only update layout. */
1343:            final static int UPDATE_LAYOUT = -2;
1344:
1345:            /**
1346:             * Single instance of the LayoutManager class.
1347:             */
1348:            static LayoutManager singleInstance = new LayoutManager();
1349:
1350:            /** Used as an index into the viewport[], for the x origin. */
1351:            final static int X = DisplayableLFImpl.X;
1352:
1353:            /** Used as an index into the viewport[], for the y origin. */
1354:            final static int Y = DisplayableLFImpl.Y;
1355:
1356:            /** Used as an index into the viewport[], for the width. */
1357:            final static int WIDTH = DisplayableLFImpl.WIDTH;
1358:
1359:            /** Used as an index into the viewport[], for the height. */
1360:            final static int HEIGHT = DisplayableLFImpl.HEIGHT;
1361:
1362:            /** Width of viewport, as passed to layout(). */
1363:            int viewportWidth = 0;
1364:
1365:            /** Height of viewport, as passed to layout(). */
1366:            int viewportHeight = 0;
1367:
1368:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.