Interactive/ButtonSimulateCustom.py

# (C) Copyright 2012 Autodesk, Inc.  All rights reserved.
#
# Use of this software is subject to the terms of the Autodesk license
# agreement provided at the time of installation or download, or which
# otherwise accompanies this software in either electronic or hard copy
# form.

# Example how to simulate arrow keys and page up/down presses from
# menu items (if kEnableMenuItems is set to True) or expose those
# to the external UI.
#
# For example, if you are sending this through Ajax (e.g., localhost:5555)
# the first would press the up button, the second one would release it.
#
# BUTTON_SIMULATE::4::1
# BUTTON_SIMULATE::4::0


__all__ = ['ButtonPressCustom']

# ################
# SET THIS TO False IF YOU DO NOT WANT THE MENU ITEMS
kEnableMenuItems = True


from MessageInterpreter import MessageInterpreter
from RTFapi             import Event, EventRef
from UserCustomization  import UserCustomBase, CustomInfo
from MessageRegistry    import theMessageRegistry

BUTTON_SIMULATE_Doc = \
[(
"""
Simulate pressing and releasing arrow keys and page up/down.
"""
),
[[("button"),("1 - left, 2 - right, 3 - down, 4 - up, 5 - page down, 6 - page up")],
 [("what"),("1 - press, 0 - release, < 0 - press for that many seconds, then release")],
 ]
]

theMessageRegistry.register("BUTTON_SIMULATE", (int,int,), 0, BUTTON_SIMULATE_Doc)

class ButtonPressCustom (UserCustomBase):
    def __init__(self):
        self.__myMenuItems = None
        self.__myInterpreter = MoveInterpreter()

    def getInterpreter(self,isInteractive):
        if isInteractive:
            return self.__myInterpreter
        return None

    def appendMenuItems(self,id,menu):
        if kEnableMenuItems and "View" == id:
            self.__myMenuItems = []
            self.__myMenuItems.append( menu.appendItem(_( 'Left Press and Hold for 3' ),
                                                       self.__onLeftPressAndHold ) )

            self.__myMenuItems.append( menu.appendItem(_( 'Left Press' ),
                                                       self.__onLeftPress ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Left Release' ),
                                                       self.__onLeftRelease ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Right Press' ),
                                                       self.__onRightPress ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Right Release' ),
                                                       self.__onRightRelease ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Down Press' ),
                                                       self.__onDownPress ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Down Release' ),
                                                       self.__onDownRelease ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Up Press' ),
                                                       self.__onUpPress ) )
            self.__myMenuItems.append( menu.appendItem(_( 'Up Release' ),
                                                       self.__onUpRelease ) )
            self.__myMenuItems.append( menu.appendItem(_( 'PageDown Press' ),
                                                       self.__onPageDownPress ) )
            self.__myMenuItems.append( menu.appendItem(_( 'PageDown Release' ),
                                                       self.__onPageDownRelease ) )
            self.__myMenuItems.append( menu.appendItem(_( 'PageUp Press' ),
                                                       self.__onPageUpPress ) )
            self.__myMenuItems.append( menu.appendItem(_( 'PageUp Release' ),
                                                       self.__onPageUpRelease ) )


    def enableMenuStates(self,id,enableStates):
        if self.__myMenuItems is not None and "View" == id:
            for i in self.__myMenuItems:
                enableStates[i] = True

    def __onLeftPressAndHold( self, event ):
        self.__myInterpreter.ButtonEx(1,-3)
    def __onLeftPress( self, event ):
        self.__myInterpreter.Button(1,1)
    def __onLeftRelease( self, event ):
        self.__myInterpreter.Button(1,0)
    def __onRightPress( self, event ):
        self.__myInterpreter.Button(2,1)
    def __onRightRelease( self, event ):
        self.__myInterpreter.Button(2,0)
    def __onDownPress( self, event ):
        self.__myInterpreter.Button(3,1)
    def __onDownRelease( self, event ):
        self.__myInterpreter.Button(3,0)
    def __onUpPress( self, event ):
        self.__myInterpreter.Button(4,1)
    def __onUpRelease( self, event ):
        self.__myInterpreter.Button(4,0)
    def __onPageDownPress( self, event ):
        self.__myInterpreter.Button(5,1)
    def __onPageDownRelease( self, event ):
        self.__myInterpreter.Button(5,0)
    def __onPageUpPress( self, event ):
        self.__myInterpreter.Button(6,1)
    def __onPageUpRelease( self, event ):
        self.__myInterpreter.Button(6,0)


# -----------------------------------------------------------------------

class MoveInterpreter( MessageInterpreter ):

    def __init__( self ):
        MessageInterpreter.__init__( self )
        self.__myEventQueue = None

    def SET_DISPLAY( self, message ):
        ( display, ) = message.data
        self.__myEventQueue = display.getEventQueue()

    def ButtonEx( self, button, action ):
        self.sendMessage( "BUTTON_SIMULATE", (button, action) )


    def BUTTON_SIMULATE( self, message ):
        (button,action) = message.data
        if action >= 0:
            self.Button(button, action)
        else:
            self.Button(button, 1)
            self.sendMessage( "AT_DELAY", (float(-action), "BUTTON_SIMULATE", (button, 0)) )

    def Button( self, button, action ):
        if self.__myEventQueue is None:
            return

        key = None
        dir = None
        if 1 == button:
            key = Event.BUTTON_Left
        elif 2 == button:
            key = Event.BUTTON_Right
        elif 3 == button:
            key = Event.BUTTON_Down
        elif 4 == button:
            key = Event.BUTTON_Up
        elif 5 == button:
            key = Event.BUTTON_Page_Down
        elif 6 == button:
            key = Event.BUTTON_Page_Up

        if action:
            dir = Event.BUTTONDOWN
        else:
            dir = Event.BUTTONUP

        if dir is not None and key is not None:
            event = Event(dir, key)
            eventRef = EventRef(event)
            self.__myEventQueue.queueEvent(event)

# --------------------------------------------------------------------

def instantiate():
    return ButtonPressCustom()


def info():
    customInfo = CustomInfo()
    customInfo.vendor = 'Autodesk'
    customInfo.version = '2.0'
    customInfo.api = '2013'
    customInfo.shortInfo = "Send a message that presses a keyboard button."
    customInfo.longInfo = \
"""An example and support for pressing a keyboard key by sending a message. This can be useful \
for the scenario where navigation is done from custom UI.
"""
    return customInfo