-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from Carifio24/ui-layer-types
Support multiple layer types in tool UI, fix colormap bug
- Loading branch information
Showing
9 changed files
with
183 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import os | ||
|
||
from echo import SelectionCallbackProperty | ||
from echo.qt import autoconnect_callbacks_to_qt, connect_checkable_button, connect_float_text | ||
|
||
from glue.config import DictRegistry | ||
from glue.core.data_combo_helper import ComboHelper | ||
from glue.core.state_objects import State | ||
from glue_qt.utils import load_ui | ||
from qtpy.QtGui import QDoubleValidator, QIntValidator | ||
|
||
|
||
from qtpy.QtWidgets import QCheckBox, QDialog, QHBoxLayout, QLabel, QLineEdit | ||
from qtpy.QtGui import QIntValidator, QDoubleValidator | ||
|
||
|
||
__all__ = ['ar_layer_export', 'ARExportDialog'] | ||
|
||
|
||
def display_name(prop): | ||
return prop.replace("_", " ").capitalize() | ||
|
||
|
||
class ARExportLayerOptionsRegistry(DictRegistry): | ||
|
||
def add(self, layer_state_cls, layer_options_state): | ||
if not issubclass(layer_options_state, State): | ||
raise ValueError("Layer options must be a glue State type") | ||
self._members[layer_state_cls] = layer_options_state | ||
|
||
def __call__(self, layer_state_cls): | ||
def adder(export_state_class): | ||
self.add(layer_state_cls, export_state_class) | ||
return adder | ||
|
||
|
||
ar_layer_export = ARExportLayerOptionsRegistry() | ||
|
||
|
||
class ARExportDialogState(State): | ||
|
||
filetype = SelectionCallbackProperty() | ||
layer = SelectionCallbackProperty() | ||
|
||
def __init__(self, viewer_state): | ||
|
||
super(ARExportDialogState, self).__init__() | ||
|
||
self.filetype_helper = ComboHelper(self, 'filetype') | ||
self.filetype_helper.choices = ['glTF', 'OBJ'] | ||
|
||
self.layers = [state for state in viewer_state.layers if state.visible] | ||
self.layer_helper = ComboHelper(self, 'layer') | ||
self.layer_helper.choices = [state.layer.label for state in self.layers] | ||
|
||
|
||
class ARExportDialog(QDialog): | ||
|
||
def __init__(self, parent=None, viewer_state=None): | ||
|
||
super(ARExportDialog, self).__init__(parent=parent) | ||
|
||
self.viewer_state = viewer_state | ||
self.state = ARExportDialogState(self.viewer_state) | ||
self.ui = load_ui('export_dialog.ui', self, directory=os.path.dirname(__file__)) | ||
|
||
layers = [state for state in self.viewer_state.layers if state.visible] | ||
self.state_dictionary = { | ||
layer.layer.label: ar_layer_export.members[type(layer)]() | ||
for layer in layers | ||
} | ||
|
||
self._connections = autoconnect_callbacks_to_qt(self.state, self.ui) | ||
self._layer_connections = [] | ||
|
||
self.ui.button_cancel.clicked.connect(self.reject) | ||
self.ui.button_ok.clicked.connect(self.accept) | ||
|
||
self.state.add_callback('layer', self._update_layer_ui) | ||
|
||
self._update_layer_ui(self.state.layer) | ||
|
||
def _widgets_for_property(self, instance, property, display_name): | ||
value = getattr(instance, property) | ||
t = type(value) | ||
if t is bool: | ||
widget = QCheckBox() | ||
widget.setChecked(value) | ||
widget.setText(display_name) | ||
self._layer_connections.append(connect_checkable_button(instance, property, widget)) | ||
return [widget] | ||
elif t in [int, float]: | ||
label = QLabel() | ||
prompt = f"{display_name}:" | ||
label.setText(prompt) | ||
widget = QLineEdit() | ||
validator = QIntValidator() if t is int else QDoubleValidator() | ||
widget.setText(str(value)) | ||
widget.setValidator(validator) | ||
self._layer_connections.append(connect_float_text(instance, property, widget)) | ||
return [label, widget] | ||
|
||
def _clear_layout(self, layout): | ||
if layout is not None: | ||
while layout.count(): | ||
item = layout.takeAt(0) | ||
widget = item.widget() | ||
if widget is not None: | ||
widget.deleteLater() | ||
else: | ||
self._clear_layout(item.layout()) | ||
|
||
def _clear_layer_layout(self): | ||
self._clear_layout(self.ui.layer_layout) | ||
|
||
def _update_layer_ui(self, layer): | ||
self._clear_layer_layout() | ||
self._layer_connections = [] | ||
state = self.state_dictionary[layer] | ||
for property in state.callback_properties(): | ||
row = QHBoxLayout() | ||
name = display_name(property) | ||
widgets = self._widgets_for_property(state, property, name) | ||
for widget in widgets: | ||
row.addWidget(widget) | ||
self.ui.layer_layout.addRow(row) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,13 @@ | ||
import os | ||
|
||
from qtpy.QtWidgets import QDialog, QListWidgetItem | ||
|
||
from echo import CallbackProperty | ||
from glue.core.state_objects import State | ||
from glue.core.data_combo_helper import ComboHelper | ||
from glue_qt.utils import load_ui | ||
from glue_ar.export_dialog import ar_layer_export | ||
from glue_vispy_viewers.scatter.layer_state import ScatterLayerState | ||
|
||
from echo import CallbackProperty, SelectionCallbackProperty | ||
from echo.qt import autoconnect_callbacks_to_qt | ||
__all__ = ["ARScatterExportOptions"] | ||
|
||
__all__ = ["ExportScatterDialog"] | ||
|
||
# Note that this class only holds the state that is | ||
# currently displayed in the dialog. In particular, | ||
# this means that `theta_resolution` and `phi_resolution` | ||
# represent the resolutions for `layer` | ||
class ExportScatterDialogState(State): | ||
@ar_layer_export(ScatterLayerState) | ||
class ARScatterExportOptions(State): | ||
|
||
filetype = SelectionCallbackProperty() | ||
layer = SelectionCallbackProperty() | ||
theta_resolution = CallbackProperty(8) | ||
phi_resolution = CallbackProperty(8) | ||
|
||
def __init__(self, viewer_state): | ||
|
||
super(ExportScatterDialogState, self).__init__() | ||
|
||
self.filetype_helper = ComboHelper(self, 'filetype') | ||
self.filetype_helper.choices = ['glTF', 'OBJ'] | ||
|
||
self.layers = [state for state in viewer_state.layers if state.visible] | ||
self.layer_helper = ComboHelper(self, 'layer') | ||
self.layer_helper.choices = [state.layer.label for state in self.layers] | ||
|
||
|
||
class ExportScatterDialog(QDialog): | ||
|
||
def __init__(self, parent=None, viewer_state=None): | ||
|
||
super(ExportScatterDialog, self).__init__(parent=parent) | ||
|
||
self.viewer_state = viewer_state | ||
self.state = ExportScatterDialogState(self.viewer_state) | ||
self.ui = load_ui('export_scatter.ui', self, directory=os.path.dirname(__file__)) | ||
|
||
layers = [state for state in self.viewer_state.layers if state.visible] | ||
self.info_dictionary = { | ||
layer.layer.label: { | ||
"theta_resolution": 8, | ||
"phi_resolution": 8 | ||
} for layer in layers | ||
} | ||
|
||
for layer in layers: | ||
item = QListWidgetItem(layer.layer.label) | ||
self.ui.listsel_layer.addItem(item) | ||
|
||
self._connections = autoconnect_callbacks_to_qt(self.state, self.ui) | ||
|
||
self.ui.button_cancel.clicked.connect(self.reject) | ||
self.ui.button_ok.clicked.connect(self.accept) | ||
|
||
self.state.add_callback('theta_resolution', self._on_theta_resolution_change) | ||
self.state.add_callback('phi_resolution', self._on_phi_resolution_change) | ||
self.state.add_callback('layer', self._on_layer_change) | ||
|
||
def _on_theta_resolution_change(self, resolution): | ||
self.info_dictionary[self.state.layer]["theta_resolution"] = int(resolution) | ||
|
||
def _on_phi_resolution_change(self, resolution): | ||
self.info_dictionary[self.state.layer]["phi_resolution"] = int(resolution) | ||
|
||
def _on_layer_change(self, layer): | ||
self.state.theta_resolution = self.info_dictionary[layer]["theta_resolution"] | ||
self.state.phi_resolution = self.info_dictionary[layer]["phi_resolution"] | ||
|
Oops, something went wrong.