Here is what I am trying to do:
User right clicks on a textfield, the system menu that shows the options of "cut,copy,paste,delete,Select All" appears (with only "Paste" and "Select all" active)
User clicks on "paste"
The pasted text is added to the textfield.
My issue is being able to run code right after the user selects the "paste" option from the contextmenu. I tried listening to the textfield change, eventchange, to no avail. This is the code I am using. When the above happens, the following code does not fire. "d" is the textfield object
d.addEventListener(Event.CHANGE, paste);
private function paste(e: Event): void {
trace("paste event fired");
if(Clipboard.generalClipboard.hasFormat(ClipboardFormats.TEXT_FORMAT)) {
trace("pasted data is ", String(Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT)));
}
}
UPDATE:
I tried the suggestions below, but still no luck. Here is the code I have. "d" is already added to stage
private function start():void {
d.addEventListener(TextEvent.PASTE, paste);
}
private function paste(event:TextEvent):void{
trace("something got pasted");
}
What's bugging me is that event is not firing for whatever reason
A TextField is an InteractiveObject, which has a paste event. You can listen for it with the flash.events.Event.PASTE constant.
EDIT: Apologies, the paste event documentation says it doesn't work with TextField. It recommends using the Flash Text Engine, though that is difficult and I don't know how to do text input with it.
You could try:
The textInput event.
The paste, change, and textInput events with a TextInput component instead of a TextField.
The paste, change, and textInput events with a TextArea component instead of a TextField.
Related
I recently switched over from Adobe CS6 to Adobe CC. In the new Adobe CC Flash, it no longer supports action script 2. I need to create an AS3, click tag. Is there a universal AS3 clickTag code you know of that is used? I've googled it, but found some unreliable results.
I'm assuming that you mean you want to have a button react to a click? If so, you simply have to create a button object, and then add a listener for that button where you choose 1) the event you want to listen for, in this case a click, and 2) the code you wish to execute when that event is fired, in most cases this is a function call.
For exaxmple, the following code was placed on the first frame of an .FLA:
import flash.events.MouseEvent;
var myButton:SimpleButton = new SimpleButton();
var myButtonSprite:Sprite = new Sprite();
myButtonSprite.graphics.lineStyle(1, 0x555555);
myButtonSprite.graphics.beginFill(0xff000,1);
myButtonSprite.graphics.drawRect(0,0,200,30);
myButtonSprite.graphics.endFill();
myButton.overState = myButton.downState = myButton.upState = myButton.hitTestState = myButtonSprite;
myButton.addEventListener(MouseEvent.CLICK,buttonClickHandler);
addChild(myButton);
function buttonClickHandler(e:MouseEvent):void {
trace("YAY! My Button was clicked!");
}
To give credit where it is due, the code for creating the button dynamically that you see above is showcased here: Create a Button with only code AS3
If you already have a button on your stage that you want to wire up with a click event you simply have to give the button an instance name and then use that instance name in the code. In the following example, the instance name of the button on the stage is myButton:
myButton.addEventListener(MouseEvent.CLICK,buttonClickHandler);
function buttonClickHandler(e:MouseEvent):void {
trace("YAY! My Button was clicked!");
}
I am pretty new to AS3 and I'd like to learn from the more experienced ones how to do it right. The problem I have is: having two text inputs, having the ability to change the focus from one to another and the most important one, make the input lose focus on click outside.
The problems I faced here are:
When I click outside text inputs, it does not loses focus
If I focus in a text input, minimize browser and come back, it auto refocuses the last element.
How do you see this process implemented and what could I do to solve the problems I face?
To drop focus on your textfields, set a mouse event on the stage:
stage.addEventListener( MouseEvent.CLICK, onDropFocus );
function onDropFocus( evt:MouseEvent ):void
{
Stage.focus = null;
}
To reset the proper textfield focus, store a reference to it when you focus in on your textfield, then try listening for Event.DEACTIVATE on your stage, which is triggered when the flash movie loses focus. Then you can refocus to the intended textfield before leaving the page, (like when minimizing).
I'm working on something similar to the Angry Birds "rollout" for options, etc., but I'm running into a fairly substantial problem.
The rollout itself is just a toggle button, with several other buttons added to the display list that move when you touch the toggle button. Each of these buttons is a class that extends Sprite and contains individual methods for touch events, begin, end and out. When these buttons get initialized (NOT instantiated), the touch begin listener is added. Something like this:
public function Initialize():void
{
this.addEventListener(TouchEvent.TOUCH_BEGIN, OnTouchBegin, false, int.MAX_VALUE);
}
private function OnTouchBegin(e:TouchEvent):void
{
this.removeEventListener(TouchEvent.TOUCH_BEGIN, OnTouchBegin);
this.addEventListener(TouchEvent.TOUCH_END, OnTouchRelease, false, int.MAX_VALUE);
this.addEventListener(TouchEvent.TOUCH_OUT, OnTouchOut, false, int.MAX_VALUE);
}
private function OnTouchRelease(e:TouchEvent):void
{
this.addEventListener(TouchEvent.TOUCH_BEGIN, OnTouchBegin, false, int.MAX_VALUE);
this.removeEventListener(TouchEvent.TOUCH_END, OnTouchRelease);
this.removeEventListener(TouchEvent.TOUCH_OUT, OnTouchOut);
}
private function OnTouchOut(e:TouchEvent):void
{
this.addEventListener(TouchEvent.TOUCH_BEGIN, OnTouchBegin, false, int.MAX_VALUE);
this.removeEventListener(TouchEvent.TOUCH_END, OnTouchRelease);
this.removeEventListener(TouchEvent.TOUCH_OUT, OnTouchOut);
}
Then, when these buttons get hidden from the screen, a method is called to remove any of the listeners that are currently active on them:
public function Deactivate():void
{
this.removeEventListener(TouchEvent.TOUCH_OUT, OnTouchOut);
this.removeEventListener(TouchEvent.TOUCH_END, OnTouchRelease);
this.removeEventListener(TouchEvent.TOUCH_BEGIN, OnTouchBegin);
}
This is just for the standard button functionality (up/down texture and sound), on top of this, when I make the game, in my rollout class, I have an additional method that will add another event listener for custom logic that should occur when the button is touched (the button itself is created elsewhere).
public function AddRolloutButton(listener:Function):void
{
if (listener != null)
{
_buttons[index].addEventListener(TouchEvent.TOUCH_BEGIN, listener);
}
The buttons in the rollout itself are removed from the display list until they are to be shown. When the rollout is closed, the buttons are deactivated (removed from display list and the 3 button listeners within the button class are removed).
Everything works perfectly fine the very first time I open and close the rollout. After that, the event dispatching system just inexplicably dies. Every single InteractiveObject on the screen, regardless of position or type, becomes unusable. I traced out whether or not the listeners were still there on the rollout toggle button, and it was. I also confirmed that the rollout button itself was the only thing on the display list.
What I've noticed is that if I comment out the listener removal in the deactivate method of the button for the touch begin listener, or pass in null for the listener method in the AddRolloutButton method, everything works just fine. The issue seems to stem from having multiple listeners of the same type on the rollout buttons, and then removing one or all of them.
If anyone has any ideas of just what is going on, that would be very helpful. I was under the impression that adding multiple listeners of the same type to an InteractiveObject was perfectly valid.
UPDATE:
It appears that only TouchEvents get broken by this issue I'm having. I just tried using a mouse click listener on the stage after opening and closing the rollout, and that still works. So, only touch events are getting broken, if that helps at all.
Seems like there is something going wrong in your AddRolloutButton method. Are you sure you are assigning the correct listener function?
In your example the listener:Function argument should be equal to _buttons[index]. OnTouchBegin.
Or, since whatever class that owns the AddRolloutButton method seems to be in control of the buttons, you could potentially scrap the listener argument altogether since you know what method that needs to be triggered.
For example like this:
public function AddRolloutButton():void {
var currentButton:MyButtonClass = _buttons[index] as MyButtonClass;
currentButton.addEventListener(TouchEvent.TOUCH_BEGIN, currentButton.OnTouchBegin);
[...]
}
However, what you could do is to never remove the TouchEvent.TOUCH_BEGIN in the Deactivate function. The touch events will never be triggered when the DisplayObject isn't on the Display List. This means you don't have to worry about adding the listener every time you want to add the button to the Display List again.
If you set the listener to use a weak reference it will not hinder the button from being garbage collected when it's not needed anymore. To make your event listener use a weak reference, set the fifth argument of the addEventListener method to true.
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
public function Initialize():void {
this.addEventListener(TouchEvent.TOUCH_BEGIN, OnTouchBegin, false, int.MAX_VALUE, true);
}
Do you call the Initialize method again at some point after closing the rollout?
From your code it looks as though you remove all of the event listeners in Deactivate and then never add the TouchEvent.TOUCH_BEGIN listener again.
I'm not sure what you're trying to accomplish by removing the event listeners. Since the Button has a reference to the callback, it has a reference to that callback whether the listeners are attached or not. Are you thinking that adding a listener creates a reference from the callback to the button? It doesn't--the reverse is true.
If you really want to have the Button release the callback when it is removed from the display list, then it can't hold that reference after it removes the listeners. Consider using something like Supervising Presenter or a RobotLegs Mediator to manage those dependencies.
I seriously doubt that the entire event system is being borked by what you're doing.
I'd be more inclined to believe that this:
if (listener != null)
{
_buttons[index].addEventListener(TouchEvent.TOUCH_BEGIN, listener);
}
is failing, either because the button that's referenced is not the one that's actually on stage, or because listener is null..
I have seen times where adding and removing events with priorities can cause things to fail, but typically this is with events that aren't propagating on the display list.
One way that you can test this is simply to listen to the main document or the stage for touch events and see if you're getting those events. If the entire event system is borked, you won't get them, but if your listener logic is wrong, you will.
You may also want to check the willTrigger property on the button and event.
I tried to do this :
panel.addEventListener(MouseEvent.DOUBLE_CLICK,showEditPopup);
but it is not working.
It works fine for
panel.addEventListener(MouseEvent.CLICK,showEditPopup);
So, I guess I have to enable double click first. Need help on it.
You have to enable double click for your panel before by doing this :
panel.doubleClickEnabled=true;
And then you can do :
panel.addEventListener(MouseEvent.DOUBLE_CLICK,showEditPopup);
I had this problem this morning trying to add a double click to my game.
This is what i found out.
First of all you gotta enable doubleclick like this:
panel.addEventListener(MouseEvent.DOUBLE_CLICK,showEditPopup);
You can also add the singe CLICK on the same function to prevent click to happen twice when double clicking, like this:
panel.addEventListener(MouseEvent.CLICK,showEditPopup);
Then this would be the function, interacting with both but 1 at a time:
function showEditPopup(e:MouseEvent) {
if (e.type == "click") {
//single click
} else if (e.type == "doubleClick") {
//double click
}
}
Now there is 2 problem that come up. First you gotta enable double click like this before the listener:
panel.enableDoubleClick = true;
Then the worse, if the display object is binded to another display object, which have a mouse event, you have to disable those event for the children so the double click work. Like this:
panel.mouseChildren = false;
That was bad for me because this is what i was doing.
Created a card with skills, skills had mouseevent.move_over to show a tooltip. But then i wanted to double click the card to place it/remove it from the deck. But it was not working because the skills, attached to that movieclip, had mouseevent in them. So i had to disable them and find another way to do it. Because tooltip wasnt showing with that mousechildren set to false and i had no choice to have this to bypass those event.
And this is why the timer solution seem a better idea indeed.You can go as up as 1 second for the wait time of a double click. It won't affect people and will fit even the slowest dude ;)
Two years ago, when I was developing an application for the iPhone, I used the following built-in system method on all of my buttons:
[button setExclusiveTouch:YES];
Essentially, if you had many buttons on screen, this method insured that the application wouldn't be permitted do crazy things when several button events firing at the same time as any new button press would cancel all others.
problematic: ButtonA and ButtonB are available. Each button has a mouse up event which fire a specific animated (tweened) reorganization/layout of the UI. If both button's events are fired at the same time, their events will likely conflict, causing a strange new layout, perhaps a runtime error.
solution: Application buttons cancel any current pending mouse up events when said button enters mouse down.
private function mouseDownEventHandler(evt:MouseEvent):void
{
//if other buttons are currently in a mouse down state ready to fire
//a mouse up event, cancel them all here.
}
It's simple to manually handle this if there are only a few buttons on stage, but managing buttons becomes more and more complicated / bug-prone if there are several / many buttons available.
Is there a convenience method available in AIR specifically for this functionality?
I'm not aware of such thing.
I guess your best bet would be creating your own Button class where you handle mouse down, set a static flag and prevent reaction if that flag has been already set up by other instance of the same class.
In pseudo-code:
class MyButton
{
private static var pressed : Boolean = false;
function mouseDown(evt : MouseEvent)
{
if(!pressed)
{
pressed = true;
// Do your thing
}
}
}
Just remember to set pressed to false on mouse up and you should be good to go.
HTH,
J