mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Add OSD headerbar and transition to floating mode
This commit is contained in:
@@ -18,6 +18,12 @@ radio {
|
||||
.gtk402 .osd trough highlight {
|
||||
border-color: inherit;
|
||||
}
|
||||
.osd headerbar {
|
||||
background: transparent;
|
||||
}
|
||||
.osd headerbar button {
|
||||
border: transparent;
|
||||
}
|
||||
.adwrounded.csd {
|
||||
border-radius: 8px;
|
||||
}
|
||||
@@ -72,6 +78,9 @@ radio {
|
||||
font-size: 23px;
|
||||
text-shadow: none;
|
||||
}
|
||||
.reavealertop {
|
||||
background: transparent;
|
||||
}
|
||||
.tvmode .reavealertop {
|
||||
min-height: 88px;
|
||||
box-shadow: inset 0px 200px 10px -132px rgba(0,0,0,0.4);
|
||||
@@ -79,7 +88,6 @@ radio {
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
text-shadow: none;
|
||||
background: transparent;
|
||||
}
|
||||
.tvtime {
|
||||
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 { HeaderBar } = imports.src.headerbar;
|
||||
const { Widget } = imports.src.widget;
|
||||
const Debug = imports.src.debug;
|
||||
|
||||
@@ -23,14 +22,20 @@ class ClapperApp extends AppBase
|
||||
{
|
||||
super.vfunc_startup();
|
||||
|
||||
this.active_window.isClapperApp = true;
|
||||
this.active_window.add_css_class('nobackground');
|
||||
const window = this.active_window;
|
||||
|
||||
const clapperWidget = new Widget();
|
||||
this.active_window.set_child(clapperWidget);
|
||||
window.isClapperApp = true;
|
||||
window.add_css_class('nobackground');
|
||||
|
||||
const headerBar = new HeaderBar(this.active_window);
|
||||
this.active_window.set_titlebar(headerBar);
|
||||
const clapperWidget = new Widget(window);
|
||||
window.set_child(clapperWidget);
|
||||
|
||||
const dummyHeaderbar = new Gtk.HeaderBar({
|
||||
can_focus: false,
|
||||
focusable: false,
|
||||
visible: false,
|
||||
});
|
||||
window.set_titlebar(dummyHeaderbar);
|
||||
}
|
||||
|
||||
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.currentDuration = 0;
|
||||
this.isPositionDragging = false;
|
||||
|
||||
this.isMobileMonitor = false;
|
||||
this.isMobile = false;
|
||||
|
||||
this.showHours = false;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
const { GObject } = imports.gi;
|
||||
const { GObject, Gtk } = imports.gi;
|
||||
const { HeaderBarBase } = imports.src.headerbarBase;
|
||||
|
||||
var HeaderBar = GObject.registerClass(
|
||||
@@ -8,21 +8,18 @@ class ClapperHeaderBar extends HeaderBarBase
|
||||
{
|
||||
super._init(window);
|
||||
|
||||
const clapperWidget = window.get_child();
|
||||
clapperWidget.controls.unfloatButton.bind_property('visible', this, 'visible',
|
||||
GObject.BindingFlags.INVERT_BOOLEAN
|
||||
);
|
||||
this.title_widget.visible = false;
|
||||
}
|
||||
|
||||
_onFloatButtonClicked()
|
||||
{
|
||||
const clapperWidget = this.get_prev_sibling();
|
||||
clapperWidget.setFloatingMode(true);
|
||||
const clapperWidget = this.root.child;
|
||||
|
||||
clapperWidget.controlsRevealer.toggleReveal();
|
||||
}
|
||||
|
||||
_onFullscreenButtonClicked()
|
||||
{
|
||||
const window = this.get_parent();
|
||||
window.fullscreen();
|
||||
this.root.fullscreen();
|
||||
}
|
||||
});
|
||||
|
@@ -20,26 +20,31 @@ class ClapperHeaderBarBase extends Gtk.HeaderBar
|
||||
|
||||
const mainMenuButton = new Gtk.MenuButton({
|
||||
icon_name: 'open-menu-symbolic',
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
const mainMenuModel = uiBuilder.get_object('mainMenu');
|
||||
const mainMenuPopover = new HeaderBarPopover(mainMenuModel);
|
||||
mainMenuButton.set_popover(mainMenuPopover);
|
||||
mainMenuButton.add_css_class('circular');
|
||||
this.pack_start(mainMenuButton);
|
||||
|
||||
const buttonsBox = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
buttonsBox.add_css_class('linked');
|
||||
|
||||
const floatButton = new Gtk.Button({
|
||||
icon_name: 'preferences-desktop-remote-desktop-symbolic',
|
||||
});
|
||||
floatButton.add_css_class('circular');
|
||||
floatButton.connect('clicked', this._onFloatButtonClicked.bind(this));
|
||||
buttonsBox.append(floatButton);
|
||||
|
||||
const fullscreenButton = new Gtk.Button({
|
||||
icon_name: 'view-fullscreen-symbolic',
|
||||
});
|
||||
fullscreenButton.add_css_class('circular');
|
||||
fullscreenButton.connect('clicked', this._onFullscreenButtonClicked.bind(this));
|
||||
|
||||
buttonsBox.append(fullscreenButton);
|
||||
|
@@ -685,11 +685,6 @@ class ClapperPlayer extends PlayerBase
|
||||
if(!this._updateTimeTimeout)
|
||||
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();
|
||||
}
|
||||
else {
|
||||
@@ -698,6 +693,12 @@ class ClapperPlayer extends PlayerBase
|
||||
if(this._updateTimeTimeout)
|
||||
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;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
const { GLib, GObject, Gtk, Pango } = imports.gi;
|
||||
const { HeaderBar } = imports.src.headerbar;
|
||||
const Debug = imports.src.debug;
|
||||
|
||||
const REVEAL_TIME = 800;
|
||||
@@ -89,7 +90,7 @@ class ClapperCustomRevealer extends Gtk.Revealer
|
||||
var RevealerTop = GObject.registerClass(
|
||||
class ClapperRevealerTop extends CustomRevealer
|
||||
{
|
||||
_init()
|
||||
_init(window)
|
||||
{
|
||||
super._init({
|
||||
transition_duration: REVEAL_TIME,
|
||||
@@ -103,12 +104,6 @@ class ClapperRevealerTop extends CustomRevealer
|
||||
? '%I:%M %p'
|
||||
: '%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({
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
vexpand: true,
|
||||
@@ -131,11 +126,25 @@ class ClapperRevealerTop extends CustomRevealer
|
||||
this.endTime = new Gtk.Label(timeLabelOpts);
|
||||
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.currentTime, 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)
|
||||
@@ -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(
|
||||
class ClapperButtonsRevealer extends Gtk.Revealer
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ const { settings } = Misc;
|
||||
var Widget = GObject.registerClass(
|
||||
class ClapperWidget extends Gtk.Grid
|
||||
{
|
||||
_init()
|
||||
_init(window)
|
||||
{
|
||||
super._init();
|
||||
|
||||
@@ -27,11 +27,12 @@ class ClapperWidget extends Gtk.Grid
|
||||
this.fullscreenMode = false;
|
||||
this.floatingMode = false;
|
||||
this.isSeekable = false;
|
||||
this.isMobileMonitor = false;
|
||||
|
||||
this.needsTracksUpdate = true;
|
||||
|
||||
this.overlay = new Gtk.Overlay();
|
||||
this.revealerTop = new Revealers.RevealerTop();
|
||||
this.revealerTop = new Revealers.RevealerTop(window);
|
||||
this.revealerBottom = new Revealers.RevealerBottom();
|
||||
this.controls = new Controls();
|
||||
|
||||
@@ -41,8 +42,11 @@ class ClapperWidget extends Gtk.Grid
|
||||
this.controlsBox.add_css_class('controlsbox');
|
||||
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.controlsBox, 0, 1, 1, 1);
|
||||
this.attach(this.controlsRevealer, 0, 1, 1, 1);
|
||||
|
||||
this.mapSignal = this.connect('map', this._onMap.bind(this));
|
||||
|
||||
@@ -112,7 +116,9 @@ class ClapperWidget extends Gtk.Grid
|
||||
const root = this.get_root();
|
||||
const action = (isFullscreen) ? 'add' : 'remove';
|
||||
root[action + '_css_class']('gpufriendlyfs');
|
||||
root[action + '_css_class']('tvmode');
|
||||
|
||||
if(!this.isMobileMonitor)
|
||||
root[action + '_css_class']('tvmode');
|
||||
|
||||
if(!this.floatingMode)
|
||||
this._changeControlsPlacement(isFullscreen);
|
||||
@@ -125,6 +131,10 @@ class ClapperWidget extends Gtk.Grid
|
||||
|
||||
this.controls.setFullscreenMode(isFullscreen);
|
||||
this.showControls(isFullscreen);
|
||||
|
||||
this.revealerTop.headerBar.visible = !isFullscreen;
|
||||
this.revealerTop.revealerGrid.visible = (isFullscreen && !this.isMobileMonitor);
|
||||
|
||||
this.player.widget.grab_focus();
|
||||
|
||||
if(this.player.playOnFullscreen && isFullscreen) {
|
||||
@@ -617,7 +627,7 @@ class ClapperWidget extends Gtk.Grid
|
||||
const monitorWidth = Math.max(geometry.width, geometry.height);
|
||||
|
||||
if(monitorWidth < 1280) {
|
||||
this.controls.isMobileMonitor = true;
|
||||
this.isMobileMonitor = true;
|
||||
debug('mobile monitor detected');
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user