Chinaunix首页 | 论坛 | 博客
  • 博客访问: 516128
  • 博文数量: 95
  • 博客积分: 5168
  • 博客等级: 大校
  • 技术积分: 1271
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-28 23:31
文章分类

全部博文(95)

文章存档

2013年(2)

2012年(3)

2011年(1)

2010年(8)

2009年(81)

分类:

2009-10-12 23:53:54

-----------------------------------------------------------
本文系本站原创,欢迎转载!

转载请注明出处:http://sjj0412.cublog.cn/

-----------------------------------------------------------

 上面刚讲到事件处理已经到了Tool层,而GEF的默认Tool就是SelectionTool,故今天来讲下SelectionTool及它映射出的其他几个Tool

Class SelectionTool.

从上面我们看到各种事件处理函数:

mouseDown, mouseUPmouseDrag等,但是你可能会说怎么不见key的相关函数啊,这个其实在它的父类TargetingTool.

我们先来看一个mouseDown

 

Class SelectionTool

 

public void mouseDown(MouseEvent e, EditPartViewer viewer) {

    super.mouseDown(e, viewer);

//这一步其实就是调用handleMouseDown

    if (getDragTracker() != null)

       getDragTracker().mouseDown(e, viewer);

// DragTracker也是Tool,这种Tool主要用来针对具体事件跟踪处理的,这部分很重要,是拖曳,移动GEF图形节点的十分重要的

}

 

Class TargetingTool

 

public void mouseDown(MouseEvent me, EditPartViewer viewer) {

    if (!isViewerImportant(viewer))

       return;

    setViewer(viewer);

 

    getCurrentInput().setInput(me);

    getCurrentInput().setMouseButton(me.buttontrue);

 

    startX = me.x;

    startY = me.y;

 

    handleButtonDown(me.button);

//这个一般被重载了。

}

因为重载了,所以又是到了SelectionTool

 

Class SelectionTool

 

// handleButtonDown是真正的处理函数,同时也找到TargetEditPart,DragTracker,及向TargetEditPart发送相关request.

 

protected boolean handleButtonDown(int button) {

    if (!stateTransition(STATE_INITIALSTATE_DRAG)) {

       resetHover();

       return true;

    }

    resetHover();

    EditPartViewer viewer = getCurrentViewer();

    Point p = getLocation();

 

    if (getDragTracker() != null)

       getDragTracker().deactivate();

 

    if (viewer instanceof GraphicalViewer) {

       Handle handle = ((GraphicalViewer) viewer).findHandleAt(p);

       if (handle != null) {

           setDragTracker(handle.getDragTracker());

           return true;

       }

    //DragTracker的一种方法,比如改变大小的事件就是在这里找到DragTracker,为ResizeTracer,同时点击周围移动handle找到时movehandle,这个handle返回DragEditPartTracker.

    }

    updateTargetRequest();

//这个是更新request,比如坐标值,request type的类型,不过在selectionTool, type不变都是selection,ResizeTracertool里,其会随着state变化而变化。

    ((SelectionRequest)getTargetRequest()).setLastButtonPressed(button);

    updateTargetUnderMouse();

//这个就是更新TargetEditPart,同时进行相关feedback调用

    EditPart editpart = getTargetEditPart();

    if (editpart != null) {

       setDragTracker(editpart.getDragTracker(getTargetRequest()));

 

//这也是一种获取DragTracker的方法,想平移GEF图形节点的DragTracker就是这中方法找到的,对于一般的GraphicEditPart,其实DragEditPartTracer.

      

lockTargetEditPart(editpart);

       return true;

    }

    return false;

}

 

protected boolean updateTargetUnderMouse() {

    if (!isTargetLocked()) {

       EditPart editPart = getCurrentViewer().findObjectAtExcluding(

           getLocation(),

           getExclusionSet(),

           getTargetingConditional());

       //获取鼠标所在GEF图形节点,其中getTargetingConditional()很重要,这个将在讲解DrageEditPartTracer时将。

       if (editPart != null)

           editPart = editPart.getTargetEditPart(getTargetRequest());

       boolean changed = getTargetEditPart() != editPart;

       setTargetEditPart(editPart);

//这个是更新TargetEditPart,同时调用feedBack相关的函数。

       return changed;

    } else

       return false;

}

protected void setTargetEditPart(EditPart editpart) {

    if (editpart != targetEditPart) {

       if (targetEditPart != null)

           handleExitingEditPart();

       targetEditPart = editpart;

       if (getTargetRequest() instanceof TargetRequest)

           ((TargetRequest)getTargetRequest()).setTargetEditPart(targetEditPart);

       handleEnteredEditPart();

    }

}

当我们选择一个对象的feedback就是handleEnteredEditPart调用的。

protected boolean handleEnteredEditPart() {

    updateTargetRequest();

    showTargetFeedback();

    return true;

}

到此点击事件完成了。

其实SelectionTool从事件处理方面来说没起多大多大作用,既没有command相关的作用,也没有feedback相关的作用,因为SelectionToolrequesttypeselection,但是你看下editpart的各个policy,基本没有处理selection类型的request,不论是policygetCommand函数,还是showTargetFeedBackshowSourceFeedBack。那它的作用是什么呢?其实它可以看成是所有Tool层事件的入口,事件从它进入,然后根据不同情况选择不同真正起作用的Tool(比如DragEditPartTracer,ResizeTracer,SelectionTool的各个事件函数都要调用getDragTracker().mouseDown(up/drag/…)(e, viewer);就可以看出,同时由于SelectionTool只有Target,对于像拖曳,改变大小这些涉及sourcetarget的肯定不适合。

 

下面就开始将真正起作用的Tool,各种Tracer tool.

选择对象事件的DragTracer---SelectEditPartTracker:

对于选择对象mouseDown,移动(drag)对象都是DrageEditPartTracer,对于鼠标单击这一事件(选择对象),DrageEditPartTracer没有handleMouseDown函数,故调用的是SelectEditPartTracker的函数,所以对于选择事件,可以看成SelectEditPartTracker

    protected boolean handleButtonDown(int button) {

    if ((button == 3 || button == 1)

      && isInState(STATE_INITIAL))

       performConditionalSelection();

//这个起真正的作用,让graphicViewer选择editpart元件。

    if (button != 1) {

       setState(STATE_INVALID);

       if (button == 3)

           setState(STATE_TERMINAL);

       handleInvalidInput();

    } else

       stateTransition(STATE_INITIALSTATE_DRAG);

//左键选择节点后,就进入STATE_DRAG了。

    return true;

}

public SelectEditPartTracker(EditPart owner) {

    setSourceEditPart(owner);

}

 

protected void performConditionalSelection() {

    if (getSourceEditPart().getSelected() == EditPart.SELECTED_NONE)

       performSelection();

    else if (getCurrentInput().getModifiers() == 0)

       setFlag(FLAG_ENABLE_DIRECT_EDITtrue);

}

protected void performSelection() {

    if (hasSelectionOccurred())

       return;

    setFlag(FLAG_SELECTION_PERFORMEDtrue);

    EditPartViewer viewer = getCurrentViewer();

    List selectedObjects = viewer.getSelectedEditParts();

 

    if (getCurrentInput().isModKeyDown(SWT.MOD1)) {

       if (selectedObjects.contains(getSourceEditPart()))

           viewer.deselect(getSourceEditPart());

       else

           viewer.appendSelection(getSourceEditPart());

    } else if (getCurrentInput().isShiftKeyDown())

       viewer.appendSelection(getSourceEditPart());

    else

       viewer.select(getSourceEditPart());

}

这样viewer就选择了节点。

从上面我们可以看出,根本没有feedback相关的处理,那为什么当我们选择一个对象时会多出一个框呢?这个在下面提问解答部分单独的讨论一下。

当我们点击松开鼠标时

protected boolean handleButtonUp(int button) {

    if (isInState(STATE_DRAG)) {

       performSelection();

       if (getFlag(FLAG_ENABLE_DIRECT_EDIT))

           performDirectEdit();

//我们松开鼠标可以编辑节点就是因为这个。

       if (button == 1 && getSourceEditPart().getSelected() != EditPart.SELECTED_NONE)

           getCurrentViewer().reveal(getSourceEditPart());

       setState(STATE_TERMINAL);

       return true;

    }

    return false;

}

protected void performDirectEdit() {

    DirectEditRequest req = new DirectEditRequest();

    req.setLocation(getCurrentInput().getMouseLocation());

    new DelayedDirectEditHelper(

       getSourceEditPart().getViewer(),

       req,

       getSourceEditPart());

}

 

平移对象事件的DragTracer---DrageEditPartTracker:

因为单击节点editpart时,selectionToolTarget是节点editpart,故通过mouseDown获得的是节点editpart.getDragTracer();而节点editpart一般继承AbstractEditPart,这个类的getDragTracer返回DrageEditPartTracker,故其DragTracerDrageEditPartTracker,如果是点击周围的Movehandle,则是通过。

Class  AbstractGraphicalEditPart

public DragTracker getDragTracker(Request request) {

    return new org.eclipse.gef.tools.DragEditPartsTracker(this);

}

拖曳时调用:

 public void mouseDrag(MouseEvent me, EditPartViewer viewer) {

    if (!isViewerImportant(viewer))

       return;

    setViewer(viewer);

    boolean wasDragging = movedPastThreshold();

    getCurrentInput().setInput(me);

    handleDrag();

    if (movedPastThreshold()) {

       if (!wasDragging)

           handleDragStarted();

       handleDragInProgress();

    }

}

protected boolean handleDragInProgress() {

    if (isInDragInProgress()) {

       updateTargetRequest();

//这里的request就是REQ_MOVE

       if (updateTargetUnderMouse())

           updateTargetRequest();

       showTargetFeedback();

       showSourceFeedback();

//feedback反馈。

       setCurrentCommand(getCommand());

//使用命令,比如拖曳完成后要执行什么命令

    }

    return true;

}

//这个调用target的,其实拖曳时targetcontenteditpart

protected void showTargetFeedback() {

    if (getTargetEditPart() != null)

       getTargetEditPart().showTargetFeedback(getTargetRequest());

    setFlag(FLAG_TARGET_FEEDBACKtrue);

}

//所有被选择的对象是sourceEditpart,

protected void showSourceFeedback() {

    List editParts = getOperationSet();

//获取所有被选择的节点editpart

    for (int i = 0; i < editParts.size(); i++) {

       EditPart editPart = (EditPart) editParts.get(i);

       editPart.showSourceFeedback(getTargetRequest());

    }

    setFlag(FLAG_SOURCE_FEEDBACKtrue);

}

protected Command getCommand() {

    CompoundCommand command = new CompoundCommand();

    command.setDebugLabel("Drag Object Tracker");//$NON-NLS-1$

 

    Iterator iter = getOperationSet().iterator();

 

    Request request = getTargetRequest();

    //这个requestREQ_MOVE

    if (isCloneActive())

       request.setType(REQ_CLONE);

    else if (isMove())

        request.setType(REQ_MOVE);

    else

       request.setType(REQ_ORPHAN);

      

    if (!isCloneActive()) {

       while (iter.hasNext()) {

           EditPart editPart = (EditPart)iter.next();

           command.add(editPart.getCommand(request));

       }

    }

   

    if (!isMove() || isCloneActive()) {

       if (!isCloneActive())

           request.setType(REQ_ADD);

      

       if (getTargetEditPart() == null)

           command.add(UnexecutableCommand.INSTANCE);

       else

           command.add(getTargetEditPart().getCommand(getTargetRequest()));

//这个会调用policycreateChangeConstraintCommand

 

    }

   

    return command;

}

 

Class in policy

 

public Command getCommand(Request request) {

    if (REQ_RESIZE_CHILDREN.equals(request.getType()))

       return getResizeChildrenCommand((ChangeBoundsRequest)request);

    if (REQ_ALIGN_CHILDREN.equals(request.getType()))

       return getAlignChildrenCommand((AlignmentRequest)request);

 

    return super.getCommand(request);

}

public Command getCommand(Request request) {

 

    if (REQ_MOVE_CHILDREN.equals(request.getType()))

       return getMoveChildrenCommand(request);

 

    return null;

}

protected Command getMoveChildrenCommand(Request request) {

    //By default, move and resize are treated the same for constrained layouts.

    return getResizeChildrenCommand((ChangeBoundsRequest)request);

}

protected Command getResizeChildrenCommand(ChangeBoundsRequest request) {

    CompoundCommand resize = new CompoundCommand();

    Command c;

    GraphicalEditPart child;

    List children = request.getEditParts();

 

    for (int i = 0; i < children.size(); i++) {

       child = (GraphicalEditPart)children.get(i);

       c = createChangeConstraintCommand(request, child,

           translateToModelConstraint(

              getConstraintFor(request, child)));

       resize.add(c);

    }

    return resize.unwrap();

}

mouseUp时会调用:

protected boolean handleButtonUp(int button) {

    if (stateTransition(STATE_DRAG_IN_PROGRESSSTATE_TERMINAL)) {

       eraseSourceFeedback();

       eraseTargetFeedback();

       performDrag();

       return true;

    }

    return super.handleButtonUp(button);

}

protected void performDrag() {

    executeCurrentCommand();

}

protected void executeCurrentCommand() {

    Command curCommand = getCurrentCommand();

    if (curCommand != null && curCommand.canExecute())

       executeCommand(curCommand);

    setCurrentCommand(null);

}

这个command其实就是createChangeConstraintCommand函数返回的command.

执行后,节点constraint变化了,也就是位置变化了。

到此平移结束了。

 

阅读(1969) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~