1 /*******************************************************************************
\r
2 * Copyright (c) 2012 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.template2d.ui.diagram.adapter;
\r
14 import java.awt.BasicStroke;
\r
15 import java.awt.Color;
\r
16 import java.awt.Shape;
\r
17 import java.awt.Stroke;
\r
18 import java.awt.geom.AffineTransform;
\r
19 import java.awt.geom.Line2D;
\r
20 import java.awt.geom.Rectangle2D;
\r
21 import java.util.ArrayList;
\r
22 import java.util.Collection;
\r
23 import java.util.Collections;
\r
24 import java.util.Iterator;
\r
25 import java.util.List;
\r
26 import java.util.Map.Entry;
\r
27 import java.util.TreeMap;
\r
28 import java.util.concurrent.atomic.AtomicReference;
\r
30 import org.simantics.Simantics;
\r
31 import org.simantics.databoard.Bindings;
\r
32 import org.simantics.databoard.annotations.Optional;
\r
33 import org.simantics.databoard.util.Bean;
\r
34 import org.simantics.db.ReadGraph;
\r
35 import org.simantics.db.Resource;
\r
36 import org.simantics.db.Session;
\r
37 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
\r
38 import org.simantics.db.common.request.ResourceRead;
\r
39 import org.simantics.db.exception.DatabaseException;
\r
40 import org.simantics.db.layer0.variable.Variable;
\r
41 import org.simantics.db.layer0.variable.Variables;
\r
42 import org.simantics.diagram.elements.TextNode;
\r
43 import org.simantics.diagram.function.All;
\r
44 import org.simantics.diagram.function.PredefinedVariables;
\r
45 import org.simantics.diagram.profile.ProfileKeys;
\r
46 import org.simantics.diagram.profile.StyleBase;
\r
47 import org.simantics.diagram.stubs.DiagramResource;
\r
48 import org.simantics.g2d.diagram.IDiagram;
\r
49 import org.simantics.g2d.element.ElementClass;
\r
50 import org.simantics.g2d.element.ElementHints;
\r
51 import org.simantics.g2d.element.ElementUtils;
\r
52 import org.simantics.g2d.element.IElement;
\r
53 import org.simantics.g2d.element.SceneGraphNodeKey;
\r
54 import org.simantics.g2d.element.handler.ElementAdapter;
\r
55 import org.simantics.g2d.element.handler.FillColor;
\r
56 import org.simantics.g2d.element.handler.InternalSize;
\r
57 import org.simantics.g2d.element.handler.Outline;
\r
58 import org.simantics.g2d.element.handler.OutlineColorSpec;
\r
59 import org.simantics.g2d.element.handler.SceneGraph;
\r
60 import org.simantics.g2d.element.handler.SelectionSpecification;
\r
61 import org.simantics.g2d.element.handler.StrokeSpec;
\r
62 import org.simantics.g2d.element.handler.Transform;
\r
63 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
\r
64 import org.simantics.g2d.element.impl.Element;
\r
65 import org.simantics.g2d.elementclass.NonCopyable;
\r
66 import org.simantics.g2d.scenegraph.SceneGraphConstants;
\r
67 import org.simantics.layer0.Layer0;
\r
68 import org.simantics.modeling.template2d.ui.function.DrawingTemplateInfo;
\r
69 import org.simantics.modeling.template2d.ui.function.FlagInfo;
\r
70 import org.simantics.modeling.template2d.ui.function.FlagTableColumnInfo;
\r
71 import org.simantics.modeling.template2d.ui.function.FlagTableInfo;
\r
72 import org.simantics.modeling.template2d.ui.function.MonitorInfo;
\r
73 import org.simantics.modeling.template2d.ui.function.TranslateFlag;
\r
74 import org.simantics.scenegraph.INode;
\r
75 import org.simantics.scenegraph.g2d.G2DParentNode;
\r
76 import org.simantics.scenegraph.g2d.G2DSceneGraph;
\r
77 import org.simantics.scenegraph.g2d.nodes.ShapeNode;
\r
78 import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
\r
79 import org.simantics.scenegraph.profile.DataNodeMap;
\r
80 import org.simantics.scenegraph.profile.EvaluationContext;
\r
81 import org.simantics.scenegraph.profile.common.ProfileVariables;
\r
82 import org.simantics.scenegraph.utils.NodeUtil;
\r
83 import org.simantics.ui.colors.Colors;
\r
84 import org.simantics.ui.fonts.Fonts;
\r
85 import org.simantics.utils.datastructures.hints.IHintContext.Key;
\r
87 public class DrawingFlagTableStyle extends StyleBase<DrawingFlagTableStyle.StyleInfo> {
\r
89 private static final boolean DEBUG_PAINT_ELEMENTS = false;
\r
91 private static final String SLOT_TABLE_PREFIX = "slotTable<";
\r
92 private static final String SLOT_TABLE_SEPARATOR = ">";
\r
94 private static final String SLOT_TABLE_ELEMENTS = "slotTableElements";
\r
96 private ElementClass rowElementClass;
\r
98 public DrawingFlagTableStyle(ReadGraph graph) {
\r
99 rowElementClass = ElementClass.compile(
\r
100 RowElementHandler.INSTANCE,
\r
101 RowElementSelectionHandler.INSTANCE,
\r
102 NonCopyable.INSTANCE,
\r
103 new StaticObjectAdapter(DiagramResource.getInstance(graph).Flag)
\r
104 ).setId(RowElementHandler.class.getSimpleName());
\r
105 if (DEBUG_PAINT_ELEMENTS)
\r
106 rowElementClass = rowElementClass.newClassWith(TestSceneGraph.INSTANCE);
\r
109 public static class StyleInfo extends Bean {
\r
110 public TreeMap<String, FlagTableInfo> name2table;
\r
111 public List<FlagInfo> flags;
\r
113 public Resource template = null;
\r
114 //public String digest = "";
\r
119 public static class FlagInfos extends ResourceRead<ArrayList<FlagInfo>> {
\r
120 public FlagInfos(Resource diagram) {
\r
125 public ArrayList<FlagInfo> perform(ReadGraph g) throws DatabaseException {
\r
126 ArrayList<FlagInfo> flagInfos = new ArrayList<FlagInfo>();
\r
128 Layer0 L0 = Layer0.getInstance(g);
\r
129 DiagramResource DIA = DiagramResource.getInstance(g);
\r
131 Collection<Resource> children = g.getObjects(resource, L0.ConsistsOf);
\r
132 for (Resource child:children){
\r
133 if (!g.isInstanceOf(child, DIA.Flag))
\r
136 Resource flag = child;
\r
137 String tableName = g.getPossibleRelatedValue(flag, DIA.Flag_HasIOTableBinding, Bindings.STRING);
\r
138 Integer rowIndex = g.getPossibleRelatedValue(flag, DIA.Flag_HasIOTableRowIndex, Bindings.INTEGER);
\r
139 FlagInfo flagInfo = new FlagInfo();
\r
140 flagInfo.flag = flag;
\r
141 if (tableName != null && tableName.length() > 0)
\r
142 flagInfo.flagTableName = tableName;
\r
143 flagInfo.flagTableRowIndex = rowIndex;
\r
144 flagInfos.add(flagInfo);
\r
146 } catch (Throwable e){
\r
147 e.printStackTrace(System.err);
\r
154 public StyleInfo calculateStyle(ReadGraph graph, Resource runtimeDiagram,
\r
155 Resource entry, Resource diagram, Variable activeComposite)
\r
156 throws DatabaseException {
\r
157 Resource template = All.getTemplate(graph, runtimeDiagram);
\r
158 if (template == null)
\r
160 DiagramResource DIA = DiagramResource.getInstance(graph);
\r
161 Resource diagram2 = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration);
\r
163 StyleInfo info = new StyleInfo();
\r
164 DrawingTemplateInfo templateInfo = new DrawingTemplateInfo(template);
\r
165 info.template = template;
\r
166 info.name2table = graph.syncRequest(templateInfo, TransientCacheListener.<TreeMap<String, FlagTableInfo>> instance());
\r
167 if (info.name2table == null)
\r
168 info.name2table = new TreeMap<String,FlagTableInfo>();
\r
169 //info.digest = templateInfo.getDigest();
\r
170 //System.err.println(templateInfo.getDigest());
\r
172 info.flags = graph.syncRequest(new FlagInfos(diagram2), TransientCacheListener.<ArrayList<FlagInfo>> instance());
\r
173 if (info.flags == null)
\r
174 info.flags = Collections.emptyList();
\r
179 public void applyStyleForItem(EvaluationContext evaluationContext, DataNodeMap map, Object item, StyleInfo info) {
\r
180 if (info == null || info.flags == null || info.name2table == null)
\r
183 cleanupStyleForItem(evaluationContext, map, item);
\r
186 Iterator<Entry<String,FlagTableInfo>> it = info.name2table.entrySet().iterator();
\r
187 while(it.hasNext()) {
\r
188 Entry<String,FlagTableInfo> entry = it.next();
\r
189 String name = entry.getKey();
\r
190 FlagTableInfo table = entry.getValue();
\r
191 RenderTable com = new RenderTable(evaluationContext, table, name);
\r
194 // render header texts
\r
195 RenderHeaderTexts com3 = new RenderHeaderTexts(evaluationContext, table, name);
\r
199 // render texts of flags
\r
200 // for (FlagInfo flagInfo : info.flags) {
\r
201 // RenderFlagTexts com2 = new RenderFlagTexts(evaluationContext, flagInfo, info.name2table);
\r
208 * This is just for debugging where the invisible IO row elements are.
\r
209 * Not intended to be enabled.
\r
211 private static class TestSceneGraph implements SceneGraph {
\r
213 private static final long serialVersionUID = 5749410674482131633L;
\r
215 public static final TestSceneGraph INSTANCE = new TestSceneGraph();
\r
216 private static final Key KEY_SG = new SceneGraphNodeKey(INode.class, "DEBUG_SG_NODE");
\r
219 public void init(IElement e, G2DParentNode parent) {
\r
220 ShapeNode node = parent.getOrCreateNode("debug", ShapeNode.class);
\r
221 if (node != null) {
\r
222 node.setTransform(new AffineTransform(ElementUtils.getTransform(e)));
\r
223 node.setShape(ElementUtils.getElementBounds(e));
\r
224 node.setFill(true);
\r
225 node.setColor(Color.CYAN);
\r
226 e.setHint(KEY_SG, node);
\r
231 public void cleanup(IElement e) {
\r
232 ElementUtils.removePossibleNode(e, KEY_SG);
\r
238 static class RowElementSelectionHandler implements SelectionSpecification {
\r
243 private static final long serialVersionUID = 2539536175525595035L;
\r
245 static final RowElementSelectionHandler INSTANCE = new RowElementSelectionHandler();
\r
248 private RowElementSelectionHandler() {
\r
252 public Object getAdapter(Class adapter) {
\r
254 if (adapter.equals(OutlineColorSpec.class)){
\r
255 return new OutlineColorSpec() {
\r
259 private static final long serialVersionUID = 2372559366005877243L;
\r
262 public void setColor(IElement e, Color c) {
\r
266 public Color getColor(IElement e) {
\r
267 return new Color(10,10,10,40);
\r
271 if (adapter.equals(FillColor.class)){
\r
272 return new FillColor() {
\r
276 private static final long serialVersionUID = 558080965120741509L;
\r
279 public void setFillColor(IElement e, Color c) {
\r
280 // TODO Auto-generated method stub
\r
285 public Color getFillColor(IElement e) {
\r
286 return new Color(10,10,10,40);
\r
290 if (adapter.equals(Outline.class)){
\r
291 return new Outline() {
\r
295 private static final long serialVersionUID = 272200345438045483L;
\r
298 public Shape getElementShape(IElement e) {
\r
299 return e.getHint(ElementHints.KEY_BOUNDS);
\r
303 if (adapter.equals(Transform.class)){
\r
304 return new Transform() {
\r
308 private static final long serialVersionUID = 7653122570884609688L;
\r
311 public AffineTransform getTransform(IElement e) {
\r
312 return e.getHint(ElementHints.KEY_TRANSFORM);
\r
316 public void setTransform(IElement e, AffineTransform at) {
\r
320 if (adapter.equals(StrokeSpec.class)){
\r
321 return new StrokeSpec() {
\r
326 private static final long serialVersionUID = 1074910311375484373L;
\r
329 public Stroke getStroke(IElement e) {
\r
330 return new BasicStroke(0.15f, BasicStroke.CAP_SQUARE,
\r
331 BasicStroke.CAP_SQUARE, 10.0f,
\r
336 public void setStroke(IElement e, Stroke at) {
\r
337 // TODO Auto-generated method stub
\r
343 // TODO Auto-generated method stub
\r
350 static class RowElementHandler implements InternalSize, Transform, ElementAdapter {
\r
352 static final RowElementHandler INSTANCE = new RowElementHandler();
\r
354 private static final long serialVersionUID = 829379327756475944L;
\r
356 private RowElementHandler() {
\r
360 public Rectangle2D getBounds(IElement e, Rectangle2D size) {
\r
362 size = new Rectangle2D.Double();
\r
363 Rectangle2D r = e.getHint(ElementHints.KEY_BOUNDS);
\r
369 public AffineTransform getTransform(IElement e) {
\r
370 AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
\r
371 return at != null ? at : new AffineTransform();
\r
375 public void setTransform(IElement e, AffineTransform at) {
\r
376 e.setHint(ElementHints.KEY_TRANSFORM, at.clone());
\r
379 @SuppressWarnings("unchecked")
\r
381 public <T> T adapt(IElement e, Class<T> toClass) {
\r
382 if (toClass == Resource.class) {
\r
383 Wrapper ref = e.getHint(ElementHints.KEY_OBJECT);
\r
385 return (T) ref.get();
\r
393 public static class RenderHeaderTexts {
\r
394 private FlagTableInfo table = null;
\r
395 private String tableName = null;
\r
396 private EvaluationContext evaluationContext = null;
\r
398 public RenderHeaderTexts(EvaluationContext evaluationContext, FlagTableInfo table, String tableName){
\r
399 this.table = table;
\r
400 this.tableName = tableName;
\r
401 this.evaluationContext = evaluationContext;
\r
404 public void perform(){
\r
405 if (table == null || evaluationContext == null || tableName == null)
\r
408 Session session = Simantics.peekSession();
\r
409 if (session == null)
\r
412 G2DSceneGraph sg = evaluationContext.getSceneGraph();
\r
416 for (int k=0;k<table.columns.size();k++){
\r
417 FlagTableColumnInfo slotcolumn = table.columns.get(k);
\r
418 if (slotcolumn == null)
\r
421 List<MonitorInfo> monitorInfos = slotcolumn.columnHeaders;
\r
422 if (monitorInfos == null)
\r
426 for (MonitorInfo slotColumnData:monitorInfos){
\r
427 String cellNodeName = null;
\r
428 cellNodeName = cellLookupName(tableName, k, 0, cellInx);
\r
430 TextNode cellNode = (TextNode) NodeUtil.lookup(sg, cellNodeName);
\r
431 if (cellNode == null)
\r
433 String txtValue = "";
\r
434 if (slotColumnData != null && slotColumnData.getText() != null)
\r
435 txtValue = slotColumnData.getText();
\r
436 final String text = txtValue;
\r
440 if (slotColumnData.getResource() != null)
\r
441 value = Simantics.getSession().sync(new EvaluatePath(slotColumnData.getResource(), text)); // , TransientCacheListener.<String> instance()
\r
443 cellNode.setText(value.toString());
\r
444 } catch (DatabaseException e) {
\r
445 // TODO Auto-generated catch block
\r
446 e.printStackTrace();
\r
457 // public class RenderFlagTexts {
\r
458 // private FlagInfo flagInfo = null;
\r
459 // private TreeMap<String, FlagTableInfo> tables = null;
\r
460 // private EvaluationContext evaluationContext = null;
\r
462 // public RenderFlagTexts(EvaluationContext evaluationContext, FlagInfo flagInfo, TreeMap<String, FlagTableInfo> tables){
\r
463 // this.flagInfo = flagInfo;
\r
464 // this.tables = tables;
\r
465 // this.evaluationContext = evaluationContext;
\r
468 // public void perform(){
\r
469 // Session session = Simantics.peekSession();
\r
470 // if (session == null)
\r
473 // FlagTableInfo table = tables.get(flagInfo.flagTableName);
\r
474 // if (table == null)
\r
477 // G2DSceneGraph sg = evaluationContext.getSceneGraph();
\r
481 // INode tableNode = sg.lookupNode(tableLookupName(flagInfo.flagTableName));
\r
482 // if (tableNode == null)
\r
485 // Rectangle2D rowBounds = new Rectangle2D.Double(0, table.getRowHeight()*flagInfo.flagTableRowIndex, table.getWidth(), table.getRowHeight());
\r
486 // rowBounds = GeometryUtils.transformShape(rowBounds, table.affineTransform).getBounds2D();
\r
487 // addFlagElement(evaluationContext, tableNode, rowBounds, flagInfo.flag);
\r
489 // for (int k=0;k<table.columns.size();k++){
\r
490 // FlagTableColumnInfo slotcolumn = table.columns.get(k);
\r
491 // if (slotcolumn == null)
\r
494 // List<MonitorInfo> monitorInfos = slotcolumn.columnDatas;
\r
495 // if (monitorInfos == null)
\r
498 // int cellInx = 0;
\r
499 // for (MonitorInfo slotColumnData:monitorInfos){
\r
500 // String cellNodeName = cellLookupName(flagInfo.flagTableName, k, flagInfo.flagTableRowIndex, cellInx);
\r
502 // TextNode cellNode = (TextNode) NodeUtil.lookup(sg, cellNodeName);
\r
503 // if (cellNode == null)
\r
506 // String txtValue = "";
\r
507 // if (slotColumnData != null && slotColumnData.getText() != null)
\r
508 // txtValue = slotColumnData.getText();
\r
509 // final String text = txtValue;
\r
512 // String value = null;
\r
513 // if (slotcolumn.getType() != FlagTableColumnInfo.TYPE_ROW_NUMBERING)
\r
514 // value = Simantics.getSession().sync(new EvaluatePath(flagInfo.flag, text)); // , TransientCacheListener.<String> instance()
\r
515 // if (value != null)
\r
516 // cellNode.setText(value.toString());
\r
517 // } catch (DatabaseException e) {
\r
518 // // TODO Auto-generated catch block
\r
519 // e.printStackTrace();
\r
526 public static class EvaluatePath extends ResourceRead<String> {
\r
527 private String path = null;
\r
529 public EvaluatePath(Resource res, String path) {
\r
532 // this.flagInfo = flagInfo;
\r
536 public String perform(ReadGraph g) throws DatabaseException {
\r
537 PredefinedVariables vars = PredefinedVariables.getInstance();
\r
538 Variable resourceVariable = Variables.getVariable(g, resource);
\r
539 //v = g.adapt(this.flag, Variable.class);
\r
540 if (resourceVariable == null)
\r
542 Variable property = vars.getVariable(g, path, resource, resourceVariable);
\r
543 Object value = null;
\r
544 if (property == null)
\r
547 value = property.getValue(g);
\r
548 } catch (DatabaseException ex){
\r
550 if (value == null || !(value instanceof String))
\r
552 return value.toString();
\r
556 public static class RenderTable {
\r
557 private FlagTableInfo table = null;
\r
558 private String tableName = null;
\r
559 private EvaluationContext evaluationContext = null;
\r
561 public RenderTable(EvaluationContext evaluationContext, FlagTableInfo table, String tableName){
\r
562 this.table = table;
\r
563 this.evaluationContext = evaluationContext;
\r
564 this.tableName = tableName;
\r
567 public void perform(){
\r
569 G2DSceneGraph sg = evaluationContext.getSceneGraph();
\r
572 G2DParentNode nav = (G2DParentNode) sg.getNode(SceneGraphConstants.NAVIGATION_NODE_NAME);
\r
576 String tableNodeName = tableLookupName(tableName);
\r
577 RTreeNode tableNode = (RTreeNode) sg.getNode(tableNodeName);
\r
578 if (tableNode == null){
\r
579 tableNode = ProfileVariables.claimChild(evaluationContext.getSceneGraph(),
\r
580 SceneGraphConstants.NAVIGATION_NODE_NAME, tableNodeName, RTreeNode.class, //SingleElementNode.class,
\r
581 evaluationContext);
\r
583 if (tableNode == null)
\r
585 tableNode.setTransform(new AffineTransform(table.affineTransform));
\r
586 //tableNode.setVisible(false);
\r
587 tableNode.setLookupId(tableNodeName);
\r
589 // Initialize row node book-keeping for this table
\r
590 evaluationContext.setProperty(tableNode, SLOT_TABLE_ELEMENTS, new ArrayList<IElement>());
\r
592 Integer rowCount = table.getRowCount();
\r
596 // test if table is already generated
\r
597 String colNodeName = SLOT_TABLE_PREFIX + tableName + SLOT_TABLE_SEPARATOR + "0";
\r
598 RTreeNode colNode = (RTreeNode) sg.getNode(colNodeName);
\r
599 if (colNode != null)
\r
602 tableNode.setZIndex(2);
\r
604 //if (table.columns.size()> 0){
\r
605 // draw horisontal lines
\r
606 for (int k=-1;k<rowCount;k++){
\r
607 int lineY = (int)(table.getRowHeight()*k+table.getRowHeight());
\r
608 if (k==-1 || k+1 == rowCount){
\r
609 this.addLine("line_" + k, 0, lineY, table.getWidth().intValue(), lineY, BasicStroke.CAP_BUTT, tableNode);
\r
612 this.addLine("lineEnd_" + k, table.getWidth().intValue()-3, lineY, table.getWidth().intValue(), lineY, BasicStroke.CAP_BUTT, tableNode);
\r
613 this.addLine("lineStart_" + k, 0, lineY, 3, lineY, BasicStroke.CAP_BUTT, tableNode);
\r
616 // draw the first vertical line
\r
617 int lineY = (int)(table.getRowHeight()*(rowCount));
\r
618 this.addLine("bar_0", 0, 0, 0, lineY, BasicStroke.CAP_SQUARE, tableNode);
\r
619 // draw the last vertical line
\r
620 this.addLine("bar_last", (int)((double)table.getWidth()), 0, (int)((double)table.getWidth()), lineY, BasicStroke.CAP_SQUARE, tableNode);
\r
624 // Support header row hiding when there are no header columns
\r
626 int maxColumnHeaders = 0;
\r
627 if (table.columns.size() > 0) {
\r
628 for (FlagTableColumnInfo column : table.columns) {
\r
629 maxColumnHeaders = Math.max(maxColumnHeaders, column.columnHeaders.size());
\r
633 // generate columns and cells
\r
634 String cellNodeName = null;
\r
635 TextNode cellNode = null;
\r
636 for (int k = 0;k<table.columns.size();k++){
\r
637 colNodeName = SLOT_TABLE_PREFIX + tableName + SLOT_TABLE_SEPARATOR + k;
\r
638 colNode = ProfileVariables.claimChild(evaluationContext.getSceneGraph(),
\r
639 SceneGraphConstants.NAVIGATION_NODE_NAME+"."+tableNodeName, colNodeName, RTreeNode.class,
\r
640 evaluationContext);
\r
641 if (colNode == null)
\r
644 double colXAfter = 0.0;
\r
645 if (table.getWeightTotal() != 0.0){
\r
646 double weightBefore = 0.0;
\r
647 for (int m=0;m<k;m++){
\r
648 FlagTableColumnInfo slotcolumn = table.columns.get(m);
\r
649 if (slotcolumn == null || slotcolumn.getWeight() == Float.NaN)
\r
651 weightBefore = weightBefore + slotcolumn.getWeight();
\r
653 FlagTableColumnInfo slotcolumn = table.columns.get(k);
\r
654 colXAfter = ((weightBefore+slotcolumn.getWeight())/table.getWeightTotal())*table.getWidth();
\r
655 double procent = weightBefore/table.getWeightTotal();
\r
656 colX = procent*table.getWidth();
\r
657 colNode.setTransform(AffineTransform.getTranslateInstance(colX, 0.0));
\r
660 // draw intermediate vertical lines
\r
661 // int lineY = (int)(table.getRowHeight()*(rowCount));
\r
662 // this.addLine("bar_" + (k+1), (int)colXAfter, 0, (int)colXAfter, lineY, BasicStroke.CAP_SQUARE, tableNode);
\r
664 FlagTableColumnInfo slotcolumn = table.columns.get(k);
\r
665 double cellProcent = slotcolumn.getWeight()/table.getWeightTotal();
\r
666 float cellWidth = (float)cellProcent*table.getWidth();
\r
667 if (cellWidth < 0.0)
\r
669 if (cellWidth == 0.0F)
\r
672 for (int lineInx=0;lineInx<rowCount;lineInx++){
\r
673 List<MonitorInfo> monitorInfos = slotcolumn.columnDatas;
\r
674 if (lineInx < maxColumnHeaders)
\r
675 monitorInfos = slotcolumn.columnHeaders;
\r
678 for (MonitorInfo slotColumnData:monitorInfos){
\r
679 cellNodeName = cellLookupName(tableName, k, lineInx, cellInx);
\r
681 cellNode = ProfileVariables.claimChild(evaluationContext.getSceneGraph(),
\r
682 SceneGraphConstants.NAVIGATION_NODE_NAME+"."+tableNodeName+"."+colNodeName, cellNodeName, TextNode.class,
\r
683 evaluationContext);
\r
684 if (cellNode == null)
\r
686 cellNode.setLookupId(cellNodeName);
\r
688 AffineTransform transform = new AffineTransform();
\r
689 if (slotColumnData != null){
\r
690 if (slotColumnData.getFont() != null)
\r
691 cellNode.setFont(Fonts.awt(slotColumnData.getFont()));
\r
692 if (slotColumnData.getColor() != null)
\r
693 cellNode.setColor(Colors.awt(slotColumnData.getColor()));
\r
694 if (slotColumnData.getTransform() != null)
\r
695 transform = new AffineTransform(slotColumnData.getTransform());
\r
697 cellNode.setVerticalAlignment((byte) 3);
\r
698 double cellY = table.getRowHeight()*lineInx+DrawingTemplateInfo.BASELINE_VERTICAL_OFFSET*table.getRowHeight();
\r
699 //cellNode.setText("yÃ…column_" + k);
\r
700 cellNode.setText("");
\r
701 if (lineInx >= maxColumnHeaders && slotcolumn.getType() == FlagTableColumnInfo.TYPE_ROW_NUMBERING){
\r
703 cellNode.setText(new Integer(lineInx-maxColumnHeaders+slotcolumn.getStartOffset()).toString());
\r
704 cellNode.setHorizontalAlignment((byte) 0);
\r
707 // FontMetrics metrics = new FontMetrics(cellNode.getFont());
\r
708 // double dy = (metrics.getAscent() + metrics.getLeading())/2;
\r
709 cellNode.setBorderWidth(0.f);
\r
710 cellNode.setPadding(0.0, 0.0);
\r
711 Rectangle2D bounds = cellNode.getBoundsInLocal();
\r
712 //double dy = bounds.getHeight()/2.0;
\r
713 transform.translate(0.0, cellY);
\r
714 cellNode.setTransform(transform);
\r
715 cellNode.setFixedWidth(cellWidth);
\r
720 //tableNode.setVisible(true);
\r
723 void addLine(String nodeId, int x1, int y1, int x2, int y2, int cap, RTreeNode parent){
\r
724 Line2D line = new Line2D.Float(x1, y1, x2, y2);
\r
725 BasicStroke stroke = new BasicStroke(TranslateFlag.lineWidth, cap, BasicStroke.JOIN_MITER);
\r
726 ShapeNode shape = parent.addNode(nodeId, ShapeNode.class); // SingleElementNode
\r
727 shape.setShape(line);
\r
728 shape.setScaleStroke(false);
\r
729 shape.setStroke(stroke);
\r
730 shape.setFill(false);
\r
731 shape.setColor(new Color(0, 0, 0));
\r
732 shape.setZIndex(10);
\r
736 protected void cleanupStyleForItem(EvaluationContext evaluationContext, DataNodeMap map, Object item) {
\r
737 INode root = evaluationContext.getSceneGraph();
\r
738 if (root instanceof G2DSceneGraph) {
\r
739 G2DSceneGraph sg = (G2DSceneGraph) root;
\r
740 G2DParentNode nav = (G2DParentNode) sg.getNode(SceneGraphConstants.NAVIGATION_NODE_NAME);
\r
742 // ProfileVariables.denyChildren(nav, SLOT_TABLE_PREFIX);
\r
744 IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM);
\r
745 for (String childId : NodeUtil.filterDirectChildIds(nav, SLOT_TABLE_PREFIX)) {
\r
746 INode child = nav.getNode(childId);
\r
747 List<IElement> elements = evaluationContext.setProperty(child, SLOT_TABLE_ELEMENTS, null);
\r
748 if (elements != null && diagram != null)
\r
749 for (IElement e : elements)
\r
750 cleanupElement(diagram, e);
\r
751 nav.removeNode(childId);
\r
756 private void cleanupElement(IDiagram diagram, IElement e) {
\r
757 diagram.removeElement(e);
\r
761 * @param tableName slot table name
\r
762 * @return lookup ID for the cell node
\r
764 private static String tableLookupName(String tableName) {
\r
765 return new StringBuilder()
\r
766 .append(SLOT_TABLE_PREFIX)
\r
767 .append(tableName).toString();
\r
771 * @param tableName slot table name
\r
772 * @param column 0..C-1, where C is the amount of columns
\r
773 * @param row 0..N, where 0 is header
\r
774 * @return lookup ID for the cell node
\r
776 private static String cellLookupName(String tableName, int column, int row, int index) {
\r
777 return new StringBuilder()
\r
778 .append(SLOT_TABLE_PREFIX)
\r
780 .append(SLOT_TABLE_SEPARATOR)
\r
782 .append(SLOT_TABLE_SEPARATOR)
\r
784 .append(SLOT_TABLE_SEPARATOR)
\r
785 .append(index).toString();
\r
788 private IElement addFlagElement(EvaluationContext evaluationContext, INode tableNode, Rectangle2D bounds, Resource flag) {
\r
789 IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM);
\r
790 assert diagram != null;
\r
791 List<IElement> elements = evaluationContext.getProperty(tableNode, SLOT_TABLE_ELEMENTS);
\r
792 assert elements != null;
\r
793 IElement e = newFlagElement(evaluationContext, bounds, flag);
\r
795 diagram.addElement(e);
\r
799 private IElement newFlagElement(EvaluationContext evaluationContext, Rectangle2D bounds, Resource flag) {
\r
800 IElement e = Element.spawnNew(rowElementClass);
\r
801 e.setHint(ElementHints.KEY_BOUNDS, bounds.clone());
\r
802 e.setHint(ElementHints.KEY_TRANSFORM, new AffineTransform());
\r
803 // Just incase there's problems with same objects in multiple diagram elements
\r
804 //e.setHint(ElementHints.KEY_OBJECT, flag);
\r
805 // Didn't seem to help though.
\r
806 e.setHint(ElementHints.KEY_OBJECT, new Wrapper(flag));
\r
811 public String toString() {
\r
812 return "Flag table style";
\r
816 * IO table flag elements need a wrapper KEY_OBJECT whose toString()
\r
817 * produces something else besides {@link Resource#toString()}.
\r
819 public static class Wrapper extends AtomicReference<Resource> {
\r
820 private static final long serialVersionUID = -4041629837352874410L;
\r
821 public Wrapper(Resource r) {
\r
825 public String toString() {
\r
826 return "IO-" + super.toString();
\r