Skip to content

Commit cc1a688

Browse files
committed
Create instruments from mixer contextmenu
1 parent 003ea18 commit cc1a688

5 files changed

Lines changed: 69 additions & 45 deletions

File tree

src/App.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ButtonToolbar, CommandHost, formatHotkey, FullScreen, GridFrameContainer, HFlex, ICommand, IComponent, StatusBar, TabFrameContainer, visitNodeAndChildNodesBreadth, visitNodeAndChildNodesDepth } from "./nutz";
1+
import { ButtonToolbar, CommandHost, formatHotkey, FullScreen, getOrCreateDirectory, GridFrameContainer, HFlex, ICommand, IComponent, StatusBar, TabFrameContainer, visitNodeAndChildNodesBreadth, visitNodeAndChildNodesDepth } from "./nutz";
22
import { MenuBar } from "./nutz/Menubar";
33
import { ModalDialogContainer } from "./nutz/ModalDialogContainer";
44
import { mainMenu } from './menu/menu';
@@ -25,6 +25,8 @@ import { ChorusFactory } from "./audio/plugins/Chorus";
2525
import { CompressorFactory } from "./audio/plugins/Compressor";
2626
import { MasterizerFactory } from "./audio/plugins/Masterizer";
2727
import { SaturationFactory } from "./audio/plugins/Saturation";
28+
import { getInstrumentName } from "./components/PatternEditorHelper";
29+
import { importJsonPreset } from "./presetfile/JsonPreset";
2830

2931
class PeakMeter implements IComponent {
3032
app: Appl;
@@ -383,6 +385,29 @@ export class Appl extends CommandHost implements IComponent {
383385
this.recordOffset = 0;
384386
}
385387

388+
async createInstrument(instrumentId: string, x: number, y: number) {
389+
const instrument = this.song.createInstrument(instrumentId, getInstrumentName(this.song.instruments, instrumentId), x, y, {});
390+
391+
// If instrument has notes: Create sequence column and empty pattern with default pattern columns
392+
const instrumenteer = this.playerSongAdapter.instrumentMap.get(instrument);
393+
if (instrumenteer.factory.maxPolyphony > 0) {
394+
const column = this.song.createSequenceColumn(instrument);
395+
const pa = this.song.createPattern(instrument, "00", 64, 4);
396+
this.song.createPatternColumn(pa, instrument, "midinote");
397+
}
398+
399+
// Load default preset bank if exist
400+
const instrumentName = instrument.instrumentId.replace(/[\/\\:*?"<>|]/g, "_");
401+
402+
const instrumentPresetHandle = await getOrCreateDirectory(this.homeDir, "presets", instrumentName)
403+
404+
const bankHandle = await instrumentPresetHandle.getFileHandle("default.mprs")
405+
const bank = await importJsonPreset(bankHandle);
406+
407+
console.log("Createing instrument with bank", bank)
408+
this.song.setInstrumentBank(instrument, bank);
409+
}
410+
386411
onInput = (ev: CustomEvent<Float32Array[]>) => {
387412
const inputs = ev.detail;
388413
const inputLength = inputs[0].length;
Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Appl } from "../../App";
22
import { InstrumentFactoryPicker } from "../../components/InstrumentFactoryPicker";
33
import { MixerPanel } from "../../components/MixerPanel";
4+
import { getInstrumentName } from "../../components/PatternEditorHelper";
45
import { getOrCreateDirectory, ICommand } from "../../nutz";
56
import { importJsonPreset } from "../../presetfile/JsonPreset";
67

@@ -22,43 +23,6 @@ export class AddInstrumentCommand implements ICommand {
2223
const instrumentId = factory.identifier;
2324

2425
const clickPt = this.component.mixerCanvas.clickPt;
25-
const instrument = this.app.song.createInstrument(instrumentId, this.getInstrumentName(instrumentId), clickPt[0], clickPt[1], {});
26-
27-
// If instrument has notes: Create sequence column and empty pattern with default pattern columns
28-
const instrumenteer = this.app.playerSongAdapter.instrumentMap.get(instrument);
29-
if (instrumenteer.factory.maxPolyphony > 0) {
30-
const column = this.app.song.createSequenceColumn(instrument);
31-
const pa = this.app.song.createPattern(instrument, "00", 64, 4);
32-
this.app.song.createPatternColumn(pa, instrument, "midinote");
33-
}
34-
35-
// Load default preset bank if exist
36-
const instrumentName = instrument.instrumentId.replace(/[\/\\:*?"<>|]/g, "_");
37-
38-
const instrumentPresetHandle = await getOrCreateDirectory(this.component.app.homeDir, "presets", instrumentName)
39-
40-
const bankHandle = await instrumentPresetHandle.getFileHandle("default.mprs")
41-
const bank = await importJsonPreset(bankHandle);
42-
43-
console.log("Createing instrument with bank", bank)
44-
this.app.song.setInstrumentBank(instrument, bank);
45-
}
46-
47-
getInstrumentName(instrumentId: string): string {
48-
const ls = instrumentId.lastIndexOf("/");
49-
50-
const baseName = instrumentId.substring(ls + 1);
51-
let name = baseName;
52-
let counter = 2;
53-
while (this.instrumentNameExists(name)) {
54-
name = baseName + "-" + counter;
55-
counter++;
56-
}
57-
58-
return name;
59-
}
60-
61-
instrumentNameExists(name: string) {
62-
return this.app.song.instruments.findIndex(i => i.name === name) !== -1;
26+
const instrument = this.app.createInstrument(instrumentId, clickPt[0], clickPt[1]);
6327
}
6428
}

src/components/MixerCanvas.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ export class MixerCanvas implements IComponent {
272272
return;
273273
};
274274

275-
onContextMenu = (e: MouseEvent) => {
275+
onContextMenu = async (e: MouseEvent) => {
276276
console.log("onContextMenu")
277277

278278
const p: PointType = [ e.offsetX, e.offsetY ];
@@ -288,17 +288,34 @@ export class MixerCanvas implements IComponent {
288288
// create menu with instrument factory parameter
289289
const mixerMenu: MenuItem[] = [ {
290290
label: "Create Instrument...",
291-
action: "add-instrument"
291+
items: []
292+
},
293+
{
294+
label: "Create Effect...",
295+
items: []
292296
}];
293297

294-
this.app.contextMenuContainer.show(this.commandHost, rc.left + e.offsetX, rc.top + e.offsetY, mixerMenu);
298+
for (let factory of this.app.instrumentFactories) {
299+
const index = factory.maxPolyphony > 0 ? 0 : 1;
300+
mixerMenu[index].items.push({
301+
label: factory.identifier,
302+
action: factory.identifier,
303+
});
304+
}
305+
306+
mixerMenu[0].items.sort((a, b) => a.label.localeCompare(b.label));
307+
mixerMenu[1].items.sort((a, b) => a.label.localeCompare(b.label));
308+
295309
e.preventDefault();
296310

311+
const action = await this.app.contextMenuContainer.showPopup(rc.left + e.offsetX, rc.top + e.offsetY, mixerMenu);
312+
await this.app.createInstrument(action, this.clickPt[0], this.clickPt[1]);
313+
297314
return;
298315
}
299316

300-
this.app.contextMenuContainer.show(this.commandHost, rc.left + e.offsetX, rc.top + e.offsetY, instrumentMenu);
301317
e.preventDefault();
318+
await this.app.contextMenuContainer.show(this.commandHost, rc.left + e.offsetX, rc.top + e.offsetY, instrumentMenu);
302319
};
303320

304321
onDblClick = (e: MouseEvent) => {

src/components/PatternEditorHelper.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,22 @@ export function getNoteForKey(code: string, octave: number) {
461461
}
462462

463463
return -1;
464-
}
464+
}
465+
466+
export function getInstrumentName(instruments: InstrumentDocument[], instrumentId: string): string {
467+
const ls = instrumentId.lastIndexOf("/");
468+
469+
const baseName = instrumentId.substring(ls + 1);
470+
let name = baseName;
471+
let counter = 2;
472+
while (instrumentNameExists(instruments, name)) {
473+
name = baseName + "-" + counter;
474+
counter++;
475+
}
476+
477+
return name;
478+
}
479+
480+
export function instrumentNameExists(instruments: InstrumentDocument[], name: string) {
481+
return instruments.findIndex(i => i.name === name) !== -1;
482+
}

src/nutz/ContextMenuContainer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class ContextMenuContainer {
3131
}
3232

3333
// Returns the action property of the selected menu item, or null if canceled
34-
async showPopup(x: number, y: number, menu: NutzMenuItem[]) {
34+
async showPopup(x: number, y: number, menu: NutzMenuItem[]): Promise<string | null> {
3535

3636
if (this.resolve) {
3737
this.resolve(null);

0 commit comments

Comments
 (0)