git clone https://git.lucas.co/hou-control.git
python3.11libs/hc/hcstatusbar.py (5.4K)
1 import hou
2 from PySide6.QtCore import QEvent, QObject, Qt, QTimer
3 from PySide6.QtWidgets import QFrame, QHBoxLayout, QLabel, QPushButton, QWidget
4
5
6 HCSTATUSBAR_HEIGHT = 48
7 HCSTATUSBAR_WIDTH = 500
8 HCSTATUSBAR_MARGIN = 4
9 HCSTATUSBAR_RIGHT_MARGIN = 360
10 HCSTATUSBAR_STYLE = """
11 QFrame#hc_status_overlay {
12 background: #2a2a2a;
13 border: 1px solid #444;
14 }
15 QFrame#hc_status_overlay QLabel {
16 color: #ccc;
17 background: transparent;
18 padding: 0 6px;
19 }
20 QFrame#hc_status_overlay QPushButton {
21 color: #eee;
22 background: #3a3a3a;
23 border: 1px solid #555;
24 padding: 0 10px;
25 }
26 QFrame#hc_status_overlay QPushButton:hover {
27 background: #4a4a4a;
28 }
29 """
30
31
32 class _ResizeFilter(QObject):
33 def __init__(self, manager):
34 super().__init__(manager.overlay)
35 self.manager = manager
36
37 def eventFilter(self, obj, event):
38 if event.type() == QEvent.Resize:
39 self.manager._pin()
40 return False
41
42
43 class HCStatusBar:
44 OVERLAY_NAME = "hc_status_overlay"
45 TAB_TYPE_LABEL = "hc_status_tab_type"
46 AUTOSAVE_LABEL = "hc_status_autosave"
47
48 def __init__(self):
49 self.main = hou.qt.mainWindow()
50 self.overlay = self._findOverlay()
51
52 def _findOverlay(self):
53 return self.main.findChild(QFrame, self.OVERLAY_NAME)
54
55 def _ensureOverlay(self):
56 if self.overlay is not None and self.overlay.parent() is self.main:
57 return self.overlay
58 frame = QFrame(self.main)
59 frame.setObjectName(self.OVERLAY_NAME)
60 frame.setStyleSheet(HCSTATUSBAR_STYLE)
61 layout = QHBoxLayout(frame)
62 layout.setContentsMargins(2, 0, 2, 0)
63 layout.setSpacing(4)
64 layout.addStretch()
65 frame.setLayout(layout)
66 filt = _ResizeFilter(self)
67 self.main.installEventFilter(filt)
68 frame._hc_filter = filt # keep reference alive
69 self.overlay = frame
70 self._pin()
71 frame.show()
72 frame.raise_()
73 self._installLabels()
74 return frame
75
76 def _installLabels(self):
77 frame = self.overlay
78 layout = frame.layout()
79
80 tab_lbl = QLabel("—", frame)
81 tab_lbl.setObjectName(self.TAB_TYPE_LABEL)
82 layout.insertWidget(0, tab_lbl)
83
84 autosave_lbl = QLabel("—", frame)
85 autosave_lbl.setObjectName(self.AUTOSAVE_LABEL)
86 layout.insertWidget(1, autosave_lbl)
87
88 timer = QTimer(frame)
89 timer.timeout.connect(self._refreshTabType)
90 timer.start(250)
91 frame._hc_tab_type_timer = timer
92
93 self._refreshTabType()
94 self.updateAutosave()
95
96 def _refreshTabType(self):
97 if self.overlay is None:
98 return
99 lbl = self.overlay.findChild(QLabel, self.TAB_TYPE_LABEL)
100 if lbl is None:
101 return
102 from .hcsession import HCSession
103 tab = HCSession().currentTab()
104 if tab is None:
105 lbl.setText("—")
106 return
107 lbl.setText(tab.hou_tab.type().name())
108
109 def updateAutosave(self):
110 if self.overlay is None:
111 return
112 lbl = self.overlay.findChild(QLabel, self.AUTOSAVE_LABEL)
113 if lbl is None:
114 return
115 autosave = hou.getPreference("autoSave")
116 lbl.setText("Autosave: On" if autosave == "1" else "Autosave: Off")
117
118 def _pin(self):
119 if self.overlay is None:
120 return
121 x = self.main.width() - HCSTATUSBAR_WIDTH - HCSTATUSBAR_RIGHT_MARGIN
122 y = self.main.height() - HCSTATUSBAR_HEIGHT - HCSTATUSBAR_MARGIN
123 self.overlay.setGeometry(x, y, HCSTATUSBAR_WIDTH, HCSTATUSBAR_HEIGHT)
124 self.overlay.raise_()
125
126
127 """ Show / Hide """
128
129
130 def show(self):
131 self._ensureOverlay()
132
133 def hide(self):
134 if self.overlay is not None:
135 self.overlay.hide()
136
137 def isVisible(self):
138 return self.overlay is not None and self.overlay.isVisible()
139
140
141 """ Add """
142
143
144 def addButton(self, name, label, callback):
145 frame = self._ensureOverlay()
146 self.removeWidget(name)
147 btn = QPushButton(label, frame)
148 btn.setObjectName(name)
149 btn.clicked.connect(callback)
150 frame.layout().addWidget(btn)
151 frame.raise_()
152 return btn
153
154 def addLabel(self, name, text):
155 frame = self._ensureOverlay()
156 self.removeWidget(name)
157 lbl = QLabel(text, frame)
158 lbl.setObjectName(name)
159 frame.layout().addWidget(lbl)
160 frame.raise_()
161 return lbl
162
163 def addWidget(self, name, widget):
164 frame = self._ensureOverlay()
165 self.removeWidget(name)
166 widget.setObjectName(name)
167 widget.setParent(frame)
168 frame.layout().addWidget(widget)
169 frame.raise_()
170 return widget
171
172
173 """ Remove """
174
175
176 def removeWidget(self, name):
177 if self.overlay is None:
178 return
179 existing = self.overlay.findChild(QWidget, name)
180 if existing is not None:
181 self.overlay.layout().removeWidget(existing)
182 existing.setParent(None)
183 existing.deleteLater()
184
185 def clear(self):
186 if self.overlay is None:
187 return
188 self.overlay.setParent(None)
189 self.overlay.deleteLater()
190 self.overlay = None
191
192
193 """ Query """
194
195
196 def exists(self):
197 return self._findOverlay() is not None
198
199 def widget(self, name):
200 if self.overlay is None:
201 return None
202 return self.overlay.findChild(QWidget, name)