Source code for schrodinger.trajectory.trajectory_gui_dir.banners
from enum import Enum
from schrodinger import get_maestro
from schrodinger.Qt import QtCore
from schrodinger.Qt import QtWidgets
from schrodinger.ui import picking
from schrodinger.ui.qt import basewidgets
from . import centroid_banner_ui
from . import planar_banner_ui
from . import stylesheet
maestro = get_maestro()
[docs]class MeasurementMode(Enum):
"""
Type of measurement for the CentroidBanner to search for
"""
DISTANCE = 1
ANGLE = 2
[docs]class CentroidBanner(basewidgets.BaseWidget):
"""
Banner for picking the centroid of angles or distances
"""
SETS_REQUIRED = {MeasurementMode.DISTANCE: 2, MeasurementMode.ANGLE: 3}
ui_module = centroid_banner_ui
closeBanner = QtCore.pyqtSignal()
# Signal to emit when all centroid atoms are picked
centroidsPicked = QtCore.pyqtSignal(list)
[docs] def __init__(self):
super().__init__()
self.picked_sets = []
self.current_aids = []
self._measurement_mode = MeasurementMode.DISTANCE
[docs] def initSetUp(self):
super().initSetUp()
self.setStyleSheet(stylesheet.TRAJECTORY_PLOT_BANNERS)
self.setObjectName('centroid_banner')
self._setupMeasurementMenu()
self.ui.cancel_btn.clicked.connect(self._handleCancel)
self.ui.save_set_tb.clicked.connect(self._saveSet)
self.ui.ok_btn.clicked.connect(self._handleOk)
self.cb = QtWidgets.QCheckBox()
self.atom_picker = picking.PickAtomsToggle(self.cb,
None,
self._pickCallback,
pick_text='')
[docs] def startPicking(self):
self.atom_picker.start()
[docs] def stopPicking(self):
self.atom_picker.stop()
def _pickCallback(self, aids):
required_sets = self.SETS_REQUIRED[self._measurement_mode]
if len(self.picked_sets) < required_sets:
self.current_aids = aids
self._updateUI()
def _saveSet(self):
if len(self.picked_sets) < self.SETS_REQUIRED[self._measurement_mode]:
self.picked_sets.append(self.current_aids)
self.current_aids = set()
self._updateUI()
# Toggle Picking state to clear current selections
self.stopPicking()
self.startPicking()
def _updateUI(self):
"""
Updates UI to account for changes
"""
self._updateCancelString()
self._updatePickProgressString()
self._updateDescriptionString()
self._updateOKButton()
def _updatePickProgressString(self):
sets_needed = self.SETS_REQUIRED[self._measurement_mode]
pick_string = f'{len(self.picked_sets)} / {sets_needed} sets defined'
self.ui.number_selected_lbl.setText(pick_string)
color = 'yellow' if len(self.picked_sets) >= 1 else 'white'
formatted_color = 'QLabel {color: ' + color + ';}'
self.ui.number_selected_lbl.setStyleSheet(formatted_color)
def _updateOKButton(self):
enable = len(
self.picked_sets) == self.SETS_REQUIRED[self._measurement_mode]
self.ui.ok_btn.setEnabled(enable)
def _updateCancelString(self):
text = 'Start Over' if len(self.picked_sets) >= 1 else 'Cancel'
self.ui.cancel_btn.setText(text)
def _updateDescriptionString(self):
sets_needed = self.SETS_REQUIRED[self._measurement_mode]
description = f"""<i>Define {sets_needed} sets of atoms, clicking Save Set after each set has been selected.</i>"""
self.ui.description_lbl.setText(description)
def _setupMeasurementMenu(self):
self.measurement_menu = QtWidgets.QMenu(self)
action = self.measurement_menu.addAction('Distance')
action.triggered.connect(
lambda: self._onMenuChange(MeasurementMode.DISTANCE))
action = self.measurement_menu.addAction('Angle')
action.triggered.connect(
lambda: self._onMenuChange(MeasurementMode.ANGLE))
self.ui.measurement_tb.setPopupMode(QtWidgets.QToolButton.InstantPopup)
self.ui.measurement_tb.setMenu(self.measurement_menu)
def _onMenuChange(self, mode):
"""
Handle a change in the measurement menu
"""
if mode != self._measurement_mode:
self._measurement_mode = mode
formatted_text = mode.name.title()
self.ui.measurement_tb.setText(formatted_text)
self.picked_sets.clear()
self.current_aids = set()
self._updateUI()
def _handleCancel(self):
# If we have more than one pick, reset all picks
if len(self.picked_sets) >= 1:
self.picked_sets.clear()
self._updateUI()
# Otherwise, quit the banner
else:
self._handleClose()
def _handleClose(self):
self.stopPicking()
self.closeBanner.emit()
def _handleOk(self):
if len(self.picked_sets) == self.SETS_REQUIRED[self._measurement_mode]:
self.centroidsPicked.emit(self.picked_sets)
self._handleClose()
[docs]class PlanarBanner(basewidgets.BaseWidget):
"""
Banner for picking the planar angle of six atoms
"""
ui_module = planar_banner_ui
closeBanner = QtCore.pyqtSignal()
# Signal to emit when all planar atoms are picked
planarAnglesPicked = QtCore.pyqtSignal(list)
[docs] def __init__(self):
super().__init__()
self.setStyleSheet(stylesheet.TRAJECTORY_PLOT_BANNERS)
[docs] def initSetUp(self):
super().initSetUp()
self.picked_atoms = []
self.setObjectName('planar_banner')
self.ui.cancel_btn.clicked.connect(self._handleCancel)
self.ui.ok_btn.clicked.connect(self._handleClose)
self._cb = QtWidgets.QCheckBox()
self.atom_picker = picking.PickAtomsToggle(self._cb,
None,
self._pickCallback,
pick_text='')
self._updateUI()
[docs] def startPicking(self):
self.atom_picker.start()
[docs] def stopPicking(self):
self.atom_picker.stop()
self.picked_atoms.clear()
self._updateUI()
def _pickCallback(self, aids):
self.picked_atoms = aids
if len(self.picked_atoms) == 6:
self.planarAnglesPicked.emit(self.picked_atoms)
self._resetPicks()
self._updateUI()
def _updateUI(self):
"""
Updates UI to account for changes
"""
self._updateCancelString()
self._updatePickProgressString()
def _updatePickProgressString(self):
pick_string = f'{len(self.picked_atoms)} / 6 atoms selected'
self.ui.number_selected_lbl.setText(pick_string)
color = 'yellow' if len(self.picked_atoms) >= 1 else 'white'
formatted_color = 'QLabel {color: ' + color + ';}'
self.ui.number_selected_lbl.setStyleSheet(formatted_color)
def _updateCancelString(self):
text = 'Start Over' if len(self.picked_atoms) >= 1 else 'Cancel'
self.ui.cancel_btn.setText(text)
def _handleCancel(self):
# If we have more than one pick, reset all picks
if len(self.picked_atoms) >= 1:
self._resetPicks()
# Otherwise, quit the banner
else:
self._handleClose()
def _handleClose(self):
self.stopPicking()
self.closeBanner.emit()
def _resetPicks(self):
self.stopPicking()
self.startPicking()