forked from jummbus/jummbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChannelSettingsPrompt.ts
More file actions
131 lines (114 loc) · 6.22 KB
/
ChannelSettingsPrompt.ts
File metadata and controls
131 lines (114 loc) · 6.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (C) 2021 John Nesky, distributed under the MIT license.
import {Config} from "../synth/SynthConfig";
import {HTML} from "imperative-html/dist/esm/elements-strict";
import {SongDocument} from "./SongDocument";
import {Prompt} from "./Prompt";
import {ChangeGroup} from "./Change";
import {ChangePatternsPerChannel, ChangeInstrumentsFlags, ChangeChannelCount} from "./changes";
const {button, div, label, br, h2, input} = HTML;
export class ChannelSettingsPrompt implements Prompt {
private readonly _patternsStepper: HTMLInputElement = input({style: "width: 3em; margin-left: 1em;", type: "number", step: "1"});
private readonly _pitchChannelStepper: HTMLInputElement = input({style: "width: 3em; margin-left: 1em;", type: "number", step: "1"});
private readonly _drumChannelStepper: HTMLInputElement = input({style: "width: 3em; margin-left: 1em;", type: "number", step: "1"});
private readonly _layeredInstrumentsBox: HTMLInputElement = input({style: "width: 3em; margin-left: 1em;", type: "checkbox"});
private readonly _patternInstrumentsBox: HTMLInputElement = input({style: "width: 3em; margin-left: 1em;", type: "checkbox"});
private readonly _cancelButton: HTMLButtonElement = button({class: "cancelButton"});
private readonly _okayButton: HTMLButtonElement = button({class: "okayButton", style: "width:45%;"}, "Okay");
public readonly container: HTMLDivElement = div({class: "prompt noSelection", style: "width: 250px; text-align: right;"},
h2("Channel Settings"),
label({style: "display: flex; flex-direction: row; align-items: center; height: 2em; justify-content: flex-end;"},
"Pitch channels:",
this._pitchChannelStepper,
),
label({style: "display: flex; flex-direction: row; align-items: center; height: 2em; justify-content: flex-end;"},
"Drum channels:",
this._drumChannelStepper,
),
label({style: "display: flex; flex-direction: row; align-items: center; height: 2em; justify-content: flex-end;"},
"Available patterns per channel:",
this._patternsStepper,
),
label({style: "display: flex; flex-direction: row; align-items: center; height: 2em; justify-content: flex-end;"},
"Simultaneous instruments",
br(),
"per channel:",
this._layeredInstrumentsBox,
),
label({style: "display: flex; flex-direction: row; align-items: center; height: 2em; justify-content: flex-end;"},
"Different instruments",
br(),
"per pattern:",
this._patternInstrumentsBox,
),
label({style: "display: flex; flex-direction: row-reverse; justify-content: space-between;"},
this._okayButton,
),
this._cancelButton,
);
constructor(private _doc: SongDocument) {
this._patternsStepper.value = this._doc.song.patternsPerChannel + "";
this._patternsStepper.min = "1";
this._patternsStepper.max = Config.barCountMax + "";
this._pitchChannelStepper.value = this._doc.song.pitchChannelCount + "";
this._pitchChannelStepper.min = Config.pitchChannelCountMin + "";
this._pitchChannelStepper.max = Config.pitchChannelCountMax + "";
this._drumChannelStepper.value = this._doc.song.noiseChannelCount + "";
this._drumChannelStepper.min = Config.noiseChannelCountMin + "";
this._drumChannelStepper.max = Config.noiseChannelCountMax + "";
this._layeredInstrumentsBox.checked = this._doc.song.layeredInstruments;
this._patternInstrumentsBox.checked = this._doc.song.patternInstruments;
this._pitchChannelStepper.select();
setTimeout(()=>this._pitchChannelStepper.focus());
this._okayButton.addEventListener("click", this._saveChanges);
this._cancelButton.addEventListener("click", this._close);
this._patternsStepper.addEventListener("keypress", ChannelSettingsPrompt._validateKey);
this._pitchChannelStepper.addEventListener("keypress", ChannelSettingsPrompt._validateKey);
this._drumChannelStepper.addEventListener("keypress", ChannelSettingsPrompt._validateKey);
this._patternsStepper.addEventListener("blur", this._validateNumber);
this._pitchChannelStepper.addEventListener("blur", this._validateNumber);
this._drumChannelStepper.addEventListener("blur", this._validateNumber);
this.container.addEventListener("keydown", this._whenKeyPressed);
}
private _close = (): void => {
this._doc.undo();
}
public cleanUp = (): void => {
this._okayButton.removeEventListener("click", this._saveChanges);
this._cancelButton.removeEventListener("click", this._close);
this._patternsStepper.removeEventListener("keypress", ChannelSettingsPrompt._validateKey);
this._pitchChannelStepper.removeEventListener("keypress", ChannelSettingsPrompt._validateKey);
this._drumChannelStepper.removeEventListener("keypress", ChannelSettingsPrompt._validateKey);
this._patternsStepper.removeEventListener("blur", this._validateNumber);
this._pitchChannelStepper.removeEventListener("blur", this._validateNumber);
this._drumChannelStepper.removeEventListener("blur", this._validateNumber);
this.container.removeEventListener("keydown", this._whenKeyPressed);
}
private _whenKeyPressed = (event: KeyboardEvent): void => {
if ((<Element> event.target).tagName != "BUTTON" && event.keyCode == 13) { // Enter key
this._saveChanges();
}
}
private static _validateKey(event: KeyboardEvent): boolean {
const charCode = (event.which) ? event.which : event.keyCode;
if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
event.preventDefault();
return true;
}
return false;
}
private _validateNumber = (event: Event): void => {
const input: HTMLInputElement = <HTMLInputElement>event.target;
input.value = String(ChannelSettingsPrompt._validate(input));
}
private static _validate(input: HTMLInputElement): number {
return Math.floor(Math.max(Number(input.min), Math.min(Number(input.max), Number(input.value))));
}
private _saveChanges = (): void => {
const group: ChangeGroup = new ChangeGroup();
group.append(new ChangeInstrumentsFlags(this._doc, this._layeredInstrumentsBox.checked, this._patternInstrumentsBox.checked));
group.append(new ChangePatternsPerChannel(this._doc, ChannelSettingsPrompt._validate(this._patternsStepper)));
group.append(new ChangeChannelCount(this._doc, ChannelSettingsPrompt._validate(this._pitchChannelStepper), ChannelSettingsPrompt._validate(this._drumChannelStepper)));
this._doc.prompt = null;
this._doc.record(group, true);
}
}