From 03b96add4cb06b8c694772d9e369bb257c9d88e6 Mon Sep 17 00:00:00 2001 From: lempinen Date: Tue, 13 Mar 2012 07:12:22 +0000 Subject: [PATCH] Font chooser to context menu of diagram elements, including dependencies. (refs #2959) git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@24416 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.sysdyn.ontology/graph.tg | Bin 90504 -> 90536 bytes .../graph/Sysdyn.pgraph | 2 +- org.simantics.sysdyn.ui/META-INF/MANIFEST.MF | 1 - org.simantics.sysdyn.ui/plugin.xml | 17 ++ .../ui/editor/routing/DependencyRouter.java | 2 + .../DependencyConnectionFactory.java | 101 ++++----- .../connections/DependencyEdgeClass.java | 13 +- .../elements2/connections/DependencyNode.java | 169 ++++++++-------- .../connections/SysdynConnectionClass.java | 17 +- .../handlers/FontContextMenuContribution.java | 191 ++++++++++++++++++ .../ui/properties/VariableInformationTab.java | 103 ++-------- .../properties/widgets/CustomFontDialog.java | 86 +++++--- 12 files changed, 447 insertions(+), 255 deletions(-) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FontContextMenuContribution.java diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index d1dcc33a4b740c5a8113585809344d74e411f1d5..bb8b1f48baca7664d8af54eb4ccbd1efac04087c 100644 GIT binary patch delta 51 wcmeA;%(~(*>jnWk#vhvn?GDeBO<`bQ@M2(Ktpw6f7#J9l`A;`ryuQ5?0FM(6@Bjb+ delta 21 dcmZ2+n6=|D>jnWk#t)kX?GDe}{N?(VP5^5(3dsNf diff --git a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph index 0e46d521..99219f2a 100644 --- a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph +++ b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph @@ -405,7 +405,7 @@ SYSDYN.FlowConnection -- SYSDYN.DependencyConnection.polarity --> L0.String -- SYSDYN.DependencyConnection.polarityLocation --> L0.String + + + + + + + + + + diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java index e7d42fc5..bbd982da 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java @@ -12,6 +12,8 @@ import org.simantics.sysdyn.ui.elements2.connections.Arcs; import org.simantics.utils.datastructures.Pair; public class DependencyRouter implements IRouter2 { + + public static DependencyRouter INSTANCE = new DependencyRouter(); @Override public void route(IConnection connection) { diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java index 4baa6824..10af9e77 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in + * Copyright (c) 2010, 2012 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 @@ -17,20 +17,24 @@ import java.util.concurrent.atomic.AtomicInteger; import org.simantics.databoard.Bindings; import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.db.procedure.SyncProcedure; +import org.simantics.diagram.G2DUtils; import org.simantics.diagram.adapter.ElementFactoryAdapter; import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; import org.simantics.layer0.Layer0; -import org.simantics.modeling.ModelingResources; import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; import org.simantics.utils.datastructures.Pair; @@ -61,8 +65,50 @@ public class DependencyConnectionFactory extends ElementFactoryAdapter { final AtomicInteger ready = new AtomicInteger(1); final ConcurrentSkipListMap> properties = new ConcurrentSkipListMap>(); - element.setHint(DiagramHints.ROUTE_ALGORITHM, new DependencyRouter()); - + element.setHint(DiagramHints.ROUTE_ALGORITHM, DependencyRouter.INSTANCE); + + G2DResource G2D; + try { + G2D = G2DResource.getInstance(graph.getSession()); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + // Find possible font + graph.forPossibleObject(elementResource, G2D.HasFont, new SyncProcedure() { + + @Override + public void execute(ReadGraph graph, Resource result) throws DatabaseException { + if(result != null) { + element.setHint(ElementHints.KEY_FONT, G2DUtils.getFont(graph, result)); + } + } + + @Override + public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException { + throwable.printStackTrace(); + } + }); + + // Find possible color + graph.forPossibleObject(elementResource, G2D.HasColor, new SyncProcedure() { + + @Override + public void execute(ReadGraph graph, Resource result) throws DatabaseException { + if(result != null) { + element.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, result)); + } + } + + @Override + public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException { + throwable.printStackTrace(); + } + }); + + + // A complicated-looking procedure for obtaining all HasProperties to properties map graph.forEachPredicate(elementResource, new AsyncMultiProcedure() { @Override @@ -75,14 +121,13 @@ public class DependencyConnectionFactory extends ElementFactoryAdapter { ready.incrementAndGet(); Layer0 l0; - ModelingResources mr; try { l0 = Layer0.getInstance(graph.getSession()); - mr = ModelingResources.getInstance(graph.getSession()); } catch (DatabaseException e) { e.printStackTrace(); return; } + graph.forIsSubrelationOf(property, l0.HasProperty, new AsyncProcedure() { @Override @@ -124,7 +169,6 @@ public class DependencyConnectionFactory extends ElementFactoryAdapter { public void execute(AsyncReadGraph graph, String name) { properties.put(name, Pair.make(property, value)); -// System.out.println("load properties " + name + " => " + value); if(ready.decrementAndGet() == 0) { element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); procedure.execute(graph, element); @@ -151,49 +195,6 @@ public class DependencyConnectionFactory extends ElementFactoryAdapter { } }); - - -// graph.forPossibleObject(elementResource, mr.DiagramConnectionToConnection, new AsyncProcedure() { -// -// @Override -// public void execute(AsyncReadGraph graph, Resource result) { -// SysdynResource sr; -// try { -// sr = SysdynResource.getInstance(graph.getSession()); -// } catch (DatabaseException e) { -// e.printStackTrace(); -// return; -// } -// graph.forPossibleRelatedValue(result, sr.Polarity, Bindings.STRING, new AsyncProcedure() { -// -// @Override -// public void exception(AsyncReadGraph graph, Throwable throwable) { -// throwable.printStackTrace(); -// } -// -// @Override -// public void execute(AsyncReadGraph graph, String name) { -// -// properties.put("polarity", Pair.make(property, (Object)name)); -//// System.out.println("load properties " + name + " => " + value); -// if(ready.decrementAndGet() == 0) { -// element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); -// procedure.execute(graph, element); -// } -// -// } -// -// }); -// -// } -// -// @Override -// public void exception(AsyncReadGraph graph, Throwable throwable) { -// throwable.printStackTrace(); -// } -// -// }); - } @Override diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java index 45d4e7ae..a87f6423 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in + * Copyright (c) 2010, 2012 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 @@ -62,9 +62,11 @@ import org.simantics.utils.datastructures.hints.IHintContext.Key; public class DependencyEdgeClass { - public static class NodePick implements Pick { + private static class NodePick implements Pick { private static final long serialVersionUID = 1L; + + public static NodePick INSTANCE = new NodePick(); @Override public boolean pickTest(IElement e, Shape s, PickPolicy policy) { @@ -86,7 +88,6 @@ public class DependencyEdgeClass { } - // TODO scale, rotate, move, transform public static final ElementClass CLASS = ElementClass.compile( SysdynEdgeSceneGraph.INSTANCE, @@ -97,7 +98,7 @@ public class DependencyEdgeClass { TextImpl.INSTANCE, TextColorImpl.BLACK, TextFontImpl.DEFAULT, - new NodePick(), + NodePick.INSTANCE, ConnectionSelectionOutline.INSTANCE, SimpleElementLayers.INSTANCE, ParentImpl.INSTANCE @@ -121,8 +122,8 @@ public class DependencyEdgeClass { Color color = ElementUtils.getTextColor(e); HashMap properties = e.getHint(DiagramHints.PROPERTIES); - Pair polarityPair = (Pair)properties.get("Polarity"); - Pair polarityLocationPair = (Pair)properties.get("PolarityLocation"); + Pair polarityPair = (Pair)properties.get("polarity"); + Pair polarityLocationPair = (Pair)properties.get("polarityLocation"); String location; if(polarityLocationPair == null) diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java index 529ca158..95513a8f 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in + * Copyright (c) 2010, 2012 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 @@ -16,9 +16,6 @@ import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Stroke; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; import java.awt.geom.Arc2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; @@ -27,17 +24,27 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.utils.Alignment; import org.simantics.scenegraph.ISelectionPainterNode; -import org.simantics.scenegraph.g2d.events.ISGMouseEvent; +import org.simantics.scenegraph.g2d.events.EventTypes; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; import org.simantics.scenegraph.utils.NodeUtil; import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; import org.simantics.utils.datastructures.Pair; -public class DependencyNode extends TextNode implements ISelectionPainterNode, MouseListener, MouseMotionListener { +/** + * Node for dependency arrows and polarity text + * @author Teemu Lempinen + * + */ +public class DependencyNode extends TextNode implements ISelectionPainterNode { public static final String INSIDE = "Inside"; public static final String OUTSIDE = "Outside"; - + private static final long serialVersionUID = 1294351381209071074L; private static final BasicStroke STROKE = new BasicStroke(1.0f); @@ -51,26 +58,37 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode, M private transient Pair shapes = new Pair(new Arc2D.Double(), new Path2D.Double()); transient public boolean hover = false; + private boolean dragging = false; private transient PropertyChangeListener fieldListener = null; @Override public void init() { super.init(); - NodeUtil.getEventDelegator(this).addMouseListener(this); - NodeUtil.getEventDelegator(this).addMouseMotionListener(this); + addEventHandler(this); + } - - + + + /** + * Inits the dependency node with a text + * @param text Polarity + * @param side Polarity Location + * @param font Font + * @param color Color + * @param x Text initial location x + * @param y Text initial location y + * @param scale Scale + */ public void init(String text, String side, Font font, Color color, double x, double y, double scale) { super.init(text, font, color, x, y, scale); this.side = side; + setHorizontalAlignment((byte) Alignment.CENTER.ordinal()); + setVerticalAlignment((byte) Alignment.CENTER.ordinal()); } @Override public void cleanup() { - NodeUtil.getEventDelegator(this).removeMouseListener(this); - NodeUtil.getEventDelegator(this).removeMouseMotionListener(this); super.cleanup(); } @@ -157,6 +175,7 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode, M //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); boolean selected = NodeUtil.isSelected(this, 2); + if(font != null) g.setFont(font); if(selected) { g.setColor(Color.PINK); g.setStroke(STROKE); @@ -182,44 +201,39 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode, M g.fill(shapes.second); } - double angleRad = angle > 0 ? Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent()) : Math.toRadians(shapes.first.getAngleStart()); - Point2D point = angle > 0 ? shapes.first.getEndPoint() : shapes.first.getStartPoint(); - - int angle1 = 225; - int angle2 = -75; - if(OUTSIDE.equals(side)) { - angle1 *= -1; - angle2 *= -1; - } - double a = Math.toRadians(angle < 0 ? angle1 : angle2); - double s = Math.sin(a) * 2; - double c = Math.cos(a) * 3; - - g.translate(point.getX(), point.getY()); - g.rotate(-angleRad); - g.translate(s, c); - g.rotate(angleRad); - super.render(g); - g.rotate(-angleRad); - g.translate(-s, -c); - g.rotate(angleRad); - g.translate(-point.getX(), -point.getY()); - + Point2D point = angle > 0 ? shapes.first.getEndPoint() : shapes.first.getStartPoint(); + + int angle1 = 220; + int angle2 = -40; + if(OUTSIDE.equals(side)) { + angle1 *= -1; + angle2 *= -1; + } + double a = Math.toRadians(angle < 0 ? angle1 : angle2); + double s = Math.sin(a) * 3; + double c = Math.cos(a) * 4; + + g.translate(point.getX(), point.getY()); + g.rotate(-angleRad); + g.translate(s, c); + g.rotate(angleRad); + super.render(g); + g.rotate(-angleRad); + g.translate(-s, -c); + g.rotate(angleRad); + g.translate(-point.getX(), -point.getY()); + } boolean pressHit = false; - private boolean hitTest(MouseEvent event, double tolerance) { - if(event instanceof ISGMouseEvent) { - if(beginBounds == null || endBounds == null) return false; - - return Arcs.hitTest(beginBounds, endBounds, angle, ((ISGMouseEvent)event).getDoubleX(), ((ISGMouseEvent)event).getDoubleY(), tolerance); - } else { - return false; - } + private boolean hitTest(org.simantics.scenegraph.g2d.events.MouseEvent event, double tolerance) { + if(beginBounds == null || endBounds == null) return false; + Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double()); + return Arcs.hitTest(beginBounds, endBounds, angle, localPos.getX(), localPos.getY(), tolerance); } @Override @@ -228,58 +242,53 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode, M } @Override - public void mouseDragged(MouseEvent e) { - if(pressHit && e instanceof ISGMouseEvent) { + public int getEventMask() { + return super.getEventMask() | EventTypes.MouseDragBeginMask + | EventTypes.MouseButtonPressedMask + | EventTypes.MouseButtonReleasedMask + ; + } + + @Override + protected boolean mouseMoved(MouseMovedEvent event) { + boolean hit = hitTest(event, 3.0); + if(dragging) { + Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double()); + setAngle(Arcs.angleOfArc( beginBounds.getCenterX(), beginBounds.getCenterY(), - ((ISGMouseEvent)e).getDoubleX(), ((ISGMouseEvent)e).getDoubleY(), + localPos.getX(), localPos.getY(), endBounds.getCenterX(), endBounds.getCenterY())); + repaint(); } - } - - @Override - public void mouseMoved(MouseEvent e) { - boolean hit = hitTest(e, 3.0); - if(hit != hover) { + + if (hit != hover) { hover = hit; repaint(); } + return false; } @Override - public void mouseClicked(MouseEvent e) { - // TODO Auto-generated method stub - + protected boolean mouseDragged(MouseDragBegin e) { + if(!dragging && hitTest(e, 3.0)) { + dragging = true; + return true; // consume event + } else { + return false; + } } @Override - public void mousePressed(MouseEvent e) { - boolean hit = hitTest(e, 3.0); - pressHit = hit; - if(hit) { - commitProperty("angle", angle); - } - + protected boolean mouseButtonPressed(MouseButtonPressedEvent e) { + return false; } - @Override - public void mouseReleased(MouseEvent e) { - boolean hit = hitTest(e, 3.0); - if(hit) { + protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) { + if(dragging) { commitProperty("angle", angle); + dragging = false; } + return false; } - - @Override - public void mouseEntered(MouseEvent e) { - // TODO Auto-generated method stub - - } - - @Override - public void mouseExited(MouseEvent e) { - // TODO Auto-generated method stub - - } - } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java index ed1fc608..79899e87 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in + * Copyright (c) 2010, 2012 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 @@ -11,7 +11,9 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.elements2.connections; +import java.awt.Color; import java.awt.Composite; +import java.awt.Font; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; @@ -47,6 +49,8 @@ import org.simantics.g2d.element.handler.Transform; import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.element.handler.impl.ParentImpl; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; import org.simantics.g2d.element.handler.impl.TextImpl; import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; import org.simantics.g2d.utils.GeometryUtils; @@ -69,6 +73,8 @@ public class SysdynConnectionClass { public static final ElementClass CLASS = ElementClass.compile( TextImpl.INSTANCE, + TextFontImpl.DEFAULT, + TextColorImpl.BLACK, FixedTransform.INSTANCE, ConnectionPick.INSTANCE, ConnectionBounds.INSTANCE, @@ -156,6 +162,9 @@ public class SysdynConnectionClass { Set tmp = new HashSet(); Map> properties = connection.getHint(DiagramHints.PROPERTIES); + + Font font = connection.getHint(ElementHints.KEY_FONT); + Color color = connection.getHint(ElementHints.KEY_TEXT_COLOR); int zIndex = 0; for (IElement child : children) { @@ -171,6 +180,12 @@ public class SysdynConnectionClass { if(properties != null) child.setHint(DiagramHints.PROPERTIES, properties); + if(font != null) + child.setHint(ElementHints.KEY_FONT, font); + + if(color != null) + child.setHint(ElementHints.KEY_TEXT_COLOR, color); + SingleElementNode holder = child.getHint(ElementHints.KEY_SG_NODE); if (holder == null) { holder = parent.addNode(ElementUtils.generateNodeId(child), SingleElementNode.class); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FontContextMenuContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FontContextMenuContribution.java new file mode 100644 index 00000000..9b2b9e05 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FontContextMenuContribution.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 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.sysdyn.ui.handlers; + +import java.awt.Color; +import java.awt.Font; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.G2DUtils; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.contribution.DynamicMenuContribution; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Context menu contribution for modifying fonts and font colors in diagram elements + * + * @author Teemu Lempinen + * + */ +public class FontContextMenuContribution extends DynamicMenuContribution { + + @Override + protected IContributionItem[] getContributionItems(final ReadGraph graph, + Object[] selection) throws DatabaseException { + if (selection.length == 0) + return new IContributionItem[0]; + + return new IContributionItem[] { new ContributionItem() { + + @Override + public void fill(Menu menu, int index) { + + G2DResource G2D = G2DResource.getInstance(graph); + + Object[] selections = getSelectedObjects(); + + Font font = null; + Color color = null; + + /* + * Find a common font and color for the selected elements. + * + * If a common font or color is not found, the initial value in dialog is empty. + */ + try { + for(Object o : selections) { + Resource element = ResourceAdaptionUtils + .adaptToResource(o); + Resource fontResource = graph.getPossibleObject(element, G2D.HasFont); + if(fontResource != null) { + Font newFont = G2DUtils.getFont(graph, fontResource); + if(font == null) { + font = newFont; + } + + if(font != null && !font.equals(newFont)) { + font = null; + break; + } + } + } + } catch (DatabaseException e) { + } + + try { + for(Object o : selections) { + Resource element = ResourceAdaptionUtils + .adaptToResource(o); + Resource colorResource = graph.getPossibleObject(element, G2D.HasColor); + if(colorResource != null ) { + Color newColor = G2DUtils.getColor(graph, colorResource); + if(color == null) + color = newColor; + + if(color != null && !color.equals(newColor)) { + color = null; + break; + } + } + } + } catch (DatabaseException e) { + } + + // Create the menu item with a selection listener + MenuItem item; + item = new MenuItem(menu, SWT.PUSH); + + item.setText("Font..."); + + item.addSelectionListener(new FontSelectionListener(selections, font, color)); + } + } + }; + + } + + /** + * Selection listener for font context menu action + * @author Teemu Lempinen + * + */ + class FontSelectionListener implements SelectionListener { + + private Font font; + private Color color; + private Object[] selections; + + /** + * Font selection listener for context menu action in diagram + * + * @param selections Selected elements + * @param font Possible common font for the selected elements + * @param color Possible common color for the selected elements + */ + public FontSelectionListener(Object[] selections, Font font, Color color) { + this.selections = selections; + this.font = font; + this.color = color; + } + + @Override + public void widgetSelected(SelectionEvent e) { + // Create the dialog + CustomFontDialog dialog = new CustomFontDialog(e.widget.getDisplay().getActiveShell(), "Sample"); + + // Set possible font and color defaults + if(font != null) + dialog.setAWTFont(font); + + if(color != null) + dialog.setColor(color); + + // Open dialog + dialog.open(); + + // Get results + final Font resultFont = dialog.getAWTFont(); + final Color resultColor = dialog.getAWTColor(); + + // Apply results to all selected elements + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + G2DResource G2D = G2DResource.getInstance(graph); + + for(Object o : selections) { + Resource element = ResourceAdaptionUtils + .adaptToResource(o); + if(resultFont != null) { + graph.deny(element, G2D.HasFont); + graph.claim(element, G2D.HasFont, G2DUtils.createFont(graph, resultFont)); + } + + if(resultColor != null) { + graph.deny(element, G2D.HasColor); + graph.claim(element, G2D.HasColor, G2DUtils.createColor(graph, resultColor)); + } + } + } + }); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java index 9781e8e2..d084ad4a 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java @@ -13,16 +13,13 @@ package org.simantics.sysdyn.ui.properties; import java.awt.Color; -import javax.swing.JPanel; - import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.SWTException; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; @@ -306,7 +303,7 @@ public class VariableInformationTab extends LabelPropertyTabContributor implemen @Override public void run() { if(result.first != null) { - FontData fd = toSwtFontData(device, result.first, true); + FontData fd = toSwtFontData(result.first); sample.setFont(new Font(device, fd)); } if(result.second != null) { @@ -317,7 +314,11 @@ public class VariableInformationTab extends LabelPropertyTabContributor implemen result.second.getBlue()) ); } - sample.getWidget().getParent().getParent().layout(); + try { + sample.getWidget().getParent().getParent().layout(); + } catch (SWTException e) { + + } } }); @@ -337,96 +338,16 @@ public class VariableInformationTab extends LabelPropertyTabContributor implemen } } - - - /** - * Copied from jfreechart experimental SWTUtils - */ - private final static String Az = "ABCpqr"; - public static java.awt.Font toAwtFont(Device device, FontData fontData, - boolean ensureSameSize) { - int height = (int) Math.round(fontData.getHeight() * device.getDPI().y - / 72.0); - // hack to ensure the newly created awt fonts will be rendered with the - // same height as the swt one - if (ensureSameSize) { - GC tmpGC = new GC(device); - Font tmpFont = new Font(device, fontData); - tmpGC.setFont(tmpFont); - JPanel DUMMY_PANEL = new JPanel(); - java.awt.Font tmpAwtFont = new java.awt.Font(fontData.getName(), - fontData.getStyle(), height); - if (DUMMY_PANEL.getFontMetrics(tmpAwtFont).stringWidth(Az) - > tmpGC.textExtent(Az).x) { - while (DUMMY_PANEL.getFontMetrics(tmpAwtFont).stringWidth(Az) - > tmpGC.textExtent(Az).x) { - height--; - tmpAwtFont = new java.awt.Font(fontData.getName(), - fontData.getStyle(), height); - } - } - else if (DUMMY_PANEL.getFontMetrics(tmpAwtFont).stringWidth(Az) - < tmpGC.textExtent(Az).x) { - while (DUMMY_PANEL.getFontMetrics(tmpAwtFont).stringWidth(Az) - < tmpGC.textExtent(Az).x) { - height++; - tmpAwtFont = new java.awt.Font(fontData.getName(), - fontData.getStyle(), height); - } - } - tmpFont.dispose(); - tmpGC.dispose(); - } - return new java.awt.Font(fontData.getName(), fontData.getStyle(), - height); - } - - /** - * Copied from jfreechart SWTUtils + * Create SWT FontData based on AWT Font + * @param font AWT Font + * @return SWT FontData based on AWT Font */ - private static final JPanel DUMMY_PANEL = new JPanel(); - public static FontData toSwtFontData(Device device, java.awt.Font font, - boolean ensureSameSize) { + private static FontData toSwtFontData(java.awt.Font font) { FontData fontData = new FontData(); fontData.setName(font.getFamily()); - // SWT and AWT share the same style constants. fontData.setStyle(font.getStyle()); - // convert the font size (in pt for awt) to height in pixels for swt - int height = (int) Math.round(font.getSize() * 72.0 - / device.getDPI().y); - fontData.setHeight(height); - // hack to ensure the newly created swt fonts will be rendered with the - // same height as the awt one - if (ensureSameSize) { - GC tmpGC = new GC(device); - Font tmpFont = new Font(device, fontData); - tmpGC.setFont(tmpFont); - if (tmpGC.textExtent(Az).x - > DUMMY_PANEL.getFontMetrics(font).stringWidth(Az)) { - while (tmpGC.textExtent(Az).x - > DUMMY_PANEL.getFontMetrics(font).stringWidth(Az)) { - tmpFont.dispose(); - height--; - fontData.setHeight(height); - tmpFont = new Font(device, fontData); - tmpGC.setFont(tmpFont); - } - } - else if (tmpGC.textExtent(Az).x - < DUMMY_PANEL.getFontMetrics(font).stringWidth(Az)) { - while (tmpGC.textExtent(Az).x - < DUMMY_PANEL.getFontMetrics(font).stringWidth(Az)) { - tmpFont.dispose(); - height++; - fontData.setHeight(height); - tmpFont = new Font(device, fontData); - tmpGC.setFont(tmpFont); - } - } - tmpFont.dispose(); - tmpGC.dispose(); - } + fontData.setHeight(font.getSize()); return fontData; } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java index 51f70069..71c62662 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java @@ -61,7 +61,7 @@ public class CustomFontDialog extends Dialog { private org.eclipse.swt.graphics.Color swtColor; // Default color map - private static Map createColorMap() { + protected static Map createColorMap() { LinkedHashMap colors = new LinkedHashMap(); colors.put("Black", SWT.COLOR_BLACK); colors.put("White", SWT.COLOR_WHITE); @@ -142,17 +142,14 @@ public class CustomFontDialog extends Dialog { public org.eclipse.swt.graphics.Color getSWTColor() { return swtColor; } - - @Override - protected Control createDialogArea(Composite parent) - { - Composite composite = ( Composite )super.createDialogArea(parent); - composite.getShell().setText("Choose Font"); - - GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); - - // Font selection composite - vpc = new FontSelectionComposite(composite, SWT.NONE); + + + /** + * Creates font choosing area + * @param parent Parent composite + */ + protected void createFontChooser(Composite parent) { + vpc = new FontSelectionComposite(parent, SWT.NONE); vpc.setFont(awtFont, false); GridDataFactory.fillDefaults().span(2, 1).applyTo(vpc); @@ -169,8 +166,14 @@ public class CustomFontDialog extends Dialog { } }); - // Color selection - Composite colorComposite = new Composite(composite, SWT.NONE); + } + + /** + * Creates a TableCombo for choosing a color for a font + * @param parent Parent composite + */ + protected void createColorChooser(Composite parent) { + Composite colorComposite = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorComposite); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(colorComposite); @@ -185,7 +188,11 @@ public class CustomFontDialog extends Dialog { tc.setDisplayColumnIndex(1); tc.setToolTipText("this is tooltip"); - createItems(tc.getTable()); + if(swtColor != null) { + tc.setForeground(swtColor); + } + + createColorItems(tc.getTable()); if(this.color != null) { for(int i = 0; i < tc.getTable().getItemCount(); i++) { @@ -210,6 +217,7 @@ public class CustomFontDialog extends Dialog { org.eclipse.swt.graphics.Color color = (org.eclipse.swt.graphics.Color) selection[0].getData(); swtColor = color; sample.setForeground(swtColor); + tc.setForeground(swtColor); } tc.getTextControl().setSelection(0); tc.getParent().forceFocus(); @@ -219,9 +227,14 @@ public class CustomFontDialog extends Dialog { public void widgetDefaultSelected(SelectionEvent e) { } }); - - // Sample text - sampleGroup = new Group(composite, SWT.NONE); + } + + /** + * Creates a sample text area + * @param parent Parent composite + */ + protected void createSampleArea(Composite parent) { + sampleGroup = new Group(parent, SWT.NONE); sampleGroup.setText("Sample"); GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 70).applyTo(sampleGroup); GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(sampleGroup); @@ -232,14 +245,35 @@ public class CustomFontDialog extends Dialog { swtFont = new org.eclipse.swt.graphics.Font(sample.getDisplay(), toSwtFontData(awtFont, -1)); sample.setFont(swtFont); } - if(color != null) { - swtColor = new org.eclipse.swt.graphics.Color(sample.getDisplay(), color.getRed(), color.getGreen(), color.getBlue()); + if(swtColor != null) { sample.setForeground(swtColor); } GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).applyTo(sample); + } + + @Override + protected Control createDialogArea(Composite parent) + { + Composite composite = ( Composite )super.createDialogArea(parent); + composite.getShell().setText("Choose Font"); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + // Init SWT color, if AWT color has been set + if(color != null) + this.swtColor = new org.eclipse.swt.graphics.Color(Display.getCurrent(), color.getRed(), color.getGreen(), color.getBlue()); + + // Font selection composite + createFontChooser(composite); + + // Color selection + createColorChooser(composite); + + // Sample text + createSampleArea(composite); //Set the dialog position in the middle of the monitor - setDialogLocation(); + setDialogLocationToMonitorCenter(); return composite; } @@ -273,7 +307,7 @@ public class CustomFontDialog extends Dialog { /** * Sets the dialog location to the middle of the screen */ - private void setDialogLocation() { + protected void setDialogLocationToMonitorCenter() { Rectangle monitorArea = getShell().getDisplay().getPrimaryMonitor().getBounds(); Rectangle shellArea = getShell().getBounds(); int x = monitorArea.x + (monitorArea.width - shellArea.width)/2; @@ -300,17 +334,18 @@ public class CustomFontDialog extends Dialog { * Creates color items for color combo * @param table */ - private void createItems(Table table) { + protected void createColorItems(Table table) { Image image; GC gc; TableItem ti; int code; org.eclipse.swt.graphics.Color color; + Display display = Display.getCurrent(); for(String text : systemColors.keySet()) { code = systemColors.get(text); - color = Display.getCurrent().getSystemColor(code); + color = display.getSystemColor(code); - image = new Image(Display.getCurrent(), 25, 15); + image = new Image(display, 25, 15); gc = new GC (image); gc.setBackground (color); gc.fillRectangle (image.getBounds()); @@ -320,6 +355,7 @@ public class CustomFontDialog extends Dialog { ti = new TableItem(table, SWT.NONE); ti.setImage(0, image); ti.setText(1, text); + ti.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); ti.setData(color); } -- 2.47.1