Skip to content

Commit

Permalink
Add post trigger to GUI (#224)
Browse files Browse the repository at this point in the history
* Add TypeComboBox which uses type(value) as immutable symbol
* Inline GUI strings, don't auto-create QLabel if one argument
* Add LayoutStack.parent (unused)
* Always dump trigger.post_trigger/radius
  • Loading branch information
nyanpasu64 committed Mar 12, 2019
1 parent b5de8d7 commit 1456be2
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 103 deletions.
22 changes: 14 additions & 8 deletions corrscope/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
behead,
rgetattr,
rsetattr,
Value,
ValueText,
Symbol,
SymbolText,
)
from corrscope.gui.util import color2hex, Locked, find_ranges, TracebackDialog
from corrscope.gui.view_mainwindow import MainWindow as Ui_MainWindow
Expand All @@ -42,6 +42,7 @@
CorrelationTriggerConfig,
MainTriggerConfig,
SpectrumConfig,
ZeroCrossingTriggerConfig,
)
from corrscope.util import obj_name
from corrscope.wave import Flatten
Expand Down Expand Up @@ -630,13 +631,13 @@ def setter(self: "ConfigModel", val: str):

class ConfigModel(PresentationModel):
cfg: Config
combo_value_text: Dict[str, Sequence[ValueText]] = {}
combo_symbol_text: Dict[str, Sequence[SymbolText]] = {}

master_audio = path_fix_property("master_audio")

# Stereo flattening
combo_value_text["trigger_stereo"] = list(flatten_no_stereo.items())
combo_value_text["render_stereo"] = list(flatten_modes.items())
combo_symbol_text["trigger_stereo"] = list(flatten_no_stereo.items())
combo_symbol_text["render_stereo"] = list(flatten_modes.items())

# Trigger
@property
Expand All @@ -650,11 +651,16 @@ def trigger__pitch_tracking(self, gui: bool):
scfg = SpectrumConfig() if gui else None
self.cfg.trigger.pitch_tracking = scfg

combo_value_text["trigger__edge_direction"] = [
combo_symbol_text["trigger__edge_direction"] = [
(1, "Rising (+1)"),
(-1, "Falling (-1)"),
]

combo_symbol_text["trigger__post_trigger"] = [
(type(None), "Disabled"),
(ZeroCrossingTriggerConfig, "Zero Crossing"),
]

# Render
@property
def render_resolution(self) -> str:
Expand Down Expand Up @@ -690,10 +696,10 @@ def render_resolution(self, value: str):
_orientations = [["h", "Horizontal"], ["v", "Vertical"]]
_stereo_orientations = _orientations + [["overlay", "Overlay"]]

combo_value_text["layout__orientation"] = [
combo_symbol_text["layout__orientation"] = [
(Orientation(key), name) for key, name in _orientations
]
combo_value_text["layout__stereo_orientation"] = [
combo_symbol_text["layout__stereo_orientation"] = [
(StereoOrientation(key), name) for key, name in _stereo_orientations
]

Expand Down
60 changes: 44 additions & 16 deletions corrscope/gui/model_bind.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@
"behead",
"rgetattr",
"rsetattr",
"Value",
"ValueText",
"Symbol",
"SymbolText",
]


Signal = Any
WidgetUpdater = Callable[[], None]
Value = Hashable
Symbol = Hashable


ValueText = Tuple[Value, str]
SymbolText = Tuple[Symbol, str]

# Data binding presentation-model
class PresentationModel(qc.QObject):
Expand All @@ -48,7 +48,7 @@ class PresentationModel(qc.QObject):

# These fields are specific to each subclass, and assigned there.
# Although less explicit, these can be assigned using __init_subclass__.
combo_value_text: Dict[str, Sequence[ValueText]]
combo_symbol_text: Dict[str, Sequence[SymbolText]]
edited = qc.pyqtSignal()

def __init__(self, cfg: DumpableAttrs):
Expand Down Expand Up @@ -277,37 +277,65 @@ def set_model(self, value: CheckState):


class BoundComboBox(qw.QComboBox, BoundWidget):
combo_value_text: Sequence[ValueText]
value2idx: Dict[Value, int]
"""Combo box using values as immutable symbols.
- Converts immutable values (from model) into symbols: value
- Converts symbols (hard-coded) into immutable values: value
"""

combo_symbol_text: Sequence[SymbolText]
symbol2idx: Dict[Symbol, int]

# noinspection PyAttributeOutsideInit
def bind_widget(self, model: PresentationModel, path: str, *args, **kwargs) -> None:
# Effectively enum values.
self.combo_value_text = model.combo_value_text[path]
self.combo_symbol_text = model.combo_symbol_text[path]

# value2idx[enum] = combo-box index
self.value2idx = {}
# symbol2idx[enum] = combo-box index
self.symbol2idx = {}

for i, (value, text) in enumerate(self.combo_value_text):
self.value2idx[value] = i
for i, (symbol, text) in enumerate(self.combo_symbol_text):
self.symbol2idx[symbol] = i
# Pretty-printed text
self.addItem(text)

BoundWidget.bind_widget(self, model, path, *args, **kwargs)

# combobox.index = pmodel.attr
def set_gui(self, value: Value) -> None:
combo_index = self.value2idx[value]
def set_gui(self, model_value: Any) -> None:
combo_index = self.symbol2idx[self._symbol_from_value(model_value)]
self.setCurrentIndex(combo_index)

@staticmethod
def _symbol_from_value(value) -> Symbol:
return value

gui_changed = alias("currentIndexChanged")

# pmodel.attr = combobox.index
@pyqtSlot(int)
def set_model(self, combo_index: int):
assert isinstance(combo_index, int)
value, _ = self.combo_value_text[combo_index]
self.pmodel[self.path] = value
combo_symbol, _ = self.combo_symbol_text[combo_index]
self.pmodel[self.path] = self._value_from_symbol(combo_symbol)

@staticmethod
def _value_from_symbol(symbol: Symbol):
return symbol


class TypeComboBox(BoundComboBox):
"""Combo box using types as immutable symbols.
- Converts mutable values (from model) into symbols: type(value)
- Converts symbols (hard-coded) into mutable values: cls()
"""

@staticmethod
def _symbol_from_value(instance) -> type:
return type(instance)

@staticmethod
def _value_from_symbol(obj_type: type):
return obj_type()


# Color-specific widgets
Expand Down
Loading

0 comments on commit 1456be2

Please sign in to comment.