📄 containerview.java
字号:
//#condition polish.usePolishGui/* * Created on Oct 27, 2004 at 7:03:40 PM. * * Copyright (c) 2004-2005 Robert Virkus / Enough Software * * This file is part of J2ME Polish. * * J2ME Polish is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * J2ME Polish is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with J2ME Polish; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Commercial licenses are also available, please * refer to the accompanying LICENSE.txt or visit * http://www.j2mepolish.org for details. */package de.enough.polish.ui;import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Graphics;import de.enough.polish.util.ArrayList;import de.enough.polish.util.TextUtil;/** * <p>Is responsible for visual representation and interpretation of user-input.</p> * <p>Copyright Enough Software 2004, 2005</p> * <pre> * history * Oct 27, 2004 - rob creation * </pre> * @author Robert Virkus, robert@enough.de */public class ContainerView { //#if polish.css.columns || polish.useTable //#define tmp.useTable //#ifdef polish.css.columns-width.star private int starIndex; //#endif //#endif private static final int NO_COLUMNS = 0; private static final int EQUAL_WIDTH_COLUMNS = 1; private static final int NORMAL_WIDTH_COLUMNS = 2; private static final int STATIC_WIDTH_COLUMNS = 3; protected int yOffset; protected int contentWidth; protected int contentHeight; protected int focusedIndex = -1; /** this field is set automatically, so that subclasses can use it for referencing the parent-container */ protected Container parentContainer; /** determines whether any animation of this view should be (re) started at the next possibility. this is set to "true" in each showNotify() method. */ protected boolean restartAnimation; protected int paddingVertical; protected int paddingHorizontal; protected int layout; protected boolean focusFirstElement; protected int appearanceMode; protected boolean isFocused; protected Item focusedItem; // table support: protected int columnsSetting = NO_COLUMNS; protected int numberOfColumns; protected int[] columnsWidths; protected int[] rowsHeights; protected int numberOfRows; protected boolean isLayoutCenter; protected boolean isLayoutRight; protected boolean allowCycling = true; //#if polish.css.view-type-left-x-offset protected int leftXOffset; //#endif //#if polish.css.view-type-right-x-offset protected int rightXOffset; //#endif //#if polish.css.view-type-top-y-offset protected int topYOffset; //#endif /** * Creates a new view */ protected ContainerView() { super(); } /** * Initialises this item. * The implementation needs to calculate and set the contentWidth and * contentHeight fields. * The style of the focused item has already been set. * * @param parent the Container which uses this view, use parent.getItems() for retrieving all items. * @param firstLineWidth the maximum width of the first line * @param lineWidth the maximum width of any following lines * @see #contentWidth * @see #contentHeight */ protected void initContent( Container parent, int firstLineWidth, int lineWidth ) { //#debug System.out.println("ContainerView: intialising content for " + this + " with vertical-padding " + this.paddingVertical ); //#if polish.Container.allowCycling != false this.allowCycling = parent.allowCycling; if (parent.parent == null || ( (parent.parent instanceof Container) && ((Container)parent.parent).getItems().length>1) ) { this.allowCycling = false; } //#endif //#if polish.css.view-type-left-x-offset lineWidth -= this.leftXOffset; //#endif //#if polish.css.view-type-right-x-offset lineWidth -= this.rightXOffset; //#endif this.parentContainer = parent; Item[] myItems = parent.items; //#ifdef tmp.useTable if (this.columnsSetting == NO_COLUMNS || myItems.length <= 1) { //#endif // look at the layout of the parentContainer, since the SHRINK layout can be set outside of the setStyle method as well: boolean isLayoutShrink = (this.parentContainer.layout & Item.LAYOUT_SHRINK) == Item.LAYOUT_SHRINK; int myContentWidth = 0; int myContentHeight = 0; boolean hasFocusableItem = false; for (int i = 0; i < myItems.length; i++) { Item item = myItems[i]; //System.out.println("initalising " + item.getClass().getName() + ":" + i); int width = item.getItemWidth( firstLineWidth, lineWidth ); int height = item.getItemHeight( firstLineWidth, lineWidth ); // now the item should have a style, so it can be safely focused // without loosing the style information: if (item.appearanceMode != Item.PLAIN) { hasFocusableItem = true; } if (isLayoutShrink && i == this.focusedIndex) { width = 0; } if (width > myContentWidth) { myContentWidth = width; } item.yTopPos = myContentHeight; item.yBottomPos = myContentHeight + item.itemHeight; myContentHeight += height + this.paddingVertical; } if (hasFocusableItem) { this.appearanceMode = Item.INTERACTIVE; if (isLayoutShrink && this.focusedItem != null) { Item item = this.focusedItem; //System.out.println("container has shrinking layout and contains focuse item " + item); item.isInitialised = false; boolean doExpand = item.isLayoutExpand; int width; if (doExpand) { item.isLayoutExpand = false; width = item.getItemWidth( lineWidth, lineWidth ); item.isInitialised = false; item.isLayoutExpand = true; } else { width = item.itemWidth; } if (width > myContentWidth) { myContentWidth = width; } } } else { this.appearanceMode = Item.PLAIN; } //#if polish.css.view-type-top-y-offset this.contentHeight = myContentHeight + this.topYOffset; //#else this.contentHeight = myContentHeight; //#endif this.contentWidth = myContentWidth; //System.out.println("ContainerView.initContent(): contentWidth=" + this.contentWidth ); return; //#ifdef tmp.useTable } //#endif //#ifdef tmp.useTable // columns are used boolean isNormalWidthColumns = (this.columnsSetting == NORMAL_WIDTH_COLUMNS); //#ifdef polish.css.columns-width.star if (this.columnsSetting == STATIC_WIDTH_COLUMNS) { if (this.starIndex != -1) { int combinedWidth = 0; for (int i = 0; i < this.numberOfColumns; i++) { combinedWidth += this.columnsWidths[i]; } this.columnsWidths[this.starIndex] = lineWidth - combinedWidth; } } else { //#else //# if (this.columnsSetting != STATIC_WIDTH_COLUMNS) { //#endif int availableColumnWidth; if (isNormalWidthColumns) { // this.columnsSetting == NORMAL_WIDTH_COLUMNS // each column should use as much space as it can use // without ousting the other columns // (the calculation will be finished below) availableColumnWidth = lineWidth - ((this.numberOfColumns -1) * this.paddingHorizontal); } else { // each column should take an equal share availableColumnWidth = (lineWidth - ((this.numberOfColumns -1) * this.paddingHorizontal)) / this.numberOfColumns; } //System.out.println("available column width: " + availableColumnWidth ); this.columnsWidths = new int[ this.numberOfColumns ]; for (int i = 0; i < this.numberOfColumns; i++) { this.columnsWidths[i] = availableColumnWidth; } } //#if polish.css.colspan ArrayList rowHeightsList = new ArrayList( (myItems.length / this.numberOfColumns) + (myItems.length % 2) + 1 ); //#else this.numberOfRows = (myItems.length / this.numberOfColumns) + (myItems.length % 2); this.rowsHeights = new int[ this.numberOfRows ]; //#endif int maxRowHeight = 0; int columnIndex = 0; int rowIndex = 0; int[] maxColumnWidths = null; if (isNormalWidthColumns) { maxColumnWidths = new int[ this.numberOfColumns ]; } int maxWidth = 0; // important for "equal" columns-width int myContentHeight = 0; boolean hasFocusableItem = false; //System.out.println("starting init of " + myItems.length + " container items."); for (int i=0; i< myItems.length; i++) { Item item = myItems[i]; if (item.appearanceMode != Item.PLAIN) { hasFocusableItem = true; } int availableWidth = this.columnsWidths[columnIndex]; //#if polish.css.colspan int itemColSpan = item.colSpan; if (!item.isInitialised && item.style != null) { Integer colSpanInt = item.style.getIntProperty("colspan"); if ( colSpanInt != null ) { itemColSpan = colSpanInt.intValue(); //System.out.println("colspan of item " + i + "/" + item + ", column " + columnIndex + ": " + itemColSpan); } } //System.out.println("ContainerView.init(): colspan of item " + i + "=" + itemColSpan); if (itemColSpan > 1) { // okay, this item stretched beyond one column, // so let's calculate the correct available cell width // and switch to the right column index: int maxColSpan = this.numberOfColumns - columnIndex; if (itemColSpan > maxColSpan) { //#debug error System.err.println("Warning: colspan " + itemColSpan + " is invalid at column " + columnIndex + " of a table with " + this.numberOfColumns + " columns, now using maximum possible value " + maxColSpan + "."); itemColSpan = maxColSpan; } // adjust the available width only when // each column has an equal size or when // the column widths are static, // otherwise the complete row width // is available anyhow: if (!isNormalWidthColumns) { if (itemColSpan == maxColSpan) { availableWidth = 0; for (int j = 0; j < columnIndex; j++) { availableWidth += this.paddingHorizontal + this.columnsWidths[j]; } availableWidth = lineWidth - availableWidth; } else { for (int j = columnIndex + 1; j < columnIndex + itemColSpan; j++) { availableWidth += this.paddingHorizontal + this.columnsWidths[j]; } } //System.out.println("ContainerView.init(): adjusted availableWidth for item " + i + ": " + availableWidth); } } //#endif //System.out.println( i + ": available with: " + availableWidth + ", item.isInitialized=" + item.isInitialised + ", itemWidth=" + item.getItemWidth( availableWidth, availableWidth )); if (item.isInitialised && item.itemWidth > availableWidth) { item.isInitialised = false; } int width = item.getItemWidth( availableWidth, availableWidth ); //System.out.println("got item width"); int height = item.getItemHeight( availableWidth, availableWidth ); if (height > maxRowHeight) { maxRowHeight = height; } //#if polish.css.colspan if (itemColSpan == 1) { //#endif if (isNormalWidthColumns && width > maxColumnWidths[columnIndex ]) { maxColumnWidths[ columnIndex ] = width; } if (width > maxWidth ) { maxWidth = width; } //#if polish.css.colspan } //#endif //#if polish.css.colspan if (item.colSpan != itemColSpan) { //#debug System.out.println("initializing new colspan of item " + i + "/" + item + ", column " + columnIndex + ": " + itemColSpan); item.colSpan = itemColSpan; item.isInitialised = false; } columnIndex += itemColSpan; //#else columnIndex++; //#endif item.yTopPos = myContentHeight; item.yBottomPos = myContentHeight + height; if (columnIndex == this.numberOfColumns) { //System.out.println("starting new row: rowIndex=" + rowIndex + " numberOfRows: " + numberOfRows); columnIndex = 0; //#if polish.css.colspan //System.out.println("ContainerView.init(): adding new row " + rowIndex + " with height " + maxRowHeight + ", contentHeight=" + myContentHeight + ", item " + i); rowHeightsList.add( new Integer( maxRowHeight ) ); //#else this.rowsHeights[rowIndex] = maxRowHeight; //#endif myContentHeight += maxRowHeight + this.paddingVertical; maxRowHeight = 0; rowIndex++; } } // for each item if (hasFocusableItem) { this.appearanceMode = Item.INTERACTIVE; } else { this.appearanceMode = Item.PLAIN; } if (columnIndex != 0) { // last row is not completely filled. //#if polish.css.colspan rowHeightsList.add( new Integer( maxRowHeight ) ); //#endif myContentHeight += maxRowHeight; } //#if polish.css.colspan this.numberOfRows = rowHeightsList.size(); //System.out.println("ContainerView.init(): numberOfRows=" + this.numberOfRows + ", rowIndex=" + rowIndex); this.rowsHeights = new int[ this.numberOfRows ]; for (int i = 0; i < this.numberOfRows; i++) { this.rowsHeights[i] = ((Integer) rowHeightsList.get(i)).intValue(); } //#endif // now save the worked out dimensions: if (isNormalWidthColumns) { // Each column should use up as much space as // needed in the "normal" columns-width mode. // Each column which takes less than available // the available-row-width / number-of-columns // can keep, but the others might need to be adjusted, // in case the complete width of the table is wider // than the allowed width. int availableRowWidth = lineWidth - ((this.numberOfColumns -1) * this.paddingHorizontal); int availableColumnWidth = availableRowWidth / this.numberOfColumns; int usedUpWidth = 0; int leftColumns = this.numberOfColumns; int completeWidth = 0; for (int i = 0; i < maxColumnWidths.length; i++) { int maxColumnWidth = maxColumnWidths[i]; if (maxColumnWidth <= availableColumnWidth) { usedUpWidth += maxColumnWidth; leftColumns--; } completeWidth += maxColumnWidth; } if (completeWidth <= availableRowWidth) { // okay, the table is fine just how it is this.columnsWidths = maxColumnWidths; } else { // okay, some columns need to be adjusted: // re-initialise the table: int leftAvailableColumnWidth = (availableRowWidth - usedUpWidth) / leftColumns; int[] newMaxColumnWidths = new int[ this.numberOfColumns ]; myContentHeight = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -