From e9ec155e7b3f965d372fe944f67bc86d24061a72 Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Thu, 10 Sep 2020 14:24:02 +0200 Subject: [PATCH] Move fullscreen and menu buttons to header bar Follow other GNOME apps designs by having fullscreen button on the right side of window header bar. The control panel had too many buttons already and we still need to make some space for playlist. This way "fullscreen" button will be on top bar while windowed and "unfullscreen" button will appear on the bottom right only when player entered fullscreen mode. --- clapper_src/app.js | 30 +++++---- clapper_src/controls.js | 134 ++++++++++++++++++++++----------------- clapper_src/interface.js | 13 ++-- 3 files changed, 103 insertions(+), 74 deletions(-) diff --git a/clapper_src/app.js b/clapper_src/app.js index 91d04280..3676c7fb 100644 --- a/clapper_src/app.js +++ b/clapper_src/app.js @@ -105,9 +105,14 @@ var App = GObject.registerClass({ title: APP_NAME, show_close_button: true, }); + headerBar.pack_end(this.interface.controls.openMenuButton); + headerBar.pack_end(this.interface.controls.fullscreenButton); this.interface.addHeaderBar(headerBar, APP_NAME); - this.interface.controls.toggleFullscreenButton.connect( - 'clicked', this._onInterfaceToggleFullscreenClicked.bind(this) + this.interface.controls.fullscreenButton.connect( + 'clicked', () => this._onInterfaceToggleFullscreenClicked(true) + ); + this.interface.controls.unfullscreenButton.connect( + 'clicked', () => this._onInterfaceToggleFullscreenClicked(false) ); this.window.set_titlebar(this.interface.headerBar); @@ -172,14 +177,17 @@ var App = GObject.registerClass({ // and we need to re-add marks to the new layout this.interface.controls.setVolumeMarks(false); - this.interface.controls.toggleFullscreenButton.image = (isFullscreen) - ? this.interface.controls.unfullscreenImage - : this.interface.controls.fullscreenImage; - if(isFullscreen) { this.interface.showControls(true); this.setHideControlsTimeout(); + this.interface.controls.unfullscreenButton.set_sensitive(true); + this.interface.controls.unfullscreenButton.show(); } + else { + this.interface.controls.unfullscreenButton.set_sensitive(false); + this.interface.controls.unfullscreenButton.hide(); + } + this.interface.setControlsOnVideo(isFullscreen); this.interface.controls.setVolumeMarks(true); this.interface.controls.fullscreenMode = isFullscreen; @@ -225,14 +233,12 @@ var App = GObject.registerClass({ } } - _onInterfaceToggleFullscreenClicked() + _onInterfaceToggleFullscreenClicked(isFsRequested) { - // we need some way to refresh toggle fullscreen button on click - // otherwise it does not lose the hover effect after window transition - // for now hide->transition->show does the job done - this.interface.controls.toggleFullscreenButton.hide(); + if(this.window.isFullscreen === isFsRequested) + return; + this.window.toggleFullscreen(); - this.interface.controls.toggleFullscreenButton.show(); } _onPlayerRealize() diff --git a/clapper_src/controls.js b/clapper_src/controls.js index da28a9df..b40d47f1 100644 --- a/clapper_src/controls.js +++ b/clapper_src/controls.js @@ -23,46 +23,12 @@ var Controls = GObject.registerClass({ valign: Gtk.Align.END, }); - let style; - this._fullscreenMode = false; this.durationFormated = '00:00:00'; this.buttonImages = []; - this.togglePlayButton = this.addButton( - 'media-playback-pause-symbolic', - Gtk.IconSize.LARGE_TOOLBAR - ); - this.pauseButton = this.addButton( - 'media-playback-start-symbolic', - Gtk.IconSize.LARGE_TOOLBAR, - true - ); - this.playImage = this.pauseButton.image; - this.pauseImage = this.togglePlayButton.image; - - this.positionScale = new Gtk.Scale({ - orientation: Gtk.Orientation.HORIZONTAL, - value_pos: Gtk.PositionType.LEFT, - draw_value: true, - hexpand: true, - }); - style = this.positionScale.get_style_context(); - style.add_class('positionscale'); - - this.positionScale.connect( - 'format-value', this._onPositionScaleFormatValue.bind(this) - ); - this.positionScale.connect( - 'button-press-event', this._onPositionScaleButtonPressEvent.bind(this) - ); - this.positionScale.connect( - 'button-release-event', this._onPositionScaleButtonReleaseEvent.bind(this) - ); - - this.positionAdjustment = this.positionScale.get_adjustment(); - this.pack_start(this.positionScale, true, true, 0); - + this._addTogglePlayButton(); + this._addPositionScale(); this.videoTracksButton = this.addPopoverButton( 'emblem-videos-symbolic' ); @@ -72,32 +38,23 @@ var Controls = GObject.registerClass({ this.subtitleTracksButton = this.addPopoverButton( 'media-view-subtitles-symbolic' ); - - 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, - }); - this.volumeScale.get_style_context().add_class('volumescale'); - this.volumeAdjustment = this.volumeScale.get_adjustment(); - this._prepareVolumeButton(); - - this.toggleFullscreenButton = this.addButton( - 'view-fullscreen-symbolic' - ); + this._addVolumeButton(); this.unfullscreenButton = this.addButton( 'view-restore-symbolic', Gtk.IconSize.SMALL_TOOLBAR, true ); - this.fullscreenImage = this.toggleFullscreenButton.image; - this.unfullscreenImage = this.unfullscreenButton.image; + + this.fullscreenButton = Gtk.Button.new_from_icon_name( + 'view-fullscreen-symbolic', + Gtk.IconSize.SMALL_TOOLBAR + ); + this.setDefaultWidgetBehaviour(this.fullscreenButton); + this.openMenuButton = Gtk.Button.new_from_icon_name( + 'open-menu-symbolic', + Gtk.IconSize.SMALL_TOOLBAR + ); + this.setDefaultWidgetBehaviour(this.openMenuButton); this.forall(this.setDefaultWidgetBehaviour); } @@ -205,8 +162,69 @@ var Controls = GObject.registerClass({ this.volumeScale.add_mark(2, Gtk.PositionType.LEFT, '200%'); } - _prepareVolumeButton() + _addTogglePlayButton() { + this.togglePlayButton = this.addButton( + 'media-playback-pause-symbolic', + Gtk.IconSize.LARGE_TOOLBAR + ); + this.togglePlayButton.setPlayImage = () => + { + this.togglePlayButton.image.set_from_icon_name( + 'media-playback-start-symbolic', + this.togglePlayButton.image.icon_size + ); + } + this.togglePlayButton.setPauseImage = () => + { + this.togglePlayButton.image.set_from_icon_name( + 'media-playback-pause-symbolic', + this.togglePlayButton.image.icon_size + ); + } + } + + _addPositionScale() + { + this.positionScale = new Gtk.Scale({ + orientation: Gtk.Orientation.HORIZONTAL, + value_pos: Gtk.PositionType.LEFT, + draw_value: true, + hexpand: true, + }); + let style = this.positionScale.get_style_context(); + style.add_class('positionscale'); + + this.positionScale.connect( + 'format-value', this._onPositionScaleFormatValue.bind(this) + ); + this.positionScale.connect( + 'button-press-event', this._onPositionScaleButtonPressEvent.bind(this) + ); + this.positionScale.connect( + 'button-release-event', this._onPositionScaleButtonReleaseEvent.bind(this) + ); + + this.positionAdjustment = this.positionScale.get_adjustment(); + this.pack_start(this.positionScale, true, true, 0); + } + + _addVolumeButton() + { + 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, + }); + this.volumeScale.get_style_context().add_class('volumescale'); + this.volumeAdjustment = this.volumeScale.get_adjustment(); + this.volumeAdjustment.set_upper(2); this.volumeAdjustment.set_step_increment(0.05); this.volumeAdjustment.set_page_increment(0.05); diff --git a/clapper_src/interface.js b/clapper_src/interface.js index d69361c6..27bf30b8 100644 --- a/clapper_src/interface.js +++ b/clapper_src/interface.js @@ -93,15 +93,20 @@ class ClapperInterface extends Gtk.Grid setControlsOnVideo(isOnVideo) { - if(isOnVideo && !this.controlsInVideo) { + if(this.controlsInVideo === isOnVideo) + return; + + if(isOnVideo) { this.remove(this.controls); + this.controls.pack_start(this.controls.unfullscreenButton, false, false, 0); this.overlay.add_overlay(this.revealer); this.revealerBox.pack_start(this.controls, false, true, 0); this.revealer.show(); this.revealerBox.show(); } - else if(!isOnVideo && this.controlsInVideo) { + else { this.revealerBox.remove(this.controls); + this.controls.remove(this.controls.unfullscreenButton); this.overlay.remove(this.revealer); this.attach(this.controls, 0, 1, 1, 1); this.controls.show(); @@ -260,10 +265,10 @@ class ClapperInterface extends Gtk.Grid case GstPlayer.PlayerState.STOPPED: this.needsTracksUpdate = true; case GstPlayer.PlayerState.PAUSED: - this.controls.togglePlayButton.image = this.controls.playImage; + this.controls.togglePlayButton.setPlayImage(); break; case GstPlayer.PlayerState.PLAYING: - this.controls.togglePlayButton.image = this.controls.pauseImage; + this.controls.togglePlayButton.setPauseImage(); if(this.needsTracksUpdate) { this.needsTracksUpdate = false; this.updateMediaTracks();