diff --git a/src/buildable/live_set.py b/src/buildable/live_set.py index 5c64e09..a98d8a3 100644 --- a/src/buildable/live_set.py +++ b/src/buildable/live_set.py @@ -643,6 +643,39 @@ def view_state_sesstion_track_width(self) -> _Element: return _presence(self.element.find("ViewStateSesstionTrackWidth")) +class AutomationLane(ElementObject): + TAG = "AutomationLane" + + @xml_property(attrib="Value", property_type=int) + def is_content_selected_in_document(self) -> _Element: + return _presence(self.element.find("IsContentSelectedInDocument")) + + @xml_property(attrib="Value", property_type=int) + def lane_height(self) -> _Element: + return _presence(self.element.find("LaneHeight")) + + @xml_property(attrib="Value", property_type=int) + def selected_device(self) -> _Element: + return _presence(self.element.find("SelectedDevice")) + + @xml_property(attrib="Value", property_type=int) + def selected_envelope(self) -> _Element: + return _presence(self.element.find("SelectedEnvelope")) + + +class AutomationLanes(ElementObject): + TAG = "AutomationLanes" + + def are_additional_automation_lanes_folded(self) -> _Element: + return _presence(self.element.find("AreAdditionalAutomationLanesFolded")) + + @property + def automation_lanes(self) -> Sequence[AutomationLane]: + # There's an inner AutomationLanes tag which contains the actual lane objects. + automation_lanes_child = _presence(self.element.find("AutomationLanes")) + return tuple(AutomationLane(el) for el in automation_lanes_child) + + class DeviceChain(ElementObject): TAG = "DeviceChain" @@ -654,6 +687,10 @@ def audio_input_routing(self) -> _Element: def audio_output_routing(self) -> _Element: return self.element + @child_element_object_property(property_type=AutomationLanes) + def automation_lanes(self) -> _Element: + return self.element + @child_element_object_property(property_type=MidiInputRouting) def midi_input_routing(self) -> _Element: return self.element @@ -886,6 +923,10 @@ def chooser_bar(self) -> _Element: """Selector for arrangment (0) or session (1) view.""" return _presence(self._element.find("ChooserBar")) + @xml_property(attrib="Value", property_type=int) + def highlighted_track_index(self) -> _Element: + return _presence(self._element.find("HighlightedTrackIndex")) + @xml_property(attrib="Value", property_type=bool) def view_state_main_window_clip_detail_open(self) -> _Element: return _presence(self._element.find("ViewStateMainWindowClipDetailOpen")) diff --git a/tests/test_live_set.py b/tests/test_live_set.py index 5b79081..ccae0bd 100644 --- a/tests/test_live_set.py +++ b/tests/test_live_set.py @@ -735,7 +735,11 @@ def test_view_properties(live_12_default_set: pathlib.Path): for track in (*live_set.primary_tracks, *live_set.return_tracks): track_width = track.device_chain.mixer.view_state_sesstion_track_width - assert track_width == 93, f"Unexpected track_width value: {track_width}" + assert track_width == 93, f"Unexpected track width: {track_width}" + + for track in live_set.primary_tracks: + track_height = track.device_chain.automation_lanes.automation_lanes[0].lane_height + assert track_height == 68, f"Unexpected track height: {track_height}" # Change one property and make sure it gets saved. live_set.chooser_bar = LiveSet.CHOOSER_BAR_ARRANGEMENT