Setting cursor priority with AIR native cursors - actionscript-3

Is there a way to set the priority (CursorManagerPriority.HIGH) of a mouse cursor set via Mouse.cursor = '...';?
Long story short, I've had to resort to using the CursorManager to apply cursors, because setting the priority is crucial for my application due to the HTML control overriding all cursor changes without a high priority. Setting cursors with the cursor manager totally works, but the cursors aren't as fast/response as those rendered at the OS level (as described here).
If there isn't a way, my next question is: is there any way to suppress the cursor changes made by the HTML control? Setting mouseEnabled = false does it... but disables all mouse events on the HTML page, so that doesn't work.
Example:
This doesn't work:
setInterval(function():void { Mouse.cursor = 'ibeam'; }, 100);
Setting a cursor with a high priority works, however:
// ibeamCursor is an embedded PNG
CursorManager.setCursor(ibeamCursor, CursorManagerPriority.HIGH, -2, -4);
(this code is used at mx:Application scope)

I'm going to assume that you have access to the code for the HTML control...otherwise, I'm not sure you can do this at all.
I don't think you can set priority on cursors set by Mouse.cursor = "..."; (tho I could be wrong...if anyone has info to the contrary, feel free to correct me.)
However, I think you can very easily suppress cursor changes simply by using a boolean variable and an if-statement.
var customCursors:Boolean;
Then, on each place where the cursor changes occur...
if(customCursors == true)
{
Mouse.cursor = "mycursor";
}
This will allow or suppress changes to the cursors, simply by changing the customCursors variable.
However, there may be something more useful if you're dealing with two conflicting cursors, and you want one to only take place during certain instances. For that, you could try a different if statement.
In my own code, I want one cursor to show up only while dragging an object, but not just while the mouse is over it. One is inside the move event, and the other inside the over event. There was a third that would show up only when the object was dragged over a certain point, and when it was not, it needed to be the regular dragging cursor.
This created a rather annoying conflict...
To fix that, I actually checked the Mouse.cursor property in my if statement! The placement of various Mouse.cursor statements in my events created a sort of priority for the cursors. It works perfectly.
In my mouse over statement:
Mouse.cursor = "hand";
In my mouse down statement (where I start dragging):
Mouse.cursor = "dragging";
In my move statement:
if(Mouse.cursor == "draggingover")
{
Mouse.cursor = "dragging";
}
In my mouse up statement (where I stop dragging):
Mouse.cursor = "hand";
In my mouse out statement:
Mouse.cursor = "pointer";
I hope this helps! If it does, don't worry about overlooking this seemingly obvious solution...I think we're all prone to do so when we're looking for built-in functions.
If this isn't helpful, sorry. Again, I don't think there is another way, but if anyone knows of one, please weigh in.

I believe HTML control inherits from ScrollControlBase. Try fixing your Mouse issues on that parent control, rather than on the HTML control.
Also, you can try overriding the HTML control, adding code to remove default cursor look and feel. See this blog post, and just do the opposite.

Related

Flash Escape Game Item

I'm making a flash game that requires picking up items. The item disappears when you click on it, but it reappears when you leave the room and come back. I tried setting a variable in the function and then using an if statement in the main code but that didn't work because the variable is local. And if I declare the variable outside the function, it reinitializes when you enter the frame(return to the room). A global variable should solve this problem. I know everyone says they're bad to use but I'm just looking for a solution.
//Pick up key
key_btn.addEventListener(MouseEvent.MOUSE_UP, getKey);
function getKey(Event: MouseEvent):void{
var gotKey:Boolean = true;
}
if(gotKey == true){
key_btn.visible = false;
}
First of all: I suggest you to keep all codes in one frame and use movieclips to represent different rooms.
You can add a layer for the global vars and expand it, such as this:

SVG onload event called too early?

I have code like this, using jQuery-svg
function replaceRaster(){
$('#png').remove()
a = $('#graphic')
b = a.svg(a)
a.load('IDC_Energy.svg',
{onLoad:bind} )
svg = document.getElementById("graphic").children[0]
console.log(svg)
svg.addEventListener('load', bind)
}
The event handler, bind, is fired before jQuery-svg-dom is able to select elements within the SVG data. My code is supposed to look over the SVG and assign various classes and attach listeners to various elements, but it's not able to find any. If I call bind in the console after everything is loaded it can find alll the SVG elements.
Am I doing something wrong? Is there another way to detect when the SVG DOM is available? I've thought of using a timer, but that's really hacky, especially considering my SVG files could be a few MB large.
Have you tried using a timer with a timer delay of '0' or perhaps just '10'? I've frequently used this technique to push the work out of the current run loop as timers are fired after the redraw ghas completed. With luck the bind will only be fired once the repaint has finished. I'm not sure whether this will help in your particular instance because I don't know what else you are doing in the page - it won't help, for example, if you have some asynchronous data handling going on.

How to handle mouseEvent transparently in AS3?

I have a DisplayObject docked at the top of my interface that displays debug information (frames per second, etc.) and is translucent with an alpha of 60%.
I would like to interact with items under this surface, such that when the mouse rolls over it, it dims to 10% alpha, and mouse events pass through it to the underlying objects.
Normally, I have this debug info panel's mouseEnabled and mouseChildren properties set to false, so objects under it receive mouse events.
The problem is that in order to hide it when the mouse rolls over it, it needs to have mouseEnabled set to true. However, if mouseEnabled is true, the mouse events are not picked up by objects underneath it.
As far as I know, I can't selectively enable mouseEvents, so it's either going to receive them all or none of them. That means that I'd have to handle and forward ALL events, if I took that approach.
I really wish the mouseEnabled property had a "peek" mode or something, so that it could receive the events if it is on top, but also allow them to pass through to objects underneath.
If a DisplayObject has mouseEnabled=true it means that its events will be sent to its container not to whateve is underneath the object. So this solution will not work. The best solution would be to reroute events from it manually using getObjectsUnderPoint as described here.
I've been using this approach for years in multi-touch apps. With multiple touch points I don't see any processor overhead. And you got only one cursor.
I feel your pain. Unfortunately, I don't know of a way to enable/disable specific mouse events. You could get creative with the solution though. For instance, maybe try adding a MOUSE_MOVE listener to your stage and track the coordinates of the mouse. Then, if the stageX,stageY of the mouse is in the area of your panel, set the visibility. You might also be able to use getObjectsUnderPoint() to determine which objects are under the mouse. But, my guess is that it would get a little intense on the processor to run that on each frame iteration.
I believe you are looking for mouseEnabled = false
But another last ditch attempt you can do is on mouse over move it to the other side of the screen.
One approach you can take, although not ideal, is to add an enter frame listener and check the mouse position every frame. something along the lines of:
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
private function onEnterFrame(e:Event):void {
if(mouseX > width || mouseY > height){
//hide stats
}
}
I'm assuming you have this display hierarchy:
Debug Window
Debug Control 1
Debug Control 2
...
Overlay
Why not make the overlay a mask on DebugWindow and have your mouseEvents attached to DebugWindow itself? See this page for some inspiration: http://blog.shaperstudio.com/2010/11/as3-inverse-mask/
I had this same problem.. i made function to check is mouse over certain object:
public function isMouseOverObject(mPos: Point, pObject:DisplayObject, pContainer:DisplayObjectContainer) {
var under_objects:Array = pContainer.getObjectsUnderPoint(mPos);
var is_under:Boolean = false;
for (var i:int = 0; i < under_objects.length; i++) {
if (under_objects[i] == pObject) {
is_under = true;
break;
}
}
return is_under;
}

Approaches to replace cursor in pure AS3 / Flare project?

I've got a pure AS3 (no Flex) project that uses Flare to display and interact with a data visualization. I just implemented some panning behavior, so you can click and drag the visualization around, and now I'd like to give the user a visual indicator that this is possible, by switching the arrow cursor with a nice grabby-looking hand icon.
The user can click and drag at any time except when the mouse is over a clickable node (at which time the cursor swaps to a pointer - this behavior is already in place).
So...
1) Do I need to create my own custom bitmap/sprite or is there a palette of built-in cursors I can use? (I'm not using Flex.)
2) Is there a way to simply replace the default arrow with the pan cursor project-wide, or do I need to attach the swapping to mouse events on display objects? Can I use the stage object to make this behavior apply everywhere?
3) How do I perform the swap? Do I use the Cursor object directly or do I need to get involved with the CursorManager?
Any guidance, pseudo-code, or words of wisdom is greatly appreciated!
I don't think there's a CursorManger in flash, only flex. The way i'm doing is with a custom class which hides the cursor and drags the customized cursor at mouse_move. You have to set it to mouseChildren=false, otherwise will flickr or the buttons will not be clickable. One problem i found is with custom contextual menus. Try this link http://abrahamyan.com/2009/03/23/as3-cursormanager/
A few things I learned (all pretty newby, really). Firstly, there are some built-in cursor options you can set by setting Mouse.cursor to any of the options of MouseCursor.TYPE. The Mouse object is a singleton available app-wide, so anywhere you change it in your code, the change persists until another change is triggered.
For my simple case, I did this:
//on init, start with the "hand"
Mouse.cursor = MouseCursor.HAND;
//on clickable items, change to "pointer", then back to "hand"
myClickableNode.addEventListener(MouseEvent.ROLL_OVER, function(evt:Event):void {
Mouse.cursor = MouseCursor.BUTTON;
});
myClickableNode.addEventListener(MouseEvent.ROLL_OUT, function(evt:Event):void {
Mouse.cursor = MouseCursor.HAND;
});
The result is you always have the "hand" until you rollover something clickable, then you get the "pointer".

How do I force or lock focus in actionscript 3?

I want to create a dialog or alert box, where a DisplayObject would take and force the focus, until an okay button or something releases the lock. thanks.
The easy way to do this is to make your "dialog" as big as the stage, with a whacking great transparent area around the dialog itself.
The transparent area can listen for any mouse clicks, and just swallow them (which will prevent them being picked up by stuff further back in the display list).
To show the alert, just stick it on top of everything else, When the user closes it, take it away again.
If you are using flex and actionscript, simply use a SkinnablePopUpContainer
var alt:CustomPopUp = new CustomPopUp();
alt.open(this,true) //the second variable is for modal, which will disable view
this.enabled = false; //this will grey out the parent view and provide visual focus to your popup.
To do this, you will need to disable access to all objects under your 'alert' DisplayObject. There are multiple ways of doing this, here 2 I can think off:
Loop through the display list and disable any display objects under your alert depth wise.
Cheat it with a blocker. When you display your alert, display another clip (could have alpha set to 0 ) that blocks the user from hovering/clicking objects. The blocker might need a bit of setup( buttonMode = true, useHandCursor = false, etc. )
This 'modal' behavior has been around for some so there might be no need to reinvent the wheel, depending of your current setup.
If you're using the Flex framework, you've got the functionality in, for Flash you can use the Alert Manager from the Yahoo! Flash Astra Components:
Goodluck,