/******************************************************************************* * Copyright (c) 2007, 2010 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.g2d.utils; import java.util.function.Supplier; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.scenegraph.g2d.events.command.Command; import org.simantics.scenegraph.g2d.events.command.CommandEvent; import org.simantics.scenegraph.g2d.events.command.Commands; import org.simantics.utils.threads.IThreadWorkQueue; import org.simantics.utils.threads.ThreadUtils; /** * @author Toni Kalajainen * @author Tuukka Lehtonen */ public class CanvasUtils { /** * Enqueue a command in the event queue of the specified canvas context. * * @param ctx queue context * @param commandId ID of the command to queue * * @see #sendCommand(ICanvasContext, Command) */ public static void sendCommand(ICanvasContext ctx, String commandId) { sendCommand(ctx, new Command(commandId)); } /** * Enqueue a command in the event queue of the specified canvas context. * * @param ctx queue context * @param cmd the command to queue */ public static void sendCommand(ICanvasContext ctx, Command cmd) { CommandEvent e = new CommandEvent(ctx, System.currentTimeMillis(), cmd); ctx.getEventQueue().queueEvent(e); } /** * A utility for scheduling a zoom-to-fit operation when an Eclipse * workbench editor is initially opened. * *

* There are two asynchronous calls, first into the workbench (SWT) UI * thread and then into the canvas context thread. This will guarantee that * the parenting SWT control has been resized to its actual size instead of * the initial (0,0) size which widgets start out at. In order to perform a * zoom-to-fit operation we simply have to know the bounds of the parenting * control. Thus, we need to ensure that this information is available and * correct. * * @param swtThread * @param disposed * @param canvasContext * @param diagramToFit */ public static void scheduleZoomToFit(IThreadWorkQueue swtThread, final Supplier disposed, final ICanvasContext canvasContext, final IDiagram diagramToFit) { scheduleZoomToFit(swtThread, disposed, canvasContext, diagramToFit, true); } /** * A utility for scheduling a zoom-to-fit operation when an Eclipse * workbench editor is initially opened. * *

* There are two asynchronous calls, first into the workbench (SWT) UI * thread and then into the canvas context thread. This will guarantee that * the parenting SWT control has been resized to its actual size instead of * the initial (0,0) size which widgets start out at. In order to perform a * zoom-to-fit operation we simply have to know the bounds of the parenting * control. Thus, we need to ensure that this information is available and * correct. * * @param swtThread * @param disposed * @param canvasContext * @param diagramToFit * @param zoomToFit */ public static void scheduleZoomToFit(IThreadWorkQueue swtThread, final Supplier disposed, final ICanvasContext canvasContext, final IDiagram diagramToFit, boolean zoomToFit) { if (diagramToFit == null) throw new IllegalStateException("source diagram is null"); Boolean canvasZoomToFit = canvasContext.getHintStack().getHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT); diagramToFit.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE); if (zoomToFit && !Boolean.FALSE.equals(canvasZoomToFit)) diagramToFit.setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.TRUE); ThreadUtils.asyncExec(swtThread, new Runnable() { @Override public void run() { if (disposed.get() || canvasContext.isDisposed()) return; ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() { @Override public void run() { if (disposed.get() || canvasContext.isDisposed()) return; Boolean zoomToFit = diagramToFit.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT); diagramToFit.removeHint(Hints.KEY_DISABLE_PAINTING); if (Boolean.TRUE.equals(zoomToFit)) CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT); CanvasUtils.sendCommand(canvasContext, Commands.ENABLE_PAINTING); } }); } }); } }