kAnchorNone = "none"
kAnchorBL = "bottomLeft"
kAnchorBR = "bottomRight"
kAnchorTL = "topLeft"
kAnchorTR = "topRight"
kWhatToShow = (
("canvas1", "http://www.google.com/", (kAnchorBL, 0, 0), (20,20), (256,400)),
("canvas2", "http://www.autodesk.com/", (kAnchorBR, 0, 0), (20,20), (256,400)),
)
from UserCustomization import UserCustomBase
from RTFapi import Event, Id, NodeRef, WebContainer
from UI import ControlState, getID, ImageButton
from MessageInterpreter import MessageInterpreter
from ActionRegistry import theActionRegistry
from RunInUiThread import RunInUiThread
from UiSelector import OverlayUiNew
kCanvasKeyMappingId = 'CanvasKeys'
class MyImageButton(ImageButton):
def __init__(self, clickCallback, imagesToUse, winsize=(32,32)):
assert(callable(clickCallback))
ImageButton.__init__(self)
self.myClickCallback = clickCallback
self.myPressOffset = (0, 0)
self.setImages(imagesToUse)
self.setSize(winsize)
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.Example"
def __init__(self):
self.myWidth = 0
self.myHeight = 0
self.myInCanvas = {}
self.myPosition = {}
OverlayUiNew.__init__(self)
self.getRoot().setUniqueId(getID(self.kCanvasUiUniqueId))
self.doCreate()
def anchorToAbsolute( self, anchor, percW, percH, loc, sz ):
x = loc[0]
y = loc[1]
if kAnchorNone == anchor:
pass
elif kAnchorBL == anchor:
x += percW*self.myWidth
y += percH*self.myHeight
elif kAnchorBR == anchor:
x = (1.0-percW)*self.myWidth - sz[0] - x
y += percH*self.myHeight
elif kAnchorTL == anchor:
x += percW*self.myWidth
y = (1.0-percH)*self.myHeight - sz[1] - y
elif kAnchorTR == anchor:
x = (1.0-percW)*self.myWidth - sz[0] - x
y = (1.0-percH)*self.myHeight - sz[1] - y
return (x,y)
def makeBrowser(self):
wc = WebContainer.instance()
for (name,url,anchor,loc,sz) in kWhatToShow:
id = self._id(name)
br = wc.browser(id)
if br is None:
id = wc.createBrowser( id.getFullId(), sz[0], sz[1] )
br = wc.browser(id)
if br is not None:
br.navigate( url )
def _id(self,name):
return Id("mem:WEB:%s" % (name))
def doCreate(self):
self.makeBrowser()
for (name,url,anchor,loc,sz) in kWhatToShow:
id = self._id(name)
self.myPosition[name] = self.anchorToAbsolute(anchor[0],anchor[1],
anchor[2],loc,sz)
self.myInCanvas[name] = \
MyImageButton( self.__onInCanvasClick,
{ControlState.kNormal : id.getFullId(),
ControlState.kHighlight : id.getFullId(),
ControlState.kPress : id.getFullId()},
sz)
self.getControls().append(self.myInCanvas[name])
for control in self.getControls():
self.getRoot().insertChild(NodeRef(control.getNode().get()))
def doRefresh(self):
wc = WebContainer.instance()
for (name,url,anchor,loc,sz) in kWhatToShow:
id = self._id(name)
br = wc.browser(id)
if br is not None:
br.navigate( url )
def doCleanup(self):
for each in self.myInCanvas.values():
each.detachCallbacks()
self.getRoot().removeChild(NodeRef(each.getNode().get()))
self.myInCanvas = {}
def doLayout(self, position, size):
self.layoutCommon(position, size)
def __onInCanvasClick(self, x, y):
for (name,url,anchor,loc,sz) in kWhatToShow:
pos = self.myPosition[name]
if (x > pos[0]) and (x < (pos[0]+sz[0])) and \
(y > pos[1]) and (y < (pos[1]+sz[1])):
normX = float(x - pos[0]) / float(sz[0])
normY = float(y - pos[1]) / float(sz[1])
id = self._id(name)
br = WebContainer.instance().browser(id)
if br is not None:
br.mouseDownRel(normX,normY)
br.mouseUpRel(normX,normY)
break
def __recomputePosition(self):
for (name,url,anchor,loc,sz) in kWhatToShow:
id = self._id(name)
self.myPosition[name] = self.anchorToAbsolute(anchor[0],anchor[1],
anchor[2],loc,sz)
def __setPosition(self):
if self.isVisible():
for (name,url,anchor,loc,sz) in kWhatToShow:
inc = self.myInCanvas[name]
inc.setPosition(self.myPosition[name])
inc.doLayout()
def __setVisibility(self, visible):
if visible != self.isVisible():
self.setVisible(visible)
self.__setPosition()
"""
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)
if not visible:
self.doRefresh()
def APPLICATION_CLOSE_SCENE( self, message ):
self.__setVisibility(False)
def SET_DISPLAY( self, message ):
(display,) = message.data
(x, y, self.myWidth, self.myHeight) = display.getPositionAndSize(0)
def APPLICATION_VIEW_POSITION_AND_SIZE_CHANGED( self, message ):
(x, y, self.myWidth, self.myHeight, s) = message.data
self.__recomputePosition()
self.__setPosition()
class InCanvas( UserCustomBase ):
def __init__( self ):
self.myInterpreter = LocalInterpreter()
self.myCanvasShowId = None
self.myUniqueCanvasId = None
self.myMenuId = None
self.myMenu = None
pass
def getInterpreter( self, isInteractive ):
if isInteractive:
return self.myInterpreter
return None
def getCustomUi( self ):
ui = InCanvasUi()
self.myUniqueCanvasId = ui.kCanvasUiUniqueId
self.myInterpreter.myUniqueCanvasId = self.myUniqueCanvasId
return (self.myUniqueCanvasId,ui)
def appendMenuItems( self, id, menu ):
if self.myMenuId is None and ('Display' == id):
self.myMenuId = id
self.myMenu = menu
self.myInterpreter.myMenu = menu
menu.AppendSeparator()
self.myCanvasShowId = menu.appendCheckItem( _( 'Canvas UI\tQ' ),
self.__onCanvasShow )
self.myContDrawId = menu.appendCheckItem( _( 'Continuous Draw' ),
self.__onContDraw )
theActionRegistry.register( Event.BUTTON_q,
(),
True,
Event.BUTTONUP,
'CanvasMode',
'Global' )
self.myInterpreter.myCanvasShowId = self.myCanvasShowId
def enableMenuStates( self, id, enableStates ):
if self.myMenuId == id:
enableStates[self.myCanvasShowId] = True
enableStates[self.myContDrawId] = True
def resetMenuStates(self, id):
if self.myMenuId == id:
menuItemStates = {}
menuItemStates[self.myCanvasShowId] = False
menuItemStates[self.myContDrawId] = False
self.myMenu.checkMenuItems(menuItemStates)
def __onCanvasShow( self, event ):
isOn = event.IsChecked()
self.myInterpreter.myCanvasMode = isOn
self.sendMessage( 'CUSTOM_OVERLAY_SET_MODE',
( self.myUniqueCanvasId, isOn, ) )
def __onContDraw( self, event ):
isOn = event.IsChecked()
self.myInterpreter.setContinuousDraw( isOn )
class LocalInterpreter( MessageInterpreter ):
def __init__( self ):
MessageInterpreter.__init__( self )
self.myDisplay = None
self.myCanvasMode = False
def SET_DISPLAY( self, message ):
( self.myDisplay, ) = message.data
def setContinuousDraw( self, state ):
if self.myDisplay is not None:
self.myDisplay.setContinuousDraw(state)
def APPLICATION_CLOSE_SCENE( self, message ):
self.myDisplay.setContinuousDraw(False)
def CanvasMode( self, evt ):
self.myCanvasMode = not self.myCanvasMode
self.sendMessage( 'CUSTOM_OVERLAY_SET_MODE',
( self.myUniqueCanvasId, self.myCanvasMode, ) )
if self.myMenu is not None and self.myUniqueCanvasId is not None:
RunInUiThread( self.myMenu.Check,
self.myCanvasShowId,
self.myCanvasMode )
def instantiate():
return InCanvas()