package com.aelitis.azureus.ui.swt.layout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
public class SimpleReorderableListLayout extends Layout {
public int margin;
public boolean wrap;
public boolean center;
public int borderW = 3;
public int borderH = 3;
private int itemsPerRow;
private int maxHeight = 0;
private int maxWidth = 0;
private int extraSpacing;
private int previouswHint = SWT.DEFAULT;
private boolean cached = false;
private Point cachedSize = null;
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
if(flushCache || ! cached || cachedSize == null) {
Control[] controls = composite.getChildren();
for(int i = 0 ; i < controls.length ; i++) {
Object layoutData = controls[i].getLayoutData();
if(layoutData != null && layoutData instanceof SimpleReorderableListLayoutData) {
SimpleReorderableListLayoutData sData = (SimpleReorderableListLayoutData) layoutData;
if(sData.height > maxHeight) maxHeight = sData.height;
if(sData.width > maxWidth) maxWidth = sData.width;
}
}
if((wHint != SWT.DEFAULT || previouswHint != SWT.DEFAULT) && wrap) {
if(wHint != SWT.DEFAULT) {
previouswHint = wHint;
} else {
wHint = previouswHint;
}
itemsPerRow = 1;
int width = 2 * borderW + maxWidth;
while(width < wHint) {
width += margin + maxWidth;
if(width < wHint) {
itemsPerRow++;
}
}
if(center) {
width = 2 * borderW + (margin + maxWidth) * itemsPerRow - margin;
extraSpacing = itemsPerRow == 0 ? 0 : (wHint - width) / (itemsPerRow);
} else {
extraSpacing = 0;
}
} else {
itemsPerRow = controls.length;
}
//Avoid dividing by 0 when there are no items
int nbRows = itemsPerRow > 0 ? (controls.length+itemsPerRow-1) / itemsPerRow : 1;
cached = true;
cachedSize = new Point(2 * borderW + (maxWidth+margin) * itemsPerRow - margin, 2 * borderH + (margin + maxHeight) * nbRows - margin);
}
return cachedSize;
}
protected void layout(Composite composite, boolean flushCache) {
Control[] controls = composite.getChildren();
List sortedControls = new ArrayList(controls.length);
for(int i = 0 ; i < controls.length ; i++) {
sortedControls.add(controls[i]);
}
Collections.sort(sortedControls,new Comparator() {
public int compare(Object o1, Object o2) {
Control c1 = (Control) o1;
Control c2 = (Control) o2;
Object layoutData1 = c1.getLayoutData();
Object layoutData2 = c2.getLayoutData();
if(layoutData1 == null || ! (layoutData1 instanceof SimpleReorderableListLayoutData) ) return 0;
if(layoutData2 == null || ! (layoutData2 instanceof SimpleReorderableListLayoutData) ) return 0;
SimpleReorderableListLayoutData data1 = (SimpleReorderableListLayoutData) layoutData1;
SimpleReorderableListLayoutData data2 = (SimpleReorderableListLayoutData) layoutData2;
return data1.position - data2.position;
}
});
for(int i = 0 ; i < sortedControls.size() ; i++) {
int xn = i % itemsPerRow;
int yn = i / itemsPerRow;
Control control = (Control) sortedControls.get(i);
//int x = borderW + (margin + maxWidth + extraSpacing) * xn + extraSpacing;
int x = borderW + (margin + maxWidth + extraSpacing) * xn;
int y = borderH + (margin + maxHeight) * yn;
control.setLocation(x,y);
//control.setBounds(x,y,maxWidth,maxHeight);
control.setBounds(x,y,maxWidth + extraSpacing,maxHeight);
}
}
}