✨ feat(center-window/big-media): add player select button
This commit is contained in:
+21
-13
@@ -198,22 +198,18 @@ tooltip > box {
|
||||
}
|
||||
}
|
||||
|
||||
popover.menu {
|
||||
popover.menu contents {
|
||||
background: wal.$background;
|
||||
border-radius: 14px;
|
||||
$padding: 4px;
|
||||
|
||||
& contents {
|
||||
& viewport > stack > * {
|
||||
padding: 4px;
|
||||
padding-top: 0;
|
||||
|
||||
& > * > * {
|
||||
& viewport > stack > * > * > * {
|
||||
& > separator {
|
||||
min-height: .5px;
|
||||
margin: 3px 2px;
|
||||
background: rgba(colors.$fg-disabled, .1);
|
||||
}
|
||||
|
||||
& > *:not(separator) > * {
|
||||
padding: 6px;
|
||||
border-radius: 10px;
|
||||
@@ -226,30 +222,42 @@ popover.menu {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-row {
|
||||
& > button {
|
||||
$active-radius: 8px;
|
||||
$corner-radius: calc($active-radius + 2px);
|
||||
|
||||
background: colors.$bg-secondary;
|
||||
margin: 0 1px;
|
||||
padding: 4px 6px;
|
||||
border-radius: 2px;
|
||||
transition: 120ms linear;
|
||||
|
||||
&:hover {
|
||||
background: colors.$bg-tertiary;
|
||||
}
|
||||
|
||||
&:active {
|
||||
border-radius: $active-radius;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
margin-left: 0;
|
||||
|
||||
&:not(:active) {
|
||||
border-top-left-radius: $corner-radius;
|
||||
border-bottom-left-radius: $corner-radius;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
margin-right: 0;
|
||||
|
||||
&:not(:active) {
|
||||
border-top-right-radius: $corner-radius;
|
||||
border-bottom-right-radius: $corner-radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-10
@@ -1,8 +1,18 @@
|
||||
@use "sass:color";
|
||||
@use "./mixins";
|
||||
@use "./colors";
|
||||
@use "./wal";
|
||||
@use "./functions";
|
||||
|
||||
|
||||
$radius: 18px;
|
||||
$padding: 4px;
|
||||
$color-hover: colors.$bg-primary;
|
||||
|
||||
|
||||
@mixin button-reactivity {
|
||||
&:active {
|
||||
box-shadow: 0 0 0 2px $color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
.bar-container {
|
||||
padding: 6px;
|
||||
@@ -17,16 +27,14 @@
|
||||
|
||||
// Style widget groups
|
||||
& > .bar-centerbox > * {
|
||||
$radius: 18px !global;
|
||||
$padding: 4px !global;
|
||||
$color-hover: colors.$bg-primary;
|
||||
|
||||
background: rgba(colors.$bg-translucent, .6);
|
||||
border-radius: $radius;
|
||||
padding: 0 $padding;
|
||||
|
||||
& > box:not(.workspaces-row):not(.tray):not(.focused-client):not(.media),
|
||||
& > button {
|
||||
@include button-reactivity;
|
||||
|
||||
border-radius: calc($radius - $padding);
|
||||
margin: $padding 0;
|
||||
padding: 0 8px;
|
||||
@@ -48,6 +56,10 @@
|
||||
padding: 0 6px;
|
||||
background: colors.$bg-tertiary;
|
||||
|
||||
&:active {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
& label.id {
|
||||
font-weight: 600;
|
||||
margin-right: 4px;
|
||||
@@ -110,15 +122,13 @@
|
||||
|
||||
.media {
|
||||
$spacing: 5px;
|
||||
$hover-color: color.scale($color: colors.$bg-primary, $lightness: 15%);
|
||||
|
||||
background: colors.$bg-primary;
|
||||
border-radius: calc($radius - $padding);
|
||||
margin: $padding 0;
|
||||
padding: 0 calc($padding + 3px);
|
||||
|
||||
&:hover {
|
||||
background: color.scale($color: colors.$bg-primary, $lightness: 15%);
|
||||
}
|
||||
|
||||
& image.player-icon {
|
||||
-gtk-icon-size: 14px;
|
||||
margin-right: $spacing;
|
||||
@@ -135,6 +145,15 @@
|
||||
-gtk-icon-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&:hover {
|
||||
background: $hover-color;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0 0 2px $hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
.tray {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@use "sass:color";
|
||||
@use "./wal";
|
||||
@use "./colors";
|
||||
@use "./mixins";
|
||||
|
||||
|
||||
.popup-window.center-window .center-window-container {
|
||||
@@ -34,6 +35,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
& .player-select {
|
||||
@include mixins.button-reactive-secondary;
|
||||
|
||||
border-radius: 14px;
|
||||
|
||||
& revealer label {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
margin-right: 2px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
image.arrow {
|
||||
-gtk-icon-size: 12px;
|
||||
margin-left: 6px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
& popover contents {
|
||||
background: colors.$bg-primary;
|
||||
border-radius: 16px;
|
||||
padding: 4px;
|
||||
|
||||
& button {
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
|
||||
& image {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: colors.$bg-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& slider {
|
||||
all: unset;
|
||||
opacity: 0;
|
||||
|
||||
@@ -63,14 +63,16 @@
|
||||
}
|
||||
|
||||
button {
|
||||
@include mixins.hover-shadow2;
|
||||
|
||||
padding: 4px;
|
||||
border-radius: 16px;
|
||||
|
||||
icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(colors.$fg-primary, .2);
|
||||
}
|
||||
}
|
||||
|
||||
& .page .content {
|
||||
@@ -125,8 +127,6 @@
|
||||
}
|
||||
|
||||
& button {
|
||||
@include mixins.hover-shadow;
|
||||
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
|
||||
@@ -143,6 +143,10 @@
|
||||
& icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(colors.$fg-primary, .1);
|
||||
}
|
||||
}
|
||||
|
||||
& .bottom-buttons button {
|
||||
@@ -194,14 +198,19 @@
|
||||
background: colors.$bg-secondary;
|
||||
}
|
||||
|
||||
&.has-more > .toggle-button {
|
||||
&.has-more > .toggle-button,
|
||||
&.has-more > button.toggle-button:active {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
& > .toggle-button {
|
||||
& > button.toggle-button {
|
||||
border-radius: $radius;
|
||||
|
||||
&:active {
|
||||
border-radius: calc($radius - 4px);
|
||||
}
|
||||
|
||||
& .content {
|
||||
padding: 8px;
|
||||
|
||||
@@ -228,6 +237,11 @@
|
||||
border-top-right-radius: $radius;
|
||||
border-bottom-right-radius: $radius;
|
||||
|
||||
&:active {
|
||||
border-top-right-radius: calc($radius - 4px);
|
||||
border-bottom-right-radius: calc($radius - 4px);
|
||||
}
|
||||
|
||||
& label {
|
||||
font-size: 16px;
|
||||
}
|
||||
@@ -272,6 +286,7 @@ box.notif-history {
|
||||
margin-top: 12px;
|
||||
|
||||
& button {
|
||||
@include mixins.button-reactive-secondary;
|
||||
padding: 7px;
|
||||
|
||||
& label {
|
||||
|
||||
+18
-10
@@ -1,7 +1,5 @@
|
||||
@use "sass:color";
|
||||
@use "./wal";
|
||||
@use "./colors";
|
||||
@use "./functions" as funs;
|
||||
|
||||
@mixin reset-props {
|
||||
all: unset;
|
||||
@@ -14,20 +12,30 @@
|
||||
color: colors.$fg-primary;
|
||||
}
|
||||
|
||||
@mixin hover-shadow {
|
||||
@mixin button-reactive-primary {
|
||||
background: colors.$bg-primary;
|
||||
border-radius: 14px;
|
||||
padding: 6px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 500px rgba(colors.$fg-primary, .1);
|
||||
background: colors.$bg-secondary;
|
||||
}
|
||||
|
||||
&:active {
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin hover-shadow2 {
|
||||
@mixin button-reactive-secondary {
|
||||
background: colors.$bg-secondary;
|
||||
border-radius: 12px;
|
||||
padding: 6px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 500px rgba(colors.$fg-primary, .2);
|
||||
}
|
||||
background: colors.$bg-tertiary;
|
||||
}
|
||||
|
||||
@mixin hover-shadow3 {
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 500px rgba(colors.$fg-primary, .3);
|
||||
&:active {
|
||||
border-radius: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,26 +1,26 @@
|
||||
// SCSS Variables
|
||||
// Generated by 'wal'
|
||||
$wallpaper: "/home/joaov/wallpapers/Anna Yanami Makeine Blue Sky.jpg";
|
||||
$wallpaper: "/home/joaov/wallpapers/Frieren Battleground.jpg";
|
||||
|
||||
// Special
|
||||
$background: #2d3643;
|
||||
$foreground: #caccd0;
|
||||
$cursor: #caccd0;
|
||||
$background: #181515;
|
||||
$foreground: #c5c4c4;
|
||||
$cursor: #c5c4c4;
|
||||
|
||||
// Colors
|
||||
$color0: #2d3643;
|
||||
$color1: #738AA7;
|
||||
$color2: #3784E4;
|
||||
$color3: #5A99EA;
|
||||
$color4: #B8A9A4;
|
||||
$color5: #8CB9EB;
|
||||
$color6: #A2C8EF;
|
||||
$color7: #a0a4a9;
|
||||
$color8: #707b89;
|
||||
$color9: #87a5cb;
|
||||
$color10: #87a5cb;
|
||||
$color11: #9db5d4;
|
||||
$color12: #dab6a8;
|
||||
$color13: #b7cae0;
|
||||
$color14: #c5d5e6;
|
||||
$color15: #caccd0;
|
||||
$color0: #181515;
|
||||
$color1: #975969;
|
||||
$color2: #7f6960;
|
||||
$color3: #7f697f;
|
||||
$color4: #a57e83;
|
||||
$color5: #878193;
|
||||
$color6: #9d8793;
|
||||
$color7: #9b9090;
|
||||
$color8: #715c5c;
|
||||
$color9: #CA778C;
|
||||
$color10: #AA8C81;
|
||||
$color11: #AA8CAA;
|
||||
$color12: #DCA8AF;
|
||||
$color13: #B4ADC5;
|
||||
$color14: #D2B5C5;
|
||||
$color15: #c5c4c4;
|
||||
|
||||
@@ -2,9 +2,9 @@ import { timeout } from "ags/time";
|
||||
import { execAsync } from "ags/process";
|
||||
import { Astal, Gtk } from "ags/gtk4";
|
||||
import { Clipboard } from "../../scripts/clipboard";
|
||||
import { player } from "../bar/Media";
|
||||
import { createBinding, With } from "ags";
|
||||
import { pathToURI } from "../../scripts/utils";
|
||||
import { player, setPlayer } from "../bar/Media";
|
||||
import { Accessor, createBinding, createConnection, For, With } from "ags";
|
||||
import { getPlayerIconFromBusName, pathToURI } from "../../scripts/utils";
|
||||
|
||||
import AstalMpris from "gi://AstalMpris";
|
||||
import AstalIO from "gi://AstalIO";
|
||||
@@ -23,13 +23,16 @@ export const BigMedia = () => {
|
||||
|
||||
<Gtk.Revealer hexpand={false} revealChild={
|
||||
createBinding(player, "artUrl").as(Boolean)
|
||||
} transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN} transitionDuration={250}>
|
||||
} transitionType={Gtk.RevealerTransitionType.SLIDE_LEFT} transitionDuration={300}>
|
||||
|
||||
<Gtk.Box class={"image"} css={createBinding(player, "artUrl").as((art) =>
|
||||
`background-image: url("${pathToURI(art)}");`)}
|
||||
hexpand={false} vexpand={false} widthRequest={132} heightRequest={128}
|
||||
valign={Gtk.Align.START} halign={Gtk.Align.CENTER}
|
||||
/>
|
||||
valign={Gtk.Align.START} halign={Gtk.Align.CENTER}>
|
||||
|
||||
<PlayerSelectButton player={player} halign={Gtk.Align.END}
|
||||
valign={Gtk.Align.END} />
|
||||
</Gtk.Box>
|
||||
</Gtk.Revealer>
|
||||
|
||||
<Gtk.Box class={"info"} orientation={Gtk.Orientation.VERTICAL}
|
||||
@@ -49,6 +52,16 @@ export const BigMedia = () => {
|
||||
/>
|
||||
</Gtk.Box>
|
||||
|
||||
<Gtk.Box>
|
||||
<With value={createBinding(player, "artUrl").as(Boolean)}>
|
||||
{(hasAlbumArt) => !hasAlbumArt &&
|
||||
<PlayerSelectButton player={player} reveal={true}
|
||||
halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER}
|
||||
/>
|
||||
}
|
||||
</With>
|
||||
</Gtk.Box>
|
||||
|
||||
<Gtk.Box class={"progress"} hexpand visible={createBinding(player, "canSeek")}>
|
||||
<Astal.Slider hexpand max={createBinding(player, "length").as(Math.floor)}
|
||||
value={createBinding(player, "position").as(Math.floor)}
|
||||
@@ -151,3 +164,82 @@ export const BigMedia = () => {
|
||||
</With>
|
||||
</Gtk.Box> as Gtk.Box;
|
||||
}
|
||||
|
||||
export function PlayerSelectButton({ player, reveal, halign = Gtk.Align.CENTER, valign = Gtk.Align.CENTER }: {
|
||||
player: AstalMpris.Player,
|
||||
reveal?: Accessor<boolean>|boolean,
|
||||
halign?: Gtk.Align;
|
||||
valign?: Gtk.Align;
|
||||
}) {
|
||||
const availablePlayers = createBinding(AstalMpris.get_default(), "players").as(players =>
|
||||
players.filter(p => p.available));
|
||||
|
||||
return <Gtk.Box vexpand={false} valign={valign} halign={halign}>
|
||||
<With value={availablePlayers.as(apls => apls.length > 1)}>
|
||||
{(show: boolean) => show &&
|
||||
<Gtk.MenuButton halign={Gtk.Align.CENTER} hexpand
|
||||
class={"player-select"} popover={
|
||||
<Gtk.Popover class={"players-list"} hasArrow={false}>
|
||||
<Gtk.Box orientation={Gtk.Orientation.VERTICAL}>
|
||||
<For each={availablePlayers}>
|
||||
{(pl: AstalMpris.Player) =>
|
||||
<Gtk.Button class={"player"} onClicked={() => setPlayer(pl)}>
|
||||
<Gtk.Box>
|
||||
<Gtk.Image iconName={createBinding(player, "busName").as(
|
||||
getPlayerIconFromBusName
|
||||
)} />
|
||||
<Gtk.Label label={createBinding(player, "identity")}
|
||||
hexpand={false} class={"identity"} singleLineMode
|
||||
maxWidthChars={8}
|
||||
/>
|
||||
</Gtk.Box>
|
||||
</Gtk.Button>
|
||||
}
|
||||
</For>
|
||||
</Gtk.Box>
|
||||
</Gtk.Popover> as Gtk.Popover
|
||||
} $={(self) => {
|
||||
const controllerMotion = Gtk.EventControllerMotion.new();
|
||||
self.add_controller(controllerMotion);
|
||||
|
||||
self.set_child(
|
||||
<Gtk.Box class={"player"}>
|
||||
<Gtk.Image iconName={createBinding(player, "busName").as(
|
||||
getPlayerIconFromBusName)}
|
||||
/>
|
||||
<Gtk.Revealer transitionType={Gtk.RevealerTransitionType.SLIDE_LEFT}
|
||||
transitionDuration={280} revealChild={reveal ?? createConnection(false,
|
||||
[controllerMotion, "enter", () => {
|
||||
self.add_css_class("reveal");
|
||||
return true;
|
||||
}],
|
||||
[controllerMotion, "leave", () => {
|
||||
self.remove_css_class("reveal");
|
||||
return false;
|
||||
}]
|
||||
)
|
||||
}>
|
||||
|
||||
<Gtk.Box>
|
||||
<Gtk.Label label={createBinding(player, "identity")}
|
||||
class={"identity"} maxWidthChars={6}
|
||||
ellipsize={Pango.EllipsizeMode.END}
|
||||
tooltipText={createBinding(player, "identity")}
|
||||
/>
|
||||
<Gtk.Image iconName={
|
||||
createConnection("go-next-symbolic",
|
||||
[self.popover, "show", () => "go-down-symbolic"],
|
||||
[self.popover, "closed", () => "go-next-symbolic"]
|
||||
)
|
||||
} class={"arrow"} iconSize={Gtk.IconSize.NORMAL}
|
||||
/>
|
||||
</Gtk.Box>
|
||||
</Gtk.Revealer>
|
||||
</Gtk.Box> as Gtk.Box
|
||||
);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</With>
|
||||
</Gtk.Box>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user