From 29cdca3f38985b8103f7c1e6453e7541e06eb579 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 08:10:48 -0600 Subject: [PATCH 1/8] Change docks to tabs --- openmc_plotter/docks.py | 175 ++++++++++++++++++---------------- openmc_plotter/main_window.py | 113 +++++++--------------- 2 files changed, 129 insertions(+), 159 deletions(-) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index 5470e0c..dec559f 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -7,7 +7,8 @@ QGroupBox, QFormLayout, QLabel, QLineEdit, QComboBox, QSpinBox, QDoubleSpinBox, QSizePolicy, QCheckBox, QDockWidget, QScrollArea, QListWidget, - QListWidgetItem, QTreeWidget, QTreeWidgetItem) + QListWidgetItem, QTreeWidget, QTreeWidgetItem, + QTabWidget) import matplotlib.pyplot as plt import numpy as np import openmc @@ -18,26 +19,26 @@ _REACTION_UNITS, _SPATIAL_FILTERS) -class PlotterDock(QDockWidget): +class PlotterPanel(QWidget): """ - Dock widget with common settings for the plotting application + Base panel widget with common settings for the plotting application """ - def __init__(self, model, font_metric, parent=None): + def __init__(self, model, font_metric, main_window, parent=None): super().__init__(parent) self.model = model self.font_metric = font_metric - self.main_window = parent + self.main_window = main_window self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) -class MeshAnnotationDock(PlotterDock): - """Dock for mesh annotation options""" +class MeshAnnotationPanel(PlotterPanel): + """Panel for mesh annotation options""" - def __init__(self, model, font_metric, parent=None): - super().__init__(model, font_metric, parent) + def __init__(self, model, font_metric, main_window, parent=None): + super().__init__(model, font_metric, main_window, parent) self.treeLayout = QVBoxLayout() self.meshTree = QTreeWidget() @@ -56,21 +57,9 @@ def __init__(self, model, font_metric, parent=None): self.meshTree.setHeaderHidden(True) - # Create submit button - self.applyButton = QPushButton("Apply Changes") - # Mac bug fix - self.applyButton.setMinimumHeight(self.font_metric.height() * 1.6) - self.applyButton.clicked.connect(self.main_window.applyChanges) - - label = QLabel("Mesh Annotations") - self.treeLayout.addWidget(label) self.treeLayout.addWidget(self.meshTree) - self.treeLayout.addWidget(HorizontalLine()) - self.treeLayout.addWidget(self.applyButton) - self.optionsWidget = QWidget() - self.optionsWidget.setLayout(self.treeLayout) - self.setWidget(self.optionsWidget) + self.setLayout(self.treeLayout) def get_checked_meshes(self): return [id for id, item in self.mesh_items if item.checkState(0) == QtCore.Qt.Checked] @@ -78,33 +67,78 @@ def get_checked_meshes(self): def update(self): pass + +class TabbedDock(QDockWidget): + """ + Dock widget containing tabbed panels for Geometry, Tallies, and Mesh Annotations + """ + + def __init__(self, model, font_metric, parent=None): + super().__init__(parent) + + self.model = model + self.font_metric = font_metric + self.main_window = parent + + self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) + self.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea) + + # Create the tab widget + self.tabWidget = QTabWidget() + + # Create the three panels + self.geometryPanel = GeometryPanel(model, font_metric, parent, self) + self.tallyPanel = TallyPanel(model, font_metric, parent, self) + self.meshAnnotationPanel = MeshAnnotationPanel(model, font_metric, parent, self) + + # Add panels as tabs + self.tabWidget.addTab(self.geometryPanel, "Geometry") + self.tabWidget.addTab(self.tallyPanel, "Tallies") + self.tabWidget.addTab(self.meshAnnotationPanel, "Mesh Annotations") + + # Create Apply Changes button + self.applyButton = QPushButton("Apply Changes") + self.applyButton.setMinimumHeight(self.font_metric.height() * 1.6) + self.applyButton.clicked.connect(self.main_window.applyChanges) + + # Main layout with tabs and apply button + self.mainLayout = QVBoxLayout() + self.mainLayout.addWidget(self.tabWidget) + self.mainLayout.addWidget(HorizontalLine()) + self.mainLayout.addWidget(self.applyButton) + + # Create container widget + self.containerWidget = QWidget() + self.containerWidget.setLayout(self.mainLayout) + self.setWidget(self.containerWidget) + + def updateDock(self): + """Update geometry panel""" + self.geometryPanel.updateDock() + + def update(self): + """Update tally panel""" + self.tallyPanel.update() + def resizeEvent(self, event): self.main_window.resizeEvent(event) hideEvent = showEvent = moveEvent = resizeEvent -class DomainDock(PlotterDock): +class GeometryPanel(PlotterPanel): """ - Domain options dock + Geometry options panel """ - def __init__(self, model, font_metric, parent=None): - super().__init__(model, font_metric, parent) - - self.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea) + def __init__(self, model, font_metric, main_window, parent=None): + super().__init__(model, font_metric, main_window, parent) # Create Controls self._createOriginBox() self._createOptionsBox() self._createResolutionBox() - # Create submit button - self.applyButton = QPushButton("Apply Changes") - # Mac bug fix - self.applyButton.setMinimumHeight(self.font_metric.height() * 1.6) - self.applyButton.clicked.connect(self.main_window.applyChanges) - # Create Zoom box self.zoomBox = QSpinBox() self.zoomBox.setSuffix(' %') @@ -120,22 +154,15 @@ def __init__(self, model, font_metric, parent=None): self.zoomWidget.setLayout(self.zoomLayout) # Create Layout - self.dockLayout = QVBoxLayout() - self.dockLayout.addWidget(QLabel("Geometry/Properties")) - self.dockLayout.addWidget(HorizontalLine()) - self.dockLayout.addWidget(self.originGroupBox) - self.dockLayout.addWidget(self.optionsGroupBox) - self.dockLayout.addWidget(self.resGroupBox) - self.dockLayout.addWidget(HorizontalLine()) - self.dockLayout.addWidget(self.zoomWidget) - self.dockLayout.addWidget(HorizontalLine()) - self.dockLayout.addStretch() - self.dockLayout.addWidget(self.applyButton) - self.dockLayout.addWidget(HorizontalLine()) - - self.optionsWidget = QWidget() - self.optionsWidget.setLayout(self.dockLayout) - self.setWidget(self.optionsWidget) + self.panelLayout = QVBoxLayout() + self.panelLayout.addWidget(self.originGroupBox) + self.panelLayout.addWidget(self.optionsGroupBox) + self.panelLayout.addWidget(self.resGroupBox) + self.panelLayout.addWidget(HorizontalLine()) + self.panelLayout.addWidget(self.zoomWidget) + self.panelLayout.addStretch() + + self.setLayout(self.panelLayout) def _createOriginBox(self): @@ -362,20 +389,12 @@ def revertToCurrent(self): self.widthBox.setValue(cv.width) self.heightBox.setValue(cv.height) - def resizeEvent(self, event): - self.main_window.resizeEvent(event) - - hideEvent = showEvent = moveEvent = resizeEvent - - -class TallyDock(PlotterDock): - - def __init__(self, model, font_metric, parent=None): - super().__init__(model, font_metric, parent) +class TallyPanel(PlotterPanel): - self.setAllowedAreas(QtCore.Qt.RightDockWidgetArea) + def __init__(self, model, font_metric, main_window, parent=None): + super().__init__(model, font_metric, main_window, parent) - # Dock maps for tally information + # Panel maps for tally information self.tally_map = {} self.filter_map = {} self.score_map = {} @@ -395,11 +414,6 @@ def __init__(self, model, font_metric, parent=None): self.tallyGroupBox = QGroupBox('Selected Tally') self.tallyGroupBox.setLayout(self.tallySelectorLayout) - # Create submit button - self.applyButton = QPushButton("Apply Changes") - self.applyButton.setMinimumHeight(self.font_metric.height() * 1.6) - self.applyButton.clicked.connect(self.main_window.applyChanges) - # Color options section self.tallyColorForm = ColorForm(self.model, self.main_window, 'tally') self.scoresGroupBox = Expander(title="Scores:") @@ -408,23 +422,24 @@ def __init__(self, model, font_metric, parent=None): self.nuclidesListWidget = QListWidget() # Main layout - self.dockLayout = QVBoxLayout() - self.dockLayout.addWidget(QLabel("Tallies")) - self.dockLayout.addWidget(HorizontalLine()) - self.dockLayout.addWidget(self.tallyGroupBox) - self.dockLayout.addStretch() - self.dockLayout.addWidget(HorizontalLine()) - self.dockLayout.addWidget(self.tallyColorForm) - self.dockLayout.addWidget(HorizontalLine()) - self.dockLayout.addWidget(self.applyButton) - - # Create widget for dock and apply main layout + self.panelLayout = QVBoxLayout() + self.panelLayout.addWidget(self.tallyGroupBox) + self.panelLayout.addStretch() + self.panelLayout.addWidget(HorizontalLine()) + self.panelLayout.addWidget(self.tallyColorForm) + + # Create widget for scroll area and apply main layout self.scroll = QScrollArea() self.scroll.setWidgetResizable(True) self.widget = QWidget() - self.widget.setLayout(self.dockLayout) + self.widget.setLayout(self.panelLayout) self.scroll.setWidget(self.widget) - self.setWidget(self.scroll) + + # Set scroll area as main layout + mainLayout = QVBoxLayout() + mainLayout.setContentsMargins(0, 0, 0, 0) + mainLayout.addWidget(self.scroll) + self.setLayout(mainLayout) def _createFilterTree(self, spatial_filters): av = self.model.activeView diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index 34d045d..e777363 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -22,7 +22,7 @@ from .plotmodel import PlotModel, DomainTableModel, hash_model from .plotgui import PlotImage, ColorDialog -from .docks import DomainDock, TallyDock, MeshAnnotationDock +from .docks import TabbedDock from .overlays import ShortcutsOverlay from .tools import ExportDataDialog, SourceSitesDialog @@ -80,24 +80,17 @@ def loadGui(self, use_settings_pkl=True): self.plotIm.frozen = True self.frame.setWidget(self.plotIm) - # Dock - self.dock = DomainDock(self.model, self.font_metric, self) - self.dock.setObjectName("Domain Options Dock") + # Tabbed Dock (contains Geometry, Tallies, and Mesh Annotations) + self.dock = TabbedDock(self.model, self.font_metric, self) + self.dock.setObjectName("Options Dock") self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dock) - # Tally Dock - self.tallyDock = TallyDock(self.model, self.font_metric, self) - self.tallyDock.update() - self.tallyDock.setObjectName("Tally Options Dock") - self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tallyDock) + # Create shortcuts for accessing panels + self.geometryPanel = self.dock.geometryPanel + self.tallyPanel = self.dock.tallyPanel + self.meshAnnotationPanel = self.dock.meshAnnotationPanel - # Mesh Annotation Dock - self.meshAnnotationDock = MeshAnnotationDock(self.model, self.font_metric, self) - self.meshAnnotationDock.update() - self.meshAnnotationDock.setObjectName("Mesh Annotation Dock") - self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.meshAnnotationDock) - - # Color DialogtallyDock + # Color Dialog self.colorDialog = ColorDialog(self.model, self.font_metric, self) self.colorDialog.hide() @@ -124,7 +117,7 @@ def loadGui(self, use_settings_pkl=True): # Load Plot self.statusBar().showMessage('Generating Plot...') self.dock.updateDock() - self.tallyDock.update() + self.dock.update() self.colorDialog.updateDialogValues() self.statusBar().showMessage('') @@ -386,18 +379,6 @@ def createMenuBar(self): self.dockAction.setStatusTip('Toggle dock visibility') self.dockAction.triggered.connect(self.toggleDockView) - self.tallyDockAction = QAction('Tally &Dock', self) - self.tallyDockAction.setShortcut("Ctrl+T") - self.tallyDockAction.setToolTip('Toggle tally dock visibility') - self.tallyDockAction.setStatusTip('Toggle tally dock visibility') - self.tallyDockAction.triggered.connect(self.toggleTallyDockView) - - self.meshAnnotationDockAction = QAction('Mesh &Annotation Dock', self) - self.meshAnnotationDockAction.setShortcut("Ctrl+E") - self.meshAnnotationDockAction.setToolTip('Toggle mesh annotation dock visibility') - self.meshAnnotationDockAction.setStatusTip('Toggle mesh annotation dock visibility') - self.meshAnnotationDockAction.triggered.connect(self.toggleMeshAnnotationDockView) - self.zoomAction = QAction('&Zoom...', self) self.zoomAction.setShortcut('Alt+Shift+Z') self.zoomAction.setToolTip('Edit zoom factor') @@ -406,8 +387,6 @@ def createMenuBar(self): self.viewMenu = self.mainMenu.addMenu('&View') self.viewMenu.addAction(self.dockAction) - self.viewMenu.addAction(self.tallyDockAction) - self.viewMenu.addAction(self.meshAnnotationDockAction) self.viewMenu.addSeparator() self.viewMenu.addAction(self.zoomAction) self.viewMenu.aboutToShow.connect(self.updateViewMenu) @@ -595,7 +574,7 @@ def openStatePoint(self): finally: self.statusBar().showMessage(message.format(filename), 5000) self.updateDataMenu() - self.tallyDock.update() + self.tallyPanel.update() def importProperties(self): filename, ext = QFileDialog.getOpenFileName(self, "Import properties", @@ -629,8 +608,8 @@ def closeStatePoint(self): msg = "Closed statepoint file {}".format(filename) self.statusBar().showMessage(msg) self.updateDataMenu() - self.tallyDock.selectTally() - self.tallyDock.update() + self.tallyPanel.selectTally() + self.tallyPanel.update() self.plotIm.updatePixmap() def updateDataMenu(self): @@ -644,7 +623,7 @@ def updateDataMenu(self): def updateMeshAnnotations(self): - self.model.activeView.mesh_annotations = self.meshAnnotationDock.get_checked_meshes() + self.model.activeView.mesh_annotations = self.meshAnnotationPanel.get_checked_meshes() def plotSourceSites(self): self.sourceSitesDialog.show() @@ -656,7 +635,7 @@ def applyChanges(self): self.statusBar().showMessage('Generating Plot...') QApplication.processEvents() if self.model.activeView.selectedTally is not None: - self.tallyDock.updateModel() + self.tallyPanel.updateModel() self.updateMeshAnnotations() self.model.storeCurrent() self.model.subsequentViews = [] @@ -716,13 +695,13 @@ def restoreDefault(self): def editBasis(self, basis, apply=False): self.model.activeView.basis = basis - self.dock.updateBasis() + self.geometryPanel.updateBasis() if apply: self.applyChanges() def editColorBy(self, domain_kind, apply=False): self.model.activeView.colorby = domain_kind - self.dock.updateColorBy() + self.geometryPanel.updateColorBy() self.colorDialog.updateColorBy() if apply: self.applyChanges() @@ -732,7 +711,7 @@ def editUniverseLevel(self, level, apply=False): self.model.activeView.level = -1 else: self.model.activeView.level = int(level) - self.dock.updateUniverseLevel() + self.geometryPanel.updateUniverseLevel() self.colorDialog.updateUniverseLevel() if apply: self.applyChanges() @@ -822,40 +801,16 @@ def toggleDockView(self): self.resizePixmap() self.showMainWindow() - def toggleTallyDockView(self): - if self.tallyDock.isVisible(): - self.tallyDock.hide() - if not self.isMaximized() and not self.tallyDock.isFloating(): - self.resize(self.width() - self.tallyDock.width(), self.height()) - else: - self.tallyDock.setVisible(True) - if not self.isMaximized() and not self.tallyDock.isFloating(): - self.resize(self.width() + self.tallyDock.width(), self.height()) - self.resizePixmap() - self.showMainWindow() - - def toggleMeshAnnotationDockView(self): - if self.meshAnnotationDock.isVisible(): - self.meshAnnotationDock.hide() - if not self.isMaximized() and not self.meshAnnotationDock.isFloating(): - self.resize(self.width() - self.meshAnnotationDock.width(), self.height()) - else: - self.meshAnnotationDock.setVisible(True) - if not self.isMaximized() and not self.meshAnnotationDock.isFloating(): - self.resize(self.width() + self.meshAnnotationDock.width(), self.height()) - self.resizePixmap() - self.showMainWindow() - def editZoomAct(self): percent, ok = QInputDialog.getInt(self, "Edit Zoom", "Zoom Percent:", - self.dock.zoomBox.value(), 25, 2000) + self.geometryPanel.zoomBox.value(), 25, 2000) if ok: - self.dock.zoomBox.setValue(percent) + self.geometryPanel.zoomBox.setValue(percent) def editZoom(self, value): self.zoom = value self.resizePixmap() - self.dock.zoomBox.setValue(value) + self.geometryPanel.zoomBox.setValue(value) def showMainWindow(self): self.raise_() @@ -884,14 +839,14 @@ def editPlotVisibility(self, value): def toggleOutlinesCell(self, value, apply=False): self.model.activeView.outlinesCell = bool(value) - self.dock.updateOutlines() + self.geometryPanel.updateOutlines() if apply: self.applyChanges() def toggleOutlinesMat(self, value, apply=False): self.model.activeView.outlinesMat = bool(value) - self.dock.updateOutlines() + self.geometryPanel.updateOutlines() if apply: self.applyChanges() @@ -899,26 +854,26 @@ def toggleOutlinesMat(self, value, apply=False): def editWidth(self, value): self.model.activeView.width = value self.onRatioChange() - self.dock.updateWidth() + self.geometryPanel.updateWidth() def editHeight(self, value): self.model.activeView.height = value self.onRatioChange() - self.dock.updateHeight() + self.geometryPanel.updateHeight() def toggleAspectLock(self, state): self.model.activeView.aspectLock = bool(state) self.onRatioChange() - self.dock.updateAspectLock() + self.geometryPanel.updateAspectLock() def editVRes(self, value): self.model.activeView.v_res = value - self.dock.updateVRes() + self.geometryPanel.updateVRes() def editHRes(self, value): self.model.activeView.h_res = value self.onRatioChange() - self.dock.updateHRes() + self.geometryPanel.updateHRes() # Color dialog methods: @@ -987,7 +942,7 @@ def editSelectedTally(self, event): av.selectedTally = None else: av.selectedTally = int(event.split()[1]) - self.tallyDock.selectTally(event) + self.tallyPanel.selectTally(event) def editTallyValue(self, event): av = self.model.activeView @@ -1054,7 +1009,7 @@ def setTallyMinMaxType(self, index, apply=False): # Immediately update visibility of min/max fields based on selection show_custom = (new_type == 'custom') - form = self.tallyDock.tallyColorForm + form = self.tallyPanel.tallyColorForm form.minLabel.setVisible(show_custom) form.minBox.setVisible(show_custom) form.maxLabel.setVisible(show_custom) @@ -1086,7 +1041,7 @@ def toggleReverseCmap(self, state): av.tallyDataReverseCmap = bool(state) def updateTallyMinMax(self): - self.tallyDock.updateMinMax() + self.tallyPanel.updateMinMax() # Plot image methods def editPlotOrigin(self, xOr, yOr, zOr=None, apply=False): @@ -1099,13 +1054,13 @@ def editPlotOrigin(self, xOr, yOr, zOr=None, apply=False): origin[self.zBasis] = self.model.activeView.origin[self.zBasis] self.model.activeView.origin = origin - self.dock.updateOrigin() + self.geometryPanel.updateOrigin() if apply: self.applyChanges() def revertDockControls(self): - self.dock.revertToCurrent() + self.geometryPanel.revertToCurrent() def editDomainColor(self, kind, id): if kind == 'Cell': @@ -1211,7 +1166,7 @@ def onRatioChange(self): if av.aspectLock: ratio = av.width / max(av.height, .001) av.v_res = int(av.h_res / ratio) - self.dock.updateVRes() + self.geometryPanel.updateVRes() def showCoords(self, xPlotPos, yPlotPos): cv = self.model.currentView From f87939a7dd0e38f9a26fc75003bc578ce757ac6b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 08:12:50 -0600 Subject: [PATCH 2/8] Rename Mesh Annotations -> Meshes --- openmc_plotter/docks.py | 10 +++++----- openmc_plotter/main_window.py | 2 +- openmc_plotter/overlays.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index dec559f..c17d102 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -34,8 +34,8 @@ def __init__(self, model, font_metric, main_window, parent=None): self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) -class MeshAnnotationPanel(PlotterPanel): - """Panel for mesh annotation options""" +class MeshPanel(PlotterPanel): + """Panel for mesh options""" def __init__(self, model, font_metric, main_window, parent=None): super().__init__(model, font_metric, main_window, parent) @@ -70,7 +70,7 @@ def update(self): class TabbedDock(QDockWidget): """ - Dock widget containing tabbed panels for Geometry, Tallies, and Mesh Annotations + Dock widget containing tabbed panels for Geometry, Tallies, and Meshes """ def __init__(self, model, font_metric, parent=None): @@ -89,12 +89,12 @@ def __init__(self, model, font_metric, parent=None): # Create the three panels self.geometryPanel = GeometryPanel(model, font_metric, parent, self) self.tallyPanel = TallyPanel(model, font_metric, parent, self) - self.meshAnnotationPanel = MeshAnnotationPanel(model, font_metric, parent, self) + self.meshAnnotationPanel = MeshPanel(model, font_metric, parent, self) # Add panels as tabs self.tabWidget.addTab(self.geometryPanel, "Geometry") self.tabWidget.addTab(self.tallyPanel, "Tallies") - self.tabWidget.addTab(self.meshAnnotationPanel, "Mesh Annotations") + self.tabWidget.addTab(self.meshAnnotationPanel, "Meshes") # Create Apply Changes button self.applyButton = QPushButton("Apply Changes") diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index e777363..1c6622c 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -80,7 +80,7 @@ def loadGui(self, use_settings_pkl=True): self.plotIm.frozen = True self.frame.setWidget(self.plotIm) - # Tabbed Dock (contains Geometry, Tallies, and Mesh Annotations) + # Tabbed Dock (contains Geometry, Tallies, and Meshes) self.dock = TabbedDock(self.model, self.font_metric, self) self.dock.setObjectName("Options Dock") self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dock) diff --git a/openmc_plotter/overlays.py b/openmc_plotter/overlays.py index 9c7d1d2..c68eb67 100644 --- a/openmc_plotter/overlays.py +++ b/openmc_plotter/overlays.py @@ -40,7 +40,7 @@ class ShortcutsOverlay(QWidget): ("Horizontal Scroll", "Alt+Scroll")], "Menus": [("Hide/Show Geometry Dock", c_key + "+D"), ("Hide/Show Tally Dock", c_key + "+T"), - ("Hide/Show Mesh Annotation Dock", c_key + "+E"), + ("Hide/Show Mesh Dock", c_key + "+E"), ("Reload Model", "Shift+" + c_key + "+R"), ("Quit", c_key + "+Q"), ("Display Shortcuts", "?")], From 992a8a25a1e311d5ee85c0650223c31886d5f39d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 08:17:26 -0600 Subject: [PATCH 3/8] Make apply changes button green --- openmc_plotter/docks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index c17d102..7f691fe 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -99,6 +99,7 @@ def __init__(self, model, font_metric, parent=None): # Create Apply Changes button self.applyButton = QPushButton("Apply Changes") self.applyButton.setMinimumHeight(self.font_metric.height() * 1.6) + self.applyButton.setStyleSheet("QPushButton { background-color: #4CAF50; color: white; }") self.applyButton.clicked.connect(self.main_window.applyChanges) # Main layout with tabs and apply button From 3167f684bd730e2a2ad3c4c399199a38b5cac09f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 08:27:43 -0600 Subject: [PATCH 4/8] Rename a few methods for consistency --- openmc_plotter/docks.py | 12 ++++++------ openmc_plotter/main_window.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index 7f691fe..f68cfbb 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -113,12 +113,12 @@ def __init__(self, model, font_metric, parent=None): self.containerWidget.setLayout(self.mainLayout) self.setWidget(self.containerWidget) - def updateDock(self): - """Update geometry panel""" - self.geometryPanel.updateDock() + def updateGeometryPanel(self): + """Update geometry panel controls from current model state""" + self.geometryPanel.update() - def update(self): - """Update tally panel""" + def updateTallyPanel(self): + """Update tally panel controls (called when statepoint changes)""" self.tallyPanel.update() def resizeEvent(self, event): @@ -320,7 +320,7 @@ def _createResolutionBox(self): self.resGroupBox = QGroupBox("Resolution") self.resGroupBox.setLayout(self.resLayout) - def updateDock(self): + def update(self): self.updateOrigin() self.updateWidth() self.updateHeight() diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index 1c6622c..73a7cd3 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -116,8 +116,8 @@ def loadGui(self, use_settings_pkl=True): # Load Plot self.statusBar().showMessage('Generating Plot...') - self.dock.updateDock() - self.dock.update() + self.dock.updateGeometryPanel() + self.dock.updateTallyPanel() self.colorDialog.updateDialogValues() self.statusBar().showMessage('') @@ -533,7 +533,7 @@ def loadViewFile(self, filename): self.model.activeView.outlinesCell = False if not hasattr(self.model.activeView, 'outlinesMat'): self.model.activeView.outlinesMat = False - self.dock.updateDock() + self.dock.updateGeometryPanel() self.colorDialog.updateDialogValues() self.applyChanges() message = '{} loaded'.format(filename) @@ -653,7 +653,7 @@ def undo(self): self.model.undo() self.resetModels() self.showCurrentView() - self.dock.updateDock() + self.dock.updateGeometryPanel() self.colorDialog.updateDialogValues() if not self.model.previousViews: @@ -668,7 +668,7 @@ def redo(self): self.model.redo() self.resetModels() self.showCurrentView() - self.dock.updateDock() + self.dock.updateGeometryPanel() self.colorDialog.updateDialogValues() if not self.model.subsequentViews: @@ -687,7 +687,7 @@ def restoreDefault(self): self.plotIm.generatePixmap() self.resetModels() self.showCurrentView() - self.dock.updateDock() + self.dock.updateGeometryPanel() self.colorDialog.updateDialogValues() self.model.subsequentViews = [] From 7f8a4a44cfb60941351816a97e769cae1a5203de Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 08:29:59 -0600 Subject: [PATCH 5/8] Fix warning about MaskedConstant --- openmc_plotter/plotgui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc_plotter/plotgui.py b/openmc_plotter/plotgui.py index ee54e00..af62f21 100644 --- a/openmc_plotter/plotgui.py +++ b/openmc_plotter/plotgui.py @@ -290,7 +290,7 @@ def mouseMoveEvent(self, event): if value is not None and not np.isnan(value): self.updateTallyDataIndicatorValue(value) tallyInfo = "Tally {} {}: {:.5E}".format( - tid, cv.tallyValue, value) + tid, cv.tallyValue, float(value)) else: self.updateTallyDataIndicatorValue(0.0) else: From d2f5211f68cb04e2a0c706827a26a665d7025963 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 15:25:16 -0600 Subject: [PATCH 6/8] Use geometryPanel and tallyPanel attributes --- openmc_plotter/docks.py | 8 -------- openmc_plotter/main_window.py | 12 ++++++------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index f68cfbb..dc92f70 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -113,14 +113,6 @@ def __init__(self, model, font_metric, parent=None): self.containerWidget.setLayout(self.mainLayout) self.setWidget(self.containerWidget) - def updateGeometryPanel(self): - """Update geometry panel controls from current model state""" - self.geometryPanel.update() - - def updateTallyPanel(self): - """Update tally panel controls (called when statepoint changes)""" - self.tallyPanel.update() - def resizeEvent(self, event): self.main_window.resizeEvent(event) diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index 73a7cd3..f174bb3 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -116,8 +116,8 @@ def loadGui(self, use_settings_pkl=True): # Load Plot self.statusBar().showMessage('Generating Plot...') - self.dock.updateGeometryPanel() - self.dock.updateTallyPanel() + self.geometryPanel.update() + self.tallyPanel.update() self.colorDialog.updateDialogValues() self.statusBar().showMessage('') @@ -533,7 +533,7 @@ def loadViewFile(self, filename): self.model.activeView.outlinesCell = False if not hasattr(self.model.activeView, 'outlinesMat'): self.model.activeView.outlinesMat = False - self.dock.updateGeometryPanel() + self.geometryPanel.update() self.colorDialog.updateDialogValues() self.applyChanges() message = '{} loaded'.format(filename) @@ -653,7 +653,7 @@ def undo(self): self.model.undo() self.resetModels() self.showCurrentView() - self.dock.updateGeometryPanel() + self.geometryPanel.update() self.colorDialog.updateDialogValues() if not self.model.previousViews: @@ -668,7 +668,7 @@ def redo(self): self.model.redo() self.resetModels() self.showCurrentView() - self.dock.updateGeometryPanel() + self.geometryPanel.update() self.colorDialog.updateDialogValues() if not self.model.subsequentViews: @@ -687,7 +687,7 @@ def restoreDefault(self): self.plotIm.generatePixmap() self.resetModels() self.showCurrentView() - self.dock.updateGeometryPanel() + self.geometryPanel.update() self.colorDialog.updateDialogValues() self.model.subsequentViews = [] From 590440e227abbcc59f177076e30560b2ee4db059 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 15:25:32 -0600 Subject: [PATCH 7/8] Avoid converting MaskedConstant to nan --- openmc_plotter/plotgui.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openmc_plotter/plotgui.py b/openmc_plotter/plotgui.py index af62f21..41e118d 100644 --- a/openmc_plotter/plotgui.py +++ b/openmc_plotter/plotgui.py @@ -12,6 +12,7 @@ from matplotlib.backends.backend_qt5agg import FigureCanvas import matplotlib.pyplot as plt import numpy as np +import numpy.ma as ma from .plot_colors import rgb_normalize, invert_rgb from .plotmodel import DomainDelegate, PlotModel @@ -287,7 +288,7 @@ def mouseMoveEvent(self, event): if self.model.tally_data is not None: tid, value = self.getTallyInfo(event) - if value is not None and not np.isnan(value): + if value is not None and value is not ma.masked: self.updateTallyDataIndicatorValue(value) tallyInfo = "Tally {} {}: {:.5E}".format( tid, cv.tallyValue, float(value)) From 870e144a4fe500faed9ab2e8d3a8b9d3b22f8b2b Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Jan 2026 15:56:51 -0600 Subject: [PATCH 8/8] Make sure panels are resizable so that full GUI window can be resized --- openmc_plotter/docks.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/openmc_plotter/docks.py b/openmc_plotter/docks.py index dc92f70..ac9b2d5 100644 --- a/openmc_plotter/docks.py +++ b/openmc_plotter/docks.py @@ -91,10 +91,23 @@ def __init__(self, model, font_metric, parent=None): self.tallyPanel = TallyPanel(model, font_metric, parent, self) self.meshAnnotationPanel = MeshPanel(model, font_metric, parent, self) + # Wrap panels in scroll areas + geometryScroll = QScrollArea() + geometryScroll.setWidget(self.geometryPanel) + geometryScroll.setWidgetResizable(True) + + tallyScroll = QScrollArea() + tallyScroll.setWidget(self.tallyPanel) + tallyScroll.setWidgetResizable(True) + + meshScroll = QScrollArea() + meshScroll.setWidget(self.meshAnnotationPanel) + meshScroll.setWidgetResizable(True) + # Add panels as tabs - self.tabWidget.addTab(self.geometryPanel, "Geometry") - self.tabWidget.addTab(self.tallyPanel, "Tallies") - self.tabWidget.addTab(self.meshAnnotationPanel, "Meshes") + self.tabWidget.addTab(geometryScroll, "Geometry") + self.tabWidget.addTab(tallyScroll, "Tallies") + self.tabWidget.addTab(meshScroll, "Meshes") # Create Apply Changes button self.applyButton = QPushButton("Apply Changes") @@ -421,18 +434,7 @@ def __init__(self, model, font_metric, main_window, parent=None): self.panelLayout.addWidget(HorizontalLine()) self.panelLayout.addWidget(self.tallyColorForm) - # Create widget for scroll area and apply main layout - self.scroll = QScrollArea() - self.scroll.setWidgetResizable(True) - self.widget = QWidget() - self.widget.setLayout(self.panelLayout) - self.scroll.setWidget(self.widget) - - # Set scroll area as main layout - mainLayout = QVBoxLayout() - mainLayout.setContentsMargins(0, 0, 0, 0) - mainLayout.addWidget(self.scroll) - self.setLayout(mainLayout) + self.setLayout(self.panelLayout) def _createFilterTree(self, spatial_filters): av = self.model.activeView