mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Move "clapper_src" dir to "src"
The "clapper_src" directory name was unusual. This was done to make it work as a widget for other apps. Now that this functionality got removed it can be named simply "src" as recommended by guidelines.
This commit is contained in:
207
src/playlist.js
Normal file
207
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 = 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;
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user