我正在构建一个类似于项目的图形板,我面临设计问题。
Main Class是Board,它是一个画布,负责在绘制形状时处理鼠标事件。它还有上下文变量,如currentShape或snapFlag,以激活网格磁力。
为了处理形状的移动/调整大小/旋转,它们继承自第三方开源工具ObjectHandles(flex)。
我有一个扩展ObjectHandles主类的baseShape来覆盖它的一些内部函数,比如onMove函数。
当创建一个形状(鼠标按下,移动,向上鼠标)时,它由棋盘处理,它知道他自己的快照标记。
var mouseUpPoint:Point = boardCanvas.globalToLocal(new Point(event.stageX,event.stageY)); var snapMouseUpPoint = snapPoint(mouseUpPoint.x,mouseUpPoint.y);
在我的overover onMove方法中,我希望该形状能够识别Board snap标志以及何时更改。我该怎么做?
我是否将Board作为参数传递给我的basicShape构造函数,以便我可以检查snap?
我是否将旗帜作为参数传递,并以某种方式让所有形状都听取变化?
什么是最干净的解决方案?
非常感谢。
答案 0 :(得分:1)
我会从略微不同的角度来看待这个问题。我假设Board
对象首先捕获鼠标事件,以便它可以决定单击哪个形状。我也会让电路板捕获鼠标移动,将正确的(捕捉或未绑定的)坐标“向下”传递给选定的Shape
对象,而不是让形状对象弄明白。
这会将网格捕捉处理留给Board
,并使您的Shape
对象onMove
方法保持杂乱无章。
答案 1 :(得分:1)
不知道您的应用:
Shape是否有可能拥有自己的“快照”行为?也就是说,一个Shape可以被排除在对齐之外吗?如果是这样,请使snapFlag成为Shape的成员。在Board上设置snapFlag时,遍历您的Shapes并根据您的规则设置或不设置。
如果捕捉行为适用于棋盘上的所有形状,请考虑事件驱动模型(如果它可用 - 我是Flex noob)。当Shape移动时,让它引发OnMove事件。然后,董事会可以做出回应,并决定在合适的情况下将形状“捕捉”到位。
如果快照行为适用于所有形状并且事件不可用,我只是说在这种情况下松散耦合的地狱 - 让Shapes Board知道。听起来你通过使用ObjectHandle来保存一堆代码。这种好处可能会超过耦合UI元素的成本。
答案 2 :(得分:0)
试着和你一起思考.. 我认为拥有IBoard界面的Shapes没什么大不了的。 虽然,我不喜欢他们必须检查棋盘上的旗帜......
你如何将旗帜作为参数传递?在OnMove()方法?我不太明白这个......你能扩展吗?
虽然.. 如果你试着想一下SRP - 单一责任原则...... Shape类的责任是什么? 是的,这就是eJames已经写过的。
我觉得他们的主要责任可能不是处理鼠标事件......这里需要了解更多关于你的应用程序的信息,但我的一般感觉是为什么没有其他人把鼠标弄下来然后找出形状应该是什么用它来做,例如用新坐标调用Shape上的Draw()?
假设你想要应用像复合模式(形状内的形状......)这样的东西,你希望它们能够自己处理那些鼠标事件......但是 然后,如果他们在本地坐标中察觉到这个鼠标事件,那将是合乎逻辑的,但是我认为你应该通过这个事件提供所有信息(本地坐标,鼠标状态......),这样他们就不必要求“全球“董事会中的变量......
答案 3 :(得分:0)
将标志作为形状构造函数的参数传递。但它不会很好,因为标志会改变,我必须使每个形状更新他们的标志副本。
确实,形状责任不是要知道如何处理鼠标事件。但这就是ObjectHandles所做的:对事件做出反应,更新形状的高度宽度旋转参数。
也许我应该在我的电路板类中传输一些库代码来处理形状选择和移动/调整大小/旋转。
答案 4 :(得分:0)
OnMouseMove ObjectHandles
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));
所有形状都遵循捕捉规则,不能有一个对齐而另一个是自由的。
答案 5 :(得分: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中进行了一些更多的计算,导致了对齐的快速移动。
答案 6 :(得分:0)
使用ObjectHandles版本2,然后创建约束以执行您想要的操作。