from collections.abc import Callable from solo_tool.solo_tool import SoloTool def playPause(st: SoloTool) -> Callable[[], None]: def f(): if st.playing: st.pause() else: st.play() return f def songRelative(st: SoloTool, delta: int) -> Callable[[], None]: def f(): if st.song is None: st.song = 0 else: st.song += delta return f def restartOrPreviousSong(st: SoloTool, threshold: float) -> Callable[[], None]: def f(): if st.position < threshold and st.song > 0: st.song -= 1 else: st.position = 0.0 return f def songAbsolute(st: SoloTool, index: int, followUp: Callable[[], None]=None) -> Callable[[], None]: def f(): st.song = index if followUp is not None: followUp() return f def seekRelative(st: SoloTool, delta: float) -> Callable[[], None]: def f(): st.position += delta return f def seekAbsolute(st: SoloTool, delta: float) -> Callable[[], None]: def f(): st.position = delta return f def positionToKeyPoint(st: SoloTool) -> Callable[[], None]: def f(): st.keyPoint = st.position return f def keyPointAbsolute(st: SoloTool, kp: float) -> Callable[[], None]: def f(): st.keyPoint = kp return f def keyPointRelative(st: SoloTool, delta: int) -> Callable[[], None]: from bisect import bisect_right, bisect_left def f(): l = sorted(set(st.keyPoints + [st.keyPoint])) if delta > 0: pivot = bisect_right(l, st.keyPoint) - 1 elif delta < 0: pivot = bisect_left(l, st.keyPoint) else: return new = max(min(pivot + delta, len(l) - 1), 0) st.keyPoint = l[new] return f def rateAbsolute(st: SoloTool, value: float) -> Callable[[], None]: def f(): st.rate = value return f def rateRelative(st: SoloTool, delta: float) -> Callable[[], None]: def f(): st.rate += delta return f def volumeAbsolute(st: SoloTool, value: float) -> Callable[[], None]: def f(): st.volume = value return f