4d654791925080230f51a9b525cc777a1f7760d7
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / elements / SVGNode.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2017 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.elements;
13
14 import java.awt.Graphics2D;
15 import java.util.List;
16 import java.util.Set;
17
18 import org.simantics.g2d.canvas.ICanvasContext;
19 import org.simantics.g2d.diagram.participant.Selection;
20 import org.simantics.g2d.element.IElement;
21 import org.simantics.scenegraph.ExportableWidget.RasterOutputWidget;
22 import org.simantics.scenegraph.INode;
23 import org.simantics.scenegraph.g2d.IG2DNode;
24 import org.simantics.scenegraph.g2d.events.EventTypes;
25 import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
26 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
27 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
28 import org.simantics.scenegraph.g2d.nodes.SVGNodeAssignment;
29 import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
30 import org.simantics.scenegraph.utils.NodeUtil;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.kitfox.svg.SVGDiagram;
35 import com.kitfox.svg.SVGException;
36 import com.kitfox.svg.Text;
37 import com.kitfox.svg.Tspan;
38
39 @RasterOutputWidget
40 public class SVGNode extends org.simantics.scenegraph.g2d.nodes.SVGNode {
41
42     private static final Logger LOGGER = LoggerFactory.getLogger(SVGNode.class);
43
44     private static final long serialVersionUID = 4735066193941274186L;
45
46     transient EditorStateManager esm  = null;
47     transient boolean parametersProcessed = false;
48
49     @Override
50     public void cleanup() {
51         if (esm != null)
52             removeEventHandler(this);
53         super.cleanup();
54     }
55
56     @Override
57     public void render(Graphics2D g2d) {
58         if (!parametersProcessed) {
59             SingleElementNode sne = getSingleElementNode();
60             if (sne != null) {
61                 Boolean enableEditing = sne.getParameter("enableEditing");
62                 if (enableEditing != null && enableEditing) {
63                     esm = new EditorStateManager(this);
64                     addEventHandler(this);
65                 }
66                 parametersProcessed = true;
67             }
68         }
69
70         super.render(g2d);
71     }
72
73     @Override
74     protected int dynamicHash() {
75         return esm != null ? esm.currentHash() : 0;
76     }
77
78     @Override
79     protected boolean applyAssignments(SVGDiagram diagram, List<SVGNodeAssignment> assignments) throws SVGException {
80         boolean changed = super.applyAssignments(diagram, assignments);
81         if (esm != null && !esm.applyEditMode(diagram))
82             diagram.updateTime(0);
83         return changed;
84     }
85
86     private boolean isSelected(IG2DNode node) {
87         ICanvasContext ctx = DiagramNodeUtil.getPossibleCanvasContext(this);
88         if (ctx == null)
89             return false;
90         IElement ie = DiagramNodeUtil.getElement(ctx, node);
91         if (ie == null)
92             return false;
93         Selection sel = ctx.getAtMostOneItemOfClass(Selection.class);
94         if (sel != null) {
95             Set<IElement> elems = sel.getSelection(0);
96             if (elems.size() == 1 && elems.contains(ie))
97                 return true;
98         }
99         return false;
100     }
101
102     private boolean isSelected() {
103         SingleElementNode sne = getSingleElementNode();
104         if (isSelected(sne))
105             return true;
106         INode n = sne.getParent();
107         while (n != null) {
108             if (isSelected((IG2DNode)n))
109                 return true;
110             n = n.getParent();
111         }
112         return false;
113     }
114
115     @Override
116     protected boolean mouseClicked(MouseClickEvent e) {
117         if(esm != null) {
118             if(esm.isEditMode()) {
119                 esm.applyEdit();
120                 esm.deactivateEdit();
121                 return true;
122             }
123             if(isSelected()) {
124                 if(esm.tryToStartEditMode(diagramCache, e))
125                     return true;
126             }
127         }
128         return super.mouseClicked(e);
129     }
130
131     SingleElementNode getSingleElementNode() {
132         return (SingleElementNode)NodeUtil.getNearestParentOfType(this, SingleElementNode.class);
133     }
134
135     @Override
136     protected boolean keyPressed(KeyPressedEvent e) {
137         if (esm != null && esm.keyPressed(e))
138             return true;
139         return super.keyPressed(e);
140     }
141
142     @Override
143     protected boolean handleCommand(CommandEvent e) {
144         if (esm != null
145                 && !esm.isEditMode()
146                 && "org.eclipse.ui.edit.rename".equals(e.command.id)
147                 && isSelected()
148                 && esm.tryToStartEditMode(diagramCache)) {
149             return true;
150         }
151         return super.handleCommand(e);
152     }
153
154     @Override
155     public int getEventMask() {
156         return EventTypes.KeyPressedMask | EventTypes.MouseClickMask | EventTypes.CommandMask;
157     }
158
159     public void modifyTextElement(String id, String newText) {
160         Text text = (Text) diagramCache.getElement(id);
161
162         EditorState es = new EditorState();
163         es.base = new EditorStateStatic();
164         es.base.textElementId = text.getId();
165
166         Tspan span = (Tspan)text.getContent().get(0);
167
168         try {
169             span.setText(newText);
170             text.rebuild();
171             diagramCache.updateTime(0);
172         } catch (SVGException e) {
173             LOGGER.error("Failed to update text span element " + id + " with text " + newText, e);
174         }
175     }
176
177 }