Fix the font selector. (#660)
This commit is contained in:
@@ -8,7 +8,13 @@ export const BarGeneral = (): JSX.Element => {
|
||||
<scrollable name={'General'} className="bar-theme-page paged-container" vscroll={Gtk.PolicyType.AUTOMATIC}>
|
||||
<box vertical>
|
||||
<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.weight}
|
||||
|
||||
@@ -14,6 +14,8 @@ import { Gtk } from 'astal/gtk3';
|
||||
|
||||
const InputField = <T extends string | number | boolean | object>({
|
||||
opt,
|
||||
fontStyle,
|
||||
fontLabel,
|
||||
type = typeof opt.get() as RowProps<T>['type'],
|
||||
enums = [],
|
||||
disabledBinding,
|
||||
@@ -44,7 +46,7 @@ const InputField = <T extends string | number | boolean | object>({
|
||||
case 'wallpaper':
|
||||
return <WallpaperInputter opt={opt} />;
|
||||
case 'font':
|
||||
return <FontInputter opt={opt} />;
|
||||
return <FontInputter fontFamily={opt} fontLabel={fontLabel} fontStyle={fontStyle} />;
|
||||
case 'color':
|
||||
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>({
|
||||
opt,
|
||||
fontStyle,
|
||||
fontLabel,
|
||||
type = typeof opt.get() as RowProps<T>['type'],
|
||||
enums,
|
||||
disabledBinding,
|
||||
@@ -71,6 +75,8 @@ export const Inputter = <T extends string | number | boolean | object>({
|
||||
<InputField
|
||||
type={type}
|
||||
opt={opt}
|
||||
fontStyle={fontStyle}
|
||||
fontLabel={fontLabel}
|
||||
enums={enums}
|
||||
disabledBinding={disabledBinding}
|
||||
dependencies={dependencies}
|
||||
|
||||
@@ -10,6 +10,8 @@ export const SettingInput = <T extends string | number | boolean | object>({
|
||||
return (
|
||||
<Inputter
|
||||
opt={props.opt}
|
||||
fontStyle={props.fontStyle}
|
||||
fontLabel={props.fontLabel}
|
||||
type={props.type}
|
||||
enums={props.enums}
|
||||
disabledBinding={props.disabledBinding}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
43
src/components/settings/shared/inputs/font/index.tsx
Normal file
43
src/components/settings/shared/inputs/font/index.tsx
Normal 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>;
|
||||
}
|
||||
72
src/components/settings/shared/inputs/font/utils.ts
Normal file
72
src/components/settings/shared/inputs/font/utils.ts
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user