Bug 13080 fixed: Datatip contextual menu did not exist 25/14125/3
Calixte DENIZET [Tue, 25 Mar 2014 15:09:49 +0000 (16:09 +0100)]
Change-Id: I5cf15405407f90896773eb1ef93c3bcde6377929

scilab/CHANGES_5.5.X
scilab/modules/gui/src/java/org/scilab/modules/gui/datatip/DatatipCreate.java
scilab/modules/gui/src/java/org/scilab/modules/gui/datatip/DatatipManager.java
scilab/modules/gui/src/java/org/scilab/modules/gui/datatip/DatatipManagerMode.java
scilab/modules/gui/src/java/org/scilab/modules/gui/editor/Editor.java
scilab/modules/gui/src/java/org/scilab/modules/gui/editor/EditorEventListener.java

index 0fc557a..8b38c0f 100644 (file)
@@ -696,6 +696,8 @@ Scilab Bug Fixes
 
 * Bug #13066 fixed - data_bounds was not fully documented in axes_properties.
 
+* Bug #13080 fixed - No contextual menu was available for datatips management.
+
 * Bug #13082 fixed - Datatip mark style was not inherited from the parent polyline.
 
 * Bug #13083 fixed - Datatip marks did not inherit colors from the parent polyline.
index 56f54c7..545e835 100755 (executable)
@@ -170,6 +170,8 @@ public class DatatipCreate {
             controller.setProperty(newDatatip, GraphicObjectProperties.__GO_CLIP_STATE__, 0);
         }
 
+        DatatipManagerMode.getInstance().setLastTip(axesUid, newDatatip);
+
         return newDatatip;
     }
 
@@ -179,7 +181,7 @@ public class DatatipCreate {
      * @param datatipUid datatip unique identifier.
      * @param interpMode boolean for the interpolation mode.
      */
-    private static void datatipSetInterp(int uid, boolean interpMode) {
+    public static void datatipSetInterp(int uid, boolean interpMode) {
         GraphicController controller = GraphicController.getController();
         Object o = controller.getObjectFromId(uid);
         if (o instanceof Datatip) {
index 2b5269c..c3a248c 100644 (file)
 
 package org.scilab.modules.gui.datatip;
 
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+import org.scilab.modules.commons.gui.FindIconHelper;
 import org.scilab.modules.localization.Messages;
+import org.scilab.modules.gui.editor.AxesHandler;
+import org.scilab.modules.gui.editor.ObjectSearcher;
 import org.scilab.modules.gui.editor.EntityPicker;
+import org.scilab.modules.gui.utils.ScilabSwingUtilities;
 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
 import org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties;
+import org.scilab.modules.renderer.CallRenderer;
 import org.scilab.modules.renderer.JoGLView.DrawerVisitor;
 
 /**
@@ -24,18 +52,22 @@ import org.scilab.modules.renderer.JoGLView.DrawerVisitor;
  */
 public class DatatipManagerMode {
     private static DatatipManagerMode instance;
+
     private Integer selectedTip;
     private Integer markColor;
 
     private Integer figureUid;
     private boolean datatipManagerModeStatus;
 
+    private Map<Integer, Stack<Integer>> lastDatatips;
+
     private static String datatipMessage = Messages.gettext("Left click on the curve creates a datatip and right click on the datatip removes it.");
 
     public DatatipManagerMode() {
         instance = this;
         selectedTip = null;
         figureUid = null;
+        lastDatatips = new HashMap<Integer, Stack<Integer>>();
         datatipManagerModeStatus = false;
     }
 
@@ -81,7 +113,6 @@ public class DatatipManagerMode {
         return datatipManagerModeStatus;
     }
 
-
     public void setSelectedTip(Integer uid) {
         markColor = highlightSelected(uid, selectedTip, markColor);
         selectedTip = uid;
@@ -91,6 +122,30 @@ public class DatatipManagerMode {
         return selectedTip;
     }
 
+    public void setLastTip(Integer axes, Integer uid) {
+        Stack<Integer> stack = lastDatatips.get(axes);
+        if (stack == null) {
+            stack = new Stack<Integer>();
+            lastDatatips.put(axes, stack);
+        }
+
+        stack.push(uid);
+    }
+
+    public Integer getLastTip(Integer axes) {
+        Stack<Integer> stack = lastDatatips.get(axes);
+        if (stack != null && !stack.isEmpty()) {
+            return stack.pop();
+        }
+
+        return null;
+    }
+
+    public boolean hasLast(Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        return axes != null && lastDatatips.containsKey(axes) && !lastDatatips.get(axes).isEmpty();
+    }
+
     public void enableTranslation(boolean enabled) {
         DrawerVisitor.getVisitor(figureUid).getInteractionManager().setTranslationEnable(enabled);
     }
@@ -109,6 +164,15 @@ public class DatatipManagerMode {
     }
 
     /**
+     * Set figure uid
+     *
+     * @param uid Figure unique identifier.
+     */
+    public Integer getFigure() {
+        return figureUid;
+    }
+
+    /**
      * Highlight the datatip mark when selected
      *
      * @param newTip datatip to highlight.
@@ -117,7 +181,6 @@ public class DatatipManagerMode {
      * @return the original datatip mark color.
      */
     private Integer highlightSelected(Integer newTip, Integer oldTip, Integer oldTipColor) {
-
         Integer color = 0;
         if (oldTip != null) {
             GraphicController.getController().setProperty(oldTip, GraphicObjectProperties.__GO_MARK_BACKGROUND__, oldTipColor);
@@ -149,4 +212,270 @@ public class DatatipManagerMode {
         }
         return (datatip != null);
     }
+
+    /**
+     * On right mouse click, set popup menu visible.
+     * @param event MouseEvent to retrieve click positon in figure.
+     */
+    public void onRightMouseClick(final MouseEvent e) {
+        JPopupMenu menu = new JPopupMenu();
+        JMenuItem deleteAll = new JMenuItem(Messages.gettext("Delete all the datatips"));
+        deleteAll.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                deleteAll(new Integer[] {e.getX(), e.getY()});
+            }
+        });
+
+        JMenuItem deleteAllOnCurve = new JMenuItem(Messages.gettext("Delete all the datatips on the selected curve"));
+        deleteAllOnCurve.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                deleteAllOnCurve(new Integer[] {e.getX(), e.getY()});
+            }
+        });
+        deleteAllOnCurve.setEnabled(onCurve(new Integer[] {e.getX(), e.getY()}));
+
+        JMenuItem deleteNearest = new JMenuItem(Messages.gettext("Delete the nearest datatip"));
+        deleteNearest.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                deleteNearest(new Integer[] {e.getX(), e.getY()});
+            }
+        });
+
+        JMenuItem deleteLast = new JMenuItem(Messages.gettext("Delete the last datatip"));
+        deleteLast.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                deleteLast(new Integer[] {e.getX(), e.getY()});
+            }
+        });
+        deleteLast.setEnabled(hasLast(new Integer[] {e.getX(), e.getY()}));
+
+        JMenuItem editDisplayFunction = new JMenuItem(Messages.gettext("Edit curve datatip display function"));
+        editDisplayFunction.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                editDisplayFunction(e.getComponent(), new Integer[] {e.getX(), e.getY()});
+            }
+        });
+        editDisplayFunction.setEnabled(onCurve(new Integer[] {e.getX(), e.getY()}));
+
+        JMenuItem enableInterpolation = new JMenuItem(Messages.gettext("Enable interpolation"));
+        enableInterpolation.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                enableInterpolation(new Integer[] {e.getX(), e.getY()}, true);
+            }
+        });
+        enableInterpolation.setEnabled(onCurve(new Integer[] {e.getX(), e.getY()}));
+
+        JMenuItem disableInterpolation = new JMenuItem(Messages.gettext("Disable interpolation"));
+        disableInterpolation.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent actionEvent) {
+                enableInterpolation(new Integer[] {e.getX(), e.getY()}, false);
+            }
+        });
+        disableInterpolation.setEnabled(onCurve(new Integer[] {e.getX(), e.getY()}));
+
+        menu.add(deleteAll);
+        menu.add(deleteAllOnCurve);
+        menu.add(deleteNearest);
+        menu.add(deleteLast);
+        menu.addSeparator();
+        menu.add(editDisplayFunction);
+        menu.addSeparator();
+        menu.add(enableInterpolation);
+        menu.add(disableInterpolation);
+
+        menu.show(e.getComponent(), e.getX(), e.getY());
+    }
+
+    /**
+     * Enable interpolation
+     * @param pos the mouse position
+     * @param enabled to enable or not tuhe interpolation
+     */
+    private void enableInterpolation(Integer[] pos, boolean enabled) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            final Integer curve = (new EntityPicker()).pick(getFigure(), pos[0], pos[1]);
+            if (curve != null) {
+                DatatipCreate.datatipSetInterp(curve, enabled);
+            }
+        }
+    }
+
+    /**
+     * Edit display function
+     * @param c the component
+     * @param pos the mouse position
+     */
+    private void editDisplayFunction(Component c, Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            final Integer curve = (new EntityPicker()).pick(getFigure(), pos[0], pos[1]);
+            if (curve != null) {
+                String fnc = (String) GraphicController.getController().getProperty(curve, GraphicObjectProperties.__GO_DATATIP_DISPLAY_FNC__);
+                JFrame parentWin = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, c);
+                final JDialog dialog = new JDialog(parentWin);
+                dialog.setIconImage(new ImageIcon(FindIconHelper.findIcon("datatips")).getImage());
+                dialog.setTitle(Messages.gettext("Display function name"));
+                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+                ScilabSwingUtilities.closeOnEscape(dialog);
+                boolean isWin = System.getProperty("os.name").toLowerCase().contains("windows");
+                JPanel main = new JPanel();
+                final JTextField text = new JTextField(30);
+                text.setText(fnc);
+                JButton ok = new JButton(Messages.gettext("OK"));
+                ActionListener valid = new ActionListener() {
+                    public void actionPerformed(ActionEvent actionEvent) {
+                        String s = text.getText();
+                        if (s != null && !s.isEmpty()) {
+                            GraphicController.getController().setProperty(curve, GraphicObjectProperties.__GO_DATATIP_DISPLAY_FNC__, s);
+                        }
+                        dialog.dispose();
+                    }
+                };
+
+                ok.addActionListener(valid);
+                text.addActionListener(valid);
+
+                JButton cancel = new JButton(Messages.gettext("Cancel"));
+                cancel.addActionListener(new ActionListener() {
+                    public void actionPerformed(ActionEvent actionEvent) {
+                        dialog.dispose();
+                    }
+                });
+
+                main.setLayout(new GridBagLayout());
+                GridBagConstraints gbc = new GridBagConstraints();
+
+                gbc.gridx = gbc.gridy = 0;
+                gbc.gridwidth = 3;
+                gbc.weightx = gbc.weighty = 1;
+                gbc.fill = GridBagConstraints.HORIZONTAL;
+                gbc.insets = new Insets(10, 5, 5, 5);
+                main.add(text, gbc);
+
+                gbc.gridx = 0;
+                gbc.gridy = 1;
+                gbc.weighty = 0;
+                gbc.gridwidth = 1;
+                gbc.fill = GridBagConstraints.HORIZONTAL;
+                main.add(new JPanel(), gbc);
+
+                gbc.gridx = isWin ? 1 : 2;
+                gbc.weightx = gbc.weighty = 0;
+                gbc.anchor = GridBagConstraints.LINE_START;
+                gbc.fill = GridBagConstraints.NONE;
+                gbc.insets = new Insets(0, 0, 5, 5);
+                main.add(ok, gbc);
+
+                gbc.gridx = isWin ? 2 : 1;
+                main.add(cancel, gbc);
+
+                dialog.setContentPane(main);
+                dialog.pack();
+
+                Point loc = parentWin.getLocationOnScreen();
+                Dimension pdim = parentWin.getSize();
+                Dimension ddim = dialog.getSize();
+                dialog.setLocation(loc.x + (pdim.width - ddim.width) / 2, loc.y + (pdim.height - ddim.height) / 2);
+                dialog.setVisible(true);
+
+                text.requestFocus();
+            }
+        }
+    }
+
+    /**
+     * Delete last datatip
+     * @param pos the mouse position
+     */
+    private void deleteLast(Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            Integer datatip = getLastTip(axes);
+            if (datatip != null) {
+                DatatipDelete.deleteDatatip(datatip);
+            }
+        }
+    }
+
+    /**
+     * Delete the nearest datatip
+     * @param pos the mouse position
+     */
+    private void deleteNearest(Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            Integer[] datatips = (new ObjectSearcher()).search(axes, GraphicObjectProperties.__GO_DATATIP__, true);
+            if (datatips != null) {
+                int x = pos[0];
+                int y = pos[1];
+                double min = Double.POSITIVE_INFINITY;
+                int datatip = -1;
+                for (int i : datatips) {
+                    Double[] tip_pos = (Double[]) GraphicController.getController().getProperty(i, GraphicObjectProperties.__GO_DATATIP_DATA__);
+                    double[] point = new double[] {tip_pos[0], tip_pos[1], tip_pos[2]};
+                    double[] pix = CallRenderer.getPixelFrom3dCoordinates(axes, point);
+                    double d = Math.hypot(x - pix[0], y - pix[1]);
+                    if (d < min) {
+                        min = d;
+                        datatip = i;
+                    }
+                }
+
+                if (datatip != -1) {
+                    DatatipDelete.deleteDatatip(datatip);
+                }
+            }
+        }
+    }
+
+    /**
+     * Delete all datatips on a curve
+     * @param pos the mouse position
+     */
+    private void deleteAllOnCurve(Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            Integer curve = (new EntityPicker()).pick(getFigure(), pos[0], pos[1]);
+            if (curve != null) {
+                Integer[] datatips = (Integer[]) GraphicController.getController().getProperty(curve, GraphicObjectProperties.__GO_DATATIPS__);
+                if (datatips != null) {
+                    for (int i : datatips) {
+                        DatatipDelete.deleteDatatip(i);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Delete all datatips
+     * @param pos the mouse position
+     */
+    private void deleteAll(Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            Integer[] datatips = (new ObjectSearcher()).search(axes, GraphicObjectProperties.__GO_DATATIP__, true);
+            if (datatips != null) {
+                for (int i : datatips) {
+                    DatatipDelete.deleteDatatip(i);
+                }
+            }
+        }
+    }
+
+    /**
+     * Check if we are on a curve
+     * @param pos the mouse position
+     * @return true if the click occured on a curve
+     */
+    private boolean onCurve(Integer[] pos) {
+        Integer axes = AxesHandler.clickedAxes(getFigure(), pos);
+        if (axes != null) {
+            Integer curve = (new EntityPicker()).pick(getFigure(), pos[0], pos[1]);
+            return curve != null;
+        }
+
+        return false;
+    }
 }
index cac58a3..3fe038d 100644 (file)
@@ -127,7 +127,6 @@ public class Editor {
      * @param event MouseEvent to retrieve click positon in figure.
      */
     public void onRightMouseClick(MouseEvent event) {
-
         if (!dataEditEnabled) {
             lastClick[0] = event.getX();
             lastClick[1] = event.getY();
index 3c6250a..c9940bb 100644 (file)
@@ -188,7 +188,9 @@ public class EditorEventListener implements KeyListener, MouseListener, MouseMot
                 }
             } else {
                 if (arg0.getButton() == 3 && !isInRotation) {
-                    datatipManagerMode.pickAndDelete(arg0.getX(), arg0.getY());
+                    if (!datatipManagerMode.pickAndDelete(arg0.getX(), arg0.getY())) {
+                        datatipManagerMode.onRightMouseClick(arg0);
+                    }
                 }
                 datatipManagerMode.enableTranslation(true);
             }