package org.csstudio.sds.ui.internal.commands;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.csstudio.sds.model.AbstractWidgetModel;
import org.csstudio.sds.model.commands.SetPropertyCommand;
import org.csstudio.sds.ui.editparts.AbstractBaseEditPart;
import org.csstudio.sds.ui.internal.editor.Arrange;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
public class ArrangeCommand extends Command {
private final List<AbstractBaseEditPart> _editParts;
private final String _positionProperty;
private final String _sizeProperty;
private Command _chain;
public ArrangeCommand(List<AbstractBaseEditPart> editParts, Arrange direction) {
_editParts = editParts;
if (direction == Arrange.HORIZONTAL) {
_positionProperty = AbstractWidgetModel.PROP_POS_X;
_sizeProperty = AbstractWidgetModel.PROP_WIDTH;
} else {
_positionProperty = AbstractWidgetModel.PROP_POS_Y;
_sizeProperty = AbstractWidgetModel.PROP_HEIGHT;
}
}
@Override
public void execute() {
if (_chain == null) {
_chain = createCommandChain();
}
_chain.execute();
}
@Override
public void undo() {
if (_chain != null) {
_chain.undo();
}
}
private Command createCommandChain() {
CompoundCommand chain = new CompoundCommand();
sort(_editParts);
double startPosition = calculateStartPosition();
double spacing = calculateSpacing();
for (int i = 1; i < _editParts.size() - 1; i++) {
AbstractWidgetModel widget = _editParts.get(i).getWidgetModel();
int newPosition = calculateNewPosition(startPosition, spacing, i);
chain.add(new SetPropertyCommand(widget, _positionProperty, newPosition));
}
return chain;
}
private void sort(List<AbstractBaseEditPart> selectedEditParts) {
Collections.sort(selectedEditParts, new Comparator<AbstractBaseEditPart>() {
@Override
public int compare(AbstractBaseEditPart o1, AbstractBaseEditPart o2) {
return (int) (calculateCenter(o1.getWidgetModel()) - calculateCenter(o2.getWidgetModel()));
}
});
}
private double calculateCenter(AbstractWidgetModel widget) {
return widget.getIntegerProperty(_positionProperty) + (widget.getIntegerProperty(_sizeProperty) / 2);
}
private double calculateEndPosition() {
return calculateCenter(_editParts.get(_editParts.size() - 1).getWidgetModel());
}
private double calculateStartPosition() {
return calculateCenter(_editParts.get(0).getWidgetModel());
}
private double calculateSpacing() {
double leftBound = calculateStartPosition();
double rightBound = calculateEndPosition();
return (rightBound - leftBound) / (_editParts.size() - 1);
}
private int calculateNewPosition(double startPosition, double spacing, int index) {
return (int) (startPosition + (index * spacing) - (_editParts.get(index).getWidgetModel()
.getIntegerProperty(_sizeProperty) / 2));
}
}