Event MOUSE_WHEEL
Hi!
Is it possible to add MOUSE_WHEEL event for Starling InteractiveDisplayObject? Or how do you add this in your projects?
Thx!
// NOTE that is the native stage not the Starling stage below
// added so that we can track movement on right mouse and left mouse actions
stage.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, onOtherMouse, false, 0, true);
stage.addEventListener(flash.events.MouseEvent.MOUSE_UP, onOtherMouse, false, 0, true);
stage.addEventListener(flash.events.MouseEvent.MOUSE_MOVE, onOtherMouse, false, 0, true);
stage.addEventListener(flash.events.MouseEvent.RIGHT_MOUSE_DOWN, onOtherMouse, false, 0, true);
stage.addEventListener(flash.events.MouseEvent.RIGHT_MOUSE_UP, onOtherMouse, false, 0, true);
...
// some captured state across different callbacks if needed
// we also track left mouse down so that we ignore right events in that mode
private var inLeftMouseMode:Boolean = false;
private var inRightMouseMode:Boolean = false;
private var mLastRightX:Number = 0;
private var mLastRightY:Number = 0;
...
private function onOtherMouse(event:flash.events.MouseEvent):void
{
// on OS X when control is down we get sent context and right mouse events
// context and right mouse come together
if (event.type == flash.events.MouseEvent.MOUSE_DOWN) {
inLeftMouseMode = true;
}
else if (event.type == flash.events.MouseEvent.MOUSE_UP) {
inLeftMouseMode = false;
}
else if (event.type == flash.events.MouseEvent.RIGHT_MOUSE_DOWN) {
inRightMouseMode = true;
mLastRightX = event.stageX;
mLastRightY = event.stageY;
...
// could send a custom event out or fire right mouse starting
}
else if (event.type == flash.events.MouseEvent.RIGHT_MOUSE_UP) {
inRightMouseMode = false;
...
// could send a custom event out or fire right mouse ending
}
else if (event.type == flash.events.MouseEvent.MOUSE_MOVE) {
// can choose to only do something with right mouse movement only if left mouse isn't also down
if (inRightMouseMode && !inLeftMouseMode) {
if (mLastRightX != event.stageX || mLastRightY != event.stageY) {
// could do something with a pan based on a right movement or send out a custom right mouse moved event
// pan(event.stageX - mLastRightX, event.stageY - mLastRightY);
...
mLastRightX = event.stageX;
mLastRightY = event.stageY;
}
}
}
}
Thanks for posting your code, @varadig-fg! Does that help you, @Mintonist?
I understand idea. So seems Starling has no plan to support it?
I think it is more difficult, because of starling viewport, high screen resolution etc.
Ok, I ask other questions:
- How to convert native stage Point (x,y) to Starling coordinates?
- How to detect is Point (x,y) placed under DisplayObject (or any its children) inside Starling ? Thx!
@Mintonist It would definitely make sense to add it – I'll try to have a look, but it's always good to have a workaround. 😃
As for your questions:
- Hm, there is unfortunately no helper method available. (Also something worth adding ...)
But this code should do the trick:
var mouseX:Number = mouseEvent.stageX;
var mouseY:Number = mouseEvent.stageY;
var stage = Starling.current.stage;
var viewPort = Starling.current.viewPort;
var globalX:Number = stage.stageWidth * (mouseX - viewPort.x) / viewPort.width;
var globalY:Number = stage.stageHeight * (mouseY - viewPort.y) / viewPort.height;
- Feed the global point from above into globalToLocal() (on the display object you want to test), and then call hitTest() with those coordinates on the same object.
I hope that helps!
I need implement scrolling logic to Starling objects. So it will be great to catch scroll mouse event to any InteractiveDisplayObject. But of course anyone can do it yourself.
May be helper method to convert coordinates can be a part of Starling.
I find this in Feather control/Scroller.as
var starling:Starling = this.stage !== null ? this.stage.starling : Starling.current;
var nativeScaleFactor:Number = 1;
if(starling.supportHighResolutions)
{
nativeScaleFactor = starling.nativeStage.contentsScaleFactor;
}
var starlingViewPort:Rectangle = starling.viewPort;
var scaleFactor:Number = nativeScaleFactor / starling.contentScaleFactor;
var point:Point = Pool.getPoint(
(event.stageX - starlingViewPort.x) * scaleFactor,
(event.stageY - starlingViewPort.y) * scaleFactor);
var isContained:Boolean = this.stage !== null && this.contains(this.stage.hitTest(point));
It is help me. And it is very similar to your code example. Thx!