mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 07:42:23 +02:00
Move event controllers to widget and add them to top revealer
This commit is contained in:
@@ -44,8 +44,8 @@ class ClapperCustomButton extends Gtk.Button
|
|||||||
if(!this.isFullscreen)
|
if(!this.isFullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const { player } = this.get_ancestor(Gtk.Grid);
|
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||||
player._setHideControlsTimeout();
|
clapperWidget._setHideControlsTimeout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
12
src/controls.js
vendored
12
src/controls.js
vendored
@@ -478,13 +478,13 @@ class ClapperControls extends Gtk.Box
|
|||||||
this.disconnect(this.realizeSignal);
|
this.disconnect(this.realizeSignal);
|
||||||
this.realizeSignal = null;
|
this.realizeSignal = null;
|
||||||
|
|
||||||
const { player } = this.get_ancestor(Gtk.Grid);
|
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||||
const scrollController = new Gtk.EventControllerScroll();
|
const scrollController = new Gtk.EventControllerScroll();
|
||||||
scrollController.set_flags(
|
scrollController.set_flags(
|
||||||
Gtk.EventControllerScrollFlags.VERTICAL
|
Gtk.EventControllerScrollFlags.VERTICAL
|
||||||
| Gtk.EventControllerScrollFlags.DISCRETE
|
| Gtk.EventControllerScrollFlags.DISCRETE
|
||||||
);
|
);
|
||||||
scrollController.connect('scroll', player._onScroll.bind(player));
|
scrollController.connect('scroll', clapperWidget._onScroll.bind(clapperWidget));
|
||||||
this.volumeButton.add_controller(scrollController);
|
this.volumeButton.add_controller(scrollController);
|
||||||
|
|
||||||
const initialVolume = (settings.get_string('volume-initial') === 'custom')
|
const initialVolume = (settings.get_string('volume-initial') === 'custom')
|
||||||
@@ -541,8 +541,8 @@ class ClapperControls extends Gtk.Box
|
|||||||
|
|
||||||
_onPositionScaleScroll(controller, dx, dy)
|
_onPositionScaleScroll(controller, dx, dy)
|
||||||
{
|
{
|
||||||
const { player } = this.get_ancestor(Gtk.Grid);
|
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||||
player._onScroll(controller, dx || dy, 0);
|
clapperWidget._onScroll(controller, dx || dy, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPositionScaleValueChanged(scale)
|
_onPositionScaleValueChanged(scale)
|
||||||
@@ -617,8 +617,8 @@ class ClapperControls extends Gtk.Box
|
|||||||
/* Only happens when navigating through controls panel */
|
/* Only happens when navigating through controls panel */
|
||||||
_onControlsKeyPressed(controller, keyval, keycode, state)
|
_onControlsKeyPressed(controller, keyval, keycode, state)
|
||||||
{
|
{
|
||||||
const { player } = this.get_ancestor(Gtk.Grid);
|
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||||
player._setHideControlsTimeout();
|
clapperWidget._setHideControlsTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onControlsKeyReleased(controller, keyval, keycode, state)
|
_onControlsKeyReleased(controller, keyval, keycode, state)
|
||||||
|
@@ -22,7 +22,7 @@ class ClapperHeaderBar extends HeaderBarBase
|
|||||||
clapperWidget.controlsRevealer.toggleReveal();
|
clapperWidget.controlsRevealer.toggleReveal();
|
||||||
|
|
||||||
/* Reset timer to not disappear during click */
|
/* Reset timer to not disappear during click */
|
||||||
clapperWidget.player._setHideControlsTimeout();
|
clapperWidget._setHideControlsTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onFullscreenButtonClicked()
|
_onFullscreenButtonClicked()
|
||||||
|
291
src/player.js
291
src/player.js
@@ -14,10 +14,7 @@ class ClapperPlayer extends PlayerBase
|
|||||||
{
|
{
|
||||||
super._init();
|
super._init();
|
||||||
|
|
||||||
this.cursorInPlayer = false;
|
|
||||||
this.seek_done = true;
|
this.seek_done = true;
|
||||||
this.dragAllowed = false;
|
|
||||||
this.isWidgetDragging = false;
|
|
||||||
this.doneStartup = false;
|
this.doneStartup = false;
|
||||||
this.needsFastSeekRestore = false;
|
this.needsFastSeekRestore = false;
|
||||||
|
|
||||||
@@ -25,54 +22,15 @@ class ClapperPlayer extends PlayerBase
|
|||||||
this.quitOnStop = false;
|
this.quitOnStop = false;
|
||||||
this.needsTocUpdate = true;
|
this.needsTocUpdate = true;
|
||||||
|
|
||||||
this.posX = 0;
|
|
||||||
this.posY = 0;
|
|
||||||
this.keyPressCount = 0;
|
this.keyPressCount = 0;
|
||||||
|
|
||||||
this._maxVolume = Misc.getLinearValue(Misc.maxVolume);
|
this._maxVolume = Misc.getLinearValue(Misc.maxVolume);
|
||||||
|
|
||||||
this._hideControlsTimeout = null;
|
|
||||||
this._updateTimeTimeout = null;
|
|
||||||
|
|
||||||
const clickGesture = new Gtk.GestureClick();
|
|
||||||
clickGesture.set_button(0);
|
|
||||||
clickGesture.connect('pressed', this._onWidgetPressed.bind(this));
|
|
||||||
this.widget.add_controller(clickGesture);
|
|
||||||
|
|
||||||
const dragGesture = new Gtk.GestureDrag();
|
|
||||||
dragGesture.connect('drag-update', this._onWidgetDragUpdate.bind(this));
|
|
||||||
this.widget.add_controller(dragGesture);
|
|
||||||
|
|
||||||
const swipeGesture = new Gtk.GestureSwipe({
|
|
||||||
touch_only: true,
|
|
||||||
});
|
|
||||||
swipeGesture.connect('swipe', this._onWidgetSwipe.bind(this));
|
|
||||||
swipeGesture.connect('update', this._onWidgetSwipeUpdate.bind(this));
|
|
||||||
this.widget.add_controller(swipeGesture);
|
|
||||||
|
|
||||||
const keyController = new Gtk.EventControllerKey();
|
const keyController = new Gtk.EventControllerKey();
|
||||||
keyController.connect('key-pressed', this._onWidgetKeyPressed.bind(this));
|
keyController.connect('key-pressed', this._onWidgetKeyPressed.bind(this));
|
||||||
keyController.connect('key-released', this._onWidgetKeyReleased.bind(this));
|
keyController.connect('key-released', this._onWidgetKeyReleased.bind(this));
|
||||||
this.widget.add_controller(keyController);
|
this.widget.add_controller(keyController);
|
||||||
|
|
||||||
const scrollController = new Gtk.EventControllerScroll();
|
|
||||||
scrollController.set_flags(Gtk.EventControllerScrollFlags.BOTH_AXES);
|
|
||||||
scrollController.connect('scroll', this._onScroll.bind(this));
|
|
||||||
this.widget.add_controller(scrollController);
|
|
||||||
|
|
||||||
const motionController = new Gtk.EventControllerMotion();
|
|
||||||
motionController.connect('enter', this._onWidgetEnter.bind(this));
|
|
||||||
motionController.connect('leave', this._onWidgetLeave.bind(this));
|
|
||||||
motionController.connect('motion', this._onWidgetMotion.bind(this));
|
|
||||||
this.widget.add_controller(motionController);
|
|
||||||
|
|
||||||
const dropTarget = new Gtk.DropTarget({
|
|
||||||
actions: Gdk.DragAction.COPY,
|
|
||||||
});
|
|
||||||
dropTarget.set_gtypes([GObject.TYPE_STRING]);
|
|
||||||
dropTarget.connect('drop', this._onDataDrop.bind(this));
|
|
||||||
this.widget.add_controller(dropTarget);
|
|
||||||
|
|
||||||
this.connect('state-changed', this._onStateChanged.bind(this));
|
this.connect('state-changed', this._onStateChanged.bind(this));
|
||||||
this.connect('uri-loaded', this._onUriLoaded.bind(this));
|
this.connect('uri-loaded', this._onUriLoaded.bind(this));
|
||||||
this.connect('end-of-stream', this._onStreamEnded.bind(this));
|
this.connect('end-of-stream', this._onStreamEnded.bind(this));
|
||||||
@@ -300,76 +258,6 @@ class ClapperPlayer extends PlayerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getIsSwipeOk(velocity, otherVelocity)
|
|
||||||
{
|
|
||||||
if(!velocity)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const absVel = Math.abs(velocity);
|
|
||||||
|
|
||||||
if(absVel < 20 || Math.abs(otherVelocity) * 1.5 >= absVel)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const clapperWidget = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
|
|
||||||
return clapperWidget.isFullscreenMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
_setHideControlsTimeout()
|
|
||||||
{
|
|
||||||
this._clearTimeout('hideControls');
|
|
||||||
this._hideControlsTimeout = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => {
|
|
||||||
this._hideControlsTimeout = null;
|
|
||||||
|
|
||||||
if(this.cursorInPlayer) {
|
|
||||||
const clapperWidget = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
const blankCursor = Gdk.Cursor.new_from_name('none', null);
|
|
||||||
|
|
||||||
this.widget.set_cursor(blankCursor);
|
|
||||||
clapperWidget.revealerTop.set_cursor(blankCursor);
|
|
||||||
|
|
||||||
if(clapperWidget.isFullscreenMode)
|
|
||||||
this._clearTimeout('updateTime');
|
|
||||||
|
|
||||||
clapperWidget.revealControls(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLib.SOURCE_REMOVE;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_setUpdateTimeInterval()
|
|
||||||
{
|
|
||||||
this._clearTimeout('updateTime');
|
|
||||||
|
|
||||||
const clapperWidget = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
const nextUpdate = clapperWidget.updateTime();
|
|
||||||
|
|
||||||
if(nextUpdate === null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._updateTimeTimeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, nextUpdate, () => {
|
|
||||||
this._updateTimeTimeout = null;
|
|
||||||
|
|
||||||
if(clapperWidget.isFullscreenMode)
|
|
||||||
this._setUpdateTimeInterval();
|
|
||||||
|
|
||||||
return GLib.SOURCE_REMOVE;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_clearTimeout(name)
|
|
||||||
{
|
|
||||||
if(!this[`_${name}Timeout`])
|
|
||||||
return;
|
|
||||||
|
|
||||||
GLib.source_remove(this[`_${name}Timeout`]);
|
|
||||||
this[`_${name}Timeout`] = null;
|
|
||||||
|
|
||||||
if(name === 'updateTime')
|
|
||||||
debug('cleared update time interval');
|
|
||||||
}
|
|
||||||
|
|
||||||
_performCloseCleanup(window)
|
_performCloseCleanup(window)
|
||||||
{
|
{
|
||||||
window.disconnect(this.closeRequestSignal);
|
window.disconnect(this.closeRequestSignal);
|
||||||
@@ -546,7 +434,7 @@ class ClapperPlayer extends PlayerBase
|
|||||||
bool = true;
|
bool = true;
|
||||||
case Gdk.KEY_Left:
|
case Gdk.KEY_Left:
|
||||||
this.adjust_position(bool);
|
this.adjust_position(bool);
|
||||||
this._clearTimeout('hideControls');
|
clapperWidget._clearTimeout('hideControls');
|
||||||
if(this.keyPressCount > 1) {
|
if(this.keyPressCount > 1) {
|
||||||
clapperWidget.revealerBottom.set_can_focus(false);
|
clapperWidget.revealerBottom.set_can_focus(false);
|
||||||
clapperWidget.revealerBottom.revealChild(true);
|
clapperWidget.revealerBottom.revealChild(true);
|
||||||
@@ -572,7 +460,7 @@ class ClapperPlayer extends PlayerBase
|
|||||||
case Gdk.KEY_Return:
|
case Gdk.KEY_Return:
|
||||||
if(clapperWidget.isFullscreenMode) {
|
if(clapperWidget.isFullscreenMode) {
|
||||||
clapperWidget.revealControls(true);
|
clapperWidget.revealControls(true);
|
||||||
this._setHideControlsTimeout();
|
clapperWidget._setHideControlsTimeout();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Gdk.KEY_Right:
|
case Gdk.KEY_Right:
|
||||||
@@ -581,7 +469,7 @@ class ClapperPlayer extends PlayerBase
|
|||||||
clapperWidget.controls.positionScale.get_value()
|
clapperWidget.controls.positionScale.get_value()
|
||||||
);
|
);
|
||||||
this.seek_seconds(value);
|
this.seek_seconds(value);
|
||||||
this._setHideControlsTimeout();
|
clapperWidget._setHideControlsTimeout();
|
||||||
break;
|
break;
|
||||||
case Gdk.KEY_F11:
|
case Gdk.KEY_F11:
|
||||||
case Gdk.KEY_f:
|
case Gdk.KEY_f:
|
||||||
@@ -604,179 +492,6 @@ class ClapperPlayer extends PlayerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onWidgetPressed(gesture, nPress, x, y)
|
|
||||||
{
|
|
||||||
const button = gesture.get_current_button();
|
|
||||||
const isDouble = (nPress % 2 == 0);
|
|
||||||
this.dragAllowed = !isDouble;
|
|
||||||
|
|
||||||
switch(button) {
|
|
||||||
case Gdk.BUTTON_PRIMARY:
|
|
||||||
if(isDouble) {
|
|
||||||
const clapperWidget = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
clapperWidget.toggleFullscreen();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Gdk.BUTTON_SECONDARY:
|
|
||||||
this.toggle_play();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onWidgetEnter(controller, x, y)
|
|
||||||
{
|
|
||||||
this.cursorInPlayer = true;
|
|
||||||
this.isWidgetDragging = false;
|
|
||||||
|
|
||||||
this._setHideControlsTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
_onWidgetLeave(controller)
|
|
||||||
{
|
|
||||||
this.cursorInPlayer = false;
|
|
||||||
|
|
||||||
this._clearTimeout('hideControls');
|
|
||||||
}
|
|
||||||
|
|
||||||
_onWidgetMotion(controller, posX, posY)
|
|
||||||
{
|
|
||||||
this.cursorInPlayer = true;
|
|
||||||
|
|
||||||
/* GTK4 sometimes generates motions with same coords */
|
|
||||||
if(this.posX === posX && this.posY === posY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Do not show cursor on small movements */
|
|
||||||
if(
|
|
||||||
Math.abs(this.posX - posX) >= 0.5
|
|
||||||
|| Math.abs(this.posY - posY) >= 0.5
|
|
||||||
) {
|
|
||||||
const clapperWidget = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
const defaultCursor = Gdk.Cursor.new_from_name('default', null);
|
|
||||||
|
|
||||||
this.widget.set_cursor(defaultCursor);
|
|
||||||
clapperWidget.revealerTop.set_cursor(defaultCursor);
|
|
||||||
|
|
||||||
this._setHideControlsTimeout();
|
|
||||||
|
|
||||||
if(clapperWidget.isFullscreenMode) {
|
|
||||||
if(!this._updateTimeTimeout)
|
|
||||||
this._setUpdateTimeInterval();
|
|
||||||
}
|
|
||||||
else if(this._updateTimeTimeout)
|
|
||||||
this._clearTimeout('updateTime');
|
|
||||||
|
|
||||||
if(!clapperWidget.revealerTop.get_reveal_child()) {
|
|
||||||
/* Do not grab controls key focus on mouse movement */
|
|
||||||
clapperWidget.revealerBottom.set_can_focus(false);
|
|
||||||
clapperWidget.revealControls(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.posX = posX;
|
|
||||||
this.posY = posY;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onWidgetDragUpdate(gesture, offsetX, offsetY)
|
|
||||||
{
|
|
||||||
if(!this.dragAllowed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const clapperWidget = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
if(clapperWidget.isFullscreenMode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const { gtk_double_click_distance } = this.widget.get_settings();
|
|
||||||
|
|
||||||
if (
|
|
||||||
Math.abs(offsetX) > gtk_double_click_distance
|
|
||||||
|| Math.abs(offsetY) > gtk_double_click_distance
|
|
||||||
) {
|
|
||||||
const [isActive, startX, startY] = gesture.get_start_point();
|
|
||||||
if(!isActive) return;
|
|
||||||
|
|
||||||
const native = this.widget.get_native();
|
|
||||||
if(!native) return;
|
|
||||||
|
|
||||||
let [isShared, winX, winY] = this.widget.translate_coordinates(
|
|
||||||
native, startX, startY
|
|
||||||
);
|
|
||||||
if(!isShared) return;
|
|
||||||
|
|
||||||
const [nativeX, nativeY] = native.get_surface_transform();
|
|
||||||
winX += nativeX;
|
|
||||||
winY += nativeY;
|
|
||||||
|
|
||||||
this.isWidgetDragging = true;
|
|
||||||
native.get_surface().begin_move(
|
|
||||||
gesture.get_device(),
|
|
||||||
gesture.get_current_button(),
|
|
||||||
winX,
|
|
||||||
winY,
|
|
||||||
gesture.get_current_event_time()
|
|
||||||
);
|
|
||||||
|
|
||||||
gesture.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onWidgetSwipe(gesture, velocityX, velocityY)
|
|
||||||
{
|
|
||||||
if(!this.getIsSwipeOk(velocityX, velocityY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._onScroll(gesture, -velocityX, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onWidgetSwipeUpdate(gesture, sequence)
|
|
||||||
{
|
|
||||||
const [isCalc, velocityX, velocityY] = gesture.get_velocity();
|
|
||||||
if(!isCalc) return;
|
|
||||||
|
|
||||||
if(!this.getIsSwipeOk(velocityY, velocityX))
|
|
||||||
return;
|
|
||||||
|
|
||||||
const isIncrease = velocityY < 0;
|
|
||||||
|
|
||||||
this.adjust_volume(isIncrease, 0.01);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onScroll(controller, dx, dy)
|
|
||||||
{
|
|
||||||
const isHorizontal = (Math.abs(dx) >= Math.abs(dy));
|
|
||||||
const isIncrease = (isHorizontal) ? dx < 0 : dy < 0;
|
|
||||||
|
|
||||||
if(isHorizontal) {
|
|
||||||
this.adjust_position(isIncrease);
|
|
||||||
const { controls } = this.widget.get_ancestor(Gtk.Grid);
|
|
||||||
const value = Math.round(controls.positionScale.get_value());
|
|
||||||
this.seek_seconds(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this.adjust_volume(isIncrease);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDataDrop(dropTarget, value, x, y)
|
|
||||||
{
|
|
||||||
const playlist = value.split(/\r?\n/).filter(uri => {
|
|
||||||
return Gst.uri_is_valid(uri);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(!playlist.length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
this.set_playlist(playlist);
|
|
||||||
|
|
||||||
const { application } = this.widget.get_root();
|
|
||||||
application.activate();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onCloseRequest(window)
|
_onCloseRequest(window)
|
||||||
{
|
{
|
||||||
this._performCloseCleanup(window);
|
this._performCloseCleanup(window);
|
||||||
|
358
src/widget.js
358
src/widget.js
@@ -1,4 +1,4 @@
|
|||||||
const { Gdk, GLib, GObject, GstClapper, Gtk } = imports.gi;
|
const { Gdk, GLib, GObject, Gst, GstClapper, Gtk } = imports.gi;
|
||||||
const { Controls } = imports.src.controls;
|
const { Controls } = imports.src.controls;
|
||||||
const Debug = imports.src.debug;
|
const Debug = imports.src.debug;
|
||||||
const Dialogs = imports.src.dialogs;
|
const Dialogs = imports.src.dialogs;
|
||||||
@@ -20,6 +20,9 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
* separately as a pre-made GTK widget */
|
* separately as a pre-made GTK widget */
|
||||||
Misc.loadCustomCss();
|
Misc.loadCustomCss();
|
||||||
|
|
||||||
|
this.posX = 0;
|
||||||
|
this.posY = 0;
|
||||||
|
|
||||||
this.windowSize = JSON.parse(settings.get_string('window-size'));
|
this.windowSize = JSON.parse(settings.get_string('window-size'));
|
||||||
this.layoutWidth = 0;
|
this.layoutWidth = 0;
|
||||||
|
|
||||||
@@ -27,6 +30,13 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
this.isSeekable = false;
|
this.isSeekable = false;
|
||||||
this.isMobileMonitor = false;
|
this.isMobileMonitor = false;
|
||||||
|
|
||||||
|
this.dragAllowed = false;
|
||||||
|
this.cursorInPlayer = false;
|
||||||
|
this.isWidgetDragging = false;
|
||||||
|
|
||||||
|
this._hideControlsTimeout = null;
|
||||||
|
this._updateTimeTimeout = null;
|
||||||
|
|
||||||
this.needsTracksUpdate = true;
|
this.needsTracksUpdate = true;
|
||||||
|
|
||||||
this.overlay = new Gtk.Overlay();
|
this.overlay = new Gtk.Overlay();
|
||||||
@@ -49,6 +59,8 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
this.mapSignal = this.connect('map', this._onMap.bind(this));
|
this.mapSignal = this.connect('map', this._onMap.bind(this));
|
||||||
|
|
||||||
this.player = new Player();
|
this.player = new Player();
|
||||||
|
const playerWidget = this.player.widget;
|
||||||
|
|
||||||
this.controls.elapsedButton.scrolledWindow.set_child(this.player.playlistWidget);
|
this.controls.elapsedButton.scrolledWindow.set_child(this.player.playlistWidget);
|
||||||
this.controls.speedAdjustment.bind_property(
|
this.controls.speedAdjustment.bind_property(
|
||||||
'value', this.player, 'rate', GObject.BindingFlags.BIDIRECTIONAL
|
'value', this.player, 'rate', GObject.BindingFlags.BIDIRECTIONAL
|
||||||
@@ -60,27 +72,34 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
/* FIXME: re-enable once ported to new GstPlayer API with messages bus */
|
/* FIXME: re-enable once ported to new GstPlayer API with messages bus */
|
||||||
//this.player.connect('volume-changed', this._onPlayerVolumeChanged.bind(this));
|
//this.player.connect('volume-changed', this._onPlayerVolumeChanged.bind(this));
|
||||||
|
|
||||||
this.overlay.set_child(this.player.widget);
|
this.overlay.set_child(playerWidget);
|
||||||
this.overlay.add_overlay(this.revealerTop);
|
this.overlay.add_overlay(this.revealerTop);
|
||||||
this.overlay.add_overlay(this.revealerBottom);
|
this.overlay.add_overlay(this.revealerBottom);
|
||||||
|
|
||||||
const motionController = new Gtk.EventControllerMotion();
|
const clickGesture = this._getClickGesture();
|
||||||
motionController.connect('leave', this._onLeave.bind(this));
|
playerWidget.add_controller(clickGesture);
|
||||||
this.add_controller(motionController);
|
const clickGestureTop = this._getClickGesture();
|
||||||
|
this.revealerTop.add_controller(clickGestureTop);
|
||||||
|
|
||||||
const topClickGesture = new Gtk.GestureClick();
|
const dragGesture = this._getDragGesture();
|
||||||
topClickGesture.set_button(0);
|
playerWidget.add_controller(dragGesture);
|
||||||
topClickGesture.connect('pressed', this.player._onWidgetPressed.bind(this.player));
|
const dragGestureTop = this._getDragGesture();
|
||||||
this.revealerTop.add_controller(topClickGesture);
|
this.revealerTop.add_controller(dragGestureTop);
|
||||||
|
|
||||||
const topMotionController = new Gtk.EventControllerMotion();
|
const scrollController = this._getScrollController();
|
||||||
topMotionController.connect('motion', this.player._onWidgetMotion.bind(this.player));
|
playerWidget.add_controller(scrollController);
|
||||||
this.revealerTop.add_controller(topMotionController);
|
const scrollControllerTop = this._getScrollController();
|
||||||
|
this.revealerTop.add_controller(scrollControllerTop);
|
||||||
|
|
||||||
const topScrollController = new Gtk.EventControllerScroll();
|
const motionController = this._getMotionController();
|
||||||
topScrollController.set_flags(Gtk.EventControllerScrollFlags.BOTH_AXES);
|
playerWidget.add_controller(motionController);
|
||||||
topScrollController.connect('scroll', this.player._onScroll.bind(this.player));
|
const motionControllerTop = this._getMotionController();
|
||||||
this.revealerTop.add_controller(topScrollController);
|
this.revealerTop.add_controller(motionControllerTop);
|
||||||
|
|
||||||
|
const dropTarget = this._getDropTarget();
|
||||||
|
playerWidget.add_controller(dropTarget);
|
||||||
|
const dropTargetTop = this._getDropTarget();
|
||||||
|
this.revealerTop.add_controller(dropTargetTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
revealControls(isReveal)
|
revealControls(isReveal)
|
||||||
@@ -524,17 +543,6 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
this.controls._onPlayerResize(width, height);
|
this.controls._onPlayerResize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onLeave(controller)
|
|
||||||
{
|
|
||||||
if(
|
|
||||||
this.isFullscreenMode
|
|
||||||
|| this.player.isWidgetDragging
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.revealerBottom.revealChild(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMap()
|
_onMap()
|
||||||
{
|
{
|
||||||
this.disconnect(this.mapSignal);
|
this.disconnect(this.mapSignal);
|
||||||
@@ -562,4 +570,300 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
surface.connect('notify::state', this._onStateNotify.bind(this));
|
surface.connect('notify::state', this._onStateNotify.bind(this));
|
||||||
surface.connect('layout', this._onLayoutUpdate.bind(this));
|
surface.connect('layout', this._onLayoutUpdate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_clearTimeout(name)
|
||||||
|
{
|
||||||
|
if(!this[`_${name}Timeout`])
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLib.source_remove(this[`_${name}Timeout`]);
|
||||||
|
this[`_${name}Timeout`] = null;
|
||||||
|
|
||||||
|
if(name === 'updateTime')
|
||||||
|
debug('cleared update time interval');
|
||||||
|
}
|
||||||
|
|
||||||
|
_setHideControlsTimeout()
|
||||||
|
{
|
||||||
|
this._clearTimeout('hideControls');
|
||||||
|
this._hideControlsTimeout = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => {
|
||||||
|
this._hideControlsTimeout = null;
|
||||||
|
|
||||||
|
if(this.cursorInPlayer) {
|
||||||
|
const blankCursor = Gdk.Cursor.new_from_name('none', null);
|
||||||
|
|
||||||
|
this.player.widget.set_cursor(blankCursor);
|
||||||
|
this.revealerTop.set_cursor(blankCursor);
|
||||||
|
|
||||||
|
if(this.isFullscreenMode)
|
||||||
|
this._clearTimeout('updateTime');
|
||||||
|
|
||||||
|
this.revealControls(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_setUpdateTimeInterval()
|
||||||
|
{
|
||||||
|
this._clearTimeout('updateTime');
|
||||||
|
|
||||||
|
const nextUpdate = this.updateTime();
|
||||||
|
|
||||||
|
if(nextUpdate === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._updateTimeTimeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, nextUpdate, () => {
|
||||||
|
this._updateTimeTimeout = null;
|
||||||
|
|
||||||
|
if(this.isFullscreenMode)
|
||||||
|
this._setUpdateTimeInterval();
|
||||||
|
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_getClickGesture()
|
||||||
|
{
|
||||||
|
const clickGesture = new Gtk.GestureClick();
|
||||||
|
clickGesture.set_button(0);
|
||||||
|
clickGesture.connect('pressed', this._onPressed.bind(this));
|
||||||
|
|
||||||
|
return clickGesture;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getDragGesture()
|
||||||
|
{
|
||||||
|
const dragGesture = new Gtk.GestureDrag();
|
||||||
|
dragGesture.connect('drag-update', this._onDragUpdate.bind(this));
|
||||||
|
|
||||||
|
return dragGesture;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getSwipeGesture()
|
||||||
|
{
|
||||||
|
const swipeGesture = new Gtk.GestureSwipe({
|
||||||
|
touch_only: true,
|
||||||
|
});
|
||||||
|
swipeGesture.connect('swipe', this._onSwipe.bind(this));
|
||||||
|
swipeGesture.connect('update', this._onSwipeUpdate.bind(this));
|
||||||
|
|
||||||
|
return swipeGesture;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getScrollController()
|
||||||
|
{
|
||||||
|
const scrollController = new Gtk.EventControllerScroll();
|
||||||
|
scrollController.set_flags(Gtk.EventControllerScrollFlags.BOTH_AXES);
|
||||||
|
scrollController.connect('scroll', this._onScroll.bind(this));
|
||||||
|
|
||||||
|
return scrollController;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getMotionController()
|
||||||
|
{
|
||||||
|
const motionController = new Gtk.EventControllerMotion();
|
||||||
|
motionController.connect('enter', this._onEnter.bind(this));
|
||||||
|
motionController.connect('leave', this._onLeave.bind(this));
|
||||||
|
motionController.connect('motion', this._onMotion.bind(this));
|
||||||
|
|
||||||
|
return motionController;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getDropTarget()
|
||||||
|
{
|
||||||
|
const dropTarget = new Gtk.DropTarget({
|
||||||
|
actions: Gdk.DragAction.COPY,
|
||||||
|
});
|
||||||
|
dropTarget.set_gtypes([GObject.TYPE_STRING]);
|
||||||
|
dropTarget.connect('drop', this._onDataDrop.bind(this));
|
||||||
|
|
||||||
|
return dropTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getIsSwipeOk(velocity, otherVelocity)
|
||||||
|
{
|
||||||
|
if(!velocity)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const absVel = Math.abs(velocity);
|
||||||
|
|
||||||
|
if(absVel < 20 || Math.abs(otherVelocity) * 1.5 >= absVel)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return this.isFullscreenMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onPressed(gesture, nPress, x, y)
|
||||||
|
{
|
||||||
|
const button = gesture.get_current_button();
|
||||||
|
const isDouble = (nPress % 2 == 0);
|
||||||
|
this.dragAllowed = !isDouble;
|
||||||
|
|
||||||
|
switch(button) {
|
||||||
|
case Gdk.BUTTON_PRIMARY:
|
||||||
|
if(isDouble)
|
||||||
|
this.toggleFullscreen();
|
||||||
|
break;
|
||||||
|
case Gdk.BUTTON_SECONDARY:
|
||||||
|
this.player.toggle_play();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDragUpdate(gesture, offsetX, offsetY)
|
||||||
|
{
|
||||||
|
if(!this.dragAllowed || this.isFullscreenMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const { gtk_double_click_distance } = this.get_settings();
|
||||||
|
|
||||||
|
if (
|
||||||
|
Math.abs(offsetX) > gtk_double_click_distance
|
||||||
|
|| Math.abs(offsetY) > gtk_double_click_distance
|
||||||
|
) {
|
||||||
|
const [isActive, startX, startY] = gesture.get_start_point();
|
||||||
|
if(!isActive) return;
|
||||||
|
|
||||||
|
const playerWidget = this.player.widget;
|
||||||
|
|
||||||
|
const native = playerWidget.get_native();
|
||||||
|
if(!native) return;
|
||||||
|
|
||||||
|
let [isShared, winX, winY] = playerWidget.translate_coordinates(
|
||||||
|
native, startX, startY
|
||||||
|
);
|
||||||
|
if(!isShared) return;
|
||||||
|
|
||||||
|
const [nativeX, nativeY] = native.get_surface_transform();
|
||||||
|
winX += nativeX;
|
||||||
|
winY += nativeY;
|
||||||
|
|
||||||
|
this.isWidgetDragging = true;
|
||||||
|
native.get_surface().begin_move(
|
||||||
|
gesture.get_device(),
|
||||||
|
gesture.get_current_button(),
|
||||||
|
winX,
|
||||||
|
winY,
|
||||||
|
gesture.get_current_event_time()
|
||||||
|
);
|
||||||
|
|
||||||
|
gesture.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSwipe(gesture, velocityX, velocityY)
|
||||||
|
{
|
||||||
|
if(!this._getIsSwipeOk(velocityX, velocityY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._onScroll(gesture, -velocityX, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSwipeUpdate(gesture, sequence)
|
||||||
|
{
|
||||||
|
const [isCalc, velocityX, velocityY] = gesture.get_velocity();
|
||||||
|
if(!isCalc) return;
|
||||||
|
|
||||||
|
if(!this._getIsSwipeOk(velocityY, velocityX))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const isIncrease = velocityY < 0;
|
||||||
|
|
||||||
|
this.player.adjust_volume(isIncrease, 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onScroll(controller, dx, dy)
|
||||||
|
{
|
||||||
|
const isHorizontal = (Math.abs(dx) >= Math.abs(dy));
|
||||||
|
const isIncrease = (isHorizontal) ? dx < 0 : dy < 0;
|
||||||
|
|
||||||
|
if(isHorizontal) {
|
||||||
|
this.player.adjust_position(isIncrease);
|
||||||
|
const value = Math.round(this.controls.positionScale.get_value());
|
||||||
|
this.player.seek_seconds(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.player.adjust_volume(isIncrease);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onEnter(controller, x, y)
|
||||||
|
{
|
||||||
|
this.cursorInPlayer = true;
|
||||||
|
this.isWidgetDragging = false;
|
||||||
|
|
||||||
|
this._setHideControlsTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
_onLeave(controller)
|
||||||
|
{
|
||||||
|
this.cursorInPlayer = false;
|
||||||
|
this._setHideControlsTimeout(250);
|
||||||
|
|
||||||
|
if(
|
||||||
|
this.isFullscreenMode
|
||||||
|
|| this.isWidgetDragging
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//this.revealerBottom.revealChild(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMotion(controller, posX, posY)
|
||||||
|
{
|
||||||
|
this.cursorInPlayer = true;
|
||||||
|
|
||||||
|
/* GTK4 sometimes generates motions with same coords */
|
||||||
|
if(this.posX === posX && this.posY === posY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Do not show cursor on small movements */
|
||||||
|
if(
|
||||||
|
Math.abs(this.posX - posX) >= 0.5
|
||||||
|
|| Math.abs(this.posY - posY) >= 0.5
|
||||||
|
) {
|
||||||
|
const defaultCursor = Gdk.Cursor.new_from_name('default', null);
|
||||||
|
|
||||||
|
this.player.widget.set_cursor(defaultCursor);
|
||||||
|
this.revealerTop.set_cursor(defaultCursor);
|
||||||
|
|
||||||
|
this._setHideControlsTimeout();
|
||||||
|
|
||||||
|
if(this.isFullscreenMode) {
|
||||||
|
if(!this._updateTimeTimeout)
|
||||||
|
this._setUpdateTimeInterval();
|
||||||
|
}
|
||||||
|
else if(this._updateTimeTimeout)
|
||||||
|
this._clearTimeout('updateTime');
|
||||||
|
|
||||||
|
if(!this.revealerTop.get_reveal_child()) {
|
||||||
|
/* Do not grab controls key focus on mouse movement */
|
||||||
|
this.revealerBottom.set_can_focus(false);
|
||||||
|
this.revealControls(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.posX = posX;
|
||||||
|
this.posY = posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDataDrop(dropTarget, value, x, y)
|
||||||
|
{
|
||||||
|
const playlist = value.split(/\r?\n/).filter(uri => {
|
||||||
|
return Gst.uri_is_valid(uri);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!playlist.length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this.player.set_playlist(playlist);
|
||||||
|
this.root.application.activate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user