Add OSD headerbar and transition to floating mode

This commit is contained in:
Rafał Dzięgiel
2021-02-13 17:19:03 +01:00
parent bb8ae47a66
commit 1d16d3e2ac
8 changed files with 128 additions and 38 deletions

View File

@@ -18,6 +18,12 @@ radio {
.gtk402 .osd trough highlight { .gtk402 .osd trough highlight {
border-color: inherit; border-color: inherit;
} }
.osd headerbar {
background: transparent;
}
.osd headerbar button {
border: transparent;
}
.adwrounded.csd { .adwrounded.csd {
border-radius: 8px; border-radius: 8px;
} }
@@ -72,6 +78,9 @@ radio {
font-size: 23px; font-size: 23px;
text-shadow: none; text-shadow: none;
} }
.reavealertop {
background: transparent;
}
.tvmode .reavealertop { .tvmode .reavealertop {
min-height: 88px; min-height: 88px;
box-shadow: inset 0px 200px 10px -132px rgba(0,0,0,0.4); box-shadow: inset 0px 200px 10px -132px rgba(0,0,0,0.4);
@@ -79,7 +88,6 @@ radio {
font-size: 28px; font-size: 28px;
font-weight: 500; font-weight: 500;
text-shadow: none; text-shadow: none;
background: transparent;
} }
.tvtime { .tvtime {
margin-top: -2px; margin-top: -2px;

View File

@@ -1,6 +1,5 @@
const { Gio, GObject } = imports.gi; const { Gio, GObject, Gtk } = imports.gi;
const { AppBase } = imports.src.appBase; const { AppBase } = imports.src.appBase;
const { HeaderBar } = imports.src.headerbar;
const { Widget } = imports.src.widget; const { Widget } = imports.src.widget;
const Debug = imports.src.debug; const Debug = imports.src.debug;
@@ -23,14 +22,20 @@ class ClapperApp extends AppBase
{ {
super.vfunc_startup(); super.vfunc_startup();
this.active_window.isClapperApp = true; const window = this.active_window;
this.active_window.add_css_class('nobackground');
const clapperWidget = new Widget(); window.isClapperApp = true;
this.active_window.set_child(clapperWidget); window.add_css_class('nobackground');
const headerBar = new HeaderBar(this.active_window); const clapperWidget = new Widget(window);
this.active_window.set_titlebar(headerBar); window.set_child(clapperWidget);
const dummyHeaderbar = new Gtk.HeaderBar({
can_focus: false,
focusable: false,
visible: false,
});
window.set_titlebar(dummyHeaderbar);
} }
vfunc_open(files, hint) vfunc_open(files, hint)

2
src/controls.js vendored
View File

@@ -28,8 +28,6 @@ class ClapperControls extends Gtk.Box
this.currentPosition = 0; this.currentPosition = 0;
this.currentDuration = 0; this.currentDuration = 0;
this.isPositionDragging = false; this.isPositionDragging = false;
this.isMobileMonitor = false;
this.isMobile = false; this.isMobile = false;
this.showHours = false; this.showHours = false;

View File

@@ -1,4 +1,4 @@
const { GObject } = imports.gi; const { GObject, Gtk } = imports.gi;
const { HeaderBarBase } = imports.src.headerbarBase; const { HeaderBarBase } = imports.src.headerbarBase;
var HeaderBar = GObject.registerClass( var HeaderBar = GObject.registerClass(
@@ -8,21 +8,18 @@ class ClapperHeaderBar extends HeaderBarBase
{ {
super._init(window); super._init(window);
const clapperWidget = window.get_child(); this.title_widget.visible = false;
clapperWidget.controls.unfloatButton.bind_property('visible', this, 'visible',
GObject.BindingFlags.INVERT_BOOLEAN
);
} }
_onFloatButtonClicked() _onFloatButtonClicked()
{ {
const clapperWidget = this.get_prev_sibling(); const clapperWidget = this.root.child;
clapperWidget.setFloatingMode(true);
clapperWidget.controlsRevealer.toggleReveal();
} }
_onFullscreenButtonClicked() _onFullscreenButtonClicked()
{ {
const window = this.get_parent(); this.root.fullscreen();
window.fullscreen();
} }
}); });

View File

@@ -20,26 +20,31 @@ class ClapperHeaderBarBase extends Gtk.HeaderBar
const mainMenuButton = new Gtk.MenuButton({ const mainMenuButton = new Gtk.MenuButton({
icon_name: 'open-menu-symbolic', icon_name: 'open-menu-symbolic',
valign: Gtk.Align.CENTER,
}); });
const mainMenuModel = uiBuilder.get_object('mainMenu'); const mainMenuModel = uiBuilder.get_object('mainMenu');
const mainMenuPopover = new HeaderBarPopover(mainMenuModel); const mainMenuPopover = new HeaderBarPopover(mainMenuModel);
mainMenuButton.set_popover(mainMenuPopover); mainMenuButton.set_popover(mainMenuPopover);
mainMenuButton.add_css_class('circular');
this.pack_start(mainMenuButton); this.pack_start(mainMenuButton);
const buttonsBox = new Gtk.Box({ const buttonsBox = new Gtk.Box({
orientation: Gtk.Orientation.HORIZONTAL, orientation: Gtk.Orientation.HORIZONTAL,
valign: Gtk.Align.CENTER,
}); });
buttonsBox.add_css_class('linked'); buttonsBox.add_css_class('linked');
const floatButton = new Gtk.Button({ const floatButton = new Gtk.Button({
icon_name: 'preferences-desktop-remote-desktop-symbolic', icon_name: 'preferences-desktop-remote-desktop-symbolic',
}); });
floatButton.add_css_class('circular');
floatButton.connect('clicked', this._onFloatButtonClicked.bind(this)); floatButton.connect('clicked', this._onFloatButtonClicked.bind(this));
buttonsBox.append(floatButton); buttonsBox.append(floatButton);
const fullscreenButton = new Gtk.Button({ const fullscreenButton = new Gtk.Button({
icon_name: 'view-fullscreen-symbolic', icon_name: 'view-fullscreen-symbolic',
}); });
fullscreenButton.add_css_class('circular');
fullscreenButton.connect('clicked', this._onFullscreenButtonClicked.bind(this)); fullscreenButton.connect('clicked', this._onFullscreenButtonClicked.bind(this));
buttonsBox.append(fullscreenButton); buttonsBox.append(fullscreenButton);

View File

@@ -685,11 +685,6 @@ class ClapperPlayer extends PlayerBase
if(!this._updateTimeTimeout) if(!this._updateTimeTimeout)
this._setUpdateTimeInterval(); this._setUpdateTimeInterval();
if(!clapperWidget.revealerTop.get_reveal_child()) {
/* Do not grab controls key focus on mouse movement */
clapperWidget.revealerBottom.set_can_focus(false);
clapperWidget.revealControls(true);
}
this._setHideControlsTimeout(); this._setHideControlsTimeout();
} }
else { else {
@@ -698,6 +693,12 @@ class ClapperPlayer extends PlayerBase
if(this._updateTimeTimeout) if(this._updateTimeTimeout)
this._clearTimeout('updateTime'); this._clearTimeout('updateTime');
} }
if(!clapperWidget.revealerTop.get_reveal_child()) {
/* Do not grab controls key focus on mouse movement */
clapperWidget.revealerBottom.set_can_focus(false);
clapperWidget.revealControls(true);
}
} }
this.posX = posX; this.posX = posX;

View File

@@ -1,4 +1,5 @@
const { GLib, GObject, Gtk, Pango } = imports.gi; const { GLib, GObject, Gtk, Pango } = imports.gi;
const { HeaderBar } = imports.src.headerbar;
const Debug = imports.src.debug; const Debug = imports.src.debug;
const REVEAL_TIME = 800; const REVEAL_TIME = 800;
@@ -89,7 +90,7 @@ class ClapperCustomRevealer extends Gtk.Revealer
var RevealerTop = GObject.registerClass( var RevealerTop = GObject.registerClass(
class ClapperRevealerTop extends CustomRevealer class ClapperRevealerTop extends CustomRevealer
{ {
_init() _init(window)
{ {
super._init({ super._init({
transition_duration: REVEAL_TIME, transition_duration: REVEAL_TIME,
@@ -103,12 +104,6 @@ class ClapperRevealerTop extends CustomRevealer
? '%I:%M %p' ? '%I:%M %p'
: '%H:%M'; : '%H:%M';
this.revealerGrid = new Gtk.Grid({
column_spacing: 8
});
this.revealerGrid.add_css_class('osd');
this.revealerGrid.add_css_class('reavealertop');
this.mediaTitle = new Gtk.Label({ this.mediaTitle = new Gtk.Label({
ellipsize: Pango.EllipsizeMode.END, ellipsize: Pango.EllipsizeMode.END,
vexpand: true, vexpand: true,
@@ -131,11 +126,25 @@ class ClapperRevealerTop extends CustomRevealer
this.endTime = new Gtk.Label(timeLabelOpts); this.endTime = new Gtk.Label(timeLabelOpts);
this.endTime.add_css_class('tvendtime'); this.endTime.add_css_class('tvendtime');
const revealerBox = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
});
revealerBox.add_css_class('osd');
revealerBox.add_css_class('reavealertop');
this.headerBar = new HeaderBar(window);
revealerBox.append(this.headerBar);
this.revealerGrid = new Gtk.Grid({
column_spacing: 8,
visible: false,
});
this.revealerGrid.attach(this.mediaTitle, 0, 0, 1, 1); this.revealerGrid.attach(this.mediaTitle, 0, 0, 1, 1);
this.revealerGrid.attach(this.currentTime, 1, 0, 1, 1); this.revealerGrid.attach(this.currentTime, 1, 0, 1, 1);
this.revealerGrid.attach(this.endTime, 1, 0, 1, 1); this.revealerGrid.attach(this.endTime, 1, 0, 1, 1);
revealerBox.append(this.revealerGrid);
this.set_child(this.revealerGrid); this.set_child(revealerBox);
} }
setMediaTitle(title) setMediaTitle(title)
@@ -229,6 +238,63 @@ class ClapperRevealerBottom extends CustomRevealer
} }
}); });
var ControlsRevealer = GObject.registerClass(
class ClapperControlsRevealer extends Gtk.Revealer
{
_init()
{
super._init({
transition_duration: 600,
transition_type: Gtk.RevealerTransitionType.SLIDE_DOWN,
reveal_child: true,
});
this.connect('notify::child-revealed', this._onControlsRevealed.bind(this));
}
toggleReveal()
{
/* Prevent interrupting transition */
if(this.reveal_child !== this.child_revealed)
return;
const { widget } = this.root.child.player;
if(!this.child_revealed)
this.visible = true;
else
this.add_tick_callback(this._onUnrevealTick.bind(this, widget));
widget.height_request = widget.get_height();
this.reveal_child ^= true;
}
_onControlsRevealed()
{
if(this.child_revealed) {
const clapperWidget = this.root.child;
const [width, height] = this.root.get_default_size();
clapperWidget.player.widget.height_request = -1;
this.root.set_default_size(width, height);
}
}
_onUnrevealTick(playerWidget)
{
const [width, height] = this.root.get_default_size();
if(!this.child_revealed) {
playerWidget.height_request = -1;
this.visible = false;
}
this.root.set_default_size(width, playerWidget.get_height());
return this.child_revealed;
}
});
var ButtonsRevealer = GObject.registerClass( var ButtonsRevealer = GObject.registerClass(
class ClapperButtonsRevealer extends Gtk.Revealer class ClapperButtonsRevealer extends Gtk.Revealer
{ {

View File

@@ -12,7 +12,7 @@ const { settings } = Misc;
var Widget = GObject.registerClass( var Widget = GObject.registerClass(
class ClapperWidget extends Gtk.Grid class ClapperWidget extends Gtk.Grid
{ {
_init() _init(window)
{ {
super._init(); super._init();
@@ -27,11 +27,12 @@ class ClapperWidget extends Gtk.Grid
this.fullscreenMode = false; this.fullscreenMode = false;
this.floatingMode = false; this.floatingMode = false;
this.isSeekable = false; this.isSeekable = false;
this.isMobileMonitor = false;
this.needsTracksUpdate = true; this.needsTracksUpdate = true;
this.overlay = new Gtk.Overlay(); this.overlay = new Gtk.Overlay();
this.revealerTop = new Revealers.RevealerTop(); this.revealerTop = new Revealers.RevealerTop(window);
this.revealerBottom = new Revealers.RevealerBottom(); this.revealerBottom = new Revealers.RevealerBottom();
this.controls = new Controls(); this.controls = new Controls();
@@ -41,8 +42,11 @@ class ClapperWidget extends Gtk.Grid
this.controlsBox.add_css_class('controlsbox'); this.controlsBox.add_css_class('controlsbox');
this.controlsBox.append(this.controls); this.controlsBox.append(this.controls);
this.controlsRevealer = new Revealers.ControlsRevealer();
this.controlsRevealer.set_child(this.controlsBox);
this.attach(this.overlay, 0, 0, 1, 1); this.attach(this.overlay, 0, 0, 1, 1);
this.attach(this.controlsBox, 0, 1, 1, 1); this.attach(this.controlsRevealer, 0, 1, 1, 1);
this.mapSignal = this.connect('map', this._onMap.bind(this)); this.mapSignal = this.connect('map', this._onMap.bind(this));
@@ -112,7 +116,9 @@ class ClapperWidget extends Gtk.Grid
const root = this.get_root(); const root = this.get_root();
const action = (isFullscreen) ? 'add' : 'remove'; const action = (isFullscreen) ? 'add' : 'remove';
root[action + '_css_class']('gpufriendlyfs'); root[action + '_css_class']('gpufriendlyfs');
root[action + '_css_class']('tvmode');
if(!this.isMobileMonitor)
root[action + '_css_class']('tvmode');
if(!this.floatingMode) if(!this.floatingMode)
this._changeControlsPlacement(isFullscreen); this._changeControlsPlacement(isFullscreen);
@@ -125,6 +131,10 @@ class ClapperWidget extends Gtk.Grid
this.controls.setFullscreenMode(isFullscreen); this.controls.setFullscreenMode(isFullscreen);
this.showControls(isFullscreen); this.showControls(isFullscreen);
this.revealerTop.headerBar.visible = !isFullscreen;
this.revealerTop.revealerGrid.visible = (isFullscreen && !this.isMobileMonitor);
this.player.widget.grab_focus(); this.player.widget.grab_focus();
if(this.player.playOnFullscreen && isFullscreen) { if(this.player.playOnFullscreen && isFullscreen) {
@@ -617,7 +627,7 @@ class ClapperWidget extends Gtk.Grid
const monitorWidth = Math.max(geometry.width, geometry.height); const monitorWidth = Math.max(geometry.width, geometry.height);
if(monitorWidth < 1280) { if(monitorWidth < 1280) {
this.controls.isMobileMonitor = true; this.isMobileMonitor = true;
debug('mobile monitor detected'); debug('mobile monitor detected');
} }