forked from Shinonome/dots-hyprland
sidebar: bluetooth: add connection toggle
This commit is contained in:
@@ -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),
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user