mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 15:22:11 +02:00
Redo controls popovers into GtkMenuButtons
This commit is contained in:
@@ -5,17 +5,33 @@ scale marks {
|
||||
radio {
|
||||
margin-left: -2px;
|
||||
}
|
||||
scrolledwindow scrollbar.vertical slider {
|
||||
min-height: 16px;
|
||||
}
|
||||
|
||||
/* Adwaita is missing osd ListBox */
|
||||
.playlistrow {
|
||||
.clapperplaylist row {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.playlistrow {
|
||||
.clapperplaylist row {
|
||||
color: @theme_fg_color;
|
||||
}
|
||||
.osd .playlist {
|
||||
.clapperplaylist row button {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
min-width: 28px;
|
||||
min-height: 28px;
|
||||
}
|
||||
.fullscreen.tvmode .clapperplaylist row button {
|
||||
min-width: 36px;
|
||||
min-height: 36px;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.osd .clapperplaylist {
|
||||
background: none;
|
||||
}
|
||||
.osd .playlist row image {
|
||||
.osd .clapperplaylist row image {
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
.osdheaderbar {
|
||||
@@ -41,6 +57,9 @@ popover contents {
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.popoverseparator separator {
|
||||
background-color: @insensitive_fg_color;
|
||||
}
|
||||
|
||||
/* Rounded corners */
|
||||
.adwrounded.csd {
|
||||
@@ -79,25 +98,29 @@ scale trough slider {
|
||||
font-size: 21px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.adwicons .playercontrols {
|
||||
.adwicons .clappercontrols {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.playercontrols {
|
||||
.clappercontrols {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.playercontrols button {
|
||||
.clappercontrolsbutton {
|
||||
margin: 3px;
|
||||
margin-left: 1px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
.fullscreen.tvmode .playercontrols button {
|
||||
.fullscreen.tvmode .clappercontrolsbutton {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
margin: 5px;
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.clappercontrolsbutton.text-button {
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.fullscreen.tvmode button image {
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
@@ -109,7 +132,8 @@ scale trough slider {
|
||||
min-height: 17px;
|
||||
}
|
||||
|
||||
.fullscreen.tvmode .playercontrols button image {
|
||||
/* Also affects popover buttons */
|
||||
.fullscreen.tvmode .clappercontrols button image {
|
||||
-gtk-icon-size: 24px;
|
||||
}
|
||||
.adwicons .playbackicon {
|
||||
@@ -118,15 +142,12 @@ scale trough slider {
|
||||
.adwicons.fullscreen.tvmode .playbackicon {
|
||||
-gtk-icon-size: 28px;
|
||||
}
|
||||
.labelbuttonlabel {
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
min-width: 8px;
|
||||
.clappercontrolsbutton.text-button label {
|
||||
font-family: 'Cantarell', sans-serif;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 600;
|
||||
}
|
||||
.fullscreen.tvmode .labelbuttonlabel {
|
||||
.fullscreen.tvmode .clappercontrolsbutton.text-button label {
|
||||
font-size: 22px;
|
||||
text-shadow: none;
|
||||
}
|
||||
@@ -157,12 +178,6 @@ scale trough slider {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* Button Inside Popover */
|
||||
.popoverbutton {
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
/* Position Scale */
|
||||
.positionscale {
|
||||
margin: -2px;
|
||||
@@ -245,14 +260,11 @@ scale trough slider {
|
||||
}
|
||||
|
||||
/* Elapsed Popover */
|
||||
.elapsedpopoverbox {
|
||||
min-width: 260px;
|
||||
.elapsedpopover {
|
||||
min-width: 326px;
|
||||
}
|
||||
.elapsedpopoverbox box separator {
|
||||
background: @insensitive_fg_color;
|
||||
}
|
||||
.fullscreen.tvmode .elapsedpopoverbox {
|
||||
min-width: 360px;
|
||||
.fullscreen.tvmode .elapsedpopover {
|
||||
min-width: 448px;
|
||||
}
|
||||
.speedscale trough highlight {
|
||||
min-height: 4px;
|
||||
|
328
src/buttons.js
328
src/buttons.js
@@ -1,12 +1,6 @@
|
||||
const { GObject, Gtk } = imports.gi;
|
||||
const Misc = imports.src.misc;
|
||||
|
||||
/* Negative values from CSS */
|
||||
const PopoverOffset = {
|
||||
DEFAULT: -3,
|
||||
TVMODE: -5,
|
||||
};
|
||||
|
||||
var CustomButton = GObject.registerClass(
|
||||
class ClapperCustomButton extends Gtk.Button
|
||||
{
|
||||
@@ -23,29 +17,16 @@ class ClapperCustomButton extends Gtk.Button
|
||||
|
||||
super._init(opts);
|
||||
|
||||
this.isFullscreen = false;
|
||||
this.add_css_class('flat');
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen)
|
||||
{
|
||||
if(this.isFullscreen === isFullscreen)
|
||||
return;
|
||||
|
||||
/* Redraw icon after style class change */
|
||||
if(this.icon_name)
|
||||
this.set_icon_name(this.icon_name);
|
||||
|
||||
this.isFullscreen = isFullscreen;
|
||||
this.add_css_class('clappercontrolsbutton');
|
||||
}
|
||||
|
||||
vfunc_clicked()
|
||||
{
|
||||
if(!this.isFullscreen)
|
||||
return;
|
||||
|
||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||
clapperWidget.revealControls();
|
||||
|
||||
if(clapperWidget.isFullscreenMode)
|
||||
clapperWidget.revealControls();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -73,160 +54,6 @@ class ClapperIconToggleButton extends CustomButton
|
||||
}
|
||||
});
|
||||
|
||||
var PopoverButtonBase = GObject.registerClass(
|
||||
class ClapperPopoverButtonBase extends Gtk.ToggleButton
|
||||
{
|
||||
_init()
|
||||
{
|
||||
super._init({
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.CENTER,
|
||||
can_focus: false,
|
||||
});
|
||||
|
||||
this.isFullscreen = false;
|
||||
this.add_css_class('flat');
|
||||
|
||||
this.popover = new Gtk.Popover({
|
||||
position: Gtk.PositionType.TOP,
|
||||
});
|
||||
this.popoverBox = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
});
|
||||
|
||||
this.popover.set_child(this.popoverBox);
|
||||
this.popover.set_offset(0, PopoverOffset.DEFAULT);
|
||||
|
||||
if(this.isFullscreen)
|
||||
this.popover.add_css_class('osd');
|
||||
|
||||
this.popover.connect('closed', this._onClosed.bind(this));
|
||||
this.popover.set_parent(this);
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen)
|
||||
{
|
||||
if(this.isFullscreen === isFullscreen)
|
||||
return;
|
||||
|
||||
/* Redraw icon after style class change */
|
||||
if(this.icon_name)
|
||||
this.set_icon_name(this.icon_name);
|
||||
|
||||
this.isFullscreen = isFullscreen;
|
||||
|
||||
/* TODO: Fullscreen non-tv mode */
|
||||
const offset = (isFullscreen)
|
||||
? PopoverOffset.TVMODE
|
||||
: PopoverOffset.DEFAULT;
|
||||
|
||||
this.popover.set_offset(0, offset);
|
||||
|
||||
const cssClass = 'osd';
|
||||
if(isFullscreen === this.popover.has_css_class(cssClass))
|
||||
return;
|
||||
|
||||
const action = (isFullscreen) ? 'add' : 'remove';
|
||||
this.popover[action + '_css_class'](cssClass);
|
||||
}
|
||||
|
||||
vfunc_toggled()
|
||||
{
|
||||
if(!this.active)
|
||||
return;
|
||||
|
||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||
|
||||
if(this.isFullscreen) {
|
||||
clapperWidget.revealControls();
|
||||
clapperWidget.isPopoverOpen = true;
|
||||
}
|
||||
|
||||
this.popover.popup();
|
||||
}
|
||||
|
||||
_onClosed()
|
||||
{
|
||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||
|
||||
/* Set again timeout as popover is now closed */
|
||||
if(clapperWidget.isFullscreenMode)
|
||||
clapperWidget.revealControls();
|
||||
|
||||
clapperWidget.isPopoverOpen = false;
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
_onCloseRequest()
|
||||
{
|
||||
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('labelbuttonlabel');
|
||||
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.popoverBox.add_css_class('elapsedpopoverbox');
|
||||
|
||||
this.scrolledWindow = new Gtk.ScrolledWindow({
|
||||
max_content_height: 150,
|
||||
propagate_natural_height: true,
|
||||
});
|
||||
this.popoverBox.append(this.scrolledWindow);
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen)
|
||||
{
|
||||
super.setFullscreenMode(isFullscreen);
|
||||
|
||||
this.scrolledWindow.max_content_height = (isFullscreen)
|
||||
? 190 : 150;
|
||||
}
|
||||
|
||||
addSeparator(text)
|
||||
{
|
||||
this.popoverBox.append(new PopoverSeparator({
|
||||
label: text,
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
var PopoverSeparator = GObject.registerClass({
|
||||
GTypeName: 'ClapperPopoverSeparator',
|
||||
Template: `file://${Misc.getClapperPath()}/ui/popover-separator.ui`,
|
||||
@@ -246,11 +73,158 @@ class ClapperPopoverSeparator extends Gtk.Box
|
||||
_init(opts)
|
||||
{
|
||||
super._init();
|
||||
|
||||
if(!opts.label)
|
||||
this.visible = false;
|
||||
|
||||
this.label = opts.label;
|
||||
}
|
||||
|
||||
set label(value)
|
||||
{
|
||||
this._middle_label.label = value || "";
|
||||
|
||||
if(value)
|
||||
this.visible = true;
|
||||
}
|
||||
});
|
||||
|
||||
var PopoverButtonBase = GObject.registerClass({
|
||||
GTypeName: 'ClapperPopoverButtonBase',
|
||||
},
|
||||
class ClapperPopoverButtonBase extends Gtk.MenuButton
|
||||
{
|
||||
_init(opts = {})
|
||||
{
|
||||
super._init(opts);
|
||||
|
||||
if(opts.icon_name)
|
||||
this.icon_name = opts.icon_name;
|
||||
else if(opts.label)
|
||||
this.label = opts.label;
|
||||
|
||||
this.toggleButton = this.get_first_child();
|
||||
this.toggleButton.add_css_class('clappercontrolsbutton');
|
||||
|
||||
this.set_create_popup_func(this._onPopoverOpened);
|
||||
this.popover.connect('closed', this._onPopoverClosed.bind(this));
|
||||
}
|
||||
|
||||
_onPopoverOpened(self)
|
||||
{
|
||||
const clapperWidget = self.get_ancestor(Gtk.Grid);
|
||||
|
||||
if(clapperWidget.isFullscreenMode) {
|
||||
clapperWidget.revealControls();
|
||||
clapperWidget.isPopoverOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
_onPopoverClosed(popover)
|
||||
{
|
||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||
|
||||
/* Set again timeout as popover is now closed */
|
||||
if(clapperWidget.isFullscreenMode)
|
||||
clapperWidget.revealControls();
|
||||
|
||||
clapperWidget.isPopoverOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
var ElapsedTimeButton = GObject.registerClass({
|
||||
GTypeName: 'ClapperElapsedTimeButton',
|
||||
Template: `file://${Misc.getClapperPath()}/ui/elapsed-time-button.ui`,
|
||||
Children: ['scrolledWindow', 'speedScale'],
|
||||
},
|
||||
class ClapperElapsedTimeButton extends PopoverButtonBase
|
||||
{
|
||||
_init(opts)
|
||||
{
|
||||
super._init(opts);
|
||||
|
||||
this.setInitialState();
|
||||
this.popover.add_css_class('elapsedpopover');
|
||||
|
||||
this.scrolledWindow.max_content_height = 150;
|
||||
}
|
||||
|
||||
set label(value)
|
||||
{
|
||||
this.toggleButton.label = value;
|
||||
}
|
||||
|
||||
get label()
|
||||
{
|
||||
return this.toggleButton.label;
|
||||
}
|
||||
|
||||
setInitialState()
|
||||
{
|
||||
this.label = '00:00/00:00';
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||
{
|
||||
this.scrolledWindow.max_content_height = (isFullscreen && !isMobileMonitor)
|
||||
? 190 : 150;
|
||||
}
|
||||
});
|
||||
|
||||
var TrackSelectButton = GObject.registerClass({
|
||||
GTypeName: 'ClapperTrackSelectButton',
|
||||
Template: `file://${Misc.getClapperPath()}/ui/track-select-button.ui`,
|
||||
Children: ['popoverBox'],
|
||||
InternalChildren: ['scrolled_window', 'decoder_separator'],
|
||||
},
|
||||
class ClapperTrackSelectButton extends PopoverButtonBase
|
||||
{
|
||||
_init(opts)
|
||||
{
|
||||
super._init(opts);
|
||||
|
||||
this._scrolled_window.max_content_height = 220;
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||
{
|
||||
this._scrolled_window.max_content_height = (isFullscreen && !isMobileMonitor)
|
||||
? 290 : 220;
|
||||
}
|
||||
});
|
||||
|
||||
var VolumeButton = GObject.registerClass({
|
||||
GTypeName: 'ClapperVolumeButton',
|
||||
Template: `file://${Misc.getClapperPath()}/ui/volume-button.ui`,
|
||||
Children: ['volumeScale'],
|
||||
},
|
||||
class ClapperVolumeButton extends PopoverButtonBase
|
||||
{
|
||||
_onVolumeScaleValueChanged(scale)
|
||||
{
|
||||
const volume = scale.get_value();
|
||||
const cssClass = 'overamp';
|
||||
const hasOveramp = (scale.has_css_class(cssClass));
|
||||
|
||||
if(volume > 1) {
|
||||
if(!hasOveramp)
|
||||
scale.add_css_class(cssClass);
|
||||
}
|
||||
else {
|
||||
if(hasOveramp)
|
||||
scale.remove_css_class(cssClass);
|
||||
}
|
||||
|
||||
const icon = (volume <= 0)
|
||||
? 'muted'
|
||||
: (volume <= 0.3)
|
||||
? 'low'
|
||||
: (volume <= 0.7)
|
||||
? 'medium'
|
||||
: (volume <= 1)
|
||||
? 'high'
|
||||
: 'overamplified';
|
||||
|
||||
this.icon_name = `audio-volume-${icon}-symbolic`;
|
||||
}
|
||||
});
|
||||
|
246
src/controls.js
vendored
246
src/controls.js
vendored
@@ -29,15 +29,29 @@ class ClapperControls extends Gtk.Box
|
||||
|
||||
this.showHours = false;
|
||||
this.durationFormatted = '00:00';
|
||||
this.buttonsArr = [];
|
||||
this.revealersArr = [];
|
||||
this.chapters = null;
|
||||
|
||||
this.chapterShowId = null;
|
||||
this.chapterHideId = null;
|
||||
|
||||
this._addTogglePlayButton();
|
||||
this._addElapsedButton();
|
||||
this.togglePlayButton = new Buttons.IconToggleButton(
|
||||
'media-playback-start-symbolic',
|
||||
'media-playback-pause-symbolic'
|
||||
);
|
||||
this.togglePlayButton.child.add_css_class('playbackicon');
|
||||
this.togglePlayButton.connect(
|
||||
'clicked', this._onTogglePlayClicked.bind(this)
|
||||
);
|
||||
this.append(this.togglePlayButton);
|
||||
|
||||
const elapsedRevealer = new Revealers.ButtonsRevealer('SLIDE_RIGHT');
|
||||
this.elapsedButton = new Buttons.ElapsedTimeButton();
|
||||
elapsedRevealer.append(this.elapsedButton);
|
||||
elapsedRevealer.reveal_child = true;
|
||||
this.append(elapsedRevealer);
|
||||
this.revealersArr.push(elapsedRevealer);
|
||||
|
||||
this._addPositionScale();
|
||||
|
||||
const revealTracksButton = new Buttons.IconToggleButton(
|
||||
@@ -45,30 +59,29 @@ class ClapperControls extends Gtk.Box
|
||||
'go-next-symbolic'
|
||||
);
|
||||
revealTracksButton.add_css_class('narrowbutton');
|
||||
this.buttonsArr.push(revealTracksButton);
|
||||
const tracksRevealer = new Revealers.ButtonsRevealer(
|
||||
'SLIDE_LEFT', revealTracksButton
|
||||
);
|
||||
this.visualizationsButton = this.addIconPopoverButton(
|
||||
'display-projector-symbolic',
|
||||
tracksRevealer
|
||||
);
|
||||
this.visualizationsButton.set_visible(false);
|
||||
this.videoTracksButton = this.addIconPopoverButton(
|
||||
'emblem-videos-symbolic',
|
||||
tracksRevealer
|
||||
);
|
||||
this.videoTracksButton.set_visible(false);
|
||||
this.audioTracksButton = this.addIconPopoverButton(
|
||||
'emblem-music-symbolic',
|
||||
tracksRevealer
|
||||
);
|
||||
this.audioTracksButton.set_visible(false);
|
||||
this.subtitleTracksButton = this.addIconPopoverButton(
|
||||
'media-view-subtitles-symbolic',
|
||||
tracksRevealer
|
||||
);
|
||||
this.subtitleTracksButton.set_visible(false);
|
||||
this.visualizationsButton = new Buttons.TrackSelectButton({
|
||||
icon_name: 'display-projector-symbolic',
|
||||
visible: false,
|
||||
});
|
||||
tracksRevealer.append(this.visualizationsButton);
|
||||
this.videoTracksButton = new Buttons.TrackSelectButton({
|
||||
icon_name: 'emblem-videos-symbolic',
|
||||
visible: false,
|
||||
});
|
||||
tracksRevealer.append(this.videoTracksButton);
|
||||
this.audioTracksButton = new Buttons.TrackSelectButton({
|
||||
icon_name: 'emblem-music-symbolic',
|
||||
visible: false,
|
||||
});
|
||||
tracksRevealer.append(this.audioTracksButton);
|
||||
this.subtitleTracksButton = new Buttons.TrackSelectButton({
|
||||
icon_name: 'media-view-subtitles-symbolic',
|
||||
visible: false,
|
||||
});
|
||||
tracksRevealer.append(this.subtitleTracksButton);
|
||||
|
||||
this.revealTracksRevealer = new Revealers.ButtonsRevealer('SLIDE_LEFT');
|
||||
this.revealTracksRevealer.append(revealTracksButton);
|
||||
@@ -79,24 +92,30 @@ class ClapperControls extends Gtk.Box
|
||||
this.revealersArr.push(tracksRevealer);
|
||||
this.append(tracksRevealer);
|
||||
|
||||
this._addVolumeButton();
|
||||
this.unfullscreenButton = this.addButton(
|
||||
'view-restore-symbolic'
|
||||
);
|
||||
this.volumeButton = new Buttons.VolumeButton();
|
||||
this.append(this.volumeButton);
|
||||
|
||||
this.unfullscreenButton = new Buttons.CustomButton({
|
||||
icon_name: 'view-restore-symbolic',
|
||||
});
|
||||
this.unfullscreenButton.connect('clicked', this._onUnfullscreenClicked.bind(this));
|
||||
this.unfullscreenButton.set_visible(false);
|
||||
this.append(this.unfullscreenButton);
|
||||
|
||||
this.add_css_class('playercontrols');
|
||||
this.add_css_class('clappercontrols');
|
||||
this.realizeSignal = this.connect('realize', this._onRealize.bind(this));
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen)
|
||||
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||
{
|
||||
/* Allow recheck on next resize */
|
||||
this.isMobile = null;
|
||||
|
||||
for(let button of this.buttonsArr)
|
||||
button.setFullscreenMode(isFullscreen);
|
||||
this.elapsedButton.setFullscreenMode(isFullscreen, isMobileMonitor);
|
||||
this.visualizationsButton.setFullscreenMode(isFullscreen, isMobileMonitor);
|
||||
this.videoTracksButton.setFullscreenMode(isFullscreen, isMobileMonitor);
|
||||
this.audioTracksButton.setFullscreenMode(isFullscreen, isMobileMonitor);
|
||||
this.subtitleTracksButton.setFullscreenMode(isFullscreen, isMobileMonitor);
|
||||
|
||||
this.unfullscreenButton.visible = isFullscreen;
|
||||
this.isFullscreen = isFullscreen;
|
||||
@@ -105,7 +124,7 @@ class ClapperControls extends Gtk.Box
|
||||
setLiveMode(isLive, isSeekable)
|
||||
{
|
||||
if(isLive)
|
||||
this.elapsedButton.set_label('LIVE');
|
||||
this.elapsedButton.label = 'LIVE';
|
||||
|
||||
this.positionScale.visible = isSeekable;
|
||||
}
|
||||
@@ -116,7 +135,7 @@ class ClapperControls extends Gtk.Box
|
||||
this.positionScale.set_value(0);
|
||||
this.positionScale.visible = false;
|
||||
|
||||
this.elapsedButton.set_label(INITIAL_ELAPSED);
|
||||
this.elapsedButton.setInitialState();
|
||||
this.togglePlayButton.setPrimaryIcon();
|
||||
|
||||
for(let type of ['video', 'audio', 'subtitle'])
|
||||
@@ -132,46 +151,7 @@ class ClapperControls extends Gtk.Box
|
||||
const elapsed = Misc.getFormattedTime(value, this.showHours)
|
||||
+ '/' + this.durationFormatted;
|
||||
|
||||
this.elapsedButton.set_label(elapsed);
|
||||
}
|
||||
|
||||
addButton(buttonIcon, revealer)
|
||||
{
|
||||
const button = (buttonIcon instanceof Gtk.Button)
|
||||
? buttonIcon
|
||||
: new Buttons.CustomButton({ icon_name: buttonIcon });
|
||||
|
||||
if(!revealer)
|
||||
this.append(button);
|
||||
else
|
||||
revealer.append(button);
|
||||
|
||||
this.buttonsArr.push(button);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
addIconPopoverButton(iconName, revealer)
|
||||
{
|
||||
const button = new Buttons.IconPopoverButton(iconName);
|
||||
|
||||
return this.addButton(button, revealer);
|
||||
}
|
||||
|
||||
addLabelPopoverButton(text, revealer)
|
||||
{
|
||||
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);
|
||||
this.elapsedButton.label = elapsed;
|
||||
}
|
||||
|
||||
addCheckButtons(box, array, activeId)
|
||||
@@ -285,51 +265,6 @@ class ClapperControls extends Gtk.Box
|
||||
}
|
||||
}
|
||||
|
||||
_addTogglePlayButton()
|
||||
{
|
||||
this.togglePlayButton = new Buttons.IconToggleButton(
|
||||
'media-playback-start-symbolic',
|
||||
'media-playback-pause-symbolic'
|
||||
);
|
||||
this.togglePlayButton.child.add_css_class('playbackicon');
|
||||
this.togglePlayButton.connect(
|
||||
'clicked', this._onTogglePlayClicked.bind(this)
|
||||
);
|
||||
this.addButton(this.togglePlayButton);
|
||||
}
|
||||
|
||||
_addElapsedButton()
|
||||
{
|
||||
const elapsedRevealer = new Revealers.ButtonsRevealer('SLIDE_RIGHT');
|
||||
this.elapsedButton = this.addElapsedPopoverButton(INITIAL_ELAPSED, elapsedRevealer);
|
||||
elapsedRevealer.set_reveal_child(true);
|
||||
this.revealersArr.push(elapsedRevealer);
|
||||
|
||||
this.elapsedButton.addSeparator('Speed');
|
||||
const speedScale = new Gtk.Scale({
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
value_pos: Gtk.PositionType.BOTTOM,
|
||||
draw_value: false,
|
||||
round_digits: 2,
|
||||
hexpand: true,
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
speedScale.add_css_class('speedscale');
|
||||
|
||||
this.speedAdjustment = speedScale.get_adjustment();
|
||||
this.speedAdjustment.set_lower(0.01);
|
||||
this.speedAdjustment.set_upper(2);
|
||||
this.speedAdjustment.set_value(1);
|
||||
this.speedAdjustment.set_page_increment(0.1);
|
||||
|
||||
speedScale.add_mark(0.25, Gtk.PositionType.BOTTOM, '0.25x');
|
||||
speedScale.add_mark(1, Gtk.PositionType.BOTTOM, 'Normal');
|
||||
speedScale.add_mark(2, Gtk.PositionType.BOTTOM, '2x');
|
||||
|
||||
this.elapsedButton.popoverBox.append(speedScale);
|
||||
this.append(elapsedRevealer);
|
||||
}
|
||||
|
||||
_addPositionScale()
|
||||
{
|
||||
this.positionScale = new Gtk.Scale({
|
||||
@@ -381,36 +316,6 @@ class ClapperControls extends Gtk.Box
|
||||
this.append(box);
|
||||
}
|
||||
|
||||
_addVolumeButton()
|
||||
{
|
||||
this.volumeButton = this.addIconPopoverButton(
|
||||
'audio-volume-muted-symbolic'
|
||||
);
|
||||
this.volumeScale = new Gtk.Scale({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
inverted: true,
|
||||
value_pos: Gtk.PositionType.TOP,
|
||||
draw_value: false,
|
||||
vexpand: true,
|
||||
});
|
||||
this.volumeScale.add_css_class('volumescale');
|
||||
this.volumeAdjustment = this.volumeScale.get_adjustment();
|
||||
|
||||
this.volumeAdjustment.set_upper(Misc.maxVolume);
|
||||
this.volumeAdjustment.set_step_increment(0.05);
|
||||
this.volumeAdjustment.set_page_increment(0.05);
|
||||
|
||||
for(let i of [0, 1, Misc.maxVolume]) {
|
||||
const text = (!i) ? '0%' : (i % 1 === 0) ? `${i}00%` : `${i * 10}0%`;
|
||||
this.volumeScale.add_mark(i, Gtk.PositionType.LEFT, text);
|
||||
}
|
||||
|
||||
this.volumeScale.connect(
|
||||
'value-changed', this._onVolumeScaleValueChanged.bind(this)
|
||||
);
|
||||
this.volumeButton.popoverBox.append(this.volumeScale);
|
||||
}
|
||||
|
||||
_setChapterVisible(isVisible)
|
||||
{
|
||||
const type = (isVisible) ? 'Show' : 'Hide';
|
||||
@@ -553,42 +458,6 @@ class ClapperControls extends Gtk.Box
|
||||
}
|
||||
}
|
||||
|
||||
_onVolumeScaleValueChanged(scale)
|
||||
{
|
||||
const volume = scale.get_value();
|
||||
|
||||
/* FIXME: All of below should be placed in 'volume-changed'
|
||||
* event once we move to message bus API */
|
||||
const cssClass = 'overamp';
|
||||
const hasOveramp = (scale.has_css_class(cssClass));
|
||||
|
||||
if(volume > 1) {
|
||||
if(!hasOveramp)
|
||||
scale.add_css_class(cssClass);
|
||||
}
|
||||
else {
|
||||
if(hasOveramp)
|
||||
scale.remove_css_class(cssClass);
|
||||
}
|
||||
|
||||
const icon = (volume <= 0)
|
||||
? 'muted'
|
||||
: (volume <= 0.3)
|
||||
? 'low'
|
||||
: (volume <= 0.7)
|
||||
? 'medium'
|
||||
: (volume <= 1)
|
||||
? 'high'
|
||||
: 'overamplified';
|
||||
|
||||
const iconName = `audio-volume-${icon}-symbolic`;
|
||||
if(this.volumeButton.icon_name === iconName)
|
||||
return;
|
||||
|
||||
this.volumeButton.icon_name = iconName;
|
||||
debug(`set volume icon: ${icon}`);
|
||||
}
|
||||
|
||||
_onPositionScaleDragging(scale)
|
||||
{
|
||||
const isPositionDragging = scale.has_css_class('dragging');
|
||||
@@ -638,13 +507,6 @@ class ClapperControls extends Gtk.Box
|
||||
this.positionScale.disconnect(this.positionScaleValueSignal);
|
||||
this.positionScale.disconnect(this.positionScaleDragSignal);
|
||||
|
||||
for(let button of this.buttonsArr) {
|
||||
if(!button._onCloseRequest)
|
||||
continue;
|
||||
|
||||
button._onCloseRequest();
|
||||
}
|
||||
|
||||
this.chapterPopover.unparent();
|
||||
}
|
||||
});
|
||||
|
@@ -354,9 +354,9 @@ class ClapperPlayer extends GstClapper.Clapper
|
||||
|
||||
const { controls } = this.widget.get_ancestor(Gtk.Grid);
|
||||
const value = (isIncrease) ? offset : -offset;
|
||||
const volume = controls.volumeScale.get_value() + value;
|
||||
const scale = controls.volumeButton.volumeScale;
|
||||
|
||||
controls.volumeScale.set_value(volume);
|
||||
scale.set_value(scale.get_value() + value);
|
||||
}
|
||||
|
||||
next_chapter()
|
||||
|
@@ -28,7 +28,7 @@ class ClapperPlaylistWidget extends Gtk.ListBox
|
||||
});
|
||||
this.activeRowId = -1;
|
||||
this.repeatMode = RepeatMode.NONE;
|
||||
this.add_css_class('playlist');
|
||||
this.add_css_class('clapperplaylist');
|
||||
|
||||
this.connect('row-activated', this._onRowActivated.bind(this));
|
||||
}
|
||||
@@ -255,7 +255,6 @@ class ClapperPlaylistItem extends Gtk.ListBoxRow
|
||||
}
|
||||
this.filename = filename || uri;
|
||||
this.set_tooltip_text(this.filename);
|
||||
this.add_css_class('playlistrow');
|
||||
|
||||
const box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
@@ -270,7 +269,6 @@ class ClapperPlaylistItem extends Gtk.ListBoxRow
|
||||
});
|
||||
repeatButton.add_css_class('flat');
|
||||
repeatButton.add_css_class('circular');
|
||||
repeatButton.add_css_class('popoverbutton');
|
||||
repeatButton.connect('clicked', this._onRepeatClicked.bind(this));
|
||||
const label = new Gtk.Label({
|
||||
label: this.filename,
|
||||
@@ -285,7 +283,6 @@ class ClapperPlaylistItem extends Gtk.ListBoxRow
|
||||
});
|
||||
removeButton.add_css_class('flat');
|
||||
removeButton.add_css_class('circular');
|
||||
removeButton.add_css_class('popoverbutton');
|
||||
removeButton.connect('clicked', this._onRemoveClicked.bind(this));
|
||||
|
||||
box.append(repeatButton);
|
||||
|
@@ -65,12 +65,16 @@ class ClapperWidget extends Gtk.Grid
|
||||
|
||||
this.controls.elapsedButton.scrolledWindow.set_child(this.player.playlistWidget);
|
||||
|
||||
this.controls.speedAdjustment.bind_property(
|
||||
const speedAdjustment = this.controls.elapsedButton.speedScale.get_adjustment();
|
||||
speedAdjustment.bind_property(
|
||||
'value', this.player, 'rate', GObject.BindingFlags.BIDIRECTIONAL
|
||||
);
|
||||
this.controls.volumeAdjustment.bind_property(
|
||||
|
||||
const volumeAdjustment = this.controls.volumeButton.volumeScale.get_adjustment();
|
||||
volumeAdjustment.bind_property(
|
||||
'value', this.player, 'volume', GObject.BindingFlags.BIDIRECTIONAL
|
||||
);
|
||||
|
||||
this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this));
|
||||
this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this));
|
||||
this.player.connect('media-info-updated', this._onMediaInfoUpdated.bind(this));
|
||||
@@ -155,7 +159,7 @@ class ClapperWidget extends Gtk.Grid
|
||||
this.revealerBottom.revealerBox.visible = isFullscreen;
|
||||
|
||||
this._changeControlsPlacement(isFullscreen);
|
||||
this.controls.setFullscreenMode(isFullscreen);
|
||||
this.controls.setFullscreenMode(isFullscreen, this.isMobileMonitor);
|
||||
|
||||
if(this.revealerTop.child_revealed)
|
||||
this._checkSetUpdateTimeInterval();
|
||||
|
58
ui/elapsed-time-button.ui
Normal file
58
ui/elapsed-time-button.ui
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ClapperElapsedTimeButton" parent="ClapperPopoverButtonBase">
|
||||
<property name="popover">popover</property>
|
||||
<property name="direction">up</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</template>
|
||||
<object class="GtkPopover" id="popover">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledWindow">
|
||||
<property name="propagate_natural_width">False</property>
|
||||
<property name="propagate_natural_height">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ClapperPopoverSeparator">
|
||||
<property name="label" translatable="yes">Speed</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="speedScale">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="value_pos">bottom</property>
|
||||
<property name="draw_value">False</property>
|
||||
<property name="round_digits">2</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">speed_adjustment</property>
|
||||
<marks>
|
||||
<mark value="0.25" position="bottom">0.25x</mark>
|
||||
<mark value="1" position="bottom" translatable="yes">Normal</mark>
|
||||
<mark value="2" position="bottom">2x</mark>
|
||||
</marks>
|
||||
<style>
|
||||
<class name="speedscale"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="speed_adjustment">
|
||||
<property name="lower">0.01</property>
|
||||
<property name="upper">2</property>
|
||||
<property name="value">1</property>
|
||||
<property name="page-increment">0.1</property>
|
||||
</object>
|
||||
</interface>
|
@@ -3,6 +3,9 @@
|
||||
<template class="ClapperPopoverSeparator" parent="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="hexpand">True</property>
|
||||
<style>
|
||||
<class name="popoverseparator"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">horizontal</property>
|
||||
|
37
ui/track-select-button.ui
Normal file
37
ui/track-select-button.ui
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ClapperTrackSelectButton" parent="ClapperPopoverButtonBase">
|
||||
<property name="popover">popover</property>
|
||||
<property name="direction">up</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</template>
|
||||
<object class="GtkPopover" id="popover">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="ClapperPopoverSeparator" id="decoder_separator">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolled_window">
|
||||
<property name="propagate_natural_width">True</property>
|
||||
<property name="propagate_natural_height">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="popoverBox">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
48
ui/volume-button.ui
Normal file
48
ui/volume-button.ui
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ClapperVolumeButton" parent="ClapperPopoverButtonBase">
|
||||
<property name="icon_name">audio-volume-muted-symbolic</property>
|
||||
<property name="popover">popover</property>
|
||||
<property name="direction">up</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</template>
|
||||
<object class="GtkPopover" id="popover">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkScale" id="volumeScale">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="inverted">True</property>
|
||||
<property name="value_pos">top</property>
|
||||
<property name="draw_value">False</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="adjustment">volume_adjustment</property>
|
||||
<signal name="value-changed" handler="_onVolumeScaleValueChanged"/>
|
||||
<marks>
|
||||
<mark value="0" position="left">0%</mark>
|
||||
<mark value="1" position="left">100%</mark>
|
||||
<mark value="1.5" position="left">150%</mark>
|
||||
</marks>
|
||||
<style>
|
||||
<class name="volumescale"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="volume_adjustment">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">1.5</property>
|
||||
<property name="step-increment">0.05</property>
|
||||
<property name="page-increment">0.05</property>
|
||||
</object>
|
||||
</interface>
|
Reference in New Issue
Block a user