smoosic 1.0.36 → 1.0.38
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 +6 -3
- package/build/smoosic.js +89 -29
- package/changes.md +9 -1
- package/package.json +1 -1
- package/release/html/libmode.html +36 -0
- package/release/html/smoosic.html +4 -4
- package/release/smoosic.js +89 -29
- package/release/styles/dialogs.css +25 -18
- package/release/styles/general.css +16 -9
- package/release/styles/media.css +13 -5
- package/release/styles/ribbon.css +3 -0
- package/src/application/exports.ts +4 -4
- package/src/render/audio/musicCursor.ts +1 -1
- package/src/render/sui/NoteEntryCaret.ts +4 -1
- package/src/render/sui/formatter.ts +3 -3
- package/src/render/sui/mapper.ts +1 -1
- package/src/render/sui/scoreView.ts +4 -4
- package/src/render/sui/scoreViewOperations.ts +10 -10
- package/src/render/sui/textEdit.ts +3 -1
- package/src/render/vex/vxMeasure.ts +12 -6
- package/src/smo/data/measure.ts +37 -37
- package/src/smo/data/measureModifiers.ts +106 -71
- package/src/smo/data/note.ts +4 -1
- package/src/smo/data/score.ts +50 -11
- package/src/smo/data/systemStaff.ts +2 -2
- package/src/smo/midi/midiToSmo.ts +28 -29
- package/src/smo/midi/smoToMidi.ts +3 -3
- package/src/smo/mxml/smoToXml.ts +11 -11
- package/src/smo/mxml/xmlState.ts +3 -3
- package/src/smo/mxml/xmlToSmo.ts +9 -9
- package/src/smo/xform/copypaste.ts +3 -3
- package/src/smo/xform/operations.ts +9 -6
- package/src/smo/xform/tickDuration.ts +10 -2
- package/src/ui/buttons/display.ts +2 -2
- package/src/ui/buttons/ribbon.ts +2 -2
- package/src/ui/components/dialogs/timeSignature.vue +223 -0
- package/src/ui/dialogs/fileDialogs.ts +1 -1
- package/src/ui/dialogs/keySignature.ts +1 -1
- package/src/ui/dialogs/tempo.ts +38 -38
- package/src/ui/dialogs/timeSignature.ts +45 -116
- package/src/ui/menus/timeSignature.ts +2 -2
- package/tools/smoosic-schema.json +4 -4
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, Ref, watch, reactive } from 'vue';
|
|
3
|
+
import numberInputApp from './numberInput.vue';
|
|
4
|
+
import {
|
|
5
|
+
TimeSignatureTime, SmoTimeSignature
|
|
6
|
+
} from '../../../smo/data/measureModifiers';
|
|
7
|
+
import dialogContainer from './dialogContainer.vue';
|
|
8
|
+
import { SelectOption } from '../../common';
|
|
9
|
+
import selectComp from './select.vue';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
domId: string,
|
|
13
|
+
label: string,
|
|
14
|
+
timeSignature: SmoTimeSignature,
|
|
15
|
+
updateTimeSignatureCb: (mf: SmoTimeSignature) => Promise<void>,
|
|
16
|
+
updateApplyTo: (value: string) => Promise<void>,
|
|
17
|
+
commitCb: () => Promise<void>,
|
|
18
|
+
cancelCb: () => Promise<void>
|
|
19
|
+
}
|
|
20
|
+
const props = defineProps<Props>();
|
|
21
|
+
const durationSelection: SelectOption[] = [{
|
|
22
|
+
value: '2',
|
|
23
|
+
label: '2'
|
|
24
|
+
}, {
|
|
25
|
+
value: '4',
|
|
26
|
+
label: '4'
|
|
27
|
+
}, {
|
|
28
|
+
value: '8',
|
|
29
|
+
label: '8'
|
|
30
|
+
}];
|
|
31
|
+
|
|
32
|
+
const applyToOptions: SelectOption[] = [{
|
|
33
|
+
value: "Score",
|
|
34
|
+
label: 'Score'
|
|
35
|
+
}, {
|
|
36
|
+
value: "Selected",
|
|
37
|
+
label: 'Selected Measures'
|
|
38
|
+
}, {
|
|
39
|
+
value: "Remaining",
|
|
40
|
+
label: 'Remaining Measures'
|
|
41
|
+
}];
|
|
42
|
+
const applyTo: Ref<string> = ref('Selected');
|
|
43
|
+
const mainBeat = ref(4);
|
|
44
|
+
const mainDuration = ref(4);
|
|
45
|
+
const altDuration = ref(4);
|
|
46
|
+
const altDurationString = ref('4');
|
|
47
|
+
const mainDurationString = ref('4');
|
|
48
|
+
const altBeat = ref(0);
|
|
49
|
+
const isCompound = ref(false);
|
|
50
|
+
const durationFromString = (str: string): number => {
|
|
51
|
+
const val = parseInt(str);
|
|
52
|
+
if (str === '2' || str === '4' || str === '8') {
|
|
53
|
+
return val;
|
|
54
|
+
}
|
|
55
|
+
return 4;
|
|
56
|
+
}
|
|
57
|
+
watch(mainDuration, async (newVal) => {
|
|
58
|
+
if (mainDuration.value === storedTimeSignature.times[0].beatDuration) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
storedTimeSignature.times[0].beatDuration = newVal;
|
|
62
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
63
|
+
});
|
|
64
|
+
watch(altDuration, async (newVal) => {
|
|
65
|
+
if (storedTimeSignature.times.length === 1) {
|
|
66
|
+
storedTimeSignature.times.push({ actualBeats: altBeat.value, beatDuration: altDuration.value });
|
|
67
|
+
}
|
|
68
|
+
else if (newVal === storedTimeSignature.times[1].beatDuration) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
storedTimeSignature.times[1].beatDuration = newVal;
|
|
72
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
73
|
+
});
|
|
74
|
+
watch(altBeat, async (newVal) => {
|
|
75
|
+
if (storedTimeSignature.times.length === 1 && newVal > 0) {
|
|
76
|
+
storedTimeSignature.times.push({ actualBeats: newVal, beatDuration: storedTimeSignature.times[0].beatDuration });
|
|
77
|
+
}
|
|
78
|
+
else if (newVal < 1) {
|
|
79
|
+
if (storedTimeSignature.times.length > 1) {
|
|
80
|
+
storedTimeSignature.times.pop();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (storedTimeSignature.times.length > 1 && newVal === storedTimeSignature.times[1].actualBeats) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
storedTimeSignature.times[1].actualBeats = newVal;
|
|
87
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
88
|
+
});
|
|
89
|
+
watch(mainDurationString, (newVal) => {
|
|
90
|
+
mainDuration.value = durationFromString(newVal);
|
|
91
|
+
});
|
|
92
|
+
watch(altDurationString, (newVal) => {
|
|
93
|
+
altDuration.value = durationFromString(newVal);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const { domId, label, commitCb, cancelCb, } = { ...props };
|
|
97
|
+
const useSymbol: Ref<boolean> = ref(props.timeSignature.useSymbol);
|
|
98
|
+
const display: Ref<boolean> = ref(props.timeSignature.display);
|
|
99
|
+
const displayString: Ref<string> = ref(props.timeSignature.displayString);
|
|
100
|
+
const storedTimeSignature = new SmoTimeSignature(props.timeSignature);
|
|
101
|
+
if (storedTimeSignature.times.length > 1) {
|
|
102
|
+
isCompound.value = true;
|
|
103
|
+
altBeat.value = storedTimeSignature.times[1].actualBeats;
|
|
104
|
+
altDuration.value = storedTimeSignature.times[1].beatDuration;
|
|
105
|
+
}
|
|
106
|
+
mainBeat.value = storedTimeSignature.times[0].actualBeats;
|
|
107
|
+
mainDuration.value = storedTimeSignature.times[0].beatDuration;
|
|
108
|
+
const updateMainBeat = async (newVal: number) => {
|
|
109
|
+
mainBeat.value = newVal;
|
|
110
|
+
storedTimeSignature.times[0].actualBeats = newVal;
|
|
111
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
112
|
+
}
|
|
113
|
+
const updateMainDurationString = async (newVal: string) => {
|
|
114
|
+
mainDurationString.value = newVal;
|
|
115
|
+
storedTimeSignature.times[0].beatDuration = durationFromString(newVal);
|
|
116
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
117
|
+
}
|
|
118
|
+
const updateAltDurationString = async (newVal: string) => {
|
|
119
|
+
altDurationString.value = newVal;
|
|
120
|
+
storedTimeSignature.times[1].beatDuration = durationFromString(newVal);
|
|
121
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
122
|
+
}
|
|
123
|
+
const updateAltBeat = async (newVal: number) => {
|
|
124
|
+
if (storedTimeSignature.times.length > 1 && storedTimeSignature.times[1].actualBeats === newVal) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (newVal <= 1) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (storedTimeSignature.times.length === 1) {
|
|
131
|
+
storedTimeSignature.times.push({ actualBeats: newVal, beatDuration: storedTimeSignature.times[0].beatDuration });
|
|
132
|
+
} else {
|
|
133
|
+
storedTimeSignature.times[1].actualBeats = newVal;
|
|
134
|
+
}
|
|
135
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
136
|
+
}
|
|
137
|
+
watch(isCompound, async (newVal: boolean, oldVal: boolean) => {
|
|
138
|
+
if (newVal === oldVal) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (newVal) {
|
|
142
|
+
altBeat.value = 4;
|
|
143
|
+
} else {
|
|
144
|
+
altBeat.value = 0;
|
|
145
|
+
}
|
|
146
|
+
await props.updateTimeSignatureCb(storedTimeSignature);
|
|
147
|
+
});
|
|
148
|
+
const getId = (str: string) => {
|
|
149
|
+
return `${props.domId}-${str}`;
|
|
150
|
+
}
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<template>
|
|
154
|
+
<dialogContainer :domId="domId" :label="label" :cancelCb="cancelCb" :commitCb="commitCb"
|
|
155
|
+
:classes="'text-center mw-40 nw-40'">
|
|
156
|
+
<div class="row align-items-center">
|
|
157
|
+
<div class="checkbox-input-column-div">
|
|
158
|
+
<input class="form-check-input" type="checkbox" v-model="useSymbol" :id="getId('use-symbol')">
|
|
159
|
+
</input>
|
|
160
|
+
</div>
|
|
161
|
+
<div class="checkbox-input-label-div">
|
|
162
|
+
<span class="form-check-label" :for="getId('use-symbol')">Use Symbol</span>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="checkbox-input-column-div">
|
|
165
|
+
<input class="form-check-input" type="checkbox" v-model="display" :id="getId('display-ts')">
|
|
166
|
+
</input>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="checkbox-input-label-div">
|
|
169
|
+
<span class="form-check-label" :for="getId('display-cs')">Display Time Signature</span>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="row align-items-center">
|
|
173
|
+
<div class="checkbox-input-column-div">
|
|
174
|
+
<input class="form-check-input" type="checkbox" v-model="isCompound" :id="getId('is-compound')">
|
|
175
|
+
</input>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="checkbox-input-label-div">
|
|
178
|
+
<span class="form-check-label" :for="getId('system-break')">Compound Time</span>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
<div class="row align-items-center">
|
|
182
|
+
<div class="col col-4">
|
|
183
|
+
<numberInputApp :domId="getId('num-main')" :initialValue="mainBeat" :changeCb="updateMainBeat" :precision="0"
|
|
184
|
+
:width="25" :minValue="1" :maxValue="16" />
|
|
185
|
+
</div>
|
|
186
|
+
<div class="number-input-label-div col col-4">
|
|
187
|
+
<span class="form-check-label">Beats/Measure</span>
|
|
188
|
+
</div>
|
|
189
|
+
<div class="col col-6">
|
|
190
|
+
<selectComp :domId="getId('main-duration')" :label="'Beat Duration'" :selections="durationSelection"
|
|
191
|
+
:initialValue="mainDurationString" :changeCb="updateMainDurationString" />
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
<div class="row align-items-center" :class="{ hide: !isCompound }">
|
|
195
|
+
<div class="col col-4">
|
|
196
|
+
<numberInputApp :domId="getId('num-alt')" :initialValue="altBeat" :changeCb="updateAltBeat" :precision="0"
|
|
197
|
+
:width="25" :minValue="0" :maxValue="16" />
|
|
198
|
+
</div>
|
|
199
|
+
<div class="number-input-label-div col col-4">
|
|
200
|
+
<span class="form-check-label">Compound Beats/Measure</span>
|
|
201
|
+
</div>
|
|
202
|
+
<div class="col col-6">
|
|
203
|
+
<selectComp :domId="getId('alt-duration')" :label="'Beat Duration'" :selections="durationSelection"
|
|
204
|
+
:initialValue="altDurationString" :changeCb="updateAltDurationString" />
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
<div class="row align-items-center">
|
|
208
|
+
<div class="col col-4">
|
|
209
|
+
<input type="text" class="form-control form-control-sm" v-model="displayString" :id="getId('display-string')" />
|
|
210
|
+
</div>
|
|
211
|
+
<div class="number-input-label-div col col-8">
|
|
212
|
+
<span class="form-check-lable">Alternate Display String (for pickups)</span>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="row mb-2">
|
|
216
|
+
<div class="col col-3 text-end">Apply To</div>
|
|
217
|
+
<div class="col col-6">
|
|
218
|
+
<selectComp :domId="getId('page-size-select')" :label="''" :selections="applyToOptions" :initialValue="applyTo"
|
|
219
|
+
:changeCb="props.updateApplyTo" />
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</dialogContainer>
|
|
223
|
+
</template>
|
|
@@ -65,7 +65,7 @@ export const SuiFileUploadDialog = async (parameters: SuiDialogParams) => {
|
|
|
65
65
|
if (filename.endsWith('.mid') || filename.endsWith('.midi')) {
|
|
66
66
|
await commitMidi();
|
|
67
67
|
}
|
|
68
|
-
else if (filename.endsWith('.xml') || filename.endsWith('.mxml')) {
|
|
68
|
+
else if (filename.endsWith('.xml') || filename.endsWith('.mxml') || filename.endsWith('.mxl')) {
|
|
69
69
|
await commitXml();
|
|
70
70
|
}
|
|
71
71
|
else if (filename.endsWith('.json')) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// [Smoosic](https://github.com/AaronDavidNewman/Smoosic)
|
|
2
2
|
// Copyright (c) Aaron David Newman 2021.
|
|
3
|
-
import {
|
|
3
|
+
import { SmoTempo, SmoTempoNumberAttribute, SmoTempoStringAttribute, SmoTempoBooleanAttribute } from '../../smo/data/measureModifiers';
|
|
4
4
|
import { SmoSelection, SmoSelector } from '../../smo/xform/selections';
|
|
5
5
|
import { SuiScoreViewOperations } from '../../render/sui/scoreViewOperations';
|
|
6
6
|
import { DialogDefinition, SuiDialogParams } from './dialog';
|
package/src/ui/dialogs/tempo.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// [Smoosic](https://github.com/AaronDavidNewman/Smoosic)
|
|
2
2
|
// Copyright (c) Aaron David Newman 2021.
|
|
3
|
-
import {
|
|
3
|
+
import { SmoTempo, SmoTempoNumberAttribute, SmoTempoStringAttribute, SmoTempoBooleanAttribute } from '../../smo/data/measureModifiers';
|
|
4
4
|
import { SmoSelection } from '../../smo/xform/selections';
|
|
5
5
|
import { SuiScoreViewOperations } from '../../render/sui/scoreViewOperations';
|
|
6
6
|
import { DialogDefinition, SuiDialogParams } from './dialog';
|
|
@@ -14,8 +14,8 @@ declare var $: any;
|
|
|
14
14
|
* @category SuiDialog
|
|
15
15
|
*/
|
|
16
16
|
export class SuiTempoAdapter extends SuiComponentAdapter {
|
|
17
|
-
|
|
18
|
-
backup:
|
|
17
|
+
SmoTempo: SmoTempo;
|
|
18
|
+
backup: SmoTempo;
|
|
19
19
|
applyToAllVal: boolean = false;
|
|
20
20
|
applyToSelection: boolean = false;
|
|
21
21
|
edited: boolean = false;
|
|
@@ -23,26 +23,26 @@ export class SuiTempoAdapter extends SuiComponentAdapter {
|
|
|
23
23
|
constructor(view: SuiScoreViewOperations, measure: SmoMeasure) {
|
|
24
24
|
super(view);
|
|
25
25
|
this.measure = measure;
|
|
26
|
-
this.
|
|
27
|
-
this.backup = new
|
|
26
|
+
this.SmoTempo = new SmoTempo(measure.tempo);
|
|
27
|
+
this.backup = new SmoTempo(this.SmoTempo);
|
|
28
28
|
}
|
|
29
29
|
writeNumber(param: SmoTempoNumberAttribute, value: number) {
|
|
30
|
-
this.
|
|
31
|
-
this.view.updateTempoScore(this.measure, this.
|
|
30
|
+
this.SmoTempo[param] = value;
|
|
31
|
+
this.view.updateTempoScore(this.measure, this.SmoTempo, this.applyToAll, this.applyToSelection);
|
|
32
32
|
this.edited = true;
|
|
33
33
|
}
|
|
34
34
|
writeBoolean(param: SmoTempoBooleanAttribute, value: boolean) {
|
|
35
|
-
this.
|
|
36
|
-
this.view.updateTempoScore(this.measure, this.
|
|
35
|
+
this.SmoTempo[param] = value;
|
|
36
|
+
this.view.updateTempoScore(this.measure, this.SmoTempo, this.applyToAll, this.applyToSelection);
|
|
37
37
|
this.edited = true;
|
|
38
38
|
}
|
|
39
39
|
writeString(param: SmoTempoStringAttribute, value: string) {
|
|
40
|
-
(this.
|
|
41
|
-
this.view.updateTempoScore(this.measure, this.
|
|
40
|
+
(this.SmoTempo as any)[param] = value;
|
|
41
|
+
this.view.updateTempoScore(this.measure, this.SmoTempo, this.applyToAll, this.applyToSelection);
|
|
42
42
|
this.edited = true;
|
|
43
43
|
}
|
|
44
44
|
async remove() {
|
|
45
|
-
await this.view.removeTempo(this.measure, this.
|
|
45
|
+
await this.view.removeTempo(this.measure, this.SmoTempo, this.applyToAll, this.applyToSelection);
|
|
46
46
|
}
|
|
47
47
|
async cancel() {
|
|
48
48
|
await this.view.updateTempoScore(this.measure, this.backup, this.applyToAll, this.applyToSelection);
|
|
@@ -52,50 +52,50 @@ export class SuiTempoAdapter extends SuiComponentAdapter {
|
|
|
52
52
|
}
|
|
53
53
|
set applyToAll(val: boolean) {
|
|
54
54
|
this.applyToAllVal = val;
|
|
55
|
-
this.view.updateTempoScore(this.measure, this.
|
|
55
|
+
this.view.updateTempoScore(this.measure, this.SmoTempo, this.applyToAll, this.applyToSelection);
|
|
56
56
|
this.edited = true;
|
|
57
57
|
}
|
|
58
58
|
async commit(){
|
|
59
59
|
return PromiseHelpers.emptyPromise();
|
|
60
60
|
}
|
|
61
61
|
get tempoText() {
|
|
62
|
-
return this.
|
|
62
|
+
return this.SmoTempo.tempoText;
|
|
63
63
|
}
|
|
64
64
|
set tempoText(value: string) {
|
|
65
65
|
this.writeString('tempoText', value);
|
|
66
66
|
}
|
|
67
67
|
get tempoMode() {
|
|
68
|
-
return this.
|
|
68
|
+
return this.SmoTempo.tempoMode;
|
|
69
69
|
}
|
|
70
70
|
set tempoMode(value: string) {
|
|
71
71
|
this.writeString('tempoMode', value);
|
|
72
72
|
}
|
|
73
73
|
get customText() {
|
|
74
|
-
return this.
|
|
74
|
+
return this.SmoTempo.customText;
|
|
75
75
|
}
|
|
76
76
|
set customText(value: string) {
|
|
77
77
|
this.writeString('customText', value);
|
|
78
78
|
}
|
|
79
79
|
get bpm() {
|
|
80
|
-
return this.
|
|
80
|
+
return this.SmoTempo.bpm;
|
|
81
81
|
}
|
|
82
82
|
set bpm(value: number) {
|
|
83
83
|
this.writeNumber('bpm', value);
|
|
84
84
|
}
|
|
85
85
|
get display() {
|
|
86
|
-
return this.
|
|
86
|
+
return this.SmoTempo.display;
|
|
87
87
|
}
|
|
88
88
|
set display(value: boolean) {
|
|
89
89
|
this.writeBoolean('display', value);
|
|
90
90
|
}
|
|
91
91
|
get beatDuration() {
|
|
92
|
-
return this.
|
|
92
|
+
return this.SmoTempo.beatDuration;
|
|
93
93
|
}
|
|
94
94
|
set beatDuration(value: number) {
|
|
95
95
|
this.writeNumber('beatDuration', value);
|
|
96
96
|
}
|
|
97
97
|
get yOffset() {
|
|
98
|
-
return this.
|
|
98
|
+
return this.SmoTempo.yOffset;
|
|
99
99
|
}
|
|
100
100
|
set yOffset(value: number) {
|
|
101
101
|
this.writeNumber('yOffset', value);
|
|
@@ -111,7 +111,7 @@ export class SuiTempoDialog extends SuiDialogAdapterBase<SuiTempoAdapter> {
|
|
|
111
111
|
elements: [
|
|
112
112
|
{
|
|
113
113
|
smoName: 'tempoMode',
|
|
114
|
-
defaultValue:
|
|
114
|
+
defaultValue: SmoTempo.tempoModes.durationMode,
|
|
115
115
|
control: 'SuiDropdownComponent',
|
|
116
116
|
label: 'Tempo Mode',
|
|
117
117
|
options: [{
|
|
@@ -162,57 +162,57 @@ export class SuiTempoDialog extends SuiDialogAdapterBase<SuiTempoAdapter> {
|
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
164
|
smoName: 'tempoText',
|
|
165
|
-
defaultValue:
|
|
165
|
+
defaultValue: SmoTempo.tempoTexts.allegro,
|
|
166
166
|
control: 'SuiDropdownComponent',
|
|
167
167
|
label: 'Tempo Text',
|
|
168
168
|
classes: 'hide-when-not-text-mode',
|
|
169
169
|
options: [{
|
|
170
|
-
value:
|
|
170
|
+
value: SmoTempo.tempoTexts.larghissimo,
|
|
171
171
|
label: 'Larghissimo'
|
|
172
172
|
}, {
|
|
173
|
-
value:
|
|
173
|
+
value: SmoTempo.tempoTexts.grave,
|
|
174
174
|
label: 'Grave'
|
|
175
175
|
}, {
|
|
176
|
-
value:
|
|
176
|
+
value: SmoTempo.tempoTexts.lento,
|
|
177
177
|
label: 'Lento'
|
|
178
178
|
}, {
|
|
179
|
-
value:
|
|
179
|
+
value: SmoTempo.tempoTexts.largo,
|
|
180
180
|
label: 'Largo'
|
|
181
181
|
}, {
|
|
182
|
-
value:
|
|
182
|
+
value: SmoTempo.tempoTexts.larghetto,
|
|
183
183
|
label: 'Larghetto'
|
|
184
184
|
}, {
|
|
185
|
-
value:
|
|
185
|
+
value: SmoTempo.tempoTexts.adagio,
|
|
186
186
|
label: 'Adagio'
|
|
187
187
|
}, {
|
|
188
|
-
value:
|
|
188
|
+
value: SmoTempo.tempoTexts.adagietto,
|
|
189
189
|
label: 'Adagietto'
|
|
190
190
|
}, {
|
|
191
|
-
value:
|
|
191
|
+
value: SmoTempo.tempoTexts.andante_moderato,
|
|
192
192
|
label: 'Andante moderato'
|
|
193
193
|
}, {
|
|
194
|
-
value:
|
|
194
|
+
value: SmoTempo.tempoTexts.andante,
|
|
195
195
|
label: 'Andante'
|
|
196
196
|
}, {
|
|
197
|
-
value:
|
|
197
|
+
value: SmoTempo.tempoTexts.andantino,
|
|
198
198
|
label: 'Andantino'
|
|
199
199
|
}, {
|
|
200
|
-
value:
|
|
200
|
+
value: SmoTempo.tempoTexts.moderator,
|
|
201
201
|
label: 'Moderato'
|
|
202
202
|
}, {
|
|
203
|
-
value:
|
|
203
|
+
value: SmoTempo.tempoTexts.allegretto,
|
|
204
204
|
label: 'Allegretto',
|
|
205
205
|
}, {
|
|
206
|
-
value:
|
|
206
|
+
value: SmoTempo.tempoTexts.allegro,
|
|
207
207
|
label: 'Allegro'
|
|
208
208
|
}, {
|
|
209
|
-
value:
|
|
209
|
+
value: SmoTempo.tempoTexts.vivace,
|
|
210
210
|
label: 'Vivace'
|
|
211
211
|
}, {
|
|
212
|
-
value:
|
|
212
|
+
value: SmoTempo.tempoTexts.presto,
|
|
213
213
|
label: 'Presto'
|
|
214
214
|
}, {
|
|
215
|
-
value:
|
|
215
|
+
value: SmoTempo.tempoTexts.prestissimo,
|
|
216
216
|
label: 'Prestissimo'
|
|
217
217
|
}
|
|
218
218
|
]
|
|
@@ -1,129 +1,58 @@
|
|
|
1
1
|
// [Smoosic](https://github.com/AaronDavidNewman/Smoosic)
|
|
2
2
|
// Copyright (c) Aaron David Newman 2021.
|
|
3
3
|
import { SmoMeasure } from '../../smo/data/measure';
|
|
4
|
-
import {
|
|
4
|
+
import { SmoTimeSignature } from '../../smo/data/measureModifiers';
|
|
5
|
+
import { SmoSelection } from '../../smo/xform/selections';
|
|
6
|
+
import { SuiDialogParams, InstallDialog } from './dialog';
|
|
7
|
+
import timeSignatureComp from '../components/dialogs/timeSignature.vue';
|
|
5
8
|
import { SuiScoreViewOperations } from '../../render/sui/scoreViewOperations';
|
|
6
|
-
import {
|
|
9
|
+
import { replaceVueRoot, modalContainerId } from '../common';
|
|
7
10
|
import { SuiComponentAdapter, SuiDialogAdapterBase } from './adapter';
|
|
8
11
|
import { PromiseHelpers } from '../../common/promiseHelpers';
|
|
9
|
-
|
|
10
12
|
declare var $: any;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
measure
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
get numerator() {
|
|
25
|
-
return this.measure.timeSignature.actualBeats;
|
|
26
|
-
}
|
|
27
|
-
set numerator(value: number) {
|
|
28
|
-
this.measure.timeSignature.actualBeats = value;
|
|
29
|
-
}
|
|
30
|
-
get denominator() {
|
|
31
|
-
return this.measure.timeSignature.beatDuration;
|
|
32
|
-
}
|
|
33
|
-
set denominator(value: number) {
|
|
34
|
-
this.measure.timeSignature.beatDuration = value;
|
|
35
|
-
}
|
|
36
|
-
get display() {
|
|
37
|
-
return this.measure.timeSignature.display;
|
|
38
|
-
}
|
|
39
|
-
set display(value: boolean) {
|
|
40
|
-
this.measure.timeSignature.display = value;
|
|
41
|
-
}
|
|
42
|
-
get useSymbol() {
|
|
43
|
-
return this.measure.timeSignature.useSymbol;
|
|
13
|
+
declare var $: any;
|
|
14
|
+
export const SuiTimeSignatureDialogVue = (parameters: SuiDialogParams) => {
|
|
15
|
+
const rootId = replaceVueRoot(modalContainerId);
|
|
16
|
+
const measure = parameters.view.tracker.selections[0].measure;
|
|
17
|
+
const backup = new SmoTimeSignature(measure.timeSignature);
|
|
18
|
+
let changed = false;
|
|
19
|
+
let timeSignature = new SmoTimeSignature(measure.timeSignature);
|
|
20
|
+
const updateTimeSignatureCb = async (mf: SmoTimeSignature):Promise<void> => {
|
|
21
|
+
if (!SmoTimeSignature.equal(mf, timeSignature)) {
|
|
22
|
+
changed = true;
|
|
23
|
+
await parameters.view.setTimeSignature(mf);
|
|
24
|
+
timeSignature = mf;
|
|
25
|
+
}
|
|
44
26
|
}
|
|
45
|
-
|
|
46
|
-
|
|
27
|
+
let applies = 'Selected';
|
|
28
|
+
const updateApplyTo = async (value: string) => {
|
|
29
|
+
applies = value;
|
|
30
|
+
if (value === 'Score') {
|
|
31
|
+
parameters.view.tracker.selections = SmoSelection.selectionsToEnd(parameters.view.score, parameters.view.tracker.selections[0].selector.staff, 0);
|
|
32
|
+
} else if (applies === 'Remaining') {
|
|
33
|
+
parameters.view.tracker.selections = SmoSelection.selectionsToEnd(parameters.view.score, parameters.view.tracker.selections[0].selector.staff, parameters.view.tracker.selections[0].selector.measure);
|
|
34
|
+
} else {
|
|
35
|
+
parameters.view.tracker.selections = parameters.view.tracker.selections;
|
|
36
|
+
}
|
|
47
37
|
}
|
|
48
|
-
|
|
49
|
-
return this.measure.timeSignature.displayString;
|
|
38
|
+
const commitCb = async () => {
|
|
50
39
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!(tr.indexOf('/') >= 0)) {
|
|
54
|
-
if (tr === 'C' || tr === 'C|') {
|
|
55
|
-
this.measure.timeSignature.displayString = tr;
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const ar = tr.split('/');
|
|
60
|
-
if (isNaN(parseInt(ar[0], 10)) || isNaN(parseInt(ar[1], 10))) {
|
|
61
|
-
this.measure.timeSignature.displayString = '';
|
|
40
|
+
const cancelCb = async () => {
|
|
41
|
+
if (!changed) {
|
|
62
42
|
return;
|
|
63
43
|
}
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
44
|
+
await parameters.view.setTimeSignature(backup);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const appParams = { domId: rootId, timeSignature, label: "Staff Groups",
|
|
48
|
+
updateTimeSignatureCb, updateApplyTo };
|
|
49
|
+
|
|
50
|
+
InstallDialog({
|
|
51
|
+
root: rootId,
|
|
52
|
+
app: timeSignatureComp,
|
|
53
|
+
appParams,
|
|
54
|
+
dialogParams: parameters,
|
|
55
|
+
commitCb,
|
|
56
|
+
cancelCb
|
|
57
|
+
});
|
|
73
58
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Time signature score mapping
|
|
76
|
-
* @category SuiDialog
|
|
77
|
-
*/
|
|
78
|
-
export class SuiTimeSignatureDialog extends SuiDialogAdapterBase<SuiTimeSignatureAdapter> {
|
|
79
|
-
static dialogElements: DialogDefinition =
|
|
80
|
-
{
|
|
81
|
-
label: 'Custom Time Signature',
|
|
82
|
-
elements:
|
|
83
|
-
[
|
|
84
|
-
{
|
|
85
|
-
smoName: 'numerator',
|
|
86
|
-
defaultValue: 3,
|
|
87
|
-
control: 'SuiRockerComponent',
|
|
88
|
-
label: 'Beats/Measure',
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
smoName: 'denominator',
|
|
92
|
-
defaultValue: 8,
|
|
93
|
-
dataType: 'int',
|
|
94
|
-
control: 'SuiDropdownComponent',
|
|
95
|
-
label: 'Beat Value',
|
|
96
|
-
options: [{
|
|
97
|
-
value: 16,
|
|
98
|
-
label: '16',
|
|
99
|
-
}, {
|
|
100
|
-
value: 8,
|
|
101
|
-
label: '8',
|
|
102
|
-
}, {
|
|
103
|
-
value: 4,
|
|
104
|
-
label: '4'
|
|
105
|
-
}, {
|
|
106
|
-
value: 2,
|
|
107
|
-
label: '2'
|
|
108
|
-
}]
|
|
109
|
-
}, {
|
|
110
|
-
smoName: 'display',
|
|
111
|
-
control: 'SuiToggleComponent',
|
|
112
|
-
label: 'Display',
|
|
113
|
-
}, {
|
|
114
|
-
smoName: 'useSymbol',
|
|
115
|
-
control: 'SuiToggleComponent',
|
|
116
|
-
label: 'Common/Cut',
|
|
117
|
-
}, {
|
|
118
|
-
smoName: 'customString',
|
|
119
|
-
control: 'SuiTextInputComponent',
|
|
120
|
-
label: 'Custom',
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
staticText: []
|
|
124
|
-
};
|
|
125
|
-
constructor(parameters: SuiDialogParams) {
|
|
126
|
-
const adapter = new SuiTimeSignatureAdapter(parameters.view);
|
|
127
|
-
super(SuiTimeSignatureDialog.dialogElements, { adapter, ...parameters });
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { SuiMenuBase, SuiMenuParams, MenuDefinition } from './menu';
|
|
4
4
|
import { SmoMeasure } from '../../smo/data/measure';
|
|
5
5
|
import { createAndDisplayDialog } from '../dialogs/dialog';
|
|
6
|
-
import {
|
|
6
|
+
import { SuiTimeSignatureDialogVue } from '../dialogs/timeSignature';
|
|
7
7
|
|
|
8
8
|
declare var $: any;
|
|
9
9
|
|
|
@@ -62,7 +62,7 @@ export class SuiTimeSignatureMenu extends SuiMenuBase {
|
|
|
62
62
|
async selection(ev: any) {
|
|
63
63
|
var text = $(ev.currentTarget).attr('data-value');
|
|
64
64
|
if (text === 'TimeSigOther') {
|
|
65
|
-
|
|
65
|
+
SuiTimeSignatureDialogVue({
|
|
66
66
|
completeNotifier: this.completeNotifier!,
|
|
67
67
|
view: this.view,
|
|
68
68
|
eventSource: this.eventSource,
|
|
@@ -811,14 +811,14 @@
|
|
|
811
811
|
"custom"
|
|
812
812
|
]
|
|
813
813
|
},
|
|
814
|
-
"
|
|
814
|
+
"SmoTempo": {
|
|
815
815
|
"type": "object",
|
|
816
816
|
"required": [
|
|
817
817
|
"ctor"
|
|
818
818
|
],
|
|
819
819
|
"properties": {
|
|
820
820
|
"ctor": {
|
|
821
|
-
"const": "
|
|
821
|
+
"const": "SmoTempo"
|
|
822
822
|
},
|
|
823
823
|
"tempoMode": {
|
|
824
824
|
"type": "string",
|
|
@@ -988,7 +988,7 @@
|
|
|
988
988
|
"default": "treble"
|
|
989
989
|
},
|
|
990
990
|
"tempo": {
|
|
991
|
-
"$ref": "#/definitions/measureModifierSchema/
|
|
991
|
+
"$ref": "#/definitions/measureModifierSchema/SmoTempo"
|
|
992
992
|
},
|
|
993
993
|
"format": {
|
|
994
994
|
"$ref": "#/definitions/measureModifierSchema/TimeSignature"
|
|
@@ -1795,7 +1795,7 @@
|
|
|
1795
1795
|
"tempo": {
|
|
1796
1796
|
"type": "object",
|
|
1797
1797
|
"additionaProperties": {
|
|
1798
|
-
"$ref": "#/definitions/measureModifierSchema/
|
|
1798
|
+
"$ref": "#/definitions/measureModifierSchema/SmoTempo"
|
|
1799
1799
|
}
|
|
1800
1800
|
}
|
|
1801
1801
|
}
|