/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.ui.layout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.whole.lang.ui.figures.IEntityFigure;
/**
* @author Riccardo Solmi
*/
public class TableRowLayout extends AbstractCompositeEntityLayout implements ITabularLayoutServer, ITabularLayoutClient {
{
withMinorAlignment(Alignment.MATHLINE);
}
private boolean rowInlining;
public TableRowLayout withRowInlining(boolean value) {
rowInlining = value;
return this;
}
@Override
public ITabularLayoutClient getTabularLayoutClient() {
return this;
}
@Override
public ITabularLayoutServer getTabularLayoutServer() {
return rowInlining ? this : null;
}
private ITabularLayoutServer myTabularLayoutServer;
public ITabularLayoutServer getMyTabularLayoutServer() {
if (myTabularLayoutServer == null) {
myTabularLayoutServer = new ITabularLayoutServer() {
public void invalidateTable() {
}
public int getColumnWidth(int columnIndex) {
return getPreferredColumnWith(columnIndex-getStartingCellIndex());
}
public int getColumnSpacingBefore(int columnIndex) {
return getPreferredColumnSpacingBefore(columnIndex-getStartingCellIndex());
}
public Alignment getColumnAlignment(int columnIndex) {
return Alignment.LEADING;
}
};
}
return myTabularLayoutServer;
}
public void updateMyTabularLayoutServer(IFigure container) {
IFigure parent = container.getParent();
ITabularLayoutServer tls = (parent instanceof IEntityFigure) ? ((IEntityFigure) parent).getTabularLayoutServer() : null;
if (tls != null)
myTabularLayoutServer = tls;
}
private int startingCellIndex;
public int getStartingCellIndex() {
return startingCellIndex;
}
public void setStartingCellIndex(int cellIndex) {
startingCellIndex = cellIndex;
}
public int getCells() {
return childFigure != null ? childFigure.length : 0;
}
public boolean isHorizontal() {
return true;
}
public void invalidateTable() {
invalidate();
getMyTabularLayoutServer().invalidateTable();
}
public int getColumnWidth(int columnIndex) {
return Math.max(getPreferredColumnWith(columnIndex), getMyTabularLayoutServer().getColumnWidth(getStartingCellIndex()+columnIndex));
}
public int getColumnSpacingBefore(int columnIndex) {
return Math.max(getPreferredColumnSpacingBefore(columnIndex), getMyTabularLayoutServer().getColumnSpacingBefore(getStartingCellIndex()+columnIndex));
}
public Alignment getColumnAlignment(int columnIndex) {
return getMyTabularLayoutServer().getColumnAlignment(getStartingCellIndex()+columnIndex);
}
protected int getPreferredColumnWith(int columnIndex) {
if (childSize == null || columnIndex >= childSize.length || childSize[columnIndex] == null)
return 0;
return childSize[columnIndex].width;
}
protected int getPreferredColumnSpacingBefore(int columnIndex) {
return super.getSpacingBefore(columnIndex);
}
@Override
public int getSpacingBefore(int childIndex) {
return getColumnSpacingBefore(childIndex);
}
protected BaselinedDimension calculateSize(IFigure container, int wHint, int hHint, boolean preferred) {
updateMyTabularLayoutServer(container);
return super.calculateSize(container, wHint, hHint, preferred);
}
protected void setAscentDescentWidth(int wHint, int hHint) {
figAscent = 0;
figDescent = 0;
figWidth = 0;
boolean isFirst = true;
for (int i=0; i<childSize.length; i++)
if (isChildVisible(i)) {
figAscent = Math.max(figAscent, ascent(i));
figDescent = Math.max(figDescent, descent(i));
figWidth += (isFirst ? 0 : getColumnSpacingBefore(i)) + getColumnWidth(i);
isFirst = false;
}
int figHeight = figAscent+figDescent;
switch (getMinorAlignment()) {
case FILL:
case LEADING:
figAscent = 0;
figDescent = figHeight;
break;
case CENTER:
figAscent = figHeight/2;
figDescent = figHeight - figAscent;
break;
case TRAILING:
figAscent = figHeight;
figDescent = 0;
break;
case MATHLINE:
}
}
protected void setLocation(Rectangle area, int[] x, int[] y) {
int children = childSize.length;
int xi = calculateXLocation(area, getMajorAlignment());
for (int i=0; i<children; i++)
if (isChildVisible(i)) {
int columnWidth = getColumnWidth(i);
int widthStretching = (int) ((columnWidth - childSize[i].width) * getMajorAutoresizeWeight(i));
int heightStretching = (int) ((figAscent+figDescent - childSize[i].height) * getMinorAutoresizeWeight(i));
switch (getColumnAlignment(i)) {
case FILL:
case LEADING:
x[i] = xi;
break;
case TRAILING:
x[i] = xi + columnWidth - getPreferredColumnWith(i) - widthStretching;
break;
case CENTER:
x[i] = xi + (columnWidth - getPreferredColumnWith(i) - widthStretching)/2;
break;
case MATHLINE:
}
if (widthStretching > 0) {
childFigure[i].getLayoutManager().getViewportTrackingStrategy().setIndent(
getColumnAlignment(i).equals(Alignment.MATHLINE) ? x[i] - xi : 0);
x[i] = xi;
} else if (childFigure[i].getLayoutManager() != null)
childFigure[i].getLayoutManager().getViewportTrackingStrategy().setIndent(0);
switch (getMinorAlignment()) {
case FILL:
case LEADING:
y[i] = area.y;
break;
case CENTER:
y[i] = area.y + figAscent-childSize[i].height/2-heightStretching/2;
break;
case MATHLINE:
y[i] = area.y + figAscent-ascent(i);//-heightStretching/2;//TODO ??
break;
case TRAILING:
y[i] = area.y + figAscent-ascent(i)-descent(i)-heightStretching;
break;
}
if (heightStretching > 0) {
childFigure[i].getLayoutManager().getViewportTrackingStrategy().setAscent(
getMinorAlignment().equals(Alignment.MATHLINE) ? y[i] - area.y : 0);
y[i] = area.y;
} else if (childFigure[i].getLayoutManager() != null)
childFigure[i].getLayoutManager().getViewportTrackingStrategy().setAscent(0);
childSize[i].width += widthStretching;
childSize[i].height += heightStretching;
xi += columnWidth + getColumnSpacingBefore(i+1);
}
}
public void invalidate() {
super.invalidate();
// getMyTabularLayoutServer().invalidateTable();
if (childFigure != null)
for (IEntityFigure cf : childFigure)
if (cf != null && cf.isShowing()) {
IEntityLayout el = cf.getLayoutManager();
if (el != null && (el.getMajorAutoresizeWeight() != 0.0f || el.getMinorAutoresizeWeight() != 0.0f))
cf.invalidate();
}
}
}