Add support for changing font family and font size

This commit is contained in:
Jonatan Heyman
2024-01-08 21:16:56 +01:00
parent fb62652847
commit a56a267e06
7 changed files with 108 additions and 26 deletions

View File

@ -34,6 +34,8 @@ const schema = {
"showInDock": {type: "boolean", default: true}, "showInDock": {type: "boolean", default: true},
"showInMenu": {type: "boolean", default: false}, "showInMenu": {type: "boolean", default: false},
"bracketClosing": {type: "boolean", default: false}, "bracketClosing": {type: "boolean", default: false},
"fontFamily": {type: "string"},
"fontSize": {type: "integer"},
}, },
}, },
@ -62,6 +64,8 @@ const defaults = {
showInDock: true, showInDock: true,
showInMenu: false, showInMenu: false,
bracketClosing: false, bracketClosing: false,
fontFamily: null, // we use null for the default font family and size, since we could then change
fontSize: null, // the default font family and size in the future and have it apply to existing users
}, },
theme: "system", theme: "system",
} }

View File

@ -120,6 +120,8 @@
:showLineNumberGutter="settings.showLineNumberGutter" :showLineNumberGutter="settings.showLineNumberGutter"
:showFoldGutter="settings.showFoldGutter" :showFoldGutter="settings.showFoldGutter"
:bracketClosing="settings.bracketClosing" :bracketClosing="settings.bracketClosing"
:fontFamily="settings.fontFamily"
:fontSize="settings.fontSize"
class="editor" class="editor"
ref="editor" ref="editor"
@openLanguageSelector="openLanguageSelector" @openLanguageSelector="openLanguageSelector"

View File

@ -27,6 +27,8 @@
type: Boolean, type: Boolean,
default: false, default: false,
}, },
fontFamily: String,
fontSize: Number,
}, },
components: {}, components: {},
@ -71,6 +73,8 @@
showLineNumberGutter: this.showLineNumberGutter, showLineNumberGutter: this.showLineNumberGutter,
showFoldGutter: this.showFoldGutter, showFoldGutter: this.showFoldGutter,
bracketClosing: this.bracketClosing, bracketClosing: this.bracketClosing,
fontFamily: this.fontFamily,
fontSize: this.fontSize,
}) })
window._heynote_editor = this.editor window._heynote_editor = this.editor
window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded) window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded)
@ -134,6 +138,13 @@
bracketClosing(value) { bracketClosing(value) {
this.editor.setBracketClosing(value) this.editor.setBracketClosing(value)
}, },
fontFamily() {
this.editor.setFont(this.fontFamily, this.fontSize)
},
fontSize() {
this.editor.setFont(this.fontFamily, this.fontSize)
},
}, },
methods: { methods: {

View File

@ -2,6 +2,7 @@
import KeyboardHotkey from "./KeyboardHotkey.vue" import KeyboardHotkey from "./KeyboardHotkey.vue"
import TabListItem from "./TabListItem.vue" import TabListItem from "./TabListItem.vue"
import TabContent from "./TabContent.vue" import TabContent from "./TabContent.vue"
import { defaultFontFamily, defaultFontSize } from "@/src/editor/theme/font-theme.js"
export default { export default {
props: { props: {
@ -33,14 +34,22 @@
bracketClosing: this.initialSettings.bracketClosing, bracketClosing: this.initialSettings.bracketClosing,
autoUpdate: this.initialSettings.autoUpdate, autoUpdate: this.initialSettings.autoUpdate,
bufferPath: this.initialSettings.bufferPath, bufferPath: this.initialSettings.bufferPath,
fontFamily: this.initialSettings.fontFamily || defaultFontFamily,
fontSize: this.initialSettings.fontSize || defaultFontSize,
activeTab: "general", activeTab: "general",
isWebApp: window.heynote.isWebApp, isWebApp: window.heynote.isWebApp,
customBufferLocation: !!this.initialSettings.bufferPath, customBufferLocation: !!this.initialSettings.bufferPath,
systemFonts: ["Hack"],
defaultFontSize: defaultFontSize,
} }
}, },
mounted() { async mounted() {
let localFonts = [... new Set((await window.queryLocalFonts()).map(f => f.family))].filter(f => f !== "Hack")
localFonts = [...new Set(localFonts)].map(f => [f, f])
this.systemFonts = [["Hack", "Hack (default)"], ...localFonts]
window.addEventListener("keydown", this.onKeyDown); window.addEventListener("keydown", this.onKeyDown);
this.$refs.keymapSelector.focus() this.$refs.keymapSelector.focus()
}, },
@ -69,6 +78,8 @@
autoUpdate: this.autoUpdate, autoUpdate: this.autoUpdate,
bracketClosing: this.bracketClosing, bracketClosing: this.bracketClosing,
bufferPath: this.bufferPath, bufferPath: this.bufferPath,
fontFamily: this.fontFamily === defaultFontFamily ? undefined : this.fontFamily,
fontSize: this.fontSize === defaultFontSize ? undefined : this.fontSize,
}) })
if (!this.showInDock) { if (!this.showInDock) {
this.showInMenu = true this.showInMenu = true
@ -253,6 +264,28 @@
</label> </label>
</div> </div>
</div> </div>
<div class="row font-settings">
<div class="entry">
<h2>Font Family</h2>
<select v-model="fontFamily" @change="updateSettings" class="font-family">
<option
v-for="[font, label] in systemFonts"
:selected="font === fontFamily"
:value="font"
>{{ label }}</option>
</select>
</div>
<div class="entry" v-if="keymap === 'emacs' && isMac">
<h2>Font Size</h2>
<select v-model="fontSize" @change="updateSettings" class="font-size">
<option
v-for="size in [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]"
:selected="size === fontSize"
:value="size"
>{{ size }}px{{ size === defaultFontSize ? " (default)" : "" }}</option>
</select>
</div>
</div>
</TabContent> </TabContent>
<TabContent tab="updates" :activeTab="activeTab" v-if="!isWebApp"> <TabContent tab="updates" :activeTab="activeTab" v-if="!isWebApp">
@ -359,6 +392,8 @@
flex-grow: 1 flex-grow: 1
padding: 40px padding: 40px
overflow-y: auto overflow-y: auto
select
height: 22px
.row .row
display: flex display: flex
.entry .entry
@ -383,27 +418,34 @@
position: relative position: relative
top: 2px top: 2px
left: -3px left: -3px
.buffer-location &.font-settings
width: 100%
.file-path
display: flex display: flex
> button .font-family
flex-shrink: 0 width: 280px
padding: 3px 8px .font-size
.path width: 120px
flex-grow: 1
margin-left: 10px .buffer-location
font-size: 12px width: 100%
font-family: "Hack" .file-path
padding: 5px 8px display: flex
border-radius: 3px > button
background: #f1f1f1 flex-shrink: 0
color: #555 padding: 3px 8px
white-space: nowrap .path
overflow-x: auto flex-grow: 1
+dark-mode margin-left: 10px
background: #222 font-size: 12px
color: #aaa font-family: "Hack"
padding: 5px 8px
border-radius: 3px
background: #f1f1f1
color: #555
white-space: nowrap
overflow-x: auto
+dark-mode
background: #222
color: #aaa
.bottom-bar .bottom-bar
border-radius: 0 0 5px 5px border-radius: 0 0 5px 5px
background: #eee background: #eee

View File

@ -7,6 +7,7 @@ import { closeBrackets } from "@codemirror/autocomplete";
import { heynoteLight } from "./theme/light.js" import { heynoteLight } from "./theme/light.js"
import { heynoteDark } from "./theme/dark.js" import { heynoteDark } from "./theme/dark.js"
import { heynoteBase } from "./theme/base.js" import { heynoteBase } from "./theme/base.js"
import { getFontTheme } from "./theme/font-theme.js";
import { customSetup } from "./setup.js" import { customSetup } from "./setup.js"
import { heynoteLang } from "./lang-heynote/heynote.js" import { heynoteLang } from "./lang-heynote/heynote.js"
import { noteBlockExtension, blockLineNumbers, blockState } from "./block/block.js" import { noteBlockExtension, blockLineNumbers, blockState } from "./block/block.js"
@ -44,6 +45,8 @@ export class HeynoteEditor {
showLineNumberGutter=true, showLineNumberGutter=true,
showFoldGutter=true, showFoldGutter=true,
bracketClosing=false, bracketClosing=false,
fontFamily,
fontSize,
}) { }) {
this.element = element this.element = element
this.themeCompartment = new Compartment this.themeCompartment = new Compartment
@ -55,6 +58,7 @@ export class HeynoteEditor {
this.closeBracketsCompartment = new Compartment this.closeBracketsCompartment = new Compartment
this.deselectOnCopy = keymap === "emacs" this.deselectOnCopy = keymap === "emacs"
this.emacsMetaKey = emacsMetaKey this.emacsMetaKey = emacsMetaKey
this.fontTheme = new Compartment
const state = EditorState.create({ const state = EditorState.create({
doc: content || "", doc: content || "",
@ -73,6 +77,7 @@ export class HeynoteEditor {
this.themeCompartment.of(theme === "dark" ? heynoteDark : heynoteLight), this.themeCompartment.of(theme === "dark" ? heynoteDark : heynoteLight),
heynoteBase, heynoteBase,
this.fontTheme.of(getFontTheme(fontFamily, fontSize)),
indentUnit.of(" "), indentUnit.of(" "),
EditorView.scrollMargins.of(f => { EditorView.scrollMargins.of(f => {
return {top: 80, bottom: 80} return {top: 80, bottom: 80}
@ -155,6 +160,12 @@ export class HeynoteEditor {
}) })
} }
setFont(fontFamily, fontSize) {
this.view.dispatch({
effects: this.fontTheme.reconfigure(getFontTheme(fontFamily, fontSize)),
})
}
setTheme(theme) { setTheme(theme) {
this.view.dispatch({ this.view.dispatch({
effects: this.themeCompartment.reconfigure(theme === "dark" ? heynoteDark : heynoteLight), effects: this.themeCompartment.reconfigure(theme === "dark" ? heynoteDark : heynoteLight),

View File

@ -58,9 +58,6 @@ export const heynoteBase = EditorView.theme({
".cm-content": { ".cm-content": {
paddingTop: 4, paddingTop: 4,
}, },
'.cm-scroller': {
fontFamily: "Hack, Menlo, Monaco, 'Courier New', monospace",
},
'.cm-gutters': { '.cm-gutters': {
padding: '0 2px 0 4px', padding: '0 2px 0 4px',
userSelect: 'none', userSelect: 'none',
@ -77,8 +74,8 @@ export const heynoteBase = EditorView.theme({
}, },
'.cm-cursor, .cm-dropCursor': { '.cm-cursor, .cm-dropCursor': {
borderLeftWidth:'2px', borderLeftWidth:'2px',
height:'19px !important', paddingTop: '4px',
marginTop:'-2px !important' marginTop: '-2px',
}, },
'.heynote-blocks-layer': { '.heynote-blocks-layer': {
width: '100%', width: '100%',

View File

@ -0,0 +1,15 @@
import { EditorView } from "@codemirror/view"
export const defaultFontFamily = "Hack"
export const defaultFontSize = 12
export function getFontTheme(fontFamily, fontSize) {
fontSize = fontSize || defaultFontSize
return EditorView.theme({
'.cm-scroller': {
fontFamily: fontFamily || defaultFontFamily,
fontSize: (fontSize) + "px",
},
})
}