From ab11d52a688ac38bcafb3e6f44e091fa872cd396 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Wed, 9 Sep 2020 21:34:32 +0200 Subject: [PATCH] Recreate volume button from scratch Create volume button with popover instead of using GTK provided volume button. Creating new button with only needed elements is more efficient then removing unneeded items from pre-made volume button. This should also increase performance a little when changing volume, because now we generate new icon only when a change is needed. In pre-made button icon is regenerated on each volume change. --- clapper_src/app.js | 14 ++++---- clapper_src/controls.js | 70 +++++++++++----------------------------- clapper_src/interface.js | 29 +++++++++++++++-- css/styles.css | 11 +++++++ 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/clapper_src/app.js b/clapper_src/app.js index 163e6e3d..cf096bb6 100644 --- a/clapper_src/app.js +++ b/clapper_src/app.js @@ -191,12 +191,12 @@ var App = GObject.registerClass({ bool = true; case Gdk.KEY_Left: // disabled due to missing "seek on drop" support - //this._handleScaleIncrement('position', 'Scale', bool); + //this._handleScaleIncrement('position', bool); break; case Gdk.KEY_Up: bool = true; case Gdk.KEY_Down: - this._handleScaleIncrement('volume', 'Button', bool); + this._handleScaleIncrement('volume', bool); break; case Gdk.KEY_F11: this.window.toggleFullscreen(); @@ -329,29 +329,27 @@ var App = GObject.registerClass({ if(!res) return; let type = 'volume'; - let item = 'Button'; switch(direction) { case Gdk.ScrollDirection.RIGHT: case Gdk.ScrollDirection.LEFT: type = 'position'; - item = 'Scale'; case Gdk.ScrollDirection.UP: case Gdk.ScrollDirection.DOWN: let isUp = ( direction === Gdk.ScrollDirection.UP || direction === Gdk.ScrollDirection.RIGHT ); - this._handleScaleIncrement(type, item, isUp); + this._handleScaleIncrement(type, isUp); break; default: break; } } - _handleScaleIncrement(type, item, isUp) + _handleScaleIncrement(type, isUp) { - let value = this.interface.controls[`${type}${item}`].get_value(); + let value = this.interface.controls[`${type}Scale`].get_value(); let maxValue = this.interface.controls[`${type}Adjustment`].get_upper(); let increment = this.interface.controls[`${type}Adjustment`].get_page_increment(); @@ -362,7 +360,7 @@ var App = GObject.registerClass({ ? maxValue : value; - this.interface.controls[`${type}${item}`].set_value(value); + this.interface.controls[`${type}Scale`].set_value(value); } _onPlayerEnterNotifyEvent(self, event) diff --git a/clapper_src/controls.js b/clapper_src/controls.js index 482fee73..bcc8362e 100644 --- a/clapper_src/controls.js +++ b/clapper_src/controls.js @@ -69,33 +69,20 @@ var Controls = GObject.registerClass({ 'media-view-subtitles-symbolic' ); - this.volumeButton = new Gtk.ScaleButton({ - icons: [ - 'audio-volume-muted-symbolic', - 'audio-volume-overamplified-symbolic', - 'audio-volume-low-symbolic', - 'audio-volume-medium-symbolic', - 'audio-volume-high-symbolic', - 'audio-volume-overamplified-symbolic', - 'audio-volume-overamplified-symbolic', - 'audio-volume-overamplified-symbolic', - ], - size: Gtk.IconSize.SMALL_TOOLBAR + this.volumeButton = this.addPopoverButton( + 'audio-volume-muted-symbolic' + ); + this.volumeScale = new Gtk.Scale({ + orientation: Gtk.Orientation.VERTICAL, + inverted: true, + value_pos: Gtk.PositionType.TOP, + draw_value: false, + round_digits: 2, + vexpand: true, }); - style = this.volumeButton.get_style_context(); - let styleStr = style.to_string(Gtk.StyleContextPrintFlags.SHOW_STYLE); - - if(!styleStr.includes('flat')) - style.add_class('flat'); - - this.volumeButtonImage = this.volumeButton.get_child(); - this.volumeButtonImage.defaultSize = Gtk.IconSize.SMALL_TOOLBAR; - this.volumeButtonImage.fullscreenSize = Gtk.IconSize.LARGE_TOOLBAR; - this.buttonImages.push(this.volumeButtonImage); - - this.volumeAdjustment = this.volumeButton.get_adjustment(); + this.volumeScale.get_style_context().add_class('volumescale'); + this.volumeAdjustment = this.volumeScale.get_adjustment(); this._prepareVolumeButton(); - this.pack_start(this.volumeButton, false, false, 0); this.toggleFullscreenButton = this.addButton( 'view-fullscreen-symbolic' @@ -122,7 +109,6 @@ var Controls = GObject.registerClass({ : image.defaultSize; } - this.volumeButton.size = this.volumeButtonImage.icon_size; this._fullscreenMode = isFullscreen; } @@ -136,6 +122,7 @@ var Controls = GObject.registerClass({ size = size || Gtk.IconSize.SMALL_TOOLBAR; let button = Gtk.Button.new_from_icon_name(iconName, size); + button.image.defaultSize = size; button.image.fullscreenSize = (size === Gtk.IconSize.SMALL_TOOLBAR) ? Gtk.IconSize.LARGE_TOOLBAR @@ -160,10 +147,7 @@ var Controls = GObject.registerClass({ button.popover = new Gtk.Popover({ relative_to: button }); - button.popoverBox = new Gtk.VBox({ - margin_top: 4, - margin_bottom: 4, - }); + button.popoverBox = new Gtk.VBox(); button.osd = this.fullscreenMode; button.popover.add(button.popoverBox); button.connect('clicked', this._onPopoverButtonClicked.bind(this, button)); @@ -215,31 +199,15 @@ var Controls = GObject.registerClass({ _prepareVolumeButton() { - this.volumeAdjustment.set_upper(2.001); + this.volumeAdjustment.set_upper(2); this.volumeAdjustment.set_step_increment(0.05); this.volumeAdjustment.set_page_increment(0.05); + this.setDefaultWidgetBehaviour(this.volumeScale); - this.volumeButton.popover = this.volumeButton.get_popup(); - this.volumeButton.popoverBox = this.volumeButton.popover.get_child(); - this.volumeButton.osd = this.fullscreenMode; - this.volumeButton.connect( - 'clicked', this._onPopoverButtonClicked.bind(this, this.volumeButton.popoverBox) - ); - let boxChildren = this.volumeButton.popoverBox.get_children(); + this.volumeButton.popoverBox.add(this.volumeScale); + this.volumeButton.popoverBox.show_all(); - for(let child of boxChildren) { - if(child.constructor === Gtk.Button) { - this.volumeButton.popoverBox.remove(child); - child.destroy(); - } - else if(child.constructor === Gtk.Scale) { - this.setDefaultWidgetBehaviour(child); - child.get_style_context().add_class('volumescale'); - child.round_digits = 2; - this.volumeScale = child; - this.setVolumeMarks(true); - } - } + this.setVolumeMarks(true); } _getFormatedTime(time) diff --git a/clapper_src/interface.js b/clapper_src/interface.js index b46d5ec1..e1736b86 100644 --- a/clapper_src/interface.js +++ b/clapper_src/interface.js @@ -56,7 +56,7 @@ class ClapperInterface extends Gtk.Grid this.controls.positionScale.connect( 'value-changed', this._onControlsPositionChanged.bind(this) ); - this.controls.volumeButton.connect( + this.controls.volumeScale.connect( 'value-changed', this._onControlsVolumeChanged.bind(this) ); this.controls.connect( @@ -280,7 +280,7 @@ class ClapperInterface extends Gtk.Grid return; this.lastVolumeValue = volume; - this.controls.volumeButton.set_value(volume); + this.controls.volumeScale.set_value(volume); } _onPositionSeekingChanged(self, isPositionSeeking) @@ -310,12 +310,35 @@ class ClapperInterface extends Gtk.Grid this._player.seek_seconds(positionSeconds); } - _onControlsVolumeChanged(widget, volume) + _onControlsVolumeChanged(volumeScale) { + let volume = Number(volumeScale.get_value().toFixed(2)); + if(volume === this.lastVolumeValue) return; this.lastVolumeValue = volume; this._player.set_volume(volume); + + let icon = (volume <= 0) + ? 'muted' + : (volume <= 0.33) + ? 'low' + : (volume <= 0.66) + ? 'medium' + : (volume <= 1) + ? 'high' + : 'overamplified'; + + let iconName = `audio-volume-${icon}-symbolic`; + + if(this.controls.volumeButton.image.icon_name === iconName) + return; + + debug(`set volume icon: ${icon}`); + this.controls.volumeButton.image.set_from_icon_name( + iconName, + this.controls.volumeButton.image.icon_size + ); } }); diff --git a/css/styles.css b/css/styles.css index f8d11586..cc574645 100644 --- a/css/styles.css +++ b/css/styles.css @@ -53,8 +53,19 @@ scale marks { /* Volume Scale */ .volumescale { + margin-left: 4px; min-height: 180px; } .osd .volumescale { + margin: 6px; + margin-left: 10px; min-height: 280px; } +.volumescale marks label { + margin-right: 4px; + margin-top: -4px; + margin-bottom: -6px; +} +.osd .volumescale marks label { + margin-bottom: -8px; +}