git.lucas.co / hou-control
SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git

python3.13libs/hc/hctab.py (5.9K)

  1 import hou
  2 import types
  3 from .hccommands import command
  4 
  5 class HCTab():
  6     def __init__(self, hou_tab):
  7         self.hou_tab = hou_tab
  8 
  9     def initialize(self):
 10         """Per-pane setup hook. Override in subclasses to apply pane-type
 11         defaults, register hooks, set viewport prefs, etc. Called by factory
 12         callers (e.g. HCLayout.launchFloating) after a pane tab is created."""
 13         return
 14 
 15     """ Status """
 16 
 17     @command("Close Tab")
 18     def close(self):
 19         self.hou_tab.close()
 20 
 21     @command("Close Other Tabs")
 22     def closeOtherTabs(self):
 23         for tab in self.pane().tabs():
 24             if tab.hou_tab != self.hou_tab:
 25                 tab.close()
 26 
 27     def name(self):
 28         return self.hou_tab.name()
 29 
 30     def pane(self):
 31         from .hcpane import HCPane
 32         return HCPane(self.hou_tab.pane())
 33 
 34     def setCurrent(self):
 35         self.hou_tab.setIsCurrentTab()
 36 
 37     """ Type """
 38 
 39     def type(self):
 40         return self.__class__.__name__
 41 
 42     def tab_type(self):
 43         return 'HCTab'
 44 
 45     def setTypeDetailsView(self):
 46         self.setType(hou.paneTabType.DetailsView)
 47 
 48     def setTypeNetworkEditor(self):
 49         self.setType(hou.paneTabType.NetworkEditor)
 50 
 51     def setTypeParm(self):
 52         self.setType(hou.paneTabType.Parm)
 53 
 54     def setTypePythonShell(self):
 55         self.setType(hou.paneTabType.PythonShell)
 56 
 57     def setTypeSceneViewer(self):
 58         self.setType(hou.paneTabType.SceneViewer)
 59 
 60     def paneTabTypes(self):
 61         type_specs = (
 62             ('Apex Editor', 'ApexEditor'),
 63             ('Asset Browser', 'AssetBrowser'),
 64             ('Bundle List', 'BundleList'),
 65             ('Channel Editor', 'ChannelEditor'),
 66             ('Channel List', 'ChannelList'),
 67             ('Channel Viewer', 'ChannelViewer'),
 68             ('Compositor Viewer', 'CompositorViewer'),
 69             ('Context Viewer', 'ContextViewer'),
 70             ('Data Tree', 'DataTree'),
 71             ('Details View', 'DetailsView'),
 72             ('Engine Session Sync', 'EngineSessionSync'),
 73             ('Handle List', 'HandleList'),
 74             ('Help Browser', 'HelpBrowser'),
 75             ('IPR Viewer', 'IPRViewer'),
 76             ('Light Linker', 'LightLinker'),
 77             ('Material Palette', 'MaterialPalette'),
 78             ('Network Editor', 'NetworkEditor'),
 79             ('Output Viewer', 'OutputViewer'),
 80             ('Parameter Editor', 'Parm'),
 81             ('Parameter Spreadsheet', 'ParmSpreadsheet'),
 82             ('Performance Monitor', 'PerformanceMonitor'),
 83             ('Python Panel', 'PythonPanel'),
 84             ('Python Shell', 'PythonShell'),
 85             ('Render Gallery', 'RenderGallery'),
 86             ('Scene Viewer', 'SceneViewer'),
 87             ('Shader Viewer', 'ShaderViewer'),
 88             ('Take List', 'TakeList'),
 89             ('Textport', 'Textport'),
 90             ('Tree View', 'TreeView'),
 91         )
 92 
 93         type_map = {}
 94         for label, attr in type_specs:
 95             tab_type = getattr(hou.paneTabType, attr, None)
 96             if tab_type is not None:
 97                 type_map[label] = tab_type
 98         return type_map
 99 
100     @command("Set Tab Type")
101     def changeTypeDialog(self):
102         from .hcwidgets import HCWidgets
103 
104         type_map = self.paneTabTypes()
105         list_dict = {name: (lambda t=tab_type: self.setType(t)) for name, tab_type in type_map.items()}
106         anchor_geometry = self.pane().qtScreenGeometry()
107         dialog = HCWidgets.SelectionDialog('Set Tab Type', list_dict, anchor_geometry=anchor_geometry)
108         dialog.show()
109         dialog.raise_()
110         dialog.activateWindow()
111 
112     def setType(self, tab_type):
113         if isinstance(tab_type, str):
114             tab_type_map = self.paneTabTypes()
115             compact_map = {label.replace(' ', ''): value for label, value in tab_type_map.items()}
116             compact_map['Parm'] = tab_type_map.get('Parameter Editor')
117             compact_map['DetailsView'] = tab_type_map.get('Details View')
118             tab_type = tab_type_map.get(tab_type) or compact_map.get(tab_type)
119         if tab_type is None:
120             hou.ui.setStatusMessage('Unknown pane tab type', hou.severityType.Error)
121             return None
122 
123         new_tab = self.hou_tab.setType(tab_type)
124         if new_tab is None:
125             new_tab = self.hou_tab.pane().currentTab()
126 
127         from .hcpane import HCPane
128         initialized = HCPane(new_tab.pane()).initializeObject(new_tab)
129         hou.ui.setStatusMessage('Changed tab type', hou.severityType.Message)
130         return initialized
131 
132 
133     """ Chrome """
134 
135     # "Chrome" is whatever bars and controls a tab draws around its content.
136     # HCSession.toggleMenus and isVisibleMenus used to switch on tab.type()
137     # and call a different set of methods in each branch; each tab class now
138     # answers for itself and those two methods just iterate.
139     #
140     # The path bar ("network controls" to HOM) is the one piece of chrome
141     # every kind of tab may have -- network editors, viewers and parameter
142     # editors do, and so do the channel editor and the parameter spreadsheet,
143     # which wrap as plain HCTab -- while shells and browsers have none. So the
144     # Path toggle lives here and asks the tab, rather than living on a
145     # subclass or naming tab types.
146 
147     def hasNetworkControls(self):
148         return self.hou_tab.hasNetworkControls()
149 
150     def isShowingNetworkControls(self):
151         return self.hou_tab.isShowingNetworkControls()
152 
153     def showNetworkControls(self, value):
154         self.hou_tab.showNetworkControls(value)
155 
156     def isShowingPath(self):
157         return bool(self.hasNetworkControls() and self.isShowingNetworkControls())
158 
159     @command("Path", state="isShowingPath", available="hasNetworkControls")
160     def toggleNetworkControls(self):
161         if self.hasNetworkControls():
162             self.showNetworkControls(not self.isShowingNetworkControls())
163 
164     def isChromeVisible(self):
165         return bool(self.hasNetworkControls() and self.isShowingNetworkControls())
166 
167     def showChrome(self, visible):
168         if self.hasNetworkControls():
169             self.showNetworkControls(visible)