from datetime import datetime, timedelta import gremlin from gremlin.user_plugin import * # User-configurable variables; these appear in the Joystick Gremlin UI axis = PhysicalInputVariable( "Axis", "The axis that will trigger scrolling.", [gremlin.common.InputType.JoystickAxis], ) mode = ModeVariable( "Mode", "The mode in which the axis will be mapped.", ) scroll_speed = FloatVariable( "Scroll Speed", "Adjusts the rate at which the target button is pressed, relative to the axis strength.", 1.0, ) deadzone = FloatVariable( "Deadzone", "Applies a deadzone to both sides of the axis.", 0.0, ) # NB: Not a real boolean; invert.value returns 0 or 2 invert = BoolVariable( "Invert", "Reverse the direction that the axis scrolls.", False, ) # Constants AXIS_SCALING_FACTOR = 250 # Value determined through testing. # Debugging ticks = 0 axis_decorator = axis.create_decorator(mode.value) last_timestamp = datetime.now() scroll_scaling = scroll_speed.value if scroll_speed.value != 0.0 else 1.0 # TODO: use this code instead when periodic callback is fixed # @gremlin.input_devices.periodic(1) @axis_decorator.axis(axis.input_id) def handle_axis(event): global last_timestamp global damping global ticks # debug # TODO: use this code instead when periodic callback is fixed # axis_value = joy[axis.device_guid].axis(axis.input_id).value axis_value = event.value if (abs(axis_value) < deadzone.value): return delta = (datetime.now() - last_timestamp) / timedelta(milliseconds=1) # Scroll speed is *inversely proportional* to the right-hand side of this comparison if delta >= ((1 - abs(axis_value)) * AXIS_SCALING_FACTOR) / scroll_scaling: direction = 1 if axis_value > 0 else -1 if invert.value: direction = direction * -1 gremlin.sendinput.mouse_wheel(direction) last_timestamp = datetime.now() # debug ticks += 1 gremlin.util.log(ticks)