@lvl99dotcom/paintcanvas 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/lib/assets/index.d.ts +92 -0
- package/dist/lib/assets/index.js +106 -0
- package/dist/lib/assets/schema.d.ts +151 -0
- package/dist/lib/assets/schema.js +76 -0
- package/dist/lib/brushes/presetFile/index.d.ts +6 -27
- package/dist/lib/brushes/presetFile/index.js +34 -47
- package/dist/lib/brushes/types/index.d.ts +2 -11
- package/dist/lib/classes/AssetSync/index.d.ts +45 -0
- package/dist/lib/classes/AssetSync/index.js +80 -0
- package/dist/lib/classes/ColourPalettes/index.d.ts +83 -0
- package/dist/lib/classes/ColourPalettes/index.js +165 -0
- package/dist/lib/classes/CustomPresets/index.d.ts +14 -15
- package/dist/lib/classes/CustomPresets/index.js +25 -10
- package/dist/lib/classes/LayerAutosave/index.d.ts +9 -2
- package/dist/lib/classes/LayerAutosave/index.js +16 -6
- package/dist/lib/classes/PaintCanvas/index.d.ts +111 -23
- package/dist/lib/classes/PaintCanvas/index.js +219 -58
- package/dist/lib/classes/Palette/index.d.ts +3 -2
- package/dist/lib/classes/Palette/index.js +3 -2
- package/dist/lib/classes/ProfileGraphs/index.d.ts +13 -2
- package/dist/lib/classes/ProfileGraphs/index.js +22 -2
- package/dist/lib/classes/RemoteDocumentAutosave/index.d.ts +73 -0
- package/dist/lib/classes/RemoteDocumentAutosave/index.js +119 -0
- package/dist/lib/classes/SettingsAutosave/index.d.ts +7 -3
- package/dist/lib/classes/SettingsAutosave/index.js +28 -7
- package/dist/lib/classes/SettingsExtensions/index.d.ts +67 -0
- package/dist/lib/classes/SettingsExtensions/index.js +88 -0
- package/dist/lib/document/index.d.ts +61 -4
- package/dist/lib/document/index.js +173 -4
- package/dist/lib/document/schema.d.ts +154 -39
- package/dist/lib/document/schema.js +91 -25
- package/dist/lib/messages/schema.d.ts +176 -74
- package/dist/lib/messages/schema.js +2 -1
- package/dist/lib/palette/index.d.ts +8 -42
- package/dist/lib/palette/index.js +26 -59
- package/dist/lib/palette/schema.d.ts +111 -22
- package/dist/lib/palette/schema.js +51 -26
- package/dist/lib/presets/index.d.ts +1 -9
- package/dist/lib/presets/index.js +4 -10
- package/dist/lib/presets/schema.d.ts +118 -73
- package/dist/lib/presets/schema.js +28 -60
- package/dist/lib/profiles/profileFile/index.d.ts +10 -0
- package/dist/lib/profiles/profileFile/index.js +19 -0
- package/dist/lib/profiles/schema.d.ts +96 -3
- package/dist/lib/profiles/schema.js +31 -7
- package/dist/lib/schemas/index.d.ts +42 -0
- package/dist/lib/schemas/index.js +60 -0
- package/dist/lib/settings/index.d.ts +37 -22
- package/dist/lib/settings/index.js +78 -37
- package/dist/lib/settings/schema.d.ts +198 -76
- package/dist/lib/settings/schema.js +92 -86
- package/dist/lib/storage/index.d.ts +82 -3
- package/dist/lib/storage/index.js +82 -5
- package/dist/lib/validation/validators.generated.d.ts +19 -8
- package/dist/lib/validation/validators.generated.js +44716 -18900
- package/dist/lib/version/index.js +1 -1
- package/dist/locales/en-GB.js +23 -5
- package/dist/locales/en-US.js +23 -5
- package/dist/locales/fr.js +23 -5
- package/dist/locales/ja.js +23 -5
- package/dist/locales/ko.js +23 -5
- package/dist/locales/zh-Hans.js +23 -5
- package/dist/locales/zh-Hant.js +23 -5
- package/dist/package.js +1 -1
- package/dist/testing/app.d.ts +6 -2
- package/dist/testing/app.js +7 -2
- package/dist/testing/documentStore.d.ts +26 -0
- package/dist/testing/documentStore.js +31 -0
- package/dist/ui/elements/PaintCanvas/index.d.ts +6 -2
- package/dist/ui/elements/PaintCanvas/index.js +20 -6
- package/dist/ui/elements/PcAppSettings/index.d.ts +5 -6
- package/dist/ui/elements/PcAppSettings/index.js +17 -27
- package/dist/ui/elements/PcPanelBrushes/index.d.ts +1 -1
- package/dist/ui/elements/PcPanelBrushes/index.js +22 -28
- package/dist/ui/elements/PcPanelBrushes/style.js +1 -1
- package/dist/ui/elements/PcPanelColours/index.d.ts +56 -19
- package/dist/ui/elements/PcPanelColours/index.js +251 -104
- package/dist/ui/elements/PcPanelColours/style.js +1 -1
- package/dist/ui/elements/PcStats/index.d.ts +8 -4
- package/dist/ui/elements/PcStats/index.js +39 -5
- package/locales/en-GB.json +23 -5
- package/locales/en-US.json +23 -5
- package/locales/fr.json +23 -5
- package/locales/ja.json +23 -5
- package/locales/ko.json +23 -5
- package/locales/zh-Hans.json +23 -5
- package/locales/zh-Hant.json +23 -5
- package/package.json +2 -1
|
@@ -157,6 +157,8 @@ export declare class PaintCanvasElement extends PcElement {
|
|
|
157
157
|
private watchedAutosave?;
|
|
158
158
|
/** Keeps the app settings under the `settings-store` name, if any */
|
|
159
159
|
private ownSettingsAutosave?;
|
|
160
|
+
/** The asset stores the layout gave the canvas for `settings-store`, if any */
|
|
161
|
+
private ownAssetStores?;
|
|
160
162
|
/** Stops keeping the rendering chosen in the canvas's UI settings under the `settings-store` name, if kept */
|
|
161
163
|
private stopKeepingRendering?;
|
|
162
164
|
/** Whether drawing was blocked when shortcuts were last watched */
|
|
@@ -205,8 +207,10 @@ export declare class PaintCanvasElement extends PcElement {
|
|
|
205
207
|
/** Keeps the app settings under the `settings-store` name, if any (e.g. to wait until they are restored with `ready`) */
|
|
206
208
|
get settingsAutosave(): SettingsAutosave | undefined;
|
|
207
209
|
/**
|
|
208
|
-
* Keep the canvas's app settings
|
|
209
|
-
* saves any change waiting to be saved).
|
|
210
|
+
* Keep the canvas's app settings and assets (brush presets, colour palettes, profile graphs) under the
|
|
211
|
+
* `settings-store` name, stopping the previous settings autosave (which saves any change waiting to be saved). Asset
|
|
212
|
+
* stores the layout gave a previous canvas, or this one under another name, are taken back; ones the implementer gave
|
|
213
|
+
* are replaced only when there's a name.
|
|
210
214
|
*/
|
|
211
215
|
private useSettingsStore;
|
|
212
216
|
/**
|
|
@@ -5,7 +5,8 @@ import ChangeController from "../../ChangeController/index.js";
|
|
|
5
5
|
import PaintCanvas, { Panel } from "../../../lib/classes/PaintCanvas/index.js";
|
|
6
6
|
import KeyboardShortcuts, { SHORTCUT_EVENT } from "../../../lib/classes/KeyboardShortcuts/index.js";
|
|
7
7
|
import { isTouchDevice } from "../../../lib/classes/InputSettings/index.js";
|
|
8
|
-
import IndexedDbLayerStore, {
|
|
8
|
+
import IndexedDbLayerStore, { indexedDbStores, loadRenderingChoice, saveRenderingChoice } from "../../../lib/storage/index.js";
|
|
9
|
+
import { ASSET_SYNC_ERROR_EVENT } from "../../../lib/classes/AssetSync/index.js";
|
|
9
10
|
import SettingsAutosave, { SETTINGS_AUTOSAVE_ERROR_EVENT } from "../../../lib/classes/SettingsAutosave/index.js";
|
|
10
11
|
import { AUTOSAVE_ERROR_EVENT, AutosaveState } from "../../../lib/classes/LayerAutosave/index.js";
|
|
11
12
|
import { isOwnAuthor } from "../../../lib/brushes/authors/index.js";
|
|
@@ -130,6 +131,8 @@ var PaintCanvasElement = class extends PcElement {
|
|
|
130
131
|
watchedAutosave;
|
|
131
132
|
/** Keeps the app settings under the `settings-store` name, if any */
|
|
132
133
|
ownSettingsAutosave;
|
|
134
|
+
/** The asset stores the layout gave the canvas for `settings-store`, if any */
|
|
135
|
+
ownAssetStores;
|
|
133
136
|
/** Stops keeping the rendering chosen in the canvas's UI settings under the `settings-store` name, if kept */
|
|
134
137
|
stopKeepingRendering;
|
|
135
138
|
/** Whether drawing was blocked when shortcuts were last watched */
|
|
@@ -218,7 +221,7 @@ var PaintCanvasElement = class extends PcElement {
|
|
|
218
221
|
willUpdate(changed) {
|
|
219
222
|
super.willUpdate(changed);
|
|
220
223
|
if (changed.has("app") || changed.has("store")) this.useStore(changed.get("app"));
|
|
221
|
-
if (changed.has("app") || changed.has("settingsStore")) this.useSettingsStore();
|
|
224
|
+
if (changed.has("app") || changed.has("settingsStore")) this.useSettingsStore(changed.get("app"));
|
|
222
225
|
this.watchAutosaveErrors();
|
|
223
226
|
if (this.isConnected && (changed.has("app") || changed.has("shortcuts") || this.blocked !== this.blockedShortcuts)) this.watchShortcuts();
|
|
224
227
|
}
|
|
@@ -284,16 +287,27 @@ var PaintCanvasElement = class extends PcElement {
|
|
|
284
287
|
return this.ownSettingsAutosave;
|
|
285
288
|
}
|
|
286
289
|
/**
|
|
287
|
-
* Keep the canvas's app settings
|
|
288
|
-
* saves any change waiting to be saved).
|
|
290
|
+
* Keep the canvas's app settings and assets (brush presets, colour palettes, profile graphs) under the
|
|
291
|
+
* `settings-store` name, stopping the previous settings autosave (which saves any change waiting to be saved). Asset
|
|
292
|
+
* stores the layout gave a previous canvas, or this one under another name, are taken back; ones the implementer gave
|
|
293
|
+
* are replaced only when there's a name.
|
|
289
294
|
*/
|
|
290
|
-
useSettingsStore() {
|
|
295
|
+
useSettingsStore(previousApp) {
|
|
296
|
+
const app = this.app;
|
|
291
297
|
this.ownSettingsAutosave?.stop();
|
|
292
298
|
this.stopKeepingRendering?.();
|
|
293
299
|
const name = this.settingsStore || void 0;
|
|
294
300
|
this.stopKeepingRendering = name === void 0 ? void 0 : this.keepRendering(name);
|
|
295
|
-
|
|
301
|
+
const { settings, ...assets } = name === void 0 ? { settings: void 0 } : indexedDbStores(name);
|
|
302
|
+
this.ownSettingsAutosave = settings && new SettingsAutosave(app, settings);
|
|
296
303
|
this.ownSettingsAutosave?.addEventListener(SETTINGS_AUTOSAVE_ERROR_EVENT, this.onSettingsAutosaveError);
|
|
304
|
+
const own = this.ownAssetStores;
|
|
305
|
+
const isOwn = (canvas) => own !== void 0 && canvas?.assetStores.brushes === own.brushes;
|
|
306
|
+
if (previousApp !== app && isOwn(previousApp)) previousApp?.useAssetStores({});
|
|
307
|
+
if (settings) app.useAssetStores(assets);
|
|
308
|
+
else if (isOwn(app)) app.useAssetStores({});
|
|
309
|
+
this.ownAssetStores = settings ? assets : void 0;
|
|
310
|
+
app.profileSync?.addEventListener(ASSET_SYNC_ERROR_EVENT, this.onSettingsAutosaveError);
|
|
297
311
|
}
|
|
298
312
|
/**
|
|
299
313
|
* Keep the rendering chosen in the canvas's UI settings (e.g. when they're restored, imported or changed) under a
|
|
@@ -9,8 +9,8 @@ import { type SaveMethod } from "../../../lib/rendering/screenshot";
|
|
|
9
9
|
* The user's app settings: a "Draw with the GPU" switch (the user's `ui.data.rendering`, used from the next start, so it
|
|
10
10
|
* says when the page needs reloading), and buttons: "Keyboard shortcuts", which opens a window to change them (see
|
|
11
11
|
* `pc-shortcut-settings`), and "Import settings" and "Export settings", which read and write a settings JSON file (input
|
|
12
|
-
* settings, keyboard shortcuts, colour
|
|
13
|
-
* `<pc-dialog-window>` over the whole page; it closes with its ⨉ button, Escape or a press outside it, and focus goes
|
|
12
|
+
* settings, keyboard shortcuts, colours, the user's colour palettes, profile graphs and brush presets, theme, language,
|
|
13
|
+
* rendering, and settings wrapper apps added). The window is a shaded `<pc-dialog-window>` over the whole page; it closes with its ⨉ button, Escape or a press outside it, and focus goes
|
|
14
14
|
* back to the button. Fires `pc-toast` after importing, or when importing or exporting fails.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
@@ -47,15 +47,14 @@ export declare class PcAppSettings extends PcElement {
|
|
|
47
47
|
/** Close the keyboard shortcuts window */
|
|
48
48
|
closeShortcuts(): void;
|
|
49
49
|
/**
|
|
50
|
-
* Import the settings in a settings file, using the parts it has
|
|
50
|
+
* Import the settings in a settings file, using the parts it has (the user's colour palettes, profile graphs and brush
|
|
51
|
+
* presets are added to theirs).
|
|
51
52
|
*/
|
|
52
53
|
importFile(file: File): Promise<void>;
|
|
53
54
|
/**
|
|
54
|
-
* Export the settings as a settings file.
|
|
55
|
+
* Export the settings, with the user's colour palettes, profile graphs and brush presets, as a settings file.
|
|
55
56
|
*/
|
|
56
57
|
exportFile(): Promise<void>;
|
|
57
|
-
/** Show a settings file error (one of `SETTINGS_FILE_ERRORS`) in the chosen language */
|
|
58
|
-
private toastError;
|
|
59
58
|
/** The keyboard shortcuts window, with its contents only while open */
|
|
60
59
|
private renderShortcuts;
|
|
61
60
|
/**
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { SETTINGS_FILE_FORMAT } from "../../../lib/settings/schema.js";
|
|
2
1
|
import { ICON_CONTROLS_CSS, PILLS_CSS, WINDOWS_CSS } from "../../styles/index.js";
|
|
3
2
|
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
4
3
|
import ChangeController from "../../ChangeController/index.js";
|
|
5
4
|
import "../PcShortcutSettings/index.js";
|
|
6
5
|
import "../PcToggleCheckbox/index.js";
|
|
7
6
|
import "../PcDialogWindow/index.js";
|
|
8
|
-
import {
|
|
7
|
+
import { AssetFileError } from "../../../lib/assets/index.js";
|
|
8
|
+
import { applySettings, collectSettings, exportSettingsFile, parseSettingsFile, settingsFileName } from "../../../lib/settings/index.js";
|
|
9
9
|
import { JSON_FILE_TYPE, saveFile } from "../../../lib/rendering/screenshot/index.js";
|
|
10
10
|
import { css, html, nothing, unsafeCSS } from "lit";
|
|
11
11
|
// src/ui/elements/PcAppSettings/index.ts
|
|
12
|
-
/** Translation keys of the settings file
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
/** Translation keys of the messages shown when importing a settings file fails, by reason */
|
|
13
|
+
var IMPORT_ERROR_KEYS = {
|
|
14
|
+
invalid: "paintCanvas.settings.fileIncompatible",
|
|
15
|
+
unsupported: "paintCanvas.settings.fileUnsupported"
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
18
|
* The user's app settings: a "Draw with the GPU" switch (the user's `ui.data.rendering`, used from the next start, so it
|
|
19
19
|
* says when the page needs reloading), and buttons: "Keyboard shortcuts", which opens a window to change them (see
|
|
20
20
|
* `pc-shortcut-settings`), and "Import settings" and "Export settings", which read and write a settings JSON file (input
|
|
21
|
-
* settings, keyboard shortcuts, colour
|
|
22
|
-
* `<pc-dialog-window>` over the whole page; it closes with its ⨉ button, Escape or a press outside it, and focus goes
|
|
21
|
+
* settings, keyboard shortcuts, colours, the user's colour palettes, profile graphs and brush presets, theme, language,
|
|
22
|
+
* rendering, and settings wrapper apps added). The window is a shaded `<pc-dialog-window>` over the whole page; it closes with its ⨉ button, Escape or a press outside it, and focus goes
|
|
23
23
|
* back to the button. Fires `pc-toast` after importing, or when importing or exporting fails.
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
@@ -85,36 +85,33 @@ var PcAppSettings = class extends PcElement {
|
|
|
85
85
|
this.shortcutsOpen = false;
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
|
-
* Import the settings in a settings file, using the parts it has
|
|
88
|
+
* Import the settings in a settings file, using the parts it has (the user's colour palettes, profile graphs and brush
|
|
89
|
+
* presets are added to theirs).
|
|
89
90
|
*/
|
|
90
91
|
async importFile(file) {
|
|
91
92
|
const app = this.app;
|
|
92
93
|
if (!app) return;
|
|
93
|
-
let text;
|
|
94
94
|
try {
|
|
95
|
-
|
|
96
|
-
} catch {
|
|
97
|
-
this.toastError(SETTINGS_FILE_ERRORS.read);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
applySettings(app, parseSettingsFile(text, [app.names.settingsFileFormat, SETTINGS_FILE_FORMAT]));
|
|
95
|
+
await applySettings(app, parseSettingsFile(await file.text()));
|
|
102
96
|
emit(this, "pc-toast", {
|
|
103
97
|
message: this.t("paintCanvas.settings.imported"),
|
|
104
98
|
kind: "success"
|
|
105
99
|
});
|
|
106
100
|
} catch (error) {
|
|
107
|
-
this
|
|
101
|
+
emit(this, "pc-toast", {
|
|
102
|
+
message: this.t(error instanceof AssetFileError && IMPORT_ERROR_KEYS[error.reason] || "paintCanvas.settings.fileReadFailed"),
|
|
103
|
+
kind: "error"
|
|
104
|
+
});
|
|
108
105
|
}
|
|
109
106
|
}
|
|
110
107
|
/**
|
|
111
|
-
* Export the settings as a settings file.
|
|
108
|
+
* Export the settings, with the user's colour palettes, profile graphs and brush presets, as a settings file.
|
|
112
109
|
*/
|
|
113
110
|
async exportFile() {
|
|
114
111
|
const app = this.app;
|
|
115
112
|
if (!app) return;
|
|
116
113
|
try {
|
|
117
|
-
await this.saveFile(new Blob([exportSettingsFile(collectSettings(app)
|
|
114
|
+
await this.saveFile(new Blob([exportSettingsFile(collectSettings(app))], { type: "application/json" }), settingsFileName(void 0, app.names.filePrefix));
|
|
118
115
|
} catch {
|
|
119
116
|
emit(this, "pc-toast", {
|
|
120
117
|
message: this.t("paintCanvas.settings.exportFailed"),
|
|
@@ -122,13 +119,6 @@ var PcAppSettings = class extends PcElement {
|
|
|
122
119
|
});
|
|
123
120
|
}
|
|
124
121
|
}
|
|
125
|
-
/** Show a settings file error (one of `SETTINGS_FILE_ERRORS`) in the chosen language */
|
|
126
|
-
toastError(message) {
|
|
127
|
-
emit(this, "pc-toast", {
|
|
128
|
-
message: this.t(SETTINGS_FILE_ERROR_KEYS[message]),
|
|
129
|
-
kind: "error"
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
122
|
/** The keyboard shortcuts window, with its contents only while open */
|
|
133
123
|
renderShortcuts(app) {
|
|
134
124
|
return html`<pc-dialog-window
|
|
@@ -102,7 +102,7 @@ export declare class PcPanelBrushes extends PcPanel {
|
|
|
102
102
|
*/
|
|
103
103
|
exportFile(): Promise<void>;
|
|
104
104
|
/**
|
|
105
|
-
*
|
|
105
|
+
* The message, in the chosen language, for importing or exporting a preset file failing.
|
|
106
106
|
*/
|
|
107
107
|
private presetFileError;
|
|
108
108
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import style_default from "./style.js";
|
|
2
|
-
import { BRUSH_PRESET_FILE_FORMAT } from "../../../lib/presets/schema.js";
|
|
3
2
|
import { NO_TEXT_SELECTION_CSS, PILLS_CSS, WINDOWS_CSS } from "../../styles/index.js";
|
|
4
3
|
import { defineElement } from "../../base/index.js";
|
|
5
4
|
import { PcPanel } from "../PcPanel/index.js";
|
|
@@ -7,19 +6,25 @@ import { askConfirm, deletePresetQuestion } from "../../ask/index.js";
|
|
|
7
6
|
import "../PcBrushSize/index.js";
|
|
8
7
|
import ChangeController from "../../ChangeController/index.js";
|
|
9
8
|
import { groupPresetsByAuthor } from "../../../lib/brushes/authors/index.js";
|
|
10
|
-
import "../../../lib/
|
|
11
|
-
import {
|
|
9
|
+
import { brushPresetFile } from "../../../lib/brushes/presetFile/index.js";
|
|
10
|
+
import { AssetFileError } from "../../../lib/assets/index.js";
|
|
12
11
|
import { DELETE_CURSOR } from "../../../lib/rendering/cursors/index.js";
|
|
13
12
|
import { JSON_FILE_TYPE, saveFile } from "../../../lib/rendering/screenshot/index.js";
|
|
14
13
|
import { html, nothing, unsafeCSS } from "lit";
|
|
15
14
|
import { styleMap } from "lit/directives/style-map.js";
|
|
16
15
|
// src/ui/elements/PcPanelBrushes/index.ts
|
|
17
|
-
/** Translation keys of the preset file
|
|
16
|
+
/** Translation keys of the messages shown when importing or exporting a preset file fails, by reason */
|
|
18
17
|
var PRESET_FILE_ERROR_KEYS = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
import: {
|
|
19
|
+
invalid: "paintCanvas.presets.fileIncompatible",
|
|
20
|
+
unsupported: "paintCanvas.presets.fileUnsupported"
|
|
21
|
+
},
|
|
22
|
+
export: { empty: "paintCanvas.presets.nothingToExport" }
|
|
23
|
+
};
|
|
24
|
+
/** Translation keys of the messages shown when importing or exporting fails for any other reason */
|
|
25
|
+
var PRESET_FILE_FALLBACK_KEYS = {
|
|
26
|
+
import: "paintCanvas.presets.fileReadFailed",
|
|
27
|
+
export: "paintCanvas.presets.exportFailed"
|
|
23
28
|
};
|
|
24
29
|
/** Size the previews of presets without a family are measured against, so a 50px preset fills its tile */
|
|
25
30
|
var UNGROUPED_FULL_SIZE = 50;
|
|
@@ -149,18 +154,8 @@ var PcPanelBrushes = class extends PcPanel {
|
|
|
149
154
|
async importFile(file) {
|
|
150
155
|
const app = this.app;
|
|
151
156
|
if (!app) return;
|
|
152
|
-
let text;
|
|
153
|
-
try {
|
|
154
|
-
text = await file.text();
|
|
155
|
-
} catch {
|
|
156
|
-
this.emit("pc-toast", {
|
|
157
|
-
message: this.presetFileError(void 0, PRESET_FILE_ERRORS.read),
|
|
158
|
-
kind: "error"
|
|
159
|
-
});
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
157
|
try {
|
|
163
|
-
const presets =
|
|
158
|
+
const presets = brushPresetFile.parse(await file.text());
|
|
164
159
|
await app.customPresets.save(...presets);
|
|
165
160
|
this.emit("pc-toast", {
|
|
166
161
|
message: this.t("paintCanvas.presets.imported", { count: presets.length }),
|
|
@@ -168,7 +163,7 @@ var PcPanelBrushes = class extends PcPanel {
|
|
|
168
163
|
});
|
|
169
164
|
} catch (error) {
|
|
170
165
|
this.emit("pc-toast", {
|
|
171
|
-
message: this.presetFileError(error,
|
|
166
|
+
message: this.presetFileError(error, "import"),
|
|
172
167
|
kind: "error"
|
|
173
168
|
});
|
|
174
169
|
}
|
|
@@ -180,22 +175,21 @@ var PcPanelBrushes = class extends PcPanel {
|
|
|
180
175
|
const app = this.app;
|
|
181
176
|
if (!app) return;
|
|
182
177
|
try {
|
|
183
|
-
const json =
|
|
184
|
-
await this.saveFile(new Blob([json], { type: "application/json" }),
|
|
178
|
+
const json = brushPresetFile.write(app.customPresets.presets);
|
|
179
|
+
await this.saveFile(new Blob([json], { type: "application/json" }), brushPresetFile.fileName(void 0, app.names.filePrefix));
|
|
185
180
|
} catch (error) {
|
|
186
181
|
this.emit("pc-toast", {
|
|
187
|
-
message: this.presetFileError(error,
|
|
182
|
+
message: this.presetFileError(error, "export"),
|
|
188
183
|
kind: "error"
|
|
189
184
|
});
|
|
190
185
|
}
|
|
191
186
|
}
|
|
192
187
|
/**
|
|
193
|
-
*
|
|
188
|
+
* The message, in the chosen language, for importing or exporting a preset file failing.
|
|
194
189
|
*/
|
|
195
|
-
presetFileError(error,
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
return key ? this.t(key) : message;
|
|
190
|
+
presetFileError(error, direction) {
|
|
191
|
+
const key = error instanceof AssetFileError && PRESET_FILE_ERROR_KEYS[direction][error.reason] || PRESET_FILE_FALLBACK_KEYS[direction];
|
|
192
|
+
return this.t(key);
|
|
199
193
|
}
|
|
200
194
|
/**
|
|
201
195
|
* A preset group's heading in the chosen language ("My presets" and "Unknown" are translated; author names aren't).
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// src/ui/elements/PcPanelBrushes/style.css?inline
|
|
2
|
-
var style_default = "/* Narrower than other panels by default (set --pc-panel-width to change it) */\n:host {\n --pc-panel-default-width: 240px;\n}\n/* The current preset on one row: its shape, name and size */\n.current {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 44px;\n padding: 4px 8px;\n border: 1px solid var(--pc-border);\n background: var(--pc-surface);\n}\n.current-shape {\n flex: none;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--pc-text);\n}\n.current-shape.image {\n border-radius: 0;\n mask-repeat: no-repeat;\n mask-size: contain;\n mask-position: center;\n}\n.name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.size {\n flex: none;\n align-self: stretch;\n margin: -4px -8px -4px 0;\n border-left: 1px solid var(--pc-border);\n}\n/* The presets scroll, at most 400px tall, or less so the whole menu fits under the settings bar in a shorter window */\n.presets {\n flex: 1 1 auto;\n min-height: 0;\n max-height: min(400px, calc(100vh - 180px));\n overflow-y: auto;\n}\nh3 {\n margin: 4px 0;\n font-size: 14px;\n}\nul {\n display: grid;\n grid-template-columns: repeat(5, 1fr);\n align-content: start;\n margin: 0;\n padding: 0;\n list-style: none;\n border: 1px solid var(--pc-border);\n background: var(--pc-bar);\n}\n:host([deleting]) li button.custom {\n cursor: var(--pc-delete-cursor);\n}\n/* Create, Import and Export side by side */\n.actions {\n display: grid;\n grid-template-columns: repeat(
|
|
2
|
+
var style_default = "/* Narrower than other panels by default (set --pc-panel-width to change it) */\n:host {\n --pc-panel-default-width: 240px;\n}\n/* The current preset on one row: its shape, name and size */\n.current {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 44px;\n padding: 4px 8px;\n border: 1px solid var(--pc-border);\n background: var(--pc-surface);\n}\n.current-shape {\n flex: none;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--pc-text);\n}\n.current-shape.image {\n border-radius: 0;\n mask-repeat: no-repeat;\n mask-size: contain;\n mask-position: center;\n}\n.name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.size {\n flex: none;\n align-self: stretch;\n margin: -4px -8px -4px 0;\n border-left: 1px solid var(--pc-border);\n}\n/* The presets scroll, at most 400px tall, or less so the whole menu fits under the settings bar in a shorter window */\n.presets {\n flex: 1 1 auto;\n min-height: 0;\n max-height: min(400px, calc(100vh - 180px));\n overflow-y: auto;\n}\nh3 {\n margin: 4px 0;\n font-size: 14px;\n}\nul {\n display: grid;\n grid-template-columns: repeat(5, 1fr);\n align-content: start;\n margin: 0;\n padding: 0;\n list-style: none;\n border: 1px solid var(--pc-border);\n background: var(--pc-bar);\n}\n:host([deleting]) li button.custom {\n cursor: var(--pc-delete-cursor);\n}\n/* Create, Import and Export side by side */\n.actions {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 6px;\n}\n/* New brush has a row of its own, above Import and Export */\n.actions .new-preset {\n grid-column: 1 / -1;\n}\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\nli button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n aspect-ratio: 1;\n padding: 0;\n border: none;\n border-right: 1px solid var(--pc-border);\n border-bottom: 1px solid var(--pc-border);\n background: var(--pc-bar);\n cursor: pointer;\n}\nli button:hover {\n background: var(--pc-surface-hover);\n}\nli button[aria-pressed=\"true\"] {\n background: var(--pc-surface-active);\n}\n.shape {\n background: var(--pc-text);\n border-radius: 50%;\n}\n.shape.image {\n border-radius: 0;\n mask-repeat: no-repeat;\n mask-size: 100% 100%;\n}\n";
|
|
3
3
|
export { style_default as default };
|
|
@@ -2,9 +2,12 @@ import { nothing, type PropertyValues } from "lit";
|
|
|
2
2
|
import { PcPanel } from "../PcPanel";
|
|
3
3
|
import "../PcColourPair";
|
|
4
4
|
import "../PcMenu";
|
|
5
|
+
import "../PcContextMenu";
|
|
5
6
|
import "../PcDialog";
|
|
6
7
|
import type { default as PaintCanvas } from "../../../lib/classes/PaintCanvas";
|
|
7
8
|
import { type Hsl, type Rgb } from "../../../lib/utils/colour";
|
|
9
|
+
import { type ColourPalette } from "../../../lib/palette";
|
|
10
|
+
import { type ConfirmFn, type PromptFn } from "../../ask";
|
|
8
11
|
import { type SaveMethod } from "../../../lib/rendering/screenshot";
|
|
9
12
|
/** The colour models the sliders can show */
|
|
10
13
|
export type ColourModel = "rgb" | "hsl";
|
|
@@ -21,13 +24,31 @@ export type ColourModel = "rgb" | "hsl";
|
|
|
21
24
|
export declare const channelGradient: (key: string, rgb: Rgb, hsl: Hsl) => string;
|
|
22
25
|
/** How long a touch is held on a saved colour to open its menu (milliseconds) */
|
|
23
26
|
export declare const LONG_PRESS_MS = 500;
|
|
27
|
+
/** A palette shown in the panel: one of the user's own, or the one PaintCanvas comes with */
|
|
28
|
+
interface ShownPalette {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
colours: readonly string[];
|
|
32
|
+
/** Whether it's one of the user's own (which can be renamed, exported and deleted) */
|
|
33
|
+
own: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** A saved colour: its palette's ID and its position */
|
|
36
|
+
interface SwatchRef {
|
|
37
|
+
palette: string;
|
|
38
|
+
index: number;
|
|
39
|
+
}
|
|
40
|
+
/** Actions in a palette's menu */
|
|
41
|
+
declare const PALETTE_ACTIONS: readonly ["rename", "export", "delete"];
|
|
24
42
|
/**
|
|
25
43
|
* The colour palette menu: the foreground and background colours (the selected one is configured), its hex value, RGB
|
|
26
|
-
* and HSL sliders, the
|
|
44
|
+
* and HSL sliders, the colour palettes (the user's own above the one PaintCanvas comes with), and buttons to make a
|
|
45
|
+
* palette and to import and export the user's palettes as a JSON file.
|
|
27
46
|
*
|
|
28
47
|
* - Pressing the foreground or background colour selects it.
|
|
29
|
-
* - Pressing a saved colour sets the selected colour
|
|
30
|
-
*
|
|
48
|
+
* - Pressing a saved colour sets the selected colour (changing it afterwards doesn't change the palette); a palette's [+]
|
|
49
|
+
* saves the selected colour in it. PaintCanvas's palette can't be changed.
|
|
50
|
+
* - Each of the user's palettes has a ⋮ menu to rename, export or delete it (deleting asks first).
|
|
51
|
+
* - A colour in one of the user's palettes is deleted, after asking, by clicking it with Alt/Option held (the cursor shows an "X"), from its
|
|
31
52
|
* menu (right-click, a long press on touch screens, or the context menu key), or with Delete or Backspace. Arrow keys,
|
|
32
53
|
* Home and End move between saved colours.
|
|
33
54
|
* - Escape closes it (closes the canvas's open panel).
|
|
@@ -82,19 +103,22 @@ export declare class PcPanelColours extends PcPanel {
|
|
|
82
103
|
/** The hex value being typed, while it differs from the colour */
|
|
83
104
|
hexDraft?: string;
|
|
84
105
|
/** The saved colour whose menu is open, and where */
|
|
85
|
-
menu?: {
|
|
86
|
-
index: number;
|
|
106
|
+
menu?: SwatchRef & {
|
|
87
107
|
x: number;
|
|
88
108
|
y: number;
|
|
89
109
|
};
|
|
90
110
|
/** The saved colour being deleted, while asking */
|
|
91
|
-
confirming?:
|
|
111
|
+
confirming?: SwatchRef;
|
|
112
|
+
/** Asks the user to confirm, in a dialog (replaceable for tests) */
|
|
113
|
+
confirm: ConfirmFn;
|
|
114
|
+
/** Asks the user for text, in a dialog (replaceable for tests) */
|
|
115
|
+
prompt: PromptFn;
|
|
92
116
|
/** Saves exported files (replaceable for tests) */
|
|
93
117
|
saveFile: (blob: Blob, name: string) => Promise<SaveMethod | undefined>;
|
|
94
118
|
/** The HSL values shown, kept while they give the selected colour (so hue stays put for greys) */
|
|
95
119
|
private hsl;
|
|
96
|
-
/** The saved colour that is reached with Tab (the others with arrow keys) */
|
|
97
|
-
private
|
|
120
|
+
/** The saved colour that is reached with Tab in its palette (the others with arrow keys; other palettes' first) */
|
|
121
|
+
private focused;
|
|
98
122
|
/** A touch being held on a saved colour, until it opens its menu */
|
|
99
123
|
private press?;
|
|
100
124
|
/** Whether a long press opened a menu, so the click that follows is ignored */
|
|
@@ -108,6 +132,12 @@ export declare class PcPanelColours extends PcPanel {
|
|
|
108
132
|
/** The selected colour's value, e.g. `#000000` */
|
|
109
133
|
get colour(): string;
|
|
110
134
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
135
|
+
/** The palettes shown: the user's own, then the one PaintCanvas comes with (named after the app) */
|
|
136
|
+
shown(): ShownPalette[];
|
|
137
|
+
/** A palette's colours */
|
|
138
|
+
private coloursOf;
|
|
139
|
+
/** The saved colour at a position */
|
|
140
|
+
private colourAt;
|
|
111
141
|
/** Set the selected colour */
|
|
112
142
|
private setColour;
|
|
113
143
|
/** Select the pressed colour */
|
|
@@ -122,9 +152,9 @@ export declare class PcPanelColours extends PcPanel {
|
|
|
122
152
|
private selectModel;
|
|
123
153
|
/** Change one channel of the colour model shown */
|
|
124
154
|
private onChannel;
|
|
125
|
-
/** Set the selected colour from a saved colour, or ask to delete
|
|
155
|
+
/** Set the selected colour from a saved colour, or ask to delete one of the user's with Alt/Option held */
|
|
126
156
|
private onSwatchClick;
|
|
127
|
-
/** Open a
|
|
157
|
+
/** Open the menu of a colour in one of the user's palettes where it was right-clicked */
|
|
128
158
|
private onSwatchContextMenu;
|
|
129
159
|
/** Start waiting for a touch held on a saved colour to open its menu */
|
|
130
160
|
private onSwatchPointerDown;
|
|
@@ -137,30 +167,36 @@ export declare class PcPanelColours extends PcPanel {
|
|
|
137
167
|
* keyboard shortcuts (e.g. Delete doesn't also delete the masked image data).
|
|
138
168
|
*/
|
|
139
169
|
private onSwatchKeyDown;
|
|
140
|
-
/** How many saved colours fit in a row */
|
|
170
|
+
/** How many saved colours fit in a row of a palette */
|
|
141
171
|
private columns;
|
|
142
172
|
/** Focus a saved colour */
|
|
143
173
|
private focusSwatch;
|
|
144
|
-
/** Save the selected colour */
|
|
174
|
+
/** Save the selected colour in one of the user's palettes */
|
|
145
175
|
private onAdd;
|
|
146
176
|
/** Delete the saved colour that was asked about, if confirmed */
|
|
147
177
|
private onConfirm;
|
|
178
|
+
/**
|
|
179
|
+
* Make a palette, asking for its name. The user is its author (see `PaintCanvas.author`).
|
|
180
|
+
*/
|
|
181
|
+
createPalette(): Promise<ColourPalette | undefined>;
|
|
182
|
+
/**
|
|
183
|
+
* Do one of a palette's menu actions: rename it (asking for a name), export it, or delete it (asking first).
|
|
184
|
+
*/
|
|
185
|
+
actOnPalette(id: string, action: (typeof PALETTE_ACTIONS)[number]): Promise<void>;
|
|
148
186
|
/** Close the palette with Escape (unless a dialog or menu is open, which closes first) */
|
|
149
187
|
private onKeyDown;
|
|
150
188
|
/**
|
|
151
|
-
* Import the
|
|
189
|
+
* Import the palettes in a colour palette file as the user's own, replacing ones with the same IDs.
|
|
152
190
|
*/
|
|
153
191
|
importFile(file: File): Promise<void>;
|
|
154
192
|
/**
|
|
155
|
-
* Export the
|
|
193
|
+
* Export palettes (the user's own by default) as a colour palette file, or say there are none.
|
|
156
194
|
*/
|
|
157
|
-
exportFile(): Promise<void>;
|
|
158
|
-
/** Show a palette file error (one of `PALETTE_FILE_ERRORS`) in the chosen language */
|
|
159
|
-
private toastError;
|
|
195
|
+
exportFile(palettes?: readonly ColourPalette[]): Promise<void>;
|
|
160
196
|
/** The colour model tabs and the selected model's sliders */
|
|
161
197
|
private renderChannels;
|
|
162
|
-
/**
|
|
163
|
-
private
|
|
198
|
+
/** A palette: its name (and the ⋮ menu of the user's own), its colours and its [+] button */
|
|
199
|
+
private renderPalette;
|
|
164
200
|
/** The saved colour's menu, while open */
|
|
165
201
|
private renderMenu;
|
|
166
202
|
/** The dialog asking before deleting a saved colour, while asking */
|
|
@@ -169,3 +205,4 @@ export declare class PcPanelColours extends PcPanel {
|
|
|
169
205
|
protected get defaultLabel(): string;
|
|
170
206
|
protected renderBody(): import("lit").TemplateResult<1> | typeof nothing;
|
|
171
207
|
}
|
|
208
|
+
export {};
|