mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Buffer download whole network video during playback to allow fast seeking for online media. Can be disabled in prefs (enabled by default).
312 lines
8.9 KiB
JavaScript
312 lines
8.9 KiB
JavaScript
const { GObject, Gst, Gtk, Pango } = imports.gi;
|
|
const Misc = imports.clapper_src.misc;
|
|
const PrefsBase = imports.clapper_src.prefsBase;
|
|
|
|
let { settings } = Misc;
|
|
|
|
var GeneralPage = GObject.registerClass(
|
|
class ClapperGeneralPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
this.addTitle('Startup');
|
|
this.addCheckButton('Auto enter fullscreen', 'fullscreen-auto');
|
|
|
|
this.addTitle('Volume');
|
|
let comboBox = this.addComboBoxText('Initial value', [
|
|
['restore', "Restore"],
|
|
['custom', "Custom"],
|
|
], 'volume-initial');
|
|
let spinButton = this.addSpinButton('Value (percentage)', 0, 200, 'volume-value');
|
|
this._onVolumeInitialChanged(spinButton, comboBox);
|
|
comboBox.connect('changed', this._onVolumeInitialChanged.bind(this, spinButton));
|
|
|
|
this.addTitle('Finish');
|
|
this.addCheckButton('Close after playback', 'close-auto');
|
|
}
|
|
|
|
_onVolumeInitialChanged(spinButton, comboBox)
|
|
{
|
|
let value = comboBox.get_active_id();
|
|
spinButton.set_visible(value === 'custom');
|
|
}
|
|
});
|
|
|
|
var BehaviourPage = GObject.registerClass(
|
|
class ClapperBehaviourPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
this.addTitle('Seeking');
|
|
this.addComboBoxText('Mode', [
|
|
['normal', "Normal"],
|
|
['accurate', "Accurate"],
|
|
['fast', "Fast"],
|
|
], 'seeking-mode');
|
|
this.addComboBoxText('Unit', [
|
|
['second', "Second"],
|
|
['minute', "Minute"],
|
|
['percentage', "Percentage"],
|
|
], 'seeking-unit');
|
|
this.addSpinButton('Value', 1, 99, 'seeking-value');
|
|
}
|
|
});
|
|
|
|
var AudioPage = GObject.registerClass(
|
|
class ClapperAudioPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
this.addTitle('Synchronization');
|
|
this.addSpinButton('Offset (milliseconds)', -1000, 1000, 'audio-offset', 25);
|
|
}
|
|
});
|
|
|
|
var SubtitlesPage = GObject.registerClass(
|
|
class ClapperSubtitlesPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
/* FIXME: This should be moved to subtitles popup and displayed only when
|
|
external subtitles were added for easier customization per video. */
|
|
//this.addTitle('Synchronization');
|
|
//this.addSpinButton('Offset (milliseconds)', -5000, 5000, 'subtitle-offset', 25);
|
|
|
|
this.addTitle('External Subtitles');
|
|
this.addFontButton('Default font', 'subtitle-font');
|
|
}
|
|
});
|
|
|
|
var NetworkPage = GObject.registerClass(
|
|
class ClapperNetworkPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
this.addTitle('Client');
|
|
this.addPlayFlagCheckButton('Progressive download buffering', Gst.PlayFlags.DOWNLOAD);
|
|
}
|
|
});
|
|
|
|
var GStreamerPage = GObject.registerClass(
|
|
class ClapperGStreamerPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
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();
|
|
|
|
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 = settings.connect(
|
|
'changed::plugin-ranking', this.refreshListStore.bind(this, listStore)
|
|
);
|
|
|
|
this.refreshListStore(listStore);
|
|
}
|
|
|
|
refreshListStore(listStore)
|
|
{
|
|
let data = JSON.parse(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(settings.get_string('plugin-ranking'));
|
|
data[index][prop] = value;
|
|
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(settings.get_string('plugin-ranking'));
|
|
data.push({
|
|
apply: false,
|
|
name: '',
|
|
rank: 0,
|
|
});
|
|
settings.set_string('plugin-ranking', JSON.stringify(data));
|
|
}
|
|
|
|
_onRemoveButtonClicked(listStore, button)
|
|
{
|
|
if(this.activeIndex < 0)
|
|
return;
|
|
|
|
let data = JSON.parse(settings.get_string('plugin-ranking'));
|
|
data.splice(this.activeIndex, 1);
|
|
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');
|
|
|
|
settings.disconnect(this.settingsChangedSignal);
|
|
this.settingsChangedSignal = null;
|
|
}
|
|
});
|
|
|
|
var TweaksPage = GObject.registerClass(
|
|
class ClapperTweaksPage extends PrefsBase.Grid
|
|
{
|
|
_init()
|
|
{
|
|
super._init();
|
|
|
|
this.addTitle('Appearance');
|
|
let darkCheck = this.addCheckButton('Enable dark theme', 'dark-theme');
|
|
let brighterCheck = this.addCheckButton('Make sliders brighter', 'brighter-sliders');
|
|
this._onDarkThemeToggled(brighterCheck, darkCheck);
|
|
darkCheck.connect('toggled', this._onDarkThemeToggled.bind(this, brighterCheck));
|
|
|
|
this.addTitle('Performance');
|
|
this.addCheckButton('Render window shadows', 'render-shadows');
|
|
}
|
|
|
|
_onDarkThemeToggled(brighterCheck, darkCheck)
|
|
{
|
|
let isActive = darkCheck.get_active();
|
|
brighterCheck.set_visible(isActive);
|
|
}
|
|
});
|