const { GObject, Gtk, Gst, GstPlayer } = imports.gi; const { Controls } = imports.clapper_src.controls; const Debug = imports.clapper_src.debug; let { debug } = Debug; var Interface = GObject.registerClass( class ClapperInterface extends Gtk.Grid { _init(opts) { Debug.gstVersionCheck(); super._init(); let defaults = { seekOnDrop: true }; Object.assign(this, defaults, opts); this.controlsInVideo = false; this.lastVolumeValue = null; this.lastPositionValue = 0; this.revealTime = 800; this.overlay = new Gtk.Overlay(); this.controls = new Controls(); this.revealer= new Gtk.Revealer({ transition_duration: this.revealTime, transition_type: Gtk.RevealerTransitionType.SLIDE_UP, valign: Gtk.Align.END, }); this.attach(this.overlay, 0, 0, 1, 1); this.attach(this.controls, 0, 1, 1, 1); } addPlayer(player) { this._player = player; this._player.widget.expand = true; this._player.connect('state-changed', this._onPlayerStateChanged.bind(this)); this._player.connect('volume-changed', this._onPlayerVolumeChanged.bind(this)); this._player.connect('duration-changed', this._onPlayerDurationChanged.bind(this)); this._player.connect('position-updated', this._onPlayerPositionUpdated.bind(this)); this.controls.togglePlayButton.connect( 'clicked', this._onControlsTogglePlayClicked.bind(this) ); this.controls.positionScale.connect( 'value-changed', this._onControlsPositionChanged.bind(this) ); this.controls.volumeButton.connect( 'value-changed', this._onControlsVolumeChanged.bind(this) ); this.controls.connect( 'position-seeking-changed', this._onPositionSeekingChanged.bind(this) ); this.overlay.add(this._player.widget); } revealControls(isReveal) { this.revealer.set_transition_duration(this.revealTime); this.revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_UP); this.revealer.set_reveal_child(isReveal); } showControls(isShow) { this.revealer.set_transition_duration(0); this.revealer.set_transition_type(Gtk.RevealerTransitionType.NONE); this.revealer.set_reveal_child(isShow); } setControlsOnVideo(isOnVideo) { if(isOnVideo && !this.controlsInVideo) { this.remove_row(1); this.controls.margin = 8; this.controls.margin_start = 10; this.controls.margin_end = 10; this.overlay.add_overlay(this.revealer); this.revealer.add(this.controls); this.revealer.show(); } else if(!isOnVideo && this.controlsInVideo) { this.revealer.remove(this.controls); this.overlay.remove(this.revealer); this.controls.margin = 4; this.attach(this.controls, 0, 1, 1, 1); this.controls.show(); } this.controlsInVideo = isOnVideo; debug(`placed controls in overlay: ${isOnVideo}`); } _onPlayerStateChanged(player, state) { switch(state) { case GstPlayer.PlayerState.BUFFERING: break; case GstPlayer.PlayerState.PAUSED: case GstPlayer.PlayerState.STOPPED: this.controls.togglePlayButton.image = this.controls.playImage; break; case GstPlayer.PlayerState.PLAYING: this.controls.togglePlayButton.image = this.controls.pauseImage; break; default: break; } } _onPlayerDurationChanged(player) { let duration = player.get_duration() / 1000000000; let increment = (duration < 1) ? 0 : (duration < 100) ? 1 : duration / 100; this.controls.positionAdjustment.set_upper(duration); this.controls.positionAdjustment.set_step_increment(increment); this.controls.positionAdjustment.set_page_increment(increment); } _onPlayerPositionUpdated(player, position) { if( this.controls.isPositionSeeking || this._player.state === GstPlayer.PlayerState.BUFFERING ) return; let positionSeconds = Math.round(position / 1000000000); if(positionSeconds === this.lastPositionValue) return; this.lastPositionValue = positionSeconds; this.controls.positionScale.set_value(positionSeconds); } _onPlayerVolumeChanged() { let volume = Number(this._player.get_volume().toFixed(2)); if(volume === this.lastVolumeValue) return; this.lastVolumeValue = volume; this.controls.volumeButton.set_value(volume); } _onPositionSeekingChanged(self, isPositionSeeking) { if(isPositionSeeking || !this.seekOnDrop) return; this._onControlsPositionChanged(this.controls.positionScale); } _onControlsTogglePlayClicked() { this._player.toggle_play(); } _onControlsPositionChanged(positionScale) { if(this.seekOnDrop && this.controls.isPositionSeeking) return; let positionSeconds = Math.round(positionScale.get_value()); if(positionSeconds === this.lastPositionValue) return; this.lastPositionValue = positionSeconds; this._player.seek_seconds(positionSeconds); } _onControlsVolumeChanged(widget, volume) { if(volume === this.lastVolumeValue) return; this.lastVolumeValue = volume; this._player.set_volume(volume); } });