UNPKG

smoosic

Version:

<sub>[Github site](https://github.com/Smoosic/smoosic) | [source documentation](https://smoosic.github.io/Smoosic/release/docs/modules.html) | [change notes](https://aarondavidnewman.github.io/Smoosic/changes.html) | [application](https://smoosic.github.i

311 lines (308 loc) 9.38 kB
// [Smoosic](https://github.com/AaronDavidNewman/Smoosic) // Copyright (c) Aaron David Newman 2021. import { DialogDefinition, SuiDialogParams } from './dialog'; import { SmoSlur, SlurNumberParams } from '../../smo/data/staffModifiers'; import { SuiScoreViewOperations } from '../../render/sui/scoreViewOperations'; import { SuiComponentAdapter, SuiDialogAdapterBase } from './adapter'; import { SmoOperation } from '../../smo/xform/operations'; import { SmoScore } from '../../smo/data/score'; import { PromiseHelpers } from '../../common/promiseHelpers'; declare var $: any; export type SlurNumber = 'spacing' | 'thickness' | 'xOffset' | 'yOffset' | 'position' | 'position_end' | 'cp1x' | 'cp1y' | 'cp2x' | 'cp2y' | 'orientation'; /** * Slur properties * @category SuiDialog */ export class SuiSlurAdapter extends SuiComponentAdapter { slur: SmoSlur; backup: SmoSlur; changed: boolean = false; updating: boolean = false; constructor(view: SuiScoreViewOperations, slur: SmoSlur) { super(view); this.slur = slur; this.view = view; this.backup = new SmoSlur(this.slur); // Set the same id so the erase works this.backup.attrs.id = slur.attrs.id; this.backup.associatedStaff = this.slur.associatedStaff; } writeSlurNumber(view: SuiScoreViewOperations, slur: SmoSlur, key: SlurNumber, value: number) { const current = new SmoSlur(slur); slur[key] = value; view.addOrUpdateStaffModifier(current, slur); this.changed = true; } async cancel() { if (!this.changed) { return; } await this.view.addOrUpdateStaffModifier(this.slur, this.backup); } async commit() { return PromiseHelpers.emptyPromise(); } get resetAll(): boolean { return false; } set resetAll(value: boolean) { this.resetDefaults = value; const slurs: SmoSlur[] = []; const self = this; this.updating = true; const updateSlur = async (score: SmoScore, slur: SmoSlur) => { const params = SmoOperation.getDefaultSlurDirection(score, slur.startSelector, slur.endSelector); const original = new SmoSlur(slur); SlurNumberParams.forEach((key) => { slur[key] = params[key]; }); await self.view.addOrUpdateStaffModifier(original, slur); } new Promise<void>((resolve) => { const nextSlur = () => { setTimeout(() => { if (slurs.length) { const slur = slurs.pop(); updateSlur(self.view.score, slur!).then(() => { nextSlur(); }); } else { self.updating = false; resolve(); } }, 1); } nextSlur(); }); this.view.score.staves.forEach((staff) => { staff.modifiers.filter((x) => x.ctor === 'SmoSlur').forEach((smoObj) => { const slur = smoObj as SmoSlur; slurs.push(slur); }); }); this.changed = true; } get resetDefaults(): boolean { return false; } set resetDefaults(value: boolean) { const params = SmoOperation.getDefaultSlurDirection(this.view.score, this.slur.startSelector, this.slur.endSelector); SlurNumberParams.forEach((key) => { this.slur[key] = params[key]; }); this.view.addOrUpdateStaffModifier(this.backup, this.slur); this.changed = true; } get cp2y(): number { return this.slur.cp2y; } set cp2y(value: number) { this.writeSlurNumber(this.view, this.slur, 'cp2y', value); } get cp2x(): number { return this.slur.cp2x; } set cp2x(value: number) { this.writeSlurNumber(this.view, this.slur, 'cp2x', value); } get cp1y(): number { return this.slur.cp1y; } set cp1y(value: number) { this.writeSlurNumber(this.view, this.slur, 'cp1y', value); } get cp1x(): number { return this.slur.cp1x; } set cp1x(value: number) { this.writeSlurNumber(this.view, this.slur, 'cp1x', value); } get orientation(): number { return this.slur.orientation; } set orientation(value: number) { this.writeSlurNumber(this.view, this.slur, 'orientation', value); } get position_end(): number { return this.slur.position_end; } set position_end(value: number) { this.writeSlurNumber(this.view, this.slur, 'position_end', value); } get position(): number { return this.slur.position; } set position(value: number) { this.writeSlurNumber(this.view, this.slur, 'position', value); } get yOffset(): number { return this.slur.yOffset; } set yOffset(value: number) { this.writeSlurNumber(this.view, this.slur, 'yOffset', value); } get xOffset(): number { return this.slur.xOffset; } set xOffset(value: number) { this.writeSlurNumber(this.view, this.slur, 'xOffset', value); } get thickness(): number { return this.slur.thickness; } set thickness(value: number) { this.writeSlurNumber(this.view, this.slur, 'thickness', value); } get spacing(): number { return this.slur.spacing; } set spacing(value: number) { this.writeSlurNumber(this.view, this.slur, 'spacing', value); } async remove() { await this.view.removeStaffModifier(this.backup); } } /** * @category SuiDialog */ export class SuiSlurAttributesDialog extends SuiDialogAdapterBase<SuiSlurAdapter> { static dialogElements: DialogDefinition = { label: 'Slur Properties', elements: [{ smoName: 'spacing', defaultValue: 2, control: 'SuiRockerComponent', label: 'Spacing' }, { smoName: 'thickness', defaultValue: 2, control: 'SuiRockerComponent', label: 'Thickness' }, { smoName: 'xOffset', defaultValue: 0, control: 'SuiRockerComponent', label: 'X Offset' }, { smoName: 'yOffset', defaultValue: 10, control: 'SuiRockerComponent', label: 'Y Offset' }, { smoName: 'position', defaultValue: SmoSlur.positions.AUTO, dataType: 'int', options: [{ value: SmoSlur.positions.AUTO, label: 'Auto' }, { value: SmoSlur.positions.HEAD, label: 'Head' },{ value: SmoSlur.positions.TOP, label: 'Top' }], control: 'SuiDropdownComponent', label: 'Start Position' }, { smoName: 'position_end', defaultValue: SmoSlur.positions.HEAD, dataType: 'int', options: [{ value: SmoSlur.positions.AUTO, label: 'Auto' }, { value: SmoSlur.positions.HEAD, label: 'Head' }, { value: SmoSlur.positions.TOP, label: 'Top' }], control: 'SuiDropdownComponent', label: 'End Position' }, { smoName: 'orientation', defaultValue: SmoSlur.orientations.AUTO, dataType: 'int', options: [{ value: SmoSlur.orientations.AUTO, label: 'Auto' }, { value: SmoSlur.orientations.UP, label: 'Up' }, { value: SmoSlur.orientations.DOWN, label: 'Down' }], control: 'SuiDropdownComponent', label: 'Orientation' },{ smoName: 'resetDefaults', control: 'SuiToggleComponent', label: 'Defaults' }, { smoName: 'resetAll', control: 'SuiToggleComponent', label: 'Reset All Slurs' }, { smoName: 'cp1x', defaultValue: 0, control: 'SuiRockerComponent', label: 'Control Point 1 X' }, { smoName: 'cp1y', defaultValue: 40, control: 'SuiRockerComponent', label: 'Control Point 1 Y' }, { smoName: 'cp2x', defaultValue: 0, control: 'SuiRockerComponent', label: 'Control Point 2 X' }, { smoName: 'cp2y', defaultValue: 40, control: 'SuiRockerComponent', label: 'Control Point 2 Y' }], staticText: [] }; disableClose() { $(this.dgDom.element).find('.ok-button').prop('disabled', true); $(this.dgDom.element).find('.cancel-button').prop('disabled', true); $(this.dgDom.element).find('.remove-button').prop('disabled', true); } enableClose() { $(this.dgDom.element).find('.ok-button').prop('disabled', false); $(this.dgDom.element).find('.cancel-button').prop('disabled', false); $(this.dgDom.element).find('.remove-button').prop('disabled', false); } modalPromise() { const self = this; return new Promise<void>((resolve) => { const checkComplete = () => { setTimeout(() => { if (self.adapter.updating === false) { resolve(); } else { checkComplete(); } }, 200); }; checkComplete(); }); } async changed() { await super.changed(); if (this.adapter.updating) { this.disableClose(); await this.modalPromise(); this.enableClose(); } } constructor(parameters: SuiDialogParams) { const adapter = new SuiSlurAdapter(parameters.view, parameters.modifier); super(SuiSlurAttributesDialog.dialogElements, { adapter, ...parameters }); this.displayOptions = ['BINDCOMPONENTS', 'DRAGGABLE', 'KEYBOARD_CAPTURE', 'MODIFIERPOS']; } }