mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-31 08:21:59 +02:00
Add playlist widget to elapsed time button popover
This commit is contained in:
@@ -17,7 +17,6 @@ class ClapperApp extends AppBase
|
|||||||
this.get_flags()
|
this.get_flags()
|
||||||
| Gio.ApplicationFlags.HANDLES_OPEN
|
| Gio.ApplicationFlags.HANDLES_OPEN
|
||||||
);
|
);
|
||||||
this.playlist = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_startup()
|
vfunc_startup()
|
||||||
@@ -42,10 +41,12 @@ class ClapperApp extends AppBase
|
|||||||
{
|
{
|
||||||
super.vfunc_open(files, hint);
|
super.vfunc_open(files, hint);
|
||||||
|
|
||||||
this.playlist = files;
|
const { player } = this.active_window.get_child();
|
||||||
|
|
||||||
if(this.doneFirstActivate)
|
if(!this.doneFirstActivate)
|
||||||
this.setWindowPlaylist(this.active_window);
|
player._preparePlaylist(files);
|
||||||
|
else
|
||||||
|
player.set_playlist(files);
|
||||||
|
|
||||||
this.activate();
|
this.activate();
|
||||||
}
|
}
|
||||||
@@ -54,15 +55,12 @@ class ClapperApp extends AppBase
|
|||||||
{
|
{
|
||||||
super._onWindowShow(window);
|
super._onWindowShow(window);
|
||||||
|
|
||||||
this.setWindowPlaylist(window);
|
const { player } = this.active_window.get_child();
|
||||||
}
|
const success = player.playlistWidget.nextTrack();
|
||||||
|
|
||||||
setWindowPlaylist(window)
|
if(!success)
|
||||||
{
|
debug('playlist is empty');
|
||||||
if(!this.playlist.length)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const { player } = window.get_child();
|
player.widget.grab_focus();
|
||||||
player.set_playlist(this.playlist);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -85,13 +85,6 @@ class ClapperIconButton extends CustomButton
|
|||||||
});
|
});
|
||||||
this.floatUnaffected = true;
|
this.floatUnaffected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setFullscreenMode(isFullscreen)
|
|
||||||
{
|
|
||||||
/* Redraw icon after style class change */
|
|
||||||
this.set_icon_name(this.icon_name);
|
|
||||||
super.setFullscreenMode(isFullscreen);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var IconToggleButton = GObject.registerClass(
|
var IconToggleButton = GObject.registerClass(
|
||||||
@@ -116,38 +109,13 @@ class ClapperIconToggleButton extends IconButton
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var LabelButton = GObject.registerClass(
|
var PopoverButtonBase = GObject.registerClass(
|
||||||
class ClapperLabelButton extends CustomButton
|
class ClapperPopoverButtonBase extends CustomButton
|
||||||
{
|
{
|
||||||
_init(text)
|
_init()
|
||||||
{
|
{
|
||||||
super._init({
|
super._init();
|
||||||
margin_start: 0,
|
|
||||||
margin_end: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.customLabel = new Gtk.Label({
|
|
||||||
label: text,
|
|
||||||
single_line_mode: true,
|
|
||||||
});
|
|
||||||
this.customLabel.add_css_class('labelbutton');
|
|
||||||
this.set_child(this.customLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_label(text)
|
|
||||||
{
|
|
||||||
this.customLabel.set_text(text);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var PopoverButton = GObject.registerClass(
|
|
||||||
class ClapperPopoverButton extends IconButton
|
|
||||||
{
|
|
||||||
_init(icon)
|
|
||||||
{
|
|
||||||
super._init(icon);
|
|
||||||
|
|
||||||
this.floatUnaffected = false;
|
|
||||||
this.popover = new Gtk.Popover({
|
this.popover = new Gtk.Popover({
|
||||||
position: Gtk.PositionType.TOP,
|
position: Gtk.PositionType.TOP,
|
||||||
});
|
});
|
||||||
@@ -203,3 +171,59 @@ class ClapperPopoverButton extends IconButton
|
|||||||
this.popover.unparent();
|
this.popover.unparent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var IconPopoverButton = GObject.registerClass(
|
||||||
|
class ClapperIconPopoverButton extends PopoverButtonBase
|
||||||
|
{
|
||||||
|
_init(icon)
|
||||||
|
{
|
||||||
|
super._init();
|
||||||
|
|
||||||
|
this.icon_name = icon;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var LabelPopoverButton = GObject.registerClass(
|
||||||
|
class ClapperLabelPopoverButton extends PopoverButtonBase
|
||||||
|
{
|
||||||
|
_init(text)
|
||||||
|
{
|
||||||
|
super._init();
|
||||||
|
|
||||||
|
this.customLabel = new Gtk.Label({
|
||||||
|
label: text,
|
||||||
|
single_line_mode: true,
|
||||||
|
});
|
||||||
|
this.customLabel.add_css_class('labelbutton');
|
||||||
|
this.set_child(this.customLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_label(text)
|
||||||
|
{
|
||||||
|
this.customLabel.set_text(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var ElapsedPopoverButton = GObject.registerClass(
|
||||||
|
class ClapperElapsedPopoverButton extends LabelPopoverButton
|
||||||
|
{
|
||||||
|
_init(text)
|
||||||
|
{
|
||||||
|
super._init(text);
|
||||||
|
|
||||||
|
this.scrolledWindow = new Gtk.ScrolledWindow({
|
||||||
|
max_content_height: 150,
|
||||||
|
min_content_width: 250,
|
||||||
|
propagate_natural_height: true,
|
||||||
|
});
|
||||||
|
this.popoverBox.append(this.scrolledWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
setFullscreenMode(isFullscreen)
|
||||||
|
{
|
||||||
|
super.setFullscreenMode(isFullscreen);
|
||||||
|
|
||||||
|
this.scrolledWindow.max_content_height = (isFullscreen)
|
||||||
|
? 190 : 150;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
30
clapper_src/controls.js
vendored
30
clapper_src/controls.js
vendored
@@ -42,7 +42,7 @@ class ClapperControls extends Gtk.Box
|
|||||||
this._addTogglePlayButton();
|
this._addTogglePlayButton();
|
||||||
|
|
||||||
const elapsedRevealer = new Revealers.ButtonsRevealer('SLIDE_RIGHT');
|
const elapsedRevealer = new Revealers.ButtonsRevealer('SLIDE_RIGHT');
|
||||||
this.elapsedButton = this.addLabelButton('00:00/00:00', elapsedRevealer);
|
this.elapsedButton = this.addElapsedPopoverButton('00:00/00:00', elapsedRevealer);
|
||||||
elapsedRevealer.set_reveal_child(true);
|
elapsedRevealer.set_reveal_child(true);
|
||||||
this.revealersArr.push(elapsedRevealer);
|
this.revealersArr.push(elapsedRevealer);
|
||||||
this.append(elapsedRevealer);
|
this.append(elapsedRevealer);
|
||||||
@@ -59,22 +59,22 @@ class ClapperControls extends Gtk.Box
|
|||||||
const tracksRevealer = new Revealers.ButtonsRevealer(
|
const tracksRevealer = new Revealers.ButtonsRevealer(
|
||||||
'SLIDE_LEFT', revealTracksButton
|
'SLIDE_LEFT', revealTracksButton
|
||||||
);
|
);
|
||||||
this.visualizationsButton = this.addPopoverButton(
|
this.visualizationsButton = this.addIconPopoverButton(
|
||||||
'display-projector-symbolic',
|
'display-projector-symbolic',
|
||||||
tracksRevealer
|
tracksRevealer
|
||||||
);
|
);
|
||||||
this.visualizationsButton.set_visible(false);
|
this.visualizationsButton.set_visible(false);
|
||||||
this.videoTracksButton = this.addPopoverButton(
|
this.videoTracksButton = this.addIconPopoverButton(
|
||||||
'emblem-videos-symbolic',
|
'emblem-videos-symbolic',
|
||||||
tracksRevealer
|
tracksRevealer
|
||||||
);
|
);
|
||||||
this.videoTracksButton.set_visible(false);
|
this.videoTracksButton.set_visible(false);
|
||||||
this.audioTracksButton = this.addPopoverButton(
|
this.audioTracksButton = this.addIconPopoverButton(
|
||||||
'emblem-music-symbolic',
|
'emblem-music-symbolic',
|
||||||
tracksRevealer
|
tracksRevealer
|
||||||
);
|
);
|
||||||
this.audioTracksButton.set_visible(false);
|
this.audioTracksButton.set_visible(false);
|
||||||
this.subtitleTracksButton = this.addPopoverButton(
|
this.subtitleTracksButton = this.addIconPopoverButton(
|
||||||
'media-view-subtitles-symbolic',
|
'media-view-subtitles-symbolic',
|
||||||
tracksRevealer
|
tracksRevealer
|
||||||
);
|
);
|
||||||
@@ -165,17 +165,25 @@ class ClapperControls extends Gtk.Box
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
addLabelButton(text, revealer)
|
addIconPopoverButton(iconName, revealer)
|
||||||
{
|
{
|
||||||
text = text || '';
|
const button = new Buttons.IconPopoverButton(iconName);
|
||||||
const button = new Buttons.LabelButton(text);
|
|
||||||
|
|
||||||
return this.addButton(button, revealer);
|
return this.addButton(button, revealer);
|
||||||
}
|
}
|
||||||
|
|
||||||
addPopoverButton(iconName, revealer)
|
addLabelPopoverButton(text, revealer)
|
||||||
{
|
{
|
||||||
const button = new Buttons.PopoverButton(iconName);
|
text = text || '';
|
||||||
|
const button = new Buttons.LabelPopoverButton(text);
|
||||||
|
|
||||||
|
return this.addButton(button, revealer);
|
||||||
|
}
|
||||||
|
|
||||||
|
addElapsedPopoverButton(text, revealer)
|
||||||
|
{
|
||||||
|
text = text || '';
|
||||||
|
const button = new Buttons.ElapsedPopoverButton(text);
|
||||||
|
|
||||||
return this.addButton(button, revealer);
|
return this.addButton(button, revealer);
|
||||||
}
|
}
|
||||||
@@ -363,7 +371,7 @@ class ClapperControls extends Gtk.Box
|
|||||||
|
|
||||||
_addVolumeButton()
|
_addVolumeButton()
|
||||||
{
|
{
|
||||||
this.volumeButton = this.addPopoverButton(
|
this.volumeButton = this.addIconPopoverButton(
|
||||||
'audio-volume-muted-symbolic'
|
'audio-volume-muted-symbolic'
|
||||||
);
|
);
|
||||||
this.volumeScale = new Gtk.Scale({
|
this.volumeScale = new Gtk.Scale({
|
||||||
|
@@ -15,7 +15,6 @@ class ClapperPlayer extends PlayerBase
|
|||||||
super._init();
|
super._init();
|
||||||
|
|
||||||
this.cursorInPlayer = false;
|
this.cursorInPlayer = false;
|
||||||
this.is_local_file = false;
|
|
||||||
this.seek_done = true;
|
this.seek_done = true;
|
||||||
this.dragAllowed = false;
|
this.dragAllowed = false;
|
||||||
this.isWidgetDragging = false;
|
this.isWidgetDragging = false;
|
||||||
@@ -32,9 +31,6 @@ class ClapperPlayer extends PlayerBase
|
|||||||
|
|
||||||
this._maxVolume = Misc.getLinearValue(Misc.maxVolume);
|
this._maxVolume = Misc.getLinearValue(Misc.maxVolume);
|
||||||
|
|
||||||
this._playlist = [];
|
|
||||||
this._trackId = 0;
|
|
||||||
|
|
||||||
this._hideCursorTimeout = null;
|
this._hideCursorTimeout = null;
|
||||||
this._hideControlsTimeout = null;
|
this._hideControlsTimeout = null;
|
||||||
this._updateTimeTimeout = null;
|
this._updateTimeTimeout = null;
|
||||||
@@ -80,45 +76,24 @@ class ClapperPlayer extends PlayerBase
|
|||||||
this._realizeSignal = this.widget.connect('realize', this._onWidgetRealize.bind(this));
|
this._realizeSignal = this.widget.connect('realize', this._onWidgetRealize.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
set_media(source)
|
set_uri(uri)
|
||||||
{
|
{
|
||||||
let file;
|
if(Gst.Uri.get_protocol(uri) !== 'file')
|
||||||
|
return super.set_uri(uri);
|
||||||
if(source.get_path)
|
|
||||||
file = source;
|
|
||||||
else {
|
|
||||||
if(!Gst.uri_is_valid(source))
|
|
||||||
source = Gst.filename_to_uri(source);
|
|
||||||
|
|
||||||
if(!source)
|
|
||||||
return debug('parsing source to URI failed');
|
|
||||||
|
|
||||||
debug(`parsed source to URI: ${source}`);
|
|
||||||
|
|
||||||
if(Gst.Uri.get_protocol(source) !== 'file') {
|
|
||||||
this.is_local_file = false;
|
|
||||||
return this.set_uri(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
file = Gio.file_new_for_uri(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let file = Gio.file_new_for_uri(uri);
|
||||||
if(!file.query_exists(null)) {
|
if(!file.query_exists(null)) {
|
||||||
debug(`file does not exist: ${file.get_path()}`, 'LEVEL_WARNING');
|
debug(`file does not exist: ${file.get_path()}`, 'LEVEL_WARNING');
|
||||||
this._trackId++;
|
|
||||||
|
|
||||||
if(this._playlist.length <= this._trackId)
|
if(!this.playlistWidget.nextTrack())
|
||||||
return debug('set media reached end of playlist');
|
debug('set media reached end of playlist');
|
||||||
|
|
||||||
return this.set_media(this._playlist[this._trackId]);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uri = file.get_uri();
|
|
||||||
if(uri.endsWith('.claps'))
|
if(uri.endsWith('.claps'))
|
||||||
return this.load_playlist_file(file);
|
return this.load_playlist_file(file);
|
||||||
|
|
||||||
this.is_local_file = true;
|
super.set_uri(uri);
|
||||||
this.set_uri(uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load_playlist_file(file)
|
load_playlist_file(file)
|
||||||
@@ -140,7 +115,7 @@ class ClapperPlayer extends PlayerBase
|
|||||||
if(!lineFile)
|
if(!lineFile)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
line = lineFile.get_path();
|
line = lineFile.get_uri();
|
||||||
}
|
}
|
||||||
debug(`new playlist item: ${line}`);
|
debug(`new playlist item: ${line}`);
|
||||||
playlist.push(line);
|
playlist.push(line);
|
||||||
@@ -149,20 +124,29 @@ class ClapperPlayer extends PlayerBase
|
|||||||
this.set_playlist(playlist);
|
this.set_playlist(playlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_playlist(playlist)
|
_preparePlaylist(playlist)
|
||||||
{
|
{
|
||||||
if(!Array.isArray(playlist) || !playlist.length)
|
this.playlistWidget.removeAll();
|
||||||
return;
|
|
||||||
|
|
||||||
this._trackId = 0;
|
for(let source of playlist) {
|
||||||
this._playlist = playlist;
|
const uri = (source.get_uri != null)
|
||||||
|
? source.get_uri()
|
||||||
|
: Gst.uri_is_valid(source)
|
||||||
|
? source
|
||||||
|
: Gst.filename_to_uri(source);
|
||||||
|
|
||||||
this.set_media(this._playlist[0]);
|
this.playlistWidget.addItem(uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_playlist()
|
set_playlist(playlist)
|
||||||
{
|
{
|
||||||
return this._playlist;
|
this._preparePlaylist(playlist);
|
||||||
|
|
||||||
|
const firstTrack = this.playlistWidget.get_row_at_index(0);
|
||||||
|
if(!firstTrack) return;
|
||||||
|
|
||||||
|
firstTrack.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
set_subtitles(source)
|
set_subtitles(source)
|
||||||
@@ -433,14 +417,15 @@ class ClapperPlayer extends PlayerBase
|
|||||||
|
|
||||||
_onStreamEnded(player)
|
_onStreamEnded(player)
|
||||||
{
|
{
|
||||||
debug(`end of stream: ${this._trackId}`);
|
const lastTrackId = this.playlistWidget.activeRowId;
|
||||||
this.emitWs('end_of_stream', this._trackId);
|
|
||||||
|
|
||||||
this._trackId++;
|
debug(`end of stream: ${lastTrackId}`);
|
||||||
|
this.emitWs('end_of_stream', lastTrackId);
|
||||||
|
|
||||||
if(this._trackId < this._playlist.length)
|
if(this.playlistWidget.nextTrack())
|
||||||
this.set_media(this._playlist[this._trackId]);
|
return;
|
||||||
else if(settings.get_boolean('close-auto')) {
|
|
||||||
|
if(settings.get_boolean('close-auto')) {
|
||||||
/* Stop will be automatically called soon afterwards */
|
/* Stop will be automatically called soon afterwards */
|
||||||
this._performCloseCleanup(this.widget.get_root());
|
this._performCloseCleanup(this.widget.get_root());
|
||||||
this.quitOnStop = true;
|
this.quitOnStop = true;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
const { Gio, GLib, GObject, Gst, GstPlayer, Gtk } = imports.gi;
|
const { Gio, GLib, GObject, Gst, GstPlayer, Gtk } = imports.gi;
|
||||||
const Debug = imports.clapper_src.debug;
|
const Debug = imports.clapper_src.debug;
|
||||||
const Misc = imports.clapper_src.misc;
|
const Misc = imports.clapper_src.misc;
|
||||||
|
const { PlaylistWidget } = imports.clapper_src.playlist;
|
||||||
const { WebApp } = imports.clapper_src.webApp;
|
const { WebApp } = imports.clapper_src.webApp;
|
||||||
|
|
||||||
const { debug } = Debug;
|
const { debug } = Debug;
|
||||||
@@ -54,6 +55,7 @@ class ClapperPlayerBase extends GstPlayer.Player
|
|||||||
|
|
||||||
this.webserver = null;
|
this.webserver = null;
|
||||||
this.webapp = null;
|
this.webapp = null;
|
||||||
|
this.playlistWidget = new PlaylistWidget();
|
||||||
|
|
||||||
this.set_all_plugins_ranks();
|
this.set_all_plugins_ranks();
|
||||||
this.set_initial_config();
|
this.set_initial_config();
|
||||||
|
207
clapper_src/playlist.js
Normal file
207
clapper_src/playlist.js
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
const { Gdk, GLib, GObject, Gst, Gtk, Pango } = imports.gi;
|
||||||
|
|
||||||
|
var PlaylistWidget = GObject.registerClass(
|
||||||
|
class ClapperPlaylistWidget extends Gtk.ListBox
|
||||||
|
{
|
||||||
|
_init()
|
||||||
|
{
|
||||||
|
super._init({
|
||||||
|
selection_mode: Gtk.SelectionMode.NONE,
|
||||||
|
});
|
||||||
|
this.activeRowId = -1;
|
||||||
|
this.connect('row-activated', this._onRowActivated.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(uri)
|
||||||
|
{
|
||||||
|
const item = new PlaylistItem(uri);
|
||||||
|
this.append(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(item)
|
||||||
|
{
|
||||||
|
const itemIndex = item.get_index();
|
||||||
|
|
||||||
|
/* TODO: Handle this case somehow (should app quit?)
|
||||||
|
* or disable remove button */
|
||||||
|
if(itemIndex === this.activeRowId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(itemIndex < this.activeRowId)
|
||||||
|
this.activeRowId--;
|
||||||
|
|
||||||
|
this.remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAll()
|
||||||
|
{
|
||||||
|
let oldItem;
|
||||||
|
while((oldItem = this.get_row_at_index(0)))
|
||||||
|
this.remove(oldItem);
|
||||||
|
|
||||||
|
this.activeRowId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTrack()
|
||||||
|
{
|
||||||
|
const nextRow = this.get_row_at_index(this.activeRowId + 1);
|
||||||
|
if(!nextRow)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nextRow.activate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getActiveFilename()
|
||||||
|
{
|
||||||
|
const row = this.get_row_at_index(this.activeRowId);
|
||||||
|
if(!row) return null;
|
||||||
|
|
||||||
|
return row.filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Remove once/if GstPlay(er) gets
|
||||||
|
* less vague MediaInfo signals */
|
||||||
|
getActiveIsLocalFile()
|
||||||
|
{
|
||||||
|
const row = this.get_row_at_index(this.activeRowId);
|
||||||
|
if(!row) return null;
|
||||||
|
|
||||||
|
return row.isLocalFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onRowActivated(listBox, row)
|
||||||
|
{
|
||||||
|
const { player } = this.get_ancestor(Gtk.Grid);
|
||||||
|
|
||||||
|
this.activeRowId = row.get_index();
|
||||||
|
player.set_uri(row.uri);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let PlaylistItem = GObject.registerClass(
|
||||||
|
class ClapperPlaylistItem extends Gtk.ListBoxRow
|
||||||
|
{
|
||||||
|
_init(uri)
|
||||||
|
{
|
||||||
|
super._init();
|
||||||
|
|
||||||
|
this.uri = uri;
|
||||||
|
this.isLocalFile = false;
|
||||||
|
|
||||||
|
let filename;
|
||||||
|
if(Gst.Uri.get_protocol(uri) === 'file') {
|
||||||
|
filename = GLib.path_get_basename(
|
||||||
|
GLib.filename_from_uri(uri)[0]
|
||||||
|
);
|
||||||
|
this.isLocalFile = true;
|
||||||
|
}
|
||||||
|
this.filename = filename || uri;
|
||||||
|
|
||||||
|
const box = new Gtk.Box({
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
spacing: 6,
|
||||||
|
margin_start: 6,
|
||||||
|
margin_end: 6,
|
||||||
|
height_request: 22,
|
||||||
|
});
|
||||||
|
const icon = new Gtk.Image({
|
||||||
|
icon_name: 'open-menu-symbolic',
|
||||||
|
});
|
||||||
|
const label = new Gtk.Label({
|
||||||
|
label: filename,
|
||||||
|
single_line_mode: true,
|
||||||
|
ellipsize: Pango.EllipsizeMode.END,
|
||||||
|
width_chars: 5,
|
||||||
|
hexpand: true,
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
});
|
||||||
|
const button = new Gtk.Button({
|
||||||
|
icon_name: 'edit-delete-symbolic',
|
||||||
|
});
|
||||||
|
button.add_css_class('flat');
|
||||||
|
button.add_css_class('circular');
|
||||||
|
button.add_css_class('popoverbutton');
|
||||||
|
button.connect('clicked', this._onRemoveClicked.bind(this));
|
||||||
|
|
||||||
|
box.append(icon);
|
||||||
|
box.append(label);
|
||||||
|
box.append(button);
|
||||||
|
this.set_child(box);
|
||||||
|
|
||||||
|
/* FIXME: D&D inside popover is broken in GTK4
|
||||||
|
const dragSource = new Gtk.DragSource({
|
||||||
|
actions: Gdk.DragAction.MOVE
|
||||||
|
});
|
||||||
|
dragSource.connect('prepare', this._onDragPrepare.bind(this));
|
||||||
|
dragSource.connect('drag-begin', this._onDragBegin.bind(this));
|
||||||
|
dragSource.connect('drag-end', this._onDragEnd.bind(this));
|
||||||
|
this.add_controller(dragSource);
|
||||||
|
|
||||||
|
const dropTarget = new Gtk.DropTarget({
|
||||||
|
actions: Gdk.DragAction.MOVE,
|
||||||
|
preload: true,
|
||||||
|
});
|
||||||
|
dropTarget.set_gtypes([PlaylistItem]);
|
||||||
|
dropTarget.connect('enter', this._onEnter.bind(this));
|
||||||
|
dropTarget.connect('drop', this._onDrop.bind(this));
|
||||||
|
this.add_controller(dropTarget);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
_onRemoveClicked(button)
|
||||||
|
{
|
||||||
|
const listBox = this.get_ancestor(Gtk.ListBox);
|
||||||
|
|
||||||
|
listBox.removeItem(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDragPrepare(source, x, y)
|
||||||
|
{
|
||||||
|
const widget = source.get_widget();
|
||||||
|
const paintable = new Gtk.WidgetPaintable({ widget });
|
||||||
|
const staticImg = paintable.get_current_image();
|
||||||
|
|
||||||
|
source.set_icon(staticImg, x, y);
|
||||||
|
|
||||||
|
return Gdk.ContentProvider.new_for_value(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDragBegin(source, drag)
|
||||||
|
{
|
||||||
|
this.child.set_opacity(0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDragEnd(source, drag, deleteData)
|
||||||
|
{
|
||||||
|
this.child.set_opacity(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onEnter(target, x, y)
|
||||||
|
{
|
||||||
|
return (target.value)
|
||||||
|
? Gdk.DragAction.MOVE
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDrop(target, value, x, y)
|
||||||
|
{
|
||||||
|
const destIndex = this.get_index();
|
||||||
|
const targetIndex = target.value.get_index();
|
||||||
|
|
||||||
|
if(destIndex === targetIndex)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const listBox = this.get_ancestor(Gtk.ListBox);
|
||||||
|
|
||||||
|
if(listBox && destIndex >= 0) {
|
||||||
|
listBox.remove(target.value);
|
||||||
|
listBox.insert(target.value, destIndex);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
@@ -1,4 +1,4 @@
|
|||||||
const { Gdk, GLib, GObject, Gst, GstPlayer, Gtk } = imports.gi;
|
const { Gdk, GLib, GObject, GstPlayer, Gtk } = imports.gi;
|
||||||
const { Controls } = imports.clapper_src.controls;
|
const { Controls } = imports.clapper_src.controls;
|
||||||
const Debug = imports.clapper_src.debug;
|
const Debug = imports.clapper_src.debug;
|
||||||
const Misc = imports.clapper_src.misc;
|
const Misc = imports.clapper_src.misc;
|
||||||
@@ -45,6 +45,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();
|
||||||
|
this.controls.elapsedButton.scrolledWindow.set_child(this.player.playlistWidget);
|
||||||
|
|
||||||
this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this));
|
this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this));
|
||||||
this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this));
|
this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this));
|
||||||
|
|
||||||
@@ -324,17 +326,10 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
updateTitles(mediaInfo)
|
updateTitles(mediaInfo)
|
||||||
{
|
{
|
||||||
let title = mediaInfo.get_title();
|
let title = mediaInfo.get_title();
|
||||||
let subtitle = mediaInfo.get_uri();
|
let subtitle = this.player.playlistWidget.getActiveFilename();
|
||||||
|
|
||||||
if(Gst.Uri.get_protocol(subtitle) === 'file') {
|
|
||||||
subtitle = GLib.path_get_basename(
|
|
||||||
GLib.filename_from_uri(subtitle)[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if(!title) {
|
if(!title) {
|
||||||
title = (!subtitle)
|
title = (subtitle.includes('.'))
|
||||||
? this.defaultTitle
|
|
||||||
: (subtitle.includes('.'))
|
|
||||||
? subtitle.split('.').slice(0, -1).join('.')
|
? subtitle.split('.').slice(0, -1).join('.')
|
||||||
: subtitle;
|
: subtitle;
|
||||||
|
|
||||||
@@ -461,7 +456,7 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
this.controls.positionScale.clear_marks();
|
this.controls.positionScale.clear_marks();
|
||||||
this.controls.chapters = null;
|
this.controls.chapters = null;
|
||||||
}
|
}
|
||||||
if(!player.is_local_file) {
|
if(!player.playlistWidget.getActiveIsLocalFile()) {
|
||||||
this.needsTracksUpdate = true;
|
this.needsTracksUpdate = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -22,6 +22,10 @@ radio {
|
|||||||
min-width: 17px;
|
min-width: 17px;
|
||||||
min-height: 17px;
|
min-height: 17px;
|
||||||
}
|
}
|
||||||
|
/* Adwaita is missing osd ListBox */
|
||||||
|
.osd list {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
.osd .playercontrols {
|
.osd .playercontrols {
|
||||||
-gtk-icon-size: 24px;
|
-gtk-icon-size: 24px;
|
||||||
}
|
}
|
||||||
@@ -70,6 +74,10 @@ radio {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
.popoverbutton {
|
||||||
|
min-width: 24px;
|
||||||
|
min-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Position Scale */
|
/* Position Scale */
|
||||||
.positionscale {
|
.positionscale {
|
||||||
|
Reference in New Issue
Block a user