@@ -43,12 +43,29 @@ def update_items(self, items):
4343 for layer , fixtures in items .items ():
4444 self .mount (Static (f"Layer: [blue]{ self .app .get_layer_name (layer )} [/blue]" ))
4545
46- for fixture in fixtures :
47- self .mount (
48- Static (
49- f"[green]{ fixture .short_name } [/green] { f'IP Address: { fixture .ip_address } ' if fixture .ip_address else '' } { f'Universe: { fixture .universe } ' if fixture .universe else '' } { f'DMX: { fixture .address } ' if fixture .address else '' } "
50- )
51- )
46+ for index , fixture in enumerate (fixtures ):
47+ self .mount (MVRFixtureRow (layer , index , fixture ))
48+
49+
50+ class MVRFixtureRow (Horizontal ):
51+ def __init__ (self , layer_id , index , fixture ):
52+ super ().__init__ ()
53+ self .layer_id = layer_id
54+ self .index = index
55+ self .fixture = fixture
56+
57+ def compose (self ) -> ComposeResult :
58+ yield Button ("x" , classes = "remove_fixture" , variant = "error" )
59+ yield Static (
60+ f"[green]{ self .fixture .short_name } [/green] "
61+ f"{ f'IP Address: { self .fixture .ip_address } ' if self .fixture .ip_address else '' } "
62+ f"{ f'Universe: { self .fixture .universe } ' if self .fixture .universe else '' } "
63+ f"{ f'DMX: { self .fixture .address } ' if self .fixture .address else '' } "
64+ )
65+
66+ def on_button_pressed (self , event : Button .Pressed ) -> None :
67+ if "remove_fixture" in event .button .classes :
68+ self .app .remove_mvr_fixture (self .layer_id , self .index )
5269
5370
5471class GDTFMapping (VerticalScroll ):
@@ -238,6 +255,7 @@ def import_discovered(data):
238255
239256 self .mvr_display .update_items (self .mvr_fixtures )
240257 self .gdtf_mapping .update_items ()
258+ self ._update_save_button_state ()
241259
242260 self .push_screen (ArtNetScreen (), layer_selector )
243261
@@ -271,6 +289,32 @@ def get_layer_name(self, uuid):
271289 return layer_name
272290 return None
273291
292+ def remove_mvr_fixture (self , layer_id , index ) -> None :
293+ fixtures = self .mvr_fixtures .get (layer_id , [])
294+ if index < 0 or index >= len (fixtures ):
295+ return
296+ fixtures .pop (index )
297+ if not fixtures :
298+ self .mvr_fixtures .pop (layer_id , None )
299+ self ._cleanup_gdtf_map ()
300+ self .mvr_display .update_items (self .mvr_fixtures )
301+ self .gdtf_mapping .update_items ()
302+ self ._update_save_button_state ()
303+
304+ def _cleanup_gdtf_map (self ) -> None :
305+ active_fixtures = {
306+ fixture .short_name
307+ for layer in self .mvr_fixtures .values ()
308+ for fixture in layer
309+ }
310+ for name in list (self .gdtf_map .keys ()):
311+ if name not in active_fixtures :
312+ self .gdtf_map .pop (name , None )
313+
314+ def _update_save_button_state (self ) -> None :
315+ save_button = self .query_one ("#save_mvr" , Button )
316+ save_button .disabled = not any (self .mvr_fixtures .values ())
317+
274318 def _keyring_get (self , key ):
275319 if not keyring :
276320 return None
0 commit comments