X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fmultileveldiagram%2FLayerComposition.java;fp=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fmultileveldiagram%2FLayerComposition.java;h=3f341fd1eafadf0e6330aca9a6d5628f6f3d763c;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/multileveldiagram/LayerComposition.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/multileveldiagram/LayerComposition.java new file mode 100644 index 000000000..3f341fd1e --- /dev/null +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/multileveldiagram/LayerComposition.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.g2d.multileveldiagram; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.impl.Diagram; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; + +/** + * This class describes a composition of a multi-layer diagram. + * + * @author Toni Kalajainen + */ +public class LayerComposition { + + /** Diagram hint, MorphHandlers read this key from the diagram */ + public static final Key KEY_PHASE = new KeyOf(MorphPhase.class); + + /** Transition function */ + TransitionFunction function = TransitionFunction.SIGMOID; + + /** Diagramming info */ + ArrayList nodes = new ArrayList(); + /** All diagrams */ + ArrayList diagrams = new ArrayList(); + /** Zoom levels */ + MorphLevel[] levels = null; + + /** + * Add a new diagram to the composition. + * The top most diagram has startZoom open-ended, and the bottom diagram + * has endZoom open-ended. + * + * @param diagram + * @param startZoom startZoom in percents or null if open-ended + * @param endZoom endZoom in percents or null if open-ended + */ + public void addLayer(IDiagram diagram, Double startZoom, Double endZoom) + { + assert(diagram!=null); + if (startZoom!=null && endZoom!=null) + assert(startZoom i = nodes.iterator(); + while (i.hasNext()) { + Node n = i.next(); + if (n.diagram == diagram) + i.remove(); + } + levels = null; + } + + /** + * Builds Zoom Levels. + */ + private void _buildZoomLevels() + { + diagrams.clear(); + Collections.sort(nodes); + int c = nodes.size(); + ArrayList levels = new ArrayList(c+1); + MorphLevel prevZL = null; + for (int i = 0; i<=c; i++ ) + { + MorphLevel zl = new MorphLevel(); + if (i==0) { + zl.ud = nodes.get(0).diagram; + zl.ld = nodes.get(0).diagram; + zl.ul = -Double.MAX_VALUE; + zl.ll = nodes.get(0).level; + } else if (i==c) { + zl.ud = nodes.get(c-1).diagram; + zl.ld = nodes.get(c-1).diagram; + zl.ul = nodes.get(c-1).level; + zl.ll = Double.MAX_VALUE; + } else { + zl.ud = nodes.get(i-1).diagram; + zl.ld = nodes.get(i ).diagram; + zl.ul = nodes.get(i-1).level; + zl.ll = nodes.get(i ).level; + } + + if (prevZL!=null && prevZL.ld == zl.ld && prevZL.ud == zl.ud) + { + prevZL.ll = Math.max(prevZL.ll, zl.ll); + prevZL.ul = Math.min(prevZL.ul, zl.ul); + zl = prevZL; + } else { + prevZL = zl; + levels.add(zl); + } + if (i>0) { + nodes.get(i-1).upper = prevZL; + nodes.get(i-1).lower = zl; + } + + if (zl.ud!=null && !diagrams.contains(zl.ud)) + diagrams.add(zl.ud); + if (zl.ld!=null && !diagrams.contains(zl.ld)) + diagrams.add(zl.ld); + } + this.levels = levels.toArray(new MorphLevel[levels.size()]); + } + + /** + * Get ordered list of zoom levels starting from the top most level + * (which is diagram) + * @return ordered list of zoom levels + */ + public MorphLevel[] getMorphLevels() + { + if (levels==null) _buildZoomLevels(); + return levels; + } + + public MorphPhase getTransitionInfo(double zoomLevel) + { + if (levels==null) _buildZoomLevels(); + MorphLevel zl = null; + for (int i=0; i1) zp.phase = 1; + return zp; + } + + public void setTransitionFunction(TransitionFunction function) + { + this.function = function; + } + + public TransitionFunction getFunction() { + return function; + } + + /** + * Diagrams from (first occurance) top to down order + * @return + */ + public List getDiagrams() { + if (levels==null) _buildZoomLevels(); + return Collections.unmodifiableList(diagrams); + } + + @Override + public String toString() { + return getDiagrams().toString(); + } + + /** Information about a single layer */ + public static class LayerInfo { + public double ul, ll; + public IDiagram diagram; + } + + public List buildMorphLayers() + { + List result = new ArrayList(); + + for (MorphLevel ml : getMorphLevels()) + { + // Upper and lower layers are the same + if (ml.ud != null && ml.ud==ml.ld) + { + LayerInfo li = new LayerInfo(); + li.diagram = ml.ud; + li.ll = ml.ll; + li.ul = ml.ul; + result.add(li); + continue; + } + // Build morphing layer + IDiagram ud = ml.ud == null ? Diagram.EMPTY_DIAGRAM : ml.ud; + IDiagram ld = ml.ld == null ? Diagram.EMPTY_DIAGRAM : ml.ld; + LayerInfo li = new LayerInfo(); + li.ll = ml.ll; + li.ul = ml.ul; + li.diagram = TransitionDiagram.createTransitionDiagram(ud, ld, TransitionDiagram.MORPH_ELEMENT_CLASS); + result.add(li); + } + + return result; + } + + private static class Node implements Comparable { + double level; + IDiagram diagram; + MorphLevel upper, lower; + @Override + public int compareTo(Node n) { + double diff = level - n.level; + if (diff<0) return -1; + if (diff>0) return 1; + return 0; + } + public Node(IDiagram diagram, double level) { + this.level = level; + this.diagram = diagram; + } + } + public static class MorphPhase { + public MorphLevel level; + /** Phase, 0==upper .. 1==lower */ + public double phase; + @Override + public String toString() { + return phase + "\t"+level; + } + } + + public static class MorphLevel { + /** + * Upper and lower diagrams (one may be null) + */ + public IDiagram ud, ld; + public double ul, ll; + public IDiagram diagram; + + /** + * Is zoom level locked to a diagram + * @return + */ + public boolean isLocked() + { + return ud == ld; + } + + public boolean isInTransition() + { + return ud != ld; + } + + public boolean isInLevel(double zoomLevel) + { + return zoomLevel >=ul && zoomLevel<=ll; + } + + @Override + public String toString() { + String un = "[]"; + if (ud!=null) un = ud.toString(); + String ln = "[]"; + if (ld!=null) ln = ld.toString(); + + return un+" .. "+ln; + } + + } + +}