notations 1.0.4 → 1.0.7
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/NotationView.css +15 -0
- package/dist/NotationView.css.map +1 -1
- package/dist/NotationView.min.css +1 -1
- package/dist/NotationView.min.css.map +1 -1
- package/dist/notations.umd.js +469 -108
- package/dist/notations.umd.min.js +2 -2
- package/dist/notations.umd.min.js.map +1 -1
- package/lib/cjs/beats.js +1 -1
- package/lib/cjs/beats.js.map +1 -1
- package/lib/cjs/block.d.ts +4 -0
- package/lib/cjs/block.js +24 -0
- package/lib/cjs/block.js.map +1 -1
- package/lib/cjs/carnatic/NotationView.d.ts +1 -0
- package/lib/cjs/carnatic/NotationView.js +10 -0
- package/lib/cjs/carnatic/NotationView.js.map +1 -1
- package/lib/cjs/carnatic/atomviews.d.ts +4 -1
- package/lib/cjs/carnatic/atomviews.js +18 -2
- package/lib/cjs/carnatic/atomviews.js.map +1 -1
- package/lib/cjs/carnatic/embelishments.d.ts +18 -1
- package/lib/cjs/carnatic/embelishments.js +87 -1
- package/lib/cjs/carnatic/embelishments.js.map +1 -1
- package/lib/cjs/core.d.ts +18 -3
- package/lib/cjs/core.js +161 -21
- package/lib/cjs/core.js.map +1 -1
- package/lib/cjs/entity.d.ts +4 -0
- package/lib/cjs/entity.js +12 -0
- package/lib/cjs/entity.js.map +1 -1
- package/lib/cjs/events.d.ts +56 -0
- package/lib/cjs/events.js +27 -0
- package/lib/cjs/events.js.map +1 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/shapes.d.ts +13 -1
- package/lib/cjs/shapes.js +35 -7
- package/lib/cjs/shapes.js.map +1 -1
- package/lib/esm/beats.js +1 -1
- package/lib/esm/beats.js.map +1 -1
- package/lib/esm/block.d.ts +4 -0
- package/lib/esm/block.js +24 -0
- package/lib/esm/block.js.map +1 -1
- package/lib/esm/carnatic/NotationView.d.ts +1 -0
- package/lib/esm/carnatic/NotationView.js +10 -0
- package/lib/esm/carnatic/NotationView.js.map +1 -1
- package/lib/esm/carnatic/atomviews.d.ts +4 -1
- package/lib/esm/carnatic/atomviews.js +19 -3
- package/lib/esm/carnatic/atomviews.js.map +1 -1
- package/lib/esm/carnatic/embelishments.d.ts +18 -1
- package/lib/esm/carnatic/embelishments.js +85 -0
- package/lib/esm/carnatic/embelishments.js.map +1 -1
- package/lib/esm/core.d.ts +18 -3
- package/lib/esm/core.js +161 -21
- package/lib/esm/core.js.map +1 -1
- package/lib/esm/entity.d.ts +4 -0
- package/lib/esm/entity.js +12 -0
- package/lib/esm/entity.js.map +1 -1
- package/lib/esm/events.d.ts +56 -0
- package/lib/esm/events.js +24 -0
- package/lib/esm/events.js.map +1 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/shapes.d.ts +13 -1
- package/lib/esm/shapes.js +34 -7
- package/lib/esm/shapes.js.map +1 -1
- package/package.json +3 -1
- package/styles/NotationView.scss +15 -0
package/lib/esm/block.js
CHANGED
|
@@ -40,6 +40,7 @@ export class Block extends Entity {
|
|
|
40
40
|
this._parentBlock = null;
|
|
41
41
|
this._currRoleDef = null;
|
|
42
42
|
this._currentLine = null;
|
|
43
|
+
this._observers = [];
|
|
43
44
|
this._unnamedLayoutParams = [];
|
|
44
45
|
this._namedLayoutParams = new Map();
|
|
45
46
|
this._layoutParams = null;
|
|
@@ -50,6 +51,16 @@ export class Block extends Entity {
|
|
|
50
51
|
this.setParent(parent);
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
addObserver(observer) {
|
|
55
|
+
this._observers.push(observer);
|
|
56
|
+
return () => this.removeObserver(observer);
|
|
57
|
+
}
|
|
58
|
+
removeObserver(observer) {
|
|
59
|
+
const index = this._observers.indexOf(observer);
|
|
60
|
+
if (index >= 0) {
|
|
61
|
+
this._observers.splice(index, 1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
53
64
|
children() {
|
|
54
65
|
return this.blockItems;
|
|
55
66
|
}
|
|
@@ -195,14 +206,27 @@ export class Block extends Entity {
|
|
|
195
206
|
return rd;
|
|
196
207
|
}
|
|
197
208
|
addBlockItem(item) {
|
|
209
|
+
var _a;
|
|
210
|
+
const index = this.blockItems.length;
|
|
198
211
|
item.setParent(this);
|
|
199
212
|
this.blockItems.push(item);
|
|
213
|
+
if (this._eventsEnabled) {
|
|
214
|
+
for (const observer of this._observers) {
|
|
215
|
+
(_a = observer.onItemAdded) === null || _a === void 0 ? void 0 : _a.call(observer, this, item, index);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
200
218
|
}
|
|
201
219
|
removeBlockItem(item) {
|
|
220
|
+
var _a;
|
|
202
221
|
const index = this.blockItems.indexOf(item);
|
|
203
222
|
if (index >= 0) {
|
|
204
223
|
this.blockItems.splice(index, 1);
|
|
205
224
|
item.setParent(null);
|
|
225
|
+
if (this._eventsEnabled) {
|
|
226
|
+
for (const observer of this._observers) {
|
|
227
|
+
(_a = observer.onItemRemoved) === null || _a === void 0 ? void 0 : _a.call(observer, this, item, index);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
206
230
|
}
|
|
207
231
|
return index;
|
|
208
232
|
}
|
package/lib/esm/block.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity } from \"./entity\";\nimport { Cycle } from \"./cycle\";\nimport { Line } from \"./core\";\nimport { LayoutParams } from \"./layouts\";\n\n/**\n * Definition of a role in a block context.\n * This is used for block-scoped role definitions.\n */\nexport class RoleDef {\n /** Name of the role */\n name = \"\";\n\n /** Whether this role contains only notes (true) or can also contain syllables/text (false) */\n notesOnly = false;\n\n /** Index of this role in the notation */\n index = 0;\n}\n\n/**\n * Represents a raw block of content in the notation.\n * Raw blocks can contain arbitrary content like markdown, HTML, etc.\n */\nexport class RawBlock extends Entity {\n readonly TYPE: string = \"RawBlock\";\n\n /**\n * Creates a new RawBlock.\n * @param content The content of the block\n * @param contentType The type of content (e.g., \"md\" for markdown)\n */\n constructor(\n public content: string,\n public contentType: string = \"md\",\n ) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this raw block.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), content: this.content, contentType: this.contentType };\n }\n}\n\n/**\n * Union type for items that can appear in a block.\n */\nexport type BlockItem = Block | Line | RawBlock;\n\n/**\n * Type guard to check if an entity is a Block.\n */\nexport function isBlock(item: BlockItem): item is Block {\n return item.TYPE === \"Block\";\n}\n\n/**\n * Type guard to check if an entity is a Line.\n */\nexport function isLine(item: BlockItem): item is Line {\n return item.TYPE === \"Line\";\n}\n\n/**\n * Type guard to check if an entity is a RawBlock.\n */\nexport function isRawBlock(item: BlockItem): item is RawBlock {\n return item.TYPE === \"RawBlock\";\n}\n\n/**\n * Represents a scoped block created by a command with braces.\n * For example: \\section(\"Pallavi\") { ... }\n *\n * Blocks inherit properties from their parent Block and can override them locally.\n * Properties are resolved lazily by walking up the tree.\n *\n * Block = Command + Children (unified model)\n */\nexport class Block extends Entity {\n readonly TYPE: string = \"Block\";\n\n /** The type of block (e.g., \"section\", \"repeat\", \"cycle\") */\n readonly blockType: string;\n\n /** Optional name for the block (e.g., section name) */\n readonly name: TSU.Nullable<string>;\n\n /** Child items (before expansion by subclasses) */\n readonly blockItems: BlockItem[] = [];\n\n // Local properties\n localCycle: TSU.Nullable<Cycle> = null;\n localAtomsPerBeat: TSU.Nullable<number> = null;\n localBreaks: TSU.Nullable<number[]> = null;\n readonly localRoles = new Map<string, RoleDef>();\n\n // Store parent reference (Block or null for root)\n private _parentBlock: TSU.Nullable<Block> = null;\n\n // State tracking for command application (protected for Notation override)\n protected _currRoleDef: TSU.Nullable<RoleDef> = null;\n protected _currentLine: TSU.Nullable<Line> = null;\n\n /**\n * Creates a new Block.\n * @param blockType The type of block (e.g., \"section\", \"group\")\n * @param parent The parent block (null for root)\n * @param name Optional name for the block\n */\n constructor(blockType: string, parent: TSU.Nullable<Block> = null, name: TSU.Nullable<string> = null) {\n super();\n this.blockType = blockType;\n this.name = name;\n this._parentBlock = parent;\n // Also set Entity's parent for tree traversal\n if (parent) {\n this.setParent(parent);\n }\n }\n\n /**\n * Returns the expanded children for layout iteration.\n * Subclasses can override this to transform children (e.g., Repeat, Section).\n */\n children(): BlockItem[] {\n return this.blockItems;\n }\n\n /**\n * Gets the parent block.\n */\n get parentBlock(): TSU.Nullable<Block> {\n return this._parentBlock;\n }\n\n // ============================================\n // Property inheritance via tree walking\n // ============================================\n\n /**\n * Gets the effective cycle by walking up the tree.\n */\n get cycle(): TSU.Nullable<Cycle> {\n if (this.localCycle !== null) {\n return this.localCycle;\n }\n return this.parentBlock?.cycle ?? null;\n }\n\n /**\n * Gets the effective atoms per beat by walking up the tree.\n * Defaults to 1 if not set anywhere in the tree.\n */\n get atomsPerBeat(): number {\n if (this.localAtomsPerBeat !== null) {\n return this.localAtomsPerBeat;\n }\n return this.parentBlock?.atomsPerBeat ?? 1;\n }\n\n /**\n * Gets the effective line breaks by walking up the tree.\n * Defaults to empty array if not set anywhere.\n */\n get breaks(): number[] {\n if (this.localBreaks !== null) {\n return this.localBreaks;\n }\n return this.parentBlock?.breaks ?? [];\n }\n\n // ============================================\n // Layout parameters management\n // ============================================\n\n /** Layout parameters caching for this block scope */\n private _unnamedLayoutParams: LayoutParams[] = [];\n private _namedLayoutParams = new Map<string, LayoutParams>();\n private _layoutParams: LayoutParams | null = null;\n\n /**\n * Gets the unnamed layout parameters for this block.\n */\n get unnamedLayoutParams(): ReadonlyArray<LayoutParams> {\n return this._unnamedLayoutParams;\n }\n\n /**\n * Gets the named layout parameters for this block.\n */\n get namedLayoutParams(): ReadonlyMap<string, LayoutParams> {\n return this._namedLayoutParams;\n }\n\n /**\n * Gets the current layout parameters for this block scope.\n * Uses the effective cycle, atomsPerBeat, and breaks from tree walking.\n * Creates or finds a matching LayoutParams if needed.\n */\n get layoutParams(): LayoutParams {\n if (this._layoutParams == null) {\n // Find or create layout params matching current effective values\n this._layoutParams = this.findUnnamedLayoutParams();\n if (this._layoutParams == null) {\n this._layoutParams = this.snapshotLayoutParams();\n this._unnamedLayoutParams.push(this._layoutParams);\n }\n }\n return this._layoutParams;\n }\n\n /**\n * Resets the current layout parameters to null.\n * Called when layout-affecting properties change.\n */\n resetLayoutParams(): void {\n this._layoutParams = null;\n this.resetLine();\n }\n\n /**\n * Creates a snapshot of the current layout parameters.\n * @returns A new LayoutParams object with the current effective settings\n */\n protected snapshotLayoutParams(): LayoutParams {\n const effectiveCycle = this.cycle;\n if (effectiveCycle == null) {\n throw new Error(\"Cannot create layout params: no cycle defined\");\n }\n return new LayoutParams({\n cycle: effectiveCycle,\n beatDuration: this.atomsPerBeat,\n layout: this.breaks,\n });\n }\n\n /**\n * Finds an unnamed layout parameters object that matches the current effective settings.\n * @returns Matching layout parameters, or null if none found\n */\n protected findUnnamedLayoutParams(): LayoutParams | null {\n const effectiveCycle = this.cycle;\n if (effectiveCycle == null) return null;\n\n return (\n this._unnamedLayoutParams.find((lp) => {\n return (\n lp.beatDuration == this.atomsPerBeat && effectiveCycle.equals(lp.cycle) && lp.lineBreaksEqual(this.breaks)\n );\n }) || null\n );\n }\n\n /**\n * Ensures that named layout parameters with the given name exist.\n * @param name The name of the layout parameters\n * @returns The layout parameters\n */\n ensureNamedLayoutParams(name: string): LayoutParams {\n let lp = this._namedLayoutParams.get(name) || null;\n if (lp == null || this._layoutParams != lp) {\n if (lp == null) {\n // Create new named layout params\n lp = this.snapshotLayoutParams();\n this._namedLayoutParams.set(name, lp);\n } else {\n // Copy named LPs attributes into our locals\n this.localCycle = lp.cycle;\n this.localAtomsPerBeat = lp.beatDuration;\n this.localBreaks = lp.lineBreaks;\n }\n this._layoutParams = lp;\n this.resetLine();\n }\n return this._layoutParams!;\n }\n\n /**\n * Gets a role definition by name, walking up the tree if not found locally.\n * @param name The name of the role\n */\n getRole(name: string): TSU.Nullable<RoleDef> {\n const local = this.localRoles.get(name.toLowerCase());\n if (local) {\n return local;\n }\n return this.parentBlock?.getRole(name) ?? null;\n }\n\n // ============================================\n // State tracking for command application\n // ============================================\n\n /**\n * Gets the current role definition.\n * Falls back to parent's current role or the last defined role.\n */\n get currRoleDef(): TSU.Nullable<RoleDef> {\n if (this._currRoleDef !== null) {\n return this._currRoleDef;\n }\n // Fall back to parent's current role\n if (this.parentBlock) {\n return this.parentBlock.currRoleDef;\n }\n // Or use the last locally defined role\n const roles = Array.from(this.localRoles.values());\n return roles.length > 0 ? roles[roles.length - 1] : null;\n }\n\n /**\n * Sets the current role by name.\n * If the role doesn't exist, tries to create it via the root container's onMissingRole.\n * @param name The name of the role to activate\n * @throws Error if the role is not found and cannot be created\n */\n setCurrRole(name: string): void {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n let roleDef = this.getRole(name);\n // If role not found, try auto-creation\n if (roleDef == null) {\n // Create the role locally in this block\n // Default: \"sw\" is notes-only, others are not\n roleDef = this.newRoleDef(name, name === \"sw\");\n }\n this._currRoleDef = roleDef;\n }\n\n /**\n * Gets the current line, creating one if needed.\n */\n get currentLine(): Line {\n if (this._currentLine === null) {\n return this.newLine();\n }\n return this._currentLine;\n }\n\n /**\n * Creates a new line in this block.\n */\n newLine(): Line {\n if (this._currentLine !== null && this._currentLine.isEmpty) {\n // Remove empty line before creating new one\n this.removeBlockItem(this._currentLine);\n }\n this._currentLine = new Line();\n this.addBlockItem(this._currentLine);\n return this._currentLine;\n }\n\n /**\n * Resets the current line pointer to null.\n * Called when layout parameters change to force a new line.\n */\n resetLine(): void {\n this._currentLine = null;\n }\n\n /**\n * Creates a new role definition local to this block.\n * @param name The name of the role\n * @param notesOnly Whether this role contains only notes\n */\n newRoleDef(name: string, notesOnly = false): RoleDef {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n if (this.localRoles.has(name)) {\n throw new Error(`Role '${name}' already exists in this block`);\n }\n const rd = new RoleDef();\n rd.name = name;\n rd.notesOnly = notesOnly;\n rd.index = this.localRoles.size;\n this.localRoles.set(name, rd);\n return rd;\n }\n\n // ============================================\n // Child management\n // ============================================\n\n /**\n * Adds a child item to this block.\n * @param item The item to add\n */\n addBlockItem(item: BlockItem): void {\n item.setParent(this);\n this.blockItems.push(item);\n }\n\n /**\n * Removes a child item from this block.\n * @param item The item to remove\n * @returns The index of the removed item, or -1 if not found\n */\n removeBlockItem(item: BlockItem): number {\n const index = this.blockItems.indexOf(item);\n if (index >= 0) {\n this.blockItems.splice(index, 1);\n item.setParent(null);\n }\n return index;\n }\n\n /**\n * Returns a debug-friendly representation of this block.\n */\n debugValue(): any {\n const out: any = {\n ...super.debugValue(),\n blockType: this.blockType,\n blockItems: this.blockItems.map((c) => c.debugValue()),\n };\n if (this.name) {\n out.name = this.name;\n }\n if (this.localCycle) {\n out.localCycle = this.localCycle.uuid;\n }\n if (this.localAtomsPerBeat !== null) {\n out.localAtomsPerBeat = this.localAtomsPerBeat;\n }\n if (this.localBreaks !== null) {\n out.localBreaks = this.localBreaks;\n }\n if (this.localRoles.size > 0) {\n out.localRoles = Array.from(this.localRoles.keys());\n }\n return out;\n }\n}\n\n/**\n * Helper function to find the containing block of an entity by walking up the tree.\n * @param entity The entity to start from\n * @returns The containing Block, or null if not found\n */\nexport function findContainingBlock(entity: Entity): TSU.Nullable<Block> {\n let current: TSU.Nullable<Entity> = entity.parent;\n while (current !== null) {\n if (current instanceof Block) {\n return current;\n }\n current = current.parent;\n }\n return null;\n}\n\n// ============================================\n// Block Subclasses\n// ============================================\n\n/**\n * A section block with a heading.\n * Expands children to include a heading RawBlock followed by the content.\n *\n * Usage: \\section(\"Pallavi\") { ... }\n */\nexport class SectionBlock extends Block {\n constructor(sectionName: string, parent: TSU.Nullable<Block> = null) {\n super(\"section\", parent, sectionName);\n }\n\n /**\n * Expands children to include a heading RawBlock.\n */\n children(): BlockItem[] {\n const heading = new RawBlock(`# ${this.name}`, \"md\");\n return [heading, ...this.blockItems];\n }\n}\n\n/**\n * A repeat block that expands its children N times.\n *\n * Usage: \\repeat(2) { ... }\n */\nexport class RepeatBlock extends Block {\n /** Number of times to repeat (0 = visual markers only) */\n readonly repeatCount: number;\n\n constructor(repeatCount: number, parent: TSU.Nullable<Block> = null) {\n super(\"repeat\", parent);\n this.repeatCount = repeatCount;\n }\n\n /**\n * Expands children by repeating them N times.\n * If count is 0, returns children as-is (visual repeat markers only).\n */\n children(): BlockItem[] {\n if (this.repeatCount <= 0) {\n return this.blockItems;\n }\n const expanded: BlockItem[] = [];\n for (let i = 0; i < this.repeatCount; i++) {\n expanded.push(...this.blockItems);\n }\n return expanded;\n }\n}\n\n/**\n * A cycle block that sets localCycle for scoped notation.\n *\n * Usage: \\cycle(\"|4|4|\") { ... }\n */\nexport class CycleBlock extends Block {\n constructor(cycle: Cycle, parent: TSU.Nullable<Block> = null) {\n super(\"cycle\", parent);\n this.localCycle = cycle;\n }\n}\n\n/**\n * A beat duration block that sets localAtomsPerBeat for scoped notation.\n *\n * Usage: \\beatDuration(2) { ... }\n */\nexport class BeatDurationBlock extends Block {\n constructor(atomsPerBeat: number, parent: TSU.Nullable<Block> = null) {\n super(\"beatduration\", parent);\n this.localAtomsPerBeat = atomsPerBeat;\n }\n}\n\n/**\n * A breaks block that sets localBreaks for scoped notation.\n *\n * Usage: \\breaks(4, 2, 2) { ... }\n */\nexport class BreaksBlock extends Block {\n constructor(breaks: number[], parent: TSU.Nullable<Block> = null) {\n super(\"breaks\", parent);\n this.localBreaks = breaks;\n }\n}\n\n/**\n * A role block that creates a local role definition.\n *\n * Usage: \\role(\"Vocals\", notes=false) { ... }\n */\nexport class RoleBlock extends Block {\n constructor(roleName: string, notesOnly: boolean, parent: TSU.Nullable<Block> = null) {\n super(\"role\", parent);\n // Create the role locally\n this.newRoleDef(roleName, notesOnly);\n }\n}\n\n/**\n * A group block for organizing notation without special semantics.\n *\n * Usage: \\group(\"optional-name\") { ... }\n */\nexport class GroupBlock extends Block {\n constructor(groupName: string | null, parent: TSU.Nullable<Block> = null) {\n super(\"group\", parent, groupName);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity } from \"./entity\";\nimport { Cycle } from \"./cycle\";\nimport { Line } from \"./core\";\nimport { LayoutParams } from \"./layouts\";\nimport { BlockObserver } from \"./events\";\n\n/**\n * Definition of a role in a block context.\n * This is used for block-scoped role definitions.\n */\nexport class RoleDef {\n /** Name of the role */\n name = \"\";\n\n /** Whether this role contains only notes (true) or can also contain syllables/text (false) */\n notesOnly = false;\n\n /** Index of this role in the notation */\n index = 0;\n}\n\n/**\n * Represents a raw block of content in the notation.\n * Raw blocks can contain arbitrary content like markdown, HTML, etc.\n */\nexport class RawBlock extends Entity {\n readonly TYPE: string = \"RawBlock\";\n\n /**\n * Creates a new RawBlock.\n * @param content The content of the block\n * @param contentType The type of content (e.g., \"md\" for markdown)\n */\n constructor(\n public content: string,\n public contentType: string = \"md\",\n ) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this raw block.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), content: this.content, contentType: this.contentType };\n }\n}\n\n/**\n * Union type for items that can appear in a block.\n */\nexport type BlockItem = Block | Line | RawBlock;\n\n/**\n * Type guard to check if an entity is a Block.\n */\nexport function isBlock(item: BlockItem): item is Block {\n return item.TYPE === \"Block\";\n}\n\n/**\n * Type guard to check if an entity is a Line.\n */\nexport function isLine(item: BlockItem): item is Line {\n return item.TYPE === \"Line\";\n}\n\n/**\n * Type guard to check if an entity is a RawBlock.\n */\nexport function isRawBlock(item: BlockItem): item is RawBlock {\n return item.TYPE === \"RawBlock\";\n}\n\n/**\n * Represents a scoped block created by a command with braces.\n * For example: \\section(\"Pallavi\") { ... }\n *\n * Blocks inherit properties from their parent Block and can override them locally.\n * Properties are resolved lazily by walking up the tree.\n *\n * Block = Command + Children (unified model)\n */\nexport class Block extends Entity {\n readonly TYPE: string = \"Block\";\n\n /** The type of block (e.g., \"section\", \"repeat\", \"cycle\") */\n readonly blockType: string;\n\n /** Optional name for the block (e.g., section name) */\n readonly name: TSU.Nullable<string>;\n\n /** Child items (before expansion by subclasses) */\n readonly blockItems: BlockItem[] = [];\n\n // Local properties\n localCycle: TSU.Nullable<Cycle> = null;\n localAtomsPerBeat: TSU.Nullable<number> = null;\n localBreaks: TSU.Nullable<number[]> = null;\n readonly localRoles = new Map<string, RoleDef>();\n\n // Store parent reference (Block or null for root)\n private _parentBlock: TSU.Nullable<Block> = null;\n\n // State tracking for command application (protected for Notation override)\n protected _currRoleDef: TSU.Nullable<RoleDef> = null;\n protected _currentLine: TSU.Nullable<Line> = null;\n\n /**\n * Observers that receive notifications when block items change.\n */\n private _observers: BlockObserver<BlockItem, Block>[] = [];\n\n /**\n * Creates a new Block.\n * @param blockType The type of block (e.g., \"section\", \"group\")\n * @param parent The parent block (null for root)\n * @param name Optional name for the block\n */\n constructor(blockType: string, parent: TSU.Nullable<Block> = null, name: TSU.Nullable<string> = null) {\n super();\n this.blockType = blockType;\n this.name = name;\n this._parentBlock = parent;\n // Also set Entity's parent for tree traversal\n if (parent) {\n this.setParent(parent);\n }\n }\n\n /**\n * Adds an observer to receive block item change notifications.\n * @param observer The observer to add\n * @returns A function to remove the observer\n */\n addObserver(observer: BlockObserver<BlockItem, Block>): () => void {\n this._observers.push(observer);\n return () => this.removeObserver(observer);\n }\n\n /**\n * Removes an observer.\n * @param observer The observer to remove\n */\n removeObserver(observer: BlockObserver<BlockItem, Block>): void {\n const index = this._observers.indexOf(observer);\n if (index >= 0) {\n this._observers.splice(index, 1);\n }\n }\n\n /**\n * Returns the expanded children for layout iteration.\n * Subclasses can override this to transform children (e.g., Repeat, Section).\n */\n children(): BlockItem[] {\n return this.blockItems;\n }\n\n /**\n * Gets the parent block.\n */\n get parentBlock(): TSU.Nullable<Block> {\n return this._parentBlock;\n }\n\n // ============================================\n // Property inheritance via tree walking\n // ============================================\n\n /**\n * Gets the effective cycle by walking up the tree.\n */\n get cycle(): TSU.Nullable<Cycle> {\n if (this.localCycle !== null) {\n return this.localCycle;\n }\n return this.parentBlock?.cycle ?? null;\n }\n\n /**\n * Gets the effective atoms per beat by walking up the tree.\n * Defaults to 1 if not set anywhere in the tree.\n */\n get atomsPerBeat(): number {\n if (this.localAtomsPerBeat !== null) {\n return this.localAtomsPerBeat;\n }\n return this.parentBlock?.atomsPerBeat ?? 1;\n }\n\n /**\n * Gets the effective line breaks by walking up the tree.\n * Defaults to empty array if not set anywhere.\n */\n get breaks(): number[] {\n if (this.localBreaks !== null) {\n return this.localBreaks;\n }\n return this.parentBlock?.breaks ?? [];\n }\n\n // ============================================\n // Layout parameters management\n // ============================================\n\n /** Layout parameters caching for this block scope */\n private _unnamedLayoutParams: LayoutParams[] = [];\n private _namedLayoutParams = new Map<string, LayoutParams>();\n private _layoutParams: LayoutParams | null = null;\n\n /**\n * Gets the unnamed layout parameters for this block.\n */\n get unnamedLayoutParams(): ReadonlyArray<LayoutParams> {\n return this._unnamedLayoutParams;\n }\n\n /**\n * Gets the named layout parameters for this block.\n */\n get namedLayoutParams(): ReadonlyMap<string, LayoutParams> {\n return this._namedLayoutParams;\n }\n\n /**\n * Gets the current layout parameters for this block scope.\n * Uses the effective cycle, atomsPerBeat, and breaks from tree walking.\n * Creates or finds a matching LayoutParams if needed.\n */\n get layoutParams(): LayoutParams {\n if (this._layoutParams == null) {\n // Find or create layout params matching current effective values\n this._layoutParams = this.findUnnamedLayoutParams();\n if (this._layoutParams == null) {\n this._layoutParams = this.snapshotLayoutParams();\n this._unnamedLayoutParams.push(this._layoutParams);\n }\n }\n return this._layoutParams;\n }\n\n /**\n * Resets the current layout parameters to null.\n * Called when layout-affecting properties change.\n */\n resetLayoutParams(): void {\n this._layoutParams = null;\n this.resetLine();\n }\n\n /**\n * Creates a snapshot of the current layout parameters.\n * @returns A new LayoutParams object with the current effective settings\n */\n protected snapshotLayoutParams(): LayoutParams {\n const effectiveCycle = this.cycle;\n if (effectiveCycle == null) {\n throw new Error(\"Cannot create layout params: no cycle defined\");\n }\n return new LayoutParams({\n cycle: effectiveCycle,\n beatDuration: this.atomsPerBeat,\n layout: this.breaks,\n });\n }\n\n /**\n * Finds an unnamed layout parameters object that matches the current effective settings.\n * @returns Matching layout parameters, or null if none found\n */\n protected findUnnamedLayoutParams(): LayoutParams | null {\n const effectiveCycle = this.cycle;\n if (effectiveCycle == null) return null;\n\n return (\n this._unnamedLayoutParams.find((lp) => {\n return (\n lp.beatDuration == this.atomsPerBeat && effectiveCycle.equals(lp.cycle) && lp.lineBreaksEqual(this.breaks)\n );\n }) || null\n );\n }\n\n /**\n * Ensures that named layout parameters with the given name exist.\n * @param name The name of the layout parameters\n * @returns The layout parameters\n */\n ensureNamedLayoutParams(name: string): LayoutParams {\n let lp = this._namedLayoutParams.get(name) || null;\n if (lp == null || this._layoutParams != lp) {\n if (lp == null) {\n // Create new named layout params\n lp = this.snapshotLayoutParams();\n this._namedLayoutParams.set(name, lp);\n } else {\n // Copy named LPs attributes into our locals\n this.localCycle = lp.cycle;\n this.localAtomsPerBeat = lp.beatDuration;\n this.localBreaks = lp.lineBreaks;\n }\n this._layoutParams = lp;\n this.resetLine();\n }\n return this._layoutParams!;\n }\n\n /**\n * Gets a role definition by name, walking up the tree if not found locally.\n * @param name The name of the role\n */\n getRole(name: string): TSU.Nullable<RoleDef> {\n const local = this.localRoles.get(name.toLowerCase());\n if (local) {\n return local;\n }\n return this.parentBlock?.getRole(name) ?? null;\n }\n\n // ============================================\n // State tracking for command application\n // ============================================\n\n /**\n * Gets the current role definition.\n * Falls back to parent's current role or the last defined role.\n */\n get currRoleDef(): TSU.Nullable<RoleDef> {\n if (this._currRoleDef !== null) {\n return this._currRoleDef;\n }\n // Fall back to parent's current role\n if (this.parentBlock) {\n return this.parentBlock.currRoleDef;\n }\n // Or use the last locally defined role\n const roles = Array.from(this.localRoles.values());\n return roles.length > 0 ? roles[roles.length - 1] : null;\n }\n\n /**\n * Sets the current role by name.\n * If the role doesn't exist, tries to create it via the root container's onMissingRole.\n * @param name The name of the role to activate\n * @throws Error if the role is not found and cannot be created\n */\n setCurrRole(name: string): void {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n let roleDef = this.getRole(name);\n // If role not found, try auto-creation\n if (roleDef == null) {\n // Create the role locally in this block\n // Default: \"sw\" is notes-only, others are not\n roleDef = this.newRoleDef(name, name === \"sw\");\n }\n this._currRoleDef = roleDef;\n }\n\n /**\n * Gets the current line, creating one if needed.\n */\n get currentLine(): Line {\n if (this._currentLine === null) {\n return this.newLine();\n }\n return this._currentLine;\n }\n\n /**\n * Creates a new line in this block.\n */\n newLine(): Line {\n if (this._currentLine !== null && this._currentLine.isEmpty) {\n // Remove empty line before creating new one\n this.removeBlockItem(this._currentLine);\n }\n this._currentLine = new Line();\n this.addBlockItem(this._currentLine);\n return this._currentLine;\n }\n\n /**\n * Resets the current line pointer to null.\n * Called when layout parameters change to force a new line.\n */\n resetLine(): void {\n this._currentLine = null;\n }\n\n /**\n * Creates a new role definition local to this block.\n * @param name The name of the role\n * @param notesOnly Whether this role contains only notes\n */\n newRoleDef(name: string, notesOnly = false): RoleDef {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n if (this.localRoles.has(name)) {\n throw new Error(`Role '${name}' already exists in this block`);\n }\n const rd = new RoleDef();\n rd.name = name;\n rd.notesOnly = notesOnly;\n rd.index = this.localRoles.size;\n this.localRoles.set(name, rd);\n return rd;\n }\n\n // ============================================\n // Child management\n // ============================================\n\n /**\n * Adds a child item to this block.\n * @param item The item to add\n */\n addBlockItem(item: BlockItem): void {\n const index = this.blockItems.length;\n item.setParent(this);\n this.blockItems.push(item);\n\n // Notify observers of added item\n if (this._eventsEnabled) {\n for (const observer of this._observers) {\n observer.onItemAdded?.(this, item, index);\n }\n }\n }\n\n /**\n * Removes a child item from this block.\n * @param item The item to remove\n * @returns The index of the removed item, or -1 if not found\n */\n removeBlockItem(item: BlockItem): number {\n const index = this.blockItems.indexOf(item);\n if (index >= 0) {\n this.blockItems.splice(index, 1);\n item.setParent(null);\n\n // Notify observers of removed item\n if (this._eventsEnabled) {\n for (const observer of this._observers) {\n observer.onItemRemoved?.(this, item, index);\n }\n }\n }\n return index;\n }\n\n /**\n * Returns a debug-friendly representation of this block.\n */\n debugValue(): any {\n const out: any = {\n ...super.debugValue(),\n blockType: this.blockType,\n blockItems: this.blockItems.map((c) => c.debugValue()),\n };\n if (this.name) {\n out.name = this.name;\n }\n if (this.localCycle) {\n out.localCycle = this.localCycle.uuid;\n }\n if (this.localAtomsPerBeat !== null) {\n out.localAtomsPerBeat = this.localAtomsPerBeat;\n }\n if (this.localBreaks !== null) {\n out.localBreaks = this.localBreaks;\n }\n if (this.localRoles.size > 0) {\n out.localRoles = Array.from(this.localRoles.keys());\n }\n return out;\n }\n}\n\n/**\n * Helper function to find the containing block of an entity by walking up the tree.\n * @param entity The entity to start from\n * @returns The containing Block, or null if not found\n */\nexport function findContainingBlock(entity: Entity): TSU.Nullable<Block> {\n let current: TSU.Nullable<Entity> = entity.parent;\n while (current !== null) {\n if (current instanceof Block) {\n return current;\n }\n current = current.parent;\n }\n return null;\n}\n\n// ============================================\n// Block Subclasses\n// ============================================\n\n/**\n * A section block with a heading.\n * Expands children to include a heading RawBlock followed by the content.\n *\n * Usage: \\section(\"Pallavi\") { ... }\n */\nexport class SectionBlock extends Block {\n constructor(sectionName: string, parent: TSU.Nullable<Block> = null) {\n super(\"section\", parent, sectionName);\n }\n\n /**\n * Expands children to include a heading RawBlock.\n */\n children(): BlockItem[] {\n const heading = new RawBlock(`# ${this.name}`, \"md\");\n return [heading, ...this.blockItems];\n }\n}\n\n/**\n * A repeat block that expands its children N times.\n *\n * Usage: \\repeat(2) { ... }\n */\nexport class RepeatBlock extends Block {\n /** Number of times to repeat (0 = visual markers only) */\n readonly repeatCount: number;\n\n constructor(repeatCount: number, parent: TSU.Nullable<Block> = null) {\n super(\"repeat\", parent);\n this.repeatCount = repeatCount;\n }\n\n /**\n * Expands children by repeating them N times.\n * If count is 0, returns children as-is (visual repeat markers only).\n */\n children(): BlockItem[] {\n if (this.repeatCount <= 0) {\n return this.blockItems;\n }\n const expanded: BlockItem[] = [];\n for (let i = 0; i < this.repeatCount; i++) {\n expanded.push(...this.blockItems);\n }\n return expanded;\n }\n}\n\n/**\n * A cycle block that sets localCycle for scoped notation.\n *\n * Usage: \\cycle(\"|4|4|\") { ... }\n */\nexport class CycleBlock extends Block {\n constructor(cycle: Cycle, parent: TSU.Nullable<Block> = null) {\n super(\"cycle\", parent);\n this.localCycle = cycle;\n }\n}\n\n/**\n * A beat duration block that sets localAtomsPerBeat for scoped notation.\n *\n * Usage: \\beatDuration(2) { ... }\n */\nexport class BeatDurationBlock extends Block {\n constructor(atomsPerBeat: number, parent: TSU.Nullable<Block> = null) {\n super(\"beatduration\", parent);\n this.localAtomsPerBeat = atomsPerBeat;\n }\n}\n\n/**\n * A breaks block that sets localBreaks for scoped notation.\n *\n * Usage: \\breaks(4, 2, 2) { ... }\n */\nexport class BreaksBlock extends Block {\n constructor(breaks: number[], parent: TSU.Nullable<Block> = null) {\n super(\"breaks\", parent);\n this.localBreaks = breaks;\n }\n}\n\n/**\n * A role block that creates a local role definition.\n *\n * Usage: \\role(\"Vocals\", notes=false) { ... }\n */\nexport class RoleBlock extends Block {\n constructor(roleName: string, notesOnly: boolean, parent: TSU.Nullable<Block> = null) {\n super(\"role\", parent);\n // Create the role locally\n this.newRoleDef(roleName, notesOnly);\n }\n}\n\n/**\n * A group block for organizing notation without special semantics.\n *\n * Usage: \\group(\"optional-name\") { ... }\n */\nexport class GroupBlock extends Block {\n constructor(groupName: string | null, parent: TSU.Nullable<Block> = null) {\n super(\"group\", parent, groupName);\n }\n}\n"]}
|
|
@@ -167,6 +167,7 @@ export class NotationView {
|
|
|
167
167
|
const lp = line.layoutParams;
|
|
168
168
|
curr = new BeatView(cell, beat, lineView.gElem, lp.cycle);
|
|
169
169
|
this.beatViews.set(beat.uuid, curr);
|
|
170
|
+
this.eagerlyPositionView(curr, cell);
|
|
170
171
|
}
|
|
171
172
|
return curr;
|
|
172
173
|
}
|
|
@@ -181,9 +182,18 @@ export class NotationView {
|
|
|
181
182
|
const isPreMarker = cell.colIndex % 3 == 0;
|
|
182
183
|
curr = new MarkerView(cell, beat, marker.markers, isPreMarker, lineView.gElem);
|
|
183
184
|
this.markerViews.set("pre:" + beat.uuid, curr);
|
|
185
|
+
this.eagerlyPositionView(curr, cell);
|
|
184
186
|
}
|
|
185
187
|
return curr;
|
|
186
188
|
}
|
|
187
189
|
}
|
|
190
|
+
eagerlyPositionView(view, cell) {
|
|
191
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
192
|
+
const x = (_b = (_a = cell.colAlign) === null || _a === void 0 ? void 0 : _a.coordOffset) !== null && _b !== void 0 ? _b : 0;
|
|
193
|
+
const y = (_d = (_c = cell.rowAlign) === null || _c === void 0 ? void 0 : _c.coordOffset) !== null && _d !== void 0 ? _d : 0;
|
|
194
|
+
const w = (_f = (_e = cell.colAlign) === null || _e === void 0 ? void 0 : _e.maxLength) !== null && _f !== void 0 ? _f : null;
|
|
195
|
+
const h = (_h = (_g = cell.rowAlign) === null || _g === void 0 ? void 0 : _g.maxLength) !== null && _h !== void 0 ? _h : null;
|
|
196
|
+
view.setBounds(x, y, w, h, true);
|
|
197
|
+
}
|
|
188
198
|
}
|
|
189
199
|
//# sourceMappingURL=NotationView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotationView.js","sourceRoot":"","sources":["../../../src/carnatic/NotationView.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { LineView } from \"./LineView\";\nimport { Notation, RawBlock, Block, BlockItem, isLine, isBlock, isRawBlock } from \"../notation\";\nimport { Beat, GlobalBeatLayout } from \"../beats\";\nimport { GridCell, GridCellView, GridLayoutGroup, LayoutChangeEvent } from \"../grids\";\nimport { Line } from \"../core\";\nimport { BeatView, MarkerView } from \"./beatviews\";\n\n/**\n * Configuration options for NotationView.\n */\nexport interface NotationViewConfig {\n /**\n * Optional shared GridLayoutGroup for column alignment across multiple NotationViews.\n * When provided, this view will share column widths with other views using the same group.\n */\n sharedGridLayoutGroup?: GridLayoutGroup;\n\n /**\n * Optional markdown parser for RawBlock content.\n */\n markdownParser?: (contents: string) => string;\n}\n\nexport class NotationView {\n headerElement: HTMLDivElement;\n notation: Notation;\n lineViews: LineView[] = [];\n // Mapping from line id -> list of beats in each of its roles\n currentSVGElement: SVGSVGElement | null = null;\n tableElement: HTMLTableElement;\n markdownParser: (contents: string) => string;\n _beatLayout: GlobalBeatLayout;\n\n /** Unsubscribe function for layout change listener */\n private layoutChangeUnsubscribe: (() => void) | null = null;\n\n constructor(\n public readonly rootElement: HTMLElement,\n public readonly config?: NotationViewConfig,\n ) {\n this.loadChildViews();\n // Default to identity function if no markdown parser provided\n this.markdownParser = config?.markdownParser ?? ((content) => content);\n }\n\n get beatLayout(): GlobalBeatLayout {\n return this._beatLayout;\n }\n\n set beatLayout(beatLayout: GlobalBeatLayout) {\n this._beatLayout = beatLayout;\n beatLayout.gridLayoutGroup.getCellView = (cell) => this.viewForBeat(cell);\n }\n\n loadChildViews(): void {\n this.tableElement = TSU.DOM.createNode(\"table\", {\n parent: this.rootElement,\n attrs: {\n class: \"notationsContentRootTable\",\n },\n }) as HTMLTableElement;\n }\n\n renderNotation(notation: Notation, beatLayout: GlobalBeatLayout): void {\n this.notation = notation;\n this.beatLayout = beatLayout;\n const startTime = performance.now();\n this.refreshLayout();\n const layoutTime = performance.now();\n console.log(`V4 Document, Layout Time: ${layoutTime - startTime}ms`);\n }\n\n public addNewRow(id: string, prefix: string, withAnnotation = true): [HTMLElement, HTMLElement] {\n const tr = TSU.DOM.createNode(\"tr\", {\n parent: this.tableElement, // parent,\n attrs: {\n class: prefix + \"Row\",\n id: prefix + \"Row\" + id,\n },\n });\n let td1: HTMLElement | null = null;\n if (withAnnotation) {\n td1 = TSU.DOM.createNode(\"td\", {\n parent: tr,\n attrs: {\n class: prefix + \"AnnotationCell\",\n id: prefix + \"Annotation\" + id,\n },\n }) as HTMLElement;\n }\n const td2 = TSU.DOM.createNode(\"td\", {\n parent: tr,\n attrs: {\n class: prefix + \"ContentCell\",\n id: prefix + \"Content\" + id,\n colspan: withAnnotation ? 1 : 2,\n },\n }) as HTMLElement;\n return [td1!, td2];\n }\n\n public newLineRoot(parent: Element, line: Line): SVGSVGElement {\n const [td1, td2] = this.addNewRow(line.uuid + \"\", \"line\");\n // Hacky solution to \"line headings\"\n if (line.marginText) {\n td1.innerHTML = line.marginText;\n }\n return TSU.DOM.createSVGNode(\"svg\", {\n parent: td2, // parent\n attrs: {\n style: \"margin-bottom: 10px\",\n class: \"lineRootSVG\",\n },\n }) as SVGSVGElement;\n }\n\n ensureLineView(line: Line): LineView {\n let lineView = this.getLineView(line);\n if (lineView == null) {\n const layoutParams = line.layoutParams || null;\n const svgElem = this.newLineRoot(this.tableElement, line);\n lineView = new LineView(svgElem, line, {\n layoutParams: layoutParams,\n } as any);\n if (!line.isEmpty) {\n // Probably because this is an empty line and AddAtoms was not called\n TSU.assert(layoutParams != null, \"Layout params for a non empty line *should* exist\");\n lineView.gridModel = this.beatLayout!.getGridModelForLine(line.uuid);\n }\n this.lineViews.push(lineView);\n }\n return lineView;\n }\n\n getLineView(line: Line): TSU.Nullable<LineView> {\n return this.lineViews.find((l) => l.line == line) || null;\n }\n\n get currentLineView(): LineView {\n return this.lineViews[this.lineViews.length - 1];\n }\n\n clear(): void {\n this.lineViews = [];\n // Mapping from line id -> list of beats in each of its roles\n this.currentSVGElement = null;\n this.tableElement.innerHTML = \"\";\n this.beatViews = new Map<number, BeatView>();\n }\n\n /**\n * Layout all the blocks in the Notation along with their corresponding blocks.\n * Key thing is here is an opportunity to perform any batch rendering as needed.\n */\n refreshLayout(): void {\n const lineViews = [] as LineView[];\n\n // Recursively process the notation (which is a Block) and collect LineViews\n this.processBlock(this.notation, lineViews);\n\n const now = performance.now();\n for (const lineView of lineViews) {\n lineView.gridModel.lastUpdatedAt = now;\n }\n\n this.beatLayout.gridLayoutGroup.refreshLayout();\n\n for (const lineView of lineViews) {\n lineView.wrapToSize();\n }\n }\n\n /**\n * Recursively processes a block and its children for rendering.\n * Uses block.children() to get expanded children (e.g., RepeatBlock expands to N copies).\n *\n * @param block The block to process\n * @param lineViews Array to collect LineViews for batch layout\n */\n protected processBlock(block: Block, lineViews: LineView[]): void {\n for (const child of block.children()) {\n this.processBlockItem(child, lineViews);\n }\n }\n\n /**\n * Processes a single block item (Block, Line, or RawBlock) for rendering.\n *\n * @param item The item to process\n * @param lineViews Array to collect LineViews for batch layout\n */\n protected processBlockItem(item: BlockItem, lineViews: LineView[]): void {\n if (isRawBlock(item)) {\n // Render raw content (markdown, metadata)\n this.renderBlock(item as RawBlock);\n } else if (isLine(item)) {\n // Render line\n const line = item as Line;\n if (!line.isEmpty) {\n const lineView = this.ensureLineView(line);\n lineViews.push(lineView);\n }\n } else if (isBlock(item)) {\n // Recursively process nested block\n this.processBlock(item as Block, lineViews);\n }\n }\n\n renderBlock(raw: RawBlock): void {\n const [, td2] = this.addNewRow(raw.uuid + \"\", \"rawBlock\", false);\n if (raw.contentType == \"metadata\") {\n // we have a metadata block\n const meta = this.notation.metadata.get(raw.content);\n if (meta) {\n // For now ignore metadata with \":\" in the key\n if (meta.key.toLowerCase().indexOf(\":\") < 0) {\n const div = td2.appendChild(TSU.DOM.createNode(\"div\"));\n const html = `<span class = \"${meta.key.toLowerCase()}\"><strong>${meta.key}</strong>: ${meta.value}</span>`;\n div.innerHTML = html;\n }\n }\n } else {\n const div = td2.appendChild(TSU.DOM.createNode(\"div\"));\n div.innerHTML = this.markdownParser(raw.content.trim());\n }\n this.currentSVGElement = null;\n }\n\n beatViews = new Map<number, BeatView>();\n markerViews = new Map<string, MarkerView>();\n viewForBeat(cell: GridCell): GridCellView {\n if (cell.colIndex % 3 == 1) {\n // beat view needed\n const beat = cell.value;\n let curr = this.beatViews.get(beat.uuid) || null;\n if (curr == null) {\n const line = beat.role.line;\n // how to get the bar and beat index for a given beat in a given row?\n const lineView = this.ensureLineView(line);\n const lp = line.layoutParams;\n curr = new BeatView(cell, beat, lineView.gElem, lp.cycle);\n this.beatViews.set(beat.uuid, curr);\n }\n return curr;\n } else {\n // markers view\n const marker = cell.value;\n const beat = marker.beat as Beat;\n let curr = this.markerViews.get(\"pre:\" + beat.uuid) || null;\n if (curr == null) {\n const line = beat.role.line;\n const lineView = this.ensureLineView(line);\n const lp = line.layoutParams;\n const isPreMarker = cell.colIndex % 3 == 0;\n curr = new MarkerView(cell, beat, marker.markers, isPreMarker, lineView.gElem);\n this.markerViews.set(\"pre:\" + beat.uuid, curr);\n }\n return curr;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NotationView.js","sourceRoot":"","sources":["../../../src/carnatic/NotationView.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { LineView } from \"./LineView\";\nimport { Notation, RawBlock, Block, BlockItem, isLine, isBlock, isRawBlock } from \"../notation\";\nimport { Beat, GlobalBeatLayout } from \"../beats\";\nimport { GridCell, GridCellView, GridLayoutGroup, LayoutChangeEvent } from \"../grids\";\nimport { Line } from \"../core\";\nimport { BeatView, MarkerView } from \"./beatviews\";\n\n/**\n * Configuration options for NotationView.\n */\nexport interface NotationViewConfig {\n /**\n * Optional shared GridLayoutGroup for column alignment across multiple NotationViews.\n * When provided, this view will share column widths with other views using the same group.\n */\n sharedGridLayoutGroup?: GridLayoutGroup;\n\n /**\n * Optional markdown parser for RawBlock content.\n */\n markdownParser?: (contents: string) => string;\n}\n\nexport class NotationView {\n headerElement: HTMLDivElement;\n notation: Notation;\n lineViews: LineView[] = [];\n // Mapping from line id -> list of beats in each of its roles\n currentSVGElement: SVGSVGElement | null = null;\n tableElement: HTMLTableElement;\n markdownParser: (contents: string) => string;\n _beatLayout: GlobalBeatLayout;\n\n /** Unsubscribe function for layout change listener */\n private layoutChangeUnsubscribe: (() => void) | null = null;\n\n constructor(\n public readonly rootElement: HTMLElement,\n public readonly config?: NotationViewConfig,\n ) {\n this.loadChildViews();\n // Default to identity function if no markdown parser provided\n this.markdownParser = config?.markdownParser ?? ((content) => content);\n }\n\n get beatLayout(): GlobalBeatLayout {\n return this._beatLayout;\n }\n\n set beatLayout(beatLayout: GlobalBeatLayout) {\n this._beatLayout = beatLayout;\n beatLayout.gridLayoutGroup.getCellView = (cell) => this.viewForBeat(cell);\n }\n\n loadChildViews(): void {\n this.tableElement = TSU.DOM.createNode(\"table\", {\n parent: this.rootElement,\n attrs: {\n class: \"notationsContentRootTable\",\n },\n }) as HTMLTableElement;\n }\n\n renderNotation(notation: Notation, beatLayout: GlobalBeatLayout): void {\n this.notation = notation;\n this.beatLayout = beatLayout;\n const startTime = performance.now();\n this.refreshLayout();\n const layoutTime = performance.now();\n console.log(`V4 Document, Layout Time: ${layoutTime - startTime}ms`);\n }\n\n public addNewRow(id: string, prefix: string, withAnnotation = true): [HTMLElement, HTMLElement] {\n const tr = TSU.DOM.createNode(\"tr\", {\n parent: this.tableElement, // parent,\n attrs: {\n class: prefix + \"Row\",\n id: prefix + \"Row\" + id,\n },\n });\n let td1: HTMLElement | null = null;\n if (withAnnotation) {\n td1 = TSU.DOM.createNode(\"td\", {\n parent: tr,\n attrs: {\n class: prefix + \"AnnotationCell\",\n id: prefix + \"Annotation\" + id,\n },\n }) as HTMLElement;\n }\n const td2 = TSU.DOM.createNode(\"td\", {\n parent: tr,\n attrs: {\n class: prefix + \"ContentCell\",\n id: prefix + \"Content\" + id,\n colspan: withAnnotation ? 1 : 2,\n },\n }) as HTMLElement;\n return [td1!, td2];\n }\n\n public newLineRoot(parent: Element, line: Line): SVGSVGElement {\n const [td1, td2] = this.addNewRow(line.uuid + \"\", \"line\");\n // Hacky solution to \"line headings\"\n if (line.marginText) {\n td1.innerHTML = line.marginText;\n }\n return TSU.DOM.createSVGNode(\"svg\", {\n parent: td2, // parent\n attrs: {\n style: \"margin-bottom: 10px\",\n class: \"lineRootSVG\",\n },\n }) as SVGSVGElement;\n }\n\n ensureLineView(line: Line): LineView {\n let lineView = this.getLineView(line);\n if (lineView == null) {\n const layoutParams = line.layoutParams || null;\n const svgElem = this.newLineRoot(this.tableElement, line);\n lineView = new LineView(svgElem, line, {\n layoutParams: layoutParams,\n } as any);\n if (!line.isEmpty) {\n // Probably because this is an empty line and AddAtoms was not called\n TSU.assert(layoutParams != null, \"Layout params for a non empty line *should* exist\");\n lineView.gridModel = this.beatLayout!.getGridModelForLine(line.uuid);\n }\n this.lineViews.push(lineView);\n }\n return lineView;\n }\n\n getLineView(line: Line): TSU.Nullable<LineView> {\n return this.lineViews.find((l) => l.line == line) || null;\n }\n\n get currentLineView(): LineView {\n return this.lineViews[this.lineViews.length - 1];\n }\n\n clear(): void {\n this.lineViews = [];\n // Mapping from line id -> list of beats in each of its roles\n this.currentSVGElement = null;\n this.tableElement.innerHTML = \"\";\n this.beatViews = new Map<number, BeatView>();\n }\n\n /**\n * Layout all the blocks in the Notation along with their corresponding blocks.\n * Key thing is here is an opportunity to perform any batch rendering as needed.\n */\n refreshLayout(): void {\n const lineViews = [] as LineView[];\n\n // Recursively process the notation (which is a Block) and collect LineViews\n this.processBlock(this.notation, lineViews);\n\n const now = performance.now();\n for (const lineView of lineViews) {\n lineView.gridModel.lastUpdatedAt = now;\n }\n\n this.beatLayout.gridLayoutGroup.refreshLayout();\n\n for (const lineView of lineViews) {\n lineView.wrapToSize();\n }\n }\n\n /**\n * Recursively processes a block and its children for rendering.\n * Uses block.children() to get expanded children (e.g., RepeatBlock expands to N copies).\n *\n * @param block The block to process\n * @param lineViews Array to collect LineViews for batch layout\n */\n protected processBlock(block: Block, lineViews: LineView[]): void {\n for (const child of block.children()) {\n this.processBlockItem(child, lineViews);\n }\n }\n\n /**\n * Processes a single block item (Block, Line, or RawBlock) for rendering.\n *\n * @param item The item to process\n * @param lineViews Array to collect LineViews for batch layout\n */\n protected processBlockItem(item: BlockItem, lineViews: LineView[]): void {\n if (isRawBlock(item)) {\n // Render raw content (markdown, metadata)\n this.renderBlock(item as RawBlock);\n } else if (isLine(item)) {\n // Render line\n const line = item as Line;\n if (!line.isEmpty) {\n const lineView = this.ensureLineView(line);\n lineViews.push(lineView);\n }\n } else if (isBlock(item)) {\n // Recursively process nested block\n this.processBlock(item as Block, lineViews);\n }\n }\n\n renderBlock(raw: RawBlock): void {\n const [, td2] = this.addNewRow(raw.uuid + \"\", \"rawBlock\", false);\n if (raw.contentType == \"metadata\") {\n // we have a metadata block\n const meta = this.notation.metadata.get(raw.content);\n if (meta) {\n // For now ignore metadata with \":\" in the key\n if (meta.key.toLowerCase().indexOf(\":\") < 0) {\n const div = td2.appendChild(TSU.DOM.createNode(\"div\"));\n const html = `<span class = \"${meta.key.toLowerCase()}\"><strong>${meta.key}</strong>: ${meta.value}</span>`;\n div.innerHTML = html;\n }\n }\n } else {\n const div = td2.appendChild(TSU.DOM.createNode(\"div\"));\n div.innerHTML = this.markdownParser(raw.content.trim());\n }\n this.currentSVGElement = null;\n }\n\n beatViews = new Map<number, BeatView>();\n markerViews = new Map<string, MarkerView>();\n viewForBeat(cell: GridCell): GridCellView {\n if (cell.colIndex % 3 == 1) {\n // beat view needed\n const beat = cell.value;\n let curr = this.beatViews.get(beat.uuid) || null;\n if (curr == null) {\n const line = beat.role.line;\n // how to get the bar and beat index for a given beat in a given row?\n const lineView = this.ensureLineView(line);\n const lp = line.layoutParams;\n curr = new BeatView(cell, beat, lineView.gElem, lp.cycle);\n this.beatViews.set(beat.uuid, curr);\n\n // Eagerly position view based on current alignment offsets.\n // Since BFS layout processes alignments in order, predecessors are already positioned.\n this.eagerlyPositionView(curr, cell);\n }\n return curr;\n } else {\n // markers view\n const marker = cell.value;\n const beat = marker.beat as Beat;\n let curr = this.markerViews.get(\"pre:\" + beat.uuid) || null;\n if (curr == null) {\n const line = beat.role.line;\n const lineView = this.ensureLineView(line);\n const lp = line.layoutParams;\n const isPreMarker = cell.colIndex % 3 == 0;\n curr = new MarkerView(cell, beat, marker.markers, isPreMarker, lineView.gElem);\n this.markerViews.set(\"pre:\" + beat.uuid, curr);\n\n // Eagerly position view based on current alignment offsets.\n this.eagerlyPositionView(curr, cell);\n }\n return curr;\n }\n }\n\n /**\n * Eagerly positions a newly created view based on current alignment offsets.\n * This helps with debugging by showing intermediate positions during BFS layout.\n */\n protected eagerlyPositionView(view: GridCellView, cell: GridCell): void {\n const x = cell.colAlign?.coordOffset ?? 0;\n const y = cell.rowAlign?.coordOffset ?? 0;\n const w = cell.colAlign?.maxLength ?? null;\n const h = cell.rowAlign?.maxLength ?? null;\n view.setBounds(x, y, w, h, true);\n }\n}\n"]}
|
|
@@ -2,7 +2,10 @@ import * as TSU from "@panyam/tsutils";
|
|
|
2
2
|
import { Atom } from "../core";
|
|
3
3
|
import { LeafAtomView as LeafAtomViewBase, GroupView as GroupViewBase, AtomView, Embelishment, ElementShape } from "../shapes";
|
|
4
4
|
export declare class GroupView extends GroupViewBase {
|
|
5
|
+
static readonly BRACKET_HEIGHT = 8;
|
|
5
6
|
createAtomView(atom: Atom): AtomView;
|
|
7
|
+
protected createEmbelishments(): Embelishment[];
|
|
8
|
+
protected refreshMinSize(): TSU.Geom.Size;
|
|
6
9
|
}
|
|
7
10
|
export declare abstract class LeafAtomView extends LeafAtomViewBase {
|
|
8
11
|
leftSlot: Embelishment[];
|
|
@@ -29,4 +32,4 @@ export declare abstract class LeafAtomView extends LeafAtomViewBase {
|
|
|
29
32
|
protected createGlyphElement(): void;
|
|
30
33
|
protected createPostSpacingElement(): void;
|
|
31
34
|
}
|
|
32
|
-
export declare function createAtomView(parent: SVGGraphicsElement, atom: Atom, litDefaultsToNote?: boolean, groupViewScale?: number): AtomView;
|
|
35
|
+
export declare function createAtomView(parent: SVGGraphicsElement, atom: Atom, litDefaultsToNote?: boolean, groupViewScale?: number, depth?: number): AtomView;
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import * as TSU from "@panyam/tsutils";
|
|
2
2
|
import { AtomType, Note, Syllable } from "../core";
|
|
3
3
|
import { LeafAtomView as LeafAtomViewBase, GroupView as GroupViewBase, ElementShape, } from "../shapes";
|
|
4
|
-
import { OctaveIndicator, Kampitham, Nokku, Spuritham, Prathyagatham, Orikkai, Odukkal, Raavi, Kandippu, Vaali, Jaaru, } from "./embelishments";
|
|
4
|
+
import { OctaveIndicator, Kampitham, Nokku, Spuritham, Prathyagatham, Orikkai, Odukkal, Raavi, Kandippu, Vaali, Jaaru, GroupBracket, } from "./embelishments";
|
|
5
5
|
import { GamakaType } from "./gamakas";
|
|
6
6
|
export class GroupView extends GroupViewBase {
|
|
7
7
|
createAtomView(atom) {
|
|
8
|
-
return createAtomView(this.groupElement, atom, this.defaultToNotes, 0.7);
|
|
8
|
+
return createAtomView(this.groupElement, atom, this.defaultToNotes, 0.7, this.depth + 1);
|
|
9
|
+
}
|
|
10
|
+
createEmbelishments() {
|
|
11
|
+
const embelishments = super.createEmbelishments();
|
|
12
|
+
if (this.depth >= 1) {
|
|
13
|
+
embelishments.push(new GroupBracket(this));
|
|
14
|
+
}
|
|
15
|
+
return embelishments;
|
|
16
|
+
}
|
|
17
|
+
refreshMinSize() {
|
|
18
|
+
const baseSize = super.refreshMinSize();
|
|
19
|
+
if (this.depth >= 1) {
|
|
20
|
+
return new TSU.Geom.Size(baseSize.width, baseSize.height + GroupView.BRACKET_HEIGHT * this.scaleFactor);
|
|
21
|
+
}
|
|
22
|
+
return baseSize;
|
|
9
23
|
}
|
|
10
24
|
}
|
|
25
|
+
GroupView.BRACKET_HEIGHT = 8;
|
|
11
26
|
export class LeafAtomView extends LeafAtomViewBase {
|
|
12
27
|
constructor() {
|
|
13
28
|
super(...arguments);
|
|
@@ -246,7 +261,7 @@ class SyllableView extends LeafAtomView {
|
|
|
246
261
|
return this.leafAtom;
|
|
247
262
|
}
|
|
248
263
|
}
|
|
249
|
-
export function createAtomView(parent, atom, litDefaultsToNote = false, groupViewScale = 1.0) {
|
|
264
|
+
export function createAtomView(parent, atom, litDefaultsToNote = false, groupViewScale = 1.0, depth = 0) {
|
|
250
265
|
let out;
|
|
251
266
|
switch (atom.TYPE) {
|
|
252
267
|
case AtomType.SPACE:
|
|
@@ -276,6 +291,7 @@ export function createAtomView(parent, atom, litDefaultsToNote = false, groupVie
|
|
|
276
291
|
default:
|
|
277
292
|
throw new Error("Invalid atom type: " + atom.TYPE);
|
|
278
293
|
}
|
|
294
|
+
out.depth = depth;
|
|
279
295
|
out.createElements(parent);
|
|
280
296
|
return out;
|
|
281
297
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atomviews.js","sourceRoot":"","sources":["../../../src/carnatic/atomviews.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Atom, Group, Literal, AtomType, Note, Space, Syllable } from \"../core\";\nimport {\n LeafAtomView as LeafAtomViewBase,\n GroupView as GroupViewBase,\n AtomView,\n Embelishment,\n ElementShape,\n} from \"../shapes\";\nimport {\n OctaveIndicator,\n Kampitham,\n Nokku,\n Spuritham,\n Prathyagatham,\n Orikkai,\n Odukkal,\n Raavi,\n Kandippu,\n Vaali,\n Jaaru,\n} from \"./embelishments\";\nimport { GamakaType } from \"./gamakas\";\n\nexport class GroupView extends GroupViewBase {\n createAtomView(atom: Atom): AtomView {\n return createAtomView(this.groupElement, atom, this.defaultToNotes, 0.7);\n }\n}\n\nexport abstract class LeafAtomView extends LeafAtomViewBase {\n leftSlot: Embelishment[] = [];\n topSlot: Embelishment[] = [];\n rightSlot: Embelishment[] = [];\n bottomSlot: Embelishment[] = [];\n glyph: ElementShape;\n\n // Spaces required before and after to accomodate for left and right slots\n protected postSpacingSpan: SVGTSpanElement;\n // Sometimes this.element may not be the root element if we need spacings\n // the rootElement is the top of the chain\n protected rootGroup: ElementShape;\n protected rootText: ElementShape;\n\n abstract get glyphLabel(): string;\n\n protected refreshBBox(): TSU.Geom.Rect {\n return TSU.DOM.svgBBox(this.rootGroup.element);\n }\n\n protected refreshMinSize(): TSU.Geom.Size {\n const out = { ...this.rootText.minSize };\n const totalWidth =\n this.leftSlot.reduce((a, b) => a + b.minSize.width, 0) +\n this.rightSlot.reduce((a, b) => a + b.minSize.width, 0) +\n this.leftSlot.length + // Padding of 1\n this.rightSlot.length; // Padding of 1\n const totalHeight =\n this.topSlot.reduce((a, b) => a + b.minSize.height, 0) +\n this.bottomSlot.reduce((a, b) => a + b.minSize.height, 0);\n out.width += totalWidth;\n out.height += totalHeight;\n // if (this.postSpacingSpan) out.width += this.postSpacingSpan.getBBox().width;\n return out;\n }\n\n /**\n * Returns the horizontal offset from the atom's origin to where the note glyph starts.\n * This is the total width of left embellishments (e.g., Jaaru symbols).\n */\n get glyphOffset(): number {\n return (\n this.leftSlot.reduce((a, b) => a + b.minSize.width, 0) + this.leftSlot.length // Padding of 1 per embellishment\n );\n }\n\n protected updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null] {\n return [x, y, NaN, NaN];\n }\n\n protected layoutElements(): void {\n // Lays out all the child elements locally\n const textSize = this.rootText.minSize;\n // assume text is at 0,0 and lay things around it\n\n // now layout leftSlots\n let currX = 0;\n let currY = this.hasY ? this.y : 0;\n // place left embelishments\n for (const emb of this.leftSlot) {\n emb.x = currX;\n emb.refreshLayout();\n currX += emb.minSize.width + 1;\n }\n\n // now place the text\n const textX = currX;\n this.rootText.x = currX;\n this.rootText.refreshLayout();\n\n // And right embelishments\n currX += this.rootText.minSize.width;\n for (const emb of this.rightSlot) {\n emb.x = currX;\n emb.refreshLayout();\n currX += emb.minSize.width + 1;\n }\n\n // layout top and bottom if x or y has changed\n const gminSize = this.glyph.minSize;\n\n // top embelishments\n const glyphX = textX + this.glyph.x;\n const glyphY = this.glyph.y;\n currY = glyphY - this.glyph.minSize.height + 5;\n for (const emb of this.topSlot) {\n const bb = emb.minSize;\n emb.setBounds(glyphX + (gminSize.width - bb.width) / 2, currY - bb.height, null, null, true);\n currY = emb.y;\n }\n\n // bottom embelishments\n currY = glyphY + 7;\n for (const emb of this.bottomSlot) {\n const bb = emb.minSize;\n emb.setBounds(glyphX + (gminSize.width - bb.width) / 2, currY, null, null, true);\n currY = emb.y + bb.height;\n }\n this.invalidateBounds();\n }\n\n refreshLayout(): void {\n // TODO - move this code out to refreshLayout?\n // set the glyphs Y first so we can layout others\n this.layoutElements();\n this.rootGroup.element.setAttribute(\"transform\", \"translate(\" + this.x + \",\" + this.y + \")\");\n }\n\n protected addEmbelishment(slot: Embelishment[], emb: Embelishment): void {\n slot.push(emb);\n // this.addShape(emb);\n }\n\n /**\n * Orders embelishments and creates their views.\n */\n orderEmbelishments(): void {\n const atom = this.leafAtom;\n if (atom.TYPE != AtomType.SYLLABLE && atom.TYPE != AtomType.NOTE) {\n return;\n }\n const lit = atom as Literal;\n if (lit.embelishments.length == 0) return;\n for (const emb of lit.embelishments) {\n switch (emb.type) {\n case GamakaType.Kampitham:\n this.addEmbelishment(this.topSlot, new Kampitham(this));\n break;\n case GamakaType.Nokku:\n this.addEmbelishment(this.topSlot, new Nokku(this));\n break;\n case GamakaType.Spuritham:\n this.addEmbelishment(this.topSlot, new Spuritham(this));\n break;\n case GamakaType.Prathyagatham:\n this.addEmbelishment(this.topSlot, new Prathyagatham(this));\n break;\n case GamakaType.Orikkai:\n this.addEmbelishment(this.topSlot, new Orikkai(this));\n break;\n case GamakaType.Odukkal:\n this.addEmbelishment(this.topSlot, new Odukkal(this));\n break;\n case GamakaType.Aahaatam_Raavi:\n this.addEmbelishment(this.topSlot, new Raavi(this));\n break;\n case GamakaType.Aahaatam_Kandippu:\n this.addEmbelishment(this.topSlot, new Kandippu(this));\n break;\n case GamakaType.Vaali:\n this.addEmbelishment(this.topSlot, new Vaali(this));\n break;\n case GamakaType.Jaaru_Eetra:\n case GamakaType.Jaaru_Irakka:\n this.addEmbelishment(this.leftSlot, new Jaaru(emb, this));\n break;\n }\n }\n }\n\n embRoot(): SVGGraphicsElement {\n return this.rootGroup.element;\n }\n\n needsRootElement(): boolean {\n return true; // this.rightSlot.length > 0 || this.leafAtom.beforeRest;\n }\n\n createElements(parent: SVGGraphicsElement): void {\n // Create the glyph element first before anything\n // this allows embelishments to get early access to this element\n this.createGlyphRoot(parent);\n this.createGlyphElement();\n // Order embelishments (without creating any views)\n this.orderEmbelishments();\n this.createPostSpacingElement();\n this.invalidateBounds();\n }\n\n protected createGlyphRoot(parent: SVGGraphicsElement): void {\n this.rootGroup = new ElementShape(\n TSU.DOM.createSVGNode(\"g\", {\n doc: document,\n parent: parent,\n attrs: {\n atomid: this.leafAtom.uuid,\n class: \"atomViewRootGroup\",\n id: \"atomViewRootGroup\" + this.leafAtom.uuid,\n },\n }),\n );\n this.rootText = new ElementShape(\n TSU.DOM.createSVGNode(\"text\", {\n doc: document,\n parent: this.rootGroup.element,\n attrs: {\n atomid: this.leafAtom.uuid,\n class: \"atomViewTextRoot\",\n id: \"atomViewTextRoot\" + this.leafAtom.uuid,\n },\n }),\n );\n }\n\n protected createGlyphElement(): void {\n const atom = this.leafAtom;\n this.glyph = new ElementShape(\n TSU.DOM.createSVGNode(\"tspan\", {\n doc: document,\n parent: this.rootText.element,\n attrs: {\n atomid: atom.uuid,\n id: \"atomGlyph\" + atom.uuid,\n },\n text: this.glyphLabel, // + (note.beforeRest ? \" - \" : \" \"),\n }),\n );\n }\n\n protected createPostSpacingElement(): void {\n if (this.leafAtom.beforeRest) {\n this.postSpacingSpan = TSU.DOM.createSVGNode(\"tspan\", {\n doc: document,\n parent: this.rootText.element,\n attrs: {\n atomid: this.leafAtom.uuid,\n id: \"postSpacing\" + this.leafAtom.uuid,\n },\n text: this.leafAtom.beforeRest ? \" - \" : \" \",\n });\n }\n }\n}\n\nclass SpaceView extends LeafAtomView {\n get glyphLabel(): string {\n if (this.space.isSilent) return \" \";\n if (this.space.duration.isOne) return \",\";\n if (this.space.duration.cmpNum(2) == 0) return \";\";\n return \"_\";\n }\n\n get space(): Space {\n return this.leafAtom as Space;\n }\n}\n\nclass NoteView extends LeafAtomView {\n protected shiftElement: SVGTSpanElement;\n get glyphLabel(): string {\n return this.note.value;\n }\n\n needsRootElement(): boolean {\n return true; // this.note.shift == true || this.note.shift != 0 || super.needsRootElement();\n }\n\n protected createGlyphElement(): void {\n super.createGlyphElement();\n if (this.note.shift == true || this.note.shift != 0) {\n this.shiftElement = TSU.DOM.createSVGNode(\"tspan\", {\n doc: document,\n parent: this.rootText.element,\n attrs: {\n atomid: this.note.uuid,\n class: \"noteShiftTSpan\",\n id: \"noteShift\" + this.note.uuid,\n \"baseline-shift\": \"sub\",\n },\n text: (this.note.shift == true ? \"*\" : this.note.shift) + \" \",\n });\n }\n }\n\n protected moveGlyphToRoot(): void {\n // super.moveGlyphToRoot();\n if (this.shiftElement) {\n this.rootGroup.element.appendChild(this.shiftElement);\n }\n }\n\n orderEmbelishments(): void {\n const note = this.note;\n // create the embelishments if needed\n if (note.octave > 0) {\n this.topSlot.push(new OctaveIndicator(this, note));\n } else if (this.note.octave < 0) {\n this.bottomSlot.push(new OctaveIndicator(this, note));\n }\n super.orderEmbelishments();\n }\n\n get note(): Note {\n return this.leafAtom as Note;\n }\n}\n\nclass SyllableView extends LeafAtomView {\n get glyphLabel(): string {\n return this.syllable.value;\n }\n\n get syllable(): Syllable {\n return this.leafAtom as Syllable;\n }\n}\n\nexport function createAtomView(\n parent: SVGGraphicsElement,\n atom: Atom,\n litDefaultsToNote = false,\n groupViewScale = 1.0,\n): AtomView {\n let out: AtomView;\n switch (atom.TYPE) {\n // Dealing with leaf atoms\n case AtomType.SPACE:\n out = new SpaceView(atom as Space);\n break;\n case AtomType.SYLLABLE:\n out = new SyllableView(atom as Syllable);\n break;\n case AtomType.NOTE:\n out = new NoteView(atom as Note);\n break;\n case AtomType.LITERAL:\n if (litDefaultsToNote) {\n const lit = Note.fromLit(atom as Note);\n out = new NoteView(lit);\n } else {\n const lit = Syllable.fromLit(atom as Syllable);\n out = new SyllableView(lit);\n }\n break;\n case AtomType.GROUP:\n out = new GroupView(atom as Group);\n (out as GroupView).defaultToNotes = litDefaultsToNote;\n (out as GroupView).scaleFactor = groupViewScale;\n break;\n default:\n // We should never get a group as we are iterating\n // at leaf atom levels\n throw new Error(\"Invalid atom type: \" + atom.TYPE);\n }\n out.createElements(parent);\n return out;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"atomviews.js","sourceRoot":"","sources":["../../../src/carnatic/atomviews.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Atom, Group, Literal, AtomType, Note, Space, Syllable } from \"../core\";\nimport {\n LeafAtomView as LeafAtomViewBase,\n GroupView as GroupViewBase,\n AtomView,\n Embelishment,\n ElementShape,\n} from \"../shapes\";\nimport {\n OctaveIndicator,\n Kampitham,\n Nokku,\n Spuritham,\n Prathyagatham,\n Orikkai,\n Odukkal,\n Raavi,\n Kandippu,\n Vaali,\n Jaaru,\n GroupBracket,\n} from \"./embelishments\";\nimport { GamakaType } from \"./gamakas\";\n\nexport class GroupView extends GroupViewBase {\n /** Height reserved for bracket line (lineOffset + circleRadius + padding) */\n static readonly BRACKET_HEIGHT = 8;\n\n createAtomView(atom: Atom): AtomView {\n // Propagate depth + 1 to child atoms\n return createAtomView(this.groupElement, atom, this.defaultToNotes, 0.7, this.depth + 1);\n }\n\n /**\n * Creates embellishments for this group, including the bracket line\n * that serves as the top border of this group container.\n */\n protected createEmbelishments(): Embelishment[] {\n const embelishments = super.createEmbelishments();\n // Add bracket line for nested groups (depth >= 1)\n if (this.depth >= 1) {\n embelishments.push(new GroupBracket(this));\n }\n return embelishments;\n }\n\n /**\n * Calculates the minimum size of this group, including space for the bracket line.\n * The bracket line adds height for nested groups (depth >= 1).\n */\n protected refreshMinSize(): TSU.Geom.Size {\n const baseSize = super.refreshMinSize();\n\n // Add height for bracket line if this is a nested group\n if (this.depth >= 1) {\n return new TSU.Geom.Size(baseSize.width, baseSize.height + GroupView.BRACKET_HEIGHT * this.scaleFactor);\n }\n\n return baseSize;\n }\n}\n\nexport abstract class LeafAtomView extends LeafAtomViewBase {\n leftSlot: Embelishment[] = [];\n topSlot: Embelishment[] = [];\n rightSlot: Embelishment[] = [];\n bottomSlot: Embelishment[] = [];\n glyph: ElementShape;\n\n // Spaces required before and after to accomodate for left and right slots\n protected postSpacingSpan: SVGTSpanElement;\n // Sometimes this.element may not be the root element if we need spacings\n // the rootElement is the top of the chain\n protected rootGroup: ElementShape;\n protected rootText: ElementShape;\n\n abstract get glyphLabel(): string;\n\n protected refreshBBox(): TSU.Geom.Rect {\n return TSU.DOM.svgBBox(this.rootGroup.element);\n }\n\n protected refreshMinSize(): TSU.Geom.Size {\n const out = { ...this.rootText.minSize };\n const totalWidth =\n this.leftSlot.reduce((a, b) => a + b.minSize.width, 0) +\n this.rightSlot.reduce((a, b) => a + b.minSize.width, 0) +\n this.leftSlot.length + // Padding of 1\n this.rightSlot.length; // Padding of 1\n const totalHeight =\n this.topSlot.reduce((a, b) => a + b.minSize.height, 0) +\n this.bottomSlot.reduce((a, b) => a + b.minSize.height, 0);\n out.width += totalWidth;\n out.height += totalHeight;\n // if (this.postSpacingSpan) out.width += this.postSpacingSpan.getBBox().width;\n return out;\n }\n\n /**\n * Returns the horizontal offset from the atom's origin to where the note glyph starts.\n * This is the total width of left embellishments (e.g., Jaaru symbols).\n */\n get glyphOffset(): number {\n return (\n this.leftSlot.reduce((a, b) => a + b.minSize.width, 0) + this.leftSlot.length // Padding of 1 per embellishment\n );\n }\n\n protected updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null] {\n return [x, y, NaN, NaN];\n }\n\n protected layoutElements(): void {\n // Lays out all the child elements locally\n const textSize = this.rootText.minSize;\n // assume text is at 0,0 and lay things around it\n\n // now layout leftSlots\n let currX = 0;\n let currY = this.hasY ? this.y : 0;\n // place left embelishments\n for (const emb of this.leftSlot) {\n emb.x = currX;\n emb.refreshLayout();\n currX += emb.minSize.width + 1;\n }\n\n // now place the text\n const textX = currX;\n this.rootText.x = currX;\n this.rootText.refreshLayout();\n\n // And right embelishments\n currX += this.rootText.minSize.width;\n for (const emb of this.rightSlot) {\n emb.x = currX;\n emb.refreshLayout();\n currX += emb.minSize.width + 1;\n }\n\n // layout top and bottom if x or y has changed\n const gminSize = this.glyph.minSize;\n\n // top embelishments\n const glyphX = textX + this.glyph.x;\n const glyphY = this.glyph.y;\n currY = glyphY - this.glyph.minSize.height + 5;\n for (const emb of this.topSlot) {\n const bb = emb.minSize;\n emb.setBounds(glyphX + (gminSize.width - bb.width) / 2, currY - bb.height, null, null, true);\n currY = emb.y;\n }\n\n // bottom embelishments\n currY = glyphY + 7;\n for (const emb of this.bottomSlot) {\n const bb = emb.minSize;\n emb.setBounds(glyphX + (gminSize.width - bb.width) / 2, currY, null, null, true);\n currY = emb.y + bb.height;\n }\n this.invalidateBounds();\n }\n\n refreshLayout(): void {\n // TODO - move this code out to refreshLayout?\n // set the glyphs Y first so we can layout others\n this.layoutElements();\n this.rootGroup.element.setAttribute(\"transform\", \"translate(\" + this.x + \",\" + this.y + \")\");\n }\n\n protected addEmbelishment(slot: Embelishment[], emb: Embelishment): void {\n slot.push(emb);\n // this.addShape(emb);\n }\n\n /**\n * Orders embelishments and creates their views.\n */\n orderEmbelishments(): void {\n const atom = this.leafAtom;\n if (atom.TYPE != AtomType.SYLLABLE && atom.TYPE != AtomType.NOTE) {\n return;\n }\n const lit = atom as Literal;\n if (lit.embelishments.length == 0) return;\n for (const emb of lit.embelishments) {\n switch (emb.type) {\n case GamakaType.Kampitham:\n this.addEmbelishment(this.topSlot, new Kampitham(this));\n break;\n case GamakaType.Nokku:\n this.addEmbelishment(this.topSlot, new Nokku(this));\n break;\n case GamakaType.Spuritham:\n this.addEmbelishment(this.topSlot, new Spuritham(this));\n break;\n case GamakaType.Prathyagatham:\n this.addEmbelishment(this.topSlot, new Prathyagatham(this));\n break;\n case GamakaType.Orikkai:\n this.addEmbelishment(this.topSlot, new Orikkai(this));\n break;\n case GamakaType.Odukkal:\n this.addEmbelishment(this.topSlot, new Odukkal(this));\n break;\n case GamakaType.Aahaatam_Raavi:\n this.addEmbelishment(this.topSlot, new Raavi(this));\n break;\n case GamakaType.Aahaatam_Kandippu:\n this.addEmbelishment(this.topSlot, new Kandippu(this));\n break;\n case GamakaType.Vaali:\n this.addEmbelishment(this.topSlot, new Vaali(this));\n break;\n case GamakaType.Jaaru_Eetra:\n case GamakaType.Jaaru_Irakka:\n this.addEmbelishment(this.leftSlot, new Jaaru(emb, this));\n break;\n }\n }\n }\n\n embRoot(): SVGGraphicsElement {\n return this.rootGroup.element;\n }\n\n needsRootElement(): boolean {\n return true; // this.rightSlot.length > 0 || this.leafAtom.beforeRest;\n }\n\n createElements(parent: SVGGraphicsElement): void {\n // Create the glyph element first before anything\n // this allows embelishments to get early access to this element\n this.createGlyphRoot(parent);\n this.createGlyphElement();\n // Order embelishments (without creating any views)\n this.orderEmbelishments();\n this.createPostSpacingElement();\n this.invalidateBounds();\n }\n\n protected createGlyphRoot(parent: SVGGraphicsElement): void {\n this.rootGroup = new ElementShape(\n TSU.DOM.createSVGNode(\"g\", {\n doc: document,\n parent: parent,\n attrs: {\n atomid: this.leafAtom.uuid,\n class: \"atomViewRootGroup\",\n id: \"atomViewRootGroup\" + this.leafAtom.uuid,\n },\n }),\n );\n this.rootText = new ElementShape(\n TSU.DOM.createSVGNode(\"text\", {\n doc: document,\n parent: this.rootGroup.element,\n attrs: {\n atomid: this.leafAtom.uuid,\n class: \"atomViewTextRoot\",\n id: \"atomViewTextRoot\" + this.leafAtom.uuid,\n },\n }),\n );\n }\n\n protected createGlyphElement(): void {\n const atom = this.leafAtom;\n this.glyph = new ElementShape(\n TSU.DOM.createSVGNode(\"tspan\", {\n doc: document,\n parent: this.rootText.element,\n attrs: {\n atomid: atom.uuid,\n id: \"atomGlyph\" + atom.uuid,\n },\n text: this.glyphLabel, // + (note.beforeRest ? \" - \" : \" \"),\n }),\n );\n }\n\n protected createPostSpacingElement(): void {\n if (this.leafAtom.beforeRest) {\n this.postSpacingSpan = TSU.DOM.createSVGNode(\"tspan\", {\n doc: document,\n parent: this.rootText.element,\n attrs: {\n atomid: this.leafAtom.uuid,\n id: \"postSpacing\" + this.leafAtom.uuid,\n },\n text: this.leafAtom.beforeRest ? \" - \" : \" \",\n });\n }\n }\n}\n\nclass SpaceView extends LeafAtomView {\n get glyphLabel(): string {\n if (this.space.isSilent) return \" \";\n if (this.space.duration.isOne) return \",\";\n if (this.space.duration.cmpNum(2) == 0) return \";\";\n return \"_\";\n }\n\n get space(): Space {\n return this.leafAtom as Space;\n }\n}\n\nclass NoteView extends LeafAtomView {\n protected shiftElement: SVGTSpanElement;\n get glyphLabel(): string {\n return this.note.value;\n }\n\n needsRootElement(): boolean {\n return true; // this.note.shift == true || this.note.shift != 0 || super.needsRootElement();\n }\n\n protected createGlyphElement(): void {\n super.createGlyphElement();\n if (this.note.shift == true || this.note.shift != 0) {\n this.shiftElement = TSU.DOM.createSVGNode(\"tspan\", {\n doc: document,\n parent: this.rootText.element,\n attrs: {\n atomid: this.note.uuid,\n class: \"noteShiftTSpan\",\n id: \"noteShift\" + this.note.uuid,\n \"baseline-shift\": \"sub\",\n },\n text: (this.note.shift == true ? \"*\" : this.note.shift) + \" \",\n });\n }\n }\n\n protected moveGlyphToRoot(): void {\n // super.moveGlyphToRoot();\n if (this.shiftElement) {\n this.rootGroup.element.appendChild(this.shiftElement);\n }\n }\n\n orderEmbelishments(): void {\n const note = this.note;\n // create the embelishments if needed\n if (note.octave > 0) {\n this.topSlot.push(new OctaveIndicator(this, note));\n } else if (this.note.octave < 0) {\n this.bottomSlot.push(new OctaveIndicator(this, note));\n }\n super.orderEmbelishments();\n }\n\n get note(): Note {\n return this.leafAtom as Note;\n }\n}\n\nclass SyllableView extends LeafAtomView {\n get glyphLabel(): string {\n return this.syllable.value;\n }\n\n get syllable(): Syllable {\n return this.leafAtom as Syllable;\n }\n}\n\nexport function createAtomView(\n parent: SVGGraphicsElement,\n atom: Atom,\n litDefaultsToNote = false,\n groupViewScale = 1.0,\n depth = 0,\n): AtomView {\n let out: AtomView;\n switch (atom.TYPE) {\n // Dealing with leaf atoms\n case AtomType.SPACE:\n out = new SpaceView(atom as Space);\n break;\n case AtomType.SYLLABLE:\n out = new SyllableView(atom as Syllable);\n break;\n case AtomType.NOTE:\n out = new NoteView(atom as Note);\n break;\n case AtomType.LITERAL:\n if (litDefaultsToNote) {\n const lit = Note.fromLit(atom as Note);\n out = new NoteView(lit);\n } else {\n const lit = Syllable.fromLit(atom as Syllable);\n out = new SyllableView(lit);\n }\n break;\n case AtomType.GROUP:\n out = new GroupView(atom as Group);\n (out as GroupView).defaultToNotes = litDefaultsToNote;\n (out as GroupView).scaleFactor = groupViewScale;\n break;\n default:\n // We should never get a group as we are iterating\n // at leaf atom levels\n throw new Error(\"Invalid atom type: \" + atom.TYPE);\n }\n out.depth = depth;\n out.createElements(parent);\n return out;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as TSU from "@panyam/tsutils";
|
|
2
2
|
import { Note } from "../core";
|
|
3
3
|
import { BeatView } from "../beatview";
|
|
4
|
-
import { Embelishment } from "../shapes";
|
|
4
|
+
import { Embelishment, GroupView as GroupViewBase } from "../shapes";
|
|
5
5
|
import { LeafAtomView } from "./atomviews";
|
|
6
6
|
import { JaaruGamaka } from "./gamakas";
|
|
7
7
|
export declare abstract class LeafAtomViewEmbelishment extends Embelishment {
|
|
@@ -101,3 +101,20 @@ export declare class Jaaru extends LeafAtomViewEmbelishment {
|
|
|
101
101
|
protected updateBounds(x: null | number, _y: null | number, _w: null | number, _h: null | number): [number | null, number | null, number | null, number | null];
|
|
102
102
|
refreshLayout(): void;
|
|
103
103
|
}
|
|
104
|
+
export type GroupBracketPositionMode = "above-all" | "below-embellishments" | "separate-space";
|
|
105
|
+
export declare class GroupBracket extends Embelishment {
|
|
106
|
+
readonly groupView: GroupViewBase;
|
|
107
|
+
private line;
|
|
108
|
+
private leftCircle;
|
|
109
|
+
private rightCircle;
|
|
110
|
+
private bracketGroup;
|
|
111
|
+
lineOffset: number;
|
|
112
|
+
circleRadius: number;
|
|
113
|
+
lineExtension: number;
|
|
114
|
+
positionMode: GroupBracketPositionMode;
|
|
115
|
+
constructor(groupView: GroupViewBase);
|
|
116
|
+
protected refreshBBox(): TSU.Geom.Rect;
|
|
117
|
+
protected refreshMinSize(): TSU.Geom.Size;
|
|
118
|
+
protected updateBounds(x: null | number, y: null | number, w: null | number, h: null | number): [number | null, number | null, number | null, number | null];
|
|
119
|
+
refreshLayout(): void;
|
|
120
|
+
}
|
|
@@ -271,4 +271,89 @@ export class Jaaru extends LeafAtomViewEmbelishment {
|
|
|
271
271
|
this.pathElem.setAttribute("d", this.pathAttribute(this.x));
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
|
+
export class GroupBracket extends Embelishment {
|
|
275
|
+
constructor(groupView) {
|
|
276
|
+
super();
|
|
277
|
+
this.groupView = groupView;
|
|
278
|
+
this.line = null;
|
|
279
|
+
this.leftCircle = null;
|
|
280
|
+
this.rightCircle = null;
|
|
281
|
+
this.bracketGroup = null;
|
|
282
|
+
this.lineOffset = 2;
|
|
283
|
+
this.circleRadius = 1.5;
|
|
284
|
+
this.lineExtension = 2;
|
|
285
|
+
this.positionMode = "below-embellishments";
|
|
286
|
+
this.bracketGroup = TSU.DOM.createSVGNode("g", {
|
|
287
|
+
doc: document,
|
|
288
|
+
parent: this.groupView.groupElement,
|
|
289
|
+
attrs: {
|
|
290
|
+
class: "group-bracket",
|
|
291
|
+
source: "group" + this.groupView.group.uuid,
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
this.line = TSU.DOM.createSVGNode("line", {
|
|
295
|
+
doc: document,
|
|
296
|
+
parent: this.bracketGroup,
|
|
297
|
+
attrs: {
|
|
298
|
+
class: "group-bracket-line",
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
this.leftCircle = TSU.DOM.createSVGNode("circle", {
|
|
302
|
+
doc: document,
|
|
303
|
+
parent: this.bracketGroup,
|
|
304
|
+
attrs: {
|
|
305
|
+
class: "group-bracket-circle",
|
|
306
|
+
r: String(this.circleRadius),
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
this.rightCircle = TSU.DOM.createSVGNode("circle", {
|
|
310
|
+
doc: document,
|
|
311
|
+
parent: this.bracketGroup,
|
|
312
|
+
attrs: {
|
|
313
|
+
class: "group-bracket-circle",
|
|
314
|
+
r: String(this.circleRadius),
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
refreshBBox() {
|
|
319
|
+
if (!this.bracketGroup)
|
|
320
|
+
return new TSU.Geom.Rect(0, 0, 0, 0);
|
|
321
|
+
return TSU.DOM.svgBBox(this.bracketGroup);
|
|
322
|
+
}
|
|
323
|
+
refreshMinSize() {
|
|
324
|
+
return new TSU.Geom.Size(0, this.lineOffset + this.circleRadius);
|
|
325
|
+
}
|
|
326
|
+
updateBounds(x, y, w, h) {
|
|
327
|
+
return [x, y, w, h];
|
|
328
|
+
}
|
|
329
|
+
refreshLayout() {
|
|
330
|
+
if (!this.line || !this.leftCircle || !this.rightCircle)
|
|
331
|
+
return;
|
|
332
|
+
const bbox = this.groupView.bbox;
|
|
333
|
+
const groupWidth = this.groupView.contentWidth || bbox.width;
|
|
334
|
+
let y;
|
|
335
|
+
switch (this.positionMode) {
|
|
336
|
+
case "below-embellishments":
|
|
337
|
+
y = bbox.y + this.lineOffset - 2;
|
|
338
|
+
break;
|
|
339
|
+
case "separate-space":
|
|
340
|
+
y = bbox.y - this.lineOffset;
|
|
341
|
+
break;
|
|
342
|
+
case "above-all":
|
|
343
|
+
default:
|
|
344
|
+
y = bbox.y - this.lineOffset;
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
const x1 = -this.lineExtension;
|
|
348
|
+
const x2 = groupWidth + this.lineExtension;
|
|
349
|
+
this.line.setAttribute("x1", String(x1));
|
|
350
|
+
this.line.setAttribute("y1", String(y));
|
|
351
|
+
this.line.setAttribute("x2", String(x2));
|
|
352
|
+
this.line.setAttribute("y2", String(y));
|
|
353
|
+
this.leftCircle.setAttribute("cx", String(x1));
|
|
354
|
+
this.leftCircle.setAttribute("cy", String(y));
|
|
355
|
+
this.rightCircle.setAttribute("cx", String(x2));
|
|
356
|
+
this.rightCircle.setAttribute("cy", String(y));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
274
359
|
//# sourceMappingURL=embelishments.js.map
|