feat(center-window/big-media): add player select button

This commit is contained in:
retrozinndev
2025-07-25 19:08:03 -03:00
parent d4c1fcf327
commit 3b59243cdc
7 changed files with 260 additions and 79 deletions
+33 -25
View File
@@ -198,32 +198,26 @@ tooltip > box {
}
}
popover.menu {
popover.menu contents {
background: wal.$background;
border-radius: 14px;
$padding: 4px;
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);
}
& > * > * {
& > separator {
min-height: .5px;
margin: 3px 2px;
background: rgba(colors.$fg-disabled, .1);
}
& > *:not(separator) > * {
padding: 6px;
border-radius: 10px;
font-size: 12px;
font-weight: 600;
& > *:not(separator) > * {
padding: 6px;
border-radius: 10px;
font-size: 12px;
font-weight: 600;
&:hover, &:focus {
background: wal.$color1;
}
}
&:hover, &:focus {
background: wal.$color1;
}
}
}
@@ -231,25 +225,39 @@ 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
View File
@@ -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 {
+39
View File
@@ -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;
+21 -6
View File
@@ -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 {
+19 -11
View File
@@ -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 {
&:hover {
box-shadow: inset 0 0 0 500px rgba(colors.$fg-primary, .2);
}
}
@mixin button-reactive-secondary {
background: colors.$bg-secondary;
border-radius: 12px;
padding: 6px;
@mixin hover-shadow3 {
&:hover {
box-shadow: inset 0 0 0 500px rgba(colors.$fg-primary, .3);
background: colors.$bg-tertiary;
}
&:active {
border-radius: 9px;
}
}
+20 -20
View File
@@ -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;
+98 -6
View File
@@ -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>;
}