I'm trying to understand how to pause and resume interaction in paper.js.
I have the metaball example on a page with an input element on top, and because paper.js steals focus for driving the metaball generation onMouseMove... bad things happen. Like not able to select what you typed.
I understood I could use item.locked = true;, but I don't know what to apply it to because nothing works.
What is the parent Item for paper.js and can I lock it so that everything stops responding to the mouse?
I also couldn't reattach the mousemove event from the Tool, which is why I came to look into item.locked. What's the correct way to remove and reattach mouse events?
Related
I am aware of this question, but that's different to what I am looking for, as the accepted answer hides the cursor.
I'm writing software that remaps the left mouse button to the left CTRL key.
I have it working, with one problem: when I hold down the CTRL key and drag the mouse pointer this feature often activates, which messes up my drag operation (it feels like trying to change direction running on ice).
So the Apple engineers must have disabled this feature while the left mouse button is down and re-enabled it when the button is released.
Something like this -- however when I inject my simulated mouse events, the feature does not disable.
What I'm getting at is: there must be some programmatic way of doing it, even if it is an internal Apple function. Unless Apple are using the solution in the linked answer, i.e. NSCursor.hide() and then manually drawing the cursor icon at the cursor location.
How can I accomplish this cleanly?
EDIT: A CGEventTap for NSEventTypeGesture or NSEventTypeMagnify fails to catch anything.
I have been developing by game for some time now and I am now trying to code in a pause menu. I have been looking through forums and videos but i still do not understand how to implement in a pause menu. I have a little pause button in the top left corner which i want to click to pause. Then it to overlay a menu, such as changing the z position of items so they are now visible. And then there be buttons such as resume and main menu which respectively do what they are called. I am still quite new to coding so any help would be appreciated. I am working with falling objects and a moving player so if i need to freeze them all, then unfreeze once resumed that might be a solution I am not sure. Thanks :D
I've tried various ways to do this, but not found a satisfactory method that works for any app/game. A lot of it will depend on how your game works. As a starting point, you probably need to look at someway of pausing the SKScene - this should halt a lot of the animation (but you may have to do extra work).
You could add some kind of blur effect or overlay and then add an unpause button and then pause the scene. Touches will still be detected when paused, but you won't have any animation or updates happening after the pause. The following code should work to pause the scene.
let pauseAction = SKAction.run {
self.isPaused = true
debugPrint("Paused")
}
self.run(pauseAction)
The reason to pause the scene in an action is that any addChild calls won't be processed if you set isPaused directly. actuallyPaused is just a bool variable to keep track of wether the scene should be paused or not (if the parent view is un-paused, the scene would also be un-paused). Btw, You do not need to use an action to set isPaused to false.
You probably also should look at implementing observers for
NSNotification.Name.UIApplicationWillResignActive
NSNotification.Name.UIApplicationDidEnterBackground
NSNotification.Name.UIApplicationWillEnterForeground
as you will also need to know when your game has been sent to background either via control center or the home button.
I have a paper-button with the on-tap function that opens a paper-dialog that contains a "Accept" paper-button that will close it when clicked.
The problem i'm getting is if depending on my screen resolution, and the dialog's "Accept" button is over the initial button to open the dialog, when clicked, the dialog opens and closes. I'm assuming the on-tap event is being fired to both.
I've tried these 2 methods but they do not seem to help.
event.cancelBubble = true;
event.stopPropagation();
The problem is that a capacitive screens or even mouses can generate multiple tap event on the same spot within a few milisec.
The mouses because a quick change in a high and low voltage (logical 1 and 0) generating an AC signal wich can jump trough on a capacitator (which can be the button two contactor between the air) if the conditions matching. But the onclick event is already catching this case and you does not require to do anything to solve it.
The capacitve screens are capacitators and just rolling your finger should trigger multiple tap events because your skin has different depth of insulation and hard to mark the tap begin and end in some cases.
This physical problem should be solved by the platform, but it is not in every situation currently (but most of the devices are filtering this). Im usally solving this isse with a transparent overlay element wich can catch the pointer events for a little duration so I could catch the "prelling" of a button or the capacitive screen for a few ms.
If a 10-20ms is enough for you then wait a frame in your on-tap function with requestAnimationFrame and then show the dialog. Cheap trick, but it does what it has to, but ultimately you can wait a fix timeout to show the dialog, because you have 100ms to respond a user interaction.
You cannot fix this by manipulating the browser events options though because as I know you dont have option to how much time need to pass until the next same event should happend. But if you wait a frame thats could behave like you add a delay between the events.
Whenever I write mouse handling code, the onmousedown/onmouseup/onmousemove model always seemed to force me to produce unnecessarily complex code that would still end up causing all sorts of UI bugs.
The main problem which I see even in major pieces of software these days is the "ghost mouse" event where you drag to outside the window and then let go. Once you return back into the window, the application still thinks you have the mouse down even though the button is up. This is especially annoying when you're trying to highlight something that goes to the border of the screen.
Is there a RIGHT way to write mouse code or is the entire model just flawed?
Ordinarily one captures the mouse events on mouse down so the mouse move and mouse up go through your code regardless of the caret moving out of you application window.
More recently this is a problem when running a VM or remote session, its difficult for apps in these to track the mouse outside of the machine screen area represented by a window on a host.
I'm not sure what environment you're attempting to track mouse buttons in, but the best way to handle this is to have a mouse listener that tracks onmouseup 100% of the time after you've detected onmousedown.
That way, it doesn't matter what screen region the user releases the mouse button in. It will reset no matter where it happens.
In MFC a double-mouse click event triggers the following sequence of messages
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBCLK
WM_LBUTTONUP
So responding to the WM_LBUTTONDBCLK message allows you to detect a double-click. But if I just want to detect a single-click how to I distinguish it?
But just looking at the WM_LBUTTONUP message isn't enough as it could be a single-click or it could be the first click of a double-click.
How can I successfully identify just a single-click?
(Please allow me to call these events Mouse Up and Mouse Down. My MFC is a little rusty. And there's this stuff called .NET who's been messing up my terminology lately ;-)
Short story: You don't simply want to know about Mouse Click. You need more.
Long story:
Although this is counter-intuitive, it appears that simply wanting a mouse-click is fairly uncommon. Most often, you'll want to perform some processing on Mouse Down and do some further processing on Mouse Up. The trick is that simply tracking Mouse Up messages is not enough: Mouse Down may not have happened in your window. Do you consider it a valid click then? Especially considering that the Mouse Down processing (such as selecting an item) did not occur.
Going further up the reasoning, you should not rely on receiving a Mouse Up after you processed Mouse Down: User may have moved the mouse and released the button somewhere else (think drag'n'drop), in which case, you don't receive the MouseUp event... unless you capture the mouse on MouseDown to make sure you get mouse event up to Mouse Up even if the mouse left your window.
All in all, you end up tracking Mouse Down, capture the mouse and when you receive Mouse Up, just check if you own the capture. If not, the mouse was either double-clicked (no 2nd mouse down) or Mouse Down happened somewhere else hence you most likely don't care about this Mouse Up.
In conclusion: There's no MouseClick message simply because you wouldn't go very far with it: You need to handle more messages and implement more mechanics anyway.
Oh! And if your dealing with an existing control which already handles all this items and selection stuff, such as a listview, chances are it provides with a similar custom notification such as Item Activate or Item Selection Changed.
I just tried this in Delphi, the behavior is the same: even when a double click is happening, a single click event is issued right after the first one of the two.
I solved it using a timer, which works like this:
deactivate timer on WM_LBUTTONDBLCLK (and set bDbl to true)
activate timer on WM_LBUTTONUP if bDbl==false
deactivate on WM_LBUTTONUP if bDbl==true (and reset bDbl)
I set the interval of the timer to the time returned by GetDoubleClickTime.
MSDN says:
The GetDoubleClickTime function
retrieves the current double-click
time for the mouse. A double-click is
a series of two clicks of the mouse
button, the second occurring within a
specified time after the first. The
double-click time is the maximum
number of milliseconds that may occur
between the first and second click of
a double-click.
If the timer happens to fire then you have the real click. In my case the double click interval is 500ms, so any "real click" will be delayed this long.
You could check WM_LBUTTONDOWN has not been called more than once before WM_LBUTTONUP. In practice Windows does this for you, in that if you get a WM_LBUTTONDBCLK you tend not to get a WM_LBUTTONUP.
You can use PreTranslateMessage() to count the messages as they appear. If you've received only the mouse messages corresponding to a single-click, and the system-configured time for double-clicking has expired, you can safely assume it's a single-click.
As far as I know there is no way to know that this is the case as it is happening, which makes sense -- until the time is expired, there's no way to know that a second click is or isn't coming.
that's a little tricky.
I would detect the WM_LBUTTONDOWN & WM_LBUTTONUP combo, store that event somewhere and set a timeout for a second or so. If there isn't a WM_LBUTTONDBCLK during that timeout then you have a single click.
This might imply you need to have another thread running but I think you could accomplish it with one thread.
I think the solution is to start a timer after the first click & then check the elapsed time after at the next immediate click, this will tell you if it is a single click or double click.
You typically look at #MLButtonUp and you would not have single click and double click behavior on the same mouse button.