ffcb
This commit is contained in:
@@ -2,6 +2,7 @@ import click, re
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from textual import events
|
from textual import events
|
||||||
|
from textual.css.query import NoMatches
|
||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
from textual.widgets import Header, Footer, Static, Button, Input, DataTable, TextArea
|
from textual.widgets import Header, Footer, Static, Button, Input, DataTable, TextArea
|
||||||
from textual.containers import Grid
|
from textual.containers import Grid
|
||||||
@@ -153,6 +154,13 @@ class PatternDetailsScreen(Screen):
|
|||||||
|
|
||||||
|
|
||||||
def updateTracks(self):
|
def updateTracks(self):
|
||||||
|
selectedTrack = self.getSelectedTrackDescriptor()
|
||||||
|
selectedTrackIndex = (
|
||||||
|
self._track_row_index(selectedTrack)
|
||||||
|
if selectedTrack is not None
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
selectedCursorColumn = getattr(self.tracksTable.cursor_coordinate, "column", 0)
|
||||||
|
|
||||||
self.tracksTable.clear()
|
self.tracksTable.clear()
|
||||||
self.__trackRowData = {}
|
self.__trackRowData = {}
|
||||||
@@ -160,6 +168,7 @@ class PatternDetailsScreen(Screen):
|
|||||||
tracks = self.getCurrentTrackDescriptors()
|
tracks = self.getCurrentTrackDescriptors()
|
||||||
|
|
||||||
typeCounter = {}
|
typeCounter = {}
|
||||||
|
restoredRowIndex = None
|
||||||
|
|
||||||
td: TrackDescriptor
|
td: TrackDescriptor
|
||||||
for td in tracks:
|
for td in tracks:
|
||||||
@@ -189,9 +198,72 @@ class PatternDetailsScreen(Screen):
|
|||||||
|
|
||||||
row_key = self.tracksTable.add_row(*map(str, row))
|
row_key = self.tracksTable.add_row(*map(str, row))
|
||||||
self.__trackRowData[row_key] = td
|
self.__trackRowData[row_key] = td
|
||||||
|
if (
|
||||||
|
selectedTrack is not None
|
||||||
|
and self._descriptor_refs_same_track(td, selectedTrack)
|
||||||
|
):
|
||||||
|
restoredRowIndex = len(self.__trackRowData) - 1
|
||||||
|
|
||||||
typeCounter[trackType] += 1
|
typeCounter[trackType] += 1
|
||||||
|
|
||||||
|
if restoredRowIndex is None and selectedTrackIndex is not None and self.__trackRowData:
|
||||||
|
restoredRowIndex = min(selectedTrackIndex, len(self.__trackRowData) - 1)
|
||||||
|
|
||||||
|
if restoredRowIndex is not None:
|
||||||
|
self.tracksTable.move_cursor(
|
||||||
|
row=restoredRowIndex,
|
||||||
|
column=selectedCursorColumn,
|
||||||
|
animate=False,
|
||||||
|
scroll=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.updateTrackDropButtonState()
|
||||||
|
|
||||||
|
def _track_row_index(self, trackDescriptor: TrackDescriptor | None):
|
||||||
|
if trackDescriptor is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for rowIndex, descriptor in enumerate(self.__trackRowData.values()):
|
||||||
|
if self._descriptor_refs_same_track(descriptor, trackDescriptor):
|
||||||
|
return rowIndex
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _descriptor_refs_same_track(
|
||||||
|
self,
|
||||||
|
descriptor: TrackDescriptor,
|
||||||
|
otherDescriptor: TrackDescriptor,
|
||||||
|
) -> bool:
|
||||||
|
if descriptor.getId() != -1 and otherDescriptor.getId() != -1:
|
||||||
|
return descriptor.getId() == otherDescriptor.getId()
|
||||||
|
|
||||||
|
return (
|
||||||
|
descriptor.getPatternId() == otherDescriptor.getPatternId()
|
||||||
|
and descriptor.getIndex() == otherDescriptor.getIndex()
|
||||||
|
and descriptor.getSubIndex() == otherDescriptor.getSubIndex()
|
||||||
|
and descriptor.getType() == otherDescriptor.getType()
|
||||||
|
)
|
||||||
|
|
||||||
|
def updateTrackDropButtonState(self):
|
||||||
|
try:
|
||||||
|
button = self.query_one("#button_toggle_track_drop", Button)
|
||||||
|
except (NoMatches, AttributeError):
|
||||||
|
return
|
||||||
|
|
||||||
|
selectedTrack = self.getSelectedTrackDescriptor()
|
||||||
|
button.disabled = selectedTrack is None
|
||||||
|
button.variant = (
|
||||||
|
"warning"
|
||||||
|
if selectedTrack is not None and selectedTrack.isDropped()
|
||||||
|
else "default"
|
||||||
|
)
|
||||||
|
|
||||||
|
def on_data_table_row_highlighted(
|
||||||
|
self,
|
||||||
|
event: DataTable.RowHighlighted,
|
||||||
|
) -> None:
|
||||||
|
if event.data_table.id == "tracks_table":
|
||||||
|
self.updateTrackDropButtonState()
|
||||||
|
|
||||||
|
|
||||||
def getCurrentTrackDescriptors(self) -> List[TrackDescriptor]:
|
def getCurrentTrackDescriptors(self) -> List[TrackDescriptor]:
|
||||||
if self.__pattern is not None:
|
if self.__pattern is not None:
|
||||||
@@ -482,7 +554,7 @@ class PatternDetailsScreen(Screen):
|
|||||||
yield Static(t("Streams"))
|
yield Static(t("Streams"))
|
||||||
yield Button(t("Add"), id="button_add_track")
|
yield Button(t("Add"), id="button_add_track")
|
||||||
yield Button(t("Edit"), id="button_edit_track")
|
yield Button(t("Edit"), id="button_edit_track")
|
||||||
yield Button(t("Drop / Undrop"), id="button_toggle_track_drop")
|
yield Button(t("Drop"), id="button_toggle_track_drop")
|
||||||
|
|
||||||
yield Static(" ")
|
yield Static(" ")
|
||||||
yield Button(t("Up"), id="button_track_up")
|
yield Button(t("Up"), id="button_track_up")
|
||||||
|
|||||||
@@ -76,6 +76,12 @@ class FakeTagTable:
|
|||||||
def select_row(self, row_key):
|
def select_row(self, row_key):
|
||||||
self._selected_row_key = row_key
|
self._selected_row_key = row_key
|
||||||
|
|
||||||
|
def move_cursor(self, *, row=None, column=None, animate=False, scroll=True):
|
||||||
|
if row is not None and self._row_order:
|
||||||
|
self._selected_row_key = self._row_order[int(row)]
|
||||||
|
if column is not None:
|
||||||
|
self.cursor_coordinate = (self.cursor_coordinate[0], int(column))
|
||||||
|
|
||||||
def get_row_index(self, row_key):
|
def get_row_index(self, row_key):
|
||||||
return self._row_order.index(row_key)
|
return self._row_order.index(row_key)
|
||||||
|
|
||||||
@@ -110,6 +116,12 @@ class FakeValueWidget:
|
|||||||
self.disabled = False
|
self.disabled = False
|
||||||
|
|
||||||
|
|
||||||
|
class FakeButtonWidget:
|
||||||
|
def __init__(self):
|
||||||
|
self.disabled = False
|
||||||
|
self.variant = "default"
|
||||||
|
|
||||||
|
|
||||||
class FakeInputWidget:
|
class FakeInputWidget:
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = value
|
self.value = value
|
||||||
@@ -379,6 +391,7 @@ class TagTableScreenStateTests(unittest.TestCase):
|
|||||||
def test_pattern_details_screen_toggles_draft_track_drop_state(self):
|
def test_pattern_details_screen_toggles_draft_track_drop_state(self):
|
||||||
first_track = make_track_descriptor(0, 0, TrackType.VIDEO)
|
first_track = make_track_descriptor(0, 0, TrackType.VIDEO)
|
||||||
second_track = make_track_descriptor(1, 0, TrackType.SUBTITLE)
|
second_track = make_track_descriptor(1, 0, TrackType.SUBTITLE)
|
||||||
|
drop_button = FakeButtonWidget()
|
||||||
|
|
||||||
screen = object.__new__(PatternDetailsScreen)
|
screen = object.__new__(PatternDetailsScreen)
|
||||||
screen.context = {"logger": get_ffx_logger()}
|
screen.context = {"logger": get_ffx_logger()}
|
||||||
@@ -386,6 +399,7 @@ class TagTableScreenStateTests(unittest.TestCase):
|
|||||||
screen._PatternDetailsScreen__draftTracks = [first_track, second_track]
|
screen._PatternDetailsScreen__draftTracks = [first_track, second_track]
|
||||||
screen._PatternDetailsScreen__pattern = None
|
screen._PatternDetailsScreen__pattern = None
|
||||||
screen._PatternDetailsScreen__trackRowData = {}
|
screen._PatternDetailsScreen__trackRowData = {}
|
||||||
|
screen.query_one = lambda selector, _widget_type=None: drop_button
|
||||||
|
|
||||||
screen.updateTracks()
|
screen.updateTracks()
|
||||||
screen.tracksTable.select_row("row-1")
|
screen.tracksTable.select_row("row-1")
|
||||||
@@ -395,6 +409,39 @@ class TagTableScreenStateTests(unittest.TestCase):
|
|||||||
self.assertFalse(first_track.isDropped())
|
self.assertFalse(first_track.isDropped())
|
||||||
self.assertTrue(second_track.isDropped())
|
self.assertTrue(second_track.isDropped())
|
||||||
self.assertEqual("Ja", list(screen.tracksTable.rows.values())[1][9])
|
self.assertEqual("Ja", list(screen.tracksTable.rows.values())[1][9])
|
||||||
|
self.assertIs(second_track, screen.getSelectedTrackDescriptor())
|
||||||
|
self.assertEqual("warning", drop_button.variant)
|
||||||
|
|
||||||
|
def test_pattern_details_screen_updates_drop_button_for_selected_track(self):
|
||||||
|
first_track = make_track_descriptor(0, 0, TrackType.VIDEO)
|
||||||
|
second_track = make_track_descriptor(
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
TrackType.SUBTITLE,
|
||||||
|
dropped=True,
|
||||||
|
)
|
||||||
|
drop_button = FakeButtonWidget()
|
||||||
|
|
||||||
|
screen = object.__new__(PatternDetailsScreen)
|
||||||
|
screen.tracksTable = FakeTagTable()
|
||||||
|
screen._PatternDetailsScreen__draftTracks = [first_track, second_track]
|
||||||
|
screen._PatternDetailsScreen__pattern = None
|
||||||
|
screen._PatternDetailsScreen__trackRowData = {}
|
||||||
|
screen.query_one = lambda selector, _widget_type=None: drop_button
|
||||||
|
|
||||||
|
screen.updateTracks()
|
||||||
|
|
||||||
|
self.assertEqual("default", drop_button.variant)
|
||||||
|
|
||||||
|
screen.tracksTable.select_row("row-1")
|
||||||
|
screen.updateTrackDropButtonState()
|
||||||
|
|
||||||
|
self.assertEqual("warning", drop_button.variant)
|
||||||
|
|
||||||
|
screen.tracksTable.select_row("row-0")
|
||||||
|
screen.updateTrackDropButtonState()
|
||||||
|
|
||||||
|
self.assertEqual("default", drop_button.variant)
|
||||||
|
|
||||||
def test_pattern_details_screen_toggles_persisted_track_drop_state(self):
|
def test_pattern_details_screen_toggles_persisted_track_drop_state(self):
|
||||||
class _FakePattern:
|
class _FakePattern:
|
||||||
|
|||||||
Reference in New Issue
Block a user