diff --git a/css/styles.css b/css/styles.css index 2c84dbd0..d82d88ac 100644 --- a/css/styles.css +++ b/css/styles.css @@ -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; diff --git a/src/buttons.js b/src/buttons.js index ac619d30..a86d7e85 100644 --- a/src/buttons.js +++ b/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`; } }); diff --git a/src/controls.js b/src/controls.js index 356ac9d3..abb58561 100644 --- a/src/controls.js +++ b/src/controls.js @@ -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(); } }); diff --git a/src/player.js b/src/player.js index 6692df43..f25adc76 100644 --- a/src/player.js +++ b/src/player.js @@ -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() diff --git a/src/playlist.js b/src/playlist.js index 1c2bcbb9..84df4a6c 100644 --- a/src/playlist.js +++ b/src/playlist.js @@ -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); diff --git a/src/widget.js b/src/widget.js index 900a9f13..3a86dec4 100644 --- a/src/widget.js +++ b/src/widget.js @@ -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(); diff --git a/ui/elapsed-time-button.ui b/ui/elapsed-time-button.ui new file mode 100644 index 00000000..56173a9d --- /dev/null +++ b/ui/elapsed-time-button.ui @@ -0,0 +1,58 @@ + + + + + + + vertical + True + True + + + False + True + + + + + Speed + + + + + horizontal + bottom + False + 2 + True + center + speed_adjustment + + 0.25x + Normal + 2x + + + + + + + + + 0.01 + 2 + 1 + 0.1 + + diff --git a/ui/popover-separator.ui b/ui/popover-separator.ui index 979ab067..64eea34f 100644 --- a/ui/popover-separator.ui +++ b/ui/popover-separator.ui @@ -3,6 +3,9 @@