sonist-gtk/usr/lib/sonist/ui/timebar.py

92 lines
2.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2023-08-23 20:36:52 +08:00
import gi, threading
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject
def time_to_str(stamp = 0):
m = stamp // 60
s = stamp % 60
if m < 10:
m = f"0{m}"
if s < 10:
s = f"0{s}"
return f"{m}:{s}"
2023-08-24 18:21:45 +08:00
class Slider(Gtk.Scale):
def __init__(self, width = 256, height = 5):
Gtk.Scale.__init__(self)
self.set_name('Slider')
self.set_range(0, 100)
self.set_size_request(width, height)
self.set_draw_value(False)
class Timebar(Gtk.Fixed):
__gsignals__ = {
'seeked': (GObject.SignalFlags.RUN_FIRST, None, (float,))
}
def __init__(self):
Gtk.Fixed.__init__(self)
2023-08-23 20:36:52 +08:00
self.timer = None
self.pending = False
self._duration = 0
self._time = 0
self.slider = Slider(272)
self.curr = Gtk.Label()
self.duration = Gtk.Label()
2023-08-22 20:43:40 +08:00
self.curr.set_name('text')
2023-08-24 17:04:41 +08:00
self.curr.set_selectable(False)
self.duration.set_name('text')
self.duration.set_selectable(False)
self.duration.set_justify(Gtk.Justification.RIGHT)
self.duration.set_xalign(1)
2023-08-23 20:36:52 +08:00
self.slider.connect('change-value', self.debounce)
self.slider.set_sensitive(False)
self.put(self.curr, 3, 0)
self.put(self.duration, 233, 0)
self.put(self.slider, 0, 12)
def update_time(self, curr = 0, duration = 0):
self._duration = duration
self._time = curr
2023-08-23 20:36:52 +08:00
self.slider.set_sensitive(duration > 0)
if duration == 0:
self.curr.set_text('')
self.duration.set_text('')
self.slider.set_value(0)
else:
progress = curr * 100 / duration
self.curr.set_text(time_to_str(curr))
self.duration.set_text(time_to_str(duration))
# 优化拖拽进度时的更新
if not self.pending:
self.slider.set_value(progress)
def on_timeupdate(self):
self.pending = False
p = self.slider.get_value()
time = p * self._duration / 100
self.emit('seeked', time)
2023-08-23 20:36:52 +08:00
def debounce(self, slider, a, b):
if self.timer is not None:
self.timer.cancel()
self.pending = True
self.timer = threading.Timer(0.2, self.on_timeupdate)
self.timer.start()