Browse Source

Better undo for measures with mods

master
Nils 1 year ago
parent
commit
1ae824f564
  1. 52
      engine/api.py
  2. 6
      engine/track.py

52
engine/api.py

@ -737,33 +737,57 @@ def _setTrackStructure(trackId, structure, undoMessage):
callbacks._trackStructureChanged(track)
def _removeMeasureModificationsWithUndo(trackId, position):
"""Must be run in a history sequence context manager!"""
track = session.data.trackById(trackId)
if position in track.whichPatternsAreScaleTransposed:
setSwitchScaleTranspose(trackId, position, 0) #set to default value. track export will remove the value from the data
if position in track.whichPatternsAreHalftoneTransposed:
setSwitchHalftoneTranspose(trackId, position, 0) #set to default value. track export will remove the value from the data
if position in track.whichPatternsAreStepDelayed:
setSwitchStepDelay(trackId, position, 0) #set to default value. track export will remove the value from the data
if position in track.whichPatternsHaveAugmentationFactor:
setSwitchAugmentationsFactor(trackId, position, 1.0) #set to default value. track export will remove the value from the data
def setSwitches(trackId, setOfPositions, newBool):
"""Used in the GUI to select multiple switches in a row by dragging the mouse"""
track = session.data.trackById(trackId)
if not track: return
session.history.register(lambda tr=trackId, v=track.structure.copy(): _setTrackStructure(trackId, v, "Set Measures"), descriptionString="Set Measures")
with session.history.sequence("Set Measures"):
session.history.register(lambda tr=trackId, v=track.structure.copy(): _setTrackStructure(trackId, v, "Set Measures"), descriptionString="Set Measures")
if newBool:
track.structure = track.structure.union(setOfPositions) #merge: add setOfPositions to the existing one
else:
track.structure = track.structure.difference(setOfPositions) #replace: remove everything from setOfPositions that is in the existing one, ignore entries from setOfPositions not in existing.
for position in setOfPositions:
_removeMeasureModificationsWithUndo(trackId, position)
if newBool:
track.structure = track.structure.union(setOfPositions) #merge: add setOfPositions to the existing one
else:
track.structure = track.structure.difference(setOfPositions) #replace: remove everything from setOfPositions that is in the existing one, ignore entries from setOfPositions not in existing.
track.buildTrack()
updatePlayback()
callbacks._trackStructureChanged(track)
def setSwitch(trackId, position, newBool):
"""e.g. for GUI Single click operations. Switch on and off a measure"""
track = session.data.trackById(trackId)
if not track: return
session.history.register(lambda trId=trackId, v=track.structure.copy(): _setTrackStructure(trId, v, "Set Measures"), descriptionString="Set Measures")
with session.history.sequence("Set Measures"):
session.history.register(lambda trId=trackId, v=track.structure.copy(): _setTrackStructure(trId, v, "Set Measures"), descriptionString="Set Measures")
if newBool:
if position in track.structure: return
track.structure.add(position)
else:
if not position in track.structure: return
track.structure.remove(position)
_removeMeasureModificationsWithUndo(trackId, position)
if newBool:
if position in track.structure: return
track.structure.add(position)
else:
if not position in track.structure: return
track.structure.remove(position)
track.buildTrack()
updatePlayback()
callbacks._trackStructureChanged(track)
@ -948,7 +972,6 @@ def _registerHistoryWholeTrackSwitches(track):
It assumes that it runs inside this context:
with session.history.sequence("asdasd"):
"""
print ("reg all", track)
trackId = id(track)
session.history.register(lambda trId=trackId, v=track.patternLengthMultiplicator: setTrackPatternLengthMultiplicator(trId, v), descriptionString="Pattern Multiplier")
session.history.register(lambda trId=trackId, v=track.structure.copy(): _setTrackStructure(trId, v, "Change Group"), descriptionString="Change Group")
@ -956,7 +979,6 @@ def _registerHistoryWholeTrackSwitches(track):
session.history.register(lambda trId=trackId, v=track.whichPatternsAreHalftoneTransposed.copy(): _setSwitchHalftoneTranspose(trId, v), descriptionString="Set Half Tone Shift")
session.history.register(lambda trId=trackId, v=track.whichPatternsAreStepDelayed.copy(): _setSwitchStepDelay(trId, v), descriptionString="Set Step Delay")
session.history.register(lambda trId=trackId, v=track.whichPatternsHaveAugmentationFactor.copy(): _setSwitchAugmentationsFactor(trId, v), descriptionString="Set Augmentation Factor")
print ("reg done")
def insertSilence(howMany:int, beforeMeasureNumber:int):
"""Insert empty measures into all tracks.
@ -1238,7 +1260,7 @@ def setStep(trackId, stepExportDict):
callbacks._stepChanged(track, stepExportDict)
def removeStep(trackId, index, pitch):
"""Reverse of setStep"""
"""Reverse of setStep. e.g. GUI-Click on an existing step."""
track = session.data.trackById(trackId)
if not track: return
session.history.register(lambda trId=trackId, v=track.pattern.copyData(): setPattern(trId, v, "Remove Step"), descriptionString="Remove Step")

6
engine/track.py

@ -112,9 +112,9 @@ class Track(object): #injection at the bottom of this file!
assert ourCalfboxTrack, (ourCalfboxTrack, self, self.group, self.parentData, self.sequencerInterface)
#First clean all modifications from the default value.
#We test for k in self.structure to not have modifications for measures that will be switched on later
#TODO: Can this possibly lead to a race condition where we load modifications first and then load the structure, which results in the mods getting perma-deleted here. e.g. we could not set default value in init, even for testing purposes.
#TODO: Yes, this happened with undo. every {comprehension} had a "and if k in self.structure" at the end. We took that out without remembering what that was for.
#We test for k in self.structure to not have modifications for measures that will be switched on later. This way when you deactivate a measure it will delete modifications. However, that was inconvenient. See below:
#Can this possibly lead to a race condition where we load modifications first and then load the structure, which results in the mods getting perma-deleted here. e.g. we could not set default value in init, even for testing purposes.
#Yes, this happened with undo. every {comprehension} had a "and if k in self.structure" at the end. We took that out without remembering what that was for.
self.whichPatternsAreScaleTransposed = {k:v for k,v in self.whichPatternsAreScaleTransposed.items() if v!=0}
self.whichPatternsAreHalftoneTransposed = {k:v for k,v in self.whichPatternsAreHalftoneTransposed.items() if v!=0}
self.whichPatternsAreStepDelayed = {k:v for k,v in self.whichPatternsAreStepDelayed.items() if v!=0}

Loading…
Cancel
Save