Overlay in wxWidgets - wxwidgets

I need a control
It should be asynchronous (should not block the launching thread).
It should block all the user interactions with background screen.
Backdrop shadow on background so that it gives the feeling of disabled interactions with background.
I tried wxBusyInfo. It solves my first requirement, but one can interact with background window.
Then I use the wxWindowDisabler with wxBusyInfo, It disables the background window. But looks like events are getting buffered while disabler is on and when I am destroying wxWindowDisabler object, buffered events are firing.
Then I found wxEventBlocker that can be used to block the events.
Is this the right way to achieve the requirements?

wxBusyInfo is the right class to do what you want, it doesn't dispatch events, so I'm not sure how do you manage to interact with anything while it is shown. Because it doesn't dispatch events -- even the repaint ones -- it's not recommended to show it for relatively long periods of time. If you need something more permanent, use wxProgressDialog.
Finally, wxEventBlocker is a rather special class which is only useful in very specific circumstances and this is not one of them.

Related

How to click through elements?

I have two shape at same position, not same color, and when i click over them, i want to fire click event on both, not just the first.
These two shapes are in the same container.
I have tried getObjectsUnderPoint() under stage.on("mousemove"), but this function increase my FPS (60 to 32~, and inside there are just a console.log), So it's not a good solution.
I tried the bubble, the useCapture, but i think it isn't what i want.
I just want to fire click on all element behind my mouse.
If someone have a solution, please.
There are a few points here:
EaselJS objects sort of work like HTML DOM Elements. If an element has a mouse handler on it it will block objects in other hierarchies below it from receiving the event. This is just how it works. The main difference is that if you don't have mouse events, then they are just ignored (like if you set the pointerEvents on an HTML element to none to have the mouse ignore it).
Your idea with getObjectsUnderPoint is what I would have recommended. Running any hit-test logic on mousemove is going to be expensive (mousemove fires a LOT, which is why we give the ability to throttle the typical mouseover check if you enableMouseOver on the stage).
A few things to optimize it:
Ensure you are using mode=2 on your getObjectsUnderPoint, which will only check objects with mouse listeners. This greatly reduces the overhead in checking. [docs]
Instead of checking the stage on your own mousemove event, set a flag to check it on tick. This throttles it to your Ticker FPS at least. You could also set an interval to check it even less often. It can create a little bit of a visible lag, but you can probably find a nice balance.
Reduce what is checked. If you have a container with your clickable elements in it, you can only check that object for mouse interaction.
If your objects are the exact same, you can also just trigger the click manually on the second item.
obj1.on("click", function(event) {
obj2.dispatchEvent(event);
});
I hope those approaches provide you a solution. Let me know if you have follow-up questions.
Cheers,

NSScrollView: Magnify with CMD+scroll interaction with preserved responsive scrolling

In Mavericks, Apple introduced responsive scrolling architecture in NSScrollView. This feature adds a smart way for generating overdraws and decouples handling of the incoming scroll events from the main event loop into a separate one. This topic is described in detail in the session 215 from WWDC 2013.
Because of the different event model, the scroll events no longer go through the scrollWheel(with:) method. In fact, if you override this method in the NSScrollView subclass, you opt-out from the responsive scrolling architecture completely and fall back to the legacy model.
In my NSScrollView I'd like to implement an interaction for magnification using scrolling while holding the command key. This can be observed in MindNode or OmniGraffle apps. The standard way to do this would be overriding scrollWheel(with:) and checking the modifierFlags on each scroll event. As described above, this would cause an opt-out from the responsive scrolling model.
I wonder whether there is a way to implement this interaction while also preserving the responsive scrolling?
What I have already achieved/tried:
In my NSScrollView subclass I have overridden scrollWheel(with:) and am returning true from the static property isCompatibleWithResponsiveScrolling in order to force the participation in responsive scrolling.
This way I am able to check the first scroll event for the modifier flags. If the command key is NOT pressed, I simply pass the event to super and let the NSScrollView do its thing. If the command key is pressed, I go a different route and track next scroll events on the window to do the magnification.
The problem is when one of these tracking loops is running and the user changes the press state of the command key (either presses it or releases it).
The switch from magnification to scrolling (on command key release) is simple, since the tracking loop is fully under my control.
The switch from scrolling to magnification (on command key press) is more tricky, because I cannot check the scroll events. I have overridden flagsChanged(with:) and can observe when this moment happens but I have not found a way to end the scrolling. This SO question asks about ending/disabling scrolling but has no answer yet.
I’m going to answer here instead of in comments, since I have more data.
There are two issues with “Responsive scrolling”:
(1) A few years ago there was a bug — a difference in how accelerated responsive scrolling was vs. legacy scrolling. By accelerated I mean the distance the document would travel for any given amount of movement of the fingers on the trackpad — legacy scrolling didn’t move the document as much so it felt sluggish. I reported this and it seems to have been fixed in 10.14, at least.
⑵ As near as I can tell from my research and talking to Apple people “Responsive scrolling” was designed to make scrolling more consistent even when an application is hogging the main thread (which would normally block the flow of events) — it processes scroll wheel events on a background thread instead and then messages the main thread with them. Since this still involves the main thread being called per scrolling event (or scrolling events being coalesced) I’m not clear what situations this is a win in. There may be some extra magic where the scrollview will draw more of the document from the cached content of you implement the optional caching stuff.
In my app I’m actually using the scrollview with a dummy (transparent) document and I take its scroll events and move around a SceneKit camera. Since my scene changes dramatically as you scroll around there’s no benefit to trying to pre-render outside the visible rect.
So in my case I no longer perceive any performance difference between responsive and legacy scrolling (although I did back when I filed the bug).

CreateJS pressup/click won't trigger when target movie is played on mousedown/pressmove

I have a project where I need to make flash movie as an interactive game. Because, flash is already (or soon will be) obsolete for most of browsers, I've decided this game must be based on HTML5/JS. Because most of the graphics and animations are already done in this Flash movie (and I have its source), I'm developing it using Adobe Flash and CreateJS technology (HTML5 + Canvas + JS). So far, I like this solution pretty much, though I have an issue which I could not solve yet.
The game is a simple drag&drop matching game. The problem I have is shortly described in the question title and I will try to explain it here more detailed:
label.on('mousedown', function() {
//this.image.bg.gotoAndStop(2);
});
label.on('pressmove', function(evt) {
this.x = getStageX(evt.stageX);
this.y = getStageY(evt.stageY);
currentStage.setChildIndex(this, currentStage.getNumChildren() - 1);
stage.update();
});
label.on('pressup', function(evt) {
console.log('Hi! I'm mouseup event!')
this.x = labelInitX;
this.y = labelInitY;
this.image.bg.gotoAndStop(0);
});
Above, you can see simplified 3 event handlers I use. Everything is working fine until I uncomment second line - //this.image.bg.gotoAndStop(2);. When I do this, the pressup event does not trigger mostly, which is rather strange, because some times it does trigger (2-3 times out of 10), so the label sticks with the pointer until I press the button again.
Is this some bug or I simply does not understand something about the CreateJS and its event handlers. I tried different combinations of this. Used click instead of pressup, placing this.image.bg.gotoAndStop(2); inside the pressmove handler. Replacing pressmove handler with the stage.on('stagepressmove', handler). None did not work. this.image.bg.gotoAndStop(2); - this thing simply updates the timeframe (change the background image of the label). I do can change this image programatically (without playing timeframes) and I'm almost sure that the issue will be fixes, though I'd like to understand for myself what is wrong here or what I'm doing wrong with the event handlers.
Another, less important thing, but would be useful to know is why when pressmove event is running, the CreateJS objects stop receiving event triggers about rollover or mouseover? In DOM, by default event bubbling is working until you stop it with stopPropagation. How does it work here with CreateJS? Seems that bubbling is simply turned off here by default. How can I turn it on?
I thought I might shed some light on what I think is going on.
The normal mouse events "click", "mouseup", "rollover", "rollout", etc all function by the stage determine what the "target" of the mouse event was by default the target is the lowest-level thing that is interacted with. If you contents change while the mouse is down, it will not count as the same target when the mouseup occurs. Since positions are not re-checked without moving the mouse, the mouseover, mouseout, rollover, and rollout events may function oddly as well.
Conversely, the "pressmove" and "pressup" events do not care what is under the mouse once something is pressed. The target will always be what was pressed, which allows you to move the mouse out of the object (or even remove it), and still receive events from it. This also ensures that you receive a pressup event even if you release outside the object.
As #RandyPrad mentioned, the hitArea may solve your issue. By specifying a hit area, you are overriding the contents of your clip, so your target should always be the container (MovieClip) instead of its contents. That way no matter what is pressed inside the movieclip, it is the same target when you release. You can also get the same effect using the mouseChildren property.
movieClip.mouseChildren = false;
Hope that helps!
Please check your hit area of the button.
i think that your are playing image inside the btn is animating
please use this link http://www.createjs.com/tutorials/Mouse%20Interaction/hitArea.html

Movable objects around a wxPanel

In wxWidgets, I would like to have 2 objects on a wxPanel joined by a line and with a mouse down event to relocate the position of either of the 2 objects (The line should automatically be redrawn to follow the new position of the objects). I have tried using wxPaintDC to draw the initial position of the 2 objects (Custom created with mouse click events) and using dc.DrawLine to join these 2 objects together with a line. How should I proceed to allow make those 2 objects movable (mouse down event) along with the line? Can this even be achieve?
Of course it's possible (just about everything is, it's "only" a matter of effort), but it's not completely trivial and you may want to use OGL which does it for you. On the flip side, OGL is very old and completely unmaintained since a long time, so if your needs are really simple, it's probably still better to do it yourself.
If you do, here are some hints:
For mouse handling, you first need an (efficient if possible) hit testing function.
Once you have it, it's easy to detect where a click happens and what object is under it and start moving it if it makes sense. To be more user friendly, the move shouldn't start immediately, but wait until either the mouse moves a little, or stays pressed for some longer time (this will avoid accidental moves).
When the user is dragging the mouse you will get wxEVT_MOTION events. Use wxMouseEvent::Dragging() in your handler to check whether any mouse button is pressed.
Whatever you do, you must always draw from your wxEVT_PAINT handler, i.e. if an object moves, you must not redraw it immediately, but update its position, invalidate the area taken by it before and after the move (invalidating everything is simpler, but less efficient) and draw it from your OnPaint().
You want double buffering to avoid flicker, see wxAutoBufferedPaintDC

Core Data undo background thread deletion

I'm developing sort of a drawing app in which the user sets points on a canvas. What's being drawn gets stored as NSManagedObjects. I also enabled the undo manager so the user can undo the last drawing gestures by pressing a button.
It all works as expected.
Then I have a button to delete everything on the canvas (clear canvas). When pressed I make the deletion operation on a background thread cause it might take a while and I want to present a progress bar. Then I merge the background thread's model object context with the main thread's one. This works fine too.
But I would like to be able for the user to undo the complete deletion operation with just one tap on the undo button. This is what I'm unable to do.
For the multithreading part I'm following this tutorial: http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/
It seems I can't get this to undo beyond the merge of the two threads (it worked once, though, I don't know why). Don't know if I'm supposed to nest the whole thing in undo groups. I have tried but still no luck.
I believe you can do it with nested undo groups.
Wrap your operation and merge between
-(void)beginUndoGrouping;
-(void)endUndoGrouping;
... and use -(void)undoNestedGroup to undo.