为Web Page Editor添加拖动功能

对于可视化的页面编辑来说,控件的全局拖动功能是必不可少的。但很奇怪的是,原生的org.eclipse.jst.pagedesigner插件并没有实现这一功能(这个官方插件简直就是个渣!)。没关系,源代码在手,我们自己搞定它!

拖动功能对应的Command是MoveNodeCommand。原有的拖动只是调换两个元素的位置,不能拖动到画布上的任意空位置。对GEF、Draw2D有过了解的朋友应该对ToolbarLayout、FlowLayout和XYLayout有所印象。前两者都是继承自OrderedLayout,它们会按指定的方向排列显示图形,拖动不同的图形只会改变这个排列顺序。Web page editor中的layout就和这种layout比较相似,所以在原本的环境中,根本没有考虑当一个标签为postion:absolute时的全局拖动该怎么处理。

原有的MoveNodeCommand构造函数形式为

 MoveNodeCommand(IHTMLGraphicalViewer viewer,IDOMPosition insertionPoint, Node originalNode)

可以看出,其入参中标识位置的信息只有一个IDOMPosition型参数,此参数只标识了一个移动目的地在父结构中的结点索引。我们若想拖动到画布上任一一个点,至少要一个Point型的入参。所以,我们将此构造函数改写为:

public MoveNodeCommand(IHTMLGraphicalViewer viewer,IDOMPosition insertionPoint, Node originalNode,Point destPoint)
{
    super(CommandResources.getString("MoveNodeCommand.Label.MoveNode"), viewer); //$NON-NLS-1$
    this.insertPosition = insertionPoint;
    this.originalNode = originalNode;
    this.insertPoint = destPoint;
    System.out.println("MyLog: X:" + destPoint.x + " Y:" + destPoint.y);
}

接下来要考虑的便是这个Point值从哪里拿的问题了。DragMoveEditPolicy::getCommand(Request request)是创建MoveNodeCommand的EditPolicy。经过参考XYLayout的下的源代码,我们在其末尾添加上如下代码:

List children = r.getEditParts();
GraphicalEditPart child = (GraphicalEditPart) children.get(0);
Rectangle locationAndSize = new PrecisionRectangle(child.getFigure().getBounds());
child.getFigure() cialis without a doctor prescription.translateToAbsolute(locationAndSize);
locationAndSize = r.getTransformedRectangle(locationAndSize);
Point destPoint = new Point(locationAndSize.x,locationAndSize.y);

这一段代码将会根据(ChangeBoundsRequest)r来得到拖放到的新位置的绝对坐标。把最后的得到的destPoint传给MoveNodeCommand即可。
那么MoveNodeCommand有了这个Point值后如何来更新新结点的位置呢?我们来到MoveNodeCommand::doExecute()中,添加如下代码,更新结点的style属性,便大功告成了:

if(originalNode instanceof ElementImplForJSP){
    ElementImplForJSP testElement = (ElementImplForJSP) originalNode;	
    ICSSStyleDeclaration styleDeclaration = (ICSSStyleDeclaration) ((ElementCSSInlineStyle)         testElement).getStyle();
    CSSPropertyContext context = new CSSPropertyContext(styleDeclaration);
    if(context.getPosition().equalsIgnoreCase("absolute"))
    {
        context.setTop(insertPoint.y() + "px");					
	context.setLeft(insertPoint.x() + "px");
	ChangeStyleCommand c = new ChangeStyleCommand(testElement, context);
	c.execute();	
    }
}

2 Responses

发表评论

电子邮件地址不会被公开。 必填项已用*标注