📄 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
extends ItemView
{
//#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 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 boolean focusFirstElement;
protected int appearanceMode;
protected Item focusedItem;
// table support:
protected int columnsSetting = NO_COLUMNS;
protected int numberOfColumns;
protected int[] columnsWidths;
protected int[] rowsHeights;
protected int numberOfRows;
// /**
// * the number of items - this information is used for rebuilding the table only when it is necessary
// * (number is changed or the columns-width is not static).
// */
// protected int numberOfItems;
// /** All items ordered within a table. Some cells can be null when colspan or rowspan CSS attributes are used. */
// protected Item[][] itemsTable;
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
/** indicates whether the parent Container is allowed to change the currently focused item
* when the user traverses around a form and enters the container from different sides
*/
protected boolean allowsAutoTraversal = true;
/**
* 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 parentContainerItem 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( Item parentContainerItem, int firstLineWidth, int lineWidth ) {
Container parent = (Container) parentContainerItem;
//#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.getItems();
//#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 );
if (item.appearanceMode != Item.PLAIN) {
hasFocusableItem = true;
}
if (isLayoutShrink && i == this.focusedIndex) {
width = 0;
}
if (width > myContentWidth) {
myContentWidth = width;
}
item.relativeY = myContentHeight;
item.relativeX = 0;
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.isInitialized = false;
boolean doExpand = item.isLayoutExpand;
int width;
if (doExpand) {
item.isLayoutExpand = false;
width = item.getItemWidth( lineWidth, lineWidth );
item.isInitialized = 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;
//# this.starIndex = -1;
//#debug
//# System.out.println("width of star column=" + (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;
int columnX = 0; // the horizontal position of the current column relative to the content's left corner (starting a 0)
//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.isInitialized && item.style != null) {
//# Integer colSpanInt = item.style.getIntProperty(106);
//# 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.isInitialized && item.itemWidth > availableWidth) {
item.isInitialized = 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.isInitialized = false;
//# }
//# columnIndex += itemColSpan;
//#else
columnIndex++;
//#endif
item.relativeY = myContentHeight;
item.relativeX = columnX; // when equal or normal column widths are used, this is below changed again, since the widhs are just calculated right now.
columnX += availableWidth;
if (columnIndex == this.numberOfColumns) {
//System.out.println("starting new row: rowIndex=" + rowIndex + " numberOfRows: " + numberOfRows);
columnIndex = 0;
columnX = 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:
columnX = 0;
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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -