javapiccolo

Is Pcanvas support double click actions to zoom instead of drag actions?


When I played the zoom example of Piccolo demo, I got one wonder that is Pcanvas only support drag actions to zoom ?

Thus I went to review the source code of Pcanvas, then I found it has one variable PZoomEventHandler to control the zoom actions. Furthermore, I reviewed the source code of PZoomEventHandler, I realized it inheritances from PDragSequenceEventHandler. Is this mean Pcanvas only support drag actions to zoom ?

If I'm correct, following are my details queries:

  1. If I want to achieve double click actions to zoom, which class in Piccolo I should use to let PZoomEventHandler inherit from instead of PDragSequenceEventHandler ?

  2. If I change the PZoomEventHandler, definitely it will affect all zoom performance. Is it better I add one more variable like PZoomEventHandlerV2 in Pcanvas to handle special zoom by using double click actions ?

Thank you for your time and suggestion. :D


Solution

  • PDragSequenceEventHandler simplifies implementation of handlers that are based on mouse dragging events. In your case you can derive from PBasicInputEventHandler. Also, you can add as many event listeners as you need, just make sure they don't interfere with each other. Read more about event listeners in Adding User Interaction.

    Below is an example of a zoom handler that reacts to a mouse wheel rotation (not sure how you wanted to un-zoom in double click based zooming so I used a mouse wheel). The example keeps the original zoom handler which is based on dragging and adds a new one based on the mouse wheel. You can also remove the original zoom handler if needed using removeInputEventListener method.

    import java.awt.Dimension;
    import java.awt.geom.Point2D;
    
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    import edu.umd.cs.piccolo.PCanvas;
    import edu.umd.cs.piccolo.PLayer;
    import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
    import edu.umd.cs.piccolo.event.PInputEvent;
    import edu.umd.cs.piccolo.nodes.PPath;
    
    public class TestZoom {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {   
                public void run() {   
                    JFrame frame = new JFrame("TestZoom");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLocationByPlatform(true);
    
                    final PCanvas canvas = new PCanvas() {
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(300, 300);
                        }
                    };
    
                    PLayer layer = new PLayer();
                    canvas.getCamera().addLayer(0, layer);
                    canvas.getCamera().getRoot().addChild(layer);
    
                    final PPath node = PPath.createRectangle(100, 100, 100, 100);
                    canvas.getLayer().addChild(node);
    
                    canvas.addInputEventListener(new MouseZoomHandler());
    
                    frame.add(canvas);            
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }
    
        public static class MouseZoomHandler extends PBasicInputEventHandler {
            @Override
            public void mouseWheelRotated(final PInputEvent event) {
                final double scale = 1 - 0.2 * event.getWheelRotation(); 
                final Point2D point = event.getPosition();
                event.getCamera().scaleViewAboutPoint(scale, 
                        point.getX(), point.getY());                
            }
        }
    }