在Squeak中实现特定Morph拖拽投放功能需重写哪些方法?
Morphic拖拽与投放需求的核心方法实现
一、让Pieces支持左键直接拖拽(无需唤起Halo)
在你的PieceMorph类中重写以下方法:
handlesMouseDown::返回true,声明该Morph响应鼠标按下事件mouseDown::触发拖拽流程,可借助系统方法等待拖拽动作startDrag:event::创建拖拽替身(避免直接移动原对象)并绑定到鼠标
示例代码:
PieceMorph>>handlesMouseDown: anEvent ^ true PieceMorph>>mouseDown: anEvent anEvent hand waitForClicksOrDrag: self event: anEvent PieceMorph>>startDrag:event: anEvent | dragHand dragMorph | dragHand := anEvent hand. dragMorph := self copy. "生成拖拽副本,原对象留至投放完成再移动" dragMorph position: dragHand position. dragMorph color: self color. "确保副本可见,解决拖拽时的不可见对象问题" dragHand grabMorph: dragMorph. dragHand temporaryStorage at: #originalPiece put: self "存储原对象,用于投放时定位"
二、禁止Squares被拖拽
在SquareMorph类中重写方法阻止拖拽触发:
SquareMorph>>handlesMouseDown: anEvent ^ false "不响应鼠标按下,直接阻止拖拽启动" "若需保留其他鼠标事件,可替换为空实现的startDrag:" SquareMorph>>startDrag:event: anEvent "空方法,拦截拖拽流程"
三、实现Pieces到Squares的定向投放(拒绝投放至其他Pieces)
1. 让SquareMorph仅接收PieceMorph投放
在SquareMorph中实现投放校验与接收逻辑:
SquareMorph>>wantsDroppedMorph: aMorph event: anEvent ^ aMorph isKindOf: PieceMorph "仅接受Piece类型的拖拽对象" SquareMorph>>acceptDroppingMorph: aMorph event: anEvent | originalPiece | originalPiece := anEvent hand temporaryStorage at: #originalPiece ifAbsent: [aMorph]. originalPiece position: self bounds center - originalPiece bounds center. "居中放置原对象" aMorph delete. "清理拖拽副本" anEvent hand temporaryStorage removeKey: #originalPiece ifAbsent: []
2. 阻止PieceMorph接收任何投放
在PieceMorph中重写投放校验方法:
PieceMorph>>wantsDroppedMorph: aMorph event: anEvent ^ false "拒绝所有投放动作"
额外提示
- 确保
PieceMorph和SquareMorph正确继承自Morph或其合适子类 - 若拖拽时仍出现不可见对象,检查
startDrag:event:中拖拽副本的外观属性(如颜色、透明度)是否正确设置 - 可在
mouseEnterDragging:/mouseLeaveDragging:中添加日志输出,验证投放区域的触发逻辑是否正常
内容的提问来源于stack exchange,提问作者Sander de Jong
相关产品推荐
相关产品推荐

