sidebar: bluetooth: add connection toggle

This commit is contained in:
end-4
2024-03-28 17:34:04 +07:00
parent 5cccd08a63
commit 0b394d49ae
2 changed files with 129 additions and 92 deletions
@@ -1,37 +1,60 @@
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js'; import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js'; import { MaterialIcon } from './materialicon.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js'; import { setupCursorHover } from '../.widgetutils/cursorhover.js';
const { Box, Button, Label, Revealer } = Widget; const { Box, Button, Label, Revealer } = Widget;
export const ConfigToggle = ({ icon, name, desc = '', initValue, onChange, expandWidget = true, ...rest }) => { export const ConfigToggle = ({
let value = initValue; icon, name, desc = '', initValue,
expandWidget = true,
onChange = () => { }, extraSetup = () => { },
...rest
}) => {
const enabled = Variable(initValue);
const toggleIcon = Label({ const toggleIcon = Label({
className: `icon-material txt-bold ${value ? '' : 'txt-poof'}`, className: `icon-material txt-bold ${enabled.value ? '' : 'txt-poof'}`,
label: `${value ? 'check' : ''}`, label: `${enabled.value ? 'check' : ''}`,
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-fg-toggling-false', false);
if (!enabled.value) {
self.label = '';
self.toggleClassName('txt-poof', true);
}
else Utils.timeout(1, () => {
toggleIcon.label = 'check';
toggleIcon.toggleClassName('txt-poof', false);
})
}),
}) })
const toggleButtonIndicator = Box({ const toggleButtonIndicator = Box({
className: `switch-fg ${value ? 'switch-fg-true' : ''}`, className: `switch-fg ${enabled.value ? 'switch-fg-true' : ''}`,
vpack: 'center', vpack: 'center',
hpack: 'start', hpack: 'start',
homogeneous: true, homogeneous: true,
children: [toggleIcon,], children: [toggleIcon,],
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-fg-true', enabled.value);
}),
}); });
const toggleButton = Box({ const toggleButton = Box({
hpack: 'end', hpack: 'end',
className: `switch-bg ${value ? 'switch-bg-true' : ''}`, className: `switch-bg ${enabled.value ? 'switch-bg-true' : ''}`,
homogeneous: true, homogeneous: true,
children: [toggleButtonIndicator,], children: [toggleButtonIndicator],
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-bg-true', enabled.value);
}),
}); });
const widgetContent = Box({ const widgetContent = Box({
tooltipText: desc, tooltipText: desc,
className: 'txt spacing-h-5 configtoggle-box', className: 'txt spacing-h-5 configtoggle-box',
children: [ children: [
MaterialIcon(icon, 'norm'), (icon !== undefined ? MaterialIcon(icon, 'norm') : null),
Label({ (name !== undefined ? Label({
className: 'txt txt-small', className: 'txt txt-small',
label: name, label: name,
}), }) : null),
expandWidget ? Box({ hexpand: true }) : null, expandWidget ? Box({ hexpand: true }) : null,
toggleButton, toggleButton,
] ]
@@ -39,33 +62,24 @@ export const ConfigToggle = ({ icon, name, desc = '', initValue, onChange, expan
const interactionWrapper = Button({ const interactionWrapper = Button({
attribute: { attribute: {
toggle: (newValue) => { toggle: (newValue) => {
value = !value; enabled.value = !enabled.value;
toggleIcon.toggleClassName('switch-fg-toggling-false', false); onChange(interactionWrapper, enabled.value);
if (!value) {
toggleIcon.label = '';
toggleIcon.toggleClassName('txt-poof', true);
}
toggleButtonIndicator.toggleClassName('switch-fg-true', value);
toggleButton.toggleClassName('switch-bg-true', value);
if (value) Utils.timeout(1, () => {
toggleIcon.label = 'check';
toggleIcon.toggleClassName('txt-poof', false);
})
onChange(interactionWrapper, value);
} }
}, },
child: widgetContent, child: widgetContent,
onClicked: (self) => self.attribute.toggle(self), onClicked: (self) => self.attribute.toggle(self),
setup: (button) => { setup: (self) => {
setupCursorHover(button), setupCursorHover(self);
button.connect('pressed', () => { // mouse down self.connect('pressed', () => { // mouse down
toggleIcon.toggleClassName('txt-poof', true); toggleIcon.toggleClassName('txt-poof', true);
toggleIcon.toggleClassName('switch-fg-true', false); toggleIcon.toggleClassName('switch-fg-true', false);
if (!value) toggleIcon.toggleClassName('switch-fg-toggling-false', true); if (!enabled.value) toggleIcon.toggleClassName('switch-fg-toggling-false', true);
}); });
extraSetup(self)
}, },
...rest, ...rest,
}); });
interactionWrapper.enabled = enabled;
return interactionWrapper; return interactionWrapper;
} }
@@ -123,8 +137,8 @@ export const ConfigSegmentedSelection = ({
export const ConfigMulipleSelection = ({ export const ConfigMulipleSelection = ({
icon, name, desc = '', icon, name, desc = '',
optionsArr = [ optionsArr = [
[ { name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 } ], [{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
[ { name: 'Option 3', value: 0 }, { name: 'Option 4', value: 1 } ], [{ name: 'Option 3', value: 0 }, { name: 'Option 4', value: 1 }],
], ],
initIndex = [0, 0], initIndex = [0, 0],
onChange, onChange,
@@ -137,27 +151,27 @@ export const ConfigMulipleSelection = ({
className: 'multipleselection-container spacing-v-3', className: 'multipleselection-container spacing-v-3',
vertical: true, vertical: true,
children: optionsArr.map((options, grp) => { children: optionsArr.map((options, grp) => {
return Box({ return Box({
className: 'spacing-h-5', className: 'spacing-h-5',
hpack: 'center', hpack: 'center',
children: options.map((option, id) => { children: options.map((option, id) => {
return Button({ return Button({
setup: setupCursorHover, setup: setupCursorHover,
className: `multipleselection-btn ${id == initIndex[1] && grp == initIndex[0] ? 'multipleselection-btn-enabled' : ''}`, className: `multipleselection-btn ${id == initIndex[1] && grp == initIndex[0] ? 'multipleselection-btn-enabled' : ''}`,
label: option.name, label: option.name,
onClicked: (self) => { onClicked: (self) => {
const kidsg = widget.get_children(); const kidsg = widget.get_children();
const kids = kidsg.flatMap(widget => widget.get_children()); const kids = kidsg.flatMap(widget => widget.get_children());
kids.forEach(kid => { kids.forEach(kid => {
kid.toggleClassName('multipleselection-btn-enabled', false); kid.toggleClassName('multipleselection-btn-enabled', false);
}); });
lastSelected = id; lastSelected = id;
self.toggleClassName('multipleselection-btn-enabled', true); self.toggleClassName('multipleselection-btn-enabled', true);
onChange(option.value, option.name); onChange(option.value, option.name);
} }
}) })
}), }),
}) })
}), }),
...rest, ...rest,
}); });
@@ -8,55 +8,78 @@ const { Box, Button, Icon, Label, Scrollable, Slider, Stack } = Widget;
const { execAsync, exec } = Utils; const { execAsync, exec } = Utils;
import { MaterialIcon } from '../../.commonwidgets/materialicon.js'; import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js'; import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { ConfigToggle } from '../../.commonwidgets/configwidgets.js';
// can't connect: sync_problem
const USE_SYMBOLIC_ICONS = false; const USE_SYMBOLIC_ICONS = false;
const BluetoothDevice = (device) => { const BluetoothDevice = (device) => {
console.log(device); // console.log(device);
const deviceIcon = Icon({
className: 'sidebar-bluetooth-appicon',
vpack: 'center',
tooltipText: device.name,
setup: (self) => self.hook(device, (self) => {
self.icon = `${device.iconName}${USE_SYMBOLIC_ICONS ? '-symbolic' : ''}`;
}),
});
const deviceStatus = Box({
hexpand: true,
vpack: 'center',
vertical: true,
children: [
Label({
xalign: 0,
maxWidthChars: 10,
truncate: 'end',
label: device.name,
className: 'txt-small',
setup: (self) => self.hook(device, (self) => {
self.label = device.name;
}),
}),
Label({
xalign: 0,
maxWidthChars: 10,
truncate: 'end',
label: device.connected ? 'Connected' : (device.paired ? 'Paired' : ''),
className: 'txt-subtext',
setup: (self) => self.hook(device, (self) => {
self.label = device.connected ? 'Connected' : (device.paired ? 'Paired' : '');
}),
}),
]
});
const deviceConnectButton = ConfigToggle({
vpack: 'center',
expandWidget: false,
initValue: device.connected,
onChange: (self, newValue) => {
device.setConnection(newValue);
},
extraSetup: (self) => self.hook(device, (self) => {
Utils.timeout(200, () => self.enabled.value = device.connected);
}),
})
const deviceRemoveButton = Button({
vpack: 'center',
className: 'sidebar-bluetooth-device-remove',
child: MaterialIcon('delete', 'norm'),
setup: setupCursorHover,
onClicked: () => execAsync(['bluetoothctl', 'remove', device.address]).catch(print),
});
return Box({ return Box({
className: 'sidebar-bluetooth-device spacing-h-10', className: 'sidebar-bluetooth-device spacing-h-10',
children: [ children: [
Icon({ deviceIcon,
className: 'sidebar-bluetooth-appicon', deviceStatus,
vpack: 'center',
tooltipText: device.name,
setup: (self) => self.hook(device, (self) => {
self.icon = `${device.iconName}${USE_SYMBOLIC_ICONS ? '-symbolic' : ''}`;
}),
}),
Box({ Box({
hexpand: true, className: 'spacing-h-5',
vpack: 'center',
vertical: true,
children: [ children: [
Label({ deviceConnectButton,
xalign: 0, deviceRemoveButton,
maxWidthChars: 10,
truncate: 'end',
label: device.name,
className: 'txt-small',
setup: (self) => self.hook(device, (self) => {
self.label = device.name;
}),
}),
Label({
xalign: 0,
maxWidthChars: 10,
truncate: 'end',
label: device.connected ? 'Connected' : (device.paired ? 'Paired' : ''),
className: 'txt-subtext',
setup: (self) => self.hook(device, (self) => {
self.label = device.connected ? 'Connected' : (device.paired ? 'Paired' : '');
}),
}),
] ]
}),
Button({
vpack: 'center',
className: 'sidebar-bluetooth-device-remove',
child: MaterialIcon('delete', 'norm'),
setup: setupCursorHover,
onClicked: () => execAsync(['bluetoothctl', 'remove', device.address]).catch(print),
}) })
] ]
}) })