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.
Files changed (42) hide show
  1. package/README.md +6 -3
  2. package/build/smoosic.js +89 -29
  3. package/changes.md +9 -1
  4. package/package.json +1 -1
  5. package/release/html/libmode.html +36 -0
  6. package/release/html/smoosic.html +4 -4
  7. package/release/smoosic.js +89 -29
  8. package/release/styles/dialogs.css +25 -18
  9. package/release/styles/general.css +16 -9
  10. package/release/styles/media.css +13 -5
  11. package/release/styles/ribbon.css +3 -0
  12. package/src/application/exports.ts +4 -4
  13. package/src/render/audio/musicCursor.ts +1 -1
  14. package/src/render/sui/NoteEntryCaret.ts +4 -1
  15. package/src/render/sui/formatter.ts +3 -3
  16. package/src/render/sui/mapper.ts +1 -1
  17. package/src/render/sui/scoreView.ts +4 -4
  18. package/src/render/sui/scoreViewOperations.ts +10 -10
  19. package/src/render/sui/textEdit.ts +3 -1
  20. package/src/render/vex/vxMeasure.ts +12 -6
  21. package/src/smo/data/measure.ts +37 -37
  22. package/src/smo/data/measureModifiers.ts +106 -71
  23. package/src/smo/data/note.ts +4 -1
  24. package/src/smo/data/score.ts +50 -11
  25. package/src/smo/data/systemStaff.ts +2 -2
  26. package/src/smo/midi/midiToSmo.ts +28 -29
  27. package/src/smo/midi/smoToMidi.ts +3 -3
  28. package/src/smo/mxml/smoToXml.ts +11 -11
  29. package/src/smo/mxml/xmlState.ts +3 -3
  30. package/src/smo/mxml/xmlToSmo.ts +9 -9
  31. package/src/smo/xform/copypaste.ts +3 -3
  32. package/src/smo/xform/operations.ts +9 -6
  33. package/src/smo/xform/tickDuration.ts +10 -2
  34. package/src/ui/buttons/display.ts +2 -2
  35. package/src/ui/buttons/ribbon.ts +2 -2
  36. package/src/ui/components/dialogs/timeSignature.vue +223 -0
  37. package/src/ui/dialogs/fileDialogs.ts +1 -1
  38. package/src/ui/dialogs/keySignature.ts +1 -1
  39. package/src/ui/dialogs/tempo.ts +38 -38
  40. package/src/ui/dialogs/timeSignature.ts +45 -116
  41. package/src/ui/menus/timeSignature.ts +2 -2
  42. 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 { SmoTempoText, SmoTempoNumberAttribute, SmoTempoStringAttribute, SmoTempoBooleanAttribute } from '../../smo/data/measureModifiers';
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';
@@ -1,6 +1,6 @@
1
1
  // [Smoosic](https://github.com/AaronDavidNewman/Smoosic)
2
2
  // Copyright (c) Aaron David Newman 2021.
3
- import { SmoTempoText, SmoTempoNumberAttribute, SmoTempoStringAttribute, SmoTempoBooleanAttribute } from '../../smo/data/measureModifiers';
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
- smoTempoText: SmoTempoText;
18
- backup: SmoTempoText;
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.smoTempoText = new SmoTempoText(measure.tempo);
27
- this.backup = new SmoTempoText(this.smoTempoText);
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.smoTempoText[param] = value;
31
- this.view.updateTempoScore(this.measure, this.smoTempoText, this.applyToAll, this.applyToSelection);
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.smoTempoText[param] = value;
36
- this.view.updateTempoScore(this.measure, this.smoTempoText, this.applyToAll, this.applyToSelection);
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.smoTempoText as any)[param] = value;
41
- this.view.updateTempoScore(this.measure, this.smoTempoText, this.applyToAll, this.applyToSelection);
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.smoTempoText, this.applyToAll, this.applyToSelection);
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.smoTempoText, this.applyToAll, this.applyToSelection);
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.smoTempoText.tempoText;
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.smoTempoText.tempoMode;
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.smoTempoText.customText;
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.smoTempoText.bpm;
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.smoTempoText.display;
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.smoTempoText.beatDuration;
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.smoTempoText.yOffset;
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: SmoTempoText.tempoModes.durationMode,
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: SmoTempoText.tempoTexts.allegro,
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: SmoTempoText.tempoTexts.larghissimo,
170
+ value: SmoTempo.tempoTexts.larghissimo,
171
171
  label: 'Larghissimo'
172
172
  }, {
173
- value: SmoTempoText.tempoTexts.grave,
173
+ value: SmoTempo.tempoTexts.grave,
174
174
  label: 'Grave'
175
175
  }, {
176
- value: SmoTempoText.tempoTexts.lento,
176
+ value: SmoTempo.tempoTexts.lento,
177
177
  label: 'Lento'
178
178
  }, {
179
- value: SmoTempoText.tempoTexts.largo,
179
+ value: SmoTempo.tempoTexts.largo,
180
180
  label: 'Largo'
181
181
  }, {
182
- value: SmoTempoText.tempoTexts.larghetto,
182
+ value: SmoTempo.tempoTexts.larghetto,
183
183
  label: 'Larghetto'
184
184
  }, {
185
- value: SmoTempoText.tempoTexts.adagio,
185
+ value: SmoTempo.tempoTexts.adagio,
186
186
  label: 'Adagio'
187
187
  }, {
188
- value: SmoTempoText.tempoTexts.adagietto,
188
+ value: SmoTempo.tempoTexts.adagietto,
189
189
  label: 'Adagietto'
190
190
  }, {
191
- value: SmoTempoText.tempoTexts.andante_moderato,
191
+ value: SmoTempo.tempoTexts.andante_moderato,
192
192
  label: 'Andante moderato'
193
193
  }, {
194
- value: SmoTempoText.tempoTexts.andante,
194
+ value: SmoTempo.tempoTexts.andante,
195
195
  label: 'Andante'
196
196
  }, {
197
- value: SmoTempoText.tempoTexts.andantino,
197
+ value: SmoTempo.tempoTexts.andantino,
198
198
  label: 'Andantino'
199
199
  }, {
200
- value: SmoTempoText.tempoTexts.moderator,
200
+ value: SmoTempo.tempoTexts.moderator,
201
201
  label: 'Moderato'
202
202
  }, {
203
- value: SmoTempoText.tempoTexts.allegretto,
203
+ value: SmoTempo.tempoTexts.allegretto,
204
204
  label: 'Allegretto',
205
205
  }, {
206
- value: SmoTempoText.tempoTexts.allegro,
206
+ value: SmoTempo.tempoTexts.allegro,
207
207
  label: 'Allegro'
208
208
  }, {
209
- value: SmoTempoText.tempoTexts.vivace,
209
+ value: SmoTempo.tempoTexts.vivace,
210
210
  label: 'Vivace'
211
211
  }, {
212
- value: SmoTempoText.tempoTexts.presto,
212
+ value: SmoTempo.tempoTexts.presto,
213
213
  label: 'Presto'
214
214
  }, {
215
- value: SmoTempoText.tempoTexts.prestissimo,
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 { TimeSignature } from '../../smo/data/measureModifiers';
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 { DialogDefinition, SuiDialogParams } from './dialog';
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
- * Time signature score mapping
14
- * @category SuiDialog
15
- */
16
- export class SuiTimeSignatureAdapter extends SuiComponentAdapter {
17
- measure: SmoMeasure;
18
- backup: TimeSignature;
19
- constructor(view: SuiScoreViewOperations) {
20
- super(view);
21
- this.measure = this.view.tracker.selections[0].measure;
22
- this.backup = new TimeSignature(this.measure.timeSignature);
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
- set useSymbol(value: boolean) {
46
- this.measure.timeSignature.useSymbol = value;
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
- get customString() {
49
- return this.measure.timeSignature.displayString;
38
+ const commitCb = async () => {
50
39
  }
51
- set customString(value: string) {
52
- const tr = value.trim();
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
- this.measure.timeSignature.displayString = tr;
65
- }
66
- async commit() {
67
- await this.view.setTimeSignature(this.measure.timeSignature);
68
- }
69
- async cancel() {
70
- this.measure.timeSignature = this.backup;
71
- return PromiseHelpers.emptyPromise();
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 { SuiTimeSignatureDialog } from '../dialogs/timeSignature';
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
- createAndDisplayDialog(SuiTimeSignatureDialog, {
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
- "SmoTempoText": {
814
+ "SmoTempo": {
815
815
  "type": "object",
816
816
  "required": [
817
817
  "ctor"
818
818
  ],
819
819
  "properties": {
820
820
  "ctor": {
821
- "const": "SmoTempoText"
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/SmoTempoText"
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/SmoTempoText"
1798
+ "$ref": "#/definitions/measureModifierSchema/SmoTempo"
1799
1799
  }
1800
1800
  }
1801
1801
  }