Skip to content

Commit 153317c

Browse files
committed
Add control buttons and album art for bar/media widget
1 parent 59b57fc commit 153317c

File tree

4 files changed

+115
-7
lines changed

4 files changed

+115
-7
lines changed

src/components/bar/modules/media/index.tsx

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import { onPrimaryClick, onSecondaryClick, onMiddleClick, onScroll } from 'src/l
33
import { bind, Variable } from 'astal';
44
import { Astal } from 'astal/gtk3';
55
import AstalMpris from 'gi://AstalMpris?version=0.1';
6+
import { NextTrack, PreviousTrack } from 'src/components/menus/media/components/controls/Tracks.js';
7+
import { PlayPause } from 'src/components/menus/media/components/controls/PlayPause.js';
8+
import { Gtk } from 'astal/gtk3';
9+
import { Binding } from 'astal';
10+
import { mediaArtUrl } from 'src/services/media';
11+
612
import { BarBoxChild } from 'src/components/bar/types.js';
713
import { activePlayer, mediaTitle, mediaAlbum, mediaArtist } from 'src/services/media';
814
import options from 'src/configuration';
@@ -16,6 +22,8 @@ const {
1622
truncation_size,
1723
show_label,
1824
show_active_only,
25+
use_image_controls_mode,
26+
disable_media_label,
1927
rightClick,
2028
middleClick,
2129
scrollUp,
@@ -29,6 +37,15 @@ Variable.derive([bind(show_active_only), bind(mprisService, 'players')], (showAc
2937
isVis.set(!showActive || players?.length > 0);
3038
});
3139

40+
const MediaImage = (): Astal.Box => {
41+
const getBackground = (): Binding<string> => {
42+
return Variable.derive([bind(mediaArtUrl)], (artUrl) => {
43+
return `background-image: url('${artUrl}');`;
44+
})();
45+
};
46+
return <box className="media-image" css={getBackground()} halign={Gtk.Align.CENTER} hexpand vertical />;
47+
};
48+
3249
const Media = (): BarBoxChild => {
3350
activePlayer.set(mprisService.get_players()[0]);
3451

@@ -72,20 +89,46 @@ const Media = (): BarBoxChild => {
7289
componentClassName.drop();
7390
}}
7491
>
92+
{/* My custom media indicatior */}
93+
<box
94+
visible={bind(use_image_controls_mode).as((useImageControlsMode) => useImageControlsMode)}
95+
className={'media-indicator-current-player'}
96+
>
97+
<MediaImage />
98+
<box className={'media-indicator-current-controls'} halign={Gtk.Align.CENTER}>
99+
<PreviousTrack />
100+
<PlayPause />
101+
<NextTrack />
102+
</box>
103+
</box>
104+
{/* Old media indicator */}
75105
<label
76106
className={'bar-button-icon media txt-icon bar'}
77107
label={bind(songIcon).as((icn) => icn || '󰝚')}
108+
visible={bind(use_image_controls_mode).as((useImageControlsMode) => !useImageControlsMode)}
109+
/>
110+
<label
111+
className={'bar-button-label media'}
112+
label={mediaLabel()}
113+
visible={bind(
114+
Variable.derive(
115+
[bind(use_image_controls_mode), bind(disable_media_label)],
116+
(useImageControlsMode, disableMediaLabel) =>
117+
!useImageControlsMode || !disableMediaLabel,
118+
),
119+
)}
78120
/>
79-
<label className={'bar-button-label media'} label={mediaLabel()} />
80121
</box>
81122
);
82123

83124
return {
84125
component,
85126
isVis: bind(isVis),
127+
isBox: true,
86128
boxClass: 'media',
87129
props: {
88-
setup: (self: Astal.Button): void => {
130+
tooltipText: bind(mediaLabel),
131+
setup: (self: Astal.Box): void => {
89132
let disconnectFunctions: (() => void)[] = [];
90133

91134
Variable.derive(
@@ -102,11 +145,14 @@ const Media = (): BarBoxChild => {
102145

103146
const throttledHandler = throttledScrollHandler(options.bar.scrollSpeed.get());
104147

105-
disconnectFunctions.push(
106-
onPrimaryClick(self, (clicked, event) => {
107-
openDropdownMenu(clicked, event, 'mediamenu');
108-
}),
109-
);
148+
// NOTE: As part of my "controls experiment," I decided to remove the primary click handler
149+
// as it causes problems when clicked on the buttons.
150+
//
151+
// disconnectFunctions.push(
152+
// onPrimaryClick(self, (clicked, event) => {
153+
// openDropdownMenu(clicked, event, 'mediamenu');
154+
// }),
155+
// );
110156

111157
disconnectFunctions.push(
112158
onSecondaryClick(self, (clicked, event) => {

src/components/settings/pages/config/bar/index.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,18 @@ export const BarSettings = (): JSX.Element => {
577577
subtitle="Hide if no media detected."
578578
type="boolean"
579579
/>
580+
<Option
581+
opt={options.bar.media.use_image_controls_mode}
582+
title="Use Image Controls Mode (@yunusey mode)"
583+
subtitle="Shows album art and media controls instead of media icon."
584+
type="boolean"
585+
/>
586+
<Option
587+
opt={options.bar.media.disable_media_label}
588+
title="Completely disable media label (@yunusey mode)"
589+
subtitle=""
590+
type="boolean"
591+
/>
580592
<Option opt={options.bar.media.rightClick} title="Right Click" type="string" />
581593
<Option opt={options.bar.media.middleClick} title="Middle Click" type="string" />
582594
<Option opt={options.bar.media.scrollUp} title="Scroll Up" type="string" />

src/configuration/modules/config/bar/media/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export default {
66
show_label: opt(true),
77
truncation_size: opt(30),
88
show_active_only: opt(false),
9+
use_image_controls_mode: opt(true),
10+
disable_media_label: opt(false), // used only if `use_image_controls_mode` is true
911
rightClick: opt(''),
1012
middleClick: opt(''),
1113
scrollUp: opt(''),

src/style/scss/bar/media.scss

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,54 @@
88
color: if($bar-buttons-monochrome, $bar-buttons-icon, $bar-buttons-media-icon);
99
}
1010

11+
.media-image {
12+
font-size: 1.2em;
13+
min-height: 1.2em;
14+
min-width: 1.5em;
15+
border-radius: $bar-buttons-radius;
16+
background-size: cover;
17+
background-repeat: no-repeat;
18+
background-position: center;
19+
};
20+
21+
.media-indicator-control-button {
22+
background: if($bar-buttons-monochrome, $bar-buttons-icon_background, $bar-buttons-media-icon_background);
23+
color: if($bar-buttons-monochrome, $bar-buttons-icon, $bar-buttons-media-background); // highlighted icon
24+
// color: if($bar-buttons-monochrome, $bar-buttons-icon, $bar-buttons-media-icon); // normal icon
25+
font-size: 1.2em;
26+
min-height: 1.2em;
27+
min-width: 1.5em;
28+
border-radius: $bar-buttons-radius;
29+
margin-left: $bar-buttons-media-spacing;
30+
31+
&.disabled {
32+
background: if($bar-menus-monochrome, $bar-menus-buttons-disabled, $bar-menus-menu-media-buttons-inactive);
33+
}
34+
35+
&.enabled {
36+
background: if($bar-buttons-monochrome, $bar-buttons-icon_background, $bar-buttons-media-icon_background); // highlighted background
37+
// background: if($bar-buttons-monochrome, $bar-buttons-icon_background, $bar-buttons-background); // normal background
38+
39+
&:hover {
40+
background: transparentize(
41+
if($bar-menus-monochrome, $bar-menus-buttons-default, $bar-menus-menu-media-buttons-background),
42+
0.5
43+
);
44+
}
45+
46+
&.active {
47+
background: if($bar-buttons-monochrome, $bar-buttons-icon_background, $bar-buttons-media-icon_background);
48+
49+
&:hover {
50+
background: transparentize(
51+
if($bar-menus-monochrome, $bar-menus-buttons-default, $bar-menus-menu-media-buttons-enabled),
52+
0.5
53+
);
54+
}
55+
}
56+
}
57+
}
58+
1159
.style2 {
1260
.bar-button-icon.media {
1361
background: if($bar-buttons-monochrome, $bar-buttons-icon_background, $bar-buttons-media-icon_background);

0 commit comments

Comments
 (0)