bar: utils buttons, new battery indicator

This commit is contained in:
end-4
2023-12-31 01:01:05 +07:00
parent 7d4374d52b
commit 6a42af63ca
14 changed files with 351 additions and 244 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ const TrackProgress = () => {
const _updateProgress = (circprog) => {
const mpris = Mpris.getPlayer('');
if (!mpris) return;
// Set circular progress (font size cuz that's how this hacky circprog works)
// Set circular progress value
circprog.css = `font-size: ${Math.max(mpris.position / mpris.length * 100, 0)}px;`
}
return AnimatedCircProg({
@@ -65,7 +65,7 @@ export const ModuleMusic = () => Widget.EventBox({
Widget.Scrollable({
hexpand: true,
child: Widget.Label({
className: 'txt txt-smallie',
className: 'txt-smallie txt-onSurfaceVariant',
connections: [[Mpris, label => {
const mpris = Mpris.getPlayer('');
if (mpris)
+123 -99
View File
@@ -1,16 +1,34 @@
// This is for the right pill of the bar.
// For the cool memory indicator on the sidebar, see sysinfo.js
import { Service, Utils, Widget } from '../../imports.js';
const { Box, Label, Button, Overlay, Revealer, Scrollable, Stack, EventBox } = Widget;
const { exec, execAsync } = Utils;
const { GLib } = imports.gi;
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
import { MaterialIcon } from '../../lib/materialicon.js';
import { AnimatedCircProg } from "../../lib/animatedcircularprogress.js";
const BATTERY_LOW = 20;
const BatBatteryProgress = () => {
const _updateProgress = (circprog) => { // Set circular progress value
circprog.css = `font-size: ${Battery.percent}px;`
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= BATTERY_LOW);
circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
}
return AnimatedCircProg({
className: 'bar-batt-circprog',
vpack: 'center', hpack: 'center',
connections: [
[Battery, _updateProgress],
],
})
}
const BarClock = () => Widget.Box({
vpack: 'center',
className: 'spacing-h-5',
className: 'spacing-h-5 txt-onSurfaceVariant',
children: [
Widget.Label({
className: 'bar-clock',
@@ -20,11 +38,11 @@ const BarClock = () => Widget.Box({
}),
}),
Widget.Label({
className: 'txt-norm txt',
className: 'txt-norm',
label: '•',
}),
Widget.Label({
className: 'txt-smallie txt',
className: 'txt-smallie',
label: GLib.DateTime.new_now_local().format("%A, %d/%m"),
setup: (self) => self.poll(5000, label => {
label.label = GLib.DateTime.new_now_local().format("%A, %d/%m");
@@ -33,105 +51,110 @@ const BarClock = () => Widget.Box({
],
});
const BarBattery = () => {
const BarResourceValue = (name, icon, command) => Widget.Box({
vpack: 'center',
className: 'bar-batt spacing-h-5',
children: [
MaterialIcon(icon, 'small'),
Widget.ProgressBar({ // Progress
vpack: 'center', hexpand: true,
className: 'bar-prog-batt',
setup: (self) => self.poll(5000, (progress) => execAsync(['bash', '-c', command])
.then((output) => {
progress.value = Number(output) / 100;
progress.tooltipText = `${name}: ${Number(output)}%`
})
.catch(print)
),
}),
]
});
const batteryWidget = Widget.Box({
vpack: 'center',
hexpand: true,
className: 'spacing-h-5 bar-batt',
setup: (self) => self.hook(Battery, box => {
box.toggleClassName('bar-batt-low', Battery.percent <= BATTERY_LOW);
box.toggleClassName('bar-batt-full', Battery.charged);
}),
children: [
MaterialIcon('settings_heart', 'small'),
Widget.Label({ // Percentage
className: 'bar-batt-percentage',
setup: (self) => self.hook(Battery, label => {
label.label = `${Battery.percent}`;
}),
}),
Widget.ProgressBar({ // Progress
vpack: 'center',
hexpand: true,
className: 'bar-prog-batt',
setup: (self) => self.hook(Battery, progress => {
progress.value = Math.abs(Battery.percent / 100); // battery could be initially negative wtf
progress.toggleClassName('bar-prog-batt-low', Battery.percent <= BATTERY_LOW);
progress.toggleClassName('bar-prog-batt-full', Battery.charged);
batteryWidget.tooltipText = `Battery: ${Battery.percent}%`
}),
}),
Widget.Revealer({ // A dot for charging state
transitionDuration: 150,
revealChild: false,
transition: 'slide_left',
child: Widget.Box({
className: 'spacing-h-3',
children: [
Widget.Box({
vpack: 'center',
className: 'bar-batt-chargestate-charging-smaller',
setup: (self) => self.hook(Battery, box => {
box.toggleClassName('bar-batt-chargestate-low', Battery.percent <= BATTERY_LOW);
box.toggleClassName('bar-batt-chargestate-full', Battery.charged);
}),
}),
Widget.Box({
vpack: 'center',
className: 'bar-batt-chargestate-charging',
setup: (self) => self.hook(Battery, box => {
box.toggleClassName('bar-batt-chargestate-low', Battery.percent <= BATTERY_LOW);
box.toggleClassName('bar-batt-chargestate-full', Battery.charged);
}),
}),
]
}),
setup: (self) => self.hook(Battery, revealer => {
revealer.revealChild = Battery.charging;
}),
}),
],
});
const memUsage = Widget.Box({
const UtilButton = ({ name, icon, onClicked }) => Button({
vpack: 'center',
tooltipText: name,
onClicked: onClicked,
className: 'bar-util-btn icon-material txt-norm',
label: `${icon}`,
})
const Utilities = () => Scrollable({
hexpand: true,
child: Box({
hpack: 'center',
className: 'spacing-h-5',
children: [
BarResourceValue('RAM usage', 'memory', `free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`),
BarResourceValue('Swap usage', 'swap_horiz', `free | awk '/^Swap/ {printf("%.2f\\n", ($3/$2) * 100)}'`),
UtilButton({
name: 'Screen snip', icon: 'screenshot_region', onClicked: () => {
Utils.execAsync(['bash', '-c', `grim -g "$(slurp -d -c e2e2e2BB -b 31313122 -s 00000000)" - | wl-copy &`])
.catch(print)
}
}),
UtilButton({
name: 'Color picker', icon: 'colorize', onClicked: () => {
Utils.execAsync(['hyprpicker', '-a']).catch(print)
}
}),
UtilButton({
name: 'Toggle on-screen keyboard', icon: 'keyboard', onClicked: () => {
App.toggleWindow('osk');
}
}),
]
})
const widgetStack = Widget.Stack({
transition: 'slide_up_down',
vpack: 'center',
hexpand: true,
items: [
['fallback', memUsage],
['battery', batteryWidget],
],
setup: (stack) => Utils.timeout(1, () => { // On desktops systems with no battery, show memory usage instead
if (Battery.available) stack.shown = 'battery';
else stack.shown = 'fallback';
})
})
return widgetStack;
}
})
const BarBattery = () => Box({
className: 'spacing-h-4 txt-onSurfaceVariant',
children: [
// Revealer({ // A dot for charging state
// transitionDuration: 150,
// revealChild: false,
// transition: 'crossfade',
// child: Widget.Box({
// className: 'spacing-h-3',
// children: [
// Widget.Box({
// vpack: 'center',
// className: 'bar-batt-chargestate-charging-smaller',
// setup: (self) => self.hook(Battery, box => {
// box.toggleClassName('bar-batt-chargestate-low', Battery.percent <= BATTERY_LOW);
// box.toggleClassName('bar-batt-chargestate-full', Battery.charged);
// }),
// }),
// Widget.Box({
// vpack: 'center',
// className: 'bar-batt-chargestate-charging',
// setup: (self) => self.hook(Battery, box => {
// box.toggleClassName('bar-batt-chargestate-low', Battery.percent <= BATTERY_LOW);
// box.toggleClassName('bar-batt-chargestate-full', Battery.charged);
// }),
// }),
// ]
// }),
// setup: (self) => self.hook(Battery, revealer => {
// revealer.revealChild = Battery.charging;
// }),
// }),
Stack({
transition: 'slide_up_down',
items: [
['discharging', Widget.Label({
className: 'txt-norm txt',
label: '•',
}),],
['charging', MaterialIcon('bolt', 'norm')],
],
setup: (self) => self.hook(Battery, revealer => {
self.shown = Battery.charging ? 'charging' : 'discharging';
}),
}),
Label({
className: 'txt-smallie txt-onSurfaceVariant',
setup: (self) => self.hook(Battery, label => {
label.label = `${Battery.percent}%`;
}),
}),
Overlay({
child: Widget.Box({
vpack: 'center',
className: 'bar-batt',
homogeneous: true,
children: [
MaterialIcon('settings_heart', 'small'),
],
setup: (self) => self.hook(Battery, box => {
box.toggleClassName('bar-batt-low', Battery.percent <= BATTERY_LOW);
box.toggleClassName('bar-batt-full', Battery.charged);
}),
}),
overlays: [
BatBatteryProgress(),
]
}),
]
});
export const ModuleSystem = () => Widget.EventBox({
onScrollUp: () => execAsync('hyprctl dispatch workspace -1'),
@@ -141,9 +164,10 @@ export const ModuleSystem = () => Widget.EventBox({
className: 'bar-group-margin bar-sides',
children: [
Widget.Box({
className: 'bar-group bar-group-standalone bar-group-pad-system spacing-h-15',
className: 'bar-group bar-group-standalone bar-group-pad-system spacing-h-5',
children: [
BarClock(),
Utilities(),
BarBattery(),
],
}),
+7 -3
View File
@@ -66,6 +66,7 @@ const WorkspaceContents = (count = 10) => {
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
@@ -84,7 +85,7 @@ const WorkspaceContents = (count = 10) => {
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius , wsCenterY - workspaceRadius, workspaceRadius , workspaceRadius * 2)
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area._workspaceMask & (1 << (i + 1)))) { // Right
@@ -92,7 +93,7 @@ const WorkspaceContents = (count = 10) => {
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius , workspaceRadius * 2)
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
@@ -118,7 +119,7 @@ const WorkspaceContents = (count = 10) => {
cr.fill();
// inner decor
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.19, 0, 2 * Math.PI);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
cr.fill();
}))
,
@@ -148,12 +149,15 @@ export default () => EventBox({
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self._clicked) return;
console.log('switching move');
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES / widgetWidth);
Hyprland.sendMessage(`dispatch workspace ${wsId}`)
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
console.log('switching');
self._clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
@@ -62,7 +62,7 @@ export default () => Box({
hpack: 'start',
vpack: 'end',
vertical: true,
className: 'bg-time-box spacing-v-20',
className: 'bg-time-box spacing-h--10',
children: [
TimeAndDate(),
// QuickLaunches(),
@@ -70,6 +70,7 @@ export default () => MarginRevealer({
child: Box({
hpack: 'center',
vertical: false,
className: 'spacing-h--10',
children: [
brightnessIndicator,
volumeIndicator,
+8 -12
View File
@@ -78,20 +78,16 @@ export const ModuleNightLight = (props = {}) => Widget.Button({ // TODO: Make th
onClicked: (self) => {
self._enabled = !self._enabled;
self.toggleClassName('sidebar-button-active', self._enabled);
if (self._enabled) {
self._inhibitor = Utils.subprocess(
['wlsunset'],
(output) => print(output),
(err) => logError(err),
self,
);
}
else {
self._inhibitor.force_exit();
}
// if (self._enabled) Utils.execAsync(['bash', '-c', 'wlsunset & disown'])
if (self._enabled) Utils.execAsync('wlsunset')
else Utils.execAsync('pkill wlsunset');
},
child: MaterialIcon('nightlight', 'norm'),
setup: setupCursorHover,
setup: (self) => {
setupCursorHover(self);
self._enabled = !!exec('pidof wlsunset');
self.toggleClassName('sidebar-button-active', self._enabled);
},
...props,
});