/*******************************************************************************
* Copyright 2005, CHISEL Group, University of Victoria, Victoria, BC, Canada.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* The Chisel Group, University of Victoria
*******************************************************************************/
package org.eclipse.zest.layouts.algorithms;
import org.eclipse.zest.layouts.dataStructures.DisplayIndependentRectangle;
import org.eclipse.zest.layouts.dataStructures.InternalNode;
import org.eclipse.zest.layouts.dataStructures.InternalRelationship;
/**
*
* @author Ian Bull
*
* Used to represent algorithms that can continuously run.
*
*/
public abstract class ContinuousLayoutAlgorithm extends AbstractLayoutAlgorithm {
double x, y, widht, height;
public ContinuousLayoutAlgorithm(int styles) {
super(styles);
}
/**
* The logic to determine if a layout should continue running or not
*/
protected abstract boolean performAnotherNonContinuousIteration();
/**
* Computes a single iteration of the layout algorithm
* @return
*/
protected abstract void computeOneIteration(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider, double x, double y, double width, double height);
private boolean continueRunning() {
if (layoutStopped) {
return false;
} else if (this.internalContinuous && !layoutStopped) {
return true;
} else if (performAnotherNonContinuousIteration()) {
return true;
} else {
return false;
}
}
public void setLayoutArea(double x, double y, double width, double height) {
this.setBounds(x, y, width, height);
}
public synchronized DisplayIndependentRectangle getBounds() {
return new DisplayIndependentRectangle(this.x, this.y, this.widht, this.height);
}
public synchronized void setBounds(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.widht = width;
this.height = height;
}
/**
* Calculates and applies the positions of the given entities based on a
* spring layout using the given relationships.
*/
protected void applyLayoutInternal(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider, double x, double y, double width, double height) {
this.setBounds(x, y, width, height);
while (continueRunning()) {
// check for entities and relationships to add or remove
entitiesToLayout = updateEntities(entitiesToLayout);
relationshipsToConsider = updateRelationships(relationshipsToConsider);
DisplayIndependentRectangle bounds = this.getBounds();
double localX = bounds.x;
double localY = bounds.y;
double localWidth = bounds.width;
double localHeight = bounds.height;
computeOneIteration(entitiesToLayout, relationshipsToConsider, localX, localY, localWidth, localHeight);
updateLayoutLocations(entitiesToLayout);
if (this.internalContinuous) {
fireProgressEvent(1, 1);
} else {
fireProgressEvent(getCurrentLayoutStep(), getTotalNumberOfLayoutSteps());
}
}
}
}