Files
clapper/clapper_src/playlist.js
Rafostar d36a972864 Simplify playlist drop callback
Use value passed to the callback instead of target property
2021-01-20 11:16:51 +01:00

208 lines
5.0 KiB
JavaScript

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 = value.get_index();
if(destIndex === targetIndex)
return true;
const listBox = this.get_ancestor(Gtk.ListBox);
if(listBox && destIndex >= 0) {
listBox.remove(value);
listBox.insert(value, destIndex);
return true;
}
return false;
}
});