How to capture global touch events in MAUI app - maui

I have MAUI app and I want to record touch events by users on Android and Windows platform globally in order to record a macro and later playback the macro.

In Android, the View class defines an overridable method named OnTouchEvent to process all the touch activity. The type of the touch activity is defined by enumeration members Down, PointerDown, Move, Up, and PointerUp.The Android View also defines an event named Touch that allows an event handler to be attached to any View object.
In the Universal Windows Platform (UWP), the UIElement class defines events named PointerPressed, PointerMoved, and PointerReleased. These are described in the article Handle Pointer Input article on MSDN and the API documentation for the UIElement class.
You can check this article which shows how to implement low-level multi-touch finger tracking, and how to generate events that signal touch activity:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/effects/touch-tracking

You have two options to capture touch events of the user.
1. Easy - use GestureRecognizers
Use View.GestureRecognizers on your control on which you want to capture user inputs. The advantage is that this works on all platforms out of the box.
You can add different gesture recognizer such as tap, swipe, pan, ... in code behind or in xaml.
I guess the tap gesture is the one you are looking for
See: https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/gestures/tap
1.1 Sample
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += TapGestureRecognizer_Tapped;
elementView.GestureRecognizers.Add(tapGestureRecognizer);
2. Use platform dependent events
If you want to use more specific platform events like, "mouse over" and so on you can use the dot net maui handlers.
See here: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/handlers/customize
2.1 Sample
In this example we want to set a property called IsMouseOver depending whether the mouse is over the control CardView or not. This can look for example like the following:
//in App.xamls.cs
Microsoft.Maui.Handlers.ElementHandler.ElementMapper.AppendToMapping("IsMouseOver", (handler, view) =>
{
#if WINDOWS
if (view is CardView cardView && handler.PlatformView is ContentPanel contentPanel)
{
contentPanel.PointerEntered += (sender, e) =>
{
view.Dispatcher.Dispatch(()=>cardView.IsMouseOver = true);
};
contentPanel.PointerExited += (sender, e) =>
{
view.Dispatcher.Dispatch(()=>cardView.IsMouseOver = false);
};
}
#endif
});
The full example can be found here. Note you may need to use the Dispatcher of the control when dealing with events.
Update: On android GestureRecognizers will fire only on the control where you added the gesture. If you want to capture the events of the child controls you need to add the GestureRecognizers as well for the childs. For the windows platform you don't need to add the GestureRecognizers on the child control. It will be inherited. Hopefully they will fix this later on android.

Related

Best way to organize OnClick events for Unity buttons?

enter image description here
Unity has a component called Button as part of its UI system which you can use to subscribe on-click events to it through the inspector which is incredibly useful.
However, when projects get larger, I run into trouble in many situations:
events subscribed this way in the inspector are not rearrange-able which makes buttons that have lots of events difficult to manage
changing the contents of the scripts used for events can cause the button to not recognize a function that was used for an event which means you have to re-reference it
if anything happens to the GameObject or prefab that stores the Button component such as it getting corrupt then all your events that were serialized onto the button would be wiped and you would need to re-reference all of them
the above points make debugging very very difficult
What are some ways I can work around the problems I've listed above?
Inject event functions inside the code:
public Button playButton; // set button in inspector
public void Start()
{
playButton.onClick.AddListener(() =>
{
transform.position = point1;
// do something..
});
}

How can I make use of Event Delegation in a parent Svelte Component

In this example, if I click the Tutorial NavItem I get to the Tutorial
section. Here I forward an custom click event on every Nav Item, where I set the segment which has been clicked. In the app.svelte I pull in the NavItem component and set the segment to current, which tells the Nav Component (through Props), which segment is current and needs to be active.
My question is how Can i Make use of event Delegation, so the Nav Component listen for the click Event, so it doesn't feel so repetitiv
The minimal Example goes like that, I want the parent to handle the event?:
https://svelte.dev/repl/691e82ee168549c782b61c355e78cf9b?version=3.12.1
Here is a complex Ex. the Repl:
https://svelte.dev/repl/691e82ee168549c782b61c355e78cf9b?version=3.12.1
I see you already use the getContext and setContext functionality. Instead of firing the event you can simply update that context:
in NavItem.svelte
function setSegment(){
current.set(segment);
}

Sortable/Orderable list - draggable reset() functionality

I am implementing sortable/dorderable list functionality with Sencha Touch 2.0 . I am trying to replicate the functionality as it were in Sencha Touch 1.1 with Ext.util.Sortable class.
I am almost successful in getting the similar functionality with dragging around and with movement of other list items. However, in Sencha 1.1, there is a draggable.reset() functionality which mostly updates the boundaries as well as resets the offsets. I am unable to replicate this reset functionality with Sencha 2.0 draggable behavior.
Any ideas how to implement that? Following is the code in Sencha 1.1:
// We reset the draggable (initializes all the new start values)
draggable.reset();
// Move the draggable to its current location (since the transform is now
// different)
draggable.moveTo(region.left, region.top);
I changed moveTo() function with this:
draggable._element.setXY([region.left, region.top]);
But not the reset() functionality. I have tried to set the -webkit-transform directly to the draggable element but somehow that style isn't getting added to that element. Any help?
Fixed the issue. The reset() function is no longer required - just changed the record index in the Dataview store and refreshed the dataview in "dragend" event.
You can also do as shown in this example..
http://druckit.wordpress.com/2013/04/08/tap-and-drag-animation-domination-part-3-of-3-implementing-drag-and-drop-in-sencha-touch-2/

Safari on the iPhone & iPad gives colour feedback on touch, I want to stop this

Clicking on an element which has a Javascript handler makes the element go have a 'grey overlay'. This is normally fine but I'm using event delegation to handle the touchdown events of many child elements. Because of the delegation the 'grey overlay' is appearing over the parent element and looks bad and confusing.
I could attach event handlers to the individual elements to avoid the problem but this would be computationally very wasteful. I'd rather have some webkit css property that I can override to turn it off. I already have visual feedback in my app so the 'grey overlay' is not needed.
Any ideas?
-webkit-tap-highlight-color
To disable tap highlighting, set the
alpha value to 0 (invisible)
$('body').bind('touchstart', function(e){
e.preventDefault()
})
For those reading this question, another CSS property which will not only remove the overlay but also prevent the touch device from interacting with the user to assess a tap intention (which delays the timing of the event trigger significantly), is to use the cursor property.
a.notTappable {
cursor:default
}
Also, in the case the asker described where you have descendants of a parent and you only want the descendants to be tappable and you wish to IGNORE ALL MOUSE EVENTS OF THE PARENT, the following solution will you give you the best performance (by completely disabling the bubbling up to the parent). Read the webkit spec here.
.parent {
pointer-events:none;
}
.parent .descendant {
pointer-events:default;
}
I only mention this because the performance difference here is significant.

Disable user interaction in a GWT container?

I want to disable/enable user interaction (mouse click more specificly) on many widgets like hyperlink, button, etc which are contained in a composite (flextable)
there are more than one click handlers, and I don't want to bother with removing and adding listeners according to mode (interaction enabled/disabled)
Any ideas would be appriciated...
You forgot to mention the version of GWT. In GWT 2.0 you can use this code snippet or something similar. This feature allows you to cancel events before they are handed over to the target widget.
Event.addNativePreviewHandler(new Event.NativePreviewHandler() {
public void onPreviewNativeEvent(NativePreviewEvent pEvent) {
final Element target = pEvent.getNativeEvent().getEventTarget().cast();
// block all events targetted at the children of the composite.
if (DOM.isOrHasChild(getElement(), target)) {
pEvent.cancel();
}
}
});
There is a GlassPanel compoent in google-web-toolkit-incubator. I am almost sure it does what you need. Either way, it is a good idea to cover a disabled component whit one of these.