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

全部博文(95)

文章存档

2013年(2)

2012年(3)

2011年(1)

2010年(8)

2009年(81)

分类:

2009-10-13 00:03:04

上一篇提了几个问题,分别是

1.选择,平移,改变大小这些操作的source,targeteditpart分别是什么?

2.选择,平移,改变大小操作出来的虚框是怎么出来的,这个是feedback产生的?如果是feedback产生的,由于平移,改变会执行showTargetFeedbackshowSourceFeedback,那么这个虚框是Target产生,还是Source产生。

3.当我们拖曳时,尽管鼠标在source editpart上,为什么target editpart始终是content editpart呢?

 

下面就一个一个来回答:

1.

对于选择,sourcetarget一样,source是在创建tracer时就赋值了,target是通过updateTargetUnderMouse得到的。

     对于平移,改变大小操作,source是被选择了的editpart,targetcontent editpart,在我的例子中是DiamEditor.

 

2.

对于平移,改变大小操作的虚框是由showSourceFeedback。也就是被选择的节点的showSourceFeedback,但是如果节点没有绑定任何policy,也会显示出虚框,这是什么原因呢?这个说没有绑定任何policy应该是指没有显示绑定,以为,如果我们给content editpart绑定了继承于XYLayoutEditPolicypolicy,那么这个policy会所有节点editpart绑定一个ResizableEditPolicy.

protected void decorateChild(EditPart child) {

    EditPolicy policy = createChildEditPolicy(child);

    child.installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, policy);

}

protected EditPolicy createChildEditPolicy(EditPart child) {

    return new ResizableEditPolicy();

}这个就为child创建了policy

这个ResizableEditPolicy就有对REQ_MOVEREQ_RESIZEfeedback处理

 

public void showSourceFeedback(Request request) {

    if (REQ_RESIZE.equals(request.getType()))

       showChangeBoundsFeedback((ChangeBoundsRequest)request);

//这个是对于改变大小

    else

       super.showSourceFeedback(request);

//这个是对于平移

}

public void showSourceFeedback(Request request) {

    if ((REQ_MOVE.equals(request.getType()) && isDragAllowed())

       || REQ_ADD.equals(request.getType())

       || REQ_CLONE.equals(request.getType()))

       showChangeBoundsFeedback((ChangeBoundsRequest) request);

}

仔细看下,这个多一个isDragAllowed,也就是说平移时要判断是否允许drag.

最终都是到showChangeBoundsFeedback

protected void showChangeBoundsFeedback(ChangeBoundsRequest request) {

    IFigure feedback = getDragSourceFeedbackFigure();

   

    PrecisionRectangle rect = newPrecisionRectangle(getInitialFeedbackBounds().getCopy());

    getHostFigure().translateToAbsolute(rect);

    rect.translate(request.getMoveDelta());

    rect.resize(request.getSizeDelta());

   

    feedback.translateToRelative(rect);

    feedback.setBounds(rect);

}

 

对于选择虚框不是由feedback产生的,是由targetpolicy(这个policy也是上面那个ResizableEditPolicy)active时绑定listener,监听select事件产生。

public void activate() {

    super.activate();

    addSelectionListener();

//监听editpartselection事件,从而调用shows

    setSelectedState(getHost().getSelected());

    setFocus(getHost().hasFocus());

}

protected void addSelectionListener() {

    selectionListener = new EditPartListener.Stub() {

       public void selectedStateChanged(EditPart part) {

           setSelectedState(part.getSelected());

           setFocus(part.hasFocus());

       }

    };

    getHost().addEditPartListener(selectionListener);

}

editpart选择发生变化时便会调用setSelectedState

protected void setSelectedState(int type) {

    if (state == type)

       return;

    state = type;

    if (type == EditPart.SELECTED_PRIMARY)

       showPrimarySelection();

    else if (type == EditPart.SELECTED)

       showSelection();

    else

       hideSelection();

}

 

    showSelection就是我们选择一个editpart周围出现框的原因,其实是添加了相应的handle,这个也是一种figure,只不过这种figure,可以提供dragTracer,对于moveHandle,是DragEditPartTracer,对于Resize handle,则是resizeTracer,当我们选择节点边框拖动时,是相应的handle产生dragTracer

 

4.targetEditpart,我们主要讨论Tracer TooltargettargetEditpart

对于ResizeTracer,由于他已固定了:

protected GraphicalEditPart getTargetEditPart() {

    if (owner != null)

       return (GraphicalEditPart)owner.getParent();

    return null;

}

OwnerNodeEditor,所以其parent肯定是content editpart.

对于DragEditPartTracer:其由updateTargetUnderMouse这个函数决定,以为这个函数调用了setTargetEditPart

 protected boolean updateTargetUnderMouse() {

    if (!isTargetLocked()) {

       EditPart editPart = getCurrentViewer().findObjectAtExcluding(

           getLocation(),

           getExclusionSet(),

           getTargetingConditional());

       if (editPart != null)

           editPart = editPart.getTargetEditPart(getTargetRequest());

       boolean changed = getTargetEditPart() != editPart;

       setTargetEditPart(editPart);

       return changed;

    else

       return false;

}

    EditPart editPart = getCurrentViewer().findObjectAtExcluding(

           getLocation(),

           getExclusionSet(),

           getTargetingConditional());

 

protected EditPartViewer.Conditional getTargetingConditional() {

    return new EditPartViewer.Conditional() {

       public boolean evaluate(EditPart editpart) {

           return editpart.getTargetEditPart(getTargetRequest()) !=null;

       }

    };

}

 

public EditPart findObjectAtExcluding{

IFigure figure = getLightweightSystem()

       .getRootFigure()

       .findFigureAt(pt.x, pt.y, new ConditionalTreeSearch(exclude));

    EditPart part = null;

    while (part == null && figure != null) {

       part = (EditPart)getVisualPartMap().get(figure);

       figure = figure.getParent();

    }

    if (part == null)

       return getContents();

    return part;

}

 

public EditPart getTargetEditPart(Request request) {

    EditPolicyIterator i = getEditPolicyIterator();

    EditPart editPart;

    while (i.hasNext()) {

       editPart = i.next()

           .getTargetEditPart(request);

       if (editPart != null)

           return editPart;

    }

 

    if (RequestConstants.REQ_SELECTION == request.getType()) {

       if (isSelectable())

           return this;

    }

 

    return null;

}

由于所有的EditpartgetTargetEditPart只能处理REQ_SELECTION,所以对于其他request都返回null(不考虑editpartpolicy的影响,其实一般的policygetTargetEditPart也返回null).所以像REQ_MOVE,REQ_RESIZE这些RequestfindObjectAtExcluding都返回getContent,也就是content editpart.由于DragEditPartTracerrequestREQ_MOV,所以其TargetEditPart始终是content editpart。还有一个例子是:当在空白出进行拖曳操作时,dragTraceMarqueeDragTracker,这里的requestREQ_SELECTION,故其target就是被选择的节点由于是空白地方.

 对于selectionTool,没有source。当为resize时:TargetrootEditpart,MOVE时是NodeEditPart.

 

总结:选择对象包括Marquee选择对象事件的Tracer  Tool都是通过SelectionToolTargetEditPartgetDragTracer得到:只不过RootEditPart返回MarqueeTracer,节点EditPart返回DraEditPartTracer.Resize操作的是通过point热点返回的,((GraphicalViewer) viewer).findHandleAt(getLocation()),是ResizeTracer.

TracerTool都是在mouseDonw时确定的.

同时dragTracersourceEditPart都是通过getOperationSet获取到得editpartlist,这个函数就是返回被选择的节点的集合,而TargetEditPart是通过

UpdateUnderMouse更新的,当前鼠标下的EditPart必须接受REQ_Move才能是TargetEditPart,若没有满足条件的则TargetEditPartContentEditPart.

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