From 9f7d72d63715efdbf60ed8f09ab3c9bc98c385b4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 23 Jul 2020 21:14:06 -0700 Subject: [PATCH] Update paw draw example to show how to create untitled files Fixes https://github.com/microsoft/vscode/issues/100238 This is not well supported at the moment since we need some new APIs for working with untitled custom editors, how the current example shows how it can be implemented --- custom-editor-sample/media/pawDraw.js | 36 +++++++++++++++++--- custom-editor-sample/package.json | 10 +++++- custom-editor-sample/src/pawDrawEditor.ts | 40 +++++++++++++++++++---- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/custom-editor-sample/media/pawDraw.js b/custom-editor-sample/media/pawDraw.js index bfece22f..73098aca 100644 --- a/custom-editor-sample/media/pawDraw.js +++ b/custom-editor-sample/media/pawDraw.js @@ -172,7 +172,28 @@ this.initialCtx.drawImage(img, 0, 0); this.ready = true; } + + this.strokes = strokes; + this._redraw(); + } + + /** + * @param {Array | undefined} strokes + */ + async resetUntitled(strokes = []) { + const size = 100; + this.initialCanvas.width = size; + this.initialCanvas.height = size; + this.initialCtx.save(); + { + this.initialCtx.fillStyle = 'white'; + this.initialCtx.fillRect(0, 0, size, size); + } + this.initialCtx.restore(); + + this.ready = true; + this.strokes = strokes; this._redraw(); } @@ -203,14 +224,19 @@ switch (type) { case 'init': { - // Load the initial image into the canvas. - const data = new Uint8Array(body.value.data); - await editor.reset(data); - return; + if (body.untitled) { + await editor.resetUntitled(); + return; + } else { + // Load the initial image into the canvas. + const data = new Uint8Array(body.value.data); + await editor.reset(data); + return; + } } case 'update': { - const data = body.content ? new Uint8Array(body.content.data) : undefined;; + const data = body.content ? new Uint8Array(body.content.data) : undefined; const strokes = body.edits.map(edit => new Stroke(edit.color, edit.stroke)); await editor.reset(data, strokes) return; diff --git a/custom-editor-sample/package.json b/custom-editor-sample/package.json index 1af2829e..9cc86131 100644 --- a/custom-editor-sample/package.json +++ b/custom-editor-sample/package.json @@ -13,7 +13,8 @@ ], "activationEvents": [ "onCustomEditor:catCustoms.catScratch", - "onCustomEditor:catCustoms.pawDraw" + "onCustomEditor:catCustoms.pawDraw", + "onCommand:catCustoms.pawDraw.new" ], "repository": { "type": "git", @@ -40,6 +41,13 @@ } ] } + ], + "commands": [ + { + "command": "catCustoms.pawDraw.new", + "title": "Create new Paw Draw Document", + "category": "Paw Draw" + } ] }, "scripts": { diff --git a/custom-editor-sample/src/pawDrawEditor.ts b/custom-editor-sample/src/pawDrawEditor.ts index 63794b9d..7858e1c8 100644 --- a/custom-editor-sample/src/pawDrawEditor.ts +++ b/custom-editor-sample/src/pawDrawEditor.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; -import { getNonce } from './util'; import { Disposable, disposeAll } from './dispose'; +import { getNonce } from './util'; /** * Define the type of edits used in paw draw files. @@ -27,10 +27,17 @@ class PawDrawDocument extends Disposable implements vscode.CustomDocument { ): Promise> { // If we have a backup, read that. Otherwise read the resource from the workspace const dataFile = typeof backupId === 'string' ? vscode.Uri.parse(backupId) : uri; - const fileData = await vscode.workspace.fs.readFile(dataFile); + const fileData = await PawDrawDocument.readFile(dataFile); return new PawDrawDocument(uri, fileData, delegate); } + private static async readFile(uri: vscode.Uri): Promise { + if (uri.scheme === 'untitled') { + return new Uint8Array(); + } + return vscode.workspace.fs.readFile(uri); + } + private readonly _uri: vscode.Uri; private _documentData: Uint8Array; @@ -139,7 +146,7 @@ class PawDrawDocument extends Disposable implements vscode.CustomDocument { * Called by VS Code when the user calls `revert` on a document. */ async revert(_cancellation: vscode.CancellationToken): Promise { - const diskContent = await vscode.workspace.fs.readFile(this.uri); + const diskContent = await PawDrawDocument.readFile(this.uri); this._documentData = diskContent; this._edits = this._savedEdits; this._onDidChangeDocument.fire({ @@ -186,7 +193,22 @@ class PawDrawDocument extends Disposable implements vscode.CustomDocument { */ export class PawDrawEditorProvider implements vscode.CustomEditorProvider { + private static newPawDrawFileId = 1; + public static register(context: vscode.ExtensionContext): vscode.Disposable { + vscode.commands.registerCommand('catCustoms.pawDraw.new', () => { + const workspaceFolders = vscode.workspace.workspaceFolders; + if (!workspaceFolders) { + vscode.window.showErrorMessage("Creating new Paw Draw files currently requires opening a workspace"); + return; + } + + const uri = vscode.Uri.joinPath(workspaceFolders[0].uri, `new-${PawDrawEditorProvider.newPawDrawFileId++}.pawdraw`) + .with({ scheme: 'untitled' }); + + vscode.commands.executeCommand('vscode.openWith', uri, PawDrawEditorProvider.viewType); + }); + return vscode.window.registerCustomEditorProvider( PawDrawEditorProvider.viewType, new PawDrawEditorProvider(context), @@ -275,9 +297,15 @@ export class PawDrawEditorProvider implements vscode.CustomEditorProvider { if (e.type === 'ready') { - this.postMessage(webviewPanel, 'init', { - value: document.documentData - }); + if (document.uri.scheme === 'untitled') { + this.postMessage(webviewPanel, 'init', { + untitled: true + }); + } else { + this.postMessage(webviewPanel, 'init', { + value: document.documentData + }); + } } }); }