Skip to content

Release 0.6

Compare
Choose a tag to compare
@Empiree Empiree released this 24 Mar 16:44
· 219 commits to main since this release

0.6 Release available!

What's new:

  • Custom interceptors
  • MouseListener class improvement
  • KeyboardListener class improvement

Changelog

Custom Interceptors

Version 0.6 introduced the ability to create your own interceptors. This means that if your use case is unique and requires its own implementation, you can create a new interceptor, similar to KeyboardListener or KeyboardManipulator!

Let's try to do it together!

Our goal: block the scroll mouse event, and output all mouse events to the console except Move, since that event will quickly spam the console.

First, let's create an interceptor to block mouse scroll events:

public class ScrollDisabler : MouseInterceptor
{
    protected override bool IsInputAllowed(MouseInputArgs args)
    {
        if (args.Event is MouseInputEvent.Scroll)
            return false; // disallow mouse scroll input
        
        return true; // all other input events can be processed
    }
}

To do this, we need to inherit from the MouseInterceptor class and implement the IsInputAllowed method, which is responsible for blocking events.

Next, let's create another interceptor to output all events to the console.

public class MouseLogger : MouseInterceptor
{
    // Always allow input because it's a logger
    protected override bool IsInputAllowed(MouseInputArgs args) => true;

    // If the input event was successfully processed
    protected override void OnInputSuccess(MouseInputArgs args)
    {
        if (args.Event is MouseInputEvent.Move) // Don't log a move event
            return;
        
        Trace.WriteLine($"Processed {args.Event}");
    }

    // If the input event has been blocked
    protected override void OnInputFailure(MouseInputArgs args, IEnumerable<InterceptorInfo> failedInterceptors)
    {
        var failureReason = failedInterceptors.ToNames();
        
        Trace.WriteLine($"Failed {args.Event} by: {failureReason}");
    }
}

In addition to the familiar IsInputAllowed method, we have overridden two more methods for input processing.

OnInputSuccess - called if the input was processed successfully and no interceptor blocked it.

OnInputFailure - called if the event was blocked by one or more interceptors. In it we will get the list of these interceptors.

Note

The implementation of these 2 interceptors can be placed in one interceptor, but it is better to separate it. So that each is responsible for its own task.

All we have to do is to call the Hook method of these two classes to make the interceptors work:

var scrollDisabler = new ScrollDisabler();
var mouseLogger = new MouseLogger();
            
scrollDisabler.Hook();
mouseLogger.Hook();

Now let's run our project and test their work:

image

In the Debug console, we can see that the mouse button events have fired. And mouse wheel scrolling was blocked by ScrollDisabler class. If we need to disable this interceptor, it is enough to call the Unhook method.

It was a simple implementation of a custom interceptor. In your scenarios they can be much larger and with stronger logic.

To do the same thing but using already created interceptors, just do this:

var mouseListener = new MouseListener();
var mouseManipulator = new MouseManipulator();

mouseListener.SubscribeAll(mouseEvent =>
{
     if (mouseEvent is MouseInputEvent.Move)
         return;
                
     Trace.WriteLine($"Processed {mouseEvent}");
});
            
mouseManipulator.Prevent(PreventMouseOption.Scroll);

mouseManipulator.ClickPrevented += mouseEvent => 
     Trace.WriteLine($"Failed {mouseEvent} by: MouseManipulator");

KeyboardListener

  • Added IsKeyPressed method, which returns whether the button is pressed or not
  • Added useful properties such as IsCapsLockActive, IsNumLockActive, etc

MouseListener

  • Added SubscribeAll method that subscribes to all mouse input events
  • Added overloading for Subscribe methods, now you can get the input event. This is especially useful when using generic events like ButtonDown and ButtonUp