diff --git a/assets/icons/hicolor/scalable/devices/fa-lock-symbolic.svg b/assets/icons/hicolor/scalable/devices/fa-lock-symbolic.svg
new file mode 100644
index 0000000..e8bbd42
--- /dev/null
+++ b/assets/icons/hicolor/scalable/devices/fa-lock-symbolic.svg
@@ -0,0 +1 @@
+
diff --git a/assets/icons/hicolor/scalable/devices/fa-power-symbolic.svg b/assets/icons/hicolor/scalable/devices/fa-power-symbolic.svg
new file mode 100644
index 0000000..a15a059
--- /dev/null
+++ b/assets/icons/hicolor/scalable/devices/fa-power-symbolic.svg
@@ -0,0 +1 @@
+
diff --git a/style/_control-center.scss b/style/_control-center.scss
new file mode 100644
index 0000000..7d59d66
--- /dev/null
+++ b/style/_control-center.scss
@@ -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;
+ }
+ }
+}
diff --git a/style/main.scss b/style/main.scss
index bf73e20..30372f5 100644
--- a/style/main.scss
+++ b/style/main.scss
@@ -9,3 +9,6 @@
// notifications
@use "./_notification.scss";
+
+// control center
+@use "./_control-center.scss";
diff --git a/widgets/control-center/footer.tsx b/widgets/control-center/footer.tsx
new file mode 100644
index 0000000..e03bd6e
--- /dev/null
+++ b/widgets/control-center/footer.tsx
@@ -0,0 +1,11 @@
+import { Gtk } from "ags/gtk4";
+
+export const Footer = () => {
+ const { END } = Gtk.Align;
+
+ return (
+
+
+
+ );
+};
diff --git a/widgets/control-center/header.tsx b/widgets/control-center/header.tsx
new file mode 100644
index 0000000..02e2784
--- /dev/null
+++ b/widgets/control-center/header.tsx
@@ -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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/widgets/control-center/index.tsx b/widgets/control-center/index.tsx
new file mode 100644
index 0000000..2ec29fa
--- /dev/null
+++ b/widgets/control-center/index.tsx
@@ -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 (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const onKey = (
+ _e: Gtk.EventControllerKey,
+ keyval: number,
+ _: number,
+ mod: number,
+) => {
+ if (keyval === Gdk.KEY_Escape) {
+ app.toggle_window(WINDOW_NAME);
+ return;
+ }
+};
diff --git a/widgets/control-center/notification-list.tsx b/widgets/control-center/notification-list.tsx
new file mode 100644
index 0000000..bc0f671
--- /dev/null
+++ b/widgets/control-center/notification-list.tsx
@@ -0,0 +1,12 @@
+import { Gtk } from "ags/gtk4";
+
+export const NotificationList = () => {
+ const { VERTICAL } = Gtk.Orientation;
+
+ return (
+
+
+
+
+ );
+};
diff --git a/widgets/control-center/sliding-controls.tsx b/widgets/control-center/sliding-controls.tsx
new file mode 100644
index 0000000..3cb8496
--- /dev/null
+++ b/widgets/control-center/sliding-controls.tsx
@@ -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 (
+
+
+
+ val ? "fa-speaker-muted-symbolic" : "fa-speaker-symbolic",
+ )}
+ />
+
+ speaker.set_volume(value)}
+ value={createBinding(speaker, "volume")}
+ />
+
+
+
+
+ microphone.set_volume(value)}
+ value={createBinding(microphone, "volume")}
+ />
+
+
+ );
+};
diff --git a/windows.ts b/windows.ts
index 84c5189..11b2e74 100644
--- a/windows.ts
+++ b/windows.ts
@@ -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];