feat: add control center widget

This commit is contained in:
tux
2025-09-25 19:29:18 +05:30
parent 96431e101a
commit bd8cd294ee
10 changed files with 217 additions and 1 deletions

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M5.25 10.0546V8C5.25 4.27208 8.27208 1.25 12 1.25C15.7279 1.25 18.75 4.27208 18.75 8V10.0546C19.8648 10.1379 20.5907 10.348 21.1213 10.8787C22 11.7574 22 13.1716 22 16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H8C5.17157 22 3.75736 22 2.87868 21.1213C2 20.2426 2 18.8284 2 16C2 13.1716 2 11.7574 2.87868 10.8787C3.40931 10.348 4.13525 10.1379 5.25 10.0546ZM6.75 8C6.75 5.10051 9.10051 2.75 12 2.75C14.8995 2.75 17.25 5.10051 17.25 8V10.0036C16.867 10 16.4515 10 16 10H8C7.54849 10 7.13301 10 6.75 10.0036V8ZM8 17C8.55228 17 9 16.5523 9 16C9 15.4477 8.55228 15 8 15C7.44772 15 7 15.4477 7 16C7 16.5523 7.44772 17 8 17ZM12 17C12.5523 17 13 16.5523 13 16C13 15.4477 12.5523 15 12 15C11.4477 15 11 15.4477 11 16C11 16.5523 11.4477 17 12 17ZM17 16C17 16.5523 16.5523 17 16 17C15.4477 17 15 16.5523 15 16C15 15.4477 15.4477 15 16 15C16.5523 15 17 15.4477 17 16Z" fill="#000"></path> </g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M5.66953 9.91436L8.73167 5.77133C10.711 3.09327 11.7007 1.75425 12.6241 2.03721C13.5474 2.32018 13.5474 3.96249 13.5474 7.24712V7.55682C13.5474 8.74151 13.5474 9.33386 13.926 9.70541L13.946 9.72466C14.3327 10.0884 14.9492 10.0884 16.1822 10.0884C18.4011 10.0884 19.5106 10.0884 19.8855 10.7613C19.8917 10.7724 19.8977 10.7837 19.9036 10.795C20.2576 11.4784 19.6152 12.3475 18.3304 14.0857L15.2683 18.2287C13.2889 20.9067 12.2992 22.2458 11.3758 21.9628C10.4525 21.6798 10.4525 20.0375 10.4525 16.7528L10.4526 16.4433C10.4526 15.2585 10.4526 14.6662 10.074 14.2946L10.054 14.2754C9.6673 13.9117 9.05079 13.9117 7.81775 13.9117C5.59888 13.9117 4.48945 13.9117 4.1145 13.2387C4.10829 13.2276 4.10225 13.2164 4.09639 13.205C3.74244 12.5217 4.3848 11.6526 5.66953 9.91436Z" fill="#000"></path> </g></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,65 @@
@use "./_variable.scss" as *;
@use "sass:math";
@use "sass:list";
window.control-center {
background: $bg-color;
color: $fg-color;
min-width: 400px;
padding: 20px;
margin: 10px;
border-radius: $rounded;
.pill {
font-size: $font-size;
color: $fg-color;
background-color: $inactive-color;
border-radius: calc($rounded / 1.5);
padding: 20px;
image {
-gtk-icon-size: 2rem;
}
}
.header {
.controls {
button {
background-color: $inactive-color;
border-radius: calc($rounded / 1.5);
padding: 20px;
&:hover {
background-color: $bg-color;
}
}
image {
-gtk-icon-size: 2rem;
}
}
}
.footer {
label {
font-size: 18px;
font-family: BigBlueTermPlus Nerd Font;
}
}
.volume {
trough {
background-color: $bg-color;
min-height: 10px;
min-width: 10px;
border-radius: 10px;
}
highlight {
background-color: $fg-color;
min-height: 10px;
min-width: 10px;
border-radius: 10px;
}
}
}

View File

@@ -9,3 +9,6 @@
// notifications
@use "./_notification.scss";
// control center
@use "./_control-center.scss";

View File

@@ -0,0 +1,11 @@
import { Gtk } from "ags/gtk4";
export const Footer = () => {
const { END } = Gtk.Align;
return (
<box valign={END} cssClasses={["footer"]}>
<label hexpand label="NOBODY FUX WITH TUX" />
</box>
);
};

View File

@@ -0,0 +1,39 @@
import { Gdk, Gtk } from "ags/gtk4";
import { exec } from "ags/process";
import GLib from "gi://GLib";
export const Header = () => {
const { VERTICAL } = Gtk.Orientation;
const { CENTER, START, END } = Gtk.Align;
return (
<box cssClasses={["header"]}>
<image
css="margin-left: -15px;"
file={`${GLib.get_user_config_dir()}/tpanel/assets/avatar.png`}
pixelSize={100}
/>
<box valign={CENTER} orientation={VERTICAL} spacing={5}>
<label halign={START} label="tux" />
<label halign={START} label="@tuxdotrs" />
</box>
<box hexpand halign={END} spacing={10} cssClasses={["controls"]}>
<button
cursor={Gdk.Cursor.new_from_name("pointer", null)}
onClicked={() => exec("hyprlock")}
>
<image iconName="fa-lock-symbolic" />
</button>
<button
cursor={Gdk.Cursor.new_from_name("pointer", null)}
onClicked={() => exec("poweroff")}
>
<image iconName="fa-power-symbolic" />
</button>
</box>
</box>
);
};

View File

@@ -0,0 +1,44 @@
import { Astal, Gdk, Gtk } from "ags/gtk4";
import app from "ags/gtk4/app";
import { Footer } from "./footer";
import { Header } from "./header";
import { NotificationList } from "./notification-list";
import { SlidingControls } from "./sliding-controls";
export const WINDOW_NAME = "control-center";
export const ControlCenter = (gdkmonitor: Gdk.Monitor) => {
const { TOP, BOTTOM, RIGHT } = Astal.WindowAnchor;
const { VERTICAL } = Gtk.Orientation;
return (
<window
name={WINDOW_NAME}
cssClasses={["control-center"]}
gdkmonitor={gdkmonitor}
application={app}
keymode={Astal.Keymode.ON_DEMAND}
anchor={TOP | BOTTOM | RIGHT}
>
<Gtk.EventControllerKey onKeyPressed={onKey} />
<box vexpand orientation={VERTICAL} spacing={20}>
<Header />
<SlidingControls />
<NotificationList />
<Footer />
</box>
</window>
);
};
const onKey = (
_e: Gtk.EventControllerKey,
keyval: number,
_: number,
mod: number,
) => {
if (keyval === Gdk.KEY_Escape) {
app.toggle_window(WINDOW_NAME);
return;
}
};

View File

@@ -0,0 +1,12 @@
import { Gtk } from "ags/gtk4";
export const NotificationList = () => {
const { VERTICAL } = Gtk.Orientation;
return (
<box vexpand orientation={VERTICAL} spacing={20}>
<label label="Notifications" />
<box vexpand cssClasses={["pill"]}></box>
</box>
);
};

View File

@@ -0,0 +1,39 @@
import { createBinding } from "ags";
import { Gtk } from "ags/gtk4";
import AstalWp from "gi://AstalWp";
export const SlidingControls = () => {
const { VERTICAL } = Gtk.Orientation;
const { defaultSpeaker: speaker, defaultMicrophone: microphone } =
AstalWp.get_default()!;
const speakerIsMuted = createBinding(speaker, "mute");
return (
<box spacing={20} cssClasses={["pill"]} orientation={VERTICAL}>
<box cssClasses={["volume"]} spacing={20}>
<image
iconName={speakerIsMuted((val) =>
val ? "fa-speaker-muted-symbolic" : "fa-speaker-symbolic",
)}
/>
<slider
hexpand
onChangeValue={({ value }) => speaker.set_volume(value)}
value={createBinding(speaker, "volume")}
/>
</box>
<box cssClasses={["volume"]} spacing={20}>
<image iconName="fa-microphone-symbolic" />
<slider
hexpand
onChangeValue={({ value }) => microphone.set_volume(value)}
value={createBinding(microphone, "volume")}
/>
</box>
</box>
);
};

View File

@@ -1,5 +1,6 @@
import { Bar } from "./widgets/bar";
import { Launcher } from "./widgets/launcher";
import { Notifications } from "./widgets/notifications";
import { ControlCenter } from "./widgets/control-center";
export default [Bar, Launcher, Notifications];
export default [Bar, Launcher, Notifications, ControlCenter];