Fix the font selector. (#660)

This commit is contained in:
Jas Singh
2024-12-28 17:55:20 -08:00
committed by GitHub
parent a7b553725c
commit 9343ae85a3
11 changed files with 303 additions and 202 deletions

View File

@@ -8,7 +8,13 @@ export const BarGeneral = (): JSX.Element => {
<scrollable name={'General'} className="bar-theme-page paged-container" vscroll={Gtk.PolicyType.AUTOMATIC}> <scrollable name={'General'} className="bar-theme-page paged-container" vscroll={Gtk.PolicyType.AUTOMATIC}>
<box vertical> <box vertical>
<Header title="General Settings" /> <Header title="General Settings" />
<Option opt={options.theme.font.name} title="Font" type="font" /> <Option
opt={options.theme.font.name}
fontLabel={options.theme.font.label}
fontStyle={options.theme.font.style}
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 <Option
opt={options.theme.font.weight} opt={options.theme.font.weight}

View File

@@ -14,6 +14,8 @@ import { Gtk } from 'astal/gtk3';
const InputField = <T extends string | number | boolean | object>({ const InputField = <T extends string | number | boolean | object>({
opt, opt,
fontStyle,
fontLabel,
type = typeof opt.get() as RowProps<T>['type'], type = typeof opt.get() as RowProps<T>['type'],
enums = [], enums = [],
disabledBinding, disabledBinding,
@@ -44,7 +46,7 @@ const InputField = <T extends string | number | boolean | object>({
case 'wallpaper': case 'wallpaper':
return <WallpaperInputter opt={opt} />; return <WallpaperInputter opt={opt} />;
case 'font': case 'font':
return <FontInputter opt={opt} />; return <FontInputter fontFamily={opt} fontLabel={fontLabel} fontStyle={fontStyle} />;
case 'color': case 'color':
return <ColorInputter opt={opt} />; return <ColorInputter opt={opt} />;
@@ -55,6 +57,8 @@ const InputField = <T extends string | number | boolean | object>({
export const Inputter = <T extends string | number | boolean | object>({ export const Inputter = <T extends string | number | boolean | object>({
opt, opt,
fontStyle,
fontLabel,
type = typeof opt.get() as RowProps<T>['type'], type = typeof opt.get() as RowProps<T>['type'],
enums, enums,
disabledBinding, disabledBinding,
@@ -71,6 +75,8 @@ export const Inputter = <T extends string | number | boolean | object>({
<InputField <InputField
type={type} type={type}
opt={opt} opt={opt}
fontStyle={fontStyle}
fontLabel={fontLabel}
enums={enums} enums={enums}
disabledBinding={disabledBinding} disabledBinding={disabledBinding}
dependencies={dependencies} dependencies={dependencies}

View File

@@ -10,6 +10,8 @@ export const SettingInput = <T extends string | number | boolean | object>({
return ( return (
<Inputter <Inputter
opt={props.opt} opt={props.opt}
fontStyle={props.fontStyle}
fontLabel={props.fontLabel}
type={props.type} type={props.type}
enums={props.enums} enums={props.enums}
disabledBinding={props.disabledBinding} disabledBinding={props.disabledBinding}

View File

@@ -1,23 +0,0 @@
import FontButton from 'src/components/shared/FontButton';
import { Opt } from 'src/lib/option';
export const FontInputter = <T extends string | number | boolean | object>({
opt,
}: FontInputterProps<T>): JSX.Element => {
return (
<FontButton
showSize={false}
useSize={false}
setup={(self) => {
self.font = opt.get() as string;
self.hook(opt, () => (self.font = opt.get() as string));
self.connect('font-set', ({ font }) => opt.set(font!.split(' ').slice(0, -1).join(' ') as T));
}}
/>
);
};
interface FontInputterProps<T> {
opt: Opt<T>;
}

View File

@@ -0,0 +1,43 @@
import FontButton from 'src/components/shared/FontButton';
import { Opt } from 'src/lib/option';
import { styleToString } from './utils';
export const FontInputter = <T extends string | number | boolean | object>({
fontFamily,
fontStyle,
fontLabel,
}: FontInputterProps<T>): JSX.Element => (
<FontButton
showSize={false}
useSize={false}
setup={(self) => {
self.font = fontLabel?.get() ?? (fontFamily.get() as string);
if (fontLabel) {
self.hook(fontLabel, () => {
self.font = fontLabel.get() as string;
});
} else {
self.hook(fontFamily, () => {
self.font = fontFamily.get() as string;
});
}
self.connect('font-set', ({ fontDesc, font }) => {
const selectedFontFamily = fontDesc.get_family();
const selectedFontStyle = styleToString(fontDesc.get_style());
fontFamily.set(selectedFontFamily as T);
fontStyle?.set(selectedFontStyle);
fontLabel?.set(font.split(' ').slice(0, -1).join(' '));
});
}}
/>
);
interface FontInputterProps<T> {
fontFamily: Opt<T>;
fontStyle?: Opt<string>;
fontLabel?: Opt<string>;
}

View File

@@ -0,0 +1,72 @@
import Pango from 'gi://Pango?version=1.0';
export type FontStyle = 'normal' | 'italic' | 'oblique';
export type FontVariant = 'normal' | 'small-caps';
export type FontWeight =
| 'thin'
| 'ultralight'
| 'light'
| 'semilight'
| 'book'
| 'normal'
| 'medium'
| 'semibold'
| 'bold'
| 'ultrabold'
| 'heavy';
const DEFAULT_FONT_STYLE: FontStyle = 'normal';
const DEFAULT_FONT_VARIANT: FontVariant = 'normal';
const DEFAULT_FONT_WEIGHT: FontWeight = 'normal';
const styleMap: Record<Pango.Style, FontStyle> = {
[Pango.Style.NORMAL]: 'normal',
[Pango.Style.ITALIC]: 'italic',
[Pango.Style.OBLIQUE]: 'oblique',
};
const variantMap: Record<Pango.Variant, FontVariant> = {
[Pango.Variant.NORMAL]: 'normal',
[Pango.Variant.SMALL_CAPS]: 'small-caps',
};
const weightMap: Record<Pango.Weight, FontWeight> = {
[Pango.Weight.THIN]: 'thin',
[Pango.Weight.ULTRALIGHT]: 'ultralight',
[Pango.Weight.LIGHT]: 'light',
[Pango.Weight.SEMILIGHT]: 'semilight',
[Pango.Weight.BOOK]: 'book',
[Pango.Weight.NORMAL]: 'normal',
[Pango.Weight.MEDIUM]: 'medium',
[Pango.Weight.SEMIBOLD]: 'semibold',
[Pango.Weight.BOLD]: 'bold',
[Pango.Weight.ULTRABOLD]: 'ultrabold',
[Pango.Weight.HEAVY]: 'heavy',
};
/**
* Converts a Pango.Style enum to a FontStyle string.
* @param styleEnum - The Pango.Style enum value.
* @returns The corresponding FontStyle string.
*/
export function styleToString(styleEnum: Pango.Style): FontStyle {
return styleMap[styleEnum] ?? DEFAULT_FONT_STYLE;
}
/**
* Converts a Pango.Variant enum to a FontVariant string.
* @param variantEnum - The Pango.Variant enum value.
* @returns The corresponding FontVariant string.
*/
export function variantToString(variantEnum: Pango.Variant): FontVariant {
return variantMap[variantEnum] ?? DEFAULT_FONT_VARIANT;
}
/**
* Converts a Pango.Weight enum to a FontWeight string.
* @param weightEnum - The Pango.Weight enum value.
* @returns The corresponding FontWeight string.
*/
export function weightToString(weightEnum: Pango.Weight): FontWeight {
return weightMap[weightEnum] ?? DEFAULT_FONT_WEIGHT;
}

View File

@@ -104,6 +104,8 @@ export interface RowProps<T> {
subtitleLink?: string; subtitleLink?: string;
dependencies?: string[]; dependencies?: string[];
increment?: number; increment?: number;
fontStyle?: Opt<string>;
fontLabel?: Opt<string>;
} }
export type OSDOrientation = 'horizontal' | 'vertical'; export type OSDOrientation = 'horizontal' | 'vertical';

View File

@@ -1,3 +1,4 @@
import { FontStyle } from './components/settings/shared/inputs/font/utils';
import { opt, mkOptions } from './lib/option'; import { opt, mkOptions } from './lib/option';
import { NetstatLabelType, RateUnit, ResourceLabelType } from './lib/types/bar'; import { NetstatLabelType, RateUnit, ResourceLabelType } from './lib/types/bar';
import { KbLabelType } from './lib/types/customModules/kbLayout'; import { KbLabelType } from './lib/types/customModules/kbLayout';
@@ -104,6 +105,8 @@ const options = mkOptions(CONFIG, {
font: { font: {
size: opt('1.2rem'), size: opt('1.2rem'),
name: opt('Ubuntu Nerd Font'), name: opt('Ubuntu Nerd Font'),
style: opt<FontStyle>('normal'),
label: opt('Ubuntu Nerd Font'),
weight: opt(600), weight: opt(600),
}, },
notification: { notification: {

View File

@@ -1,6 +1,7 @@
* { * {
all: unset; all: unset;
font-family: $font-name; font-family: $font-name;
font-style: $font-style;
font-size: $font-size; font-size: $font-size;
font-weight: $font-weight; font-weight: $font-weight;
} }

View File

@@ -1,222 +1,210 @@
@import "colors"; @import 'colors';
* { html,
color: $default_fg; body {
font-family: "JetBrainsMono NF"; padding: 0;
font-size: 0.9rem; margin: 0;
background-color: $primary_bg;
} }
html, body {
padding: 0;
margin: 0;
background-color: $primary_bg;
}
// scrollbar {
// background-color: red;
// min-width: 5em;
// }
.code { .code {
background: $light-background;
border-radius: 0.5rem;
.code-header {
background: $light-background; background: $light-background;
border-top-left-radius: 0.5rem; border-radius: 0.5rem;
border-top-right-radius: 0.5rem;
border-bottom: 1px solid $primary_fg;
padding: 5px;
> button { .code-header {
color: $default_fg; background: $light-background;
background: transparent; border-top-left-radius: 0.5rem;
float: right; border-top-right-radius: 0.5rem;
border: none; border-bottom: 1px solid $primary_fg;
padding: 5px;
&:before { > button {
content: '󰆏'; color: $default_fg;
display: inline-block; background: transparent;
padding-right: 0.5rem; float: right;
} border: none;
&:before {
content: '󰆏';
display: inline-block;
padding-right: 0.5rem;
}
}
} }
}
} }
$languages-map: ( $languages-map: (
arduino: "", arduino: '',
armasm: "", armasm: '',
avrasm: "", avrasm: '',
bash: "", bash: '',
c: "", c: '',
clojure: "", clojure: '',
coffeescript: "", coffeescript: '',
cpp: "", cpp: '',
csharp: "󰌛", csharp: '󰌛',
css: "", css: '',
dockerfile: "󰡨", dockerfile: '󰡨',
go: "", go: '',
gradle: "", gradle: '',
haskell: "", haskell: '',
html: "", html: '',
java: "", java: '',
javascript: "󰌞", javascript: '󰌞',
json: "", json: '',
latex: "", latex: '',
lua: "󰢱", lua: '󰢱',
makefile: "", makefile: '',
markdown: "", markdown: '',
mipsasm: "", mipsasm: '',
nginx: "", nginx: '',
nix: "󱄅", nix: '󱄅',
php: "", php: '',
prolog: "", prolog: '',
python: "", python: '',
r: "󰟔", r: '󰟔',
ruby: "", ruby: '',
rust: "", rust: '',
scss: "", scss: '',
shell: "", shell: '',
typescript: "󰛦", typescript: '󰛦',
wasm: "", wasm: '',
x86asm: "", x86asm: '',
xml: "󰗀", xml: '󰗀',
); );
@each $lang, $content in $languages-map { @each $lang, $content in $languages-map {
[data-language="#{$lang}"]:before { [data-language='#{$lang}']:before {
content: $content; content: $content;
font-size: 1.1rem; font-size: 1.1rem;
color: $primary_fg; color: $primary_fg;
padding-right: 0.5rem; padding-right: 0.5rem;
} }
} }
pre { pre {
padding: 5px; padding: 5px;
overflow-x: scroll; overflow-x: scroll;
code.hljs { code.hljs {
color: $default_fg; color: $default_fg;
background: transparent; background: transparent;
} }
} }
code { code {
& .hljs-keyword { & .hljs-keyword {
color: $mauve; color: $mauve;
} }
& .hljs-built_in { & .hljs-built_in {
color: $red; color: $red;
} }
& .hljs-type { & .hljs-type {
color: $yellow; color: $yellow;
} }
& .hljs-literal, & .hljs-literal,
& .hljs-number { & .hljs-number {
color: $orange; color: $orange;
} }
& .hljs-operator { & .hljs-operator {
color: $teal; color: $teal;
} }
& .hljs-punctuation { & .hljs-punctuation {
color: $lightteal; color: $lightteal;
} }
& .hljs-property, & .hljs-property,
& .hljs-variable.language_, & .hljs-variable.language_,
& .hljs-symbol { & .hljs-symbol {
color: $teal; color: $teal;
} }
& .hljs-regexp { & .hljs-regexp {
color: $pink; color: $pink;
} }
& .hljs-string, & .hljs-string,
& .hljs-char.escape_, & .hljs-char.escape_,
& .hljs-subst { & .hljs-subst {
color: $green; color: $green;
} }
& .hljs-comment { & .hljs-comment {
color: $grey; color: $grey;
} }
& .hljs-doctag { & .hljs-doctag {
color: $red; color: $red;
} }
& .hljs-meta, & .hljs-meta,
& .hljs-title.function_, & .hljs-title.function_,
& .hljs-section { & .hljs-section {
color: $orange; color: $orange;
} }
& .hljs-tag, & .hljs-tag,
& .hljs-attribute { & .hljs-attribute {
color: $lightgrey; color: $lightgrey;
} }
& .hljs-name, & .hljs-name,
& .hljs-selector-attr { & .hljs-selector-attr {
color: $mauve; color: $mauve;
} }
& .hljs-params, & .hljs-params,
& .hljs-selector-class, & .hljs-selector-class,
& .hljs-template-variable { & .hljs-template-variable {
color: $default_fg; color: $default_fg;
} }
& .hljs-selector-tag { & .hljs-selector-tag {
color: $yellow; color: $yellow;
} }
& .hljs-selector-id { & .hljs-selector-id {
color: $blue; color: $blue;
} }
& .hljs-bullet, & .hljs-bullet,
& .hljs-code, & .hljs-code,
& .hljs-formula { & .hljs-formula {
color: $teal; color: $teal;
} }
& .hljs-emphasis { & .hljs-emphasis {
color: $red; color: $red;
font-style: italic; font-style: italic;
} }
& .hljs-strong { & .hljs-strong {
color: $red; color: $red;
font-weight: bold; font-weight: bold;
} }
& .hljs-link { & .hljs-link {
color: $lightblue; color: $lightblue;
font-style: italic; font-style: italic;
} }
& .hljs-quote { & .hljs-quote {
color: $green; color: $green;
font-style: italic; font-style: italic;
} }
& .hljs-addition { & .hljs-addition {
color: $green; color: $green;
background: rgba(166, 227, 161, 0.15); background: rgba(166, 227, 161, 0.15);
} }
& .hljs-deletion { & .hljs-deletion {
color: $red; color: $red;
background: rgba(243, 139, 168, 0.15); background: rgba(243, 139, 168, 0.15);
} }
} }

View File

@@ -3,6 +3,7 @@ import { resetCss } from '../style';
export const initializeHotReload = async (): Promise<void> => { export const initializeHotReload = async (): Promise<void> => {
const monitorList = [ const monitorList = [
`${SRC_DIR}/src/scss/main.scss`,
`${SRC_DIR}/src/scss/style/bar`, `${SRC_DIR}/src/scss/style/bar`,
`${SRC_DIR}/src/scss/style/common`, `${SRC_DIR}/src/scss/style/common`,
`${SRC_DIR}/src/scss/style/menus`, `${SRC_DIR}/src/scss/style/menus`,