Actionscript 3 :Simple Drag Question., - apache-flex

I am trying to create a scroller...The videoSlider is my scrollBar and I want to drag it so my secondMC will move....everything works fine in my code but if I mouse down in my videoSlider and up outside of it....The drag state still apply and it's not what I desire....any ideas?? Thanks...
videoSlider.addEventListener(MouseEvent.MOUSE_DOWN, scrollMC);
videoSlider.addEventListener(MouseEvent.MOUSE_UP, stopScrollMC);
var eventTarget:Object; // to allow more global access to the dragged object
function scrollMC(event:MouseEvent):void{
eventTarget = Object(event.currentTarget);
eventTarget.startDrag(false,new Rectangle(0,0,500,0));
stage.addEventListener(MouseEvent.MOUSE_MOVE, adjust2ndX);
}
function stopScrollMC(event:MouseEvent):void{
eventTarget.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_MOVE, adjust2ndX);
}
function adjust2ndX(evt:MouseEvent):void {
secondMC.x = eventTarget.x;
}

Listen for MouseUp on the stage. Your object isn't going to get a MouseUp event if the mouseup occurs somewhere else.

Related

How can I keep Flex events from being dispatched to the target?

I'd like to avoid that mouse events triggered by the user don't get dispatched to their target objects, effectively "freezing" the GUI for the user.
In a sample application featuring just a single mx.controls.Button I called addEventListener on the button to get notified of mouse events. In the event handler, I called Event::stopImmediatePropagation on the event, assuming that this would "discard" the event. Clicking the button would call my event handler, but yet the button was "clicked" (it animated and triggered an event).
How could I do this?
button.mouseEnabled = false;
button.mouseChildren = false;
should work
Depending on how advanced your interface is, you could just throw an object (s:Rect in an s:Group would work) on top of everything, set width and height to 100%, and disable mouseChildren
USE removeEventListener()
var b:Button = new Button();
function init():void
{
b.addEventListener(MouseEvent.CLICK, onButtonClick);
}
function onButtonClick(event:MourseEvent):void
{
b.removeEventListener(MouseEvent.CLICK, onButtonClick);
}

how to stop getting mouse click events in flex

I have made a hierarchy in which there is a main page, using add element i have attached a component mxml of type group. There is a single button on main page when clicked it should add children of type group in that group type mxml component along with two buttons. Now using one of buttons i am attaching another component mxml type group. the problem is even they overlap i can still excess the children groups of first group component mxml. how can i stop this mouse events to happen.
I think those kind of events usually bubble up to parent components.
You can try using the following code in your mouse click event listener to stop further propagation:
private function onMouseClicked(event: MouseEvent): void {
event.stopPropagation();
... do whatever you wanted when smth was clicked ...
}
By setting enabled, mouseChildren, mouseEnabled to false, you will disable the entire component and it's children. example below
private var myPreviousGroupComponent:Group = null;
function addNewGroup():void
{
if(myPreviousGroupComponent != null)
{
myPreviousGroupComponent.enabled = false;
myPreviousGroupComponent.mouseChildren = false;
myPreviousGroupComponent.mouseEnabled = false;
}
var newGroup:Group = new Group();
addElement(newGroup);
myPreviousGroupComponent = newGroup;
}

How can we listen to an event dispatched in PopUpWindow inside the parent component?

I have a warning Popwindow with 2 buttons 'Submit' and 'Cancel'.
On clicking submit I invoke a function and dispatch 'submit' Event with bubble true. I want to handle this inside my parent application. I have already registered the event with the parent container as well as the popup instance.
Inside Parent.mxml :
private function launchWarningPopUp():void {
var win:Warning = PopUpManager.createPopUp(this, Warning, false ) as Warning;
win.addEventListener(SubmitQuizEvent.SUBMIT_QUIZ, submissionDone);
this.addEventListener(SubmitQuizEvent.SUBMIT_QUIZ, submissionDone);
PopUpManager.centerPopUp(win);
}
private function submissionDone():void{
Alert.show('Inside SubmissionDoneTwo');
}
Inside Warning.mxml:
private function submitHanlder():void {
dispatchEvent(new SubmitQuizEvent(SubmitQuizEvent.SUBMIT_QUIZ,true));
PopUpManager.removePopUp(this);
}
The event should bubble to Parent.mxml.
Am I doing something wrong here or is it simply not possible ?
I am stuck here, any help in this regard would be greatly appreciated.
Thanks in advance.
You should add your event listener to the systemManager because popups are direct children of the system manager
You are correct. the popup is not a child of the component that creates it. It is, as Florian said, a child of systemManager and events don't bubble as you might expect.
I was unable to catch this event inside my function as the signature was missing. After I add this the code worked.
private function submissionDone(event:SubmitQuizEvent):void{
Alert.show('Inside SubmissionDone with signature');
}
=================================================================================
I am facing another issue now.
The event is captured only when I use ' win.addEventListener....' and not with 'this.addEventListener ............'.This is surprizing to me.
If Parent.mxml is parent of 'win' then the events triggered inside 'win' should bubble and should be caught by the parent. This is not happening.
Is 'win' not considered child of the Parent.mxml ? And is treated as external component ?
Please let me know your view on this ??

Drag and drop in dataGrid, custom cursor during drag not working

I have a datagrid that I want the user to sort the rows on. To make it obvious that it's sortable I am implementing some custom cursors. But I'm having a problem when I actually drag an item.
here's a pseudo demonstration of the problem
Application = normal cursor // fine
Rollover datagrid = open hand cursor // good so far
mousedown on datagrid = closed hand cursor // good
dragging item around = closed hand cursor // switches back to normal cursor (if I move it around real fast I can see my custom curser for an instant)
mouse up on datadrid = open hand cursor // not sure, after I drop it goes back to open hand but if I mouse down, dont move and mouse up I have a closed hand
rollout of datagrid = normal cursor //good
datagrid code:
<mx:DataGrid id="sectQuestionsDG" x="10" y="204" width="558" height="277" headerHeight="0" selectable="{editMode}"
dragMoveEnabled="{editMode}" dragEnabled="{editMode}" dropEnabled="{editMode}"
dragDrop="sectQuestReOrder(event);" rollOver="over();" mouseDown="down();" mouseUp="up();" rollOut="out();"/>
functions:
public function over():void{
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,0,0);
}
public function down():void{
CursorManager.setCursor(grabbingCursor,CursorManagerPriority.HIGH,0,0);
}
public function up():void{
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,0,0);
}
public function out():void{
CursorManager.removeAllCursors();
}
Edit 12/17/09:
I've made a little bit of progress, I'm now doing this on rollOver
var styleSheet:CSSStyleDeclaration = StyleManager.getStyleDeclaration("DragManager");
styleSheet.setStyle("moveCursor", grabbingCursor);
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW);
This is giving me the correct rollover and correct drag, but if I try to add any
function to rollOut it screws up again, so now I'm stuck with the grabCursor. It
seems like when I set a rollOut on the dataGrid it's firing for each row, same
with mouseOut, is there any way to avoid that?
Edit 12/21/09:
It is a confirmed thing that roll/mouse out/over fire for every item in the datagrid. The solution I need is how to prevent that and only fire it when the user mouses out of the datagrid as a whole. I need flex to see the forest, not the trees.
PS. the rollout only fires on every item when I am dragging. mouseout fires on every item regardless
EDIT 12/21/09, End of the day:
I have managed to answer my own question so my bounty rep is lost to me :-( Anyway since my answer solves my problem I will award the bounty to anyone that can answer this. My solution uses AS to remove the the rollOut/rollOver while a user is dragging. In a dataGrid. How can you get the same result without removing the rollOut/rollOver (so that rollOut is not firing for each item as you drag another item over it)?
Why not use the property isDragging of DragManager if you are doig a drag you dont need to change the cursor. And dont forget to check for the dragExit event in case you drop outside the datagrid.
N.B
sometimes the cursor keep with the dragging shape after the drop so you can in your sectQuestReOrder remove the cursor and set it back to over state.
sample:
public function over(evt:Event):void{ //on mouse over, added with AS
if (DragManager.isDragging) // you are dragging so no cursor changed
return;
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
var styleSheet:CSSStyleDeclaration = StyleManager.getStyleDeclaration("DragManager");
styleSheet.setStyle("moveCursor",grabbingCursor); //style set for the drag cursor
}
public function down(evt:Event):void{ // on mouse down
CursorManager.removeAllCursors();
CursorManager.setCursor(grabbingCursor,CursorManagerPriority.LOW,-7,-7);
}
public function up(evt:Event):void{
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
}
public function out(evt:Event):void{
if (DragManager.isDragging) // you are dragging so no cursor changed
return;
CursorManager.removeAllCursors();
}
public function sectQuestReOrder(e:Event):void{
// sometime you will be stuck with the moving cursor
// so after the drop done reset cursor to what you want
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
...
}
public function onDragExit(e:Event):void {
// in case you go out of the datagrid reset the cursor
// so when you do a drop outside you ll not get one of your dragging cursor
CursorManager.removeAllCursors();
}
And in your grid add dragExit
<mx:DataGrid
id="sectQuestionsDG"
x="10" y="204" width="558" height="277" headerHeight="0"
selectable="{editMode}"
dragExit="onDragExit(event)"
dragMoveEnabled="{editMode}"
dragEnabled="{editMode}"
dropEnabled="{editMode}"
dragDrop="sectQuestReOrder(event);"
rollOver="over(event);"
mouseDown="down(event);"
mouseUp="up(event);"
rollOut="out(event);"/>
I would look at the mouseOut event and determine if its firing when you're moving the mouse during a drag. I have seen cases where the dragged object doesn't move exactly with the mouse, and for a short while, the mouse is actually hovering over another object (causing the mouseOut event to fire, thus changing the cursor).
OK some props to Gabriel there for getting my mind out of a rut and back into this problem in full mode. I had to go through a few steps to get to my answer
1)remove the listeners for rollOver, rollOut, and mouseUp from the mxml and add rollOver and rollOut through the addEventListener method in AS
2) add the listener dragComplete to the mxml and assign the function previously assigned to mouseUP to it
3) change the main function to this:
public function over(evt:Event):void{ //on mouse over, added with AS
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
var styleSheet:CSSStyleDeclaration = StyleManager.getStyleDeclaration("DragManager");
styleSheet.setStyle("moveCursor",grabbingCursor); //style set for the drag cursor
}
public function down(evt:Event):void{ // on mouse down
CursorManager.removeAllCursors();
CursorManager.setCursor(grabbingCursor,CursorManagerPriority.LOW,-7,-7);
sectQuestionsDG.removeEventListener(MouseEvent.ROLL_OVER,over);
sectQuestionsDG.removeEventListener(MouseEvent.ROLL_OUT,out);
//this is why I had to take it off the mxml, can only remove listeners
//added with the addEventListener, I don't remember where I read that.
}
public function up(evt:Event):void{
CursorManager.removeAllCursors();
CursorManager.setCursor(grabCursor,CursorManagerPriority.LOW,-7,-7);
sectQuestionsDG.addEventListener(MouseEvent.ROLL_OVER,over);
sectQuestionsDG.addEventListener(MouseEvent.ROLL_OUT,out);
}
public function out(evt:Event):void{
CursorManager.removeAllCursors();
}

Click-outside event on custom components in flex

Is there a way to write a custom event that gets triggered when the user clicks outside of that custom component instance? Basically anywhere else in the main flex app.
Thanks.
You can use the FlexMouseEvent.MOUSE_DOWN_OUTSIDE event. For example:
myPopup.addEventListener(
FlexMouseEvent.MOUSE_DOWN_OUTSIDE,
function(mouseEvt:FlexMouseEvent):void
{
PopUpManager.removePopUp(myPopup);
}
);
stage.addEventListener( MouseEvent.CLICK, stgMouseListener, false, 0, true );
...
private function stgMouseListener( evt:MouseEvent ):void
{
trace("click on stage");
}
private function yourComponentListener( evt:MouseEvent ):void
{
trace("do your thing");
evt.stopPropagation();
}
Got this from Senocular. I think it applies to this subject, at least it did the trick for me. What jedierikb suggested seems to be the same, but a little incomplete.
Preventing Event Propagation
If you want to prevent an event from propagating further, you can stop it from doing so within an event listener using stopPropagation() (flash.events.Event.stopPropagation()) or stopImmediatePropagation() (flash.events.Event.stopImmediatePropagation()). These methods are called from the Event objects passed into event listeners and essentially stop the event from happening - at least past that point.
stopPropagation prevents any objects beyond the current from recieving the event, and this can be within any phase of the event. stopImmediatePropagation does the same but also takes the extra step of preventing additional events within the current target receiving the event from happening too. So where as stopPropagation would prevent sprite A's parent from receiving the event, stopImmediatePropagation would prevent sprite A's parent as well as any other listeners listening to sprite A from receiving the event.
Example: toggle between using stopPropagation and stopImmediatePropagation
ActionScript Code:
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x4080A0);
circle.graphics.drawCircle(50, 50, 25);
addChild(circle);
circle.addEventListener(MouseEvent.CLICK, clickCircle1);
circle.addEventListener(MouseEvent.CLICK, clickCircle2);
stage.addEventListener(MouseEvent.CLICK, clickStage);
function clickCircle1(evt:MouseEvent):void {
evt.stopPropagation();
// evt.stopImmediatePropagation();
trace("clickCircle1");
}
function clickCircle2(evt:MouseEvent):void {
trace("clickCircle2");
}
function clickStage(evt:MouseEvent):void {
trace("clickStage");
}
Click the circle and see how the event is stopped with each method. stopPropagation prevented the stage from receiving the event while stopImmediatePropagation also prevented clickCircle2 from recognizing the event
normal output
clickCircle1
clickCircle2
clickStage
stopPropagation output
clickCircle1
clickCircle2
stopImmediatePropagation output
clickCircle1
Flex/Actionscript 3 - close popupanchor on mouse clicked anywhere outside popup anchor
for 4.6 SDK try this..
frmPUA.popUp.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, menuPopOutside, false, 0, true);
Full code is avaiable at
http://saravanakumargn.wordpress.com/2013/12/14/flexactionscript-3-close-popupanchor-on-mouse-clicked-anywhere-outside-popup-anchor-2/

Resources