From a92077c0f5aff27a1db2939e920c9dfd9ae1020e Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Sat, 16 Mar 2024 15:44:50 +0100 Subject: [PATCH] add multi tap seek gesture --- melon/widgets/player.py | 62 +++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/melon/widgets/player.py b/melon/widgets/player.py index 0375b6d..502d66e 100644 --- a/melon/widgets/player.py +++ b/melon/widgets/player.py @@ -6,6 +6,7 @@ gi.require_version('Gst', '1.0') from gi.repository import Gtk, Adw, WebKit, GLib, Gst from unidecode import unidecode from gettext import gettext as _ +from datetime import datetime from melon.servers import Stream from melon.widgets.iconbutton import IconButton @@ -235,7 +236,11 @@ class VideoPlayer(Gtk.Overlay): # also calls swipe for clicks (and on swipe end) # so we use this to handle the onclick event to toggle the controls (mobile) self.swipe_ctr.connect("swipe", self._end_swipe) - self.picture.add_controller(self.swipe_ctr) + self.add_controller(self.swipe_ctr) + # click handler + self.click_ctr = Gtk.GestureClick() + self.add_controller(self.click_ctr) + self.click_ctr.connect("pressed", lambda e,n, x,y :self._onclick(n, x,y)) # initialize volume & brightness self.change_brightness(self.brightness) @@ -272,6 +277,9 @@ class VideoPlayer(Gtk.Overlay): # randomly selected values to make it feel responsive fact = vel[2]/10000 fact = clamp(-0.2, fact, 0.2) + if abs(fact) < 0.01: + # little to no movement + return if bounds[1] >= right_bound: # volume control @@ -307,11 +315,6 @@ class VideoPlayer(Gtk.Overlay): self.brightness_overlay.set_opacity(1.0 - self.brightness) def _end_swipe(self, e, vx, vy): - # no swipe movement - # just a click - if vx==0.0 and vy == 0.0: - self._onclick() - return # hide overlay # always hide both overlays just to make sure self.brightness_display.hide() @@ -323,18 +326,41 @@ class VideoPlayer(Gtk.Overlay): self._schedule_hide_controls() _click_opened_controls = False - def _onclick(self): - # single click toggles focus - # because floats are a thing we can't use == - # however given that we switch between 0 and 1 - # we can use 0.9 or 0.1 as breakpoints - if self.controls.get_opacity() >= 0.9: - if self._click_opened_controls: - self._click_opened_controls = False - self._hide_controls(force=True) - else: - self._show_controls() - self._click_opened_controls = True + def _onclick(self, n, x, y): + if n==0: + # should never happen + return + if n == 1: + # single click toggles focus + # because floats are a thing we can't use == + # however given that we switch between 0 and 1 + # we can use 0.9 or 0.1 as breakpoints + if self.controls.get_opacity() >= 0.9: + if self._click_opened_controls: + self._click_opened_controls = False + self._hide_controls(force=True) + else: + self._show_controls() + self._click_opened_controls = True + return + + # douple tap triggers 10 second seek + # each additional tap seeks another 10 seconds + distance = (n-1) * 10 + width = self.picture.get_width() + left_bound = width*(2/5) + right_bound = width - left_bound + if x <= left_bound: + self.seek_backwards(distance) + elif x >= right_bound: + self.seek_forwards(distance) + + def seek(self, delta): + self.goto(self.position + delta) + def seek_forwards(self, delta=30): + self.seek(delta) + def seek_backwards(self, delta=30): + self.seek(-delta) def _update_quality_list(self): # TODO consider making this scrollable -- 2.38.5