1

We are creating some graphical applications to the our project. We are using Draw2d and GEF technologies in our project. We have to draw one rectangle in the draw area. The functionality is as follows.

  1. Use click the rectangle button from the toolbar.
  2. Changes cursor to Cross curson symbol.
  3. When the user clicks the area and drag the mouse, it shows the rectangle based on the dragging of the mouse.

Till now it is working fine. Now the issue is, we have zoom in and zoom out functionality. When the use zoom in and draw the rectangle, it is not coming in the desired position. It is going below parts of the area.Then user has to scroll and see the rectangle. This problem happens only when we use zoom in and zoom out.

How to ressolve this issue? Please see my code below.

package draw2dview;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.FreeformViewport;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.ScalableFigure;
import org.eclipse.draw2d.ScalableFreeformLayeredPane;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.actions.ZoomInAction;
import org.eclipse.gef.ui.actions.ZoomOutAction;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart implements org.eclipse.swt.events.MouseListener {
    public static final String ID = "draw2dview.view";



    private Action drawAction;
    private ScalableFreeformLayeredPane root;
    ScalableRootEditPart editPart = null ;
    private XYLayout layout;
    private ZoomManager zoomManager ;

    EditDomain editDomain = new DefaultEditDomain(null);
    GraphicalViewer graphicalViewer = new ScrollingGraphicalViewer();
    ScalableFreeformRootEditPart rootEditPart = new ScalableFreeformRootEditPart();



    private FigureCanvas createContents(Composite parent){



        root = new ScalableFreeformLayeredPane();
        zoomManager = new ZoomManager(root,new FreeformViewport());
        root.setFont(parent.getFont());
        //layout = new XYLayout();

        layout= new FreeformLayout();
        root.setLayoutManager(layout);




        FigureCanvas figureCanvas = new FigureCanvas(parent,SWT.DOUBLE_BUFFERED);
        figureCanvas.addMouseListener(this);
        figureCanvas.setBackground(ColorConstants.white);
        LightweightSystem lws = new LightweightSystem(figureCanvas);
        lws.setContents(root);
        return figureCanvas ;

    }




    private IFigure createPersonFigure() {
        RectangleFigure rectangleFigure = new RectangleFigure();
        rectangleFigure.setBackgroundColor(ColorConstants.blue);
        rectangleFigure.setLayoutManager(new ToolbarLayout());
        rectangleFigure.setPreferredSize(100, 100);
        return rectangleFigure ;
    }




    /**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
    public void createPartControl(Composite parent) {

    /*  graphicalViewer.createControl(parent);
        editDomain.addViewer(graphicalViewer);
        graphicalViewer.setRootEditPart(rootEditPart);*/

        createContents(parent);
        createAction();
        contributeToActionBars();
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();

        addToToolBar(bars.getToolBarManager());
    }


    private void addToToolBar(IToolBarManager toolBarManager2){
        toolBarManager2.add(drawAction);
        toolBarManager2.add(new ZoomInAction(zoomManager));
        toolBarManager2.add(new ZoomOutAction(zoomManager));


    }

    private void createAction() {
        drawAction = new Action() {
            public void run() {
                System.out.println("execued..");


            }
        };
        drawAction.setText("Draw");
        drawAction.setImageDescriptor(Activator.getImageDescriptor("icons/alt_window_16.gif"));
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
    //  viewer.getControl().setFocus();
    }




    @Override
    public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {


    }




    @Override
    public void mouseDown(org.eclipse.swt.events.MouseEvent e) {

        System.out.println("inside..Mousedeown:: "+e.x+","+e.y);
        IFigure personFigure = createPersonFigure();                
        root.add(personFigure);
        layout.setConstraint(personFigure, new Rectangle(new Point(e.x,e.y),personFigure.getPreferredSize()));
        //layout.setConstraint(personFigure, new Rectangle(new Point(e.x,e.y),personFigure.getPreferredSize()));
    }




    @Override
    public void mouseUp(org.eclipse.swt.events.MouseEvent e) {


    }

}

2 Answers2

0

You will need to scale your mouse event coordinates according to the zoom level your zoom manager is currently using. The mouse events are absolute pixels, but your ZoomManger is causing a scale factor to be applied to your figure's coordinates. I think you will also need to take into account your ViewPort's client area.

First, when you constuct your ZoomManager pass in the ViewPort from your FigureCanvas:

zoomManager = new ZoomManager(root, figureCanvas.getViewPort());

Then try something like:

double scaleFactor = zoomManager.getZoom();
Rectangle r = figureCanvas.getViewport().getClientArea();
layout.setConstraint(personFigure, new Rectangle(new Point((e.x + r.x) * scaleFactor,(e.y + r.y) * scaleFactor),personFigure.getPreferredSize()));

This may need tweaked to get it right, let me know....

Malcolm Smith
  • 3,540
  • 25
  • 29
  • No it is not working. Can I have your email please? I would like to ask you some more doubts!!!if you dont mind.. – Parameswaran May 10 '12 at 12:51
  • I'd rather keep it on the stack. Has the new code improved matters? It must now at least now be broken in a different way? – Malcolm Smith May 12 '12 at 10:08
0

You have to translate from absolute coordinates obtained from the mouse event to relative coordinates to the person figure's parent:

@Override
public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
    System.out.println("inside..Mousedeown:: "+e.x+","+e.y);
    IFigure personFigure = createPersonFigure();                
    root.add(personFigure);
    Point p = new PrecisionPoint(e.x,e.y);
    personFigure.translateToRelative(p);
    layout.setConstraint(personFigure, new Rectangle(p,personFigure.getPreferredSize()));
}

For more information look at draw2d help

Jan Krakora
  • 2,500
  • 3
  • 25
  • 52