Interactive/InCanvasCustom.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.

from UserCustomization  import UserCustomBase, CustomInfo
from RTFapi             import NodeRef
from UI                 import ControlState, FindImages, getID, ImageButton
from UiSelector         import OverlayUiNew


class MyImageButton(ImageButton):
    def __init__(self, clickCallback, imagesToUse):
        assert(callable(clickCallback))
        ImageButton.__init__(self)
        self.myClickCallback = clickCallback
        self.myPressOffset = (0, 0)
        self.setImages(imagesToUse)
        self.setSize((32, 32))
        self.setDraggable(False)
        self.setVisible(True)

    def detachCallbacks(self):
        self.myClickCallback = None

    def wantsDragData(self, dragData):
        return True

    def doRelease(self, uiEvent):
        ImageButton.doRelease(self, uiEvent)
        atX, atY = uiEvent.getPosition()
        offsetX, offsetY = self.myPressOffset
        x = int(round(atX - offsetX))
        y = int(round(atY - offsetY))
        self.myClickCallback(x, y)


class InCanvasUi(OverlayUiNew):
    kCanvasUiUniqueId = "InCanvasCustom.WireframeShadedSimpleCustom"

    def __init__(self):
        OverlayUiNew.__init__(self)
        self.getRoot().setUniqueId(getID(self.kCanvasUiUniqueId))
        self.doCreate()

    def doCreate(self):
        """
        self.setTitleImage( absoluteImageLocation )
        self.setTitleSize( (width, height) )
        self.setCloseButtonPosition( (posX, posY) )
        self.createCommon(OverlayUiNew.kTitle | \
                          OverlayUiNew.kCloseButton | \
                          OverlayUiNew.kLeftBorder | \
                          OverlayUiNew.kBottomBorder)
        """
        self.__myInCanvasL = MyImageButton( self.__onInCanvasClickL,
                                            FindImages({
                                                ControlState.kNormal    : "stop.tif",
                                                ControlState.kHighlight : "stopHighlight.tif",
                                                ControlState.kPress     : "stopPressed.tif"}))
        self.__myInCanvasR = MyImageButton( self.__onInCanvasClickR,
                                            FindImages({
                                                ControlState.kNormal    : "play.tif",
                                                ControlState.kHighlight : "playHighlight.tif",
                                                ControlState.kPress     : "playPress.tif"}))
        self.getControls().append(self.__myInCanvasL)
        self.getControls().append(self.__myInCanvasR)

        for control in self.getControls():
            self.getRoot().insertChild(NodeRef(control.getNode().get()))

    def doCleanup(self):
        self.__myInCanvasL.detachCallbacks()
        self.getRoot().removeChild(NodeRef(self.__myInCanvasL.getNode().get()))
        self.__myInCanvasL = None

        self.__myInCanvasR.detachCallbacks()
        self.getRoot().removeChild(NodeRef(self.__myInCanvasR.getNode().get()))
        self.__myInCanvasR = None

    def doLayout(self, position, size):
        self.layoutCommon(position, size)

    def __onInCanvasClickL(self, x, y):
        self.sendMessage( 'SET_DRAW_MODE', ("WIREFRAME",) )
        pass

    def __onInCanvasClickR(self, x, y):
        self.sendMessage( 'SET_DRAW_MODE', ("SHADED",) )
        pass

    def __setVisibility(self, visible):
        if visible != self.isVisible():
            self.setVisible(visible)
            if visible:
                self.__myInCanvasL.setPosition((14, 15))
                self.__myInCanvasL.doLayout()
                self.__myInCanvasR.setPosition((54, 15))
                self.__myInCanvasR.doLayout()

    """
    If the layout of the interface was changing or dynamic,
    we would collect dirty status and update it in this
    function if self.isDirty() is True.
    def FRAME_SYNCHRONIZE_END(self, message)
    """

    def CUSTOM_OVERLAY_SET_MODE( self, message):
        (which, visible) = message.data
        if which == self.kCanvasUiUniqueId:
            self.__setVisibility(visible)

    # We do not mind showing this interface together with everything else,
    # so we do not need to listen to the other _UI_SET_MODE messages.

    def APPLICATION_CLOSE_SCENE( self, message ):
        self.__setVisibility(False)


class InCanvas( UserCustomBase ):
    def __init__( self ):
        #UserCustomBase.__init__(self)
        self.myUniqueCanvasId = None
        pass

    def getInterpreter( self, isInteractive ):
        return None


    def getCustomUi( self ):
        ui = InCanvasUi()
        self.myUniqueCanvasId = ui.kCanvasUiUniqueId
        return (self.myUniqueCanvasId,ui)


    def appendMenuItems( self, id, menu ):
        if 'Edit' == id:
            menu.AppendSeparator()
            self.__myCanvasShowId = menu.appendItem(_( 'Show canvas UI' ),
                                                    self.__onCanvasShow )
            self.__myCanvasHideId = menu.appendItem(_( 'Hide canvas UI' ),
                                                    self.__onCanvasHide )

    def enableMenuStates( self, id, enableStates ):
        if 'Edit' == id:
            enableStates[self.__myCanvasShowId] = True
            enableStates[self.__myCanvasHideId] = True

    def __onCanvasShow( self, event ):
        self.sendMessage( 'CUSTOM_OVERLAY_SET_MODE',
                          ( self.myUniqueCanvasId, True, ) )

    def __onCanvasHide( self, event ):
        self.sendMessage( 'CUSTOM_OVERLAY_SET_MODE',
                          ( self.myUniqueCanvasId, False, ) )


def instantiate():
    return InCanvas()


def info():
    customInfo = CustomInfo()
    customInfo.vendor = 'Autodesk'
    customInfo.version = '1.0'
    customInfo.api = '2013'
    customInfo.shortInfo = "Switch between wireframe and shaded mode."
    customInfo.longInfo = \
"""A sample add-in showing how to switch between wireframe and shaded mode using in-canvas controls.
"""
    return customInfo