kopia lustrzana https://github.com/corrscope/corrscope
Refactor and reorganize trigger GUI (#236)
- Separate trigger options into groups - Enhance GUI framework - `append_widget(name, layout, **kwargs)` - `add_row(**kwargs{name=})`pull/357/head
rodzic
ecfa452255
commit
eed5ffddb8
|
@ -248,21 +248,56 @@ class MainWindow(QWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Trigger config
|
# Trigger config
|
||||||
with append_widget(s, QGroupBox) as self.optionTrigger:
|
with append_widget(s, QVBoxLayout):
|
||||||
set_layout(s, QVBoxLayout)
|
with append_widget(s, QHBoxLayout):
|
||||||
|
with append_widget(
|
||||||
|
s, QGroupBox, title=tr("Wave Alignment"), layout=QGridLayout
|
||||||
|
):
|
||||||
|
with add_grid_col(
|
||||||
|
s,
|
||||||
|
tr("Buffer Strength"),
|
||||||
|
BoundDoubleSpinBox,
|
||||||
|
name="trigger__buffer_strength",
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
with add_grid_col(
|
||||||
|
s,
|
||||||
|
tr("Buffer Responsiveness"),
|
||||||
|
BoundDoubleSpinBox,
|
||||||
|
name="trigger__responsiveness",
|
||||||
|
maximum=1.0,
|
||||||
|
singleStep=0.1,
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
with add_grid_col(
|
||||||
|
s,
|
||||||
|
tr("Mean Responsiveness"),
|
||||||
|
BoundDoubleSpinBox,
|
||||||
|
name="trigger__mean_responsiveness",
|
||||||
|
) as w: # type: BoundDoubleSpinBox
|
||||||
|
w.setMaximum(1.0)
|
||||||
|
w.setSingleStep(0.1)
|
||||||
|
with add_grid_col(s, BoundCheckBox, Both) as (
|
||||||
|
self.trigger__pitch_tracking
|
||||||
|
):
|
||||||
|
assert isinstance(self.trigger__pitch_tracking, QWidget)
|
||||||
|
|
||||||
# Top row
|
with append_widget(
|
||||||
with append_widget(s, QGridLayout):
|
s, QGroupBox, title=tr("Edge Search"), layout=QGridLayout
|
||||||
|
):
|
||||||
with add_grid_col(s, "", BoundComboBox) as (
|
with add_grid_col(s, "", BoundComboBox) as (
|
||||||
self.trigger__edge_direction
|
self.trigger__edge_direction
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with add_grid_col(s, "", BoundDoubleSpinBox) as (
|
with add_grid_col(s, "", BoundDoubleSpinBox) as (
|
||||||
self.trigger__edge_strength
|
self.trigger__edge_strength
|
||||||
):
|
):
|
||||||
self.trigger__edge_strength.setMinimum(0.0)
|
self.trigger__edge_strength.setMinimum(0.0)
|
||||||
|
|
||||||
|
with append_widget(s, QHBoxLayout):
|
||||||
|
with append_widget(
|
||||||
|
s, QGroupBox, title=tr("Slope Search"), layout=QGridLayout
|
||||||
|
):
|
||||||
with add_grid_col(
|
with add_grid_col(
|
||||||
s,
|
s,
|
||||||
tr("Slope Strength"),
|
tr("Slope Strength"),
|
||||||
|
@ -271,7 +306,6 @@ class MainWindow(QWidget):
|
||||||
):
|
):
|
||||||
s.widget.setSingleStep(10)
|
s.widget.setSingleStep(10)
|
||||||
s.widget.setMaximum(200)
|
s.widget.setMaximum(200)
|
||||||
|
|
||||||
with add_grid_col(
|
with add_grid_col(
|
||||||
s,
|
s,
|
||||||
tr("Slope Width"),
|
tr("Slope Width"),
|
||||||
|
@ -282,31 +316,9 @@ class MainWindow(QWidget):
|
||||||
s.widget.setMaximum(0.5)
|
s.widget.setMaximum(0.5)
|
||||||
s.widget.setSingleStep(0.02)
|
s.widget.setSingleStep(0.02)
|
||||||
|
|
||||||
with add_grid_col(s, "", BoundDoubleSpinBox) as (
|
with append_widget(
|
||||||
self.trigger__responsiveness
|
s, QGroupBox, title=tr("Post Triggering"), layout=QGridLayout
|
||||||
):
|
):
|
||||||
self.trigger__responsiveness.setMaximum(1.0)
|
|
||||||
self.trigger__responsiveness.setSingleStep(0.1)
|
|
||||||
|
|
||||||
with add_grid_col(
|
|
||||||
s,
|
|
||||||
tr("Mean Responsiveness"),
|
|
||||||
BoundDoubleSpinBox,
|
|
||||||
name="trigger__mean_responsiveness",
|
|
||||||
) as w: # type: BoundDoubleSpinBox
|
|
||||||
w.setMaximum(1.0)
|
|
||||||
w.setSingleStep(0.1)
|
|
||||||
|
|
||||||
with append_widget(s, HLine):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Bottom row
|
|
||||||
with append_widget(s, QGridLayout):
|
|
||||||
with add_grid_col(s, BoundCheckBox, Both) as (
|
|
||||||
self.trigger__pitch_tracking
|
|
||||||
):
|
|
||||||
assert isinstance(self.trigger__pitch_tracking, QWidget)
|
|
||||||
|
|
||||||
with add_grid_col(
|
with add_grid_col(
|
||||||
s, tr("Post Trigger"), TypeComboBox
|
s, tr("Post Trigger"), TypeComboBox
|
||||||
) as self.trigger__post_trigger:
|
) as self.trigger__post_trigger:
|
||||||
|
@ -423,9 +435,7 @@ class MainWindow(QWidget):
|
||||||
self.render__res_divisorL.setText(tr("Resolution Divisor"))
|
self.render__res_divisorL.setText(tr("Resolution Divisor"))
|
||||||
self.master_audio.setText(tr("/"))
|
self.master_audio.setText(tr("/"))
|
||||||
self.master_audio_browse.setText(tr("&Browse..."))
|
self.master_audio_browse.setText(tr("&Browse..."))
|
||||||
self.optionTrigger.setTitle(tr("Trigger"))
|
|
||||||
self.trigger__edge_strengthL.setText(tr("Edge Strength"))
|
self.trigger__edge_strengthL.setText(tr("Edge Strength"))
|
||||||
self.trigger__responsivenessL.setText(tr("Responsiveness"))
|
|
||||||
self.trigger__pitch_tracking.setText(tr("Pitch Tracking"))
|
self.trigger__pitch_tracking.setText(tr("Pitch Tracking"))
|
||||||
self.trigger__edge_directionL.setText(tr("Edge Direction"))
|
self.trigger__edge_directionL.setText(tr("Edge Direction"))
|
||||||
|
|
||||||
|
|
|
@ -13,20 +13,39 @@ SomeQW = TypeVar("SomeQW", bound=QWidget)
|
||||||
WidgetOrLayout = TypeVar("WidgetOrLayout", bound=Union[QWidget, QLayout])
|
WidgetOrLayout = TypeVar("WidgetOrLayout", bound=Union[QWidget, QLayout])
|
||||||
|
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# React-style component layouts
|
||||||
|
# @singledispatch
|
||||||
|
# new_widget_or_layout(type)
|
||||||
|
# LayoutStack.push(instance)
|
||||||
|
|
||||||
|
# Like HTML document.createElement()
|
||||||
def new_widget_or_layout(
|
def new_widget_or_layout(
|
||||||
item_type: Union[Type[WidgetOrLayout], str], parent: QWidget
|
item_type: Union[Type[WidgetOrLayout], str], parent: QWidget, attributes=None
|
||||||
) -> WidgetOrLayout:
|
) -> WidgetOrLayout:
|
||||||
"""Creates a widget or layout, for insertion into an existing layout.
|
"""Creates a widget or layout, for insertion into an existing layout.
|
||||||
Do NOT use for filling a widget with a layout!"""
|
Do NOT use for filling a widget with a layout!"""
|
||||||
|
|
||||||
|
if attributes is None:
|
||||||
|
attributes = {}
|
||||||
|
|
||||||
if isinstance(item_type, str):
|
if isinstance(item_type, str):
|
||||||
return QLabel(item_type, parent)
|
item = QLabel(item_type, parent)
|
||||||
elif issubclass(item_type, QWidget):
|
elif issubclass(item_type, QWidget):
|
||||||
return item_type(parent)
|
item = item_type(parent)
|
||||||
else:
|
else:
|
||||||
assert issubclass(item_type, QLayout)
|
assert issubclass(item_type, QLayout)
|
||||||
# new_widget_or_layout is used to add sublayouts, which do NOT have a parent.
|
# new_widget_or_layout is used to add sublayouts, which do NOT have a parent.
|
||||||
# Only widgets' root layouts have parents.
|
# Only widgets' root layouts have parents.
|
||||||
return item_type(None)
|
item = item_type(None)
|
||||||
|
|
||||||
|
if "name" in attributes:
|
||||||
|
item.setObjectName(attributes.pop("name"))
|
||||||
|
|
||||||
|
for key, value in attributes.items():
|
||||||
|
qt_setattr(item, key, value)
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
|
|
||||||
@attr.dataclass
|
@attr.dataclass
|
||||||
|
@ -89,21 +108,24 @@ def assert_peek(stack: LayoutStack, cls):
|
||||||
assert isinstance(stack.widget, cls)
|
assert isinstance(stack.widget, cls)
|
||||||
|
|
||||||
|
|
||||||
def central_widget(stack: LayoutStack, widget_type: Type[SomeQW] = QWidget):
|
def central_widget(stack: LayoutStack, widget_type: Type[SomeQW] = QWidget, **kwargs):
|
||||||
assert_peek(stack, QMainWindow)
|
assert_peek(stack, QMainWindow)
|
||||||
# do NOT orphan=True
|
# do NOT orphan=True
|
||||||
return _new_widget(stack, widget_type, exit_action="setCentralWidget")
|
return _new_widget(stack, widget_type, exit_action="setCentralWidget", **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def orphan_widget(stack: LayoutStack, widget_type: Type[SomeQW] = QWidget):
|
def orphan_widget(stack: LayoutStack, widget_type: Type[SomeQW] = QWidget, **kwargs):
|
||||||
return _new_widget(stack, widget_type, orphan=True)
|
return _new_widget(stack, widget_type, orphan=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def append_widget(
|
def append_widget(
|
||||||
stack: LayoutStack, item_type: Type[WidgetOrLayout], layout_args: list = []
|
stack: LayoutStack,
|
||||||
|
item_type: Type[WidgetOrLayout],
|
||||||
|
layout_args: list = [],
|
||||||
|
**kwargs,
|
||||||
) -> ctx[WidgetOrLayout]:
|
) -> ctx[WidgetOrLayout]:
|
||||||
with _new_widget(stack, item_type) as item:
|
with _new_widget(stack, item_type, **kwargs) as item:
|
||||||
yield item
|
yield item
|
||||||
_insert_widget_or_layout(stack.layout, item, *layout_args)
|
_insert_widget_or_layout(stack.layout, item, *layout_args)
|
||||||
|
|
||||||
|
@ -152,6 +174,9 @@ def _new_widget(
|
||||||
item_type: Type[WidgetOrLayout],
|
item_type: Type[WidgetOrLayout],
|
||||||
orphan=False,
|
orphan=False,
|
||||||
exit_action: Union[Callable[[Any, Any], Any], str] = "",
|
exit_action: Union[Callable[[Any, Any], Any], str] = "",
|
||||||
|
*,
|
||||||
|
layout: Optional[Type[QLayout]] = None,
|
||||||
|
**kwargs,
|
||||||
) -> ctx[WidgetOrLayout]:
|
) -> ctx[WidgetOrLayout]:
|
||||||
"""
|
"""
|
||||||
- Constructs item_type using parent.
|
- Constructs item_type using parent.
|
||||||
|
@ -163,7 +188,9 @@ def _new_widget(
|
||||||
else:
|
else:
|
||||||
parent = None
|
parent = None
|
||||||
|
|
||||||
with stack.push(new_widget_or_layout(item_type, parent)) as item:
|
with stack.push(new_widget_or_layout(item_type, parent, kwargs)) as item:
|
||||||
|
if layout:
|
||||||
|
set_layout(stack, layout)
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
real_parent = stack.widget
|
real_parent = stack.widget
|
||||||
|
@ -173,6 +200,11 @@ def _new_widget(
|
||||||
getattr(real_parent, exit_action)(item)
|
getattr(real_parent, exit_action)(item)
|
||||||
|
|
||||||
|
|
||||||
|
def qt_setattr(obj, key: str, value) -> None:
|
||||||
|
key = "set" + key[0].capitalize() + key[1:]
|
||||||
|
getattr(obj, key)(value)
|
||||||
|
|
||||||
|
|
||||||
def append_stretch(stack: LayoutStack):
|
def append_stretch(stack: LayoutStack):
|
||||||
cast(QBoxLayout, stack.layout).addStretch()
|
cast(QBoxLayout, stack.layout).addStretch()
|
||||||
|
|
||||||
|
@ -191,21 +223,23 @@ Both = _Both()
|
||||||
|
|
||||||
def widget_pair_inserter(append_widgets: Callable):
|
def widget_pair_inserter(append_widgets: Callable):
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def add_row_col(stack: LayoutStack, left_type, right_type, *, name=None):
|
def add_row_col(stack: LayoutStack, left_type, right_type, *, name=None, **kwargs):
|
||||||
parent = stack.widget
|
parent = stack.widget
|
||||||
left = new_widget_or_layout(left_type, parent)
|
|
||||||
left_is_label = isinstance(left, QLabel)
|
|
||||||
|
|
||||||
if right_type is Both:
|
if right_type is Both:
|
||||||
|
left = new_widget_or_layout(left_type, parent, kwargs)
|
||||||
right = Both
|
right = Both
|
||||||
push = left
|
push = left
|
||||||
else:
|
else:
|
||||||
right = new_widget_or_layout(right_type, parent)
|
left = new_widget_or_layout(left_type, parent)
|
||||||
|
right = new_widget_or_layout(right_type, parent, kwargs)
|
||||||
push = right
|
push = right
|
||||||
|
|
||||||
if name:
|
if name:
|
||||||
(right or left).setObjectName(name)
|
(right or left).setObjectName(name)
|
||||||
|
|
||||||
|
left_is_label = isinstance(left, QLabel)
|
||||||
|
|
||||||
with stack.push(push):
|
with stack.push(push):
|
||||||
if right is Both:
|
if right is Both:
|
||||||
yield left
|
yield left
|
||||||
|
|
Ładowanie…
Reference in New Issue