Skip to content

Commit

Permalink
Merge pull request #1056 from googlefonts/issue1050
Browse files Browse the repository at this point in the history
Expose read-only mode, and make sure the user is informed when attempting to edit a read-only font
  • Loading branch information
justvanrossum authored Jan 15, 2024
2 parents 4628157 + f699d31 commit 2934f51
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 5 deletions.
18 changes: 18 additions & 0 deletions src/fontra/client/core/font-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class FontController {
});
this.undoStacks = {}; // glyph name -> undo stack
this._rootObject = {};
this.readOnly = true;
}

async initialize() {
Expand All @@ -45,6 +46,7 @@ export class FontController {
this._rootObject["customData"] = await this.font.getCustomData();
this._rootClassDef = (await getClassSchema())["Font"];
this.backendInfo = await this.font.getBackEndInfo();
this.readOnly = await this.font.isReadOnly();
this._resolveInitialized();
}

Expand Down Expand Up @@ -207,6 +209,10 @@ export class FontController {
}

async newGlyph(glyphName, codePoint, varGlyph, undoLabel = null) {
if (this.readOnly) {
console.log("can't create glyph in read-only mode");
return;
}
if (this.glyphMap[glyphName]) {
throw new Error(`assert -- glyph "${glyphName}" already exists`);
}
Expand Down Expand Up @@ -424,11 +430,19 @@ export class FontController {
}

editIncremental(change) {
if (this.readOnly) {
console.log("can't edit font in read-only mode");
return;
}
this.font.editIncremental(change);
this.notifyChangeListeners(change, true);
}

async editFinal(finalChange, rollbackChange, editLabel, broadcast) {
if (this.readOnly) {
console.log("can't edit font in read-only mode");
return;
}
const result = await this.font.editFinal(
finalChange,
rollbackChange,
Expand All @@ -446,6 +460,10 @@ export class FontController {
}

async applyChange(change, isExternalChange) {
if (!isExternalChange && this.readOnly) {
console.log("can't edit font in read-only mode");
return;
}
const cachedPattern = this.getCachedDataPattern();

const unmatched = filterChangePattern(change, cachedPattern, true);
Expand Down
4 changes: 4 additions & 0 deletions src/fontra/core/fonthandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ async def useConnection(self, connection) -> AsyncGenerator[None, None]:
if not self.connections and self.allConnectionsClosedCallback is not None:
await self.allConnectionsClosedCallback()

@remoteMethod
async def isReadOnly(self, *, connection=None) -> bool:
return self.readOnly

@remoteMethod
async def getBackEndInfo(self, *, connection=None) -> dict:
features = {}
Expand Down
9 changes: 5 additions & 4 deletions src/fontra/views/editor/edit-tools-pointer.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ export class PointerTool extends BaseTool {
async handleDoubleCick(selection, point, event) {
const sceneController = this.sceneController;
if (!sceneController.hoverPathHit && (!selection || !selection.size)) {
const selectedGlyph = this.sceneModel.glyphAtPoint(point);
this.sceneSettings.selectedGlyph = selectedGlyph
? { ...selectedGlyph, isEditing: true }
: undefined;
const positionedGlyph = sceneController.sceneModel.getSelectedPositionedGlyph();
if (positionedGlyph?.isUndefined) {
sceneController._dispatchEvent("doubleClickedUndefinedGlyph");
} else {
const selectedGlyph = this.sceneModel.glyphAtPoint(point);
this.sceneSettings.selectedGlyph = selectedGlyph
? { ...selectedGlyph, isEditing: true }
: undefined;
}
} else {
const instance = this.sceneModel.getSelectedPositionedGlyph().glyph.instance;
Expand Down
19 changes: 18 additions & 1 deletion src/fontra/views/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,20 @@ export class EditorController {
this.doubleClickedComponentsCallback(event);
});

this.sceneController.addEventListener("glyphEditCannotEditReadOnly", async () => {
this.showDialogGlyphEditCannotEditReadOnly();
});

this.sceneController.addEventListener("glyphEditLocationNotAtSource", async () => {
this.showDialogGlyphEditLocationNotAtSource();
});

this.sceneController.addEventListener("doubleClickedUndefinedGlyph", () => {
this.showDialogNewGlyph();
if (this.fontController.readOnly) {
this.showDialogGlyphEditCannotEditReadOnly(true);
} else {
this.showDialogNewGlyph();
}
});

this.sidebars = [];
Expand Down Expand Up @@ -358,6 +366,15 @@ export class EditorController {
}
}

async showDialogGlyphEditCannotEditReadOnly(create = false) {
const glyphName = this.sceneSettings.selectedGlyphName;
const result = await dialog(
`Can’t ${create ? "create" : "edit"} glyph “${glyphName}”`,
"The font is read-only.",
[{ title: "Okay", isDefaultButton: true }]
);
}

async showDialogGlyphEditLocationNotAtSource() {
const glyphName = this.sceneSettings.selectedGlyphName;
const result = await dialog(
Expand Down
4 changes: 4 additions & 0 deletions src/fontra/views/editor/panel-selection-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export default class SelectionInfoPanel extends Panel {
this.throttledUpdate(event.senderID);
});

this.sceneController.addEventListener("glyphEditCannotEditReadOnly", async () => {
this.update();
});

this.sceneController.addEventListener("glyphEditLocationNotAtSource", async () => {
this.update();
});
Expand Down
4 changes: 4 additions & 0 deletions src/fontra/views/editor/scene-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,10 @@ export class SceneController {
doInstance,
requireSelectedLayer
) {
if (this.fontController.readOnly) {
this._dispatchEvent("glyphEditCannotEditReadOnly");
return;
}
const glyphName = this.sceneModel.getSelectedGlyphName();
const varGlyph = await this.fontController.getGlyph(glyphName);
const baseChangePath = ["glyphs", glyphName];
Expand Down

0 comments on commit 2934f51

Please sign in to comment.