diff --git a/ags/widget/control-center/Pages.tsx b/ags/widget/control-center/Pages.tsx
index cf1a970..7bdb7ec 100644
--- a/ags/widget/control-center/Pages.tsx
+++ b/ags/widget/control-center/Pages.tsx
@@ -2,16 +2,13 @@ import { register } from "ags/gobject";
import { Gtk } from "ags/gtk4";
import { Page } from "./pages/Page";
import { timeout } from "ags/time";
-import { variableToBoolean } from "../../scripts/utils";
import AstalIO from "gi://AstalIO";
-import { createRoot } from "ags";
export { Pages };
export type PagesProps = {
initialPage?: Page;
- class?: string;
transitionDuration?: number;
};
@@ -19,21 +16,20 @@ export type PagesProps = {
class Pages extends Gtk.Box {
#timeouts: Array<[AstalIO.Time, (() => void)|undefined]> = [];
#page: (Page|undefined);
- #pageWidget: (Gtk.Revealer|undefined);
#transDuration: number;
#transType: Gtk.RevealerTransitionType = Gtk.RevealerTransitionType.SLIDE_DOWN;
- get isOpen() { return Boolean(this.get_first_child()); }
+ get isOpen() { return Boolean(this.#page); }
+ get page() { return this.#page; }
constructor(props?: PagesProps) {
super({
orientation: Gtk.Orientation.VERTICAL,
- cssName: "pages"
+ cssName: "pages",
+ name: "pages"
});
- this.name = "pages";
- props?.class?.split(' ').filter(variableToBoolean).forEach(clss =>
- this.add_css_class(clss));
+ this.add_css_class("pages");
this.#transDuration = props?.transitionDuration ?? 280;
@@ -53,7 +49,7 @@ class Pages extends Gtk.Box {
}
toggle(newPage?: Page, onToggled?: () => void): void {
- if(!newPage || (this.#page?.id === newPage?.id)) {
+ if(!newPage || (this.#page?.id === newPage.id)) {
this.close(onToggled);
return;
}
@@ -69,38 +65,35 @@ class Pages extends Gtk.Box {
}
}
- open(newPage: Page, onOpened?: () => void) {
- const pageWidget = createRoot(() =>
-
- {newPage as unknown as Gtk.Widget}
- as Gtk.Revealer);
-
- this.prepend(pageWidget);
-
- this.#pageWidget = pageWidget;
+ open(newPage: Page, onOpen?: () => void) {
this.#page = newPage;
- this.reorder_child_after(this.get_last_child()!, null);
- (this.get_first_child() as Gtk.Revealer).revealChild = true;
- onOpened?.();
+ this.prepend(
+
+
+ {newPage.create()}
+ as Gtk.Revealer
+ );
+
+ (this.get_first_child() as Gtk.Revealer)?.set_reveal_child(true);
+ onOpen?.();
}
close(onClosed?: () => void): void {
- if(!this.#pageWidget) return;
+ const page = this.get_first_child() as Gtk.Revealer|null;
+ if(!page) return;
- this.#pageWidget.revealChild = false;
- const closingPage = this.#pageWidget!;
+ this.#page?.actionClosed?.();
+ this.#page = undefined;
+ page.set_reveal_child(false);
this.#timeouts.push([
- timeout(closingPage.transitionDuration, () => {
- this.remove(closingPage);
+ timeout(page.transitionDuration, () => {
+ this.remove(page);
onClosed?.();
}),
- onClosed]);
-
- this.#pageWidget = undefined;
+ onClosed
+ ]);
}
}
diff --git a/ags/widget/control-center/QuickActions.tsx b/ags/widget/control-center/QuickActions.tsx
index 1fd29d7..5271df5 100644
--- a/ags/widget/control-center/QuickActions.tsx
+++ b/ags/widget/control-center/QuickActions.tsx
@@ -2,12 +2,14 @@ import { Gtk } from "ags/gtk4";
import { Windows } from "../../windows";
import { Wallpaper } from "../../scripts/wallpaper";
import { execApp } from "../../scripts/apps";
-import GLib from "gi://GLib?version=2.0";
import { Accessor } from "ags";
import { createPoll } from "ags/time";
+import GLib from "gi://GLib?version=2.0";
+import Gio from "gi://Gio?version=2.0";
+const userFace: Gio.File = Gio.File.new_for_path(`${GLib.get_home_dir()}/.face`);
const uptime: Accessor = createPoll("Just turned on", 1000, "uptime -p");
function LockButton(): Gtk.Button {
@@ -57,22 +59,25 @@ function LogoutButton(): Gtk.Button {
export const QuickActions = () =>
-
+
+ {userFace.query_exists(null) &&
+
+ }
+
+
-
-
-
-
- str.replace(/^up /, ""))} />
+
+
+ str.replace(/^up /, ""))} />
+
-
-
+
diff --git a/ags/widget/control-center/Sliders.tsx b/ags/widget/control-center/Sliders.tsx
index 49fd084..b253328 100644
--- a/ags/widget/control-center/Sliders.tsx
+++ b/ags/widget/control-center/Sliders.tsx
@@ -3,7 +3,7 @@ import { Wireplumber } from "../../scripts/volume";
import { Pages } from "./Pages";
import { PageSound } from "./pages/Sound";
import { PageMicrophone } from "./pages/Microphone";
-import { createBinding, createRoot, With } from "ags";
+import { createBinding, With } from "ags";
import AstalWp from "gi://AstalWp";
@@ -11,51 +11,43 @@ import AstalWp from "gi://AstalWp";
export let slidersPages: Pages|undefined;
export function Sliders() {
- slidersPages = createRoot(() => new Pages())!;
-
return slidersPages = undefined}>
+ hexpand spacing={10} onUnmap={() => slidersPages = undefined}>
{(sink: AstalWp.Endpoint) =>
- Wireplumber.getDefault().toggleMuteSink()}
iconName={createBinding(sink, "volumeIcon").as((icon) =>
(!Wireplumber.getDefault().isMutedSink() &&
- Wireplumber.getDefault().getSinkVolume() > 0) ?
- icon
- : "audio-volume-muted-symbolic"
+ Wireplumber.getDefault().getSinkVolume() > 0
+ ) ? icon : "audio-volume-muted-symbolic"
)} />
- self.value = Math.floor(sink.volume * 100)}
- value={createBinding(sink, "volume").as(v => Math.floor(v * 100))}
- max={Wireplumber.getDefault().getMaxSinkVolume()}
- onChangeValue={(_, _scrollType, value) => sink.set_volume(value / 100)} />
+ sink.set_volume(value)} />
-
- slidersPages!.toggle(PageSound())} />
+
+ slidersPages?.toggle(PageSound)} />
}
{(source: AstalWp.Endpoint) =>
- Wireplumber.getDefault().toggleMuteSource()}
iconName={createBinding(source, "volumeIcon").as((icon) =>
- (!Wireplumber.getDefault().isMutedSink() &&
- Wireplumber.getDefault().getSinkVolume() > 0) ?
- icon
- : "microphone-sensitivity-muted-symbolic"
+ (!Wireplumber.getDefault().isMutedSource() &&
+ Wireplumber.getDefault().getSourceVolume() > 0
+ ) ? icon : "microphone-sensitivity-muted-symbolic"
)} />
- self.value = Math.floor(source.volume * 100)}
- value={createBinding(source, "volume").as(v => Math.floor(v * 100))}
- max={Wireplumber.getDefault().getMaxSinkVolume()}
- onChangeValue={(_, _scrollType, value) => source.set_volume(value / 100)} />
+ source.set_volume(value)} />
-
- slidersPages!.toggle(PageMicrophone())} />
+
+ slidersPages?.toggle(PageMicrophone)} />
}
- {slidersPages}
+ slidersPages = self} />
}
diff --git a/ags/widget/control-center/Tiles.tsx b/ags/widget/control-center/Tiles.tsx
index b319a7b..2a6f43c 100644
--- a/ags/widget/control-center/Tiles.tsx
+++ b/ags/widget/control-center/Tiles.tsx
@@ -5,7 +5,6 @@ import { TileDND } from "./tiles/DoNotDisturb";
import { TileRecording } from "./tiles/Recording";
import { TileNightLight } from "./tiles/NightLight";
import { Pages } from "./Pages";
-import { createRoot } from "/usr/share/ags/js/gnim/src/jsx/scope";
export let TilesPages: Pages|undefined;
@@ -19,18 +18,15 @@ export const tileList: Array<() => JSX.Element|Gtk.Widget> = [
export function Tiles(): Gtk.Widget {
return TilesPages = undefined} $={(self) => {
- if(!TilesPages)
- TilesPages = createRoot(() => new Pages({ class: "tile-pages" }));
-
- self.append(TilesPages!);
- }}>
+ onUnmap={() => TilesPages = undefined}>
+ maxChildrenPerLine={2} hexpand homogeneous>
{tileList.map(t => t())}
+
+ TilesPages = self} />
as Gtk.Box;
}
diff --git a/ags/widget/control-center/pages/Bluetooth.tsx b/ags/widget/control-center/pages/Bluetooth.tsx
index 5d1929f..7bcf065 100644
--- a/ags/widget/control-center/pages/Bluetooth.tsx
+++ b/ags/widget/control-center/pages/Bluetooth.tsx
@@ -4,60 +4,70 @@ import { tr } from "../../../i18n/intl";
import { Windows } from "../../../windows";
import { Notifications } from "../../../scripts/notifications";
import { execApp } from "../../../scripts/apps";
+import { createBinding, createComputed, For, With } from "ags";
import AstalNotifd from "gi://AstalNotifd";
import AstalBluetooth from "gi://AstalBluetooth";
-import { variableToBoolean } from "../../../scripts/utils";
-import { createBinding, createComputed, For, With } from "ags";
-export const BluetoothPage = () => discovering ?
- "arrow-circular-top-right-symbolic"
- : "media-playback-stop-symbolic")} tooltipText={
- createBinding(AstalBluetooth.get_default().adapter, "discovering").as((discovering) =>
- !discovering ?
- tr("control_center.pages.bluetooth.start_discovering")
- : tr("control_center.pages.bluetooth.stop_discovering"))}
- onClicked={() => {
- if(AstalBluetooth.get_default().adapter.discovering) {
- AstalBluetooth.get_default().adapter.stop_discovery();
- return;
- }
+export const BluetoothPage = new Page({
+ id: "bluetooth",
+ title: tr("control_center.pages.bluetooth.title"),
+ spacing: 6,
+ description: tr("control_center.pages.bluetooth.description"),
+ headerButtons: [{
+ icon: createBinding(AstalBluetooth.get_default().adapter, "discovering")
+ .as(discovering => !discovering ?
+ "arrow-circular-top-right-symbolic"
+ : "media-playback-stop-symbolic"
+ ),
+ tooltipText: createBinding(AstalBluetooth.get_default().adapter, "discovering")
+ .as((discovering) => !discovering ?
+ tr("control_center.pages.bluetooth.start_discovering")
+ : tr("control_center.pages.bluetooth.stop_discovering")),
+ actionClicked: () => {
+ if(AstalBluetooth.get_default().adapter.discovering) {
+ AstalBluetooth.get_default().adapter.stop_discovery();
+ return;
+ }
- AstalBluetooth.get_default().adapter.start_discovery();
- }}
- />
- ]}
- actionClose={() => AstalBluetooth.get_default().adapter.discovering &&
- AstalBluetooth.get_default().adapter.stop_discovery()}
- bottomButtons={[{
+ AstalBluetooth.get_default().adapter.start_discovery();
+ }
+ }],
+ actionClosed: () => AstalBluetooth.get_default().adapter.discovering &&
+ AstalBluetooth.get_default().adapter.stop_discovery(),
+ bottomButtons: [{
title: tr("control_center.pages.more_settings"),
- onClick: () => {
+ actionClicked: () => {
Windows.getDefault().close("control-center");
execApp("overskride", "[float; animation slide right]");
}
- }]} spacing={2}>
-
+ }],
+ content: () => [
+ adptrs.length > 1)
+ } spacing={2}>
-
- {(adapter: AstalBluetooth.Adapter) =>
-
+
+ adpts.length > 1)}>
+
+ {(hasMoreAdapters: boolean) => hasMoreAdapters &&
+
+
+ {(adapter: AstalBluetooth.Adapter) =>
+
+ }
+
+
}
-
-
+
+ ,
-
devs.filter(dev => dev.paired || dev.connected || dev.trusted).length > 0)}>
@@ -68,7 +78,7 @@ export const BluetoothPage = () => }
-
devs.filter(dev => !dev.connected && !dev.paired && !dev.trusted).length > 0)}>
@@ -80,7 +90,8 @@ export const BluetoothPage = () =>
- as Page;
+ ]
+});
function DeviceWidget({ device }: { device: AstalBluetooth.Device }): Gtk.Widget {
return
@@ -93,7 +104,7 @@ function DeviceWidget({ device }: { device: AstalBluetooth.Device }): Gtk.Widget
tooltipText={
createBinding(device, "connected").as(connected =>
!connected ? tr("connect") : "")
- } onClick={() => {
+ } actionClicked={() => {
if(device.connected) return;
let skipConnection: boolean = false;
@@ -135,8 +146,8 @@ function DeviceWidget({ device }: { device: AstalBluetooth.Device }): Gtk.Widget
createBinding(device, "connected"),
createBinding(device, "trusted")
])}>
- {([connected, trusted]: [boolean, boolean]) => trusted &&
-
+ {([connected, trusted]: [boolean, boolean]) =>
+
{ device.set_trusted(!trusted)}
/>
- }
+
+ }
}
- /> as Page;
+ /> as Gtk.Widget;
}
diff --git a/ags/widget/control-center/pages/Microphone.tsx b/ags/widget/control-center/pages/Microphone.tsx
index 6cec762..bca1efb 100644
--- a/ags/widget/control-center/pages/Microphone.tsx
+++ b/ags/widget/control-center/pages/Microphone.tsx
@@ -3,27 +3,32 @@ import { Wireplumber } from "../../../scripts/volume";
import { Gtk } from "ags/gtk4";
import { tr } from "../../../i18n/intl";
import { createBinding, For } from "ags";
-import AstalWp from "gi://AstalWp?version=0.1";
import { lookupIcon } from "../../../scripts/apps";
+import AstalWp from "gi://AstalWp?version=0.1";
-export const PageMicrophone = () =>
-
-
-
- {(source: AstalWp.Endpoint) => isDefault ? "default" : "")
- } icon={createBinding(source, "icon").as(ico => lookupIcon(ico) ?
- ico : "audio-input-microphone-symbolic")} title={
- createBinding(source, "description").as(desc => desc ?? "Microphone")
- } onClick={() => !source.isDefault && source.set_is_default(true)}
- endWidget={
-
- }
- />}
-
- as Page;
+export const PageMicrophone = new Page({
+ id: "microphone",
+ title: tr("control_center.pages.microphone.title"),
+ description: tr("control_center.pages.microphone.description"),
+ content: () => [
+ ,
+
+
+ {(source: AstalWp.Endpoint) => isDefault ? "default" : "")
+ } icon={createBinding(source, "icon").as(ico => lookupIcon(ico) ?
+ ico : "audio-input-microphone-symbolic")} title={
+ createBinding(source, "description").as(desc => desc ?? "Microphone")
+ } actionClicked={() => !source.isDefault && source.set_is_default(true)}
+ endWidget={
+
+ }
+ />}
+
+
+ ]
+});
diff --git a/ags/widget/control-center/pages/Network.tsx b/ags/widget/control-center/pages/Network.tsx
index a743d9d..d7752f2 100644
--- a/ags/widget/control-center/pages/Network.tsx
+++ b/ags/widget/control-center/pages/Network.tsx
@@ -6,32 +6,34 @@ import { execApp } from "../../../scripts/apps";
import { Notifications } from "../../../scripts/notifications";
import { AskPopup, AskPopupProps } from "../../AskPopup";
import { encoder, variableToBoolean } from "../../../scripts/utils";
+import { createBinding, For, With } from "ags";
import GLib from "gi://GLib?version=2.0";
import NM from "gi://NM";
import AstalNetwork from "gi://AstalNetwork";
-import { createBinding, For, With } from "ags";
-export const PageNetwork = () =>
-
- primary === AstalNetwork.Primary.WIFI)}
- tooltipText={"Re-scan networks"} onClicked={() =>
- AstalNetwork.get_default().wifi.scan()}
- />
- ]} bottomButtons={[{
- title: tr("control_center.pages.more_settings"),
- onClick: () => {
- Windows.getDefault().close("control-center");
- execApp("nm-connection-editor", "[animationstyle gnomed]");
- }
- }]}>
-
-
+export const PageNetwork = new Page({
+ id: "network",
+ title: tr("control_center.pages.network.title"),
+ headerButtons: createBinding(AstalNetwork.get_default(), "primary").as(primary =>
+ primary === AstalNetwork.Primary.WIFI ? [{
+ icon: "arrow-circular-top-right-symbolic",
+ tooltipText: "Re-scan networks",
+ actionClicked: () => AstalNetwork.get_default().wifi.scan()
+ }] : []
+ ),
+ bottomButtons: [{
+ title: tr("control_center.pages.more_settings"),
+ actionClicked: () => {
+ Windows.getDefault().close("control-center");
+ execApp("nm-connection-editor", "[animationstyle gnomed]");
+ }
+ }],
+ content: () => [
+
@@ -52,8 +54,7 @@ export const PageNetwork = () =>
]}
/>}
-
-
+ ,
primary === AstalNetwork.Primary.WIFI)}>
@@ -95,7 +96,7 @@ export const PageNetwork = () =>
})
}
}}/>
- ]} onClick={() => {
+ ]} actionClicked={() => {
const uuid = NM.utils_uuid_generate();
const ssidBytes = GLib.Bytes.new(encoder.encode(ap.ssid));
@@ -129,7 +130,8 @@ export const PageNetwork = () =>
}
- as Page;
+ ]
+});
function activateWirelessConnection(connection: NM.RemoteConnection, ssid: string): void {
AstalNetwork.get_default().get_client().activate_connection_async(
diff --git a/ags/widget/control-center/pages/NightLight.tsx b/ags/widget/control-center/pages/NightLight.tsx
index 574f00e..16be810 100644
--- a/ags/widget/control-center/pages/NightLight.tsx
+++ b/ags/widget/control-center/pages/NightLight.tsx
@@ -5,14 +5,14 @@ import { Astal, Gtk } from "ags/gtk4";
import { addSliderMarksFromMinMax } from "../../../scripts/utils";
import { createBinding } from "ags";
-export const PageNightLight = () =>
-
-
+export const PageNightLight = new Page({
+ id: "night-light",
+ title: tr("control_center.pages.night_light.title"),
+ description: tr("control_center.pages.night_light.description"),
+ content: () => [
+ )} xalign={0} />,
{
self.value = NightLight.getDefault().temperature;
addSliderMarksFromMinMax(self, 5, "{}K");
@@ -24,10 +24,10 @@ export const PageNightLight = () =>
if(type != undefined && type !== null)
NightLight.getDefault().temperature = Math.floor(value)
}}
- />
+ />,
+ )} xalign={0} />,
{
self.value = NightLight.getDefault().gamma;
addSliderMarksFromMinMax(self, 5, "{}%");
@@ -39,4 +39,5 @@ export const PageNightLight = () =>
NightLight.getDefault().gamma = Math.floor(value)
}}
/>
- as Page;
+ ]
+});
diff --git a/ags/widget/control-center/pages/Page.tsx b/ags/widget/control-center/pages/Page.tsx
index 799f9ba..74c1dac 100644
--- a/ags/widget/control-center/pages/Page.tsx
+++ b/ags/widget/control-center/pages/Page.tsx
@@ -1,24 +1,21 @@
-import { register } from "ags/gobject";
import { Gtk } from "ags/gtk4";
import { Separator } from "../../Separator";
-import { Accessor, For } from "ags";
-import { transform, transformWidget, variableToBoolean, WidgetNodeType } from "../../../scripts/utils";
+import { Accessor, createRoot } from "ags";
+import { transformWidget, variableToBoolean, WidgetNodeType } from "../../../scripts/utils";
import Pango from "gi://Pango?version=1.0";
export type PageProps = {
- $?: () => void;
- actionClose?: () => void;
id: string;
- class?: string | Accessor;
- title: string | Accessor;
- description?: string | Accessor;
- headerButtons?: Array | Accessor>;
+ title: string;
+ description?: string;
+ headerButtons?: Array | Accessor>;
bottomButtons?: Array | Accessor>;
orientation?: Gtk.Orientation | Accessor;
- spacing?: number;
- children?: WidgetNodeType;
+ spacing?: number | Accessor;
+ content: () => WidgetNodeType;
+ actionClosed?: () => void;
};
export type BottomButton = {
@@ -26,142 +23,134 @@ export type BottomButton = {
description?: string | Accessor;
tooltipText?: string | Accessor;
tooltipMarkup?: string | Accessor;
- onClick?: () => void;
+ actionClicked?: () => void;
};
-export { Page };
+export type HeaderButton = {
+ label?: string|Accessor;
+ icon: string|Accessor;
+ tooltipText?: string | Accessor;
+ tooltipMarkup?: string | Accessor;
+ actionClicked?: () => void;
+};
-@register({ GTypeName: "Page" })
-class Page extends Gtk.Box {
- #id: string | number = "";
- readonly bottomButtons?: Array = [];
-
- #subs: Array<() => void> = [];
- #title: string | Accessor = "";
- #description?: string | Accessor;
+export class Page {
+ #title: string;
+ #description?: string;
+ #orientation: Gtk.Orientation|Accessor<
+ Gtk.Orientation> = Gtk.Orientation.VERTICAL;
+ #spacing: number|Accessor = 4;
+ #headerButtons?: Array|Accessor>;
+ #bottomButtons?: Array|Accessor>;
+ readonly #id?: string;
+ readonly #create: () => WidgetNodeType;
+ public get id() { return this.#id; }
public get title() { return this.#title; }
public get description() { return this.#description; }
- public get id() { return this.#id; }
- public actionClose?: () => void = () => {};
+ public get headerButtons() { return this.#headerButtons; }
+ public get bottomButtons() { return this.#bottomButtons; }
+ public readonly actionClosed?: () => void;
constructor(props: PageProps) {
- super();
-
- this.set_hexpand(true);
- this.set_orientation(Gtk.Orientation.VERTICAL);
-
- if(props.class instanceof Accessor) {
- this.#subs.push(props.class.subscribe(() => {
- const clss = (props.class as Accessor).get();
-
- this.cssClasses = ["page", ...clss.split(' ').filter(s => s !== "")];
- }));
- } else {
- if(props.class)
- this.cssClasses = ["page",
- ...(props.class as string).split(' ').filter(s => s)];
- else
- this.add_css_class("page");
- }
-
this.#id = props.id;
this.#title = props.title;
this.#description = props.description;
- this.actionClose = props.actionClose;
+ this.#create = props.content;
+ this.actionClosed = props.actionClosed;
- this.prepend( as Gtk.Box
+ );
+ }
- this.append(
-
- {props.children}
- as Gtk.Box);
-
- this.append( buttons.length > 0)
- : (!props.bottomButtons ? false : props.bottomButtons.length > 0)}
- /> as Gtk.Widget);
-
- this.append(
-
- {transformWidget(props.bottomButtons, (button) =>
-
-
-
-
-
- )}
- as Gtk.Box);
-
- props.$?.();
+ public static getContent(pageWidget: Gtk.Box) {
+ return pageWidget.get_first_child()!.get_next_sibling()! as Gtk.Box;
}
}
-function BottomButton(props: BottomButton) {
- return
-
-
-
-
-
- as Gtk.Button;
-}
-
-export function PageButton({ onDestroy, ...props }: {
+export function PageButton({ onUnmap, ...props }: {
class?: string | Accessor;
icon?: string | Accessor;
title: string | Accessor;
endWidget?: WidgetNodeType;
description?: string | Accessor;
extraButtons?: Array | WidgetNodeType;
- onDestroy?: (self: Gtk.Box) => void;
- onClick?: (self: Gtk.Button) => void;
+ maxWidthChars?: number | Accessor;
+ onUnmap?: (self: Gtk.Box) => void;
+ actionClicked?: (self: Gtk.Button) => void;
tooltipText?: string | Accessor;
tooltipMarkup?: string | Accessor;
-}) {
- return
- onUnmap?.(self)} class={"page-button"}>
+
-
+
{props.icon && }
-
+
- `${title.substring(0, 35)}${title.length > 35 ? '…' : ""}`)
- }
+ ellipsize={Pango.EllipsizeMode.END} label={props.title}
+ maxWidthChars={props.maxWidthChars ?? 28}
/>
- as Gtk.Box;
diff --git a/ags/widget/control-center/pages/Sound.tsx b/ags/widget/control-center/pages/Sound.tsx
index 9cc1b76..f3b1065 100644
--- a/ags/widget/control-center/pages/Sound.tsx
+++ b/ags/widget/control-center/pages/Sound.tsx
@@ -4,92 +4,93 @@ import { getAppIcon, lookupIcon } from "../../../scripts/apps";
import { Wireplumber } from "../../../scripts/volume";
import { tr } from "../../../i18n/intl";
import { createBinding, For } from "ags";
-import AstalWp from "gi://AstalWp";
import { variableToBoolean } from "../../../scripts/utils";
+
+import AstalWp from "gi://AstalWp";
import GObject from "gi://GObject?version=2.0";
import Pango from "gi://Pango?version=1.0";
-export const PageSound = () =>
-
-
-
- {(sink: AstalWp.Endpoint) =>
-
- isDefault ? "default" : "")}
- icon={createBinding(sink, "icon").as(ico =>
- lookupIcon(ico) ? ico : "audio-card-symbolic")}
- title={createBinding(sink, "description").as(desc =>
- desc ?? "Speaker")}
- onClick={() => !sink.isDefault && sink.set_is_default(true)}
- endWidget={
-
- }
- />}
-
+export const PageSound = new Page({
+ id: "sound",
+ title: tr("control_center.pages.sound.title"),
+ description: tr("control_center.pages.sound.description"),
+ content: () => [
+ ,
+
+
+ {(sink: AstalWp.Endpoint) =>
+
+ isDefault ? "default" : "")}
+ icon={createBinding(sink, "icon").as(ico =>
+ lookupIcon(ico) ? ico : "audio-card-symbolic")}
+ title={createBinding(sink, "description").as(desc =>
+ desc ?? "Speaker")}
+ actionClicked={() => !sink.isDefault && sink.set_is_default(true)}
+ endWidget={
+
+ }
+ />}
+
+ ,
+
+
+
+ {(stream: AstalWp.Stream) =>
+ {
+ const conns: Map> = new Map();
+ const controllerMotion = Gtk.EventControllerMotion.new();
-
-
- {(stream: AstalWp.Stream) =>
- {
- const conns: Map> = new Map();
- const controllerMotion = Gtk.EventControllerMotion.new();
+ self.add_controller(controllerMotion);
- self.add_controller(controllerMotion);
+ conns.set(controllerMotion, [
+ controllerMotion.connect("enter", () => {
+ const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
+ revealer.set_reveal_child(true);
+ }),
+ controllerMotion.connect("leave", () => {
+ const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
+ revealer.set_reveal_child(false);
+ })
+ ]);
- conns.set(controllerMotion, [
- controllerMotion.connect("enter", () => {
- const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
- revealer.set_reveal_child(true);
- }),
- controllerMotion.connect("leave", () => {
- const revealer = self.get_first_child()!.get_first_child() as Gtk.Revealer;
- revealer.set_reveal_child(true);
- })
- ]);
+ conns.set(self, [
+ self.connect("destroy", () => conns.forEach((ids, obj) =>
+ ids.forEach(id => obj.disconnect(id))
+ ))
+ ]);
+ }}>
+
+ getAppIcon(name.split(' ')[0]) ?? "application-x-executable-symbolic")}
+ css={"font-size: 18px; margin-right: 6px;"} />
- conns.set(self, [
- self.connect("destroy", () => conns.forEach((ids, obj) =>
- ids.forEach(id => obj.disconnect(id))
- ))
- ]);
- }}>
+
+
+
+
+ desc ?? "Unnamed audio stream")}
+ ellipsize={Pango.EllipsizeMode.END}
+ tooltipText={createBinding(stream, "name")}
+ class={"name"} xalign={0}
+ />
+
-
- getAppIcon(name.split(' ')[0]) ?? "application-x-executable-symbolic")}
- css={"font-size: 18px; margin-right: 6px;"} />
-
-
-
-
-
- name ?? "Unnamed audio stream")}
- ellipsize={Pango.EllipsizeMode.END}
- tooltipText={createBinding(stream, "name")}
- class={"name"} xalign={0}
+ stream.set_volume(value)}
+ hexpand min={0} max={1.5}
/>
-
-
- {
- self.value = Math.floor(stream.volume * 100);
- }} value={createBinding(stream, "volume").as(vol =>
- Math.floor(vol * 100))}
- onChangeValue={(_, type, value) => {
- if(type !== undefined && type !== null)
- stream.volume = Math.floor(value / 100);
- }}
- />
+
-
- }
-
- as Page;
+ }
+
+
+ ]
+});
diff --git a/ags/widget/control-center/tiles/Bluetooth.tsx b/ags/widget/control-center/tiles/Bluetooth.tsx
index 3c1ad2b..0d49cda 100644
--- a/ags/widget/control-center/tiles/Bluetooth.tsx
+++ b/ags/widget/control-center/tiles/Bluetooth.tsx
@@ -13,7 +13,7 @@ export const TileBluetooth = () =>
return connected && connectedDev ? connectedDev.get_alias() : ""
})} onToggledOn={() => AstalBluetooth.get_default().adapter?.set_powered(true)}
onToggledOff={() => AstalBluetooth.get_default().adapter?.set_powered(false)}
- onClickMore={() => TilesPages?.toggle(BluetoothPage())}
+ onClickMore={() => TilesPages?.toggle(BluetoothPage)}
enableOnClickMore={true} iconSize={16}
toggleState={createBinding(AstalBluetooth.get_default(), "isPowered")}
icon={createComputed([
diff --git a/ags/widget/control-center/tiles/Network.tsx b/ags/widget/control-center/tiles/Network.tsx
index 9ab0bfd..c2eee33 100644
--- a/ags/widget/control-center/tiles/Network.tsx
+++ b/ags/widget/control-center/tiles/Network.tsx
@@ -31,7 +31,7 @@ export const TileNetwork = () =>
})()
)} onToggledOn={() => wifi.set_enabled(true)}
onToggledOff={() => wifi.set_enabled(false)}
- onClickMore={() => TilesPages?.toggle(PageNetwork())}
+ onClickMore={() => TilesPages?.toggle(PageNetwork)}
icon={"network-wireless-signal-excellent-symbolic"}
toggleState={createBinding(wifi, "enabled")}
/>
@@ -50,7 +50,7 @@ export const TileNetwork = () =>
})}
onToggledOn={() => execAsync("nmcli n on")}
onToggledOff={() => execAsync("nmcli n off")}
- onClickMore={() => TilesPages?.toggle(PageNetwork())}
+ onClickMore={() => TilesPages?.toggle(PageNetwork)}
icon={createBinding(wired, "internet").as((internet: AstalNetwork.Internet) => {
switch(internet) {
case AstalNetwork.Internet.CONNECTED:
@@ -74,7 +74,7 @@ export const TileNetwork = () =>
description={tr("disconnected")}
onToggledOn={() => execAsync("nmcli n on")}
onToggledOff={() => execAsync("nmcli n off")}
- onClickMore={() => TilesPages?.toggle(PageNetwork())}
+ onClickMore={() => TilesPages?.toggle(PageNetwork)}
icon={"network-wired-disconnected-symbolic"}
iconSize={16}
toggleState={createBinding(wired, "internet").as((internet: AstalNetwork.Internet) =>
diff --git a/ags/widget/control-center/tiles/NightLight.tsx b/ags/widget/control-center/tiles/NightLight.tsx
index 0ee5cc5..5def169 100644
--- a/ags/widget/control-center/tiles/NightLight.tsx
+++ b/ags/widget/control-center/tiles/NightLight.tsx
@@ -20,6 +20,6 @@ export const TileNightLight = () =>
onToggledOff={() => NightLight.getDefault().identity = true}
onToggledOn={() => NightLight.getDefault().identity = false}
enableOnClickMore={true}
- onClickMore={() => TilesPages?.toggle(PageNightLight())}
+ onClickMore={() => TilesPages?.toggle(PageNightLight)}
toggleState={createBinding(NightLight.getDefault(), "identity").as(identity => !identity)}
/>
diff --git a/ags/widget/control-center/tiles/Recording.tsx b/ags/widget/control-center/tiles/Recording.tsx
index ad90376..5dd5bd9 100644
--- a/ags/widget/control-center/tiles/Recording.tsx
+++ b/ags/widget/control-center/tiles/Recording.tsx
@@ -3,7 +3,6 @@ import { Recording } from "../../../scripts/recording";
import { tr } from "../../../i18n/intl";
import { isInstalled, time } from "../../../scripts/utils";
import { createBinding, createComputed } from "ags";
-import { Gtk } from "ags/gtk4";
export const TileRecording = () =>
diff --git a/ags/widget/control-center/tiles/Tile.tsx b/ags/widget/control-center/tiles/Tile.tsx
index 33dbc9e..adfb92d 100644
--- a/ags/widget/control-center/tiles/Tile.tsx
+++ b/ags/widget/control-center/tiles/Tile.tsx
@@ -15,7 +15,7 @@ export type TileProps = {
description?: string | Accessor;
toggleState?: boolean | Accessor;
enableOnClickMore?: boolean | Accessor;
- onDestroy?: (self: Gtk.Box) => void;
+ onUnmap?: (self: Gtk.Box) => void;
onToggledOn: () => void;
onToggledOff: () => void;
onClickMore?: () => void;
@@ -35,7 +35,8 @@ export function Tile(props: TileProps): Gtk.Widget {
onCleanup(() => subs.forEach(s => s()));
- return
`tile ${clss} ${isToggled ? "toggled" : ""} ${
@@ -47,7 +48,7 @@ export function Tile(props: TileProps): Gtk.Widget {
props.onClickMore ? "has-more" : ""
}`
)
- }>
+ }>
{
if(toggled.get()) {
setToggled(false);