I have a list of items. I want to be able to handle both an onClick and onLongPress events. For this purpose, I am using this hook here.
My issue is that on mobile when you start to press on the item, but them move your finger out of the "hitbox" (finger no longer on the item), this will still trigger a onLongPress event. Expected behaviour is that the user should keep their finger on the item when long pressing, and only then should the event trigger.
I found this library which doesn't have this issue but ONLY works on mobile, and I'm trying to make my app compatible with all platforms, including the browser (as a PWA): this one
Any sort of advice on how to move forward would be greatly appreciated.
Related
I'm using React, and have a material UI Card that toggles on and off when clicked. I am trying to 1) get the card to toggle on/off correctly if the user long-presses it, and 2) disable the card toggling if the user presses it and slides(drags) away, then releases. Performing these actions with a mouse has all the desired effects, and there are no problems. However, my app is used on a touch-screen monitor (without a mouse) and so I must replicate the same outcomes with touching the screen.
Initially, I was using the onClick event handler to toggle the card. Long pressing with your finger (the first issue) was not properly toggling it. After a bit of research, I learned that mouse and touch events were combined into one: pointer events. So I switched onClick to onPointerUp and it worked magically.
However, this is where the second issue comes in. If the user clicks the card and drags his or her finger away from it and releases, it still gets toggled (using the mouse doesn't have this same effect). I did some digging and according to MDN, pointer capture could be related:
Pointer capture allows events for a particular pointer event (PointerEvent) to be re-targeted to a particular element instead of the normal (or hit test) target at a pointer's location. This can be used to ensure that an element continues to receive pointer events even if the pointer device's contact moves off the element (such as by scrolling or panning).
My question is, why is the mouse click working correctly while touching doesn't? And how does one go about disabling the card getting toggled when your finger is dragged away from it?
Codesandbox of sample
Edit: Forgot to mention, I want the card to toggle correctly as long as the touch is released while on the card (even if it is dragged away and returns). This works fine with the mouse, but for touching, it toggles regardless of where your finger is released.
Edit2: Added codesandbox link.
Some things of note: touch-action is set to none (CSS) and this is where the strange behavior happens, but I need to have it set that way to prevent unwanted touch registers like scrolling.
I also noticed that for mouse clicks, you can select a card by clicking outside the card and dragging into it and releasing the click. I guess since the event is onPointerUp that would make sense. Although this effect is undesirable, users will only use touching in my app so it's not something I have to worry about. Regardless, I would like to understand the right way to approach this and how to achieve my desired effects.
How can I prevent the showing of the Next or Done buttons of the Android VKB in a Codename One app?
Currently, for my app, they are a mess: the next button of the VKB doesn't focus the next field, but the previous. After tons of trials, I didn't find a way to make them working correctly (but there are fine on iOS and on the Simulator). I also tried to override the Layout.overridesTabIndices(com.codename1.ui.Container) and Layout.getChildrenInTraversalOrder(com.codename1.ui.Container) methods in the Form, but nothing changed on Android.
I supposed two possible causes: the use of a Form inside a Form or, more probably, the fact that I replace all the TextFields and Pickers in the same Form (and other components). Maybe the fact that the inner Form is deeply changed results in a confusion for the Android mapping of the "next" button.
That's why my request: because I didn't find a way to make the "next" button useful, I'm asking how I can avoid that it's been shown.
Thank you
Nesting forms would probably mess with the focus traversal/tab order.
Normally you should be able to override public TabIterator getTabIterator(Component start) to return a blank iterator. I'd suggest doing the same for both the parent and child form to disable the "next" feature.
I am working on a windows store application and I want to be able to drag between buttons so that the originally pressed button becomes deactivated and the newly "dragged onto" button becomes activated but I can't seem to get this to work.
I have 2 Buttons inside a StackPanel and the events I have on them are:
PointerPressed
PointerEntered
PointerReleased
PointerExited
PointerCanceled
PointerCaptureLost
PointerPressed and PointerEntered share the same event handler and the rest (the "deactivation" events) share the same event handler.
If I press one button my "activated" event handler is triggered and if I drag off it my "deactivated" event handler is triggered but if I then drag onto the second button the "activated" event handler isn't triggered again.
Strangely, if I start by dragging from off the StackPanel onto one of the buttons the "activated" event handler is triggered. I assume that it is something to do with the internal pointer management stuff but can't seem to find a workaround.
Does anyone know why this is happening and how I can get it to work how I want?
Thanks for your time.
Edit
Okay I've been researching some stuff and I've come across CapturePointer() and ReleasePointerCapture() but this seems to be broken - If I capture the pointer, when I take my finger off the screen, PointerReleased doesn't even get hit.
I've also realized why the "dragging from off the SP onto one of the buttons causes it to 'activate'" - this is because when a button is pressed it doesn't route its event but fires a Click event - meaning the same pointer cannot fire a PointerEntered event of another button, but if it starts outside a Button it will trigger PointerEntered.
This doesn't get me much further but it is a little extra info :)
The concept of Button is a bit unique in regard to mouse capture and how dragging away from it happens. In your scenario I'm not sure if the event model around Button will work correctly for you. On Button, when a pointer is depressed (mouse) it has capture until it is released. This is not the same for touch where a press and drag away is different because in touch there isn't any explicit capture unless you create it.
So what you are hitting is going to be a slight conflict between mouse/touch interactions anyway using Button -- using some other UI element (not sure if you have a styled button) should get you what you want.
I'm trying to show a context menu when I left-click a NotifyIcon. Just calling NotifyIcon.ContextMenuStrip.Show() doesn't work very well. A solution has been posted here before that calls a secret method using Reflection:
Dim mi As System.Reflection.MethodInfo = GetType(NotifyIcon).GetMethod("ShowContextMenu", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
mi.Invoke(Icon, Nothing)
This works great, except that I also need to control where the menu is shown. I want to wait for the SystemInformation.DoubleClickTime to elapse between receiving the NotifyIcon.MouseUp event and displaying the menu, so that I can handle single-clicks and double-clicks separately. But invoking the ShowContextMenu method displays the menu at the current mouse position when ShowContextMenu is called, not when the icon was actually clicked. Which means that if the mouse moved during the DoubleClickTime, the menu will be displayed in a different part of the screen. So if I can control where the menu is shown, I can just save the mouse coordinates when I receive the MouseUp event, and then I can ensure that the menu is displayed near the icon. Is there a way to do this?
Thanks in advance.
Well, I just discovered that there are existing programs that exhibit this same behavior. I just went through all the icons in my system tray and about half of them do it. If you left-click the icon and then move the mouse during the delay before the menu appears, the menu will appear at the last mouse location, wherever that is on the screen. Snagit is one application that does this. Outlook is the only program in my tray that always shows the menu where I clicked the icon. But Snagit looks like it's using a .NET ContextMenuStrip, while Outlook is probably using a native menu.
So either this is standard behavior, or it's a problem that no one else has been able to solve either. And as a user, I've never noticed this behavior until yesterday when I was testing my own application. So I guess it's not that big of a deal and I won't worry about it.
I have a button which launches a "modal dialog" - it just creates a transparent grid covering everything, with the "dialog" created on top of that.
However I have a strange issue - if I double/triple click the button really fast (or add some delay in the event code), the button click event is executed multiple times, creating multiple overlapping modal dialogs. If the first action in my event is to disable the button (IsEnabled=false) it seems to prevent this.
My guess is that Silverlight is being multithreaded with input - it is not only recording the second click in another thread (while the button's click event is running), but it is jumping the gun by evaluating which control should be the target before the previous event has finished executing. Even though that event alters what control is at those mouse coordinates, it doesn't matter.
Does anyone know anything about this behavoir, or a way around it? If I have something like a save window, where the user clicks a save button, a blocking grid ("Saving...") is placed up while it saves, and then the whole "window" is closed, I'd like to avoid the user being able to queue up multiple save event clicks (this could lead to unpredictable program behavoir).
If you've ever worked with WinForms or WPF, this is expected behavior. Your button is broadcasting its Click event until your modal dialog covers it up. Unfortunately, there is some amount of time between your first click and when the modal dialog covers the button which allows multiple clicks to the original button.
You have two solution choices:
Disable the button after the first click and then re-enable after the modal dialog returns. You've already mentioned that this works.
Write code in the Event Handler of the button to determine if a modal dialog is already being displayed. This way, you're putting the responsibility in one location rather than splitting it up (disabling and re-enabling the button). This would be my preferred solution.
I think what you're seeing is the behaviour of Silverlight's routed events.
You can set the Handled property of the event arguments to true to prevent the event from bubbling.