mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 05:28:13 +08:00
Refactor font loading from per-document to the portfolio (#659)
* Cleanup default font loading * Refactor fonts * Fix menulist mouse navigation * Format * Formatting * Move default font into consts.rs Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Keavon Chambers
parent
d4539bc304
commit
8923b68e30
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<LayoutRow class="dropdown-input">
|
||||
<LayoutRow class="dropdown-input" data-dropdown-input>
|
||||
<LayoutRow
|
||||
class="dropdown-box"
|
||||
:class="{ disabled }"
|
||||
:class="{ disabled, open }"
|
||||
:style="{ minWidth: `${minWidth}px` }"
|
||||
tabindex="0"
|
||||
@click="() => !disabled && (open = true)"
|
||||
@blur="() => (open = false)"
|
||||
@blur="(e: FocusEvent) => blur(e)"
|
||||
@keydown="(e) => keydown(e)"
|
||||
ref="dropdownBox"
|
||||
data-hover-menu-spawner
|
||||
@@ -145,6 +145,9 @@ export default defineComponent({
|
||||
keydown(e: KeyboardEvent) {
|
||||
(this.$refs.menuList as typeof MenuList).keydown(e, false);
|
||||
},
|
||||
blur(e: FocusEvent) {
|
||||
if ((e.target as HTMLElement).closest("[data-dropdown-input]") !== this.$el) this.open = false;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
IconLabel,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="menu-bar-input">
|
||||
<div class="menu-bar-input" data-menu-bar-input>
|
||||
<div class="entry-container">
|
||||
<button @click="() => visitWebsite('https://graphite.rs')" class="entry">
|
||||
<IconLabel :icon="'GraphiteLogo'" />
|
||||
@@ -8,11 +8,11 @@
|
||||
<div class="entry-container" v-for="(entry, index) in entries" :key="index">
|
||||
<div
|
||||
@click="(e) => onClick(entry, e.target)"
|
||||
@blur="() => close(entry)"
|
||||
tabindex="0"
|
||||
@blur="(e: FocusEvent) => blur(e,entry)"
|
||||
@keydown="entry.ref?.keydown"
|
||||
class="entry"
|
||||
:class="{ open: entry.ref?.open }"
|
||||
:class="{ open: entry.ref?.isOpen }"
|
||||
data-hover-menu-spawner
|
||||
>
|
||||
<IconLabel v-if="entry.icon" :icon="entry.icon" />
|
||||
@@ -225,8 +225,8 @@ export default defineComponent({
|
||||
if (menuEntry.ref) menuEntry.ref.isOpen = true;
|
||||
else throw new Error("The menu bar floating menu has no associated ref");
|
||||
},
|
||||
close(menuEntry: MenuListEntry) {
|
||||
if (menuEntry.ref) menuEntry.ref.isOpen = false;
|
||||
blur(e: FocusEvent, menuEntry: MenuListEntry) {
|
||||
if ((e.target as HTMLElement).closest("[data-menu-bar-input]") !== this.$el && menuEntry.ref) menuEntry.ref.isOpen = false;
|
||||
},
|
||||
// TODO: Move to backend
|
||||
visitWebsite(url: string) {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { reactive, readonly } from "vue";
|
||||
|
||||
import { Editor } from "@/wasm-communication/editor";
|
||||
import { TriggerFontLoad, TriggerFontLoadDefault } from "@/wasm-communication/messages";
|
||||
|
||||
const DEFAULT_FONT = "Merriweather";
|
||||
const DEFAULT_FONT_STYLE = "Normal (400)";
|
||||
import { TriggerFontLoad } from "@/wasm-communication/messages";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export function createFontsState(editor: Editor) {
|
||||
@@ -40,17 +37,14 @@ export function createFontsState(editor: Editor) {
|
||||
}
|
||||
|
||||
// Subscribe to process backend events
|
||||
editor.subscriptions.subscribeJsMessage(TriggerFontLoadDefault, async (): Promise<void> => {
|
||||
const fontFileUrl = await getFontFileUrl(DEFAULT_FONT, DEFAULT_FONT_STYLE);
|
||||
if (!fontFileUrl) return;
|
||||
|
||||
const response = await fetch(fontFileUrl);
|
||||
const responseBuffer = await response.arrayBuffer();
|
||||
editor.instance.on_font_load(fontFileUrl, new Uint8Array(responseBuffer), true);
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(TriggerFontLoad, async (triggerFontLoad) => {
|
||||
const response = await (await fetch(triggerFontLoad.font_file_url)).arrayBuffer();
|
||||
editor.instance.on_font_load(triggerFontLoad.font_file_url, new Uint8Array(response), false);
|
||||
const url = await getFontFileUrl(triggerFontLoad.font.font_family, triggerFontLoad.font.font_style);
|
||||
if (url) {
|
||||
const response = await (await fetch(url)).arrayBuffer();
|
||||
editor.instance.on_font_load(triggerFontLoad.font.font_family, triggerFontLoad.font.font_style, url, new Uint8Array(response), triggerFontLoad.is_default);
|
||||
} else {
|
||||
editor.instance.error_dialog("Failed to load font", `The font ${triggerFontLoad.font.font_family} with style ${triggerFontLoad.font.font_style} does not exist`);
|
||||
}
|
||||
});
|
||||
|
||||
const fontList: Promise<{ family: string; variants: string[]; files: Map<string, string> }[]> = new Promise((resolve) => {
|
||||
|
||||
@@ -352,11 +352,18 @@ export class TriggerIndexedDbRemoveDocument extends JsMessage {
|
||||
document_id!: string;
|
||||
}
|
||||
|
||||
export class TriggerFontLoad extends JsMessage {
|
||||
font_file_url!: string;
|
||||
export class Font {
|
||||
font_family!: string;
|
||||
|
||||
font_style!: string;
|
||||
}
|
||||
|
||||
export class TriggerFontLoadDefault extends JsMessage {}
|
||||
export class TriggerFontLoad extends JsMessage {
|
||||
@Type(() => Font)
|
||||
font!: Font;
|
||||
|
||||
is_default!: boolean;
|
||||
}
|
||||
|
||||
export class TriggerVisitLink extends JsMessage {
|
||||
url!: string;
|
||||
@@ -545,7 +552,6 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||
TriggerFileUpload,
|
||||
TriggerIndexedDbRemoveDocument,
|
||||
TriggerFontLoad,
|
||||
TriggerFontLoadDefault,
|
||||
TriggerIndexedDbWriteDocument,
|
||||
TriggerRasterDownload,
|
||||
TriggerTextCommit,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use crate::helpers::{translate_key, Error};
|
||||
use crate::{EDITOR_HAS_CRASHED, EDITOR_INSTANCES, JS_EDITOR_HANDLES};
|
||||
|
||||
use editor::consts::{FILE_SAVE_SUFFIX, GRAPHITE_DOCUMENT_VERSION};
|
||||
use editor::consts::{DEFAULT_FONT_FAMILY, DEFAULT_FONT_STYLE, FILE_SAVE_SUFFIX, GRAPHITE_DOCUMENT_VERSION};
|
||||
use editor::input::input_preprocessor::ModifierKeys;
|
||||
use editor::input::mouse::{EditorMouseState, ScrollDelta, ViewportBounds};
|
||||
use editor::message_prelude::*;
|
||||
@@ -110,13 +110,21 @@ impl JsEditorHandle {
|
||||
let message = ToolMessage::InitTools;
|
||||
self.dispatch(message);
|
||||
|
||||
let message = FrontendMessage::TriggerFontLoadDefault;
|
||||
// A default font
|
||||
let font = graphene::layers::text_layer::Font::new(DEFAULT_FONT_FAMILY.into(), DEFAULT_FONT_STYLE.into());
|
||||
let message = FrontendMessage::TriggerFontLoad { font, is_default: true };
|
||||
self.dispatch(message);
|
||||
|
||||
let message = MovementMessage::TranslateCanvas { delta: (0., 0.).into() };
|
||||
self.dispatch(message);
|
||||
}
|
||||
|
||||
/// Displays a dialog with an error message
|
||||
pub fn error_dialog(&self, title: String, description: String) {
|
||||
let message = DialogMessage::DisplayDialogError { title, description };
|
||||
self.dispatch(message);
|
||||
}
|
||||
|
||||
/// Intentionally panic for debugging purposes
|
||||
pub fn intentional_panic(&self) {
|
||||
panic!();
|
||||
@@ -359,8 +367,14 @@ impl JsEditorHandle {
|
||||
}
|
||||
|
||||
/// A font has been downloaded
|
||||
pub fn on_font_load(&self, font_file_url: String, data: Vec<u8>, is_default: bool) -> Result<(), JsValue> {
|
||||
let message = DocumentMessage::FontLoaded { font_file_url, data, is_default };
|
||||
pub fn on_font_load(&self, font_family: String, font_style: String, preview_url: String, data: Vec<u8>, is_default: bool) -> Result<(), JsValue> {
|
||||
let message = PortfolioMessage::FontLoaded {
|
||||
font_family,
|
||||
font_style,
|
||||
preview_url,
|
||||
data,
|
||||
is_default,
|
||||
};
|
||||
self.dispatch(message);
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user