Skip to content

Commit e6dae5a

Browse files
committed
merge: linebreak-marker reflow and toolbar/menu polish
2 parents d7893a6 + 0331e33 commit e6dae5a

13 files changed

+446
-47
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
X:216
2+
T:Bala Jan (excerpt)
3+
L:1/8
4+
M:4/4
5+
I:linebreak $
6+
K:Amin
7+
V:1
8+
|: G2 A2 A4 | Bc d2 d2 cB | A B2 c/d/ cB A2 | $
9+
G2 A2 A4 | Bc d2 d2 cB | A B2 c/d/ cB A2 | $ %6
10+
d2 d2 dcBA | B2 c/d/c/d/ c/d/c/d/ BA | A4 z4 :| $
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
X:1
2+
T:Linebreak marker with middle comment
3+
L:1/8
4+
M:4/4
5+
I:linebreak $
6+
K:A
7+
V:1
8+
AA AA AA AA | BB BB BB BB | $
9+
CC CC CC CC | DD DD DD DD | EE EE EE EE | FF FF FF FF | $ %11
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
X:1
2+
T:Linebreak marker reflow
3+
M:4/4
4+
L:1/8
5+
I:linebreak $
6+
K:C
7+
C2 D2 | E2 F2 | $
8+
G2 A2 | B2 c2 | $ % 4
9+
d2 e2 | f2 g2 | $
10+
a2 b2 | c'2 d'2 |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
X:216
2+
T:Bala Jan (excerpt)
3+
L:1/8
4+
M:4/4
5+
I:linebreak $
6+
K:Amin
7+
V:1
8+
|: G2 A2 A4 | Bc d2 d2 cB | A B2 c/d/ cB A2 | $ G2 A2 A4 |
9+
Bc d2 d2 cB | A B2 c/d/ cB A2 | $ %6
10+
d2 d2 dcBA | B2 c/d/c/d/ c/d/c/d/ BA | A4 z4 :| $
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
X:1
2+
T:Linebreak marker with middle comment
3+
L:1/8
4+
M:4/4
5+
I:linebreak $
6+
K:A
7+
V:1
8+
AA AA AA AA | BB BB BB BB | $
9+
CC CC CC CC |
10+
DD DD DD DD | %11
11+
EE EE EE EE | FF FF FF FF | $
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
X:1
2+
T:Linebreak marker reflow
3+
M:4/4
4+
L:1/8
5+
I:linebreak $
6+
K:C
7+
C2 D2 | E2 F2 | $ G2 A2 | B2 c2 | $ % 4
8+
d2 e2 | f2 g2 | $ a2 b2 | c'2 d'2 |

devtools/measures_harness/run_tests.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ async function runReflowRoundtripCase({ name, fixture, measuresPerLineA, measure
8484
assertEqualBytes(name, twice, direct);
8585
}
8686

87+
async function runLinebreakMarkerCase({ name, fixture, expected }) {
88+
const input = readText(path.join(FIXTURES, fixture));
89+
const expectedText = readText(path.join(EXPECTED, expected));
90+
const { transformMeasuresByLinebreakMarker, normalizeMeasuresLineBreaks } = await import("../../src/renderer/measures.mjs");
91+
const actual = normalizeMeasuresLineBreaks(transformMeasuresByLinebreakMarker(input));
92+
assertNoBlankLinesOutsideBegintext(name, actual);
93+
assertEqualBytes(name, actual, expectedText);
94+
}
95+
8796
async function main() {
8897
const cases = [
8998
{
@@ -109,13 +118,29 @@ async function main() {
109118
fixture: "inline-key-change.abc",
110119
expected: "inline-key-change_mpl2.abc",
111120
measuresPerLine: 2,
121+
},
122+
{
123+
name: "TEST 5: reflow by I:linebreak marker keeps marker comments",
124+
fixture: "linebreak-marker.abc",
125+
expected: "linebreak-marker_reflow.abc",
126+
},
127+
{
128+
name: "TEST 6: marker comment line merges with pending music",
129+
fixture: "linebreak-marker-comment-merge.abc",
130+
expected: "linebreak-marker-comment-merge_reflow.abc",
131+
},
132+
{
133+
name: "TEST 7: middle inline comment does not break marker merge",
134+
fixture: "linebreak-marker-middle-comment.abc",
135+
expected: "linebreak-marker-middle-comment_reflow.abc",
112136
},
113137
];
114138

115139
for (const c of cases) {
116140
try {
117141
// eslint-disable-next-line no-await-in-loop
118-
await runCase(c);
142+
if (c.measuresPerLine) await runCase(c);
143+
else await runLinebreakMarkerCase(c);
119144
console.log(`% PASS ${c.name}`);
120145
} catch (e) {
121146
console.log(`% FAIL ${c.name}`);
@@ -129,14 +154,14 @@ async function main() {
129154

130155
try {
131156
await runReflowRoundtripCase({
132-
name: "TEST 5: reflow 1 bar/line -> 2 bars/line changes output",
157+
name: "TEST 8: reflow 1 bar/line -> 2 bars/line changes output",
133158
fixture: "hasapia-mandilatos.abc",
134159
measuresPerLineA: 1,
135160
measuresPerLineB: 2,
136161
});
137-
console.log("% PASS TEST 5: reflow 1 bar/line -> 2 bars/line changes output");
162+
console.log("% PASS TEST 8: reflow 1 bar/line -> 2 bars/line changes output");
138163
} catch (e) {
139-
console.log("% FAIL TEST 5: reflow 1 bar/line -> 2 bars/line changes output");
164+
console.log("% FAIL TEST 8: reflow 1 bar/line -> 2 bars/line changes output");
140165
const msg = String(e && e.message ? e.message : e);
141166
for (const line of msg.split(/\r\n|\n|\r/)) {
142167
console.log(`% ${line}`);

scripts/check_renderer_build.mjs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,41 @@ async function assertSaveIntentGuards() {
9090
}
9191
}
9292

93+
async function assertInlineToolbarIconsCompatibility() {
94+
const indexPath = "src/renderer/index.html";
95+
const stylePath = "src/renderer/style.css";
96+
const html = await readFile(indexPath, "utf8");
97+
const css = await readFile(stylePath, "utf8");
98+
99+
if (!html.includes("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"0\" height=\"0\"")) {
100+
throw new Error("Missing inline SVG sprite in renderer HTML.");
101+
}
102+
if (!html.includes("<use href=\"#ui-library\"></use>")) {
103+
throw new Error("Toolbar icons must use inline sprite references.");
104+
}
105+
if (css.includes("background-image: url(\"../../assets/icons/ui/")) {
106+
throw new Error("Toolbar icons must not use external SVG files.");
107+
}
108+
if (!css.includes("stroke: currentColor;") || !css.includes("fill: none;")) {
109+
throw new Error(".btn-icon must use stroke/fill inline-SVG styling.");
110+
}
111+
112+
const requiredSymbols = [
113+
"ui-fonts",
114+
"ui-focus",
115+
"ui-split",
116+
"ui-alert",
117+
"ui-follow",
118+
"ui-globe",
119+
"ui-clear",
120+
];
121+
for (const symbol of requiredSymbols) {
122+
if (!html.includes(`<symbol id="${symbol}"`)) {
123+
throw new Error(`Missing toolbar SVG symbol: ${symbol}`);
124+
}
125+
}
126+
}
127+
93128
async function main() {
94129
const res = await build({
95130
entryPoints: ["src/renderer/renderer.js"],
@@ -105,6 +140,7 @@ async function main() {
105140
}
106141

107142
await assertSaveIntentGuards();
143+
await assertInlineToolbarIconsCompatibility();
108144
}
109145

110146
main().catch((err) => {

src/main/menu.js

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ function buildDiagnosticsSubmenu(appState, sendMenuAction) {
1515
const autoDumpEnabled = Boolean(debugFlags.autoDump);
1616
return [
1717
{ label: "Save Debug Dump…", accelerator: "CmdOrCtrl+Shift+D", click: () => sendMenuAction("dumpDebug") },
18+
{ role: "toggleDevTools", label: "Toggle Developer Tools" },
19+
{ label: "Open Settings Folder", click: () => sendMenuAction("openSettingsFolder") },
1820
{ type: "separator" },
1921
{
2022
label: "Show Debug Messages",
@@ -161,8 +163,7 @@ function buildMenuTemplate(appState, sendMenuAction) {
161163
const viewMenu = {
162164
label: "View",
163165
submenu: [
164-
{ role: "toggleDevTools" },
165-
...(isMac ? [{ type: "separator" }, { role: "togglefullscreen" }] : []),
166+
...(isMac ? [{ role: "togglefullscreen" }] : []),
166167
{ type: "separator" },
167168
{ label: "Library Catalog…", accelerator: "CmdOrCtrl+Shift+L", click: () => sendMenuAction("libraryList") },
168169
{ label: "Set List…", click: () => sendMenuAction("setList") },
@@ -211,38 +212,38 @@ function buildMenuTemplate(appState, sendMenuAction) {
211212
label: "Tools",
212213
submenu: [
213214
{
214-
label: "Transform",
215+
label: "Transpose",
215216
submenu: [
216217
{
217-
label: "Transpose",
218-
submenu: [
219-
{
220-
label: "Up Semitone",
221-
accelerator: "CmdOrCtrl+Shift+Up",
222-
click: () => sendMenuAction("transformTransposeUp"),
223-
},
224-
{
225-
label: "Down Semitone",
226-
accelerator: "CmdOrCtrl+Shift+Down",
227-
click: () => sendMenuAction("transformTransposeDown"),
228-
},
229-
],
218+
label: "Up Semitone",
219+
accelerator: "CmdOrCtrl+Shift+Up",
220+
click: () => sendMenuAction("transformTransposeUp"),
230221
},
231222
{
232-
label: "Note Lengths",
233-
submenu: [
234-
{
235-
label: "Double",
236-
accelerator: "CmdOrCtrl+Shift+Right",
237-
click: () => sendMenuAction("transformDouble"),
238-
},
239-
{
240-
label: "Half",
241-
accelerator: "CmdOrCtrl+Shift+Left",
242-
click: () => sendMenuAction("transformHalf"),
243-
},
244-
],
223+
label: "Down Semitone",
224+
accelerator: "CmdOrCtrl+Shift+Down",
225+
click: () => sendMenuAction("transformTransposeDown"),
226+
},
227+
],
228+
},
229+
{
230+
label: "Note Lengths",
231+
submenu: [
232+
{
233+
label: "Double",
234+
accelerator: "CmdOrCtrl+Shift+Right",
235+
click: () => sendMenuAction("transformDouble"),
236+
},
237+
{
238+
label: "Half",
239+
accelerator: "CmdOrCtrl+Shift+Left",
240+
click: () => sendMenuAction("transformHalf"),
245241
},
242+
],
243+
},
244+
{
245+
label: "Bar Layout",
246+
submenu: [
246247
{
247248
label: "Measures per Line",
248249
submenu: [
@@ -255,6 +256,15 @@ function buildMenuTemplate(appState, sendMenuAction) {
255256
}),
256257
],
257258
},
259+
{
260+
label: "Reflow by Linebreak Marker",
261+
click: () => sendMenuAction("transformLinebreakMarkers"),
262+
},
263+
{
264+
label: "Align Bars",
265+
accelerator: "CmdOrCtrl+Shift+A",
266+
click: () => sendMenuAction("alignBars"),
267+
},
258268
],
259269
},
260270
{ type: "separator" },
@@ -276,7 +286,6 @@ function buildMenuTemplate(appState, sendMenuAction) {
276286
accelerator: "CmdOrCtrl+Shift+X",
277287
click: () => sendMenuAction("renumberXInFile"),
278288
},
279-
{ label: "Align Bars", accelerator: "CmdOrCtrl+Shift+A", click: () => sendMenuAction("alignBars") },
280289
],
281290
};
282291

@@ -287,14 +296,13 @@ function buildMenuTemplate(appState, sendMenuAction) {
287296
{ label: "ABC Guide (F1)", accelerator: "F1", click: () => sendMenuAction("helpGuide") },
288297
{ label: "ABCarus User Guide", click: () => sendMenuAction("helpUserGuide") },
289298
{ type: "separator" },
290-
{ label: "Diagnostics", submenu: buildDiagnosticsSubmenu(appState, sendMenuAction) },
291-
{ label: "Open Settings Folder", click: () => sendMenuAction("openSettingsFolder") },
292-
{ type: "separator" },
293299
{ label: "ABC Notation Homepage", click: () => sendMenuAction({ type: "helpLink", url: "https://abcnotation.com/" }) },
294300
{ label: "ABCusers (Groups.io)", click: () => sendMenuAction({ type: "helpLink", url: "https://groups.io/g/abcusers/topics" }) },
295301
{ label: "ABCNotation User Group (Facebook)", click: () => sendMenuAction({ type: "helpLink", url: "https://www.facebook.com/groups/498671610282070" }) },
296302
{ type: "separator" },
297303
{ label: "Report an Issue…", click: () => sendMenuAction({ type: "helpLink", url: "https://github.com/topchyan/abcarus/issues/new/choose" }) },
304+
{ type: "separator" },
305+
{ label: "Diagnostics", submenu: buildDiagnosticsSubmenu(appState, sendMenuAction) },
298306
...(isMac ? [] : [{ type: "separator" }, { label: "About", click: () => sendMenuAction("about") }]),
299307
],
300308
};

0 commit comments

Comments
 (0)