mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 15:52:10 +02:00
@@ -5,17 +5,33 @@ scale marks {
|
|||||||
radio {
|
radio {
|
||||||
margin-left: -2px;
|
margin-left: -2px;
|
||||||
}
|
}
|
||||||
|
scrolledwindow scrollbar.vertical slider {
|
||||||
|
min-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Adwaita is missing osd ListBox */
|
/* Adwaita is missing osd ListBox */
|
||||||
.playlistrow {
|
.clapperplaylist row {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
.playlistrow {
|
.clapperplaylist row {
|
||||||
color: @theme_fg_color;
|
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;
|
background: none;
|
||||||
}
|
}
|
||||||
.osd .playlist row image {
|
.osd .clapperplaylist row image {
|
||||||
-gtk-icon-shadow: none;
|
-gtk-icon-shadow: none;
|
||||||
}
|
}
|
||||||
.osdheaderbar {
|
.osdheaderbar {
|
||||||
@@ -41,6 +57,9 @@ popover contents {
|
|||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
.popoverseparator separator {
|
||||||
|
background-color: @insensitive_fg_color;
|
||||||
|
}
|
||||||
|
|
||||||
/* Rounded corners */
|
/* Rounded corners */
|
||||||
.adwrounded.csd {
|
.adwrounded.csd {
|
||||||
@@ -79,25 +98,29 @@ scale trough slider {
|
|||||||
font-size: 21px;
|
font-size: 21px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.adwicons .playercontrols {
|
.adwicons .clappercontrols {
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
}
|
}
|
||||||
.playercontrols {
|
.clappercontrols {
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
.playercontrols button {
|
.clappercontrolsbutton {
|
||||||
margin: 3px;
|
margin: 3px;
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
}
|
}
|
||||||
.fullscreen.tvmode .playercontrols button {
|
.fullscreen.tvmode .clappercontrolsbutton {
|
||||||
min-width: 32px;
|
min-width: 32px;
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
}
|
}
|
||||||
|
.clappercontrolsbutton.text-button {
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
.fullscreen.tvmode button image {
|
.fullscreen.tvmode button image {
|
||||||
-gtk-icon-shadow: none;
|
-gtk-icon-shadow: none;
|
||||||
}
|
}
|
||||||
@@ -109,7 +132,8 @@ scale trough slider {
|
|||||||
min-height: 17px;
|
min-height: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen.tvmode .playercontrols button image {
|
/* Also affects popover buttons */
|
||||||
|
.fullscreen.tvmode .clappercontrols button image {
|
||||||
-gtk-icon-size: 24px;
|
-gtk-icon-size: 24px;
|
||||||
}
|
}
|
||||||
.adwicons .playbackicon {
|
.adwicons .playbackicon {
|
||||||
@@ -118,15 +142,12 @@ scale trough slider {
|
|||||||
.adwicons.fullscreen.tvmode .playbackicon {
|
.adwicons.fullscreen.tvmode .playbackicon {
|
||||||
-gtk-icon-size: 28px;
|
-gtk-icon-size: 28px;
|
||||||
}
|
}
|
||||||
.labelbuttonlabel {
|
.clappercontrolsbutton.text-button label {
|
||||||
margin-left: -4px;
|
|
||||||
margin-right: -4px;
|
|
||||||
min-width: 8px;
|
|
||||||
font-family: 'Cantarell', sans-serif;
|
font-family: 'Cantarell', sans-serif;
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.fullscreen.tvmode .labelbuttonlabel {
|
.fullscreen.tvmode .clappercontrolsbutton.text-button label {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
@@ -157,12 +178,6 @@ scale trough slider {
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Button Inside Popover */
|
|
||||||
.popoverbutton {
|
|
||||||
min-width: 24px;
|
|
||||||
min-height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Position Scale */
|
/* Position Scale */
|
||||||
.positionscale {
|
.positionscale {
|
||||||
margin: -2px;
|
margin: -2px;
|
||||||
@@ -245,14 +260,14 @@ scale trough slider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Elapsed Popover */
|
/* Elapsed Popover */
|
||||||
.elapsedpopoverbox {
|
.elapsedpopover {
|
||||||
min-width: 260px;
|
min-width: 326px;
|
||||||
}
|
}
|
||||||
.elapsedpopoverbox box separator {
|
.fullscreen.tvmode .elapsedpopover {
|
||||||
background: @insensitive_fg_color;
|
min-width: 448px;
|
||||||
}
|
}
|
||||||
.fullscreen.tvmode .elapsedpopoverbox {
|
.elapsedpopover contents {
|
||||||
min-width: 360px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
.speedscale trough highlight {
|
.speedscale trough highlight {
|
||||||
min-height: 4px;
|
min-height: 4px;
|
||||||
|
279
src/buttons.js
279
src/buttons.js
@@ -1,10 +1,5 @@
|
|||||||
const { GObject, Gtk } = imports.gi;
|
const { GObject, Gtk } = imports.gi;
|
||||||
|
const Misc = imports.src.misc;
|
||||||
/* Negative values from CSS */
|
|
||||||
const PopoverOffset = {
|
|
||||||
DEFAULT: -3,
|
|
||||||
TVMODE: -5,
|
|
||||||
};
|
|
||||||
|
|
||||||
var CustomButton = GObject.registerClass(
|
var CustomButton = GObject.registerClass(
|
||||||
class ClapperCustomButton extends Gtk.Button
|
class ClapperCustomButton extends Gtk.Button
|
||||||
@@ -22,28 +17,15 @@ class ClapperCustomButton extends Gtk.Button
|
|||||||
|
|
||||||
super._init(opts);
|
super._init(opts);
|
||||||
|
|
||||||
this.isFullscreen = false;
|
|
||||||
this.add_css_class('flat');
|
this.add_css_class('flat');
|
||||||
}
|
this.add_css_class('clappercontrolsbutton');
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_clicked()
|
vfunc_clicked()
|
||||||
{
|
{
|
||||||
if(!this.isFullscreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||||
|
|
||||||
|
if(clapperWidget.isFullscreenMode)
|
||||||
clapperWidget.revealControls();
|
clapperWidget.revealControls();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -72,79 +54,73 @@ class ClapperIconToggleButton extends CustomButton
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var PopoverButtonBase = GObject.registerClass(
|
var PopoverSeparator = GObject.registerClass({
|
||||||
class ClapperPopoverButtonBase extends Gtk.ToggleButton
|
GTypeName: 'ClapperPopoverSeparator',
|
||||||
|
Template: `file://${Misc.getClapperPath()}/ui/popover-separator.ui`,
|
||||||
|
InternalChildren: ['middle_label'],
|
||||||
|
Properties: {
|
||||||
|
'label': GObject.ParamSpec.string(
|
||||||
|
'label',
|
||||||
|
'Middle label',
|
||||||
|
'Text to set in the middle',
|
||||||
|
GObject.ParamFlags.WRITABLE,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
class ClapperPopoverSeparator extends Gtk.Box
|
||||||
{
|
{
|
||||||
_init()
|
_init(opts)
|
||||||
{
|
{
|
||||||
super._init({
|
super._init();
|
||||||
halign: Gtk.Align.CENTER,
|
|
||||||
valign: Gtk.Align.CENTER,
|
|
||||||
can_focus: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.isFullscreen = false;
|
if(!opts.label)
|
||||||
this.add_css_class('flat');
|
this.visible = false;
|
||||||
|
|
||||||
this.popover = new Gtk.Popover({
|
this.label = opts.label;
|
||||||
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)
|
set label(value)
|
||||||
{
|
{
|
||||||
if(this.isFullscreen === isFullscreen)
|
this._middle_label.label = value || "";
|
||||||
return;
|
|
||||||
|
|
||||||
/* Redraw icon after style class change */
|
if(value)
|
||||||
if(this.icon_name)
|
this.visible = true;
|
||||||
this.set_icon_name(this.icon_name);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.isFullscreen = isFullscreen;
|
var PopoverButtonBase = GObject.registerClass({
|
||||||
|
GTypeName: 'ClapperPopoverButtonBase',
|
||||||
|
},
|
||||||
|
class ClapperPopoverButtonBase extends Gtk.MenuButton
|
||||||
|
{
|
||||||
|
_init(opts = {})
|
||||||
|
{
|
||||||
|
super._init(opts);
|
||||||
|
|
||||||
/* TODO: Fullscreen non-tv mode */
|
if(opts.icon_name)
|
||||||
const offset = (isFullscreen)
|
this.icon_name = opts.icon_name;
|
||||||
? PopoverOffset.TVMODE
|
else if(opts.label)
|
||||||
: PopoverOffset.DEFAULT;
|
this.label = opts.label;
|
||||||
|
|
||||||
this.popover.set_offset(0, offset);
|
this.toggleButton = this.get_first_child();
|
||||||
|
this.toggleButton.add_css_class('clappercontrolsbutton');
|
||||||
|
|
||||||
const cssClass = 'osd';
|
this.set_create_popup_func(this._onPopoverOpened);
|
||||||
if(isFullscreen === this.popover.has_css_class(cssClass))
|
this.popover.connect('closed', this._onPopoverClosed.bind(this));
|
||||||
return;
|
|
||||||
|
|
||||||
const action = (isFullscreen) ? 'add' : 'remove';
|
|
||||||
this.popover[action + '_css_class'](cssClass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_toggled()
|
_onPopoverOpened(self)
|
||||||
{
|
{
|
||||||
if(!this.active)
|
const clapperWidget = self.get_ancestor(Gtk.Grid);
|
||||||
return;
|
|
||||||
|
|
||||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
if(clapperWidget.isFullscreenMode) {
|
||||||
|
|
||||||
if(this.isFullscreen) {
|
|
||||||
clapperWidget.revealControls();
|
clapperWidget.revealControls();
|
||||||
clapperWidget.isPopoverOpen = true;
|
clapperWidget.isPopoverOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.popover.popup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClosed()
|
_onPopoverClosed(popover)
|
||||||
{
|
{
|
||||||
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
const clapperWidget = this.get_ancestor(Gtk.Grid);
|
||||||
|
|
||||||
@@ -153,94 +129,107 @@ class ClapperPopoverButtonBase extends Gtk.ToggleButton
|
|||||||
clapperWidget.revealControls();
|
clapperWidget.revealControls();
|
||||||
|
|
||||||
clapperWidget.isPopoverOpen = false;
|
clapperWidget.isPopoverOpen = false;
|
||||||
this.active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onCloseRequest()
|
|
||||||
{
|
|
||||||
this.popover.unparent();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var IconPopoverButton = GObject.registerClass(
|
var ElapsedTimeButton = GObject.registerClass({
|
||||||
class ClapperIconPopoverButton extends PopoverButtonBase
|
GTypeName: 'ClapperElapsedTimeButton',
|
||||||
|
Template: `file://${Misc.getClapperPath()}/ui/elapsed-time-button.ui`,
|
||||||
|
Children: ['scrolledWindow', 'speedScale'],
|
||||||
|
},
|
||||||
|
class ClapperElapsedTimeButton extends PopoverButtonBase
|
||||||
{
|
{
|
||||||
_init(icon)
|
_init(opts)
|
||||||
{
|
{
|
||||||
super._init();
|
super._init(opts);
|
||||||
|
|
||||||
this.icon_name = icon;
|
this.setInitialState();
|
||||||
}
|
this.popover.add_css_class('elapsedpopover');
|
||||||
});
|
|
||||||
|
|
||||||
var LabelPopoverButton = GObject.registerClass(
|
this.scrolledWindow.max_content_height = 150;
|
||||||
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)
|
set label(value)
|
||||||
{
|
{
|
||||||
this.customLabel.set_text(text);
|
this.toggleButton.label = value;
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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)
|
get label()
|
||||||
{
|
{
|
||||||
super.setFullscreenMode(isFullscreen);
|
return this.toggleButton.label;
|
||||||
|
}
|
||||||
|
|
||||||
this.scrolledWindow.max_content_height = (isFullscreen)
|
setInitialState()
|
||||||
|
{
|
||||||
|
this.label = '00:00/00:00';
|
||||||
|
}
|
||||||
|
|
||||||
|
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||||
|
{
|
||||||
|
this.scrolledWindow.max_content_height = (isFullscreen && !isMobileMonitor)
|
||||||
? 190 : 150;
|
? 190 : 150;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
addSeparator(text)
|
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
|
||||||
{
|
{
|
||||||
const box = new Gtk.Box({
|
_init(opts)
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
{
|
||||||
hexpand: true,
|
super._init(opts);
|
||||||
});
|
|
||||||
const label = new Gtk.Label({
|
this._scrolled_window.max_content_height = 220;
|
||||||
label: text,
|
}
|
||||||
halign: Gtk.Align.CENTER,
|
|
||||||
});
|
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||||
const leftSeparator = new Gtk.Separator({
|
{
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
this._scrolled_window.max_content_height = (isFullscreen && !isMobileMonitor)
|
||||||
hexpand: true,
|
? 290 : 220;
|
||||||
valign: Gtk.Align.CENTER,
|
}
|
||||||
});
|
|
||||||
const rightSeparator = new Gtk.Separator({
|
setDecoder(decoder)
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
{
|
||||||
hexpand: true,
|
this._decoder_separator.label = _('Decoder: %s').format(decoder);
|
||||||
valign: Gtk.Align.CENTER,
|
}
|
||||||
});
|
});
|
||||||
box.append(leftSeparator);
|
|
||||||
box.append(label);
|
var VolumeButton = GObject.registerClass({
|
||||||
box.append(rightSeparator);
|
GTypeName: 'ClapperVolumeButton',
|
||||||
this.popoverBox.append(box);
|
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.showHours = false;
|
||||||
this.durationFormatted = '00:00';
|
this.durationFormatted = '00:00';
|
||||||
this.buttonsArr = [];
|
|
||||||
this.revealersArr = [];
|
this.revealersArr = [];
|
||||||
this.chapters = null;
|
this.chapters = null;
|
||||||
|
|
||||||
this.chapterShowId = null;
|
this.chapterShowId = null;
|
||||||
this.chapterHideId = null;
|
this.chapterHideId = null;
|
||||||
|
|
||||||
this._addTogglePlayButton();
|
this.togglePlayButton = new Buttons.IconToggleButton(
|
||||||
this._addElapsedButton();
|
'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();
|
this._addPositionScale();
|
||||||
|
|
||||||
const revealTracksButton = new Buttons.IconToggleButton(
|
const revealTracksButton = new Buttons.IconToggleButton(
|
||||||
@@ -45,30 +59,29 @@ class ClapperControls extends Gtk.Box
|
|||||||
'go-next-symbolic'
|
'go-next-symbolic'
|
||||||
);
|
);
|
||||||
revealTracksButton.add_css_class('narrowbutton');
|
revealTracksButton.add_css_class('narrowbutton');
|
||||||
this.buttonsArr.push(revealTracksButton);
|
|
||||||
const tracksRevealer = new Revealers.ButtonsRevealer(
|
const tracksRevealer = new Revealers.ButtonsRevealer(
|
||||||
'SLIDE_LEFT', revealTracksButton
|
'SLIDE_LEFT', revealTracksButton
|
||||||
);
|
);
|
||||||
this.visualizationsButton = this.addIconPopoverButton(
|
this.visualizationsButton = new Buttons.TrackSelectButton({
|
||||||
'display-projector-symbolic',
|
icon_name: 'display-projector-symbolic',
|
||||||
tracksRevealer
|
visible: false,
|
||||||
);
|
});
|
||||||
this.visualizationsButton.set_visible(false);
|
tracksRevealer.append(this.visualizationsButton);
|
||||||
this.videoTracksButton = this.addIconPopoverButton(
|
this.videoTracksButton = new Buttons.TrackSelectButton({
|
||||||
'emblem-videos-symbolic',
|
icon_name: 'emblem-videos-symbolic',
|
||||||
tracksRevealer
|
visible: false,
|
||||||
);
|
});
|
||||||
this.videoTracksButton.set_visible(false);
|
tracksRevealer.append(this.videoTracksButton);
|
||||||
this.audioTracksButton = this.addIconPopoverButton(
|
this.audioTracksButton = new Buttons.TrackSelectButton({
|
||||||
'emblem-music-symbolic',
|
icon_name: 'emblem-music-symbolic',
|
||||||
tracksRevealer
|
visible: false,
|
||||||
);
|
});
|
||||||
this.audioTracksButton.set_visible(false);
|
tracksRevealer.append(this.audioTracksButton);
|
||||||
this.subtitleTracksButton = this.addIconPopoverButton(
|
this.subtitleTracksButton = new Buttons.TrackSelectButton({
|
||||||
'media-view-subtitles-symbolic',
|
icon_name: 'media-view-subtitles-symbolic',
|
||||||
tracksRevealer
|
visible: false,
|
||||||
);
|
});
|
||||||
this.subtitleTracksButton.set_visible(false);
|
tracksRevealer.append(this.subtitleTracksButton);
|
||||||
|
|
||||||
this.revealTracksRevealer = new Revealers.ButtonsRevealer('SLIDE_LEFT');
|
this.revealTracksRevealer = new Revealers.ButtonsRevealer('SLIDE_LEFT');
|
||||||
this.revealTracksRevealer.append(revealTracksButton);
|
this.revealTracksRevealer.append(revealTracksButton);
|
||||||
@@ -79,24 +92,30 @@ class ClapperControls extends Gtk.Box
|
|||||||
this.revealersArr.push(tracksRevealer);
|
this.revealersArr.push(tracksRevealer);
|
||||||
this.append(tracksRevealer);
|
this.append(tracksRevealer);
|
||||||
|
|
||||||
this._addVolumeButton();
|
this.volumeButton = new Buttons.VolumeButton();
|
||||||
this.unfullscreenButton = this.addButton(
|
this.append(this.volumeButton);
|
||||||
'view-restore-symbolic'
|
|
||||||
);
|
this.unfullscreenButton = new Buttons.CustomButton({
|
||||||
|
icon_name: 'view-restore-symbolic',
|
||||||
|
});
|
||||||
this.unfullscreenButton.connect('clicked', this._onUnfullscreenClicked.bind(this));
|
this.unfullscreenButton.connect('clicked', this._onUnfullscreenClicked.bind(this));
|
||||||
this.unfullscreenButton.set_visible(false);
|
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));
|
this.realizeSignal = this.connect('realize', this._onRealize.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
setFullscreenMode(isFullscreen)
|
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||||
{
|
{
|
||||||
/* Allow recheck on next resize */
|
/* Allow recheck on next resize */
|
||||||
this.isMobile = null;
|
this.isMobile = null;
|
||||||
|
|
||||||
for(let button of this.buttonsArr)
|
this.elapsedButton.setFullscreenMode(isFullscreen, isMobileMonitor);
|
||||||
button.setFullscreenMode(isFullscreen);
|
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.unfullscreenButton.visible = isFullscreen;
|
||||||
this.isFullscreen = isFullscreen;
|
this.isFullscreen = isFullscreen;
|
||||||
@@ -105,7 +124,7 @@ class ClapperControls extends Gtk.Box
|
|||||||
setLiveMode(isLive, isSeekable)
|
setLiveMode(isLive, isSeekable)
|
||||||
{
|
{
|
||||||
if(isLive)
|
if(isLive)
|
||||||
this.elapsedButton.set_label('LIVE');
|
this.elapsedButton.label = 'LIVE';
|
||||||
|
|
||||||
this.positionScale.visible = isSeekable;
|
this.positionScale.visible = isSeekable;
|
||||||
}
|
}
|
||||||
@@ -116,7 +135,7 @@ class ClapperControls extends Gtk.Box
|
|||||||
this.positionScale.set_value(0);
|
this.positionScale.set_value(0);
|
||||||
this.positionScale.visible = false;
|
this.positionScale.visible = false;
|
||||||
|
|
||||||
this.elapsedButton.set_label(INITIAL_ELAPSED);
|
this.elapsedButton.setInitialState();
|
||||||
this.togglePlayButton.setPrimaryIcon();
|
this.togglePlayButton.setPrimaryIcon();
|
||||||
|
|
||||||
for(let type of ['video', 'audio', 'subtitle'])
|
for(let type of ['video', 'audio', 'subtitle'])
|
||||||
@@ -132,46 +151,7 @@ class ClapperControls extends Gtk.Box
|
|||||||
const elapsed = Misc.getFormattedTime(value, this.showHours)
|
const elapsed = Misc.getFormattedTime(value, this.showHours)
|
||||||
+ '/' + this.durationFormatted;
|
+ '/' + this.durationFormatted;
|
||||||
|
|
||||||
this.elapsedButton.set_label(elapsed);
|
this.elapsedButton.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addCheckButtons(box, array, activeId)
|
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()
|
_addPositionScale()
|
||||||
{
|
{
|
||||||
this.positionScale = new Gtk.Scale({
|
this.positionScale = new Gtk.Scale({
|
||||||
@@ -381,36 +316,6 @@ class ClapperControls extends Gtk.Box
|
|||||||
this.append(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)
|
_setChapterVisible(isVisible)
|
||||||
{
|
{
|
||||||
const type = (isVisible) ? 'Show' : 'Hide';
|
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)
|
_onPositionScaleDragging(scale)
|
||||||
{
|
{
|
||||||
const isPositionDragging = scale.has_css_class('dragging');
|
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.positionScaleValueSignal);
|
||||||
this.positionScale.disconnect(this.positionScaleDragSignal);
|
this.positionScale.disconnect(this.positionScaleDragSignal);
|
||||||
|
|
||||||
for(let button of this.buttonsArr) {
|
|
||||||
if(!button._onCloseRequest)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
button._onCloseRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.chapterPopover.unparent();
|
this.chapterPopover.unparent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -3,6 +3,7 @@ imports.gi.versions.Gtk = '4.0';
|
|||||||
imports.gi.versions.Soup = '2.4';
|
imports.gi.versions.Soup = '2.4';
|
||||||
|
|
||||||
pkg.initGettext();
|
pkg.initGettext();
|
||||||
|
pkg.initFormat();
|
||||||
|
|
||||||
const { GstClapper, Gtk, Adw } = imports.gi;
|
const { GstClapper, Gtk, Adw } = imports.gi;
|
||||||
const { App } = imports.src.app;
|
const { App } = imports.src.app;
|
||||||
|
@@ -354,9 +354,9 @@ class ClapperPlayer extends GstClapper.Clapper
|
|||||||
|
|
||||||
const { controls } = this.widget.get_ancestor(Gtk.Grid);
|
const { controls } = this.widget.get_ancestor(Gtk.Grid);
|
||||||
const value = (isIncrease) ? offset : -offset;
|
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()
|
next_chapter()
|
||||||
|
@@ -28,7 +28,7 @@ class ClapperPlaylistWidget extends Gtk.ListBox
|
|||||||
});
|
});
|
||||||
this.activeRowId = -1;
|
this.activeRowId = -1;
|
||||||
this.repeatMode = RepeatMode.NONE;
|
this.repeatMode = RepeatMode.NONE;
|
||||||
this.add_css_class('playlist');
|
this.add_css_class('clapperplaylist');
|
||||||
|
|
||||||
this.connect('row-activated', this._onRowActivated.bind(this));
|
this.connect('row-activated', this._onRowActivated.bind(this));
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,6 @@ class ClapperPlaylistItem extends Gtk.ListBoxRow
|
|||||||
}
|
}
|
||||||
this.filename = filename || uri;
|
this.filename = filename || uri;
|
||||||
this.set_tooltip_text(this.filename);
|
this.set_tooltip_text(this.filename);
|
||||||
this.add_css_class('playlistrow');
|
|
||||||
|
|
||||||
const box = new Gtk.Box({
|
const box = new Gtk.Box({
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
@@ -270,7 +269,6 @@ class ClapperPlaylistItem extends Gtk.ListBoxRow
|
|||||||
});
|
});
|
||||||
repeatButton.add_css_class('flat');
|
repeatButton.add_css_class('flat');
|
||||||
repeatButton.add_css_class('circular');
|
repeatButton.add_css_class('circular');
|
||||||
repeatButton.add_css_class('popoverbutton');
|
|
||||||
repeatButton.connect('clicked', this._onRepeatClicked.bind(this));
|
repeatButton.connect('clicked', this._onRepeatClicked.bind(this));
|
||||||
const label = new Gtk.Label({
|
const label = new Gtk.Label({
|
||||||
label: this.filename,
|
label: this.filename,
|
||||||
@@ -285,7 +283,6 @@ class ClapperPlaylistItem extends Gtk.ListBoxRow
|
|||||||
});
|
});
|
||||||
removeButton.add_css_class('flat');
|
removeButton.add_css_class('flat');
|
||||||
removeButton.add_css_class('circular');
|
removeButton.add_css_class('circular');
|
||||||
removeButton.add_css_class('popoverbutton');
|
|
||||||
removeButton.connect('clicked', this._onRemoveClicked.bind(this));
|
removeButton.connect('clicked', this._onRemoveClicked.bind(this));
|
||||||
|
|
||||||
box.append(repeatButton);
|
box.append(repeatButton);
|
||||||
|
@@ -65,16 +65,23 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
|
|
||||||
this.controls.elapsedButton.scrolledWindow.set_child(this.player.playlistWidget);
|
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
|
'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
|
'value', this.player, 'volume', GObject.BindingFlags.BIDIRECTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this));
|
this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this));
|
||||||
this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this));
|
this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this));
|
||||||
this.player.connect('media-info-updated', this._onMediaInfoUpdated.bind(this));
|
this.player.connect('media-info-updated', this._onMediaInfoUpdated.bind(this));
|
||||||
|
|
||||||
|
this.player.connect('video-decoder-changed', this._onPlayerVideoDecoderChanged.bind(this));
|
||||||
|
this.player.connect('audio-decoder-changed', this._onPlayerAudioDecoderChanged.bind(this));
|
||||||
|
|
||||||
this.overlay.set_child(playerWidget);
|
this.overlay.set_child(playerWidget);
|
||||||
this.overlay.add_overlay(this.revealerTop);
|
this.overlay.add_overlay(this.revealerTop);
|
||||||
this.overlay.add_overlay(this.revealerBottom);
|
this.overlay.add_overlay(this.revealerBottom);
|
||||||
@@ -155,7 +162,7 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
this.revealerBottom.revealerBox.visible = isFullscreen;
|
this.revealerBottom.revealerBox.visible = isFullscreen;
|
||||||
|
|
||||||
this._changeControlsPlacement(isFullscreen);
|
this._changeControlsPlacement(isFullscreen);
|
||||||
this.controls.setFullscreenMode(isFullscreen);
|
this.controls.setFullscreenMode(isFullscreen, this.isMobileMonitor);
|
||||||
|
|
||||||
if(this.revealerTop.child_revealed)
|
if(this.revealerTop.child_revealed)
|
||||||
this._checkSetUpdateTimeInterval();
|
this._checkSetUpdateTimeInterval();
|
||||||
@@ -503,6 +510,16 @@ class ClapperWidget extends Gtk.Grid
|
|||||||
this.controls.positionScale.set_value(positionSeconds);
|
this.controls.positionScale.set_value(positionSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onPlayerVideoDecoderChanged(player, decoder)
|
||||||
|
{
|
||||||
|
this.controls.videoTracksButton.setDecoder(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onPlayerAudioDecoderChanged(player, decoder)
|
||||||
|
{
|
||||||
|
this.controls.audioTracksButton.setDecoder(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
_onStateNotify(toplevel)
|
_onStateNotify(toplevel)
|
||||||
{
|
{
|
||||||
const isMaximized = Boolean(
|
const isMaximized = Boolean(
|
||||||
|
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>
|
29
ui/popover-separator.ui
Normal file
29
ui/popover-separator.ui
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<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>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="middle_label">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparator">
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
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