Interactive/HeaderImageCustom.py

# (C) Copyright 2012 Autodesk, Inc.  All rights reserved.
#
# This computer source code and related instructions and comments are
# the unpublished confidential and proprietary information of
# Autodesk, Inc. and are protected under applicable copyright and
# trade secret law.  They may not be disclosed to, copied or used by
# any third party without the prior written consent of Autodesk, Inc.


# When a scene is opened, look for an image that matches the name, except
# with a TIFF extension (e.g., example.a3s vs. example.tiff).  You can change
# the extension, but TIFF may be the only one that works with transparency.

kLookForExtension = "tiff"
kAnchorCorner = "BottomRight" # Also, "BottomLeft", "TopRight", "TopLeft".
                              # If choosing one of the Top anchors, make
                              # sure you leave enough offset for the menubar
                              # and titlebar, or you will not see the image
                              # other than in full screen or borderless.
kAnchorOffset = (5,5)         # Offset from a corner
kAnchorPercentage = (0, 0)    # 0 is bottom and left, 1 is top and right.
kImageSize = (256,64)         # Image will be rescaled to match


# Some customization examples:
"""
# 5 pixels from the left edge of the screen in the middle
kLookForExtension = "png"
kAnchorCorner = "BottomLeft"
kAnchorOffset = (5,-32)
kAnchorPercentage = (0.0,0.5)
kImageSize = (256,64)
"""

"""
# Right in the top left corner, not visible except in the full screen
# or borderless
kLookForExtension = "png"
kAnchorCorner = "TopLeft"
kAnchorOffset = (0,0)
kAnchorPercentage = (0,0)
kImageSize = (256,64)
"""

"""
# In the middle of the screen
kLookForExtension = "png"
kAnchorCorner = "BottomLeft"
kAnchorOffset = (-128,-32)
kAnchorPercentage = (0.5,0.5)
kImageSize = (256,64)
"""




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

import os

class MyImageButton(ImageButton):
    def __init__(self, clickCallback, imagesToUse):
        assert(callable(clickCallback))
        ImageButton.__init__(self)
        self.setImages(imagesToUse)
        self.setSize(kImageSize)
        self.setDraggable(False)
        self.setVisible(True)


class HeaderImageUi(OverlayUiNew):
    kCanvasUiUniqueId = "HeaderImageCustom.HeaderImage"

    def __init__(self):
        OverlayUiNew.__init__(self)
        self.myWidth = 0
        self.myHeight = 0
        self.getRoot().setUniqueId(getID(self.kCanvasUiUniqueId))
        self.doCreate()
        self.myPosition = kAnchorOffset


    def doCreate(self):
        self.__recomputePosition()
        images = {}
        images[ControlState.kNormal] = FindFile( 'image', "stop.tif" )
        self.myHeaderImage = MyImageButton( self.__onHeaderClick, images )
        self.getControls().append(self.myHeaderImage)
        for control in self.getControls():
            self.getRoot().insertChild(NodeRef(control.getNode().get()))


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


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


    def __onHeaderClick(self, x, y):
        pass


    def __recomputePosition(self):
        self.myPosition = self.anchorToAbsolute(kAnchorCorner,
                                                kAnchorPercentage[0],
                                                kAnchorPercentage[1],
                                                kAnchorOffset, kImageSize)


    def __setPosition(self):
        if self.isVisible():
            self.myHeaderImage.setPosition(self.myPosition)
            self.myHeaderImage.doLayout()


    def __setVisibility(self, visible):
        if visible != self.isVisible():
            self.setVisible(visible)
            if visible:
                self.__setPosition()
        

    def anchorToAbsolute( self, anchor, percW, percH, loc, sz ):
        x = loc[0]
        y = loc[1]
        if "BottomLeft" == anchor:
            x += percW*self.myWidth
            y += percH*self.myHeight
        elif "BottomRight" == anchor:
            x = (1.0-percW)*self.myWidth - sz[0] - x
            y += percH*self.myHeight
        elif "TopLeft" == anchor:
            x += percW*self.myWidth
            y = (1.0-percH)*self.myHeight - sz[1] - y
        elif "TopRight" == anchor:
            x = (1.0-percW)*self.myWidth - sz[0] - x
            y = (1.0-percH)*self.myHeight - sz[1] - y
        return (x,y)


    """
    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_VIEW_POSITION_AND_SIZE_CHANGED( self, message ):
        # If the window resizes, reposition
        (x, y, self.myWidth, self.myHeight, s) = message.data
        self.__recomputePosition()
        self.__setPosition()


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


    def APPLICATION_LOAD_SCENE( self, message ):
        (scenefile,) = message.data
        im = os.path.splitext(scenefile)[0] + "." + kLookForExtension
        if os.path.isfile(im):
            self.myHeaderImage.setImages({ControlState.kNormal : im})
            self.__setVisibility(True)


class HeaderImage( UserCustomBase ):
    def __init__( self ):
        self.myUniqueCanvasId = None

    def getInterpreter( self, isInteractive ):
        return None

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


def instantiate():
    return HeaderImage()


def info():
    customInfo = CustomInfo()
    customInfo.vendor = 'Autodesk'
    customInfo.version = '1.0'
    customInfo.api = '2013'
    customInfo.shortInfo = "Show an image associated with the scene."
    customInfo.longInfo = \
"""A sample add-in for the custom overlay images. For each opened scene, \
a matching image is searched for in the same directory, and if available, \
positioned on the screen. Modify the add-in to anchor to a different corner.
"""
    return customInfo