diff --git a/src/core/properties/PropertySchema.ts b/src/core/properties/PropertySchema.ts index bb3ac478..d34bca20 100644 --- a/src/core/properties/PropertySchema.ts +++ b/src/core/properties/PropertySchema.ts @@ -64,6 +64,7 @@ import { } from './particles'; import { SHADER_KEY, shaderOf, shaderParamDefs } from './shaders'; import { LOOP_KEY as SOUND_LOOP_KEY, VOLUME_KEY as SOUND_VOLUME_KEY } from './sounds'; +import { Theme } from '../../ui'; /** * What a kind's definition carries beyond key, label and default. `decimals` belongs only on @@ -250,7 +251,7 @@ export function isValidVariableName(name: string): boolean { /** Position is deliberately absent: it belongs to scene objects, not to asset types. */ const ASSET_SCHEMAS: Record = { scene: [ - { key: 'backgroundColor', label: 'Background', kind: 'color', default: 0x2a2d34 }, + { key: 'backgroundColor', label: 'Background', kind: 'color', default: Theme.colors.graphBackground }, // Pulls on every dynamic rigidbody, in world units per second squared: 980 is Earth at 100 px = 1 m. { key: 'gravityX', label: 'Gravity X', kind: 'number', default: 0, step: 10 }, { key: 'gravityY', label: 'Gravity Y', kind: 'number', default: 980, step: 10 }, diff --git a/src/main.ts b/src/main.ts index a678e080..685d64dd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,7 +5,7 @@ import { Application, Container } from 'pixi.js'; import { captureConsole } from './editor/console/log'; import { startEditor } from './editor/App'; import { mountPlayground } from './playground'; -import { initRenderLoop, initUI, Theme, VStack } from './ui'; +import { initRenderLoop, initUI, loadEditorFonts, Theme, VStack } from './ui'; // Before anything else: a renderer warns while it is being created, and those warnings are // exactly the ones worth having in the panel. @@ -27,6 +27,7 @@ function lowLatencyContext(): { canvas?: HTMLCanvasElement; context?: WebGL2Rend async function main(): Promise { const params = new URLSearchParams(location.search); + const fonts = loadEditorFonts(); const app = new Application(); await app.init({ resizeTo: window, @@ -38,6 +39,7 @@ async function main(): Promise { ...(params.has('vsync') ? {} : lowLatencyContext()), }); document.body.appendChild(app.canvas); + await fonts; const root = new VStack(); const overlay = new Container(); diff --git a/src/ui/Theme.ts b/src/ui/Theme.ts index a50fbd7f..e37242f6 100644 --- a/src/ui/Theme.ts +++ b/src/ui/Theme.ts @@ -2,21 +2,22 @@ import { TextStyle } from 'pixi.js'; export const Theme = { - font: 'Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', - monoFont: '"JetBrains Mono", Consolas, "Courier New", monospace', - fontSize: 13, + // Both ship with the build (`fonts.ts`); the rest only covers glyphs outside their Latin subset. + font: '"Source Sans 3", "Segoe UI", Roboto, Helvetica, Arial, sans-serif', + monoFont: '"Source Code Pro", Consolas, "Courier New", monospace', + fontSize: 12, smallFontSize: 11, viewportLabelSize: 10, - rowHeight: 26, + rowHeight: 22, controlHeight: 24, padding: 8, - gap: 6, - radius: 4, - fieldPadding: 6, + gap: 4, + radius: 8, + fieldPadding: 4, checkboxSize: 16, - scrollbarWidth: 6, + scrollbarWidth: 4, /** Horizontal indent per nesting level in tree lists. */ - treeIndent: 14, + treeIndent: 12, hoverCursor: 'default', colors: { background: 0x1b1d22, @@ -108,7 +109,7 @@ export function textStyle(token: TextStyleToken = 'body'): TextStyle { style = new TextStyle(base); break; case 'bodyBold': - style = new TextStyle({ ...base, fontWeight: '600' }); + style = new TextStyle({ ...base, fontWeight: '500' }); break; case 'muted': style = new TextStyle({ ...base, fill: Theme.colors.textMuted }); @@ -129,7 +130,7 @@ export function textStyle(token: TextStyleToken = 'body'): TextStyle { style = new TextStyle({ ...base, fontSize: Theme.smallFontSize, - fontWeight: '700', + fontWeight: '500', letterSpacing: 0.5, fill: Theme.colors.textMuted, }); diff --git a/src/ui/fonts.ts b/src/ui/fonts.ts new file mode 100644 index 00000000..886222a7 --- /dev/null +++ b/src/ui/fonts.ts @@ -0,0 +1,27 @@ +import codePro400 from './fonts/source-code-pro-latin-400-normal.woff2?url'; +import sans400 from './fonts/source-sans-3-latin-400-normal.woff2?url'; +import sans600 from './fonts/source-sans-3-latin-600-normal.woff2?url'; +import sans700 from './fonts/source-sans-3-latin-700-normal.woff2?url'; + +const FACES: readonly [family: string, url: string, weight: string][] = [ + ['Source Sans 3', sans400, '400'], + ['Source Sans 3', sans600, '600'], + ['Source Sans 3', sans700, '700'], + ['Source Code Pro', codePro400, '400'], +]; + +/** + * Pixi measures a text the moment it is laid out, so the faces have to be usable before the + * first widget exists. A face that fails to load is reported and the fallback in `Theme` takes over. + */ +export async function loadEditorFonts(): Promise { + await Promise.all( + FACES.map(async ([family, url, weight]) => { + try { + document.fonts.add(await new FontFace(family, `url("${url}")`, { weight }).load()); + } catch (error) { + console.warn(`[fonts] ${family} ${weight} did not load`, error); + } + }), + ); +} diff --git a/src/ui/fonts/OFL-source-code-pro.txt b/src/ui/fonts/OFL-source-code-pro.txt new file mode 100644 index 00000000..046fc664 --- /dev/null +++ b/src/ui/fonts/OFL-source-code-pro.txt @@ -0,0 +1,93 @@ +Google Inc. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/ui/fonts/OFL-source-sans-3.txt b/src/ui/fonts/OFL-source-sans-3.txt new file mode 100644 index 00000000..046fc664 --- /dev/null +++ b/src/ui/fonts/OFL-source-sans-3.txt @@ -0,0 +1,93 @@ +Google Inc. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/ui/fonts/source-code-pro-latin-400-normal.woff2 b/src/ui/fonts/source-code-pro-latin-400-normal.woff2 new file mode 100644 index 00000000..d1f2d849 Binary files /dev/null and b/src/ui/fonts/source-code-pro-latin-400-normal.woff2 differ diff --git a/src/ui/fonts/source-sans-3-latin-400-normal.woff2 b/src/ui/fonts/source-sans-3-latin-400-normal.woff2 new file mode 100644 index 00000000..0c4242ed Binary files /dev/null and b/src/ui/fonts/source-sans-3-latin-400-normal.woff2 differ diff --git a/src/ui/fonts/source-sans-3-latin-500-normal.woff2 b/src/ui/fonts/source-sans-3-latin-500-normal.woff2 new file mode 100644 index 00000000..59189166 Binary files /dev/null and b/src/ui/fonts/source-sans-3-latin-500-normal.woff2 differ diff --git a/src/ui/fonts/source-sans-3-latin-600-normal.woff2 b/src/ui/fonts/source-sans-3-latin-600-normal.woff2 new file mode 100644 index 00000000..93511778 Binary files /dev/null and b/src/ui/fonts/source-sans-3-latin-600-normal.woff2 differ diff --git a/src/ui/fonts/source-sans-3-latin-700-normal.woff2 b/src/ui/fonts/source-sans-3-latin-700-normal.woff2 new file mode 100644 index 00000000..3cb944ca Binary files /dev/null and b/src/ui/fonts/source-sans-3-latin-700-normal.woff2 differ diff --git a/src/ui/index.ts b/src/ui/index.ts index 7ac186b0..6cd9ebfa 100644 --- a/src/ui/index.ts +++ b/src/ui/index.ts @@ -1,6 +1,7 @@ export { Widget, Box, type Size } from './Widget'; export { HStack, VStack, Spacer, Stack, type StackOptions } from './layout/Stack'; export { Theme, textStyle, type TextStyleToken } from './Theme'; +export { loadEditorFonts } from './fonts'; export { initUI, ui, type UIContext } from './UIContext'; export { afterFrames,