~comcloudway/melon

a92077c0f5aff27a1db2939e920c9dfd9ae1020e — Jakob Meier 6 months ago 8c2b75f
add multi tap seek gesture
1 files changed, 44 insertions(+), 18 deletions(-)

M melon/widgets/player.py
M melon/widgets/player.py => melon/widgets/player.py +44 -18
@@ 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