class SceneGraphEditor(SceneEditorModule): def __init__(self): super(SceneGraphEditor, self).__init__() self.sceneDirty = False self.activeSceneNode = None self.refreshScheduled = False self.previewing = False self.workspaceState = None def getName(self): return 'scenegraph_editor' def getDependency(self): return ['scene_editor', 'mock'] def onLoad(self): #UI self.windowTitle = 'Scenegraph' self.container = self.requestDockWindow('SceneGraphEditor', title='Scenegraph', size=(200, 200), minSize=(200, 200), dock='left') #Components self.treeFilter = self.container.addWidget(GenericTreeFilter( self.container), expanding=False) self.tree = self.container.addWidget( SceneGraphTreeWidget(self.container, sorting=True, editable=True, multiple_selection=True, drag_mode='internal')) self.treeFilter.setTargetTree(self.tree) self.tree.module = self self.tool = self.addToolBar('scene_graph', self.container.addToolBar()) self.delegate = MOAILuaDelegate(self) self.delegate.load(getModulePath('SceneGraphEditor.lua')) self.entityCreatorMenu = self.addMenu('main/scene/entity_create', {'label': 'Create Entity'}) self.componentCreatorMenu = self.addMenu('main/scene/component_create', {'label': 'Create Component'}) #menu self.addMenuItem('main/file/open_scene', dict(label='Open Scene', shortcut='ctrl+shift+o')) self.addMenuItem('main/file/close_scene', dict(label='Close Scene', shortcut='Ctrl+W')) self.addMenuItem('main/scene/save_scene', dict(label='Save', shortcut='Ctrl+S')) self.addMenuItem('main/scene/locate_scene_asset', dict(label='Locate Scene Asset')) self.addMenu('main/scene/----') self.addMenu('component_context', dict(label='Selected Component')) self.addMenuItem('component_context/remove_component', dict(label='Remove')) self.addMenuItem('component_context/----') self.addMenuItem('component_context/copy_component', dict(label='Copy')) self.addMenuItem('component_context/paste_component', dict(label='Paste Component Here')) self.addMenuItem('component_context/----') self.addMenuItem('component_context/move_component_up', dict(label='Move Up')) self.addMenuItem('component_context/move_component_down', dict(label='Move Down')) self.addMenuItem('component_context/----') self.addMenuItem('component_context/edit_component_alias', dict(label='Edit Alias')) self.addMenu('main/entity', dict(label='Entity')) self.addMenuItem('main/entity/add_empty_entity', dict(label='Create Empty', shortcut='ctrl+alt+N')) self.addMenuItem('main/entity/add_entity', dict(label='Create', shortcut='ctrl+shift+N')) self.addMenuItem('main/entity/----') self.addMenuItem('main/entity/group_entity', dict(label='Group Entites', shortcut='ctrl+G')) self.addMenuItem( 'main/entity/create_group', dict(label='Create Empty Group', shortcut='ctrl+shift+G')) self.addMenuItem('main/entity/----') self.addMenuItem( 'main/entity/load_prefab', dict(label='Load Prefab', shortcut='ctrl+alt+shift+N')) self.addMenuItem( 'main/entity/load_prefab_in_container', dict(label='Load Prefab In Container', shortcut='ctrl+shift+=')) self.addMenuItem('main/entity/----') self.addMenuItem('main/entity/remove_entity', dict(label='Remove')) self.addMenuItem('main/entity/clone_entity', dict(label='Clone', shortcut='ctrl+d')) self.addMenuItem('main/entity/----') self.addMenuItem('main/entity/add_component', dict(label='Add Component', shortcut='ctrl+alt+=')) self.addMenuItem('main/entity/assign_layer', dict(label='Assign Layer', shortcut='ctrl+alt+L')) self.addMenuItem('main/entity/toggle_visibility', dict(label='Toggle Visibility', shortcut='ctrl+/')) self.addMenuItem('main/entity/freeze_entity_pivot', dict(label='Freeze Pivot')) self.addMenuItem('main/entity/----') self.addMenuItem('main/find/find_entity', dict(label='Find In Scene', shortcut='ctrl+f')) self.addMenuItem('main/find/find_entity_in_group', dict(label='Find In Group', shortcut='ctrl+shift+f')) self.addMenuItem('main/find/find_entity_group', dict(label='Find Group', shortcut='ctrl+alt+f')) #Toolbars self.addTool('scene_graph/select_scene', label='Select Scene', icon='settings') self.addTool('scene_graph/----') self.addTool('scene_graph/create_group', label='+ Group', icon='add_folder') self.addTool('scene_graph/----') self.addTool('scene_graph/make_proto', label='Convert To Proto', icon='proto_make') self.addTool('scene_graph/create_proto_instance', label='Create Proto Instance', icon='proto_instantiate') self.addTool('scene_graph/create_proto_container', label='Create Proto Container', icon='proto_container') self.addTool('scene_graph/----') self.addTool('scene_graph/fold_all', label='F') self.addTool('scene_graph/unfold_all', label='U') self.addTool('scene_graph/refresh_tree', label='R') # self.addTool( 'scene_graph/load_prefab', label = '+ P' ) # self.addTool( 'scene_graph/save_prefab', label = '>>P' ) self.addTool('scene/refresh', label='refresh', icon='refresh') #SIGNALS signals.connect('moai.clean', self.onMoaiClean) signals.connect('scene.clear', self.onSceneClear) signals.connect('scene.change', self.onSceneChange) signals.connect('selection.changed', self.onSelectionChanged) signals.connect('selection.hint', self.onSelectionHint) signals.connect('preview.start', self.onPreviewStart) signals.connect('preview.stop', self.onPreviewStop) # signals.connect( 'animator.start', self.onAnimatorStart ) # signals.connect( 'animator.stop' , self.onAnimatorStop ) signals.connect('entity.added', self.onEntityAdded) signals.connect('entity.removed', self.onEntityRemoved) signals.connect('entity.renamed', self.onEntityRenamed) signals.connect('entity.modified', self.onEntityModified) signals.connect('entity.visible_changed', self.onEntityVisibleChanged) signals.connect('entity.pickable_changed', self.onEntityPickableChanged) signals.connect('prefab.unlink', self.onPrefabUnlink) signals.connect('prefab.relink', self.onPrefabRelink) signals.connect('proto.unlink', self.onPrefabUnlink) signals.connect('proto.relink', self.onPrefabRelink) signals.connect('app.ready', self.postAppReady) signals.connect('component.added', self.onComponentAdded) signals.connect('component.removed', self.onComponentRemoved) signals.connect('project.presave', self.preProjectSave) registerSearchEnumerator(sceneObjectSearchEnumerator) registerSearchEnumerator(entityNameSearchEnumerator) registerSearchEnumerator(componentNameSearchEnumerator) registerSearchEnumerator(layerNameSearchEnumerator) def onStart(self): self.refreshCreatorMenu() def postAppReady(self): self.openPreviousScene() def openPreviousScene(self): previousScene = self.getConfig('previous_scene', None) if previousScene: node = self.getAssetLibrary().getAssetNode(previousScene) if node: node.edit() def onStop(self): if self.activeSceneNode: self.setConfig('previous_scene', self.activeSceneNode.getNodePath()) else: self.setConfig('previous_scene', False) def onSetFocus(self): self.container.show() self.container.raise_() self.container.setFocus() def getActiveScene(self): return self.delegate.safeCallMethod('editor', 'getScene') def getActiveSceneRootGroup(self): scene = self.delegate.safeCallMethod('editor', 'getScene') if scene: return scene.rootGroup else: return None def openScene(self, node, protoNode=None): if self.activeSceneNode == node: if self.getModule('scene_view'): self.getModule('scene_view').setFocus() if protoNode: self.delegate.safeCallMethod('editor', 'locateProto', protoNode.getPath()) if self.getModule('scene_view'): self.getModule('scene_view').focusSelection() else: if not self.closeScene(): return if self.getModule('scene_view'): self.getModule('scene_view').makeCanvasCurrent() self.activeSceneNode = node signals.emitNow('scene.pre_open', node) scene = self.delegate.safeCallMethod('editor', 'openScene', node.getPath()) if not scene: #todo: raise something alertMessage( 'error', '%s\n\nfailed to open scene, see console for detailed information.' % node.getPath()) return False signals.emitNow('scene.open', self.activeSceneNode, scene) self.setFocus() self.editingProtoNode = protoNode self.loadWorkspaceState(False) self.delegate.safeCallMethod('editor', 'postOpenScene') def closeScene(self): if not self.activeSceneNode: return True if self.sceneDirty: res = requestConfirm('scene modified!', 'save scene before close?') if res == True: #save self.saveScene() elif res == None: #cancel return elif res == False: #no save pass self.markSceneDirty(False) self.tree.clear() self.getApp().clearCommandStack('scene_editor') self.getSelectionManager().removeSelection(self.getActiveScene()) signals.emitNow('scene.close', self.activeSceneNode) self.delegate.safeCallMethod('editor', 'closeScene') self.activeSceneNode = None return True def onSceneClear(self): # self.tree.clear() pass def markSceneDirty(self, dirty=True): if not self.previewing: self.sceneDirty = dirty def saveWorkspaceState(self): self.retainWorkspaceState() treeFoldState = self.workspaceState['tree_state'] containerFoldState = self.workspaceState['container_state'] entityLockState = self.workspaceState['entity_lock_state'] self.activeSceneNode.setMetaData('tree_state', treeFoldState) self.activeSceneNode.setMetaData('container_state', containerFoldState) self.activeSceneNode.setMetaData('entity_lock_state', entityLockState) def loadWorkspaceState(self, restoreState=True): treeFoldState = self.activeSceneNode.getMetaData('tree_state', None) containerFoldState = self.activeSceneNode.getMetaData( 'container_state', None) entityLockState = self.activeSceneNode.getMetaData( 'entity_lock_state', None) self.workspaceState = { 'tree_state': treeFoldState, 'container_state': containerFoldState, 'entity_lock_state': entityLockState } if restoreState: self.restoreWorkspaceState() def retainWorkspaceState(self): #tree node foldstate treeFoldState = self.tree.saveFoldState() #save introspector foldstate introspectorFoldState = self.delegate.safeCallMethod( 'editor', 'saveIntrospectorFoldState') entityLockState = self.delegate.safeCallMethod('editor', 'saveEntityLockState') self.workspaceState = { 'tree_state': treeFoldState, 'container_state': introspectorFoldState, 'entity_lock_state': entityLockState } def restoreWorkspaceState(self): if not self.workspaceState: return treeState = self.workspaceState.get('tree_state', None) if treeState: self.tree.loadFoldState(treeState) containerState = self.workspaceState.get('container_state', None) if containerState: self.delegate.safeCallMethod('editor', 'loadIntrospectorFoldState', containerState) lockState = self.workspaceState.get('entity_lock_state', None) if lockState: self.delegate.safeCallMethod('editor', 'loadEntityLockState', lockState) def onSceneChange(self): self.tree.hide() self.tree.rebuild() self.restoreWorkspaceState() self.tree.refreshAllContent() self.tree.verticalScrollBar().setValue(0) self.tree.show() if self.editingProtoNode: self.delegate.safeCallMethod('editor', 'locateProto', self.editingProtoNode.getPath()) self.editingProtoNode = None if self.getModule('scene_view'): self.getModule('scene_view').focusSelection() def saveScene(self): if not self.activeSceneNode: return self.markSceneDirty(False) signals.emitNow('scene.save') self.delegate.safeCallMethod('editor', 'saveScene', self.activeSceneNode.getAbsFilePath()) signals.emitNow('scene.saved') self.saveWorkspaceState() def refreshScene(self): if not self.activeSceneNode: return if self.previewing: return self.refreshScheduled = False node = self.activeSceneNode self.retainWorkspaceState() if self.delegate.safeCallMethod('editor', 'refreshScene'): self.restoreWorkspaceState() self.refreshCreatorMenu() def scheduleRefreshScene(self): if not self.activeSceneNode: return self.refreshScheduled = True def refreshCreatorMenu(self): def addEntityMenuItem(name): if name == '----': self.entityCreatorMenu.addChild('----') return self.entityCreatorMenu.addChild({ 'name': 'create_entity_' + name, 'label': name, 'command': 'scene_editor/create_entity', 'command_args': dict(name=name) }) def addComponentMenuItem(name): if name == '----': self.componentCreatorMenu.addChild('----') return self.componentCreatorMenu.addChild({ 'name': 'create_component_' + name, 'label': name, 'command': 'scene_editor/create_component', 'command_args': dict(name=name) }) self.entityCreatorMenu.clear() self.componentCreatorMenu.clear() registry = _MOCK.getEntityRegistry() #entity keys = sorted(registry.keys()) addEntityMenuItem('Entity') addEntityMenuItem('----') for entityName in sorted(registry.keys()): if entityName != 'Entity': addEntityMenuItem(entityName) #component registry = _MOCK.getComponentRegistry() for comName in sorted(registry.keys()): addComponentMenuItem(comName) def needUpdate(self): return True def onUpdate(self): if self.refreshScheduled: self.refreshScene() def preProjectSave(self, prj): if self.activeSceneNode: _MOCK.game.previewingScene = self.activeSceneNode.getNodePath() def onMoaiClean(self): self.tree.clear() def onTool(self, tool): name = tool.name if name == 'fold_all': self.tree.foldAllItems() elif name == 'unfold_all': self.tree.expandAllItems() elif name == 'refresh_tree': self.tree.rebuild() elif name == 'refresh': self.scheduleRefreshScene() elif name == 'make_proto': self.makeProto() elif name == 'create_proto_instance': requestSearchView(info='select a proto to instantiate', context='asset', type='proto', on_selection=lambda obj: self.doCommand( 'scene_editor/create_proto_instance', proto=obj.getNodePath())) elif name == 'create_proto_container': requestSearchView( info='select a proto to create contained instance', context='asset', type='proto', on_selection=lambda obj: self.doCommand( 'scene_editor/create_proto_container', proto=obj.getNodePath())) elif name == 'create_group': self.doCommand('scene_editor/entity_group_create') elif name == 'group_entity': self.doCommand('scene_editor/group_entities') elif name == 'select_scene': self.doCommand('scene_editor/select_scene') def onMenu(self, menu): name = menu.name if name == 'close_scene': if self.previewing: alertMessage('Warning', 'Stop previewing before closing scene') return self.closeScene() elif name == 'open_scene': if self.previewing: alertMessage('Warning', 'Stop previewing before opening scene') return requestSearchView(info='select scene to open', context='asset', type='scene', on_selection=self.openScene) elif name == 'save_scene': if self.previewing: alertMessage('Warning', 'Stop previewing before saving') return self.saveScene() elif name == 'locate_scene_asset': if self.activeSceneNode: assetBrowser = self.getModule('asset_browser') if assetBrowser: assetBrowser.selectAsset(self.activeSceneNode) elif name == 'add_entity': requestSearchView(info='select entity type to create', context='entity_creation', on_selection=lambda obj: self.doCommand( 'scene_editor/create_entity', name=obj)) elif name == 'add_component': requestSearchView(info='select component type to create', context='component_creation', on_selection=lambda obj: self.doCommand( 'scene_editor/create_component', name=obj)) elif name == 'add_empty_entity': self.doCommand('scene_editor/create_entity', name='Entity') elif name == 'load_prefab': requestSearchView(info='select a perfab node to instantiate', context='asset', type='prefab', on_selection=lambda obj: self.doCommand( 'scene_editor/create_prefab_entity', prefab=obj.getNodePath())) elif name == 'load_prefab_in_container': requestSearchView( info='select a perfab node to instantiate( PefabContainer )', context='asset', type='prefab', on_selection=lambda obj: self.doCommand( 'scene_editor/create_prefab_container', prefab=obj.getNodePath())) elif name == 'remove_entity': self.doCommand('scene_editor/remove_entity') elif name == 'clone_entity': self.doCommand('scene_editor/clone_entity') elif name == 'find_entity': requestSearchView( info='search for entity in current scene', context='scene', type='entity', on_selection=lambda x: self.selectEntity(x, focus_tree=True), on_test=self.selectEntity) elif name == 'find_entity_in_group': requestSearchView( info='search for entity in current entity group', context='scene', type='entity_in_group', on_selection=lambda x: self.selectEntity(x, focus_tree=True), on_test=self.selectEntity) elif name == 'find_entity_group': requestSearchView( info='search for group in current scene', context='scene', type='group', on_selection=lambda x: self.selectEntity(x, focus_tree=True), on_test=self.selectEntity) elif name == 'create_group': self.doCommand('scene_editor/entity_group_create') elif name == 'remove_component': context = menu.getContext() if context: self.doCommand('scene_editor/remove_component', target=context) elif name == 'copy_component': context = menu.getContext() if context: self.doCommand('scene_editor/copy_component', target=context) elif name == 'edit_component_alias': context = menu.getContext() if context: oldAlias = context._alias or '' alias = requestString('Edit Alias', 'Enter Alias:', oldAlias) if alias != None: if not alias: alias = False self.doCommand('scene_editor/rename_component', target=context, alias=alias) elif name == 'assign_layer': if not self.tree.getSelection(): return requestSearchView(info='select layer to assign', context='scene_layer', type=_MOCK.Entity, on_selection=self.assignEntityLayer) elif name == 'toggle_visibility': self.doCommand('scene_editor/toggle_entity_visibility') elif name == 'freeze_entity_pivot': self.doCommand('scene_editor/freeze_entity_pivot') def onSelectionChanged(self, selection, key): if key != 'scene': return if self.tree.syncSelection: self.tree.blockSignals(True) self.tree.selectNode(None) for e in selection: self.tree.selectNode(e, add=True) self.tree.blockSignals(False) def selectEntity(self, target, **option): if option.get('focus_tree', False): self.tree.setFocus() self.changeSelection(target) ##----------------------------------------------------------------## def renameEntity(self, target, name): #TODO:command pattern target.setName(target, name) signals.emit('entity.modified', target) def addEntityNode(self, entity): self.tree.addNode(entity, expanded=False) self.tree.setNodeExpanded(entity, False) def removeEntityNode(self, entity): self.tree.removeNode(entity) def assignEntityLayer(self, layerName): #TODO:command pattern if not layerName: return self.doCommand('scene_editor/assign_layer', target=layerName) def onSelectionHint(self, selection): if selection._entity: self.changeSelection(selection._entity) else: self.changeSelection(selection) def onPreviewStart(self): if not self.activeSceneNode: return self.retainWorkspaceState() self.delegate.safeCallMethod('editor', 'retainScene') self.delegate.safeCallMethod('editor', 'startScenePreview') self.previewing = True def onPreviewStop(self): if not self.activeSceneNode: return self.changeSelection(None) self.tree.clear() self.delegate.safeCallMethod('editor', 'stopScenePreview') self.previewing = False if self.delegate.safeCallMethod('editor', 'restoreScene'): self.restoreWorkspaceState() def onAnimatorStart(self): self.retainWorkspaceState() self.delegate.safeCallMethod('editor', 'retainScene') def onAnimatorStop(self): self.tree.clear() self.delegate.safeCallMethod('editor', 'clearScene') if self.delegate.safeCallMethod('editor', 'restoreScene'): self.restoreWorkspaceState() ##----------------------------------------------------------------## def updateEntityPriority(self): if not self.activeSceneNode: return self.markSceneDirty() def onEntityRenamed(self, entity, newname): self.tree.refreshNodeContent(entity) self.markSceneDirty() def onEntityVisibleChanged(self, entity): self.tree.refreshNodeContent(entity) def onEntityPickableChanged(self, entity): self.tree.refreshNodeContent(entity) def onEntityAdded(self, entity, context=None): if context == 'new': self.setFocus() pnode = entity.parent if pnode: self.tree.setNodeExpanded(pnode, True) self.tree.setFocus() self.tree.editNode(entity) self.tree.selectNode(entity) signals.emit('scene.update') self.markSceneDirty() def onEntityRemoved(self, entity): signals.emit('scene.update') self.markSceneDirty() def onEntityModified(self, entity, context=None): self.markSceneDirty() ##----------------------------------------------------------------## def onComponentAdded(self, com, entity): signals.emit('scene.update') self.markSceneDirty() def onComponentRemoved(self, com, entity): signals.emit('scene.update') self.markSceneDirty() ##----------------------------------------------------------------## def onPrefabUnlink(self, entity): self.tree.refreshNodeContent(entity, updateChildren=True) def onPrefabRelink(self, entity): self.tree.refreshNodeContent(entity, updateChildren=True) def createPrefab(self, targetPrefab): selection = self.getSelection() if not selection: return if len(selection) > 1: return alertMessage( 'multiple entities cannot be converted into prefab') target = selection[0] self.doCommand('scene_editor/create_prefab', entity=target, prefab=targetPrefab.getNodePath(), file=targetPrefab.getAbsFilePath()) def makeProto(self): selection = self.getSelection() if not selection: return if len(selection) > 1: return alertMessage( 'multiple entities cannot be converted into Proto') target = selection[0] if not target: return if requestConfirm('convert proto', 'Convert this Entity into Proto?'): self.doCommand('scene_editor/make_proto', entity=target) self.tree.refreshNodeContent(target) def createProtoInstance(self): pass ##----------------------------------------------------------------## def onCopyEntity(self): entityGroupData = self.delegate.callMethod( 'editor', 'makeSceneSelectionCopyData') if not entityGroupData: return False clip = QtGui.QApplication.clipboard() mime = QtCore.QMimeData() text = '' for s in self.getSelection(): if text == '': text = text + s.name else: text = text + '\n' + s.name mime.setText(text) mime.setData(GII_MIME_ENTITY_DATA, entityGroupData.encode('utf-8')) clip.setMimeData(mime) return True def onPasteEntity(self): clip = QtGui.QApplication.clipboard() mime = clip.mimeData() if mime.hasFormat(GII_MIME_ENTITY_DATA): data = mime.data(GII_MIME_ENTITY_DATA) self.doCommand('scene_editor/paste_entity', data=str(data).decode('utf-8')) ##----------------------------------------------------------------## def onCopyComponent(self): entityGroupData = self.delegate.callMethod('editor', 'makeEntityCopyData') if not entityGroupData: return False clip = QtGui.QApplication.clipboard() mime = QtCore.QMimeData() text = '' for s in self.getSelection(): if text == '': text = text + s.name else: text = text + '\n' + s.name mime.setText(text) mime.setData(GII_MIME_ENTITY_DATA, str(entityGroupData)) clip.setMimeData(mime) return True def onPasteComponent(self): clip = QtGui.QApplication.clipboard() mime = clip.mimeData() if mime.hasFormat(GII_MIME_ENTITY_DATA): data = mime.data(GII_MIME_ENTITY_DATA) self.doCommand('scene_editor/paste_entity', data=str(data))
class DeployManager(SceneEditorModule): def __init__(self): super(DeployManager, self).__init__() def getName(self): return 'deploy_manager' def getDependency(self): return ['mock'] def onLoad(self): self.configPath = self.getProject().getConfigPath(_DEPLOY_CONFIG_FILE) #UI self.container = self.requestDocumentWindow('DeployManager', title='Deployment Manager', allowDock=False, minSize=(300, 300), maxSize=(300, 300)) #Components self.window = self.container.addWidgetFromFile( _getModulePath('DeployManager.ui')) self.delegate = MOAILuaDelegate(self) self.delegate.load(_getModulePath('DeployManager.lua')) #scene tree layout = QtGui.QVBoxLayout() self.window.containerSceneTree.setLayout(layout) layout.setSpacing(0) layout.setMargin(0) self.treeScene = DeploySceneTree(self.window.containerSceneTree, editable=True, sorting=False, multiple_selection=False) self.treeScene.manager = self layout.addWidget(self.treeScene) sceneToolbar = QtGui.QToolBar(self.window.containerSceneTree) layout.addWidget(sceneToolbar) self.sceneTool = self.addToolBar('deploy_scene', sceneToolbar) self.addTool('deploy_scene/add_scene', label='add', icon='add') self.addTool('deploy_scene/remove_scene', label='remove', icon='remove') self.addTool('deploy_scene/move_up_scene', label='up', icon='arrow-up') self.addTool('deploy_scene/move_down_scene', label='down', icon='arrow-down') self.addTool('deploy_scene/----') self.addTool('deploy_scene/edit_scene', label='change target scene', icon='pencil') self.addTool('deploy_scene/----') self.addTool('deploy_scene/set_entry_scene', label='set as entry', icon='flag') #deploy target tree layout = QtGui.QVBoxLayout() self.window.containerTargetTree.setLayout(layout) layout.setSpacing(0) layout.setMargin(0) self.treeTarget = DeployTargetTree(self.window.containerTargetTree, editable=True, multiple_selection=False) self.treeTarget.manager = self layout.addWidget(self.treeTarget) targetToolbar = QtGui.QToolBar(self.window.containerTargetTree) layout.addWidget(targetToolbar) self.targetTool = self.addToolBar('deploy_target', targetToolbar) self.addTool('deploy_target/add_target', label='+') self.addTool('deploy_target/remove_target', label='-') #target property self.propertyTarget = addWidgetWithLayout( PropertyEditor(self.window.containerTargetProp)) #menu self.addMenuItem('main/file/----') self.addMenuItem('main/file/deploy_manager', dict(label='Deploy Manager', shortcut='F11')) self.addMenuItem('main/file/deploy_build', dict(label='Deploy Build', shortcut='Ctrl+F11')) # self.container.show() self.window.buttonOK.clicked.connect(self.onButtonOK) #other registerSearchEnumerator(deployTargetSearchEnumerator) signals.connect('project.pre_deploy', self.preDeploy) signals.connect('project.deploy', self.onDeploy) signals.connect('project.post_deploy', self.postDeploy) def onStart(self): #load config self.loadConfig() #fill trees self.treeTarget.rebuild() self.treeScene.rebuild() def onStop(self): self.saveConfig() def loadConfig(self): self.delegate.safeCall('loadDeployManagerConfig', self.configPath) def saveConfig(self): self.delegate.safeCall('saveDeployManagerConfig', self.configPath) def getDeployTargetTypes(self): registry = self.delegate.safeCall('getDeployTargetTypeRegistry') return [name for name in registry.keys()] def getDeployTargets(self): targets = self.delegate.safeCallMethod('config', 'getTargets') return [obj for obj in targets.values()] def addDeployTarget(self, targetType): target = self.delegate.safeCallMethod('config', 'addDeployTarget', targetType) self.treeTarget.addNode(target) self.treeTarget.editNode(target) def changeDeployScene(self, targetScene): for sceneEntry in self.treeScene.getSelection(): self.delegate.safeCallMethod('config', 'changeTargetScene', sceneEntry, targetScene.getPath()) self.treeScene.refreshNode(sceneEntry) return def renameDeployTarget(self, target, name): target.name = name #avoid duplicated name def addDeployScene(self, sceneNode): if not sceneNode: return entry = self.delegate.safeCallMethod('config', 'addDeployScene', sceneNode.getNodePath()) self.treeScene.addNode(entry) self.treeScene.editNode(entry) def renameDeployScene(self, entry, alias): entry.alias = alias #TODO: avoid duplicated name def getDeployScenes(self): scenes = self.delegate.safeCallMethod('config', 'getScenes') return [obj for obj in scenes.values()] def updateGameConfig(self): self.delegate.safeCallMethod('config', 'updateGameConfig') def preDeploy(self, context): self.updateGameConfig() def onDeploy(self, context): pass def postDeploy(self, context): pass def onTool(self, tool): name = tool.name if name == 'add_target': requestSearchView(info='select deploy target type', context='deploy_target_type', on_selection=self.addDeployTarget) elif name == 'remove_target': for target in self.treeTarget.getSelection(): self.treeTarget.removeNode(target) self.delegate.safeCallMethod('config', 'removeDeployTarget', target) elif name == 'add_scene': requestSearchView(info='select scene to deploy', context='asset', type='scene', on_selection=self.addDeployScene) elif name == 'edit_scene': requestSearchView(info='select new target scene ', context='asset', type='scene', on_selection=self.changeDeployScene) elif name == 'remove_scene': for entry in self.treeScene.getSelection(): self.delegate.safeCallMethod('config', 'removeDeployScene', entry) self.treeScene.removeNode(entry) self.treeScene.refreshAllContent() elif name == 'set_entry_scene': for entry in self.treeScene.getSelection(): self.delegate.safeCallMethod('config', 'setEntryScene', entry) break self.treeScene.refreshAllContent() elif name == 'move_up_scene': for target in self.treeScene.getSelection(): self.delegate.safeCallMethod('config', 'moveSceneUp', target) self.treeScene.rebuild() self.treeScene.selectNode(target) break elif name == 'move_down_scene': for target in self.treeScene.getSelection(): self.delegate.safeCallMethod('config', 'moveSceneDown', target) self.treeScene.rebuild() self.treeScene.selectNode(target) break def onMenu(self, node): name = node.name if name == 'deploy_manager': self.onSetFocus() elif name == 'deploy_build': app.getProject().deploy() def onSetFocus(self): self.container.show() self.container.raise_() def onButtonOK(self): self.saveConfig() self.container.hide()
class DeployManager( SceneEditorModule ): def __init__(self): super( DeployManager, self ).__init__() def getName( self ): return 'deploy_manager' def getDependency( self ): return [ 'mock' ] def onLoad( self ): self.configPath = self.getProject().getConfigPath( _DEPLOY_CONFIG_FILE ) #UI self.container = self.requestDocumentWindow( 'DeployManager', title = 'Deployment Manager', allowDock = False, minSize = ( 300, 300 ), maxSize = ( 300, 300 ) ) #Components self.window = self.container.addWidgetFromFile( _getModulePath('DeployManager.ui') ) self.delegate = MOAILuaDelegate( self ) self.delegate.load( _getModulePath( 'DeployManager.lua' ) ) #scene tree layout = QtGui.QVBoxLayout() self.window.containerSceneTree.setLayout( layout ) layout.setSpacing( 0 ) layout.setMargin( 0 ) self.treeScene = DeploySceneTree( self.window.containerSceneTree, editable = True, sorting = False, multiple_selection = False ) self.treeScene.manager = self layout.addWidget( self.treeScene ) sceneToolbar = QtGui.QToolBar( self.window.containerSceneTree ) layout.addWidget( sceneToolbar ) self.sceneTool = self.addToolBar( 'deploy_scene', sceneToolbar ) self.addTool( 'deploy_scene/add_scene', label = 'add' ,icon = 'add' ) self.addTool( 'deploy_scene/remove_scene', label = 'remove' ,icon = 'remove' ) self.addTool( 'deploy_scene/move_up_scene', label = 'up' ,icon = 'arrow-up' ) self.addTool( 'deploy_scene/move_down_scene', label = 'down' ,icon = 'arrow-down' ) self.addTool( 'deploy_scene/----' ) self.addTool( 'deploy_scene/edit_scene', label = 'change target scene' ,icon = 'pencil' ) self.addTool( 'deploy_scene/----' ) self.addTool( 'deploy_scene/set_entry_scene', label = 'set as entry' ,icon = 'flag' ) #deploy target tree layout = QtGui.QVBoxLayout() self.window.containerTargetTree.setLayout( layout ) layout.setSpacing( 0 ) layout.setMargin( 0 ) self.treeTarget = DeployTargetTree( self.window.containerTargetTree, editable = True, multiple_selection = False ) self.treeTarget.manager = self layout.addWidget( self.treeTarget ) targetToolbar = QtGui.QToolBar( self.window.containerTargetTree ) layout.addWidget( targetToolbar ) self.targetTool = self.addToolBar( 'deploy_target', targetToolbar ) self.addTool( 'deploy_target/add_target', label = '+' ) self.addTool( 'deploy_target/remove_target', label = '-' ) #target property self.propertyTarget = addWidgetWithLayout( PropertyEditor( self.window.containerTargetProp ) ) #menu self.addMenuItem( 'main/file/----' ) self.addMenuItem( 'main/file/deploy_manager', dict( label = 'Deploy Manager', shortcut = 'F11' ) ) self.addMenuItem( 'main/file/deploy_build', dict( label = 'Deploy Build', shortcut = 'Ctrl+F11' ) ) # self.container.show() self.window.buttonOK.clicked.connect( self.onButtonOK ) #other registerSearchEnumerator( deployTargetSearchEnumerator ) signals.connect( 'project.pre_deploy', self.preDeploy ) signals.connect( 'project.deploy', self.onDeploy ) signals.connect( 'project.post_deploy', self.postDeploy ) def onStart( self ): #load config self.loadConfig() #fill trees self.treeTarget.rebuild() self.treeScene.rebuild() def onStop( self ): self.saveConfig() def loadConfig( self ): self.delegate.safeCall( 'loadDeployManagerConfig', self.configPath ) def saveConfig( self ): self.delegate.safeCall( 'saveDeployManagerConfig', self.configPath ) def getDeployTargetTypes( self ): registry = self.delegate.safeCall( 'getDeployTargetTypeRegistry' ) return [ name for name in registry.keys() ] def getDeployTargets( self ): targets = self.delegate.safeCallMethod( 'config', 'getTargets' ) return [ obj for obj in targets.values() ] def addDeployTarget( self, targetType ): target = self.delegate.safeCallMethod( 'config', 'addDeployTarget', targetType ) self.treeTarget.addNode( target ) self.treeTarget.editNode( target ) def changeDeployScene( self, targetScene ): for sceneEntry in self.treeScene.getSelection(): self.delegate.safeCallMethod( 'config', 'changeTargetScene', sceneEntry, targetScene.getPath() ) self.treeScene.refreshNode( sceneEntry ) return def renameDeployTarget( self, target, name ): target.name = name #avoid duplicated name def addDeployScene( self, sceneNode ): if not sceneNode: return entry = self.delegate.safeCallMethod( 'config', 'addDeployScene', sceneNode.getNodePath() ) self.treeScene.addNode( entry ) self.treeScene.editNode( entry ) def renameDeployScene( self, entry, alias ): entry.alias = alias #TODO: avoid duplicated name def getDeployScenes( self ): scenes = self.delegate.safeCallMethod( 'config', 'getScenes' ) return [ obj for obj in scenes.values() ] def updateGameConfig( self ): self.delegate.safeCallMethod( 'config', 'updateGameConfig' ) def preDeploy( self, context ): self.updateGameConfig() def onDeploy( self, context ): pass def postDeploy( self, context ): pass def onTool( self, tool ): name = tool.name if name == 'add_target': requestSearchView( info = 'select deploy target type', context = 'deploy_target_type', on_selection = self.addDeployTarget ) elif name == 'remove_target': for target in self.treeTarget.getSelection(): self.treeTarget.removeNode( target ) self.delegate.safeCallMethod( 'config', 'removeDeployTarget', target ) elif name == 'add_scene': requestSearchView( info = 'select scene to deploy', context = 'asset', type = 'scene', on_selection = self.addDeployScene ) elif name == 'edit_scene': requestSearchView( info = 'select new target scene ', context = 'asset', type = 'scene', on_selection = self.changeDeployScene ) elif name == 'remove_scene': for entry in self.treeScene.getSelection(): self.delegate.safeCallMethod( 'config', 'removeDeployScene', entry ) self.treeScene.removeNode( entry ) self.treeScene.refreshAllContent() elif name == 'set_entry_scene': for entry in self.treeScene.getSelection(): self.delegate.safeCallMethod( 'config', 'setEntryScene', entry ) break self.treeScene.refreshAllContent() elif name == 'move_up_scene': for target in self.treeScene.getSelection(): self.delegate.safeCallMethod( 'config', 'moveSceneUp', target ) self.treeScene.rebuild() self.treeScene.selectNode( target ) break elif name == 'move_down_scene': for target in self.treeScene.getSelection(): self.delegate.safeCallMethod( 'config', 'moveSceneDown', target ) self.treeScene.rebuild() self.treeScene.selectNode( target ) break def onMenu( self, node ): name = node.name if name == 'deploy_manager' : self.onSetFocus() elif name == 'deploy_build': app.getProject().deploy() def onSetFocus( self ): self.container.show() self.container.raise_() def onButtonOK( self ): self.saveConfig() self.container.hide()
class SceneGraphEditor( SceneEditorModule ): def __init__(self): super( SceneGraphEditor, self ).__init__() self.sceneDirty = False self.activeSceneNode = None self.refreshScheduled = False self.previewing = False self.workspaceState = None def getName( self ): return 'scenegraph_editor' def getDependency( self ): return [ 'scene_editor', 'mock' ] def onLoad( self ): #UI self.windowTitle = 'Scenegraph' self.container = self.requestDockWindow( 'SceneGraphEditor', title = 'Scenegraph', size = (200,200), minSize = (200,200), dock = 'left' ) #Components self.treeFilter = self.container.addWidget( GenericTreeFilter( self.container ), expanding = False ) self.tree = self.container.addWidget( SceneGraphTreeWidget( self.container, sorting = True, editable = True, multiple_selection = True, drag_mode = 'internal' ) ) self.treeFilter.setTargetTree( self.tree ) self.tree.module = self self.tool = self.addToolBar( 'scene_graph', self.container.addToolBar() ) self.delegate = MOAILuaDelegate( self ) self.delegate.load( getModulePath( 'SceneGraphEditor.lua' ) ) self.entityCreatorMenu=self.addMenu( 'main/scene/entity_create', { 'label':'Create Entity' } ) self.componentCreatorMenu=self.addMenu( 'main/scene/component_create', { 'label':'Create Component' } ) #menu self.addMenuItem( 'main/file/open_scene', dict( label = 'Open Scene', shortcut = 'ctrl+shift+o' ) ) self.addMenuItem( 'main/file/close_scene', dict( label = 'Close Scene', shortcut = 'Ctrl+W' ) ) self.addMenuItem( 'main/scene/save_scene', dict( label = 'Save', shortcut = 'Ctrl+S' ) ) self.addMenuItem( 'main/scene/locate_scene_asset', dict( label = 'Locate Scene Asset' ) ) self.addMenu( 'main/scene/----' ) self.addMenu( 'component_context', dict( label = 'Selected Component' ) ) self.addMenuItem( 'component_context/remove_component', dict( label = 'Remove' ) ) self.addMenuItem( 'component_context/----' ) self.addMenuItem( 'component_context/copy_component', dict( label = 'Copy' ) ) self.addMenuItem( 'component_context/paste_component', dict( label = 'Paste Component Here' ) ) self.addMenuItem( 'component_context/----' ) self.addMenuItem( 'component_context/move_component_up', dict( label = 'Move Up' ) ) self.addMenuItem( 'component_context/move_component_down', dict( label = 'Move Down' ) ) self.addMenu( 'main/entity', dict( label = 'Entity' ) ) self.addMenuItem( 'main/entity/add_empty_entity', dict( label = 'Create Empty', shortcut = 'ctrl+alt+N' ) ) self.addMenuItem( 'main/entity/add_entity', dict( label = 'Create', shortcut = 'ctrl+shift+N' ) ) self.addMenuItem( 'main/entity/----' ) self.addMenuItem( 'main/entity/group_entity', dict( label = 'Group Entites', shortcut = 'ctrl+G' ) ) self.addMenuItem( 'main/entity/create_group', dict( label = 'Create Empty Group', shortcut = 'ctrl+shift+G' ) ) self.addMenuItem( 'main/entity/----' ) self.addMenuItem( 'main/entity/load_prefab', dict( label = 'Load Prefab', shortcut = 'ctrl+alt+shift+N' ) ) self.addMenuItem( 'main/entity/load_prefab_in_container', dict( label = 'Load Prefab In Container', shortcut = 'ctrl+shift+=' ) ) self.addMenuItem( 'main/entity/----' ) self.addMenuItem( 'main/entity/remove_entity', dict( label = 'Remove' ) ) self.addMenuItem( 'main/entity/clone_entity', dict( label = 'Clone', shortcut = 'ctrl+d' ) ) self.addMenuItem( 'main/entity/----' ) self.addMenuItem( 'main/entity/add_component', dict( label = 'Add Component', shortcut = 'ctrl+alt+=' ) ) self.addMenuItem( 'main/entity/assign_layer', dict( label = 'Assign Layer', shortcut = 'ctrl+alt+L' ) ) self.addMenuItem( 'main/entity/toggle_visibility', dict( label = 'Toggle Visibility', shortcut = 'ctrl+/' ) ) self.addMenuItem( 'main/entity/freeze_entity_pivot', dict( label = 'Freeze Pivot' ) ) self.addMenuItem( 'main/entity/----' ) self.addMenuItem( 'main/find/find_entity', dict( label = 'Find In Scene', shortcut = 'ctrl+f' ) ) self.addMenuItem( 'main/find/find_entity_in_group', dict( label = 'Find In Group', shortcut = 'ctrl+shift+f' ) ) self.addMenuItem( 'main/find/find_entity_group', dict( label = 'Find Group', shortcut = 'ctrl+alt+f' ) ) #Toolbars self.addTool( 'scene_graph/select_scene', label ='Select Scene', icon = 'settings' ) self.addTool( 'scene_graph/----' ) self.addTool( 'scene_graph/create_group', label ='+ Group', icon = 'add_folder' ) self.addTool( 'scene_graph/----' ) self.addTool( 'scene_graph/make_proto', label = 'Convert To Proto', icon = 'proto_make' ) self.addTool( 'scene_graph/create_proto_instance', label = 'Create Proto Instance', icon = 'proto_instantiate' ) self.addTool( 'scene_graph/create_proto_container', label = 'Create Proto Container', icon = 'proto_container' ) self.addTool( 'scene_graph/----' ) self.addTool( 'scene_graph/fold_all', label = 'F' ) self.addTool( 'scene_graph/unfold_all', label = 'U' ) self.addTool( 'scene_graph/refresh_tree', label = 'R' ) # self.addTool( 'scene_graph/load_prefab', label = '+ P' ) # self.addTool( 'scene_graph/save_prefab', label = '>>P' ) self.addTool( 'scene/refresh', label = 'refresh', icon='refresh' ) #SIGNALS signals.connect( 'moai.clean', self.onMoaiClean ) signals.connect( 'scene.clear', self.onSceneClear ) signals.connect( 'scene.change', self.onSceneChange ) signals.connect( 'selection.changed', self.onSelectionChanged ) signals.connect( 'selection.hint', self.onSelectionHint ) signals.connect( 'preview.start', self.onPreviewStart ) signals.connect( 'preview.stop' , self.onPreviewStop ) # signals.connect( 'animator.start', self.onAnimatorStart ) # signals.connect( 'animator.stop' , self.onAnimatorStop ) signals.connect( 'entity.added', self.onEntityAdded ) signals.connect( 'entity.removed', self.onEntityRemoved ) signals.connect( 'entity.renamed', self.onEntityRenamed ) signals.connect( 'entity.modified', self.onEntityModified ) signals.connect( 'entity.visible_changed', self.onEntityVisibleChanged ) signals.connect( 'entity.pickable_changed', self.onEntityPickableChanged ) signals.connect( 'prefab.unlink', self.onPrefabUnlink ) signals.connect( 'prefab.relink', self.onPrefabRelink ) signals.connect( 'proto.unlink', self.onPrefabUnlink ) signals.connect( 'proto.relink', self.onPrefabRelink ) signals.connect( 'app.ready', self.postAppReady ) signals.connect( 'component.added', self.onComponentAdded ) signals.connect( 'component.removed', self.onComponentRemoved ) signals.connect( 'project.presave', self.preProjectSave ) registerSearchEnumerator( sceneObjectSearchEnumerator ) registerSearchEnumerator( entityNameSearchEnumerator ) registerSearchEnumerator( componentNameSearchEnumerator ) registerSearchEnumerator( layerNameSearchEnumerator ) def onStart( self ): self.refreshCreatorMenu() def postAppReady( self ): self.openPreviousScene() def openPreviousScene( self ): previousScene = self.getConfig( 'previous_scene', None ) if previousScene: node = self.getAssetLibrary().getAssetNode( previousScene ) if node: node.edit() def onStop( self ): if self.activeSceneNode: self.setConfig( 'previous_scene', self.activeSceneNode.getNodePath() ) else: self.setConfig( 'previous_scene', False ) def onSetFocus( self ): self.container.show() self.container.raise_() self.container.setFocus() def getActiveScene( self ): return self.delegate.safeCallMethod( 'editor', 'getScene' ) def getActiveSceneRootGroup( self ): scene = self.delegate.safeCallMethod( 'editor', 'getScene' ) if scene: return scene.rootGroup else: return None def openScene( self, node, protoNode = None ): if self.activeSceneNode == node: if self.getModule('scene_view'): self.getModule('scene_view').setFocus() if protoNode: self.delegate.safeCallMethod( 'editor', 'locateProto', protoNode.getPath() ) if self.getModule('scene_view'): self.getModule('scene_view').focusSelection() else: if not self.closeScene(): return if self.getModule('scene_view'): self.getModule('scene_view').makeCanvasCurrent() self.activeSceneNode = node signals.emitNow( 'scene.pre_open', node ) scene = self.delegate.safeCallMethod( 'editor', 'openScene', node.getPath() ) if not scene: #todo: raise something alertMessage( 'error', '%s\n\nfailed to open scene, see console for detailed information.' % node.getPath() ) return False signals.emitNow( 'scene.open', self.activeSceneNode, scene ) self.setFocus() self.editingProtoNode = protoNode self.loadWorkspaceState( False ) self.delegate.safeCallMethod( 'editor', 'postOpenScene' ) def closeScene( self ): if not self.activeSceneNode: return True if self.sceneDirty: res = requestConfirm( 'scene modified!', 'save scene before close?' ) if res == True: #save self.saveScene() elif res == None: #cancel return elif res == False: #no save pass self.markSceneDirty( False ) self.tree.clear() self.getApp().clearCommandStack( 'scene_editor' ) self.getSelectionManager().removeSelection( self.getActiveScene() ) signals.emitNow( 'scene.close', self.activeSceneNode ) self.delegate.safeCallMethod( 'editor', 'closeScene' ) self.activeSceneNode = None return True def onSceneClear( self ): # self.tree.clear() pass def markSceneDirty( self, dirty = True ): if not self.previewing: self.sceneDirty = dirty def saveWorkspaceState( self ): self.retainWorkspaceState() treeFoldState = self.workspaceState['tree_state'] containerFoldState = self.workspaceState['container_state'] entityLockState = self.workspaceState['entity_lock_state'] self.activeSceneNode.setMetaData( 'tree_state', treeFoldState ) self.activeSceneNode.setMetaData( 'container_state', containerFoldState ) self.activeSceneNode.setMetaData( 'entity_lock_state', entityLockState ) def loadWorkspaceState( self, restoreState = True ): treeFoldState = self.activeSceneNode.getMetaData( 'tree_state', None ) containerFoldState = self.activeSceneNode.getMetaData( 'container_state', None ) entityLockState = self.activeSceneNode.getMetaData( 'entity_lock_state', None ) self.workspaceState = { 'tree_state' : treeFoldState, 'container_state' : containerFoldState, 'entity_lock_state' : entityLockState } if restoreState: self.restoreWorkspaceState() def retainWorkspaceState( self ): #tree node foldstate treeFoldState = self.tree.saveFoldState() #save introspector foldstate introspectorFoldState = self.delegate.safeCallMethod( 'editor', 'saveIntrospectorFoldState' ) entityLockState = self.delegate.safeCallMethod( 'editor', 'saveEntityLockState' ) self.workspaceState = { 'tree_state' : treeFoldState, 'container_state' : introspectorFoldState, 'entity_lock_state' : entityLockState } def restoreWorkspaceState( self ): if not self.workspaceState: return treeState = self.workspaceState.get( 'tree_state', None ) if treeState: self.tree.loadFoldState( treeState ) containerState = self.workspaceState.get( 'container_state', None ) if containerState: self.delegate.safeCallMethod( 'editor', 'loadIntrospectorFoldState', containerState ) lockState = self.workspaceState.get( 'entity_lock_state', None ) if lockState: self.delegate.safeCallMethod( 'editor', 'loadEntityLockState', lockState ) def onSceneChange( self ): self.tree.hide() self.tree.rebuild() self.restoreWorkspaceState() self.tree.refreshAllContent() self.tree.verticalScrollBar().setValue( 0 ) self.tree.show() if self.editingProtoNode: self.delegate.safeCallMethod( 'editor', 'locateProto', self.editingProtoNode.getPath() ) self.editingProtoNode = None if self.getModule('scene_view'): self.getModule('scene_view').focusSelection() def saveScene( self ): if not self.activeSceneNode: return self.markSceneDirty( False ) signals.emitNow( 'scene.save' ) self.delegate.safeCallMethod( 'editor', 'saveScene', self.activeSceneNode.getAbsFilePath() ) signals.emitNow( 'scene.saved' ) self.saveWorkspaceState() def refreshScene( self ): if not self.activeSceneNode: return if self.previewing: return self.refreshScheduled = False node = self.activeSceneNode self.retainWorkspaceState() if self.delegate.safeCallMethod( 'editor', 'refreshScene' ): self.restoreWorkspaceState() self.refreshCreatorMenu() def scheduleRefreshScene( self ): if not self.activeSceneNode: return self.refreshScheduled = True def refreshCreatorMenu( self ): def addEntityMenuItem( name ): if name == '----': self.entityCreatorMenu.addChild( '----' ) return self.entityCreatorMenu.addChild({ 'name' : 'create_entity_'+name, 'label' : name, 'command' : 'scene_editor/create_entity', 'command_args' : dict( name = name ) }) def addComponentMenuItem( name ): if name == '----': self.componentCreatorMenu.addChild( '----' ) return self.componentCreatorMenu.addChild({ 'name' : 'create_component_'+name, 'label' : name, 'command' : 'scene_editor/create_component', 'command_args' : dict( name = name ) }) self.entityCreatorMenu.clear() self.componentCreatorMenu.clear() registry = _MOCK.getEntityRegistry() #entity keys = sorted( registry.keys() ) addEntityMenuItem( 'Entity' ) addEntityMenuItem( '----' ) for entityName in sorted( registry.keys() ): if entityName!='Entity': addEntityMenuItem( entityName ) #component registry = _MOCK.getComponentRegistry() for comName in sorted( registry.keys() ): addComponentMenuItem( comName ) def needUpdate( self ): return True def onUpdate( self ): if self.refreshScheduled: self.refreshScene() def preProjectSave( self, prj ): if self.activeSceneNode: _MOCK.game.previewingScene = self.activeSceneNode.getNodePath() def onMoaiClean( self ): self.tree.clear() def onTool( self, tool ): name = tool.name if name == 'fold_all': self.tree.foldAllItems() elif name == 'unfold_all': self.tree.expandAllItems() elif name == 'refresh_tree': self.tree.rebuild() elif name == 'refresh': self.scheduleRefreshScene() elif name == 'make_proto': self.makeProto() elif name == 'create_proto_instance': requestSearchView( info = 'select a proto to instantiate', context = 'asset', type = 'proto', on_selection = lambda obj: self.doCommand( 'scene_editor/create_proto_instance', proto = obj.getNodePath() ) ) elif name == 'create_proto_container': requestSearchView( info = 'select a proto to create contained instance', context = 'asset', type = 'proto', on_selection = lambda obj: self.doCommand( 'scene_editor/create_proto_container', proto = obj.getNodePath() ) ) elif name == 'create_group': self.doCommand( 'scene_editor/entity_group_create' ) elif name == 'group_entity': self.doCommand( 'scene_editor/group_entities' ) elif name == 'select_scene': self.doCommand( 'scene_editor/select_scene' ) def onMenu( self, menu ): name = menu.name if name == 'close_scene': if self.previewing: alertMessage( 'Warning', 'Stop previewing before closing scene' ) return self.closeScene() elif name == 'open_scene': if self.previewing: alertMessage( 'Warning', 'Stop previewing before opening scene' ) return requestSearchView( info = 'select scene to open', context = 'asset', type = 'scene', on_selection = self.openScene ) elif name == 'save_scene': if self.previewing: alertMessage( 'Warning', 'Stop previewing before saving' ) return self.saveScene() elif name == 'locate_scene_asset': if self.activeSceneNode: assetBrowser = self.getModule( 'asset_browser' ) if assetBrowser: assetBrowser.selectAsset( self.activeSceneNode ) elif name == 'add_entity': requestSearchView( info = 'select entity type to create', context = 'entity_creation', on_selection = lambda obj: self.doCommand( 'scene_editor/create_entity', name = obj ) ) elif name == 'add_component': requestSearchView( info = 'select component type to create', context = 'component_creation', on_selection = lambda obj: self.doCommand( 'scene_editor/create_component', name = obj ) ) elif name == 'add_empty_entity': self.doCommand( 'scene_editor/create_entity', name = 'Entity' ) elif name == 'load_prefab': requestSearchView( info = 'select a perfab node to instantiate', context = 'asset', type = 'prefab', on_selection = lambda obj: self.doCommand( 'scene_editor/create_prefab_entity', prefab = obj.getNodePath() ) ) elif name == 'load_prefab_in_container': requestSearchView( info = 'select a perfab node to instantiate( PefabContainer )', context = 'asset', type = 'prefab', on_selection = lambda obj: self.doCommand( 'scene_editor/create_prefab_container', prefab = obj.getNodePath() ) ) elif name == 'remove_entity': self.doCommand( 'scene_editor/remove_entity' ) elif name == 'clone_entity': self.doCommand( 'scene_editor/clone_entity' ) elif name == 'find_entity': requestSearchView( info = 'search for entity in current scene', context = 'scene', type = 'entity', on_selection = lambda x: self.selectEntity( x, focus_tree = True ) , on_test = self.selectEntity ) elif name == 'find_entity_in_group': requestSearchView( info = 'search for entity in current entity group', context = 'scene', type = 'entity_in_group', on_selection = lambda x: self.selectEntity( x, focus_tree = True ) , on_test = self.selectEntity ) elif name == 'find_entity_group': requestSearchView( info = 'search for group in current scene', context = 'scene', type = 'group', on_selection = lambda x: self.selectEntity( x, focus_tree = True ) , on_test = self.selectEntity ) elif name == 'create_group': self.doCommand( 'scene_editor/entity_group_create' ) elif name == 'remove_component': context = menu.getContext() if context: self.doCommand( 'scene_editor/remove_component', target = context ) elif name == 'copy_component': context = menu.getContext() if context: self.doCommand( 'scene_editor/copy_component', target = context ) elif name == 'assign_layer': if not self.tree.getSelection(): return requestSearchView( info = 'select layer to assign', context = 'scene_layer', type = _MOCK.Entity, on_selection = self.assignEntityLayer ) elif name == 'toggle_visibility': self.doCommand( 'scene_editor/toggle_entity_visibility' ) elif name == 'freeze_entity_pivot': self.doCommand( 'scene_editor/freeze_entity_pivot' ) def onSelectionChanged( self, selection, key ): if key != 'scene': return if self.tree.syncSelection: self.tree.blockSignals( True ) self.tree.selectNode( None ) for e in selection: self.tree.selectNode( e, add = True) self.tree.blockSignals( False ) def selectEntity( self, target, **option ): if option.get( 'focus_tree', False ): self.tree.setFocus() self.changeSelection( target ) ##----------------------------------------------------------------## def renameEntity( self, target, name ): #TODO:command pattern target.setName( target, name ) signals.emit( 'entity.modified', target ) def addEntityNode( self, entity ): self.tree.addNode( entity, expanded = False ) self.tree.setNodeExpanded( entity, False ) def removeEntityNode( self, entity ): self.tree.removeNode( entity ) def assignEntityLayer( self, layerName ): #TODO:command pattern if not layerName: return self.doCommand( 'scene_editor/assign_layer', target = layerName ) def onSelectionHint( self, selection ): if selection._entity: self.changeSelection( selection._entity ) else: self.changeSelection( selection ) def onPreviewStart( self ): if not self.activeSceneNode: return self.retainWorkspaceState() self.delegate.safeCallMethod( 'editor', 'retainScene' ) self.delegate.safeCallMethod( 'editor', 'startScenePreview' ) self.previewing = True def onPreviewStop( self ): if not self.activeSceneNode: return self.changeSelection( None ) self.tree.clear() self.delegate.safeCallMethod( 'editor', 'stopScenePreview' ) self.previewing = False if self.delegate.safeCallMethod( 'editor', 'restoreScene' ): self.restoreWorkspaceState() def onAnimatorStart( self ): self.retainWorkspaceState() self.delegate.safeCallMethod( 'editor', 'retainScene' ) def onAnimatorStop( self ): self.tree.clear() self.delegate.safeCallMethod( 'editor', 'clearScene' ) if self.delegate.safeCallMethod( 'editor', 'restoreScene' ): self.restoreWorkspaceState() ##----------------------------------------------------------------## def updateEntityPriority( self ): if not self.activeSceneNode: return self.markSceneDirty() def onEntityRenamed( self, entity, newname ): self.tree.refreshNodeContent( entity ) self.markSceneDirty() def onEntityVisibleChanged( self, entity ): self.tree.refreshNodeContent( entity ) def onEntityPickableChanged( self, entity ): self.tree.refreshNodeContent( entity ) def onEntityAdded( self, entity, context = None ): if context == 'new': self.setFocus() pnode = entity.parent if pnode: self.tree.setNodeExpanded( pnode, True ) self.tree.setFocus() self.tree.editNode( entity ) self.tree.selectNode( entity ) signals.emit( 'scene.update' ) self.markSceneDirty() def onEntityRemoved( self, entity ): signals.emit( 'scene.update' ) self.markSceneDirty() def onEntityModified( self, entity, context = None ): self.markSceneDirty() ##----------------------------------------------------------------## def onComponentAdded( self, com, entity ): signals.emit( 'scene.update' ) self.markSceneDirty() def onComponentRemoved( self, com, entity ): signals.emit( 'scene.update' ) self.markSceneDirty() ##----------------------------------------------------------------## def onPrefabUnlink( self, entity ): self.tree.refreshNodeContent( entity, updateChildren = True ) def onPrefabRelink( self, entity ): self.tree.refreshNodeContent( entity, updateChildren = True ) def createPrefab( self, targetPrefab ): selection = self.getSelection() if not selection: return if len( selection ) > 1: return alertMessage( 'multiple entities cannot be converted into prefab' ) target = selection[0] self.doCommand( 'scene_editor/create_prefab', entity = target, prefab = targetPrefab.getNodePath(), file = targetPrefab.getAbsFilePath() ) def makeProto( self ): selection = self.getSelection() if not selection: return if len( selection ) > 1: return alertMessage( 'multiple entities cannot be converted into Proto' ) target = selection[0] if not target: return if requestConfirm( 'convert proto', 'Convert this Entity into Proto?' ): self.doCommand( 'scene_editor/make_proto', entity = target ) self.tree.refreshNodeContent( target ) def createProtoInstance( self ): pass ##----------------------------------------------------------------## def onCopyEntity( self ): entityGroupData = self.delegate.callMethod( 'editor', 'makeSceneSelectionCopyData' ) if not entityGroupData: return False clip = QtGui.QApplication.clipboard() mime = QtCore.QMimeData() text = '' for s in self.getSelection(): if text == '': text = text + s.name else: text = text + '\n' + s.name mime.setText( text ) mime.setData( GII_MIME_ENTITY_DATA, entityGroupData.encode('utf-8') ) clip.setMimeData( mime ) return True def onPasteEntity( self ): clip = QtGui.QApplication.clipboard() mime = clip.mimeData() if mime.hasFormat( GII_MIME_ENTITY_DATA ): data = mime.data( GII_MIME_ENTITY_DATA ) self.doCommand( 'scene_editor/paste_entity', data = str(data).decode('utf-8') ) ##----------------------------------------------------------------## def onCopyComponent( self ): entityGroupData = self.delegate.callMethod( 'editor', 'makeEntityCopyData' ) if not entityGroupData: return False clip = QtGui.QApplication.clipboard() mime = QtCore.QMimeData() text = '' for s in self.getSelection(): if text == '': text = text + s.name else: text = text + '\n' + s.name mime.setText( text ) mime.setData( GII_MIME_ENTITY_DATA, str(entityGroupData) ) clip.setMimeData( mime ) return True def onPasteComponent( self ): clip = QtGui.QApplication.clipboard() mime = clip.mimeData() if mime.hasFormat( GII_MIME_ENTITY_DATA ): data = mime.data( GII_MIME_ENTITY_DATA ) self.doCommand( 'scene_editor/paste_entity', data = str(data) )