Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- from collections import namedtuple
- from functools import partial
- import logging
- import MaxPlus
- class MaxUi(object):
- """
- This class is for the generic UI class
- """
- def __init__(self):
- """
- Constructor for the Ui class
- :return:
- """
- # init logger
- logger = logging.getLogger(__name__)
- # define keywords used for core 3ds max main menu items
- self.keywords = ['Edit', 'Tools', 'Group', 'Views', 'Create', 'Modifiers', 'Animation',
- 'Graph Editors', 'Rendering', 'Customize', 'MAXScript', 'Help']
- # add identifier char
- self.keywords = ['&'+word for word in self.keywords]
- # set up menu hooks in 3ds max
- self.menuSetup()
- logger.info('3ds max UI hook setup successfully!')
- def createMenu(self, menuItemName, parentMenu=MaxPlus.MenuManager.GetMainMenu(),
- delayCreate=True, position=-1):
- """
- This method creates a new 3ds max Menu item. The parent Menu is the top-level menu by default.
- :rtype : Menu/NoneType, MenuBuilder
- :param menuItemName: string for menu menuItemName
- :param parentMenu: Menu that this new menu will be parented to.
- :param delayCreate: boolean determining if the MenuBuilder Create() method is called.
- :param position: int determining the position of the new Menu.
- The creation of the Menu can be delayed if this Menu is to have items added to it.
- """
- logger = logging.getLogger(__name__)
- Menus = namedtuple('Menus', 'menu mb')
- # check that menu item does not already exist
- if MaxPlus.MenuManager.MenuExists(menuItemName):
- # remove menu
- logger.debug('The menu: {0} already exists...'.format(menuItemName))
- self.deleteMenu(menuItemName)
- # create new instance of MenuBuilder
- mb = MaxPlus.MenuBuilder(menuItemName)
- logger.debug('MenuBuilder instance of: {0} has been created!'.format(menuItemName))
- menu = MaxPlus.MenuManager.FindMenu(menuItemName)
- # check if MenuBuilder creation is to be delayed for adding items
- if not delayCreate:
- # create the menu and add it to the 3ds max main menu bar
- # this returns the Menu created
- try:
- menu = mb.Create(parentMenu, position)
- except RuntimeError, e:
- logger.error('\n ### Could not run createMenu for Menu: '
- '{0}! \n {1} \n'.format(menuItemName, e))
- raise RuntimeError
- except ValueError, e:
- logger.error('\n ### Incorrect value passed to createMenu for Menu: '
- '{0}! \n {1} \n'.format(menuItemName, e))
- raise ValueError
- logger.debug('Menu: {0} created with: {1} as parent!'
- .format(menuItemName, parentMenu.GetTitle()))
- # create namedtuple to be returned, return both the Menu and MenuBuilder items so
- # that creation of menus can be left to the addMenuItem instead
- menus = Menus(menu, mb)
- return menus
- def addMenuItem(self, name, category, command, parentMenuBuilder, createMenu=None):
- """
- This method adds a new MenuItem to the specified MenuBuilder in 3ds max.
- :rtype : MenuBuilder object
- :param name: string
- :param category: string
- :param command: function
- :param parentMenuBuilder: MenuBuilder object
- :param createMenu: Menu object
- :return: MenuBuilder object
- Also optionally can create the final menu if this is the last item added to the MenuBuilder.
- createMenu param should only used in the last item to be added before creating the Menu
- """
- logger = logging.getLogger(__name__)
- # check that MenuBuilder object is valid
- assert isinstance(parentMenuBuilder, MaxPlus.MenuBuilder), \
- '### {0} is not a valid MenuBuilder object!'.format(parentMenuBuilder)
- # create 3ds max action item and validate it
- action = MaxPlus.ActionFactory.Create(category, name, command)
- if not action._IsValidWrapper():
- logger.debug('### Action {0} invalid!\n'.format(action.GetId()))
- return
- # check for existing menu item and remove it
- if MaxPlus.MenuManager.MenuExists(name):
- self.deleteMenu(name)
- # add the action as a menu item
- menuBuilder = parentMenuBuilder.AddItem(action)
- logger.debug('Successfully added the item: "{0}" with id: {1} !'.format(name, action.GetId()))
- # create menu
- if createMenu is not None:
- try:
- if type(createMenu) is not MaxPlus.Menu:
- logger.error('### Error occurred when trying to createMenu! '
- '{0} is not a valid Menu object! \n'.format(createMenu))
- parentMenuBuilder.Create(createMenu)
- logger.debug('Successfully created the Menu: {0} and '
- 'parented it to {1} !'.format(name, createMenu))
- except RuntimeError, e:
- logger.warning('\n### Unable to create the Menu: {0} to '
- 'be parented to: {1}!\n'.format(parentMenuBuilder, createMenu))
- logger.debug('\n{0}!\n'.format(e))
- return menuBuilder
- def deleteMenu(self, menuName):
- """
- This method unregisters the specified menuName item.
- :param menuName: string or Menu
- :return:
- WARNING: this method should be used with caution to prevent corrupting an existing 3ds max installation.
- Backup your MaxStartUI.mnu file before playing around with the behaviour of this method.
- """
- logger = logging.getLogger(__name__)
- # guard against removing core 3ds max menus
- if menuName in self.keywords:
- logger.warning('\n### Cannot unregister {0} ! This is a core 3ds max menu! \n'.format(menuName))
- else:
- # unregister the Menu
- MaxPlus.MenuManager.UnregisterMenu(unicode(menuName))
- logger.debug('Unregistered menu: {0} !'.format(menuName))
- def menuSetup( self ):
- """
- This method registers the generic menu items to the 3ds max menubar.
- :rtype : object
- :return:
- """
- logger = logging.getLogger(__name__)
- genericMainMenu = self.createMenu('generic', delayCreate=False)
- # build menus and action items
- # File Menu
- generic_fileMenu = self.createMenu('File', genericMainMenu.menu)
- generic_file_publish_axn = self.addMenuItem('Publish file to generic', 'File', partial(self.foo,'publish'),
- generic_fileMenu.mb)
- generic_file_getLatest_axn = self.addMenuItem('Get latest revision', 'File', partial(self.foo, 'get latest rev'),
- generic_fileMenu.mb)
- generic_file_viewAll_axn = self.addMenuItem('View all revisions', 'File', partial(self.foo, 'view all rev'),
- generic_fileMenu.mb, createMenu=genericMainMenu.menu)
- logger.debug('# Finished building File Menu! \n')
- # Server Menu
- generic_serverMenu = self.createMenu('Server', genericMainMenu.menu)
- generic_server_feedbackMenu = self.createMenu('Feedback', generic_serverMenu.menu)
- generic_server_getFeedback_axn = self.addMenuItem('Get latest feedback', 'Feedback', partial(self.foo, 'feedback'),
- generic_server_feedbackMenu.mb)
- generic_server_viewAllFeedback_axn = self.addMenuItem('View all feedback', 'Feedback', partial(self.foo, 'all feedback'),
- generic_server_feedbackMenu.mb, createMenu=generic_serverMenu.menu)
- generic_server_newTask_axn = self.addMenuItem('Create new Task', 'Server', partial(self.foo, 'create task'),
- generic_serverMenu.mb)
- generic_server_taskStatus_axn = self.addMenuItem('Check Task status', 'Server', partial(self.foo, 'check status'),
- generic_serverMenu.mb)
- generic_serverMenu.mb.AddSeparator()
- logger.debug('Menu items setup and added to 3ds max main menubar!')
- @staticmethod
- def foo( *args ):
- for arg in args:
- print arg
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement