/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package javax.microedition.lcdui;
import java.util.Vector;
/**
* Class which represents one row in the Form.
*/
class Row
{
private Vector layoutObjects = new Vector();
private int xShift;
private int yShift;
private int rowHeight;
private int rowWidth;
private int occupiedSpace;
private int rowHLayout;
/**
* Constructor.
*
* @param rowWidth - total row width.
* @param hLayout horizontal layout
*/
Row(int rowWidth, int hLayout)
{
this.rowWidth = rowWidth;
setRowHLayout(hLayout);
}
/**
* Add new LayoutObject to the Row.
*
* @param layoutObj structure which represents Item or part Of Item.
*/
void addLayoutObject(final LayoutObject layoutObj)
{
ESWTUIThreadRunner.syncExec(new Runnable()
{
public void run()
{
eswtAddLayoutObject(layoutObj);
}
});
}
/**
* eSWT specific calls to implement addLayoutObject.
*
* @param lo structure which represents Item or part Of Item.
*/
void eswtAddLayoutObject(LayoutObject lo)
{
layoutObjects.addElement(lo);
// update actual occupiedSpace
occupiedSpace += lo.getWidth();
// update rowHeight
rowHeight = Math.max(rowHeight, lo.getHeight());
}
/**
* Get the number of items with the given layout.
*/
int getNumLayoutObjects(int layoutMask)
{
int ret = 0;
int num = layoutObjects.size();
LayoutObject lo = null;
for(int i = 0; i < num; i++)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
if(lo.getOwningItem().hasLayout(layoutMask))
{
ret++;
}
}
return ret;
}
/**
* Get available space in the Row for layout calculation.
*
* @return space available for Items on that Row in pixels.
*/
int getFreeSpace()
{
return getFreeSpace(Item.LAYOUT_SHRINK | Item.LAYOUT_EXPAND);
}
/**
* Get free space based on LAYOUT mask. Item matching the layout mask will
* be counted with their layouting size (not actual size). Used for LAYOUT_2
* row resizing.
*
* @param layoutMask layout mask
*/
int getFreeSpace(int layoutMask)
{
int ret = 0;
int num = layoutObjects.size();
LayoutObject lo = null;
for(int i = 0; i < num; i++)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
ret += getObjectWidth(lo, layoutMask);
}
return rowWidth - ret;
}
/**
* Get row height based on LAYOUT mask. Item matching the layout mask will
* be counted with their layouting size (not actual size). Used for LAYOUT_2
* row resizing.
*
* @param layoutMask layout mask
*/
int getRowHeight(int layoutMask)
{
int ret = 0;
int num = layoutObjects.size();
LayoutObject lo = null;
for(int i = 0; i < num; i++)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
ret = Math.max(ret, getObjectHeight(lo, layoutMask));
}
return ret;
}
private int getObjectWidth(LayoutObject lo, int layoutMask)
{
if(lo.getOwningItem().hasLayout(layoutMask))
{
// this returns the min/pref width
return lo.getOwningItem().getLayoutWidth();
}
else
{
return lo.getWidth();
}
}
private int getObjectHeight(LayoutObject lo, int layoutMask)
{
if(lo.getOwningItem().hasLayout(layoutMask))
{
// this returns the min/pref width
return lo.getOwningItem().getLayoutHeight();
}
else
{
return lo.getHeight();
}
}
/**
* Clean row, free resources.
*
* @param keepItem Last Item to leave in a row.
*/
boolean cleanRow(Item keepItem)
{
LayoutObject lo = null;
for(int i = (layoutObjects.size() - 1); i >= 0; i--)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
if(keepItem != null && keepItem == lo.getOwningItem())
{
updateRowInternals();
return true;
}
else
{
layoutObjects.removeElement(lo);
lo.dispose();
}
}
updateRowInternals();
return false;
}
/**
* Update item positions in a row.<br>
* This method called by Layouters or FormLayoutPolicy when row is full and
* ready for layout.
*/
void updateRowLayout(boolean isLeftToRight)
{
// update xShift
xShift = ItemLayouter.getXLocation(rowWidth, occupiedSpace, rowHLayout);
int xDelta = 0;
LayoutObject lo = null;
if(isLeftToRight)
{
for(int i = 0; i < layoutObjects.size(); i++)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
int yDelta = ItemLayouter.getYLocation(rowHeight,
lo.getHeight(), lo.getVerticalLayout());
lo.eswtSetLocation(xShift + xDelta, yShift + yDelta);
xDelta += lo.getWidth();
}
}
else
{
for(int i = layoutObjects.size() - 1; i > 0; i--)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
int yDelta = ItemLayouter.getYLocation(rowHeight,
lo.getHeight(), lo.getVerticalLayout());
lo.eswtSetLocation(xShift + xDelta, yShift + yDelta);
xDelta += lo.getWidth();
}
}
}
/**
* Update width and height of a row if some layout objects were removed or
* changed.
*/
void updateRowInternals()
{
int newRowHeight = 0;
int newOccupiedSpace = 0;
int num = layoutObjects.size();
LayoutObject lo = null;
for(int i = 0; i < num; i++)
{
lo = (LayoutObject) layoutObjects.elementAt(i);
newRowHeight = Math.max(newRowHeight, lo.getHeight());
newOccupiedSpace += lo.getWidth();
}
rowHeight = newRowHeight;
occupiedSpace = newOccupiedSpace;
}
/**
* Set the yShift to corresponding in ScrolledComposite which represents
* Form.
*
* @param aYShift yPosition of the row inside ScrolledComposite
*/
void setYShift(int aYShift)
{
yShift = aYShift;
}
/**
* Get the yPosition of a Row inside of ScrolledComposite.
*
* @return yShift in pixels
*/
int getYShift()
{
return yShift;
}
/**
* Gets the width of the row in pixels.
*
* @return - row's total width.
*/
int getRowWidth()
{
return rowWidth;
}
/**
* Get the height of a row in pixels (height of tallest item).
*
* @return height of a row;
*/
int getRowHeight()
{
return rowHeight;
}
/**
* Get the bottom (yPosition + rowHeight) of a Row .
*/
int getBottomPosition()
{
return yShift + rowHeight;
}
/**
* Get the yPosition of a Row's height inside of ScrolledComposite.
*
* @param yPosition the y position
* @return yShift + rowHeight in pixels
*/
boolean isInsideRow(int yPosition)
{
return (yShift <= yPosition && yPosition < yShift + rowHeight);
}
/**
* set new horizontal Layout of a row.
*
* @param aRowHLayout - set new horizontal of the row.
*/
void setRowHLayout(int aRowHLayout)
{
rowHLayout = aRowHLayout;
}
/**
* Get horizontal Layout of row.
*
* @return horizontal Layout of a row;
*/
int getRowHLayout()
{
return rowHLayout;
}
boolean isEmpty()
{
return ((occupiedSpace == 0) && (layoutObjects.size() == 0));
}
LayoutObject getNextLayoutObject(LayoutObject lo, Item item)
{
int startIdx = layoutObjects.indexOf(lo);
startIdx = (startIdx < 0 ? 0 : startIdx + 1);
int num = layoutObjects.size();
LayoutObject temp = null;
for(int i = startIdx; i < num; i++)
{
temp = getLayoutObject(i);
if(item == null || item == temp.getOwningItem())
{
return temp;
}
}
return null;
}
LayoutObject getPrevLayoutObject(LayoutObject lo, Item item)
{
int startIdx = layoutObjects.indexOf(lo);
startIdx = (startIdx < 0 ? layoutObjects.size() - 1 : startIdx - 1);
LayoutObject temp = null;
for(int i = startIdx; i >= 0; i--)
{
temp = getLayoutObject(i);
if(item == null || item == temp.getOwningItem())
{
return temp;
}
}
return null;
}
LayoutObject getNextLayoutObject(LayoutObject lo, int layoutMask)
{
int startIdx = layoutObjects.indexOf(lo);
startIdx = (startIdx < 0 ? 0 : startIdx + 1);
int num = layoutObjects.size();
LayoutObject temp = null;
for(int i = startIdx; i < num; i++)
{
temp = getLayoutObject(i);
if(temp.getOwningItem().hasLayout(layoutMask))
{
return temp;
}
}
return null;
}
LayoutObject getLayoutObject(int index)
{
return (LayoutObject) layoutObjects.elementAt(index);
}
int size()
{
return layoutObjects.size();
}
}