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
|
@@ -250,7 +250,7 @@ body .vueDialogContainer>div {
|
|
|
250
250
|
body.showVueDialog .vueDialogContainer,
|
|
251
251
|
body.showVueDialog .modal{
|
|
252
252
|
position:absolute;
|
|
253
|
-
display:block;
|
|
253
|
+
/* display:block; */
|
|
254
254
|
z-index:3;
|
|
255
255
|
}
|
|
256
256
|
.draggable-button {
|
|
@@ -495,14 +495,29 @@ button.nav-link {
|
|
|
495
495
|
margin:10px;
|
|
496
496
|
}
|
|
497
497
|
|
|
498
|
+
.helpDialog .button-left,
|
|
498
499
|
.attributeModal .buttonContainer .button-left {
|
|
499
500
|
margin-right:5px;
|
|
500
501
|
}
|
|
502
|
+
.helpDialog .button-left {
|
|
503
|
+
padding-left: 10px;
|
|
504
|
+
}
|
|
505
|
+
.helpDialog .button-right {
|
|
506
|
+
padding-right: 10px;
|
|
507
|
+
}
|
|
508
|
+
.prev-topic-text {
|
|
509
|
+
margin-left: 5px;
|
|
510
|
+
}
|
|
511
|
+
.next-topic-text {
|
|
512
|
+
margin-right: 5px;
|
|
513
|
+
}
|
|
514
|
+
.helpDialog .button-center,
|
|
501
515
|
.attributeModal .buttonContainer .button-center {
|
|
502
516
|
margin-right:5px;
|
|
503
517
|
margin-left:5px;
|
|
504
518
|
}
|
|
505
519
|
|
|
520
|
+
.helpDialog .button-right,
|
|
506
521
|
.attributeModal .buttonContainer .button-right {
|
|
507
522
|
margin-left:5px;
|
|
508
523
|
}
|
|
@@ -900,7 +915,7 @@ body.bugReport .bug-modal {
|
|
|
900
915
|
display: flex;
|
|
901
916
|
}
|
|
902
917
|
|
|
903
|
-
.
|
|
918
|
+
.modal.show {
|
|
904
919
|
display: block;
|
|
905
920
|
}
|
|
906
921
|
.bug-title {
|
|
@@ -923,17 +938,15 @@ body.splashScreen .bugDialog {
|
|
|
923
938
|
|
|
924
939
|
}
|
|
925
940
|
|
|
926
|
-
|
|
927
|
-
display:none;
|
|
928
|
-
}
|
|
941
|
+
|
|
929
942
|
/* change did not get propogated */
|
|
930
|
-
|
|
943
|
+
#help-dialog-container .helpDialog {
|
|
931
944
|
display:flex;
|
|
932
945
|
overflow: hidden;
|
|
933
946
|
background: #eef;
|
|
934
947
|
flex: 1 0 100%;
|
|
935
948
|
flex-flow:column wrap;
|
|
936
|
-
overflow:auto;
|
|
949
|
+
overflow-y:auto;
|
|
937
950
|
margin: 8px;
|
|
938
951
|
padding: 10px;
|
|
939
952
|
position: absolute;
|
|
@@ -984,7 +997,7 @@ body.showHelpDialog .helpDialog {
|
|
|
984
997
|
position: absolute;
|
|
985
998
|
left: 2px;
|
|
986
999
|
}
|
|
987
|
-
|
|
1000
|
+
.helpDialog button.close {
|
|
988
1001
|
position: absolute;
|
|
989
1002
|
right: 5px;
|
|
990
1003
|
color: red;
|
|
@@ -1161,7 +1174,7 @@ button.translate-submit-button {
|
|
|
1161
1174
|
border-radius: 4px;
|
|
1162
1175
|
}
|
|
1163
1176
|
|
|
1164
|
-
#
|
|
1177
|
+
#render-progress {
|
|
1165
1178
|
display: none;
|
|
1166
1179
|
width:200px;
|
|
1167
1180
|
height:25px;
|
|
@@ -1175,20 +1188,14 @@ button.translate-submit-button {
|
|
|
1175
1188
|
font-family: Arial, Helvetica, sans-serif;
|
|
1176
1189
|
font-size: 0.8em;
|
|
1177
1190
|
}
|
|
1178
|
-
#
|
|
1179
|
-
margin: -25px 0 0 100px;
|
|
1180
|
-
padding:0;
|
|
1181
|
-
display:inline-block;
|
|
1182
|
-
content: attr(value) '%';
|
|
1183
|
-
}
|
|
1184
|
-
#renderProgress[value]::-webkit-progress-bar {
|
|
1191
|
+
#render-progress[value]::-webkit-progress-bar {
|
|
1185
1192
|
background-color:#eee;
|
|
1186
1193
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
|
|
1187
1194
|
}
|
|
1188
1195
|
|
|
1189
|
-
#
|
|
1196
|
+
#render-progress[value]::-webkit-progress-value {
|
|
1190
1197
|
background: #F70;
|
|
1191
1198
|
}
|
|
1192
|
-
body.
|
|
1199
|
+
body.progress-modal #render-progress {
|
|
1193
1200
|
display: block;
|
|
1194
1201
|
}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
.
|
|
2
|
-
cursor: default;
|
|
3
|
-
pointer-events: none;
|
|
1
|
+
.musicContainer {
|
|
4
2
|
user-select: none;
|
|
5
3
|
-webkit-user-select: none;
|
|
6
4
|
-moz-user-select: none;
|
|
7
5
|
-ms-user-select: none;
|
|
8
6
|
}
|
|
9
7
|
|
|
10
|
-
.
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
8
|
+
.pitch-preview {
|
|
9
|
+
cursor: default;
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
/*user-select: none;*/
|
|
12
|
+
/*-webkit-user-select: none;*/
|
|
13
|
+
/*-moz-user-select: none;*/
|
|
14
|
+
/*-ms-user-select: none;*/
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*.note-entry-caret {*/
|
|
18
|
+
/* user-select: none;*/
|
|
19
|
+
/* -webkit-user-select: none;*/
|
|
20
|
+
/* -moz-user-select: none;*/
|
|
21
|
+
/* -ms-user-select: none;*/
|
|
22
|
+
/*}*/
|
package/release/styles/media.css
CHANGED
|
@@ -131,7 +131,7 @@ body {
|
|
|
131
131
|
}
|
|
132
132
|
/* override bootstrap */
|
|
133
133
|
body.modal {
|
|
134
|
-
display: block;
|
|
134
|
+
display: block;
|
|
135
135
|
}
|
|
136
136
|
li.nav-item button.nav-link {
|
|
137
137
|
text-align: left;
|
|
@@ -167,7 +167,7 @@ h1 {
|
|
|
167
167
|
.testTitle {
|
|
168
168
|
height: 20px;
|
|
169
169
|
font-size:1.2em;
|
|
170
|
-
|
|
170
|
+
margin:0;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
#birdy {
|
|
@@ -319,6 +319,15 @@ body.printing .printFrame {
|
|
|
319
319
|
flex-flow:column nowrap;
|
|
320
320
|
flex: 1 1 auto;
|
|
321
321
|
}
|
|
322
|
+
.musicRelief .score-container div {
|
|
323
|
+
background-color: #fff;
|
|
324
|
+
}
|
|
325
|
+
.horizontal.musicRelief {
|
|
326
|
+
flex-flow:row nowrap;
|
|
327
|
+
}
|
|
328
|
+
.horizontal.musicRelief .score-container {
|
|
329
|
+
display: flex;
|
|
330
|
+
}
|
|
322
331
|
.workspace {
|
|
323
332
|
padding-top: 2px;
|
|
324
333
|
position:relative;
|
|
@@ -330,7 +339,6 @@ body.printing .printFrame {
|
|
|
330
339
|
|
|
331
340
|
.musicRelief {
|
|
332
341
|
background:#99a;
|
|
333
|
-
|
|
334
342
|
}
|
|
335
343
|
.media {
|
|
336
344
|
display:flex;
|
|
@@ -344,8 +352,8 @@ body.printing .printFrame {
|
|
|
344
352
|
display:none;
|
|
345
353
|
}
|
|
346
354
|
|
|
347
|
-
.
|
|
348
|
-
|
|
355
|
+
.score-container {
|
|
356
|
+
position: relative;
|
|
349
357
|
background:#fff;
|
|
350
358
|
}
|
|
351
359
|
.overlay {
|
|
@@ -192,6 +192,9 @@ body.alt-key button.hover-text .ribbon-button-hotkey {
|
|
|
192
192
|
.hide {
|
|
193
193
|
display: none !important;
|
|
194
194
|
}
|
|
195
|
+
.invisible {
|
|
196
|
+
visibility: hidden !important;
|
|
197
|
+
}
|
|
195
198
|
.controls-top button.duration.expanded.tuplet span.ribbon-button-hotkey {
|
|
196
199
|
font-size:1em;
|
|
197
200
|
padding-left: 7px;
|
|
@@ -37,7 +37,7 @@ import { SuiTransposeScoreDialogVue} from '../ui/dialogs/transposeScore';
|
|
|
37
37
|
import { SuiMeasureFormatDialogVue } from '../ui/dialogs/measureFormat';
|
|
38
38
|
import { SuiInsertMeasuresVue } from '../ui/dialogs/addMeasure';
|
|
39
39
|
import { SuiInstrumentDialogVue } from '../ui/dialogs/instrument';
|
|
40
|
-
import {
|
|
40
|
+
import { SuiTimeSignatureDialogVue } from '../ui/dialogs/timeSignature';
|
|
41
41
|
import { SuiTempoDialog } from '../ui/dialogs/tempo';
|
|
42
42
|
import { SuiNoteHeadDialog } from '../ui/dialogs/noteHead';
|
|
43
43
|
import { SuiEndingsDialogVue } from '../ui/dialogs/endings';
|
|
@@ -153,7 +153,7 @@ import { SmoOperation } from '../smo/xform/operations';
|
|
|
153
153
|
import { ScoreRoadMapBuilder } from '../smo/xform/roadmap';
|
|
154
154
|
import {
|
|
155
155
|
SmoRehearsalMark, SmoMeasureFormat, SmoBarline, SmoRepeatSymbol,
|
|
156
|
-
SmoVolta, SmoMeasureText,
|
|
156
|
+
SmoVolta, SmoMeasureText, SmoTempo, SmoTimeSignature, measureModifierDynamicCtorInit
|
|
157
157
|
} from '../smo/data/measureModifiers';
|
|
158
158
|
import { SmoToXml } from '../smo/mxml/smoToXml';
|
|
159
159
|
import { MidiToSmo } from '../smo/midi/midiToSmo';
|
|
@@ -357,7 +357,7 @@ export const Smo = {
|
|
|
357
357
|
GlobalLayoutNumberAttributesArray,
|
|
358
358
|
SuiTransposeScoreDialogVue,
|
|
359
359
|
SuiScoreFontDialogVue, SuiPageLayoutDialogVue, SuiMeasureFormatDialogVue, SuiInsertMeasuresVue,
|
|
360
|
-
|
|
360
|
+
SuiTimeSignatureDialogVue,SuiTextBlockDialog, SuiLyricDialog, SuiChordChangeDialog,
|
|
361
361
|
SuiSlurAttributesDialog, SuiPedalMarkingDialog, SuiTieAttributesDialog, SuiVoltaAttributeDialog,
|
|
362
362
|
SuiHairpinAttributesDialog, SuiStaffGroupDialogVue,
|
|
363
363
|
SuiScorePreferencesDialogVue,
|
|
@@ -400,7 +400,7 @@ SuiPitchComposite,
|
|
|
400
400
|
// score modifiers
|
|
401
401
|
SmoSystemGroup, SmoAudioPlayerSettings, SmoTextGroup,
|
|
402
402
|
// measure modifiers
|
|
403
|
-
SmoRehearsalMark, SmoMeasureFormat, SmoBarline, SmoRepeatSymbol, SmoVolta, SmoMeasureText,
|
|
403
|
+
SmoRehearsalMark, SmoMeasureFormat, SmoBarline, SmoRepeatSymbol, SmoVolta, SmoMeasureText, SmoTempo, SmoTimeSignature,
|
|
404
404
|
measureModifierDynamicCtorInit,
|
|
405
405
|
// note modifiers
|
|
406
406
|
SmoOrnament, noteModifierDynamicCtorInit,
|
|
@@ -72,7 +72,7 @@ export const defaultClearAudioAnimationHandler = (delay: number) => {
|
|
|
72
72
|
}
|
|
73
73
|
const screenBox = SvgHelpers.boxPoints(x, y, width, height);
|
|
74
74
|
const fillParams: Record<string, string> = {};
|
|
75
|
-
console.log(`topbox xy ${measure.svg.logicalBox.x}, ${measure.svg.logicalBox.y} x ${x}, ${y}`);
|
|
75
|
+
// console.log(`topbox xy ${measure.svg.logicalBox.x}, ${measure.svg.logicalBox.y} x ${x}, ${y}`);
|
|
76
76
|
fillParams['fill-opacity'] = '0.5';
|
|
77
77
|
fillParams['fill'] = '#4444ff';
|
|
78
78
|
const ctx = context.getContext();
|
|
@@ -203,7 +203,10 @@ export class NoteEntryCaret {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
const staveNote = vexNote as StaveNote;
|
|
206
|
-
|
|
206
|
+
if (!staveNote.noteHeads) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const noteHeads = staveNote.noteHeads;
|
|
207
210
|
|
|
208
211
|
this.vexNoteLeftDisplacedHeadPx = staveNote.getMetrics().leftDisplacedHeadPx;
|
|
209
212
|
this.vexNoteRightDisplacedHeadPx = staveNote.getMetrics().rightDisplacedHeadPx;
|
|
@@ -16,7 +16,7 @@ import { SmoStaffHairpin, SmoStaffTextBracket, SmoTabStave } from '../../smo/dat
|
|
|
16
16
|
import { layoutDebug } from './layoutDebug';
|
|
17
17
|
import { ScaledPageLayout, SmoLayoutManager, SmoPageLayout } from '../../smo/data/scoreModifiers';
|
|
18
18
|
import { SmoMeasure, ISmoBeamGroup } from '../../smo/data/measure';
|
|
19
|
-
import {
|
|
19
|
+
import { SmoTimeSignature, SmoTempo } from '../../smo/data//measureModifiers';
|
|
20
20
|
import { SvgPageMap } from './svgPageMap';
|
|
21
21
|
import { VexFlow, defaultMeasurePadding } from '../../common/vex';
|
|
22
22
|
import { TextFormatter } from '../../common/textformatter';
|
|
@@ -831,7 +831,7 @@ export class SuiLayoutFormatter {
|
|
|
831
831
|
* @param score
|
|
832
832
|
*/
|
|
833
833
|
calculateBeginningSymbols(systemIndex: number, measure: SmoMeasure,
|
|
834
|
-
clefLast: string, keySigLast: string, timeSigLast:
|
|
834
|
+
clefLast: string, keySigLast: string, timeSigLast: SmoTimeSignature, tempoLast: SmoTempo) {
|
|
835
835
|
// The key signature is set based on the transpose index already, i.e. an Eb part in concert C already has 3 sharps.
|
|
836
836
|
const xposeScore = this.score?.preferences?.transposingScore && (this.score?.isPartExposed() === false);
|
|
837
837
|
// const xposeOffset = xposeScore ? measure.transposeIndex : 0;
|
|
@@ -850,7 +850,7 @@ export class SuiLayoutFormatter {
|
|
|
850
850
|
measure.svg.forceTempo = tempo.display && measure.svg.rowInSystem === 0;
|
|
851
851
|
} else if (tempo && tempoLast) {
|
|
852
852
|
// otherwise get tempo from the measure prior. But only one tempo per system.
|
|
853
|
-
if (!
|
|
853
|
+
if (!SmoTempo.eq(tempo, tempoLast) && measure.svg.rowInSystem === 0) {
|
|
854
854
|
measure.svg.forceTempo = tempo.display;
|
|
855
855
|
}
|
|
856
856
|
} else if (tempo) {
|
package/src/render/sui/mapper.ts
CHANGED
|
@@ -159,7 +159,7 @@ export abstract class SuiMapper {
|
|
|
159
159
|
this.localModifiers.push({ index, selection: sel, modifier: volta, box: volta.logicalBox ?? SvgBox.default });
|
|
160
160
|
index += 1;
|
|
161
161
|
});
|
|
162
|
-
sel.measure.getModifiersByType('
|
|
162
|
+
sel.measure.getModifiersByType('SmoTempo').forEach((tempo) => {
|
|
163
163
|
this.localModifiers.push({ index, selection: sel, modifier: tempo, box: tempo.logicalBox ?? SvgBox.default });
|
|
164
164
|
index += 1;
|
|
165
165
|
});
|
|
@@ -23,8 +23,8 @@ import { ScoreRenderParams } from './scoreRender';
|
|
|
23
23
|
import { SmoOperation } from '../../smo/xform/operations';
|
|
24
24
|
import { SuiAudioPlayer } from '../audio/player';
|
|
25
25
|
import { SuiAudioAnimationParams } from '../audio/musicCursor';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
26
|
+
import { SmoTempo } from '../../smo/data/measureModifiers';
|
|
27
|
+
import { SmoTimeSignature } from '../../smo/data/measureModifiers';
|
|
28
28
|
import { ref, Ref } from 'vue';
|
|
29
29
|
import { SvgBox, SvgPoint } from '../../smo/data/common';
|
|
30
30
|
import { layoutDebug } from './layoutDebug';
|
|
@@ -685,8 +685,8 @@ export abstract class SuiScoreView implements layoutProvider {
|
|
|
685
685
|
}
|
|
686
686
|
nStave.measures.forEach((measure: SmoMeasure, ix) => {
|
|
687
687
|
const srcMeasure = srcStave.measures[ix];
|
|
688
|
-
measure.tempo = new
|
|
689
|
-
measure.timeSignature = new
|
|
688
|
+
measure.tempo = new SmoTempo(srcMeasure.tempo.serialize());
|
|
689
|
+
measure.timeSignature = new SmoTimeSignature(srcMeasure.timeSignature);
|
|
690
690
|
measure.keySignature = srcMeasure.keySignature;
|
|
691
691
|
});
|
|
692
692
|
staffMap.push(i);
|
|
@@ -14,8 +14,8 @@ import { SmoTextGroup } from '../../smo/data/scoreText';
|
|
|
14
14
|
import { SmoDynamicText, SmoNoteModifierBase, SmoGraceNote, SmoArticulation,
|
|
15
15
|
SmoOrnament, SmoLyric, SmoMicrotone, SmoArpeggio, SmoArpeggioType, SmoClefChange,
|
|
16
16
|
SmoTabNote} from '../../smo/data/noteModifiers';
|
|
17
|
-
import {
|
|
18
|
-
SmoRehearsalMark, SmoMeasureFormat,
|
|
17
|
+
import { SmoTempo, SmoVolta, SmoBarline, SmoRepeatSymbol,
|
|
18
|
+
SmoRehearsalMark, SmoMeasureFormat, SmoTimeSignature } from '../../smo/data/measureModifiers';
|
|
19
19
|
import { UndoBuffer } from '../../smo/xform/undo';
|
|
20
20
|
import {
|
|
21
21
|
SmoOperation, createStaffModifierType, MakeTupletOperation
|
|
@@ -525,7 +525,7 @@ export class SuiScoreViewOperations extends SuiScoreView {
|
|
|
525
525
|
* Set the time signature for a selection
|
|
526
526
|
* @param timeSignature actual time signature
|
|
527
527
|
*/
|
|
528
|
-
async setTimeSignature(timeSignature:
|
|
528
|
+
async setTimeSignature(timeSignature: SmoTimeSignature): Promise<void> {
|
|
529
529
|
this._undoScore('Set time signature');
|
|
530
530
|
const selections = this.tracker.selections;
|
|
531
531
|
const altSelections = this._getEquivalentSelections(selections);
|
|
@@ -627,9 +627,9 @@ export class SuiScoreViewOperations extends SuiScoreView {
|
|
|
627
627
|
* @param scoreMode if true, update whole score. Else selections
|
|
628
628
|
* @returns
|
|
629
629
|
*/
|
|
630
|
-
async updateTempoScore(measure: SmoMeasure, tempo:
|
|
630
|
+
async updateTempoScore(measure: SmoMeasure, tempo: SmoTempo, scoreMode: boolean, selectionMode: boolean): Promise<void> {
|
|
631
631
|
let measureIndex = 0;
|
|
632
|
-
const originalTempo = new
|
|
632
|
+
const originalTempo = new SmoTempo(measure.tempo);
|
|
633
633
|
this._undoColumn('update tempo', measure.measureNumber.measureIndex);
|
|
634
634
|
let startMeasure = measure.measureNumber.measureIndex;
|
|
635
635
|
let endMeasure = this.score.staves[0].measures.length;
|
|
@@ -641,14 +641,14 @@ export class SuiScoreViewOperations extends SuiScoreView {
|
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
643
|
// If we are only changing the position of the text, it only affects the tempo measure.
|
|
644
|
-
if (
|
|
644
|
+
if (SmoTempo.eq(originalTempo, tempo) && tempo.yOffset !== originalTempo.yOffset && endMeasure > startMeasure) {
|
|
645
645
|
endMeasure = startMeasure + 1;
|
|
646
646
|
}
|
|
647
647
|
for (measureIndex = startMeasure; measureIndex < endMeasure; ++measureIndex) {
|
|
648
648
|
if (!scoreMode && !selectionMode) {
|
|
649
649
|
// If not whole score or selections, change until the tempo doesn't match previous measure's tempo (next tempo change)
|
|
650
650
|
const compMeasure = this.score.staves[0].measures[measureIndex];
|
|
651
|
-
if (
|
|
651
|
+
if (SmoTempo.eq(originalTempo, compMeasure.tempo) || displayed === false) {
|
|
652
652
|
const sel = SmoSelection.measureSelection(this.score, 0, measureIndex);
|
|
653
653
|
const altSel = SmoSelection.measureSelection(this.storeScore, 0, measureIndex);
|
|
654
654
|
if (sel && sel.measure.tempo.display && !displayed) {
|
|
@@ -706,17 +706,17 @@ export class SuiScoreViewOperations extends SuiScoreView {
|
|
|
706
706
|
* default tempo, or the previously-set tempo.
|
|
707
707
|
* @param scoreMode whether to reset entire score
|
|
708
708
|
*/
|
|
709
|
-
async removeTempo(measure: SmoMeasure, tempo:
|
|
709
|
+
async removeTempo(measure: SmoMeasure, tempo: SmoTempo, scoreMode: boolean, selectionMode: boolean): Promise<void> {
|
|
710
710
|
const startSelection = this.tracker.selections[0];
|
|
711
711
|
if (startSelection.selector.measure > 0) {
|
|
712
712
|
const measureIx = startSelection.selector.measure - 1;
|
|
713
713
|
const target = startSelection.staff.measures[measureIx];
|
|
714
714
|
const tempo = target.getTempo();
|
|
715
|
-
const newTempo = new
|
|
715
|
+
const newTempo = new SmoTempo(tempo);
|
|
716
716
|
newTempo.display = false;
|
|
717
717
|
this.updateTempoScore(measure, newTempo, scoreMode, selectionMode);
|
|
718
718
|
} else {
|
|
719
|
-
this.updateTempoScore(measure, new
|
|
719
|
+
this.updateTempoScore(measure, new SmoTempo(SmoTempo.defaults), scoreMode, selectionMode);
|
|
720
720
|
}
|
|
721
721
|
await this.renderer.updatePromise();
|
|
722
722
|
}
|
|
@@ -850,7 +850,9 @@ export class SuiChordEditor extends SuiTextEditor {
|
|
|
850
850
|
if (this.svgText !== null && this.svgText.blocks.length > this.textPos && this.textPos >= 0) {
|
|
851
851
|
this.textType = this.svgText.blocks[this.textPos].textType;
|
|
852
852
|
}
|
|
853
|
-
evdata.preventDefault
|
|
853
|
+
if (typeof(evdata.preventDefault) === 'function') {
|
|
854
|
+
evdata.preventDefault(); // prevent browser scroll
|
|
855
|
+
}
|
|
854
856
|
|
|
855
857
|
return edited;
|
|
856
858
|
}
|
|
@@ -543,15 +543,21 @@ export class VxMeasure implements VxMeasureIf {
|
|
|
543
543
|
this.stave = createStave(smoVexStaveParams);
|
|
544
544
|
if (this.smoMeasure.svg.forceTimeSignature) {
|
|
545
545
|
const ts = this.smoMeasure.timeSignature;
|
|
546
|
-
|
|
546
|
+
|
|
547
547
|
if (this.smoMeasure.timeSignature.useSymbol && ts.actualBeats === 4 && ts.beatDuration === 4) {
|
|
548
|
-
|
|
548
|
+
this.stave.addTimeSignature('C');
|
|
549
549
|
} else if (this.smoMeasure.timeSignature.useSymbol && ts.actualBeats === 2 && ts.beatDuration === 4) {
|
|
550
|
-
|
|
551
|
-
} else
|
|
552
|
-
tsString = this.smoMeasure.timeSignature.displayString;
|
|
550
|
+
this.stave.addTimeSignature('C|');
|
|
551
|
+
} else {
|
|
552
|
+
let tsString = this.smoMeasure.timeSignature.displayString.length ? this.smoMeasure.timeSignature.displayString : ts.timeSignature;
|
|
553
|
+
const tsStrings = tsString.split('+');
|
|
554
|
+
for (let i = 0; i < tsStrings.length; i++) {
|
|
555
|
+
const tsString = tsStrings[i].trim();
|
|
556
|
+
if (tsString.length) {
|
|
557
|
+
this.stave.addTimeSignature(tsStrings[i].trim());
|
|
558
|
+
}
|
|
559
|
+
}
|
|
553
560
|
}
|
|
554
|
-
this.stave.addTimeSignature(tsString);
|
|
555
561
|
}
|
|
556
562
|
// Connect it to the rendering context and draw!
|
|
557
563
|
this.stave.setContext(this.context.getContext());
|