2

我正在构建一个图形板,例如我面临设计问题的项目。

Main Class 是 Board,它是一个画布,负责在绘制形状时处理鼠标事件。它还具有上下文变量,例如 currentShape 或 snapFlag 来激活网格磁性。

为了处理形状的移动/调整大小/旋转,它们继承自名为 ObjectHandles (flex) 的第三方开源工具。

我有一个 baseShape 扩展 ObjectHandles 主类来覆盖它的一些内部函数,比如 onMove 函数。

当创建一个形状(鼠标向下、移动、鼠标向上)时,这是由 Board 处理的,它知道他自己的 snap 标志。

var mouseUpPoint:Point = boardCanvas.globalToLocal(new Point(event.stageX, event.stageY)); var snapMouseUpPoint = snapPoint(mouseUpPoint.x, mouseUpPoint.y);

在我覆盖的 onMove 方法中,我希望形状能够了解 Board snap 标志及其变化时间。我该怎么做呢 ?

我是否在我的 basicShape 构造函数中将 Board 作为参数传递,以便我可以检查 snap ?

我是否将标志作为参数传递并以某种方式使所有形状都监听变化?

什么是最干净的解决方案?

非常感谢。

4

7 回答 7

1

我会从一个稍微不同的角度来处理这个问题。我假设Board对象首先捕获鼠标事件,以便它可以决定单击了哪个形状。我也会让板子捕获鼠标移动,将正确的(捕捉或未捕捉的)坐标“向下”传递给选定的Shape对象,而不是让形状对象弄清楚。

这将网格捕捉处理留给Board,并使您的Shape对象onMove方法保持混乱。

于 2008-11-24T21:56:38.353 回答
1

不知道您的应用程序:

形状是否有可能拥有自己的“捕捉”行为?也就是说,是否可以将 Shape 排除在捕捉之外,而其他形状则不能?如果是这样,使 snapFlag 成为 Shape 的成员。在板上设置 snapFlag 时,遍历您的 Shapes 并根据您的规则设置或不设置。

如果吸附行为适用于板上的所有形状,请考虑使用事件驱动模型(如果可用 - 我是 Flex 菜鸟)。当 Shape 移动时,让它引发 OnMove 事件。然后,董事会可以做出回应并决定在合适的情况下将形状“卡入”到位。

如果快照行为适用于所有形状并且事件不可用,我只想说在这种情况下松散耦合的地狱 - 让形状板感知。听起来您正在使用 ObjectHandle 保存一堆代码。这种好处可能会超过耦合 UI 元素的成本。

于 2008-11-24T22:26:45.123 回答
0

以这种方式解决它:

由于我在我的 baseShape 类中覆盖了 onMouseMove 并且我使用的是 PureMVC 框架,所以我只是让 baseShape 知道我的 boardMediator。

覆盖受保护的函数 onMouseMove(event:MouseEvent) : void { [...]

// added on override
var board:BoardMediator = ApplicationFacade.getInstance().retrieveMediator(BoardMediator.NAME) as BoardMediator;

然后

desiredPos = board.snapPoint(desiredPos.x, desiredPos.y);

也许不是超级漂亮,但它有效,o 在我的棋盘视图中覆盖 globalToLocal 方法也有效,但在 onMouseMove 内部进行了一些更多的计算,导致不对齐的快速移动。

于 2008-11-25T09:35:44.837 回答
0

只是想和你一起思考.. 我认为具有 IBoard 界面的 Shapes 没什么大不了的。不过,我不喜欢他们必须检查板上的标志的想法......

您将如何将标志作为参数传递?在 OnMove() 方法中?不太明白这个……你能扩展一下吗?

虽然..如果您尝试考虑一下 SRP - 单一责任原则...... Shape 类的责任是什么?是的,这就是 eJames 已经写的。

在我看来,他们的主要职责可能不是处理鼠标事件......这里需要更多地了解您的应用程序,但我的一般感觉是为什么不让其他人放下这个鼠标,然后弄清楚形状应该用它做什么例如使用新坐标在 Shape 上调用 Draw()?

假设您想应用诸如复合模式(形状内的形状...)之类的东西,并且您希望他们能够自己处理这些鼠标事件...但是如果他们在本地感知到此鼠标事件,那将是合乎逻辑的坐标,但是我认为您应该通过此事件提供所有信息(本地坐标,鼠标状态...),这样他们就不必在板上询问“全局”变量...

于 2008-11-24T21:59:44.727 回答
0

将标志作为形状构造函数的参数传递。但这不会很好,因为标志会改变,我必须让每个形状在变化时更新他们的标志副本。

确实,形状责任不知道如何处理鼠标事件。但这就是 ObjectHandles 所做的:对事件做出反应,更新形状的高度宽度旋转参数。

也许我应该在我的板类中转移一些库代码来处理形状选择和移动/调整大小/旋转。

于 2008-11-24T22:13:12.297 回答
0

OnMouseMove 对象句柄

        protected function onMouseMove(event:MouseEvent) : void
    {
        if( ! visible ) { return; }

        if( ! event.buttonDown )
        {
            setMouseCursor( event.stageX, event.stageY );
            return;
        }

        if(parent == null )
        {
            return;
        }


        var dest:Point = parent.globalToLocal( new Point(event.stageX, event.stageY) );
        var desiredPos:Point = new Point();
        var desiredSize:Point = new Point();
        var desiredRotation:Number = 0; 

... plenty more
then 

            if( wasMoved ) {    dispatchMoving() ; }
            if( wasResized ) {  dispatchResizing() ; }
            if( wasRotated ) {  dispatchRotating(); }

所以我不能听移动事件并告诉板子捕捉它,因为形状已经自由移动。我应该在这里添加快照:

var dest:Point = parent.globalToLocal( new Point(event.stageX, event.stageY) );

所有形状都遵循捕捉规则,不能一个捕捉而另一个自由。

于 2008-11-24T22:45:18.143 回答
0

使用 ObjectHandles 版本 2,然后创建一个约束来做你想做的事。

于 2010-03-19T17:14:05.327 回答