sidebar: add volume mixer

This commit is contained in:
end-4
2024-03-24 21:37:06 +07:00
parent bf2920a76d
commit 0fd91e18fc
12 changed files with 401 additions and 42 deletions
@@ -4,9 +4,9 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
const { Box, Button, Label, Scrollable, Stack } = Widget;
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import Notification from '../.commonwidgets/notification.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import Notification from '../../.commonwidgets/notification.js';
export default (props) => {
const notifEmptyContent = Box({
@@ -18,7 +18,7 @@ export default (props) => {
children: [
Box({
vertical: true,
className: 'spacing-v-5',
className: 'spacing-v-5 txt-subtext',
children: [
MaterialIcon('notifications_active', 'gigantic'),
Label({ label: 'No notifications', className: 'txt-small' }),
@@ -88,18 +88,29 @@ export default (props) => {
Notifications.clear();
notificationList.get_children().forEach(ch => ch.attribute.destroyWithAnims())
});
const notifCount = Label({
attribute: {
updateCount: (self) => {
const count = Notifications.notifications.length;
if (count > 0) self.label = `${count} notifications`;
else self.label = '';
},
},
hexpand: true,
xalign: 0,
className: 'txt-small margin-left-10',
label: `${Notifications.notifications.length}`,
setup: (self) => self
.hook(Notifications, (box, id) => self.attribute.updateCount(self), 'notified')
.hook(Notifications, (box, id) => self.attribute.updateCount(self), 'dismissed')
.hook(Notifications, (box, id) => self.attribute.updateCount(self), 'closed')
,
});
const listTitle = Box({
vpack: 'start',
className: 'sidebar-group-invisible txt spacing-h-5',
children: [
Label({
hexpand: true,
xalign: 0,
className: 'txt-title-small margin-left-10',
// ^ (extra margin on the left so that it looks similarly spaced
// when compared to borderless "Clear" button on the right)
label: 'Notifications',
}),
notifCount,
silenceButton,
clearButton,
]
@@ -131,11 +142,11 @@ export default (props) => {
});
return Box({
...props,
className: 'sidebar-group spacing-v-5',
className: 'spacing-v-5',
vertical: true,
children: [
listTitle,
listContents,
listTitle,
]
});
}
@@ -0,0 +1,94 @@
// This file is for the notification list on the sidebar
// For the popup notifications, see onscreendisplay.js
// The actual widget for each single notification is in ags/modules/.commonwidgets/notification.js
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
const { Box, Button, Icon, Label, Scrollable, Slider, Stack } = Widget;
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { AnimatedSlider } from '../../.commonwidgets/cairo_slider.js';
const appVolume = (stream) => {
console.log(stream)
return Box({
className: 'sidebar-volmixer-stream spacing-h-10',
children: [
Icon({
className: 'sidebar-volmixer-stream-appicon',
vpack: 'center',
icon: stream.stream.name.toLowerCase(),
}),
Box({
hexpand: true,
vpack: 'center',
vertical: true,
className: 'spacing-v-5',
children: [
Label({
xalign: 0,
maxWidthChars: 10,
truncate: 'end',
label: stream.description,
className: 'txt-small',
setup: (self) => {
self.hook(stream, (self) => {
self.label = `${stream.description}`
})
}
}),
Slider({
drawValue: false,
hpack: 'fill',
className: 'sidebar-volmixer-stream-slider',
value: stream.volume,
min: 0, max: 1,
onChange: ({value}) => {
stream.volume = value;
},
setup: (self) => {
self.hook(stream, (self) => {
self.value = stream.volume;
})
}
}),
// Box({
// homogeneous: true,
// className: 'test',
// children: [AnimatedSlider({
// className: 'sidebar-volmixer-stream-slider',
// value: stream.volume,
// })],
// })
]
})
]
})
}
export default (props) => {
const appList = Scrollable({
vexpand: true,
child: Box({
attribute: {
'updateStreams': (self) => {
const streams = Audio.apps;
self.children = streams.map(stream => appVolume(stream));
},
},
vertical: true,
className: 'spacing-v-5',
setup: (self) => self
.hook(Audio, self.attribute.updateStreams, 'stream-added')
.hook(Audio, self.attribute.updateStreams, 'stream-removed')
,
})
})
return Box({
...props,
className: 'spacing-v-5',
vertical: true,
children: [
appList,
]
});
}
+46 -3
View File
@@ -15,9 +15,26 @@ import {
ModulePowerIcon,
ModuleRawInput
} from "./quicktoggles.js";
import ModuleNotificationList from "./notificationlist.js";
import ModuleNotificationList from "./centermodules/notificationlist.js";
import ModuleVolumeMixer from "./centermodules/volumemixer.js";
import { ModuleCalendar } from "./calendar.js";
import { getDistroIcon } from '../.miscutils/system.js';
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { ExpandingIconTabContainer } from '../.commonwidgets/tabcontainer.js';
import { checkKeybind } from '../.widgetutils/keybind.js';
const centerWidgets = [
{
name: 'Notifications',
materialIcon: 'notifications',
contentWidget: ModuleNotificationList(),
},
{
name: 'Volume mixer',
materialIcon: 'volume_up',
contentWidget: ModuleVolumeMixer(),
},
];
const timeRow = Box({
className: 'spacing-h-10 sidebar-group-invisible-morehorizpad',
@@ -60,6 +77,17 @@ const togglesBox = Widget.Box({
]
})
export const sidebarOptionsStack = ExpandingIconTabContainer({
tabsHpack: 'center',
tabSwitcherClassName: 'sidebar-icontabswitcher',
icons: centerWidgets.map((api) => api.materialIcon),
names: centerWidgets.map((api) => api.name),
children: centerWidgets.map((api) => api.contentWidget),
onChange: (self, id) => {
self.shown = centerWidgets[id].name;
}
});
export default () => Box({
vexpand: true,
hexpand: true,
@@ -84,9 +112,24 @@ export default () => Box({
togglesBox,
]
}),
ModuleNotificationList({ vexpand: true, }),
Box({
className: 'sidebar-group',
children: [
sidebarOptionsStack,
],
}),
ModuleCalendar(),
]
}),
]
],
setup: (self) => self
.on('key-press-event', (widget, event) => { // Handle keybinds
if (checkKeybind(event, userOptions.keybinds.sidebar.options.nextTab)) {
sidebarOptionsStack.nextTab();
}
else if (checkKeybind(event, userOptions.keybinds.sidebar.options.prevTab)) {
sidebarOptionsStack.prevTab();
}
})
,
});