@lvl99dotcom/paintcanvas 0.5.0 → 0.6.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.
Files changed (97) hide show
  1. package/dist/lib/brushes/configRanges/index.d.ts +17 -0
  2. package/dist/lib/brushes/configRanges/index.js +31 -1
  3. package/dist/lib/brushes/params/index.d.ts +2 -1
  4. package/dist/lib/brushes/params/index.js +7 -4
  5. package/dist/lib/brushes/types/index.d.ts +8 -0
  6. package/dist/lib/classes/Layer/index.d.ts +10 -0
  7. package/dist/lib/classes/Layer/index.js +15 -1
  8. package/dist/lib/classes/LayerAutosave/index.d.ts +9 -15
  9. package/dist/lib/classes/LayerAutosave/index.js +30 -43
  10. package/dist/lib/classes/LayerStack/index.d.ts +15 -0
  11. package/dist/lib/classes/LayerStack/index.js +26 -2
  12. package/dist/lib/classes/PaintCanvas/index.d.ts +26 -3
  13. package/dist/lib/classes/PaintCanvas/index.js +39 -12
  14. package/dist/lib/classes/PngEncoder/index.d.ts +41 -0
  15. package/dist/lib/classes/PngEncoder/index.js +104 -0
  16. package/dist/lib/classes/ProfileGraphs/index.d.ts +87 -0
  17. package/dist/lib/classes/ProfileGraphs/index.js +148 -0
  18. package/dist/lib/classes/SettingsAutosave/index.d.ts +1 -1
  19. package/dist/lib/classes/SettingsAutosave/index.js +2 -1
  20. package/dist/lib/messages/schema.d.ts +720 -0
  21. package/dist/lib/presets/schema.d.ts +360 -0
  22. package/dist/lib/presets/schema.js +8 -1
  23. package/dist/lib/profiles/index.d.ts +61 -0
  24. package/dist/lib/profiles/index.js +131 -0
  25. package/dist/lib/profiles/schema.d.ts +73 -0
  26. package/dist/lib/profiles/schema.js +53 -0
  27. package/dist/lib/rendering/sample/index.d.ts +11 -0
  28. package/dist/lib/rendering/sample/index.js +36 -5
  29. package/dist/lib/settings/index.d.ts +2 -1
  30. package/dist/lib/settings/index.js +4 -1
  31. package/dist/lib/settings/schema.d.ts +49 -0
  32. package/dist/lib/settings/schema.js +6 -0
  33. package/dist/lib/validation/validators.generated.js +13064 -3696
  34. package/dist/locales/en-GB.js +30 -0
  35. package/dist/locales/en-US.js +30 -0
  36. package/dist/locales/fr.js +30 -0
  37. package/dist/locales/ja.js +30 -0
  38. package/dist/locales/ko.js +30 -0
  39. package/dist/locales/zh-Hans.js +30 -0
  40. package/dist/locales/zh-Hant.js +30 -0
  41. package/dist/package.js +1 -1
  42. package/dist/ui/ask/index.d.ts +48 -0
  43. package/dist/ui/ask/index.js +67 -0
  44. package/dist/ui/base/index.d.ts +8 -1
  45. package/dist/ui/base/index.js +19 -4
  46. package/dist/ui/elements/PaintCanvas/index.js +3 -1
  47. package/dist/ui/elements/PaintCanvas/style.js +1 -1
  48. package/dist/ui/elements/PcAppSettings/index.d.ts +6 -6
  49. package/dist/ui/elements/PcAppSettings/index.js +21 -65
  50. package/dist/ui/elements/PcBrushConfig/index.d.ts +25 -14
  51. package/dist/ui/elements/PcBrushConfig/index.js +216 -146
  52. package/dist/ui/elements/PcBrushConfig/style.js +1 -1
  53. package/dist/ui/elements/PcBrushTest/index.js +7 -2
  54. package/dist/ui/elements/PcBrushTest/style.js +1 -1
  55. package/dist/ui/elements/PcButton/index.d.ts +12 -3
  56. package/dist/ui/elements/PcButton/index.js +18 -10
  57. package/dist/ui/elements/PcCanvas/index.d.ts +6 -1
  58. package/dist/ui/elements/PcCanvas/index.js +10 -3
  59. package/dist/ui/elements/PcCanvas/style.js +1 -1
  60. package/dist/ui/elements/PcClipboardTools/index.d.ts +5 -4
  61. package/dist/ui/elements/PcClipboardTools/index.js +12 -5
  62. package/dist/ui/elements/PcDialog/index.d.ts +46 -10
  63. package/dist/ui/elements/PcDialog/index.js +102 -51
  64. package/dist/ui/elements/PcDialogWindow/index.d.ts +141 -0
  65. package/dist/ui/elements/PcDialogWindow/index.js +385 -0
  66. package/dist/ui/elements/PcPanelBrushes/index.d.ts +3 -2
  67. package/dist/ui/elements/PcPanelBrushes/index.js +7 -5
  68. package/dist/ui/elements/PcPanelBrushes/style.js +1 -1
  69. package/dist/ui/elements/PcPanelColours/index.js +2 -2
  70. package/dist/ui/elements/PcPanelColours/style.js +1 -1
  71. package/dist/ui/elements/PcPanelLayers/index.js +1 -1
  72. package/dist/ui/elements/PcPanelLayers/style.js +1 -1
  73. package/dist/ui/elements/PcProfileEditor/index.d.ts +103 -0
  74. package/dist/ui/elements/PcProfileEditor/index.js +259 -0
  75. package/dist/ui/elements/PcProfileGraph/index.d.ts +84 -0
  76. package/dist/ui/elements/PcProfileGraph/index.js +317 -0
  77. package/dist/ui/elements/PcShortcutSettings/index.js +9 -13
  78. package/dist/ui/elements/PcSliderRange/index.d.ts +147 -0
  79. package/dist/ui/elements/PcSliderRange/index.js +307 -0
  80. package/dist/ui/elements/PcStats/index.d.ts +19 -4
  81. package/dist/ui/elements/PcStats/index.js +29 -13
  82. package/dist/ui/elements/PcToolSettings/index.js +6 -6
  83. package/dist/ui/icons/images/icon-profile-graph@2x.js +3 -0
  84. package/dist/ui/icons/index.d.ts +1 -1
  85. package/dist/ui/icons/index.js +2 -0
  86. package/dist/ui/index.d.ts +6 -1
  87. package/dist/ui/index.js +6 -1
  88. package/dist/ui/styles/index.d.ts +21 -1
  89. package/dist/ui/styles/index.js +73 -14
  90. package/locales/en-GB.json +30 -0
  91. package/locales/en-US.json +30 -0
  92. package/locales/fr.json +30 -0
  93. package/locales/ja.json +30 -0
  94. package/locales/ko.json +30 -0
  95. package/locales/zh-Hans.json +30 -0
  96. package/locales/zh-Hant.json +30 -0
  97. package/package.json +25 -23
@@ -1,14 +1,15 @@
1
- import { nothing, type PropertyValues } from "lit";
1
+ import { nothing } from "lit";
2
2
  import { PcElement } from "../../base";
3
3
  import "../PcShortcutSettings";
4
+ import "../PcDialogWindow";
4
5
  import type PaintCanvas from "../../../lib/classes/PaintCanvas";
5
6
  import { type SaveMethod } from "../../../lib/rendering/screenshot";
6
7
  /**
7
8
  * Buttons for the user's app settings: "Keyboard shortcuts", which opens a window to change them (see
8
9
  * `pc-shortcut-settings`), and "Import settings" and "Export settings", which read and write a settings JSON file (input
9
- * settings, keyboard shortcuts, colour palette, colours, theme and language). The window is a modal `<dialog>` above the whole page; it
10
- * closes with its Close button, Escape, or a press on the backdrop, and the browser gives focus back to the button. Fires `pc-toast` after importing, or when importing or
11
- * exporting fails.
10
+ * settings, keyboard shortcuts, colour palette, colours, profile graphs, theme and language). The window is a shaded
11
+ * `<pc-dialog-window>` over the whole page; it closes with its ⨉ button, Escape or a press outside it, and focus goes
12
+ * back to the button. Fires `pc-toast` after importing, or when importing or exporting fails.
12
13
  *
13
14
  * @example
14
15
  * html`<pc-app-settings .app=${canvas}></pc-app-settings>`
@@ -40,7 +41,6 @@ export declare class PcAppSettings extends PcElement {
40
41
  /** Saves exported files (replaceable for tests) */
41
42
  saveFile: (blob: Blob, name: string) => Promise<SaveMethod | undefined>;
42
43
  constructor();
43
- protected updated(changed: PropertyValues<this>): void;
44
44
  /** Close the keyboard shortcuts window */
45
45
  closeShortcuts(): void;
46
46
  /**
@@ -53,7 +53,7 @@ export declare class PcAppSettings extends PcElement {
53
53
  exportFile(): Promise<void>;
54
54
  /** Show a settings file error (one of `SETTINGS_FILE_ERRORS`) in the chosen language */
55
55
  private toastError;
56
- /** The keyboard shortcuts window: a modal dialog, with its contents only while open */
56
+ /** The keyboard shortcuts window, with its contents only while open */
57
57
  private renderShortcuts;
58
58
  render(): import("lit").TemplateResult<1> | typeof nothing;
59
59
  }
@@ -2,6 +2,7 @@ import { SETTINGS_FILE_FORMAT } from "../../../lib/settings/schema.js";
2
2
  import { ICON_CONTROLS_CSS, PILLS_CSS, WINDOWS_CSS } from "../../styles/index.js";
3
3
  import { PcElement, defineElement, emit } from "../../base/index.js";
4
4
  import "../PcShortcutSettings/index.js";
5
+ import "../PcDialogWindow/index.js";
5
6
  import { SETTINGS_FILE_ERRORS, SettingsFileError, applySettings, collectSettings, exportSettingsFile, parseSettingsFile, settingsFileName } from "../../../lib/settings/index.js";
6
7
  import { JSON_FILE_TYPE, saveFile } from "../../../lib/rendering/screenshot/index.js";
7
8
  import { css, html, nothing, unsafeCSS } from "lit";
@@ -14,9 +15,9 @@ var SETTINGS_FILE_ERROR_KEYS = {
14
15
  /**
15
16
  * Buttons for the user's app settings: "Keyboard shortcuts", which opens a window to change them (see
16
17
  * `pc-shortcut-settings`), and "Import settings" and "Export settings", which read and write a settings JSON file (input
17
- * settings, keyboard shortcuts, colour palette, colours, theme and language). The window is a modal `<dialog>` above the whole page; it
18
- * closes with its Close button, Escape, or a press on the backdrop, and the browser gives focus back to the button. Fires `pc-toast` after importing, or when importing or
19
- * exporting fails.
18
+ * settings, keyboard shortcuts, colour palette, colours, profile graphs, theme and language). The window is a shaded
19
+ * `<pc-dialog-window>` over the whole page; it closes with its ⨉ button, Escape or a press outside it, and focus goes
20
+ * back to the button. Fires `pc-toast` after importing, or when importing or exporting fails.
20
21
  *
21
22
  * @example
22
23
  * html`<pc-app-settings .app=${canvas}></pc-app-settings>`
@@ -48,32 +49,8 @@ var PcAppSettings = class extends PcElement {
48
49
  flex-wrap: wrap;
49
50
  gap: var(--pc-space-2);
50
51
  }
51
- /* A modal window in the browser's top layer, above everything on the page */
52
- dialog {
53
- box-sizing: border-box;
54
- width: min(480px, calc(100vw - 2 * var(--pc-space-3)));
55
- max-height: calc(100vh - 2 * var(--pc-space-3));
56
- padding: 0;
57
- border: 0;
58
- border-radius: var(--pc-radius);
59
- background: var(--pc-surface-raised);
60
- color: var(--pc-text);
61
- box-shadow: var(--pc-shadow);
62
- }
63
- dialog::backdrop {
64
- background: var(--pc-backdrop);
65
- }
66
- .window {
67
- display: flex;
68
- flex-direction: column;
69
- gap: var(--pc-space-3);
70
- box-shadow: none;
71
- }
72
- .header {
73
- display: flex;
74
- gap: var(--pc-space-2);
75
- align-items: center;
76
- justify-content: space-between;
52
+ pc-dialog-window {
53
+ --pc-dialog-width: 480px;
77
54
  }
78
55
  h2 {
79
56
  margin: 0;
@@ -87,13 +64,6 @@ var PcAppSettings = class extends PcElement {
87
64
  super();
88
65
  this.shortcutsOpen = false;
89
66
  }
90
- updated(changed) {
91
- if (!changed.has("shortcutsOpen")) return;
92
- const dialog = this.renderRoot.querySelector("dialog");
93
- if (!dialog) return;
94
- if (this.shortcutsOpen && !dialog.open) dialog.showModal();
95
- else if (!this.shortcutsOpen && dialog.open) dialog.close();
96
- }
97
67
  /** Close the keyboard shortcuts window */
98
68
  closeShortcuts() {
99
69
  this.shortcutsOpen = false;
@@ -143,34 +113,20 @@ var PcAppSettings = class extends PcElement {
143
113
  kind: "error"
144
114
  });
145
115
  }
146
- /** The keyboard shortcuts window: a modal dialog, with its contents only while open */
116
+ /** The keyboard shortcuts window, with its contents only while open */
147
117
  renderShortcuts(app) {
148
- return html`<dialog
149
- aria-labelledby="shortcuts-title"
150
- @close=${() => this.closeShortcuts()}
151
- @click=${(e) => {
152
- if (e.target === e.currentTarget) this.closeShortcuts();
153
- }}
118
+ return html`<pc-dialog-window
119
+ class="shortcuts-window"
120
+ shaded
121
+ ?open=${this.shortcutsOpen}
122
+ @pc-dismiss=${() => this.closeShortcuts()}
154
123
  >
155
- ${this.shortcutsOpen ? html`<div class="window">
156
- <div class="header">
157
- <h2 id="shortcuts-title">
158
- ${this.t("paintCanvas.shortcuts.title")}
159
- </h2>
160
- <button
161
- type="button"
162
- class="close dismiss"
163
- autofocus
164
- @click=${() => this.closeShortcuts()}
165
- >
166
- ${this.t("paintCanvas.common.close")}
167
- </button>
168
- </div>
169
- <pc-shortcut-settings
170
- .settings=${app.shortcuts}
171
- ></pc-shortcut-settings>
172
- </div>` : nothing}
173
- </dialog>`;
124
+ <h2 slot="header-middle">${this.t("paintCanvas.shortcuts.title")}</h2>
125
+ ${this.shortcutsOpen ? html`<pc-shortcut-settings
126
+ slot="body"
127
+ .settings=${app.shortcuts}
128
+ ></pc-shortcut-settings>` : nothing}
129
+ </pc-dialog-window>`;
174
130
  }
175
131
  render() {
176
132
  const app = this.app;
@@ -178,7 +134,7 @@ var PcAppSettings = class extends PcElement {
178
134
  return html`<div class="actions">
179
135
  <button
180
136
  type="button"
181
- class="pill shortcuts"
137
+ class="pill-s shortcuts"
182
138
  aria-haspopup="dialog"
183
139
  @click=${() => this.shortcutsOpen = true}
184
140
  >
@@ -186,14 +142,14 @@ var PcAppSettings = class extends PcElement {
186
142
  </button>
187
143
  <button
188
144
  type="button"
189
- class="pill import"
145
+ class="pill-s import"
190
146
  @click=${() => this.renderRoot.querySelector(".import-file")?.click()}
191
147
  >
192
148
  ${this.t("paintCanvas.settings.import")}
193
149
  </button>
194
150
  <button
195
151
  type="button"
196
- class="pill export"
152
+ class="pill-s export"
197
153
  @click=${() => void this.exportFile()}
198
154
  >
199
155
  ${this.t("paintCanvas.settings.export")}
@@ -1,13 +1,15 @@
1
1
  import { nothing } from "lit";
2
+ import { type ConfirmFn, type PromptFn } from "../../ask";
2
3
  import { PcElement } from "../../base";
3
4
  import "../PcBrushTest";
5
+ import "../PcDialogWindow";
6
+ import "../PcSliderRange";
7
+ import "../PcProfileEditor";
4
8
  import type PaintCanvas from "../../../lib/classes/PaintCanvas";
5
9
  import { SmoothingType, type BrushConfig } from "../../../lib/brushes/types";
10
+ import { type VaryingParam } from "../../../lib/brushes/configRanges";
6
11
  import { type ShapeImage } from "../../../lib/brushes/shapeImage";
7
- /** Asks the user to confirm; replaceable for tests */
8
- export type ConfirmFn = (message: string) => boolean;
9
- /** Asks the user for text; replaceable for tests */
10
- export type PromptFn = (message: string, value: string) => string | null;
12
+ export type { ConfirmFn, PromptFn } from "../../ask";
11
13
  /** The smoothing choices, in the order shown: value, translation key of the name, and icon name */
12
14
  export declare const SMOOTHING_CHOICES: readonly [{
13
15
  readonly value: SmoothingType.Linear;
@@ -26,12 +28,13 @@ export declare const SMOOTHING_CHOICES: readonly [{
26
28
  * The brush (or eraser) configuration window: a testing area, the shape (pressing it picks a built-in shape from the
27
29
  * device's own list, which says "Custom" for an uploaded or pasted one; or upload or paste one), smoothing, width, height,
28
30
  * opacity, rotation, offsets, sample rate, spacing and snapping to the pixel grid. Width, height, opacity, rotation and the offsets can vary with
29
- * pressure, tilt and randomness; when any is on, the setting has a min and max.
31
+ * pressure, tilt and randomness; when any is on, the setting has a min and max, set with a `<pc-slider-range>`.
30
32
  *
31
33
  * Changes stay in the window until "Save" (fires `pc-save` with the settings, to apply to the current tool) or "Add to
32
34
  * presets" (saves them as one of the user's presets, asking before replacing one with the same name, and selects it).
33
- * "Delete preset…" shows when editing one of the user's presets. Fires `pc-close` when closed, and `pc-toast` with a
34
- * message after adding or deleting a preset, or when a shape can't be used. Styling is structural only.
35
+ * "Delete preset…" shows when editing one of the user's presets. It's a shaded `<pc-dialog-window>`, closed with its ⨉
36
+ * button or Escape (not a press outside it, which would lose the changes). Fires `pc-close` when closed, and `pc-toast`
37
+ * with a message after adding or deleting a preset, or when a shape can't be used.
35
38
  *
36
39
  * @example
37
40
  * html`<pc-brush-config .app=${app} kind="brush" .config=${app.brush.preset} @pc-save=${apply}></pc-brush-config>`
@@ -56,6 +59,9 @@ export declare class PcBrushConfig extends PcElement {
56
59
  busy: {
57
60
  state: boolean;
58
61
  };
62
+ editingProfile: {
63
+ state: boolean;
64
+ };
59
65
  translations: {
60
66
  attribute: boolean;
61
67
  };
@@ -79,7 +85,11 @@ export declare class PcBrushConfig extends PcElement {
79
85
  draft?: BrushConfig;
80
86
  /** Whether a preset is being saved or deleted */
81
87
  busy: boolean;
88
+ /** The setting whose profile graph is being edited, if any */
89
+ editingProfile?: VaryingParam;
90
+ /** Asks the user to confirm, in a dialog (replaceable for tests) */
82
91
  confirm: ConfirmFn;
92
+ /** Asks the user for text, in a dialog (replaceable for tests) */
83
93
  prompt: PromptFn;
84
94
  /** Turns files into brush shapes (replaceable for tests) */
85
95
  readShape: (file: File) => Promise<ShapeImage>;
@@ -87,10 +97,7 @@ export declare class PcBrushConfig extends PcElement {
87
97
  * Reads a brush shape from the clipboard, or else from image data copied on the canvas (replaceable for tests)
88
98
  */
89
99
  readClipboard: () => Promise<ShapeImage>;
90
- private readonly onKeyDown;
91
100
  constructor();
92
- connectedCallback(): void;
93
- disconnectedCallback(): void;
94
101
  protected willUpdate(changed: Map<PropertyKey, unknown>): void;
95
102
  /** Fire an event that crosses shadow DOM boundaries */
96
103
  private emit;
@@ -121,10 +128,10 @@ export declare class PcBrushConfig extends PcElement {
121
128
  * Delete the preset being edited, after confirming.
122
129
  */
123
130
  deletePreset(): Promise<void>;
124
- /** Render a number input */
125
- private number;
126
- /** Render a range slider */
127
- private slider;
131
+ /**
132
+ * Render a slider for one value (a single `<pc-slider-range>`), the same as the ranges of settings that vary.
133
+ */
134
+ private single;
128
135
  /** Render a setting that can vary: its value (or min and max), and its pressure, tilt and randomise icon toggles */
129
136
  private renderParam;
130
137
  /**
@@ -134,4 +141,8 @@ export declare class PcBrushConfig extends PcElement {
134
141
  /** Render the shape and smoothing row */
135
142
  private renderShape;
136
143
  render(): import("lit").TemplateResult<1> | typeof nothing;
144
+ /** The profile graph editor for the setting being edited, while open */
145
+ private renderProfileEditor;
146
+ /** Profile graphs, when there's no canvas to keep them */
147
+ private readonly profiles;
137
148
  }