2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Clement DAVID
4 * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
17 package org.scilab.modules.xcos.palette;
19 import java.awt.Point;
20 import java.awt.datatransfer.Transferable;
21 import java.awt.dnd.DnDConstants;
22 import java.awt.dnd.DragGestureEvent;
23 import java.awt.dnd.DragGestureListener;
24 import java.awt.dnd.DragSource;
25 import java.awt.dnd.InvalidDnDOperationException;
26 import java.awt.event.MouseListener;
27 import java.lang.ref.WeakReference;
28 import java.util.logging.Level;
29 import java.util.logging.Logger;
31 import org.scilab.modules.gui.messagebox.ScilabModalDialog;
32 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
33 import org.scilab.modules.localization.Messages;
34 import org.scilab.modules.xcos.JavaController;
35 import org.scilab.modules.xcos.Kind;
36 import org.scilab.modules.xcos.block.BasicBlock;
37 import org.scilab.modules.xcos.graph.XcosDiagram;
38 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
39 import org.scilab.modules.xcos.io.scicos.ScicosFormatException;
40 import org.scilab.modules.xcos.palette.listener.PaletteBlockMouseListener;
41 import org.scilab.modules.xcos.palette.model.PaletteBlock;
42 import org.scilab.modules.xcos.palette.view.PaletteBlockView;
43 import org.scilab.modules.xcos.palette.view.PaletteManagerView;
44 import org.scilab.modules.xcos.utils.BlockPositioning;
45 import org.scilab.modules.xcos.utils.XcosMessages;
47 import com.mxgraph.swing.handler.mxGraphTransferHandler;
48 import com.mxgraph.swing.util.mxGraphTransferable;
49 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
52 * A palette block is the representation of the block in the palette. All the
53 * operations there are used to render, load and put (on a diagram) a block.
55 public final class PaletteBlockCtrl {
57 * Internal graph used to render each block.
59 public static final XcosDiagram INTERNAL_GRAPH;
61 JavaController controller = new JavaController();
62 INTERNAL_GRAPH = new XcosDiagram(controller, controller.createObject(Kind.DIAGRAM), Kind.DIAGRAM, "");
63 INTERNAL_GRAPH.installListeners();
66 private static final double BLOCK_DEFAULT_POSITION = 10.0;
67 private static final MouseListener MOUSE_LISTENER = new PaletteBlockMouseListener();
68 private static final Logger LOG = Logger.getLogger(PaletteBlockCtrl.class.getName());
70 private static final String UNABLE_TO_LOAD_BLOCK = Messages.gettext("Unable to load block from %s .");
71 private static final String LOADING_THE_BLOCK = Messages.gettext("Loading the block") + XcosMessages.DOTS;
73 private static PaletteBlockCtrl previouslySelected;
75 private final PaletteBlock model;
76 private final PaletteBlockView view;
78 private transient WeakReference<Transferable> transferable = new WeakReference<Transferable>(null);
86 public PaletteBlockCtrl(PaletteBlock model) {
88 this.view = new PaletteBlockView(this);
89 installListeners(this.view);
96 private void installListeners(PaletteBlockView view) {
97 view.addMouseListener(MOUSE_LISTENER);
104 public PaletteBlockView getView() {
111 public PaletteBlock getModel() {
116 * This function is the only access to get the block.
118 * @return the transferable object
119 * @throws ScicosFormatException
122 public synchronized Transferable getTransferable() throws ScicosFormatException {
123 Transferable transfer = transferable.get();
124 if (transfer == null) {
127 block = XcosCellFactory.createBlock(model.getName());
128 } catch (ScilabInterpreterManagement.InterpreterException ex) {
129 LOG.finest(String.format(UNABLE_TO_LOAD_BLOCK, model.getName()));
130 getView().setEnabled(false);
131 throw new InvalidDnDOperationException();
133 getView().setEnabled(true);
135 /* Render it and export it */
136 block.getGeometry().setX(BLOCK_DEFAULT_POSITION);
137 block.getGeometry().setY(BLOCK_DEFAULT_POSITION);
139 INTERNAL_GRAPH.addCell(block);
140 INTERNAL_GRAPH.selectAll();
142 BlockPositioning.updateBlockView(INTERNAL_GRAPH, block);
144 mxGraphTransferHandler handler = ((mxGraphTransferHandler) INTERNAL_GRAPH.getAsComponent().getTransferHandler());
145 Object[] cells = new Object[] {block};
146 transfer = new mxGraphTransferable(cells, INTERNAL_GRAPH.getPaintBounds(cells), handler.createTransferableImage(INTERNAL_GRAPH.getAsComponent(), cells));
147 transferable = new WeakReference<Transferable>(transfer);
149 INTERNAL_GRAPH.removeCells();
155 * This function load the block and render it on the hidden diagram. This
156 * can be time-consuming and each block should be cached on the caller when
159 * @return a rendered block
161 public BasicBlock getBlock() {
163 return (BasicBlock) ((mxGraphTransferable) getTransferable()).getCells()[0];
164 } catch (ScicosFormatException e) {
165 LOG.severe(e.toString());
171 * @return true if it is selected, false otherwise
173 public boolean isSelected() {
174 return this == previouslySelected;
179 * the selected state to set
181 public void setSelected(boolean selected) {
183 if (previouslySelected != null) {
184 previouslySelected.setSelected(false);
186 previouslySelected = this;
188 getView().setSelectedUI(selected);
192 * Install the Drag'n'Drop on this instance.
194 public void installDnd() {
195 // Install the handler for dragging nodes into a graph
196 DragGestureListener dragGestureListener = new DragGestureListener() {
198 public void dragGestureRecognized(DragGestureEvent e) {
199 if (PaletteManagerView.get() == null) {
200 PaletteManagerView.restore(null);
202 final PaletteManagerView winView = PaletteManagerView.get();
203 final DragGestureEvent event = e;
204 final String msg = String.format(UNABLE_TO_LOAD_BLOCK, getModel().getName());
206 winView.setInfo(LOADING_THE_BLOCK);
208 Transferable transfer = getTransferable();
210 if (transfer != null) {
211 event.startDrag(null, null, new Point(), transfer, null);
213 throw new InvalidDnDOperationException();
215 } catch (InvalidDnDOperationException exception) {
216 ScilabModalDialog.show(winView, msg, XcosMessages.XCOS_ERROR, IconType.ERROR_ICON);
217 } catch (ScicosFormatException ex) {
218 ScilabModalDialog.show(winView, ex.getMessage(), XcosMessages.XCOS_ERROR, IconType.ERROR_ICON);
220 winView.setInfo(XcosMessages.EMPTY_INFO);
226 DragSource dragSource = DragSource.getDefaultDragSource();
227 dragSource.createDefaultDragGestureRecognizer(this.getView(), DnDConstants.ACTION_COPY, dragGestureListener);