X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fprofile%2FTextGridStyle.java;h=997ace1d63f12a87db7fc6fcaaec5f630fc92be3;hp=6657d5a60eca5856f3785cb4f77f07197dfa5c5a;hb=ab9fcfe016ef75da40eb00a46d4a54b50e534511;hpb=b809a171b6dfb81ed9ef9e84870dcbcbc5912f0e diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java index 6657d5a60..997ace1d6 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java @@ -1,368 +1,406 @@ -package org.simantics.diagram.profile; - -import java.awt.Color; -import java.awt.Font; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; - -import org.simantics.databoard.Bindings; -import org.simantics.datatypes.literal.Vec2d; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.variable.RVI; -import org.simantics.db.layer0.variable.Variable; -import org.simantics.diagram.elements.ITextListener; -import org.simantics.diagram.elements.TextGridNode; -import org.simantics.diagram.elements.TextNode; -import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; -import org.simantics.g2d.utils.Alignment; -import org.simantics.modeling.ModelingResources; -import org.simantics.scenegraph.INode; -import org.simantics.scenegraph.g2d.nodes.ConnectionNode; -import org.simantics.scenegraph.profile.EvaluationContext; -import org.simantics.scenegraph.profile.common.ProfileVariables; -import org.simantics.scenegraph.utils.GeometryUtils; -import org.simantics.scenegraph.utils.NodeUtil; -import org.simantics.scl.runtime.function.Function1; -import org.simantics.ui.colors.Colors; - -/** - * @author Antti Villberg - * @author Tuukka Lehtonen - */ -public abstract class TextGridStyle extends StyleBase { - - private final Font FONT = Font.decode("Arial 12"); - private final Color BACKGROUND_COLOR = new Color(255, 255, 255, 192); - private static final Rectangle2D EMPTY_BOUNDS = new Rectangle2D.Double(0, 0, 0, 0); - - // NOTE: this is a hack - String id; - - protected double xOffset; - protected double yOffset; - - public TextGridStyle() { - this(0.0, 2.1); - } - - public TextGridStyle(double xOffset, double yOffset) { - this.xOffset = xOffset; - this.yOffset = yOffset; - } - - public Resource getPropertyRelation(ReadGraph g, Resource module) { - throw new Error("Fix this"); - } - - /** - * @return the name of the scene graph node to create to represent the text - * element created by this style - */ - public String getNodeName() { - return getClass().getSimpleName(); - } - - /** - * Override to customize. - * - * @param graph - * @param element - * @return - * @throws DatabaseException - */ - protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException { - ModelingResources mr = ModelingResources.getInstance(graph); - Resource config = graph.getPossibleObject(element, mr.ElementToComponent); - return config; - } - - /** - * Override to customize. - * - * @param graph - * @param element - * @return - * @throws DatabaseException - */ - protected String getConfigurationComponentNameForElement(ReadGraph graph, Resource element) throws DatabaseException { - Resource config = getConfigurationComponent(graph, element); - if (config == null) - return null; - String name = graph.getPossibleRelatedValue(config, getPropertyRelation(graph,element), Bindings.STRING); - return name; - } - - public AffineTransform getTransform(INode node, AffineTransform parentTransform, Rectangle2D elementBounds, int location, boolean up) { - return getTransform(parentTransform, elementBounds, location, up); - } - - public AffineTransform getTransform(AffineTransform parentTransform, Rectangle2D elementBounds, int location, boolean up) { - - double scale = GeometryUtils.getScale(parentTransform); - - AffineTransform at = AffineTransform.getTranslateInstance( - parentTransform.getTranslateX() + elementBounds.getCenterX() * scale + xOffset, - parentTransform.getTranslateY() + elementBounds.getMinY() * scale + yOffset*(location-1) + (up ? 0.0 : (2.0*yOffset) + elementBounds.getHeight() * scale) - ); - at.scale(0.15, 0.15); - - return at; - - } - - protected String rowId() { - return ""; - } - - @Override - public MonitorTextGridResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) - throws DatabaseException { - String name = getConfigurationComponentNameForElement(graph, element); - if (name == null) - return null; - AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element); - Vec2d offset = DiagramGraphUtil.getOffset(graph, element); - boolean enabled = !DiagramGraphUtil.getProfileMonitorsHidden(graph, element); - boolean up = DiagramGraphUtil.getProfileMonitorsUp(graph, element); - double spacing = DiagramGraphUtil.getProfileMonitorSpacing(graph, element); - return new MonitorTextGridResult(rowId(), name, "", "", enabled, up, spacing, null, null, null, transform, offset); - } - - // Not to be modified - protected final static Point2D[] DEFAULT_CELL_OFFSETS = new Point2D[] { - new Point2D.Double(-45, 0), - new Point2D.Double(22, 0), - new Point2D.Double(24, 0) - }; - - // Not to be modified - protected final static Point2D[] ZERO_CELL_OFFSETS = new Point2D[] { - new Point2D.Double(0, 0), - new Point2D.Double(0, 0), - new Point2D.Double(0, 0) - }; - - protected Point2D[] getCellOffsets() { - return DEFAULT_CELL_OFFSETS; - } - - @Override - public void applyStyleForNode(EvaluationContext observer, INode _node, MonitorTextGridResult result) { - - String value = result != null ? result.getText1() : null; - boolean enabled = result != null ? result.getEnabled() : false; - - if (value != null && enabled) { - - // if (value != null && !value.isEmpty() && !value.trim().isEmpty()) { - - String value2 = result != null ? result.getText2() : null; - String value3 = result != null ? result.getText3() : null; - - double spacing = result.getSpacing(); - - final Function1 modifier = result != null ? result.getModifier() : null; - final Function1 validator = result != null ? result.getValidator() : null; - final Function1 translator = result != null ? result.getTranslator() : null; - final RVI rvi = result != null ? result.getRVI() : null; - - final TextGridNode node = ProfileVariables.claimChild(_node, "", "TextGridStyle", TextGridNode.class, observer); - if (node == null) - return; - - // This assumes that this TextGridStyle instance will be devoted to - // this row ID until the end of its life. - String id = result.getRowId(); - //System.out.println(this + " ID: " + id); - if (!id.equals(this.id)) { - //System.out.println(this + " SET ID: " + this.id + " -> " + id); - this.id = id; - } - - Integer newRow = observer.getTemporaryProperty(_node, "location"); - if (newRow == null) - newRow = 1; - - // Remove from existing row to add to another row if necessary. - Integer row = observer.getProperty(_node, id); - if (row != null && row != newRow) { - String actualId = node.getRowId(row); - if (id.equals(actualId)) { - node.removeRow(row); - } - } - row = newRow; - - node.setRowId(row, id); - observer.setProperty(_node, id, row); - observer.setTemporaryProperty(_node, "location", row + 1); - - node.setText(2, row, value2); - node.setUp(result.getUp()); - - MonitorTextGridResult cache = node.getCache(1, row); - if(cache != null && cache.sameStructure(result)) return; - - node.setCache(1, row, result); - - boolean isConnection = _node instanceof ConnectionNode; - - Rectangle2D elementBounds = isConnection ? EMPTY_BOUNDS : NodeUtil.getLocalElementBounds(_node); - if(elementBounds == null) { - new Exception("Cannot get local element bounds for node " + _node.toString()).printStackTrace(); - // This is here for checking why getLocalElementBounds failed in the debugger. - NodeUtil.getLocalElementBounds(_node); - return; - } - - // System.err.println("elementBounds " + elementBounds); - // System.err.println("parentTransform " + result.getParentTransform()); - - AffineTransform at = getTransform(_node,result.getParentTransform(), elementBounds, row, result.getUp()); - Vec2d offset = result.getOffset(); - - Point2D[] cellOffsets = getCellOffsets(); - - AffineTransform at1 = new AffineTransform(at); - at1.translate(cellOffsets[0].getX(),cellOffsets[0].getY()); - AffineTransform at2 = new AffineTransform(at); - at2.translate(cellOffsets[1].getX()+spacing,cellOffsets[1].getY()); - AffineTransform at3 = new AffineTransform(at); - at3.translate(cellOffsets[2].getX()+spacing,cellOffsets[2].getY()); - - at1.translate(offset.x, offset.y); - at2.translate(offset.x, offset.y); - at3.translate(offset.x, offset.y); - - node.setTransform(1, row, at1); - node.setTransform(2, row, at2); - node.setTransform(3, row, at3); - - Alignment[] alignments = result.getAlignments(); - if(alignments != null) { - node.setHorizontalAlignment(1, row, (byte) alignments[0].ordinal()); - node.setHorizontalAlignment(2, row, (byte) alignments[1].ordinal()); - node.setHorizontalAlignment(3, row, (byte) alignments[2].ordinal()); - } else { - node.setHorizontalAlignment(1, row, (byte) getAlignment(1).ordinal()); - node.setHorizontalAlignment(2, row, (byte) getAlignment(2).ordinal()); - node.setHorizontalAlignment(3, row, (byte) getAlignment(3).ordinal()); - } - - Alignment[] verticalAlignments = result.getVerticalAlignments(); - if(verticalAlignments != null) { - node.setVerticalAlignment(1, row, (byte) verticalAlignments[0].ordinal()); - node.setVerticalAlignment(2, row, (byte) verticalAlignments[1].ordinal()); - node.setVerticalAlignment(3, row, (byte) verticalAlignments[2].ordinal()); - } else { - node.setVerticalAlignment(1, row, (byte) getVerticalAlignment(1).ordinal()); - node.setVerticalAlignment(2, row, (byte) getVerticalAlignment(2).ordinal()); - node.setVerticalAlignment(3, row, (byte) getVerticalAlignment(3).ordinal()); - } - - node.setZIndex(3000); - - org.simantics.common.color.Color color = result.getColor(); - java.awt.Color awtColor = color != null ? Colors.awt(color) : Color.DARK_GRAY; - - setTextNodeData(node, 1, row, value, FONT, awtColor, BACKGROUND_COLOR); - setTextNodeData(node, 2, row, value2, result.getPending(), FONT, awtColor, BACKGROUND_COLOR); - setTextNodeData(node, 3, row, value3, FONT, awtColor, BACKGROUND_COLOR); - - node.setEditable(1, row, false); - node.setForceEventListening(2, row, true); - node.setEditable(2, row, modifier != null); - node.setEditable(3, row, false); - - final int finalRow = row; - - if (modifier != null) { - node.setTextListener(2, row, new ITextListener() { - @Override - public void textChanged() {} - - @Override - public void textEditingStarted() {} - - @Override - public void textEditingCancelled() { - } - - @Override - public void textEditingEnded() { - - TextNode t = node.get(2, finalRow); - if (t == null) - return; - - if(!t.getText().equals(t.getTextBeforeEdit())) - modifier.apply(t.getText()); - - } - }); - } else { - node.setTextListener(2, row, null); - } - - node.setInputValidator(2, row, validator); - node.setTranslator(translator); - - node.setRVI(2, row, rvi); - - postProcessNode(node, row); - - } else { - cleanupStyleForNode(observer, _node); - } - } - - private void setTextNodeData(TextGridNode node, int x, int y, String text, Font font, Color fgColor, Color bgColor) { - if (text != null) { - node.setText(x, y, text); - node.setFont(x, y, font); - node.setColor(x, y, fgColor); - node.setBackgroundColor(x, y, bgColor); - } else { - // Prevent rendering of the node. - node.setFont(x, y, null); - } - } - - private void setTextNodeData(TextGridNode node, int x, int y, String text, boolean pending, Font font, Color fgColor, Color bgColor) { - setTextNodeData(node, x, y, text, font, fgColor, bgColor); - node.setPending(x, y, pending); - } - - protected Alignment getAlignment(int column) { - switch(column) { - case 1: return Alignment.TRAILING; - case 2: return Alignment.TRAILING; - case 3: return Alignment.LEADING; - default: return Alignment.LEADING; - } - } - - protected Alignment getVerticalAlignment(int column) { - return Alignment.TRAILING; - } - - @Override - protected void cleanupStyleForNode(EvaluationContext observer, INode _node) { - Integer row = observer.getProperty(_node, id); - //System.out.println(this + " cleanup(" + id + ", " + row + ")"); - //System.out.println(element); - if (row == null) - return; - observer.setProperty(_node, id, null); - TextGridNode node = ProfileVariables.browseChild(_node, "TextGridStyle"); - if (node != null) - node.removeRow(row); - } - - protected void postProcessNode(TextGridNode node, int row) { - } - -} +package org.simantics.diagram.profile; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.databoard.Bindings; +import org.simantics.datatypes.literal.Vec2d; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.RVI; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.diagram.elements.ITextListener; +import org.simantics.diagram.elements.TextGridNode; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.g2d.utils.Alignment; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.g2d.nodes.ConnectionNode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.common.ProfileVariables; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.ui.colors.Colors; + +/** + * @author Antti Villberg + * @author Tuukka Lehtonen + */ +public abstract class TextGridStyle extends StyleBase { + + private final Font FONT = Font.decode("Arial 12"); + private final Color BACKGROUND_COLOR = new Color(255, 255, 255, 192); + private static final Rectangle2D EMPTY_BOUNDS = new Rectangle2D.Double(0, 0, 0, 0); + + protected double xOffset; + protected double yOffset; + + public TextGridStyle(Resource r) { + this(r, 0.0, 2.1); + } + + public TextGridStyle(Resource r, double xOffset, double yOffset) { + super(r); + this.xOffset = xOffset; + this.yOffset = yOffset; + } + + public Resource getPropertyRelation(ReadGraph g, Resource module) { + throw new Error("Fix this"); + } + + /** + * @return the name of the scene graph node to create to represent the text + * element created by this style + */ + public String getNodeName() { + return getClass().getSimpleName(); + } + + /** + * Override to customize. + * + * @param graph + * @param element + * @return + * @throws DatabaseException + */ + protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException { + ModelingResources mr = ModelingResources.getInstance(graph); + Resource config = graph.getPossibleObject(element, mr.ElementToComponent); + return config; + } + + /** + * Override to customize. + * + * @param graph + * @param element + * @return + * @throws DatabaseException + */ + protected String getConfigurationComponentNameForElement(ReadGraph graph, Resource element) throws DatabaseException { + Resource config = getConfigurationComponent(graph, element); + if (config == null) + return null; + String name = graph.getPossibleRelatedValue(config, getPropertyRelation(graph,element), Bindings.STRING); + return name; + } + + public AffineTransform getTransform(INode node, AffineTransform parentTransform, Rectangle2D elementBounds, int location, boolean up) { + return getTransform(parentTransform, elementBounds, location, up); + } + + public AffineTransform getTransform(AffineTransform parentTransform, Rectangle2D elementBounds, int location, boolean up) { + + double scale = GeometryUtils.getScale(parentTransform); + + AffineTransform at = AffineTransform.getTranslateInstance( + parentTransform.getTranslateX() + elementBounds.getCenterX() * scale + xOffset, + parentTransform.getTranslateY() + elementBounds.getMinY() * scale + yOffset*(location-1) + (up ? 0.0 : (2.0*yOffset) + elementBounds.getHeight() * scale) + ); + at.scale(0.15, 0.15); + + return at; + + } + + protected String rowId() { + return ""; + } + + @Override + public MonitorTextGridResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) + throws DatabaseException { + String name = getConfigurationComponentNameForElement(graph, element); + if (name == null) + return null; + AffineTransform transform = DiagramGraphUtil.getDynamicAffineTransform(graph, runtimeDiagram, element); + Vec2d offset = DiagramGraphUtil.getOffset(graph, element); + boolean enabled = !DiagramGraphUtil.getProfileMonitorsHidden(graph, element); + boolean up = DiagramGraphUtil.getProfileMonitorsUp(graph, element); + double spacing = DiagramGraphUtil.getProfileMonitorSpacing(graph, element); + return new MonitorTextGridResult(rowId(), name, "", "", enabled, up, spacing, null, null, null, transform, offset); + } + + // Not to be modified + protected final static Point2D[] DEFAULT_CELL_OFFSETS = new Point2D[] { + new Point2D.Double(-45, 0), + new Point2D.Double(22, 0), + new Point2D.Double(24, 0) + }; + + // Not to be modified + protected final static Point2D[] ZERO_CELL_OFFSETS = new Point2D[] { + new Point2D.Double(0, 0), + new Point2D.Double(0, 0), + new Point2D.Double(0, 0) + }; + + protected Point2D[] getCellOffsets() { + return DEFAULT_CELL_OFFSETS; + } + + @Override + public void applyStyleForNode(EvaluationContext observer, INode _node, MonitorTextGridResult result) { + + String value = result != null ? result.getText1() : null; + boolean enabled = result != null ? result.getEnabled() : false; + + if (value != null && enabled) { + + // if (value != null && !value.isEmpty() && !value.trim().isEmpty()) { + + String value2 = result != null ? result.getText2() : null; + String value3 = result != null ? result.getText3() : null; + + double spacing = result.getSpacing(); + + final Function1 modifier = result != null ? result.getModifier() : null; + final Function1 validator = result != null ? result.getValidator() : null; + final Function1 translator = result != null ? result.getTranslator() : null; + final RVI rvi = result != null ? result.getRVI() : null; + + final TextGridNode node = ProfileVariables.claimChild(_node, "", "TextGridStyle", TextGridNode.class, observer); + if (node == null) + return; + + // This assumes that this TextGridStyle instance will be devoted to + // this row ID until the end of its life. +// String id = result.getRowId(); +// System.out.println(this + " ID: " + id); +// if (!id.equals(this.id)) { +// System.out.println(this + " SET ID: " + this.id + " -> " + id); +// this.id = id; +// } + + Integer newRow = observer.getTemporaryProperty(_node, "location"); + if (newRow == null) + newRow = 1; + + // Remove from existing row to add to another row if necessary. + Integer row = getCurrentRowNumber(observer, _node); + if (row != null && row != newRow) { + String actualId = node.getRowId(row); + String id = observer.getProperty(_node, rowIdKey()); + if (id.equals(actualId)) { + node.removeRow(row); + } + } + row = newRow; + + node.setRowId(row, result.getRowId()); + + setCurrentRowNumber(observer, _node, result.getRowId(), row); + + observer.setTemporaryProperty(_node, "location", row + 1); + + node.setText(2, row, value2); + node.setUp(result.getUp()); + + MonitorTextGridResult cache = node.getCache(1, row); + if(cache != null && cache.sameStructure(result)) return; + + node.setCache(1, row, result); + + boolean isConnection = _node instanceof ConnectionNode; + + Rectangle2D elementBounds = isConnection ? EMPTY_BOUNDS : NodeUtil.getLocalElementBounds(_node); + if(elementBounds == null) { + new Exception("Cannot get local element bounds for node " + _node.toString()).printStackTrace(); + // This is here for checking why getLocalElementBounds failed in the debugger. + NodeUtil.getLocalElementBounds(_node); + return; + } + + // System.err.println("elementBounds " + elementBounds); + // System.err.println("parentTransform " + result.getParentTransform()); + + AffineTransform at = getTransform(_node,result.getParentTransform(), elementBounds, row, result.getUp()); + Vec2d offset = result.getOffset(); + + Point2D[] cellOffsets = getCellOffsets(); + + AffineTransform at1 = new AffineTransform(at); + at1.translate(cellOffsets[0].getX(),cellOffsets[0].getY()); + AffineTransform at2 = new AffineTransform(at); + at2.translate(cellOffsets[1].getX()+spacing,cellOffsets[1].getY()); + AffineTransform at3 = new AffineTransform(at); + at3.translate(cellOffsets[2].getX()+spacing,cellOffsets[2].getY()); + + at1.translate(offset.x, offset.y); + at2.translate(offset.x, offset.y); + at3.translate(offset.x, offset.y); + + node.setTransform(1, row, at1); + node.setTransform(2, row, at2); + node.setTransform(3, row, at3); + + Alignment[] alignments = result.getAlignments(); + if(alignments != null) { + node.setHorizontalAlignment(1, row, (byte) alignments[0].ordinal()); + node.setHorizontalAlignment(2, row, (byte) alignments[1].ordinal()); + node.setHorizontalAlignment(3, row, (byte) alignments[2].ordinal()); + } else { + node.setHorizontalAlignment(1, row, (byte) getAlignment(1).ordinal()); + node.setHorizontalAlignment(2, row, (byte) getAlignment(2).ordinal()); + node.setHorizontalAlignment(3, row, (byte) getAlignment(3).ordinal()); + } + + Alignment[] verticalAlignments = result.getVerticalAlignments(); + if(verticalAlignments != null) { + node.setVerticalAlignment(1, row, (byte) verticalAlignments[0].ordinal()); + node.setVerticalAlignment(2, row, (byte) verticalAlignments[1].ordinal()); + node.setVerticalAlignment(3, row, (byte) verticalAlignments[2].ordinal()); + } else { + node.setVerticalAlignment(1, row, (byte) getVerticalAlignment(1).ordinal()); + node.setVerticalAlignment(2, row, (byte) getVerticalAlignment(2).ordinal()); + node.setVerticalAlignment(3, row, (byte) getVerticalAlignment(3).ordinal()); + } + + node.setZIndex(3000); + + org.simantics.common.color.Color color = result.getColor(); + Color awtColor = color != null ? Colors.awt(color) : Color.DARK_GRAY; + Color bgColor = getBackgroundColor(); + Font font = getFont(); + + setTextNodeData(node, 1, row, value, font, awtColor, bgColor); + setTextNodeData(node, 2, row, value2, result.getPending(), font, awtColor, bgColor); + setTextNodeData(node, 3, row, value3, font, awtColor, bgColor); + + node.setEditable(1, row, false); + node.setForceEventListening(2, row, true); + node.setEditable(2, row, modifier != null); + node.setEditable(3, row, false); + + final int finalRow = row; + + if (modifier != null) { + node.setTextListener(2, row, new ITextListener() { + @Override + public void textChanged() {} + + @Override + public void textEditingStarted() {} + + @Override + public void textEditingCancelled() { + } + + @Override + public void textEditingEnded() { + + TextNode t = node.get(2, finalRow); + if (t == null) + return; + + if(!t.getText().equals(t.getTextBeforeEdit())) + modifier.apply(t.getText()); + + } + }); + } else { + node.setTextListener(2, row, null); + } + + node.setInputValidator(2, row, validator); + node.setTranslator(translator); + + node.setRVI(2, row, rvi); + + postProcessNode(node, row); + + } else { + cleanupStyleForNode(observer, _node); + } + } + + private void setTextNodeData(TextGridNode node, int x, int y, String text, Font font, Color fgColor, Color bgColor) { + if (text != null) { + node.setText(x, y, text); + node.setFont(x, y, font); + node.setColor(x, y, fgColor); + node.setBackgroundColor(x, y, bgColor); + } else { + // Prevent rendering of the node. + node.setFont(x, y, null); + } + } + + private void setTextNodeData(TextGridNode node, int x, int y, String text, boolean pending, Font font, Color fgColor, Color bgColor) { + setTextNodeData(node, x, y, text, font, fgColor, bgColor); + node.setPending(x, y, pending); + } + + protected Font getFont() { + return FONT; + } + + protected Color getBackgroundColor() { + return BACKGROUND_COLOR; + } + + protected Alignment getAlignment(int column) { + switch(column) { + case 1: return Alignment.TRAILING; + case 2: return Alignment.TRAILING; + case 3: return Alignment.LEADING; + default: return Alignment.LEADING; + } + } + + protected Alignment getVerticalAlignment(int column) { + return Alignment.TRAILING; + } + + @Override + protected void cleanupStyleForNode(EvaluationContext observer, INode _node) { + Integer row = getCurrentRowNumber(observer, _node); + //System.out.println(this + " cleanup(" + id + ", " + row + ")"); + //System.out.println(element); + if (row == null) + return; + clearCurrentRowNumber(observer, _node); + TextGridNode node = ProfileVariables.browseChild(_node, "TextGridStyle"); + if (node != null) + node.removeRow(row); + } + + private Integer getCurrentRowNumber(EvaluationContext observer, INode _node) { + String rowId = observer.getProperty(_node, rowIdKey()); + return observer.getProperty(_node, rowId); + } + + private void setCurrentRowNumber(EvaluationContext observer, INode _node, String rowId, int row) { + // Mapping style identity -> rowId (resourceId) + observer.setProperty(_node, rowIdKey(), rowId); + // Mapping rowId (resourceId) -> row number + observer.setProperty(_node, rowId, row); + } + + private void clearCurrentRowNumber(EvaluationContext observer, INode _node) { + String rowId = observer.getProperty(_node, rowIdKey()); + if(rowId != null) { + observer.setProperty(_node, rowIdKey(), null); + Integer row = observer.getProperty(_node, rowId); + if(row != null) { + observer.setProperty(_node, rowId, null); + } + } + } + + protected void postProcessNode(TextGridNode node, int row) { + } + + private String rowIdKey() { + return "style" + getIdentity().toString(); + } + +}