feat: Audio tab drives timeline audio-mode; drag the band to set the extract region
This commit is contained in:
@@ -4533,6 +4533,7 @@ class MainWindow(QMainWindow):
|
|||||||
self._timeline.scan_region_resized.connect(self._on_scan_region_resized)
|
self._timeline.scan_region_resized.connect(self._on_scan_region_resized)
|
||||||
self._timeline.clip_count_delta.connect(self._change_clip_count)
|
self._timeline.clip_count_delta.connect(self._change_clip_count)
|
||||||
self._timeline.autoclip_requested.connect(self._autoclip)
|
self._timeline.autoclip_requested.connect(self._autoclip)
|
||||||
|
self._timeline.audio_region_changed.connect(self._on_wave_selection_changed)
|
||||||
|
|
||||||
self._lbl_file = QLabel("← Drop files onto the queue")
|
self._lbl_file = QLabel("← Drop files onto the queue")
|
||||||
self._lbl_file.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
self._lbl_file.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
@@ -5231,6 +5232,9 @@ class MainWindow(QMainWindow):
|
|||||||
panel._pinned = panel._deck_key in _deck_pinned
|
panel._pinned = panel._deck_key in _deck_pinned
|
||||||
self._refresh_deck_layout()
|
self._refresh_deck_layout()
|
||||||
|
|
||||||
|
# Sync timeline audio-mode to the current deck tab (Export default → off).
|
||||||
|
self._on_deck_tab_changed(self._control_deck.currentIndex())
|
||||||
|
|
||||||
# Defer the changelog modal so the window paints/interacts first.
|
# Defer the changelog modal so the window paints/interacts first.
|
||||||
QTimer.singleShot(120, self._show_changelog)
|
QTimer.singleShot(120, self._show_changelog)
|
||||||
|
|
||||||
@@ -5269,6 +5273,7 @@ class MainWindow(QMainWindow):
|
|||||||
deck.addTab(self._tab_audio, self._tab_audio._label)
|
deck.addTab(self._tab_audio, self._tab_audio._label)
|
||||||
self._control_deck = deck
|
self._control_deck = deck
|
||||||
deck.tabBar().pin_toggle_requested.connect(self._on_deck_pin_toggle)
|
deck.tabBar().pin_toggle_requested.connect(self._on_deck_pin_toggle)
|
||||||
|
deck.currentChanged.connect(self._on_deck_tab_changed)
|
||||||
|
|
||||||
# Side-by-side container (shown when 2+ panels are pinned), wrapped in a
|
# Side-by-side container (shown when 2+ panels are pinned), wrapped in a
|
||||||
# stack so the deck can swap between tabbed and split views.
|
# stack so the deck can swap between tabbed and split views.
|
||||||
@@ -7363,6 +7368,14 @@ class MainWindow(QMainWindow):
|
|||||||
self._wave.set_peaks(peaks(samples))
|
self._wave.set_peaks(peaks(samples))
|
||||||
return samples.size > 0
|
return samples.size > 0
|
||||||
|
|
||||||
|
def _on_deck_tab_changed(self, _idx: int) -> None:
|
||||||
|
if self._deck_loading:
|
||||||
|
return
|
||||||
|
is_audio = self._control_deck.currentWidget() is self._tab_audio
|
||||||
|
self._timeline.set_audio_mode(is_audio)
|
||||||
|
if is_audio and self._file_path:
|
||||||
|
self._update_audio_region() # ensure the band reflects cursor + length
|
||||||
|
|
||||||
def _on_wave_selection_changed(self, s: float, e: float) -> None:
|
def _on_wave_selection_changed(self, s: float, e: float) -> None:
|
||||||
if self._wave_syncing:
|
if self._wave_syncing:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -284,6 +284,9 @@ def test_timeline_audio_mode_flag(win):
|
|||||||
|
|
||||||
def test_timeline_audio_band_drag_move(win):
|
def test_timeline_audio_band_drag_move(win):
|
||||||
tl = win._timeline
|
tl = win._timeline
|
||||||
|
# The band is now wired to the window; fake a loaded file so the window's
|
||||||
|
# _update_audio_region keeps the region instead of clearing it on release.
|
||||||
|
win._file_path = "/x/v.mp4"
|
||||||
tl._duration = 20.0
|
tl._duration = 20.0
|
||||||
tl._view_start = 0.0; tl._view_span = 20.0 # full view
|
tl._view_start = 0.0; tl._view_span = 20.0 # full view
|
||||||
tl.resize(400, tl.height() or 80)
|
tl.resize(400, tl.height() or 80)
|
||||||
@@ -304,6 +307,8 @@ def test_timeline_audio_band_drag_move(win):
|
|||||||
|
|
||||||
def test_timeline_audio_band_resize_right(win):
|
def test_timeline_audio_band_resize_right(win):
|
||||||
tl = win._timeline
|
tl = win._timeline
|
||||||
|
# Fake a loaded file so the window keeps the region on release (see above).
|
||||||
|
win._file_path = "/x/v.mp4"
|
||||||
tl._duration = 20.0; tl._view_start = 0.0; tl._view_span = 20.0
|
tl._duration = 20.0; tl._view_start = 0.0; tl._view_span = 20.0
|
||||||
tl.resize(400, tl.height() or 80)
|
tl.resize(400, tl.height() or 80)
|
||||||
tl.set_audio_mode(True)
|
tl.set_audio_mode(True)
|
||||||
@@ -316,6 +321,22 @@ def test_timeline_audio_band_resize_right(win):
|
|||||||
tl.set_audio_mode(False)
|
tl.set_audio_mode(False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_timeline_audio_mode_follows_deck(win):
|
||||||
|
win._control_deck.setCurrentWidget(win._tab_audio)
|
||||||
|
assert win._timeline._audio_mode is True
|
||||||
|
win._control_deck.setCurrentWidget(win._tab_export)
|
||||||
|
assert win._timeline._audio_mode is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_timeline_audio_region_edit_syncs_cursor_length(win):
|
||||||
|
win._file_path = "/x/v.mp4"
|
||||||
|
win._cursor = 2.0
|
||||||
|
win._spn_audio_len.setValue(3.0)
|
||||||
|
win._timeline.audio_region_changed.emit(5.0, 9.0) # user dragged the band to [5,9]
|
||||||
|
assert win._cursor == 5.0
|
||||||
|
assert abs(win._spn_audio_len.value() - 4.0) < 1e-6
|
||||||
|
|
||||||
|
|
||||||
def test_audio_deck_tab_exists(win):
|
def test_audio_deck_tab_exists(win):
|
||||||
# The old "Scan" deck tab is now "Audio".
|
# The old "Scan" deck tab is now "Audio".
|
||||||
assert hasattr(win, "_tab_audio")
|
assert hasattr(win, "_tab_audio")
|
||||||
|
|||||||
Reference in New Issue
Block a user