mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 16:02:00 +02:00
Add OSD headerbar and transition to floating mode
This commit is contained in:
@@ -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;
|
||||||
|
21
src/app.js
21
src/app.js
@@ -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
2
src/controls.js
vendored
@@ -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;
|
||||||
|
@@ -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();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
{
|
{
|
||||||
|
@@ -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');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user