Callback on view transition? - c4

I'm hacking the multicanvas example. I want to modify it in order to trigger some event whenever a new target view is displayed, i.e. on completion of the transitionFromView method.
I understand I could probably trigger some event from the completion block of the transitionFromView method, but I'm wondering if there's an existing callback mechanism in place for that.
I've tried implementing the following in the target canvas, but that doesn't seem to be called when switching views:
- (void)viewDidAppear{
NSLog(#"my event");
}
Is there another callback I'm not aware of?
Thank you.

Try using the following methods:
-(void)viewDidAppear:(BOOL)animated {}
-(void)viewDidDisappear:(BOOL)animated {}
NOTE: it's the :(BOOL)animated {} part that you were missing from your method names.
I downloaded the MultiCanvas example, and set the title for each of the canvases like so (changing the A to B and C):
-(void)setup {
self.title = #"WorkSpaceA";
//... the rest of the setup code as per the example
}
I also added two methods to each of the canvases:
-(void)viewDidAppear:(BOOL)animated {
C4Log(#"%# %#",self.title,NSStringFromSelector(_cmd));
}
-(void)viewDidDisappear:(BOOL)animated {
C4Log(#"%# %#",self.title,NSStringFromSelector(_cmd));
}
I then got the following logs:
//at launch
[C4Log] WorkSpaceA viewDidAppear:
//then I tapped button B
[C4Log] WorkSpaceB viewDidAppear:
[C4Log] WorkSpaceA viewDidDisappear:
//then I tapped button A
[C4Log] WorkSpaceA viewDidAppear:
[C4Log] WorkSpaceB viewDidDisappear:
//then I tapped Button C
[C4Log] WorkSpaceA viewDidAppear:
[C4Log] WorkSpaceB viewDidAppear:
[C4Log] WorkSpaceC viewDidAppear:
[C4Log] WorkSpaceA viewDidDisappear:

Related

Adding eventhandler to tab context menu throws null pointer exception

I would like to add the event handler to a tab context menu. And after the tab context menu is selected I would like to remove the event handler from the node. The problem is that Tab2.getContextMenu().addEventHandler(Event.ANY,handler); throws a NullPointerException.
#FXML Tab Tab2; - Tab2 can be found in my fxml with fx:id="Tab2"
EventHandler<Event> handler = (new EventHandler<Event>() {
public void handle(Event event) {
System.out.println("Tab2 is selected!");
Tab2.getContextMenu().removeEventHandler(Event.ANY, this);
}
});
Tab2.getContextMenu().addEventHandler(Event.ANY, handler);
The code takes place in initialize function.
I would like to achive a similar solution like this:
Tab2.setOnSelectionChanged(e -> {
if(Tab2.isSelected()) {
System.out.println("Tab2 is selected!");
}
});
Unfortunately, with this solution it will run all the time on selection. But I want it to happen only once and also remove the event listener.
This asker used a similar solution like me:
How to remove an event handler?
But he had no problem with adding the event handler.
EDIT:
It seems like getContextMenu() function causes the nullpointer exception and it also seems I kind of misunderstood what that function does. I wanted to get the tab's "header".
But the question remains the same. How can I add an event listener to a tab, and after it is selected the first time remove the event listener from it. That's all.
You can set the listener value as null
e.g.:
tab1.setOnSelectionChanged((e)->{
if(tab1.isSelected()){
tab1.setOnSelectionChanged(null);
}
});

I tried to disable the button after the first click.it's working for me now. when the dialog box closed i want the button enabled again

void CMyViewerDlg::OnBnClickedShow()
{
m_DCM.Create(IDD_TAG, this);
m_DCM.ShowWindow(SW_SHOW);
BOOL isOn = true;
if (isOn == false)
{
GetDlgItem(IDC_SHOW)->EnableWindow(TRUE);
}
else
{
GetDlgItem(IDC_SHOW)->EnableWindow(FALSE);
}
}
now the button is disabled after the first click..i want to enable the button again when i close the dialog box..help me to slove this problem..
This is not meant to replace the existing answer but it is based on the comments.
You can use the Classwizard to add custom message handlers. I create a GUID and attach that to WM_APP and use registered messages.
This is a non modeless dialog. So you have to keep track of it on your own. The easiest way would be to send a WM_APP+n message to the parent window/dialog, when the dialog receives the OnDestroy or OnClose event. The parent dialog can handle this message and disable the appropriate button.
Another method is just setting a timer. In the timer you can check if m_DCMTagDlg.m_hWnd is still not NULL. If it reaches NULL just disable the button.

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);
}

Dispatch an event from a class that inherits from EventDispatcher

I've got a class that extends EventDispatcher.
What I want to do is to dispatch the click event when the component is clicked. (The class is essentially some text in a textfield that needs to be able to do certain things, and it needs to be able to respond to a click). Sounds easy enough... I want the event dispatched when that portion of the text is clicked. But uh...how? it's not like a button where I can just go
myButton.addEventListener(MouseEvent.CLICK, myClickHandler);
That's clear, because some component is going to be listening for the Click event dispatched when myButton is clicked. It is built into the AS3 framework that a button knows how to listen for a click event.
After the import statements I've got:
[Event(name="click" type="mx.events.Event")]
How do I dispatch the event when the component is clicked, when the component doesn't yet know how to respond to a click event? I've tried adding an event listener in the textfield which contains this custom class of text, but nothing's happening because the Click event hasn't been dispatched.
You can create your own click event and dispatch it. You can do that also to dispatch clicks on objects where no user ever have clicked :D
Try this:
var mEvent:MouseEvent = new MouseEvent(MouseEvent.CLICK, [HERE MORE PARAMS BY YOU]);
yourObject.dispatchEvent(mEvent);
Now, you will recieve Click Events from yourObject.
Let's say your class consists TextField tf. Then public function YourClass():void { //Constructor
{
//intialize Something
//initialize tf
tf.addEventListener(MouseEvent.CLICK, onClick);
...
}
...
private function onClick(e:MouseEvent):void {
this.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
OK, I tried this in the constructor:
var mEvent:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false);
this.dispatchEvent(mEvent);
Then, in the containing textfield, while iterating through these objects (each of which is called cp), I did this:
cp.addEventListener(MouseEvent.CLICK, mouseClickHandler);
Finally the mouseClickHandler:
private function mouseClickHandler(event:MouseEvent):void
{
trace("Clicked!!!!!!!!!!!");
}
Running in debug mode I get nada. Nunca. Niente. Nuttin'. Which is to say: no trace of being clicked. Did I do something wrong?

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