summaryrefslogtreecommitdiff
path: root/src/net/sourceforge/plantuml/salt/element/ElementTree.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/sourceforge/plantuml/salt/element/ElementTree.java')
-rw-r--r--src/net/sourceforge/plantuml/salt/element/ElementTree.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/net/sourceforge/plantuml/salt/element/ElementTree.java b/src/net/sourceforge/plantuml/salt/element/ElementTree.java
new file mode 100644
index 0000000..b05ef09
--- /dev/null
+++ b/src/net/sourceforge/plantuml/salt/element/ElementTree.java
@@ -0,0 +1,209 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2014, Arnaud Roques
+ *
+ * Project Info: http://plantuml.sourceforge.net
+ *
+ * This file is part of PlantUML.
+ *
+ * Licensed under The MIT License (Massachusetts Institute of Technology License)
+ *
+ * See http://opensource.org/licenses/MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+ * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Original Author: Arnaud Roques
+ */
+package net.sourceforge.plantuml.salt.element;
+
+import java.awt.geom.Dimension2D;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.plantuml.Dimension2DDouble;
+import net.sourceforge.plantuml.ISkinSimple;
+import net.sourceforge.plantuml.graphic.HtmlColorSet;
+import net.sourceforge.plantuml.graphic.StringBounder;
+import net.sourceforge.plantuml.ugraphic.UChangeColor;
+import net.sourceforge.plantuml.ugraphic.UFont;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.ULine;
+import net.sourceforge.plantuml.ugraphic.URectangle;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
+
+public class ElementTree extends AbstractElement {
+
+ private final List<ElementTreeEntry> entries = new ArrayList<ElementTreeEntry>();
+ private final UFont font;
+ private final ISkinSimple spriteContainer;
+ private final double margin = 10;
+ private final TableStrategy strategy;
+
+ public ElementTree(UFont font, ISkinSimple spriteContainer, TableStrategy strategy) {
+ this.font = font;
+ this.spriteContainer = spriteContainer;
+ this.strategy = strategy;
+ }
+
+ public void addEntry(String s) {
+ int level = 0;
+ while (s.startsWith("+")) {
+ level++;
+ s = s.substring(1);
+ }
+ final Element elmt = new ElementText(Arrays.asList(s.trim()), font, spriteContainer);
+ entries.add(new ElementTreeEntry(level, elmt));
+ }
+
+ public void addCellToEntry(String s) {
+ final int size = entries.size();
+ if (size > 0) {
+ final Element elmt = new ElementText(Arrays.asList(s.trim()), font, spriteContainer);
+ entries.get(size - 1).addCell(elmt);
+ }
+ }
+
+ public Dimension2D getPreferredDimension(StringBounder stringBounder, double x, double y) {
+ double w1 = 0;
+ double h = 0;
+ for (ElementTreeEntry entry : entries) {
+ final Dimension2D dim1 = entry.getPreferredDimensionFirstCell(stringBounder);
+ w1 = Math.max(w1, dim1.getWidth());
+ h += dim1.getHeight();
+ }
+ double w2 = getWidthOther(stringBounder).getTotalWidthWithMargin(margin);
+ if (w2 > 0) {
+ w2 += margin;
+ }
+ return new Dimension2DDouble(w1 + w2 + 2, h);
+ }
+
+ private ListWidth getWidthOther(StringBounder stringBounder) {
+ ListWidth merge = new ListWidth();
+ for (ElementTreeEntry entry : entries) {
+ final ListWidth dim2 = entry.getPreferredDimensionOtherCell(stringBounder);
+ merge = merge.mergeMax(dim2);
+ }
+ return merge;
+ }
+
+ private double getWidth1(StringBounder stringBounder) {
+ double w1 = 0;
+ for (ElementTreeEntry entry : entries) {
+ final Dimension2D dim1 = entry.getPreferredDimensionFirstCell(stringBounder);
+ w1 = Math.max(w1, dim1.getWidth());
+ }
+ return w1;
+ }
+
+ public void drawU(UGraphic ug, int zIndex, Dimension2D dimToUse) {
+ if (zIndex != 0) {
+ return;
+ }
+
+ final StringBounder stringBounder = ug.getStringBounder();
+ final double w1 = getWidth1(stringBounder);
+ final ListWidth otherWidth = getWidthOther(stringBounder);
+ final Skeleton skeleton = new Skeleton();
+ double yvar = 0;
+ final List<Double> rows = new ArrayList<Double>();
+ final List<Double> cols = new ArrayList<Double>();
+ rows.add(yvar);
+ double xvar = 0;
+ cols.add(xvar);
+ xvar += w1 + margin / 2;
+ cols.add(xvar);
+ for (final Iterator<Double> it = otherWidth.iterator(); it.hasNext();) {
+ xvar += it.next() + margin;
+ cols.add(xvar);
+ }
+
+ for (ElementTreeEntry entry : entries) {
+ entry.drawFirstCell(ug, 0, yvar);
+ entry.drawSecondCell(ug, w1 + margin, yvar, otherWidth, margin);
+ final double h = entry.getPreferredDimensionFirstCell(stringBounder).getHeight();
+ skeleton.add(entry.getXDelta() - 7, yvar + h / 2 - 1);
+ yvar += h;
+ rows.add(yvar);
+ }
+ ug = ug.apply(new UChangeColor(HtmlColorSet.getInstance().getColorIfValid("#888888")));
+ skeleton.draw(ug, 0, 0);
+ if (strategy != TableStrategy.DRAW_NONE) {
+ final Grid2 grid = new Grid2(rows, cols, strategy);
+ grid.drawU(ug);
+ }
+ }
+
+ static class Skeleton {
+
+ private final List<Entry> entries = new ArrayList<Entry>();
+
+ static class Entry {
+ private final double xpos;
+ private final double ypos;
+
+ public Entry(double x, double y) {
+ this.xpos = x;
+ this.ypos = y;
+ }
+
+ public void drawRectangle(UGraphic ug) {
+ ug.apply(new UTranslate(xpos, ypos)).draw(new URectangle(2, 2));
+ }
+ }
+
+ public void add(double x, double y) {
+ entries.add(new Entry(x, y));
+ }
+
+ public void draw(UGraphic ug, double x, double y) {
+ for (int i = 0; i < entries.size(); i++) {
+ final Entry en = entries.get(i);
+ if (i + 1 < entries.size() && entries.get(i + 1).xpos > en.xpos) {
+ en.drawRectangle(ug);
+ }
+ Entry parent = null;
+ for (int j = 0; j < i; j++) {
+ final Entry en0 = entries.get(j);
+ if (en0.xpos < en.xpos) {
+ parent = en0;
+ }
+ }
+ if (parent != null) {
+ drawChild(ug, parent, en);
+ }
+ }
+ }
+
+ private void drawChild(UGraphic ug, Entry parent, Entry child) {
+ final double dy = child.ypos - parent.ypos - 2;
+ ug.apply(new UTranslate(parent.xpos + 1, parent.ypos + 3)).draw(new ULine(0, dy));
+
+ final double dx = child.xpos - parent.xpos - 2;
+ ug.apply(new UTranslate(parent.xpos + 1, child.ypos + 1)).draw(new ULine(dx, 0));
+
+ }
+
+ }
+
+}