Implemented Wallpaper Selector and Matugen's Wallpaper based auto-theming. (#73)

* Implement matugen - WIP

* Added matugen

* Add types and cleanup code

* Matugen implementation updates and added more options such as scheme and contrast.

* Code cleanup and matugen settings renamed for clarity.

* Makon maroon a primary matugen color.

* Updates to handle variations of matugen colors

* Finalizing matugen and wrapping up variations.

* Minor styling updates of the settings dialog.

* Do a swww dependency check.

* Dependency logic update

* Switch shouldn't double trigger notifications now when checking dependency.

* Logic was inverted

* Add matugen to dependency checker.

* Fixed dependency checking conditional

* Update dependency list in readme and check for matugen before doing matugen operations

* Styling fixes

* OSD Fix

* Remove unused code from wallpaper service.

* Color fixes for matugen.

* Nix updates for new dependencies

* Change default wallpaper to empty.

* Added custom notification service for startup, cleaned up code and updated readme.
This commit is contained in:
Jas Singh
2024-08-07 21:43:31 -07:00
committed by GitHub
parent d743c98a6a
commit f5b75edbed
31 changed files with 1315 additions and 197 deletions

View File

@@ -11,7 +11,7 @@ curl -fsSL https://bun.sh/install | bash && \
sudo ln -s $HOME/.bun/bin/bun /usr/local/bin/bun sudo ln -s $HOME/.bun/bin/bun /usr/local/bin/bun
``` ```
Additional dependencies: Additional dependencies:
``` ```sh
pipewire pipewire
bluez bluez
bluez-utils bluez-utils
@@ -20,26 +20,29 @@ gpu-screen-recorder
hyprpicker hyprpicker
btop btop
networkmanager networkmanager
matugen
wl-clipboard
swww
dart-sass dart-sass
brightnessctl brightnessctl
gnome-bluetooth-3.0 gnome-bluetooth-3.0
``` ```
Optional Dependencies: Optional Dependencies:
``` ```sh
// Used for Tracking GPU Usage in your Dashboard (NVidia only) ## Used for Tracking GPU Usage in your Dashboard (NVidia only)
python python
python-gpustat python-gpustat
``` ```
Arch (pacman): Arch (pacman):
```bash ```bash
sudo pacman -S pipewire bluez bluez-utils btop networkmanager dart-sass brightnessctl python gnome-bluetooth-3.0 sudo pacman -S pipewire bluez bluez-utils btop networkmanager dart-sass wl-clipboard brightnessctl swww python gnome-bluetooth-3.0
``` ```
Arch (AUR): Arch (AUR):
```bash ```bash
yay -S grimblast gpu-screen-recorder hyprpicker python-gpustat aylurs-gtk-shell-git yay -S grimblast-git gpu-screen-recorder hyprpicker matugen-bin python-gpustat aylurs-gtk-shell-git
``` ```
For NixOS/Home-Manager, see [NixOS & Home-Manager instructions](#nixos--home-manager). For NixOS/Home-Manager, see [NixOS & Home-Manager instructions](#nixos--home-manager).

View File

@@ -15,6 +15,8 @@
, gpu-screen-recorder , gpu-screen-recorder
, networkmanager , networkmanager
, brightnessctl , brightnessctl
, matugen
, swww
, python3 , python3
}: }:
let let
@@ -58,6 +60,8 @@ in {
export PATH=$PATH:${gpu-screen-recorder}/bin export PATH=$PATH:${gpu-screen-recorder}/bin
export PATH=$PATH:${networkmanager}/bin export PATH=$PATH:${networkmanager}/bin
export PATH=$PATH:${brightnessctl}/bin export PATH=$PATH:${brightnessctl}/bin
export PATH=$PATH:${matugen}/bin
export PATH=$PATH:${swww}/bin
export PATH=$PATH:${pkgs.gnome.gnome-bluetooth}/bin export PATH=$PATH:${pkgs.gnome.gnome-bluetooth}/bin
export PATH=$PATH:${python3}/bin export PATH=$PATH:${python3}/bin
export GDK_BACKEND=wayland export GDK_BACKEND=wayland

View File

@@ -27,6 +27,8 @@
pkgsFor.${system}.bluez pkgsFor.${system}.bluez
pkgsFor.${system}.bluez-tools pkgsFor.${system}.bluez-tools
pkgsFor.${system}.grimblast pkgsFor.${system}.grimblast
pkgsFor.${system}.matugen
pkgsFor.${system}.swww
pkgsFor.${system}.gpu-screen-recorder pkgsFor.${system}.gpu-screen-recorder
pkgsFor.${system}.brightnessctl pkgsFor.${system}.brightnessctl
pkgsFor.${system}.gnome.gnome-bluetooth pkgsFor.${system}.gnome.gnome-bluetooth

View File

@@ -37,12 +37,24 @@ export class Opt<T = unknown> extends Variable<T> {
reset() { reset() {
if (this.persistent) if (this.persistent)
return return;
if (JSON.stringify(this.value) !== JSON.stringify(this.initial)) { if (JSON.stringify(this.value) !== JSON.stringify(this.initial)) {
this.value = this.initial
return this.id;
}
}
doResetColor() {
if (this.persistent)
return;
const isColor = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(`${this.value}`);
if ((JSON.stringify(this.value) !== JSON.stringify(this.initial)) && isColor) {
this.value = this.initial this.value = this.initial
return this.id return this.id
} }
return;
} }
} }
@@ -65,13 +77,13 @@ function getOptions(object: object, path = ""): Opt[] {
}) })
} }
export function mkOptions<T extends object>(cacheFile: string, object: T) { export function mkOptions<T extends object>(cacheFile: string, object: T, confFile: string = "config.json") {
for (const opt of getOptions(object)) for (const opt of getOptions(object))
opt.init(cacheFile) opt.init(cacheFile)
Utils.ensureDirectory(cacheFile.split("/").slice(0, -1).join("/")) Utils.ensureDirectory(cacheFile.split("/").slice(0, -1).join("/"))
const configFile = `${TMP}/config.json` const configFile = `${TMP}/${confFile}`
const values = getOptions(object).reduce((obj, { id, value }) => ({ [id]: value, ...obj }), {}) const values = getOptions(object).reduce((obj, { id, value }) => ({ [id]: value, ...obj }), {})
Utils.writeFileSync(JSON.stringify(values, null, 2), configFile) Utils.writeFileSync(JSON.stringify(values, null, 2), configFile)
Utils.monitorFile(configFile, () => { Utils.monitorFile(configFile, () => {
@@ -98,12 +110,27 @@ export function mkOptions<T extends object>(cacheFile: string, object: T) {
: await sleep().then(() => reset(list)) : await sleep().then(() => reset(list))
} }
async function resetTheme(
[opt, ...list] = getOptions(object),
id = opt?.doResetColor(),
): Promise<Array<string>> {
if (!opt)
return sleep().then(() => [])
return id
? [id, ...(await sleep(50).then(() => resetTheme(list)))]
: await sleep().then(() => resetTheme(list))
}
return Object.assign(object, { return Object.assign(object, {
configFile, configFile,
array: () => getOptions(object), array: () => getOptions(object),
async reset() { async reset() {
return (await reset()).join("\n") return (await reset()).join("\n")
}, },
async resetTheme() {
return (await resetTheme()).join("\n")
},
handler(deps: string[], callback: () => void) { handler(deps: string[], callback: () => void) {
for (const opt of getOptions(object)) { for (const opt of getOptions(object)) {
if (deps.some(i => opt.id.startsWith(i))) if (deps.some(i => opt.id.startsWith(i)))

View File

@@ -0,0 +1,59 @@
export const defaultColorMap = {
"rosewater": "#f5e0dc",
"flamingo": "#f2cdcd",
"pink": "#f5c2e7",
"mauve": "#cba6f7",
"red": "#f38ba8",
"maroon": "#eba0ac",
"peach": "#fab387",
"yellow": "#f9e2af",
"green": "#a6e3a1",
"teal": "#94e2d5",
"sky": "#89dceb",
"sapphire": "#74c7ec",
"blue": "#89b4fa",
"lavender": "#b4befe",
"text": "#cdd6f4",
"subtext1": "#bac2de",
"subtext2": "#a6adc8",
"overlay2": "#9399b2",
"overlay1": "#7f849c",
"overlay0": "#6c7086",
"surface2": "#585b70",
"surface1": "#45475a",
"surface0": "#313244",
"base2": "#242438",
"base": "#1e1e2e",
"mantle": "#181825",
"crust": "#11111b",
"surface1_2": "#454759",
"text2": "#cdd6f3",
"pink2": "#f5c2e6",
"red2": "#f38ba7",
"mantle2": "#181824",
"surface0_2": "#313243",
"surface2_2": "#585b69",
"overlay1_2": "#7f849b",
"lavender2": "#b4befd",
"mauve2": "#cba6f6",
"green2": "#a6e3a0",
"sky2": "#89dcea",
"teal2": "#94e2d4",
"yellow2": "#f9e2ad",
"maroon2": "#eba0ab",
"crust2": "#11111a",
"pink3": "#f5c2e8",
"red3": "#f38ba9",
"mantle3": "#181826",
"surface0_3": "#313245",
"surface2_3": "#585b71",
"overlay1_3": "#7f849d",
"lavender3": "#b4beff",
"mauve3": "#cba6f8",
"green3": "#a6e3a2",
"sky3": "#89dcec",
"teal3": "#94e2d6",
"yellow3": "#f9e2ae",
"maroon3": "#eba0ad",
"crust3": "#11111c",
};

11
lib/types/notification.d.ts vendored Normal file
View File

@@ -0,0 +1,11 @@
export interface NotificationArgs {
appName?: string;
body?: string;
iconName?: string;
id?: number;
summary?: string;
urgency?: Urgency;
category?: string;
timeout?: number;
transient?: boolean;
}

View File

@@ -1,4 +1,5 @@
import { Opt } from "lib/option"; import { Opt } from "lib/option";
import { Variable } from "types/variable";
export type Unit = "imperial" | "metric"; export type Unit = "imperial" | "metric";
export type PowerOptions = "sleep" | "reboot" | "logout" | "shutdown"; export type PowerOptions = "sleep" | "reboot" | "logout" | "shutdown";
@@ -17,12 +18,91 @@ export type RowProps<T> = {
| "enum" | "enum"
| "boolean" | "boolean"
| "img" | "img"
| "wallpaper"
| "font" | "font"
enums?: string[] enums?: string[]
max?: number max?: number
min?: number min?: number
subtitle?: string disabledBinding?: Variable<boolean>
subtitle?: string | VarType<any> | Opt,
dependencies?: string[],
increment?: number increment?: number
} }
export type OSDOrientation = "horizontal" | "vertical"; export type OSDOrientation = "horizontal" | "vertical";
export type HexColor = `#${string}`;
export type MatugenColors = {
"background": HexColor,
"error": HexColor,
"error_container": HexColor,
"inverse_on_surface": HexColor,
"inverse_primary": HexColor,
"inverse_surface": HexColor,
"on_background": HexColor,
"on_error": HexColor,
"on_error_container": HexColor,
"on_primary": HexColor,
"on_primary_container": HexColor,
"on_primary_fixed": HexColor,
"on_primary_fixed_variant": HexColor,
"on_secondary": HexColor,
"on_secondary_container": HexColor,
"on_secondary_fixed": HexColor,
"on_secondary_fixed_variant": HexColor,
"on_surface": HexColor,
"on_surface_variant": HexColor,
"on_tertiary": HexColor,
"on_tertiary_container": HexColor,
"on_tertiary_fixed": HexColor,
"on_tertiary_fixed_variant": HexColor,
"outline": HexColor,
"outline_variant": HexColor,
"primary": HexColor,
"primary_container": HexColor,
"primary_fixed": HexColor,
"primary_fixed_dim": HexColor,
"scrim": HexColor,
"secondary": HexColor,
"secondary_container": HexColor,
"secondary_fixed": HexColor,
"secondary_fixed_dim": HexColor,
"shadow": HexColor,
"surface": HexColor,
"surface_bright": HexColor,
"surface_container": HexColor,
"surface_container_high": HexColor,
"surface_container_highest": HexColor,
"surface_container_low": HexColor,
"surface_container_lowest": HexColor,
"surface_dim": HexColor,
"surface_variant": HexColor,
"tertiary": HexColor,
"tertiary_container": HexColor,
"tertiary_fixed": HexColor,
"tertiary_fixed_dim": HexColor
}
type MatugenScheme =
| "content"
| "expressive"
| "fidelity"
| "fruit-salad"
| "monochrome"
| "neutral"
| "rainbow"
| "tonal-spot";
type MatugenVariation =
| "standard_1"
| "standard_2"
| "standard_3"
| "monochrome_1"
| "monochrome_2"
| "monochrome_3"
| "vivid_1"
| "vivid_2"
| "vivid_3"
type MatugenTheme = "light" | "dark";

View File

@@ -4,6 +4,8 @@ import icons, { substitutes } from "./icons"
import Gtk from "gi://Gtk?version=3.0" import Gtk from "gi://Gtk?version=3.0"
import Gdk from "gi://Gdk" import Gdk from "gi://Gdk"
import GLib from "gi://GLib?version=2.0" import GLib from "gi://GLib?version=2.0"
import GdkPixbuf from "gi://GdkPixbuf";
import { NotificationArgs } from "types/utils/notify"
export type Binding<T> = import("types/service").Binding<any, any, T> export type Binding<T> = import("types/service").Binding<any, any, T>
@@ -73,7 +75,12 @@ export function dependencies(...bins: string[]) {
if (missing.length > 0) { if (missing.length > 0) {
console.warn(Error(`missing dependencies: ${missing.join(", ")}`)) console.warn(Error(`missing dependencies: ${missing.join(", ")}`))
Utils.notify(`missing dependencies: ${missing.join(", ")}`) Notify({
summary: "Dependencies not found!",
body: `The following dependencies are missing: ${missing.join(", ")}`,
iconName: icons.ui.warning,
timeout: 7000
});
} }
return missing.length === 0 return missing.length === 0
@@ -111,3 +118,30 @@ export function createSurfaceFromWidget(widget: Gtk.Widget) {
widget.draw(cr) widget.draw(cr)
return surface return surface
} }
/**
* Ensure that the provided filepath is a valid image
*/
export const isAnImage = (imgFilePath: string): boolean => {
try {
GdkPixbuf.Pixbuf.new_from_file(imgFilePath);
return true;
} catch (error) {
return false;
}
}
export const Notify = (notifPayload: NotificationArgs): void => {
let command = 'notify-send';
command += ` "${notifPayload.summary} "`;
if (notifPayload.body) command += ` "${notifPayload.body}" `;
if (notifPayload.appName) command += ` -a "${notifPayload.appName}"`;
if (notifPayload.iconName) command += ` -i "${notifPayload.iconName}"`;
if (notifPayload.urgency) command += ` -u "${notifPayload.urgency}"`;
if (notifPayload.timeout !== undefined) command += ` -t ${notifPayload.timeout}`;
if (notifPayload.category) command += ` -c "${notifPayload.category}"`;
if (notifPayload.transient) command += ` -e`;
if (notifPayload.id !== undefined) command += ` -r ${notifPayload.id}`;
Utils.execAsync(command)
}

View File

@@ -11,11 +11,11 @@ const BatteryLabel = () => {
const batIcon = Utils.merge([battery.bind("percent"), battery.bind("charging"), battery.bind("charged")], const batIcon = Utils.merge([battery.bind("percent"), battery.bind("charging"), battery.bind("charged")],
(batPercent: number, batCharging, batCharged) => { (batPercent: number, batCharging, batCharged) => {
if(batCharged) if (batCharged)
return `battery-level-100-charged-symbolic`; return `battery-level-100-charged-symbolic`;
else else
return `battery-level-${Math.floor(batPercent / 10) * 10}${batCharging ? '-charging' : ''}-symbolic`; return `battery-level-${Math.floor(batPercent / 10) * 10}${batCharging ? '-charging' : ''}-symbolic`;
}); });
battery.connect("changed", ({ available }) => { battery.connect("changed", ({ available }) => {
isVis.value = available; isVis.value = available;

View File

@@ -1,67 +1,67 @@
const network = await Service.import("network"); const network = await Service.import("network");
const Ethernet = () => { const Ethernet = () => {
return Widget.Box({ return Widget.Box({
class_name: "menu-section-container ethernet", class_name: "menu-section-container ethernet",
vertical: true,
children: [
Widget.Box({
class_name: "menu-label-container",
hpack: "fill",
child: Widget.Label({
class_name: "menu-label",
hexpand: true,
hpack: "start",
label: "Ethernet",
}),
}),
Widget.Box({
class_name: "menu-items-section",
vertical: true, vertical: true,
child: Widget.Box({ children: [
class_name: "menu-content", Widget.Box({
vertical: true, class_name: "menu-label-container",
setup: (self) => { hpack: "fill",
self.hook(network, () => { child: Widget.Label({
return (self.child = Widget.Box({ class_name: "menu-label",
class_name: "network-element-item", hexpand: true,
child: Widget.Box({ hpack: "start",
hpack: "start", label: "Ethernet",
children: [
Widget.Icon({
class_name: `network-icon ethernet ${network.wired.state === "activated" ? "active" : ""}`,
tooltip_text: network.wired.internet,
icon: `${network.wired["icon_name"]}`,
}),
Widget.Box({
class_name: "connection-container",
vertical: true,
children: [
Widget.Label({
class_name: "active-connection",
hpack: "start",
truncate: "end",
wrap: true,
label: `Ethernet Connection ${network.wired.state !== "unknown" && typeof network.wired?.speed === "number" ? `(${network.wired?.speed / 1000} Gbps)` : ""}`,
}),
Widget.Label({
hpack: "start",
class_name: "connection-status dim",
label:
network.wired.internet.charAt(0).toUpperCase() +
network.wired.internet.slice(1),
}),
],
}),
],
}), }),
})); }),
}); Widget.Box({
}, class_name: "menu-items-section",
}), vertical: true,
}), child: Widget.Box({
], class_name: "menu-content",
}); vertical: true,
setup: (self) => {
self.hook(network, () => {
return (self.child = Widget.Box({
class_name: "network-element-item",
child: Widget.Box({
hpack: "start",
children: [
Widget.Icon({
class_name: `network-icon ethernet ${network.wired.state === "activated" ? "active" : ""}`,
tooltip_text: network.wired.internet,
icon: `${network.wired["icon_name"]}`,
}),
Widget.Box({
class_name: "connection-container",
vertical: true,
children: [
Widget.Label({
class_name: "active-connection",
hpack: "start",
truncate: "end",
wrap: true,
label: `Ethernet Connection ${network.wired.state !== "unknown" && typeof network.wired?.speed === "number" ? `(${network.wired?.speed / 1000} Gbps)` : ""}`,
}),
Widget.Label({
hpack: "start",
class_name: "connection-status dim",
label:
network.wired.internet.charAt(0).toUpperCase() +
network.wired.internet.slice(1),
}),
],
}),
],
}),
}));
});
},
}),
}),
],
});
}; };
export { Ethernet }; export { Ethernet };

View File

@@ -1,5 +1,7 @@
import { opt, mkOptions } from "lib/option" import { opt, mkOptions } from "lib/option"
import { MatugenScheme, MatugenTheme, MatugenVariation } from "lib/types/options";
// WARN: CHANGING THESE VALUES WILL PREVENT MATUGEN COLOR GENERATION FOR THE CHANGED VALUE
const colors = { const colors = {
"rosewater": "#f5e0dc", "rosewater": "#f5e0dc",
"flamingo": "#f2cdcd", "flamingo": "#f2cdcd",
@@ -30,26 +32,70 @@ const colors = {
"crust": "#11111b" "crust": "#11111b"
}; };
// WARN: CHANGING THESE VALUES WILL PREVENT MATUGEN COLOR GENERATION FOR THE CHANGED VALUE
const secondary_colors = {
text: "#cdd6f3",
pink: "#f5c2e6",
red: "#f38ba7",
mantle: "#181824",
surface1: "#454759",
surface0: "#313243",
overlay1: "#7f849b",
lavender: "#b4befd",
mauve: "#cba6f6",
green: "#a6e3a0",
sky: "#89dcea",
teal: "#94e2d4",
yellow: "#f9e2ad",
maroon: "#eba0ab",
crust: "#11111a",
surface2: "#585b69",
}
const tertiary_colors = {
pink: "#f5c2e8",
red: "#f38ba9",
mantle: "#181826",
surface0: "#313245",
overlay1: "#7f849d",
lavender: "#b4beff",
mauve: "#cba6f8",
green: "#a6e3a2",
sky: "#89dcec",
teal: "#94e2d6",
yellow: "#f9e2ae",
maroon: "#eba0ad",
crust: "#11111c",
surface2: "#585b71",
}
const options = mkOptions(OPTIONS, { const options = mkOptions(OPTIONS, {
theme: { theme: {
matugen: opt(false),
matugen_settings: {
mode: opt<MatugenTheme>("dark"),
scheme_type: opt<MatugenScheme>("tonal-spot"),
variation: opt<MatugenVariation>("standard_1"),
contrast: opt(0.0),
},
font: { font: {
size: opt("1.2rem"), size: opt("1.2rem"),
name: opt("Ubuntu Nerd Font"), name: opt("Ubuntu Nerd Font"),
weight: opt(600), weight: opt(600),
}, },
notification: { notification: {
background: opt(colors.mantle), background: opt(tertiary_colors.mantle),
actions: { actions: {
background: opt(colors.lavender), background: opt(secondary_colors.lavender),
text: opt(colors.mantle), text: opt(colors.mantle),
}, },
label: opt(colors.lavender), label: opt(colors.lavender),
border: opt(colors.surface0), border: opt(secondary_colors.surface0),
time: opt(colors.overlay1), time: opt(secondary_colors.overlay1),
text: opt(colors.text), text: opt(colors.text),
labelicon: opt(colors.lavender), labelicon: opt(colors.lavender),
close_button: { close_button: {
background: opt(colors.red), background: opt(secondary_colors.red),
label: opt(colors.crust) label: opt(colors.crust)
} }
}, },
@@ -57,12 +103,12 @@ const options = mkOptions(OPTIONS, {
enable: opt(true), enable: opt(true),
orientation: opt<"horizontal" | "vertical">("vertical"), orientation: opt<"horizontal" | "vertical">("vertical"),
bar_container: opt(colors.crust), bar_container: opt(colors.crust),
icon_container: opt(colors.lavender), icon_container: opt(tertiary_colors.lavender),
bar_color: opt(colors.lavender), bar_color: opt(tertiary_colors.lavender),
bar_empty_color: opt(colors.surface0), bar_empty_color: opt(colors.surface0),
bar_overflow_color: opt(colors.red), bar_overflow_color: opt(secondary_colors.red),
icon: opt(colors.crust), icon: opt(colors.crust),
label: opt(colors.lavender), label: opt(tertiary_colors.lavender),
monitor: opt(0), monitor: opt(0),
active_monitor: opt(true), active_monitor: opt(true),
radius: opt("0.4em"), radius: opt("0.4em"),
@@ -177,7 +223,7 @@ const options = mkOptions(OPTIONS, {
label: opt(colors.lavender), label: opt(colors.lavender),
listitems: { listitems: {
passive: opt(colors.text), passive: opt(colors.text),
active: opt(colors.lavender) active: opt(secondary_colors.lavender)
}, },
icons: { icons: {
passive: opt(colors.surface2), passive: opt(colors.surface2),
@@ -185,18 +231,18 @@ const options = mkOptions(OPTIONS, {
}, },
switch: { switch: {
enabled: opt(colors.lavender), enabled: opt(colors.lavender),
disabled: opt(colors.surface0), disabled: opt(tertiary_colors.surface0),
puck: opt(colors.overlay0) puck: opt(secondary_colors.surface1)
}, },
buttons: { buttons: {
default: opt(colors.lavender), default: opt(colors.lavender),
active: opt(colors.pink), active: opt(secondary_colors.pink),
disabled: opt(colors.surface2), disabled: opt(tertiary_colors.surface2),
text: opt(colors.crust) text: opt(secondary_colors.mantle)
}, },
iconbuttons: { iconbuttons: {
passive: opt(colors.text), passive: opt(secondary_colors.text),
active: opt(colors.lavender) active: opt(tertiary_colors.lavender)
}, },
progressbar: { progressbar: {
foreground: opt(colors.lavender), foreground: opt(colors.lavender),
@@ -204,7 +250,7 @@ const options = mkOptions(OPTIONS, {
}, },
slider: { slider: {
primary: opt(colors.lavender), primary: opt(colors.lavender),
background: opt(colors.surface2), background: opt(tertiary_colors.surface2),
backgroundhover: opt(colors.surface1), backgroundhover: opt(colors.surface1),
puck: opt(colors.overlay0) puck: opt(colors.overlay0)
}, },
@@ -219,9 +265,9 @@ const options = mkOptions(OPTIONS, {
}, },
menu: { menu: {
media: { media: {
song: opt(colors.lavender), song: opt(tertiary_colors.lavender),
artist: opt(colors.teal), artist: opt(tertiary_colors.teal),
album: opt(colors.pink), album: opt(tertiary_colors.pink),
background: { background: {
color: opt(colors.crust), color: opt(colors.crust),
}, },
@@ -230,13 +276,13 @@ const options = mkOptions(OPTIONS, {
}, },
buttons: { buttons: {
inactive: opt(colors.surface2), inactive: opt(colors.surface2),
enabled: opt(colors.teal), enabled: opt(secondary_colors.teal),
background: opt(colors.lavender), background: opt(tertiary_colors.lavender),
text: opt(colors.crust), text: opt(colors.crust),
}, },
slider: { slider: {
primary: opt(colors.pink), primary: opt(colors.pink),
background: opt(colors.surface2), background: opt(tertiary_colors.surface2),
backgroundhover: opt(colors.surface1), backgroundhover: opt(colors.surface1),
puck: opt(colors.overlay0) puck: opt(colors.overlay0)
} }
@@ -257,7 +303,7 @@ const options = mkOptions(OPTIONS, {
text: opt(colors.text), text: opt(colors.text),
listitems: { listitems: {
passive: opt(colors.text), passive: opt(colors.text),
active: opt(colors.maroon) active: opt(secondary_colors.maroon)
}, },
iconbutton: { iconbutton: {
passive: opt(colors.text), passive: opt(colors.text),
@@ -269,15 +315,15 @@ const options = mkOptions(OPTIONS, {
}, },
audio_slider: { audio_slider: {
primary: opt(colors.maroon), primary: opt(colors.maroon),
background: opt(colors.surface2), background: opt(tertiary_colors.surface2),
backgroundhover: opt(colors.surface1), backgroundhover: opt(colors.surface1),
puck: opt(colors.overlay0) puck: opt(colors.surface2)
}, },
input_slider: { input_slider: {
primary: opt(colors.maroon), primary: opt(colors.maroon),
background: opt(colors.surface2), background: opt(tertiary_colors.surface2),
backgroundhover: opt(colors.surface1), backgroundhover: opt(colors.surface1),
puck: opt(colors.overlay0) puck: opt(colors.surface2)
} }
}, },
network: { network: {
@@ -299,7 +345,7 @@ const options = mkOptions(OPTIONS, {
}, },
listitems: { listitems: {
passive: opt(colors.text), passive: opt(colors.text),
active: opt(colors.mauve) active: opt(secondary_colors.mauve)
}, },
icons: { icons: {
passive: opt(colors.overlay2), passive: opt(colors.overlay2),
@@ -328,12 +374,12 @@ const options = mkOptions(OPTIONS, {
switch_divider: opt(colors.surface1), switch_divider: opt(colors.surface1),
switch: { switch: {
enabled: opt(colors.sky), enabled: opt(colors.sky),
disabled: opt(colors.surface0), disabled: opt(tertiary_colors.surface0),
puck: opt(colors.overlay0) puck: opt(secondary_colors.surface1)
}, },
listitems: { listitems: {
passive: opt(colors.text), passive: opt(colors.text),
active: opt(colors.sky) active: opt(secondary_colors.sky)
}, },
icons: { icons: {
passive: opt(colors.overlay2), passive: opt(colors.overlay2),
@@ -366,7 +412,7 @@ const options = mkOptions(OPTIONS, {
}, },
text: opt(colors.text), text: opt(colors.text),
listitems: { listitems: {
passive: opt(colors.text), passive: opt(secondary_colors.text),
active: opt(colors.yellow) active: opt(colors.yellow)
}, },
icons: { icons: {
@@ -375,7 +421,7 @@ const options = mkOptions(OPTIONS, {
}, },
slider: { slider: {
primary: opt(colors.yellow), primary: opt(colors.yellow),
background: opt(colors.surface2), background: opt(tertiary_colors.surface2),
backgroundhover: opt(colors.surface1), backgroundhover: opt(colors.surface1),
puck: opt(colors.overlay0) puck: opt(colors.overlay0)
}, },
@@ -398,7 +444,7 @@ const options = mkOptions(OPTIONS, {
calendar: { calendar: {
yearmonth: opt(colors.teal), yearmonth: opt(colors.teal),
weekdays: opt(colors.pink), weekdays: opt(colors.pink),
paginator: opt(colors.pink), paginator: opt(secondary_colors.pink),
currentday: opt(colors.pink), currentday: opt(colors.pink),
days: opt(colors.text), days: opt(colors.text),
contextdays: opt(colors.surface2), contextdays: opt(colors.surface2),
@@ -448,35 +494,35 @@ const options = mkOptions(OPTIONS, {
body: opt(colors.text), body: opt(colors.text),
confirm: opt(colors.green), confirm: opt(colors.green),
deny: opt(colors.red), deny: opt(colors.red),
button_text: opt(colors.crust), button_text: opt(secondary_colors.crust),
} }
}, },
shortcuts: { shortcuts: {
background: opt(colors.lavender), background: opt(colors.lavender),
text: opt(colors.crust), text: opt(secondary_colors.mantle),
recording: opt(colors.green) recording: opt(colors.green)
}, },
controls: { controls: {
disabled: opt(colors.surface2), disabled: opt(colors.surface2),
wifi: { wifi: {
background: opt(colors.mauve), background: opt(colors.mauve),
text: opt(colors.crust), text: opt(secondary_colors.mantle),
}, },
bluetooth: { bluetooth: {
background: opt(colors.sky), background: opt(colors.sky),
text: opt(colors.crust), text: opt(secondary_colors.mantle),
}, },
notifications: { notifications: {
background: opt(colors.yellow), background: opt(colors.yellow),
text: opt(colors.crust), text: opt(secondary_colors.mantle),
}, },
volume: { volume: {
background: opt(colors.maroon), background: opt(colors.maroon),
text: opt(colors.crust), text: opt(secondary_colors.mantle),
}, },
input: { input: {
background: opt(colors.pink), background: opt(colors.pink),
text: opt(colors.crust), text: opt(secondary_colors.mantle),
}, },
}, },
directories: { directories: {
@@ -507,22 +553,22 @@ const options = mkOptions(OPTIONS, {
bar_background: opt(colors.surface1), bar_background: opt(colors.surface1),
cpu: { cpu: {
icon: opt(colors.maroon), icon: opt(colors.maroon),
bar: opt(colors.maroon), bar: opt(tertiary_colors.maroon),
label: opt(colors.maroon), label: opt(colors.maroon),
}, },
ram: { ram: {
icon: opt(colors.yellow), icon: opt(colors.yellow),
bar: opt(colors.yellow), bar: opt(tertiary_colors.yellow),
label: opt(colors.yellow), label: opt(colors.yellow),
}, },
gpu: { gpu: {
icon: opt(colors.green), icon: opt(colors.green),
bar: opt(colors.green), bar: opt(tertiary_colors.green),
label: opt(colors.green), label: opt(colors.green),
}, },
disk: { disk: {
icon: opt(colors.pink), icon: opt(colors.pink),
bar: opt(colors.pink), bar: opt(tertiary_colors.pink),
label: opt(colors.pink), label: opt(colors.pink),
}, },
}, },
@@ -537,8 +583,8 @@ const options = mkOptions(OPTIONS, {
clear: opt(colors.red), clear: opt(colors.red),
switch: { switch: {
enabled: opt(colors.lavender), enabled: opt(colors.lavender),
disabled: opt(colors.surface0), disabled: opt(tertiary_colors.surface0),
puck: opt(colors.overlay0) puck: opt(secondary_colors.surface1)
}, },
}, },
} }
@@ -743,6 +789,10 @@ const options = mkOptions(OPTIONS, {
terminal: opt("kitty"), terminal: opt("kitty"),
wallpaper: {
image: opt("")
},
notifications: { notifications: {
position: opt<"top" | "top right" | "top left" | "bottom" | "bottom right" | "bottom left">("top right"), position: opt<"top" | "top right" | "top left" | "bottom" | "bottom right" | "bottom left">("top right"),
timeout: opt(7000), timeout: opt(7000),

53
scss/matugen/index.ts Normal file
View File

@@ -0,0 +1,53 @@
import { defaultColorMap } from "lib/types/defaults/options";
import { HexColor, MatugenColors } from "lib/types/options";
import { getMatugenVariations } from "./variations";
import { bash, dependencies, Notify, isAnImage } from "lib/utils";
import options from "options";
import icons from "lib/icons";
const { scheme_type, contrast } = options.theme.matugen_settings;
const { matugen } = options.theme;
export async function generateMatugenColors(): Promise<MatugenColors | undefined> {
if (!matugen.value || !dependencies('matugen')) {
return;
}
const wallpaperPath = options.wallpaper.image.value;
try {
if (!wallpaperPath.length || !isAnImage(wallpaperPath)) {
Notify({
summary: "Matugen Failed",
body: "Please select a wallpaper in 'Theming > General' first.",
iconName: icons.ui.warning,
timeout: 7000
})
return;
}
const normalizedContrast = contrast.value > 1 ? 1
: contrast.value < -1 ? -1
: contrast.value
const contents = await bash(`matugen image ${wallpaperPath} -t scheme-${scheme_type.value} --contrast ${normalizedContrast} --json hex`);
return JSON.parse(contents).colors[options.theme.matugen_settings.mode.value];
} catch (error) {
const errMsg = `An error occurred while generating matugen colors: ${error}`;
console.error(errMsg);
return;
}
}
export const replaceHexValues = (incomingHex: HexColor, matugenColors: MatugenColors): HexColor => {
if (!options.theme.matugen.value) {
return incomingHex;
}
const matugenVariation = getMatugenVariations(matugenColors, options.theme.matugen_settings.variation.value);
for (let curColor of Object.keys(defaultColorMap)) {
if (defaultColorMap[curColor] === incomingHex) {
return matugenVariation[curColor];
}
}
return incomingHex;
}

562
scss/matugen/variations.ts Normal file
View File

@@ -0,0 +1,562 @@
import { MatugenColors, MatugenVariation } from "lib/types/options";
/*
* NOTE: This maps the values of the default colors to the values generated by Matugen.
* Each of the variations are carefully tested and curated to make sure that colors don't
* have weird luminocity overlaps (light on light, dark on dark).
*/
export const getMatugenVariations = (matugenColors: MatugenColors, variation: MatugenVariation) => {
const matVtns = {
"standard_1": {
"rosewater": matugenColors.secondary,
"flamingo": matugenColors.secondary,
"pink": matugenColors.tertiary,
"mauve": matugenColors.primary,
"red": matugenColors.tertiary,
"maroon": matugenColors.primary,
"peach": matugenColors.tertiary,
"yellow": matugenColors.secondary,
"green": matugenColors.primary,
"teal": matugenColors.secondary,
"sky": matugenColors.secondary,
"sapphire": matugenColors.primary,
"blue": matugenColors.primary,
"lavender": matugenColors.primary,
"text": matugenColors.on_background,
"subtext1": matugenColors.outline,
"subtext2": matugenColors.outline,
"overlay2": matugenColors.outline,
"overlay1": matugenColors.outline,
"overlay0": matugenColors.outline,
"surface2": matugenColors.outline,
"surface1": matugenColors.surface_bright,
"surface0": matugenColors.surface_bright,
"base2": matugenColors.inverse_on_surface,
"base": matugenColors.inverse_on_surface,
"mantle": matugenColors.surface_dim,
"crust": matugenColors.surface_dim,
"notifications_closer": matugenColors.primary,
"notifications_background": matugenColors.surface_dim,
"dashboard_btn_text": matugenColors.surface_dim,
"red2": matugenColors.tertiary,
"pink2": matugenColors.tertiary,
"mantle2": matugenColors.surface_dim,
"surface1_2": matugenColors.inverse_on_surface,
"surface0_2": matugenColors.surface_bright,
"overlay1_2": matugenColors.outline,
"text2": matugenColors.on_background,
"lavender2": matugenColors.primary,
"crust2": matugenColors.surface_dim,
"maroon2": matugenColors.primary,
"mauve2": matugenColors.primary,
"green2": matugenColors.primary,
"surface2_2": matugenColors.surface,
"sky2": matugenColors.secondary,
"teal2": matugenColors.secondary,
"yellow2": matugenColors.secondary,
"pink3": matugenColors.tertiary,
"red3": matugenColors.tertiary,
"mantle3": matugenColors.inverse_on_surface,
"surface0_3": matugenColors.outline,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.outline,
"lavender3": matugenColors.primary,
"mauve3": matugenColors.primary,
"green3": matugenColors.primary,
"sky3": matugenColors.secondary,
"teal3": matugenColors.secondary,
"yellow3": matugenColors.secondary,
"maroon3": matugenColors.primary,
"crust3": matugenColors.surface_dim,
},
"standard_2": {
"rosewater": matugenColors.primary,
"flamingo": matugenColors.primary,
"pink": matugenColors.tertiary,
"mauve": matugenColors.secondary,
"red": matugenColors.tertiary,
"maroon": matugenColors.secondary,
"peach": matugenColors.tertiary,
"yellow": matugenColors.primary,
"green": matugenColors.secondary,
"teal": matugenColors.primary,
"sky": matugenColors.primary,
"sapphire": matugenColors.secondary,
"blue": matugenColors.secondary,
"lavender": matugenColors.secondary,
"text": matugenColors.on_background,
"subtext1": matugenColors.outline,
"subtext2": matugenColors.outline,
"overlay2": matugenColors.outline,
"overlay1": matugenColors.outline,
"overlay0": matugenColors.outline,
"surface2": matugenColors.outline,
"surface1": matugenColors.surface_bright,
"surface0": matugenColors.surface_bright,
"base2": matugenColors.inverse_on_surface,
"base": matugenColors.inverse_on_surface,
"mantle": matugenColors.surface_dim,
"crust": matugenColors.surface_dim,
"notifications_closer": matugenColors.tertiary,
"notifications_background": matugenColors.surface_dim,
"dashboard_btn_text": matugenColors.surface_dim,
"red2": matugenColors.tertiary,
"pink2": matugenColors.tertiary,
"mantle2": matugenColors.surface_dim,
"surface1_2": matugenColors.inverse_on_surface,
"surface0_2": matugenColors.surface_bright,
"overlay1_2": matugenColors.outline,
"text2": matugenColors.on_background,
"lavender2": matugenColors.secondary,
"crust2": matugenColors.surface_dim,
"maroon2": matugenColors.secondary,
"surface2_2": matugenColors.surface,
"mauve2": matugenColors.secondary,
"green2": matugenColors.secondary,
"sky2": matugenColors.primary,
"teal2": matugenColors.primary,
"yellow2": matugenColors.primary,
"pink3": matugenColors.tertiary,
"red3": matugenColors.tertiary,
"mantle3": matugenColors.inverse_on_surface,
"surface0_3": matugenColors.outline,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.outline,
"lavender3": matugenColors.secondary,
"mauve3": matugenColors.secondary,
"green3": matugenColors.secondary,
"sky3": matugenColors.primary,
"teal3": matugenColors.primary,
"yellow3": matugenColors.primary,
"maroon3": matugenColors.secondary,
"crust3": matugenColors.surface_dim,
},
"standard_3": {
"rosewater": matugenColors.secondary,
"flamingo": matugenColors.secondary,
"pink": matugenColors.secondary,
"mauve": matugenColors.primary,
"red": matugenColors.secondary,
"maroon": matugenColors.primary,
"peach": matugenColors.secondary,
"yellow": matugenColors.secondary,
"green": matugenColors.primary,
"teal": matugenColors.secondary,
"sky": matugenColors.secondary,
"sapphire": matugenColors.primary,
"blue": matugenColors.primary,
"lavender": matugenColors.primary,
"text": matugenColors.on_background,
"subtext1": matugenColors.outline,
"subtext2": matugenColors.outline,
"overlay2": matugenColors.outline,
"overlay1": matugenColors.outline,
"overlay0": matugenColors.outline,
"surface2": matugenColors.outline,
"surface1": matugenColors.surface_bright,
"surface0": matugenColors.surface_bright,
"base2": matugenColors.inverse_on_surface,
"base": matugenColors.inverse_on_surface,
"mantle": matugenColors.surface_dim,
"crust": matugenColors.surface_dim,
"notifications_closer": matugenColors.secondary,
"notifications_background": matugenColors.surface_dim,
"dashboard_btn_text": matugenColors.surface_dim,
"red2": matugenColors.secondary,
"pink2": matugenColors.secondary,
"mantle2": matugenColors.surface_dim,
"surface1_2": matugenColors.inverse_on_surface,
"surface0_2": matugenColors.surface_bright,
"surface2_2": matugenColors.surface,
"overlay1_2": matugenColors.outline,
"text2": matugenColors.on_background,
"lavender2": matugenColors.primary,
"crust2": matugenColors.surface_dim,
"maroon2": matugenColors.primary,
"mauve2": matugenColors.primary,
"green2": matugenColors.primary,
"sky2": matugenColors.secondary,
"teal2": matugenColors.secondary,
"yellow2": matugenColors.secondary,
"pink3": matugenColors.secondary,
"red3": matugenColors.secondary,
"mantle3": matugenColors.inverse_on_surface,
"surface0_3": matugenColors.outline,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.outline,
"lavender3": matugenColors.primary,
"mauve3": matugenColors.primary,
"green3": matugenColors.primary,
"sky3": matugenColors.secondary,
"teal3": matugenColors.secondary,
"yellow3": matugenColors.secondary,
"maroon3": matugenColors.primary,
"crust3": matugenColors.surface_dim,
},
"vivid_1": {
"rosewater": matugenColors.surface,
"flamingo": matugenColors.surface,
"pink": matugenColors.surface,
"mauve": matugenColors.surface,
"red": matugenColors.surface,
"maroon": matugenColors.surface,
"peach": matugenColors.surface,
"yellow": matugenColors.surface,
"green": matugenColors.surface,
"teal": matugenColors.surface,
"sky": matugenColors.surface,
"sapphire": matugenColors.surface,
"blue": matugenColors.surface,
"lavender": matugenColors.surface,
"text": matugenColors.surface,
"subtext1": matugenColors.primary_container,
"subtext2": matugenColors.primary_container,
"overlay2": matugenColors.primary_container,
"overlay1": matugenColors.primary_container,
"overlay0": matugenColors.primary_container,
"surface2": matugenColors.surface_container_high,
"surface1": matugenColors.surface_container_high,
"surface0": matugenColors.surface_container_high,
"base2": matugenColors.primary,
"base": matugenColors.primary,
"mantle": matugenColors.surface_container_low,
"crust": matugenColors.surface_container_lowest,
"red2": matugenColors.primary_container,
"pink2": matugenColors.primary_container,
"mantle2": matugenColors.primary,
"surface1_2": matugenColors.primary,
"surface0_2": matugenColors.primary,
"overlay1_2": matugenColors.surface_container_high,
"text2": matugenColors.outline,
"lavender2": matugenColors.primary_container,
"crust2": matugenColors.primary,
"maroon2": matugenColors.primary_container,
"mauve2": matugenColors.primary_container,
"surface2_2": matugenColors.primary_container,
"green2": matugenColors.primary_container,
"sky2": matugenColors.primary_container,
"teal2": matugenColors.primary_container,
"yellow2": matugenColors.primary_container,
"pink3": matugenColors.primary_fixed,
"red3": matugenColors.primary,
"mantle3": matugenColors.primary,
"surface0_3": matugenColors.primary,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.primary,
"lavender3": matugenColors.primary,
"mauve3": matugenColors.primary,
"green3": matugenColors.primary_fixed,
"sky3": matugenColors.primary,
"teal3": matugenColors.primary,
"yellow3": matugenColors.primary_fixed,
"maroon3": matugenColors.primary_fixed,
"crust3": matugenColors.primary,
},
"vivid_2": {
"rosewater": matugenColors.surface,
"flamingo": matugenColors.surface,
"pink": matugenColors.surface,
"mauve": matugenColors.surface,
"red": matugenColors.surface,
"maroon": matugenColors.surface,
"peach": matugenColors.surface,
"yellow": matugenColors.surface,
"green": matugenColors.surface,
"teal": matugenColors.surface,
"sky": matugenColors.surface,
"sapphire": matugenColors.surface,
"blue": matugenColors.surface,
"lavender": matugenColors.surface,
"text": matugenColors.surface,
"subtext1": matugenColors.secondary_container,
"subtext2": matugenColors.secondary_container,
"overlay2": matugenColors.secondary_container,
"overlay1": matugenColors.secondary_container,
"overlay0": matugenColors.secondary_container,
"surface2": matugenColors.surface_container_high,
"surface1": matugenColors.surface_container_high,
"surface0": matugenColors.surface_container_high,
"base2": matugenColors.secondary,
"base": matugenColors.secondary,
"mantle": matugenColors.surface_container_low,
"crust": matugenColors.surface_container_lowest,
"red2": matugenColors.secondary_container,
"pink2": matugenColors.secondary_container,
"surface2_2": matugenColors.primary_container,
"mantle2": matugenColors.secondary,
"surface1_2": matugenColors.secondary,
"surface0_2": matugenColors.secondary,
"overlay1_2": matugenColors.surface_container_high,
"text2": matugenColors.outline,
"lavender2": matugenColors.secondary_container,
"crust2": matugenColors.secondary,
"maroon2": matugenColors.secondary_container,
"mauve2": matugenColors.secondary_container,
"green2": matugenColors.secondary_container,
"sky2": matugenColors.secondary_container,
"teal2": matugenColors.secondary_container,
"yellow2": matugenColors.secondary_container,
"pink3": matugenColors.secondary_fixed,
"red3": matugenColors.secondary,
"mantle3": matugenColors.secondary,
"surface0_3": matugenColors.secondary,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.secondary,
"lavender3": matugenColors.secondary,
"mauve3": matugenColors.secondary,
"green3": matugenColors.secondary_fixed,
"sky3": matugenColors.secondary,
"teal3": matugenColors.secondary,
"yellow3": matugenColors.secondary_fixed,
"maroon3": matugenColors.secondary_fixed,
"crust3": matugenColors.secondary,
},
"vivid_3": {
"rosewater": matugenColors.surface,
"flamingo": matugenColors.surface,
"pink": matugenColors.surface,
"mauve": matugenColors.surface,
"red": matugenColors.surface,
"maroon": matugenColors.surface,
"peach": matugenColors.surface,
"yellow": matugenColors.surface,
"green": matugenColors.surface,
"teal": matugenColors.surface,
"sky": matugenColors.surface,
"sapphire": matugenColors.surface,
"blue": matugenColors.surface,
"lavender": matugenColors.surface,
"text": matugenColors.surface,
"subtext1": matugenColors.tertiary_container,
"subtext2": matugenColors.tertiary_container,
"overlay2": matugenColors.tertiary_container,
"overlay1": matugenColors.tertiary_container,
"overlay0": matugenColors.tertiary_container,
"surface2": matugenColors.surface_container_high,
"surface1": matugenColors.surface_container_high,
"surface0": matugenColors.surface_container_high,
"base2": matugenColors.tertiary,
"base": matugenColors.tertiary,
"mantle": matugenColors.surface_container_low,
"crust": matugenColors.surface_container_lowest,
"red2": matugenColors.tertiary_container,
"pink2": matugenColors.tertiary_container,
"mantle2": matugenColors.tertiary,
"surface1_2": matugenColors.tertiary,
"surface0_2": matugenColors.tertiary,
"overlay1_2": matugenColors.surface_container_high,
"text2": matugenColors.outline,
"lavender2": matugenColors.tertiary_container,
"surface2_2": matugenColors.primary_container,
"crust2": matugenColors.tertiary,
"maroon2": matugenColors.tertiary_container,
"mauve2": matugenColors.tertiary_container,
"green2": matugenColors.tertiary_container,
"sky2": matugenColors.tertiary_container,
"teal2": matugenColors.tertiary_container,
"yellow2": matugenColors.tertiary_container,
"pink3": matugenColors.tertiary_fixed,
"red3": matugenColors.tertiary,
"mantle3": matugenColors.tertiary,
"surface0_3": matugenColors.tertiary,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.tertiary,
"lavender3": matugenColors.tertiary,
"mauve3": matugenColors.tertiary,
"green3": matugenColors.tertiary_fixed,
"sky3": matugenColors.tertiary,
"teal3": matugenColors.tertiary,
"yellow3": matugenColors.tertiary_fixed,
"maroon3": matugenColors.tertiary_fixed,
"crust3": matugenColors.tertiary,
},
"monochrome_1": {
"rosewater": matugenColors.primary,
"flamingo": matugenColors.primary,
"pink": matugenColors.primary,
"mauve": matugenColors.primary,
"red": matugenColors.primary,
"maroon": matugenColors.primary,
"peach": matugenColors.primary,
"yellow": matugenColors.primary,
"green": matugenColors.primary,
"teal": matugenColors.primary,
"sky": matugenColors.primary,
"sapphire": matugenColors.primary,
"blue": matugenColors.primary,
"lavender": matugenColors.primary,
"text": matugenColors.on_background,
"subtext1": matugenColors.outline,
"subtext2": matugenColors.outline,
"overlay2": matugenColors.outline,
"overlay1": matugenColors.outline,
"overlay0": matugenColors.outline,
"surface2": matugenColors.outline,
"surface1": matugenColors.surface_bright,
"surface0": matugenColors.surface_bright,
"base2": matugenColors.inverse_on_surface,
"base": matugenColors.inverse_on_surface,
"mantle": matugenColors.surface_dim,
"crust": matugenColors.surface_dim,
"notifications_closer": matugenColors.primary,
"notifications_background": matugenColors.surface_dim,
"dashboard_btn_text": matugenColors.surface_dim,
"red2": matugenColors.primary,
"pink2": matugenColors.primary,
"mantle2": matugenColors.surface_dim,
"surface1_2": matugenColors.inverse_on_surface,
"surface0_2": matugenColors.surface_bright,
"surface2_2": matugenColors.surface,
"overlay1_2": matugenColors.outline,
"text2": matugenColors.on_background,
"lavender2": matugenColors.primary,
"crust2": matugenColors.surface_dim,
"maroon2": matugenColors.primary,
"mauve2": matugenColors.primary,
"green2": matugenColors.primary,
"sky2": matugenColors.primary,
"teal2": matugenColors.primary,
"yellow2": matugenColors.primary,
"pink3": matugenColors.primary,
"red3": matugenColors.primary,
"mantle3": matugenColors.inverse_on_surface,
"surface0_3": matugenColors.outline,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.outline,
"lavender3": matugenColors.primary,
"mauve3": matugenColors.primary,
"green3": matugenColors.primary,
"sky3": matugenColors.primary,
"teal3": matugenColors.primary,
"yellow3": matugenColors.primary,
"maroon3": matugenColors.primary,
"crust3": matugenColors.surface_dim,
},
"monochrome_2": {
"rosewater": matugenColors.secondary,
"flamingo": matugenColors.secondary,
"pink": matugenColors.secondary,
"mauve": matugenColors.secondary,
"red": matugenColors.secondary,
"maroon": matugenColors.secondary,
"peach": matugenColors.secondary,
"yellow": matugenColors.secondary,
"green": matugenColors.secondary,
"teal": matugenColors.secondary,
"sky": matugenColors.secondary,
"sapphire": matugenColors.secondary,
"blue": matugenColors.secondary,
"lavender": matugenColors.secondary,
"text": matugenColors.on_background,
"subtext1": matugenColors.outline,
"subtext2": matugenColors.outline,
"overlay2": matugenColors.outline,
"overlay1": matugenColors.outline,
"overlay0": matugenColors.outline,
"surface2": matugenColors.outline,
"surface1": matugenColors.surface_bright,
"surface0": matugenColors.surface_bright,
"base2": matugenColors.inverse_on_surface,
"base": matugenColors.inverse_on_surface,
"mantle": matugenColors.surface_dim,
"crust": matugenColors.surface_dim,
"notifications_closer": matugenColors.secondary,
"notifications_background": matugenColors.surface_dim,
"dashboard_btn_text": matugenColors.surface_dim,
"red2": matugenColors.secondary,
"pink2": matugenColors.secondary,
"mantle2": matugenColors.surface_dim,
"surface1_2": matugenColors.inverse_on_surface,
"surface0_2": matugenColors.surface_bright,
"overlay1_2": matugenColors.outline,
"surface2_2": matugenColors.surface,
"text2": matugenColors.on_background,
"lavender2": matugenColors.secondary,
"crust2": matugenColors.surface_dim,
"maroon2": matugenColors.secondary,
"mauve2": matugenColors.secondary,
"green2": matugenColors.secondary,
"sky2": matugenColors.secondary,
"teal2": matugenColors.secondary,
"yellow2": matugenColors.secondary,
"pink3": matugenColors.secondary,
"red3": matugenColors.secondary,
"mantle3": matugenColors.inverse_on_surface,
"surface0_3": matugenColors.outline,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.outline,
"lavender3": matugenColors.secondary,
"mauve3": matugenColors.secondary,
"green3": matugenColors.secondary,
"sky3": matugenColors.secondary,
"teal3": matugenColors.secondary,
"yellow3": matugenColors.secondary,
"maroon3": matugenColors.secondary,
"crust3": matugenColors.surface_dim,
},
"monochrome_3": {
"rosewater": matugenColors.tertiary,
"flamingo": matugenColors.tertiary,
"pink": matugenColors.tertiary,
"mauve": matugenColors.tertiary,
"red": matugenColors.tertiary,
"maroon": matugenColors.tertiary,
"peach": matugenColors.tertiary,
"yellow": matugenColors.tertiary,
"green": matugenColors.tertiary,
"teal": matugenColors.tertiary,
"sky": matugenColors.tertiary,
"sapphire": matugenColors.tertiary,
"blue": matugenColors.tertiary,
"lavender": matugenColors.tertiary,
"text": matugenColors.on_background,
"subtext1": matugenColors.outline,
"subtext2": matugenColors.outline,
"overlay2": matugenColors.outline,
"overlay1": matugenColors.outline,
"overlay0": matugenColors.outline,
"surface2": matugenColors.outline,
"surface1": matugenColors.surface_bright,
"surface0": matugenColors.surface_bright,
"base2": matugenColors.inverse_on_surface,
"base": matugenColors.inverse_on_surface,
"mantle": matugenColors.surface_dim,
"crust": matugenColors.surface_dim,
"notifications_closer": matugenColors.tertiary,
"notifications_background": matugenColors.surface_dim,
"dashboard_btn_text": matugenColors.surface_dim,
"red2": matugenColors.tertiary,
"pink2": matugenColors.tertiary,
"mantle2": matugenColors.surface_dim,
"surface1_2": matugenColors.inverse_on_surface,
"surface0_2": matugenColors.surface_bright,
"overlay1_2": matugenColors.outline,
"text2": matugenColors.on_background,
"lavender2": matugenColors.tertiary,
"crust2": matugenColors.surface_dim,
"maroon2": matugenColors.tertiary,
"surface2_2": matugenColors.surface,
"mauve2": matugenColors.tertiary,
"green2": matugenColors.tertiary,
"sky2": matugenColors.tertiary,
"teal2": matugenColors.tertiary,
"yellow2": matugenColors.tertiary,
"pink3": matugenColors.tertiary,
"red3": matugenColors.tertiary,
"mantle3": matugenColors.inverse_on_surface,
"surface0_3": matugenColors.outline,
"surface2_3": matugenColors.outline,
"overlay1_3": matugenColors.outline,
"lavender3": matugenColors.tertiary,
"mauve3": matugenColors.tertiary,
"green3": matugenColors.tertiary,
"sky3": matugenColors.tertiary,
"teal3": matugenColors.tertiary,
"yellow3": matugenColors.tertiary,
"maroon3": matugenColors.tertiary,
"crust3": matugenColors.surface_dim,
},
};
return matVtns[variation];
}

46
scss/options_trackers.ts Normal file
View File

@@ -0,0 +1,46 @@
import icons from "lib/icons";
import { Notify, isAnImage } from "lib/utils";
import options from "options";
import Wallpaper from "services/Wallpaper";
const { matugen } = options.theme;
const { mode, scheme_type, contrast } = options.theme.matugen_settings;
const ensureMatugenWallpaper = (): void => {
const wallpaperPath = options.wallpaper.image.value;
if (matugen.value && (!options.wallpaper.image.value.length || !isAnImage(wallpaperPath))) {
Notify({
summary: "Matugen Failed",
body: "Please select a wallpaper in 'Theming > General' first.",
iconName: icons.ui.warning,
timeout: 7000
})
matugen.value = false;
}
}
export const initializeTrackers = (resetCssFunc: Function) => {
matugen.connect("changed", () => {
ensureMatugenWallpaper();
options.resetTheme();
})
mode.connect("changed", () => {
options.resetTheme();
})
scheme_type.connect("changed", () => {
options.resetTheme();
})
contrast.connect("changed", () => {
options.resetTheme();
})
Wallpaper.connect("changed", () => {
if (options.theme.matugen.value) {
options.resetTheme();
resetCssFunc();
}
})
}

View File

@@ -1,7 +1,8 @@
/* eslint-disable max-len */ import options from "options";
import { type Opt } from "lib/option" import { bash, dependencies } from "lib/utils";
import options from "options" import { MatugenColors } from "lib/types/options";
import { bash, dependencies } from "lib/utils" import { initializeTrackers } from "./options_trackers";
import { generateMatugenColors, replaceHexValues } from "./matugen/index";
const deps = [ const deps = [
"font", "font",
@@ -10,53 +11,58 @@ const deps = [
"bar.position", "bar.position",
"bar.battery.charging", "bar.battery.charging",
"bar.battery.blocks", "bar.battery.blocks",
] ];
const $ = (name: string, value: string | Opt<any>) => `$${name}: ${value};` function extractVariables(theme: typeof options.theme, prefix = "", matugenColors: MatugenColors | undefined) {
let result = [] as string[];
function extractVariables(theme: any, prefix: string = ""): string[] {
let result: string[] = [];
for (let key in theme) { for (let key in theme) {
if (theme.hasOwnProperty(key)) { if (theme.hasOwnProperty(key)) {
const value = theme[key]; const value = theme[key];
const newPrefix = prefix ? `${prefix}-${key}` : key; const newPrefix = prefix ? `${prefix}-${key}` : key;
const isColor = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value.value);
const replacedValue = isColor && matugenColors !== undefined ? replaceHexValues(value.value, matugenColors) : value.value;
if (typeof value === 'object' && value !== null && !Array.isArray(value)) { if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
// Check if the object contains an Opt value or is a nested object
if (typeof value.value !== 'undefined') { if (typeof value.value !== 'undefined') {
result.push($(`${newPrefix}`, `${value.value}`)); result.push(`$${newPrefix}: ${replacedValue};`);
} else { } else {
result = result.concat(extractVariables(value, newPrefix)); result = result.concat(extractVariables(value, newPrefix, matugenColors));
} }
} else if (typeof value === 'function' && value.name === 'opt') { } else if (typeof value === 'function' && value.name === 'opt') {
result.push($(`${newPrefix}`, value)); result.push(`$${newPrefix}: ${replacedValue};`);
} }
} }
} }
return result; return result;
} }
const variables = () => [
...extractVariables(options.theme),
];
async function resetCss() { async function resetCss() {
if (!dependencies("sass")) if (!dependencies("sass")) return;
return
try { try {
const matugenColors = await generateMatugenColors();
const variables = [
...extractVariables(options.theme, '', matugenColors),
];
const vars = `${TMP}/variables.scss` const vars = `${TMP}/variables.scss`
const css = `${TMP}/main.css` const css = `${TMP}/main.css`
const scss = `${TMP}/entry.scss` const scss = `${TMP}/entry.scss`
const localScss = `${App.configDir}/scss/main.scss`; const localScss = `${App.configDir}/scss/main.scss`;
await Utils.writeFile(variables().join("\n"), vars) const themeVariables = variables;
const imports = [vars].map(f => `@import '${f}';`) const integratedVariables = themeVariables;
const imports = [vars].map(f => `@import '${f}';`);
await Utils.writeFile(integratedVariables.join("\n"), vars);
let mainScss = Utils.readFile(localScss); let mainScss = Utils.readFile(localScss);
mainScss = `${imports}\n${mainScss}`; mainScss = `${imports}\n${mainScss}`;
await Utils.writeFile(mainScss, scss) await Utils.writeFile(mainScss, scss);
await bash(`sass --load-path=${App.configDir}/scss/ ${scss} ${css}`); await bash(`sass --load-path=${App.configDir}/scss/ ${scss} ${css}`);
@@ -64,10 +70,12 @@ async function resetCss() {
} catch (error) { } catch (error) {
error instanceof Error error instanceof Error
? logError(error) ? logError(error)
: console.error(error) : console.error(error);
} }
} }
Utils.monitorFile(`${App.configDir}/scss/style`, resetCss) initializeTrackers(resetCss);
options.handler(deps, resetCss)
await resetCss() Utils.monitorFile(`${App.configDir}/scss/style`, resetCss);
options.handler(deps, resetCss);
await resetCss();

View File

@@ -42,7 +42,7 @@
} }
&.underline { &.underline {
border-bottom: 0.1em solid $pink; border-bottom: 0.1em solid $bar-buttons-workspaces-numbered_active_text_color;
} }
&.highlight { &.highlight {

View File

@@ -62,6 +62,11 @@
} }
} }
.menu-active-percentage.playback,
.menu-active-percentage.input {
color: if($bar-menus-monochrome, $bar-menus-text, $bar-menus-menu-volume-text);
}
.menu-active-button { .menu-active-button {
.menu-active-icon.playback, .menu-active-icon.playback,
@@ -120,7 +125,7 @@
.menu-button-name.playback, .menu-button-name.playback,
.menu-button-name.input { .menu-button-name.input {
color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-volume-icons-active); color: if($bar-menus-monochrome, $bar-menus-listitems-active, $bar-menus-menu-volume-listitems-active);
} }
} }
} }

View File

@@ -44,7 +44,7 @@
} }
image { image {
color: $base; color: if($bar-menus-monochrome, $bar-menus-buttons-text, $bar-menus-menu-dashboard-shortcuts-text);
font-size: 1.5em; font-size: 1.5em;
} }

View File

@@ -17,8 +17,9 @@
background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-battery-card-color); background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-battery-card-color);
} }
.power-profile-item { .power-profile-item {
margin-bottom: 0.5em; color: if($bar-menus-monochrome, $bar-menus-listitems-passive, $bar-menus-menu-battery-listitems-passive);
margin-bottom: 0.5em;
label { label {
margin-left: 1em; margin-left: 1em;
@@ -31,40 +32,43 @@
color: if($bar-menus-monochrome, $bar-menus-icons-passive, $bar-menus-menu-battery-icons-passive); color: if($bar-menus-monochrome, $bar-menus-icons-passive, $bar-menus-menu-battery-icons-passive);
} }
&:hover { &:hover {
label { color: if($bar-menus-monochrome, $bar-menus-listitems-active, $bar-menus-menu-battery-listitems-active);
color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active); label {
} color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active);
}
image { image {
color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active); color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active);
} }
} }
&.active { &.active {
image { color: if($bar-menus-monochrome, $bar-menus-listitems-active, $bar-menus-menu-battery-listitems-active);
color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active); image {
} color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active);
}
}
} }
}
.brightness-container { .brightness-container {
padding-bottom: 1em; padding-bottom: 1em;
} }
.brightness-slider-icon { .brightness-slider-icon {
font-size: 1.4em; font-size: 1.4em;
min-width: 1em; min-width: 1em;
min-height: 1em; min-height: 1em;
color: $overlay2; color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-battery-icons-active);
} }
.brightness-slider-label { .brightness-slider-label {
font-size: 0.9em; color: if($bar-menus-monochrome, $bar-menus-text, $bar-menus-menu-battery-text);
min-width: 2.5em; font-size: 0.9em;
font-weight: bold; min-width: 2.5em;
margin-bottom: 0.2em; font-weight: bold;
} margin-bottom: 0.2em;
}
.menu-slider.brightness { .menu-slider.brightness {
trough { trough {

View File

@@ -108,6 +108,7 @@
} }
.menu-icon-button.network.disconnect { .menu-icon-button.network.disconnect {
color: if($bar-menus-monochrome, $bar-menus-iconbuttons-passive, $bar-menus-menu-network-iconbuttons-passive);
margin: 0em; margin: 0em;
margin-top: -0.2em; margin-top: -0.2em;
margin-left: 1em; margin-left: 1em;

View File

@@ -2,7 +2,7 @@ window.settings-dialog {
background-color: $bar-menus-cards; background-color: $bar-menus-cards;
color: $bar-menus-text; color: $bar-menus-text;
$padding: 1em; $padding: 0.5em;
$primary_bg: $bar-menus-background; $primary_bg: $bar-menus-background;
$spacing: 0.4em; $spacing: 0.4em;
$radius: 0.5em; $radius: 0.5em;
@@ -10,10 +10,14 @@ window.settings-dialog {
$border: none; $border: none;
$fg: $bar-menus-text; $fg: $bar-menus-text;
.settings-dialog-box {
min-width: 75em;
}
.header { .header {
background-color: $bar-menus-background; background-color: transparentize($bar-menus-background, 0.1);
border-bottom-left-radius: $bar-menus-border-radius/2;
border-bottom-right-radius: $bar-menus-border-radius/2;
padding: $padding; padding: $padding;
button { button {
@@ -57,7 +61,7 @@ window.settings-dialog {
.group { .group {
.group-title { .group-title {
color: $primary-bg; color: $bar-menus-text;
margin-bottom: $spacing*.5; margin-bottom: $spacing*.5;
} }
@@ -178,7 +182,7 @@ window.settings-dialog {
} }
padding: 0.35em 0.35em; padding: 0.35em 0.35em;
background: $surface1; background: transparentize($bar-menus-background, 0.6);
margin-right: 1em; margin-right: 1em;
} }
} }
@@ -194,6 +198,7 @@ window.settings-dialog {
} }
.pager-button { .pager-button {
color: transparentize($bar-menus-text, 0.4);
margin: 0.5em 0.75em; margin: 0.5em 0.75em;
&.category label { &.category label {
@@ -201,11 +206,17 @@ window.settings-dialog {
} }
&:hover { &:hover {
color: $bar-menus-iconbuttons-active; label {
text-decoration: underline;
color: $bar-menus-text;
}
} }
&.active { &.active {
color: $bar-menus-iconbuttons-active; label {
text-decoration: underline;
color: $bar-menus-text;
}
} }
} }
@@ -219,7 +230,7 @@ window.settings-dialog {
.paged-container { .paged-container {
.reset-options { .reset-options {
color: $bar-menus-iconbuttons-passive; color: $bar-menus-text;
image:disabled { image:disabled {
color: $bar-menus-buttons-disabled; color: $bar-menus-buttons-disabled;
@@ -227,7 +238,7 @@ window.settings-dialog {
&:hover { &:hover {
image { image {
color: $bar-menus-buttons-active; color: transparentize($bar-menus-text, 0.5);
} }
} }
} }
@@ -246,7 +257,8 @@ window.settings-dialog {
} }
selection { selection {
background: $bar-menus-background; background: $bar-menus-label;
color: $bar-menus-cards;
} }
switch { switch {
@@ -272,6 +284,12 @@ window.settings-dialog {
dialog { dialog {
background: $bar-menus-cards; background: $bar-menus-cards;
color: $bar-menus-text;
:selected {
background: transparentize($bar-menus-label, 0.2);
color: transparentize($bar-menus-cards, 0.2);
}
headerbar { headerbar {
border-bottom: 0.075em solid $bar-menus-border-color; border-bottom: 0.075em solid $bar-menus-border-color;

64
services/Wallpaper.ts Normal file
View File

@@ -0,0 +1,64 @@
import { dependencies, sh } from "lib/utils"
const hyprland = await Service.import("hyprland");
const WP = `${Utils.HOME}/.config/background`
class Wallpaper extends Service {
static {
Service.register(this, {}, {
"wallpaper": ["string"],
})
}
#blockMonitor = false
#wallpaper() {
if (!dependencies("swww"))
return
hyprland.monitors.map(m => m.name);
sh("hyprctl cursorpos").then(pos => {
sh([
"swww", "img",
"--invert-y",
"--transition-type", "grow",
"--transition-duration", "1.5",
"--transition-fps", "30",
"--transition-pos", pos.replace(" ", ""),
WP,
]).then(() => {
this.changed("wallpaper")
})
})
}
async #setWallpaper(path: string) {
this.#blockMonitor = true
await sh(`cp ${path} ${WP}`)
this.#wallpaper()
this.#blockMonitor = false
}
readonly set = (path: string) => { this.#setWallpaper(path) }
get wallpaper() { return WP }
constructor() {
super()
if (!dependencies("swww"))
return this
Utils.monitorFile(WP, () => {
if (!this.#blockMonitor)
this.#wallpaper()
})
Utils.execAsync("swww-daemon")
.then(this.#wallpaper)
.catch(() => null)
}
}
export default new Wallpaper

View File

@@ -83,6 +83,7 @@ export default () => RegularWindow({
win.set_default_size(200, 300) win.set_default_size(200, 300)
}, },
child: Widget.Box({ child: Widget.Box({
class_name: "settings-dialog-box",
vertical: true, vertical: true,
children: [ children: [
Header(), Header(),

View File

@@ -11,7 +11,7 @@ export const BarGeneral = () => {
Header('General Settings'), Header('General Settings'),
Option({ opt: options.theme.font.name, title: 'Font', type: 'font' }), Option({ opt: options.theme.font.name, title: 'Font', type: 'font' }),
Option({ opt: options.theme.font.size, title: 'Font Size', type: 'string' }), Option({ opt: options.theme.font.size, title: 'Font Size', type: 'string' }),
Option({ opt: options.theme.font.weight, title: 'Font Weight', subtitle: "100, 200, 300, etc.", type: 'number', increment: 100, min: 100, max: 900}), Option({ opt: options.theme.font.weight, title: 'Font Weight', subtitle: "100, 200, 300, etc.", type: 'number', increment: 100, min: 100, max: 900 }),
Option({ opt: options.terminal, title: 'Terminal', subtitle: "Tools such as 'btop' will open in this terminal", type: 'string' }), Option({ opt: options.terminal, title: 'Terminal', subtitle: "Tools such as 'btop' will open in this terminal", type: 'string' }),
Header('On Screen Display'), Header('On Screen Display'),

View File

@@ -14,7 +14,7 @@ export const BarTheme = () => {
Header('General'), Header('General'),
Option({ opt: options.theme.bar.transparent, title: 'Transparent', type: 'boolean' }), Option({ opt: options.theme.bar.transparent, title: 'Transparent', type: 'boolean' }),
Option({ opt: options.theme.bar.background, title: 'Background Color', type: 'color' }), Option({ opt: options.theme.bar.background, title: 'Background Color', type: 'color' }),
Option({ opt: options.theme.bar.buttons.monochrome, title: 'Use Global Colors', type: 'boolean' }), Option({ opt: options.theme.bar.buttons.monochrome, title: 'Use Global Colors', type: 'boolean', disabledBinding: options.theme.matugen }),
Option({ opt: options.theme.bar.buttons.background, title: 'Button Background', type: 'color' }), Option({ opt: options.theme.bar.buttons.background, title: 'Button Background', type: 'color' }),
Option({ opt: options.theme.bar.buttons.hover, title: 'Button Hover', type: 'color' }), Option({ opt: options.theme.bar.buttons.hover, title: 'Button Hover', type: 'color' }),
Option({ opt: options.theme.bar.buttons.text, title: 'Button Text', type: 'color' }), Option({ opt: options.theme.bar.buttons.text, title: 'Button Text', type: 'color' }),

View File

@@ -11,8 +11,10 @@ import { NotificationsMenuTheme } from "./menus/notifications";
import { SystrayMenuTheme } from "./menus/systray"; import { SystrayMenuTheme } from "./menus/systray";
import { VolumeMenuTheme } from "./menus/volume"; import { VolumeMenuTheme } from "./menus/volume";
import { OsdTheme } from "./osd/index"; import { OsdTheme } from "./osd/index";
import { Matugen } from "./menus/matugen";
type Page = "General Settings" type Page = "General Settings"
| "Matugen Settings"
| "Bar" | "Bar"
| "Notifications" | "Notifications"
| "OSD" | "OSD"
@@ -30,6 +32,7 @@ const CurrentPage = Variable<Page>("General Settings");
const pagerMap: Page[] = [ const pagerMap: Page[] = [
"General Settings", "General Settings",
"Matugen Settings",
"Bar", "Bar",
"Notifications", "Notifications",
"OSD", "OSD",
@@ -75,6 +78,7 @@ export const ThemesMenu = () => {
class_name: "themes-menu-stack", class_name: "themes-menu-stack",
children: { children: {
"General Settings": MenuTheme(), "General Settings": MenuTheme(),
"Matugen Settings": Matugen(),
"Bar": BarTheme(), "Bar": BarTheme(),
"Notifications": NotificationsTheme(), "Notifications": NotificationsTheme(),
"OSD": OsdTheme(), "OSD": OsdTheme(),

View File

@@ -13,7 +13,8 @@ export const MenuTheme = () => {
vertical: true, vertical: true,
children: [ children: [
Header('General'), Header('General'),
Option({ opt: options.theme.bar.menus.monochrome, title: 'Use Global Colors', type: 'boolean' }), Option({ opt: options.theme.bar.menus.monochrome, title: 'Use Global Colors', type: 'boolean', disabledBinding: options.theme.matugen }),
Option({ opt: options.wallpaper.image, title: 'Wallpaper', subtitle: options.wallpaper.image.bind("value"), type: 'wallpaper' }),
Option({ opt: options.theme.bar.menus.background, title: 'Background Color', type: 'color' }), Option({ opt: options.theme.bar.menus.background, title: 'Background Color', type: 'color' }),
Option({ opt: options.theme.bar.menus.cards, title: 'Cards', type: 'color' }), Option({ opt: options.theme.bar.menus.cards, title: 'Cards', type: 'color' }),
Option({ opt: options.theme.bar.menus.card_radius, title: 'Card Radius', type: 'string' }), Option({ opt: options.theme.bar.menus.card_radius, title: 'Card Radius', type: 'string' }),

View File

@@ -0,0 +1,53 @@
import { Option } from "widget/settings/shared/Option";
import { Header } from "widget/settings/shared/Header";
import options from "options";
export const Matugen = () => {
return Widget.Scrollable({
vscroll: "automatic",
hscroll: "automatic",
class_name: "menu-theme-page paged-container",
vexpand: true,
child: Widget.Box({
vertical: true,
children: [
Header('Matugen Settings'),
Option({ opt: options.theme.matugen, title: 'Enable Matugen', subtitle: 'WARNING: THIS WILL REPLACE YOUR CURRENT COLOR SCHEME!!!', type: 'boolean', dependencies: ["matugen", "swww"] }),
Option({ opt: options.theme.matugen_settings.mode, title: 'Matugen Theme', type: 'enum', enums: ["light", "dark"] }),
Option({
opt: options.theme.matugen_settings.scheme_type,
title: 'Matugen Scheme',
type: 'enum',
enums: [
"content",
"expressive",
"fidelity",
"fruit-salad",
"monochrome",
"neutral",
"rainbow",
"tonal-spot"
]
}),
Option({
opt: options.theme.matugen_settings.variation,
title: 'Matugen Variation',
type: 'enum',
enums: [
"standard_1",
"standard_2",
"standard_3",
"monochrome_1",
"monochrome_2",
"monochrome_3",
"vivid_1",
"vivid_2",
"vivid_3",
]
}),
Option({ opt: options.theme.matugen_settings.contrast, title: 'Contrast', subtitle: 'Range: -1 to 1 (Default: 0)', type: 'float' }),
]
})
})
}

View File

@@ -3,6 +3,8 @@ import Gdk from "gi://Gdk"
import icons from "lib/icons" import icons from "lib/icons"
import { RowProps } from "lib/types/options" import { RowProps } from "lib/types/options"
import { Variable } from "types/variable"; import { Variable } from "types/variable";
import Wallpaper from "services/Wallpaper";
import { dependencies as checkDependencies } from "lib/utils";
const EnumSetter = (opt: Opt<string>, values: string[]) => { const EnumSetter = (opt: Opt<string>, values: string[]) => {
const lbl = Widget.Label({ label: opt.bind().as(v => `${v}`) }) const lbl = Widget.Label({ label: opt.bind().as(v => `${v}`) })
@@ -33,7 +35,9 @@ export const Inputter = <T>({
enums, enums,
max = 1000000, max = 1000000,
min = 0, min = 0,
increment = 1 increment = 1,
disabledBinding,
dependencies,
}: RowProps<T>, }: RowProps<T>,
className: string, className: string,
isUnsaved: Variable<boolean> isUnsaved: Variable<boolean>
@@ -130,15 +134,35 @@ export const Inputter = <T>({
] ]
case "enum": return self.child = EnumSetter(opt as unknown as Opt<string>, enums!) case "enum": return self.child = EnumSetter(opt as unknown as Opt<string>, enums!)
case "boolean": return self.child = Widget.Switch() case "boolean": return self.child = Widget.Switch({
.on("notify::active", self => opt.value = self.active as T) sensitive: disabledBinding !== undefined ? disabledBinding.bind("value").as(disabled => !disabled) : true,
.hook(opt, self => self.active = opt.value as boolean) })
.on("notify::active", self => {
if (disabledBinding !== undefined && disabledBinding.value) {
return;
}
if (self.active && dependencies !== undefined && !dependencies.every(d => checkDependencies(d))) {
self.active = false;
return;
}
opt.value = self.active as T
})
.hook(opt, self => {
self.active = opt.value as boolean
})
case "img": return self.child = Widget.FileChooserButton({ case "img": return self.child = Widget.FileChooserButton({
class_name: "image-chooser", class_name: "image-chooser",
on_file_set: ({ uri }) => { opt.value = uri!.replace("file://", "") as T }, on_file_set: ({ uri }) => { opt.value = uri!.replace("file://", "") as T },
}) })
case "wallpaper": return self.child = Widget.FileChooserButton({
on_file_set: ({ uri }) => {
opt.value = uri!.replace("file://", "") as T;
Wallpaper.set(uri!.replace("file://", ""));
},
})
case "font": return self.child = Widget.FontButton({ case "font": return self.child = Widget.FontButton({
show_size: false, show_size: false,
use_size: false, use_size: false,

View File

@@ -3,12 +3,6 @@ import { Inputter } from "./Inputter";
import icons from "lib/icons"; import icons from "lib/icons";
import { RowProps } from "lib/types/options"; import { RowProps } from "lib/types/options";
type Option = {
title: string,
subtitle: string,
}
export const Option = <T>(props: RowProps<T>, className: string = '') => { export const Option = <T>(props: RowProps<T>, className: string = '') => {
const isUnsaved = Variable(false); const isUnsaved = Variable(false);

View File

@@ -1,6 +1,9 @@
import options from "options"; import options from "options";
const { show_numbered, show_icons } = options.bar.workspaces; const { show_numbered, show_icons } = options.bar.workspaces;
const { monochrome: monoBar } = options.theme.bar.buttons;
const { monochrome: monoMenu } = options.theme.bar.menus;
const { matugen } = options.theme;
show_numbered.connect("changed", ({ value }) => { show_numbered.connect("changed", ({ value }) => {
if (value === true) { if (value === true) {
@@ -13,3 +16,10 @@ show_icons.connect("changed", ({ value }) => {
show_numbered.value = false; show_numbered.value = false;
} }
}) })
matugen.connect("changed", ({ value }) => {
if (value === true) {
monoBar.value = false;
monoMenu.value = false;
}
})