diff --git a/clapper_src/menu.js b/clapper_src/menu.js index d774b421..70b1b7db 100644 --- a/clapper_src/menu.js +++ b/clapper_src/menu.js @@ -22,7 +22,11 @@ function prefs(window, appName) default_width: 460, default_height: 400, }); - prefsDialog.connect('close-request', () => prefsDialog.run_dispose()); + prefsDialog.connect('close-request', () => { + prefsWidget._onClose(); + prefsWidget.run_dispose(); + prefsDialog.run_dispose(); + }); prefsDialog.present(); } @@ -52,7 +56,7 @@ function about(window, appName) website: 'https://github.com/Rafostar/clapper', modal: true, system_information: osInfo, - transient_for: window + transient_for: window, }); aboutDialog.connect('close-request', () => aboutDialog.run_dispose()); aboutDialog.present(); diff --git a/clapper_src/player.js b/clapper_src/player.js index a5e8085d..a3afeb07 100644 --- a/clapper_src/player.js +++ b/clapper_src/player.js @@ -601,5 +601,8 @@ class ClapperPlayer extends PlayerBase if(this.state !== GstPlayer.PlayerState.STOPPED) this.stop(); + + let app = window.get_application(); + if(app) app.quit(); } }); diff --git a/clapper_src/playerBase.js b/clapper_src/playerBase.js index 9f327d11..3b5016dd 100644 --- a/clapper_src/playerBase.js +++ b/clapper_src/playerBase.js @@ -43,8 +43,8 @@ class ClapperPlayerBase extends GstPlayer.Player }); this.visualization_enabled = false; - this.set_plugin_rank('vah264dec', 300); + this.set_all_plugins_ranks(); this.set_initial_config(); this.set_and_bind_settings(); @@ -94,18 +94,41 @@ class ClapperPlayerBase extends GstPlayer.Player pipeline.subtitle_font_desc = desc; } + set_all_plugins_ranks() + { + let data = []; + + /* Set empty plugin list if someone messed it externally */ + try { + data = JSON.parse(this.settings.get_string('plugin-ranking')); + if(!Array.isArray(data)) + throw new Error('plugin ranking data is not an array!'); + } + catch(err) { + debug(err); + this.settings.set_string('plugin-ranking', "[]"); + } + + for(let plugin of data) { + if(!plugin.apply || !plugin.name) + continue; + + this.set_plugin_rank(plugin.name, plugin.rank); + } + } + set_plugin_rank(name, rank) { - debug(`changing rank of plugin: ${name}`); - let gstRegistry = Gst.Registry.get(); let feature = gstRegistry.lookup_feature(name); if(!feature) return debug(`plugin unavailable: ${name}`); let oldRank = feature.get_rank(); - feature.set_rank(rank); + if(rank === oldRank) + return; + feature.set_rank(rank); debug(`changed rank: ${oldRank} -> ${rank} for ${name}`); } diff --git a/clapper_src/prefs.js b/clapper_src/prefs.js index c8421612..cba5348d 100644 --- a/clapper_src/prefs.js +++ b/clapper_src/prefs.js @@ -1,4 +1,4 @@ -const { GObject, Gtk } = imports.gi; +const { GObject, Gtk, Pango } = imports.gi; const PrefsBase = imports.clapper_src.prefsBase; let GeneralPage = GObject.registerClass( @@ -58,11 +58,185 @@ class ClapperGStreamerPage extends PrefsBase.Grid { super._init(); - let label; - let widget; + this.addTitle('Plugin Ranking'); + let listStore = new Gtk.ListStore(); + listStore.set_column_types([ + GObject.TYPE_BOOLEAN, + GObject.TYPE_STRING, + GObject.TYPE_STRING, + ]); + let treeView = new Gtk.TreeView({ + hexpand: true, + vexpand: true, + enable_search: false, + model: listStore, + }); + let treeSelection = treeView.get_selection(); - label = this.getLabel('Plugin Ranking', true); - this.addToGrid(label); + let apply = new Gtk.TreeViewColumn({ + title: "Apply", + }); + let name = new Gtk.TreeViewColumn({ + title: "Plugin", + expand: true, + }); + let rank = new Gtk.TreeViewColumn({ + title: "Rank", + min_width: 90, + }); + + let applyCell = new Gtk.CellRendererToggle(); + let nameCell = new Gtk.CellRendererText({ + editable: true, + placeholder_text: "Insert plugin name", + }); + let rankCell = new Gtk.CellRendererText({ + editable: true, + weight: Pango.Weight.BOLD, + placeholder_text: "Insert plugin rank", + }); + + apply.pack_start(applyCell, true); + name.pack_start(nameCell, true); + rank.pack_start(rankCell, true); + + apply.add_attribute(applyCell, 'active', 0); + name.add_attribute(nameCell, 'text', 1); + rank.add_attribute(rankCell, 'text', 2); + + treeView.insert_column(apply, 0); + treeView.insert_column(name, 1); + treeView.insert_column(rank, 2); + + let frame = new Gtk.Frame({ + child: treeView + }); + this.addToGrid(frame); + + let addButton = new Gtk.Button({ + icon_name: 'list-add-symbolic', + halign: Gtk.Align.END, + }); + let removeButton = new Gtk.Button({ + icon_name: 'list-remove-symbolic', + sensitive: false, + halign: Gtk.Align.END, + }); + let label = new Gtk.Label({ + label: 'Changes require player restart', + halign: Gtk.Align.START, + hexpand: true, + ellipsize: Pango.EllipsizeMode.END, + }); + let box = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, + spacing: 6, + hexpand: true, + }); + box.append(label); + box.append(removeButton); + box.append(addButton); + this.addToGrid(box); + + applyCell.connect('toggled', this._onApplyCellEdited.bind(this)); + nameCell.connect('edited', this._onNameCellEdited.bind(this)); + rankCell.connect('edited', this._onRankCellEdited.bind(this)); + addButton.connect('clicked', this._onAddButtonClicked.bind(this, listStore)); + removeButton.connect('clicked', this._onRemoveButtonClicked.bind(this, listStore)); + treeSelection.connect('changed', this._onTreeSelectionChanged.bind(this, removeButton)); + + this.settingsChangedSignal = this.settings.connect( + 'changed::plugin-ranking', this.refreshListStore.bind(this, listStore) + ); + + this.refreshListStore(listStore); + } + + refreshListStore(listStore) + { + let data = JSON.parse(this.settings.get_string('plugin-ranking')); + listStore.clear(); + + for(let plugin of data) { + listStore.set( + listStore.append(), + [0, 1, 2], [ + plugin.apply || false, + plugin.name || '', + plugin.rank || 0 + ] + ); + } + } + + updatePlugin(index, prop, value) + { + let data = JSON.parse(this.settings.get_string('plugin-ranking')); + data[index][prop] = value; + this.settings.set_string('plugin-ranking', JSON.stringify(data)); + } + + _onTreeSelectionChanged(removeButton, treeSelection) + { + let [isSelected, model, iter] = treeSelection.get_selected(); + this.activeIndex = -1; + + if(isSelected) { + this.activeIndex = Number(model.get_string_from_iter(iter)); + } + + removeButton.set_sensitive(this.activeIndex >= 0); + } + + _onAddButtonClicked(listStore, button) + { + let data = JSON.parse(this.settings.get_string('plugin-ranking')); + data.push({ + apply: false, + name: '', + rank: 0, + }); + this.settings.set_string('plugin-ranking', JSON.stringify(data)); + } + + _onRemoveButtonClicked(listStore, button) + { + if(this.activeIndex < 0) + return; + + let data = JSON.parse(this.settings.get_string('plugin-ranking')); + data.splice(this.activeIndex, 1); + this.settings.set_string('plugin-ranking', JSON.stringify(data)); + } + + _onApplyCellEdited(cell, path) + { + let newState = !cell.active; + this.updatePlugin(path, 'apply', newState); + } + + _onNameCellEdited(cell, path, newText) + { + newText = newText.trim(); + this.updatePlugin(path, 'name', newText); + } + + _onRankCellEdited(cell, path, newText) + { + newText = newText.trim(); + + if(isNaN(newText)) + newText = 0; + + this.updatePlugin(path, 'rank', Number(newText)); + } + + _onClose() + { + super._onClose('gstreamer'); + + this.settings.disconnect(this.settingsChangedSignal); + this.settingsChangedSignal = null; } }); @@ -82,7 +256,6 @@ function buildPrefsWidget() } ] }, -/* { title: 'Advanced', pages: [ @@ -92,7 +265,6 @@ function buildPrefsWidget() } ] } -*/ ]; let prefsNotebook = new PrefsBase.Notebook(pages); diff --git a/clapper_src/prefsBase.js b/clapper_src/prefsBase.js index 53354cce..5a8e67e8 100644 --- a/clapper_src/prefsBase.js +++ b/clapper_src/prefsBase.js @@ -1,4 +1,7 @@ const { Gio, GObject, Gtk } = imports.gi; +const Debug = imports.clapper_src.debug; + +let { debug } = Debug; var Notebook = GObject.registerClass( class ClapperPrefsNotebook extends Gtk.Notebook @@ -41,6 +44,18 @@ class ClapperPrefsNotebook extends Gtk.Notebook }); this.append_page(widget, label); } + + _onClose() + { + let totalPages = this.get_n_pages(); + let index = 0; + + while(index < totalPages) { + let page = this.get_nth_page(index); + page._onClose(); + index++; + } + } }); var Grid = GObject.registerClass( @@ -168,4 +183,10 @@ class ClapperPrefsGrid extends Gtk.Grid return checkButton; } + + _onClose(name) + { + if(name) + debug(`cleanup of prefs ${name} page`); + } }); diff --git a/data/com.github.rafostar.Clapper.gschema.xml b/data/com.github.rafostar.Clapper.gschema.xml index 84b3e2c6..19ddbd96 100644 --- a/data/com.github.rafostar.Clapper.gschema.xml +++ b/data/com.github.rafostar.Clapper.gschema.xml @@ -31,7 +31,7 @@ - "{}" + '[{"apply":true,"name":"vah264dec","rank":300}]' Custom values for GStreamer plugin ranking