1 module test1.preseteditor;
2 
3 import pixelperfectengine.concrete.window; 
4 import pixelperfectengine.audio.base.modulebase;
5 import std.conv : to;
6 import std.utf : toUTF32, toUTF8;
7 import std.algorithm.searching : countUntil;
8 import pixelperfectengine.audio.base.config;
9 
10 import test1.app;
11 import test1.editorevents;
12 
13 public class PresetEditor : Window {
14 	ListView listView_presets;
15 	ListView listView_values;
16 	SmallButton[] smallButtons;
17 	CheckBox checkBox_Globals;
18 	AudioModule editedModule;
19 	string editedModID;
20 	AudioDevKit adk;
21 	MValue[] params;
22 	int[] paramIDs;
23 	int presetID;
24 	string presetName;
25 	
26 	//CheckBox	checkBox_globals;
27 	public this(AudioDevKit adk) {
28 		super(Box(0, 0, 330, 330), "`" ~ toUTF32(adk.selectedModID) ~ "` presets"d);
29 		listView_presets = new ListView(new ListViewHeader(16, [32, 32, 240], ["Bank" ,"Prg" ,"Name"]), null, 
30 				"listView_presets", Box(5, 20, 230, 100));
31 		listView_values = new ListView(new ListViewHeader(16, [200, 100], ["Name" ,"Value"]), null, "listView_values", 
32 				Box(5, 105, 325, 325));
33 		//smallButtons ~= new SmallButton("loadB", "loadA", "load", Box(236, 20, 251, 35));
34 		//smallButtons ~= new SmallButton("saveB", "saveA", "save", Box(252, 20, 267, 35));
35 		//smallButtons ~= new SmallButton("importB", "importA", "import", Box(268, 20, 283, 36));
36 		//smallButtons ~= new SmallButton("exportB", "exportA", "export", Box(284, 20, 299, 36));
37 
38 		smallButtons ~= new SmallButton("addB", "addA", "add", Box(236, 36, 251, 51));
39 		smallButtons ~= new SmallButton("removeB", "removeA", "remove", Box(252, 36, 267, 51));
40 		checkBox_Globals = new CheckBox("globalsB", "globalsA", "globals", Box(268, 36, 283, 51));
41 		//smallButtons ~= new SmallButton("macroB", "macroA", "macro", Box(284, 36, 299, 51));
42 
43 		listView_presets.editEnable = true;
44 		listView_presets.multicellEditEnable = true;
45 		addElement(listView_presets);
46 		listView_presets.onItemSelect = &listView_presets_onSelect;
47 		listView_presets.onTextInput = &listView_presets_onTextEdit;
48 		listView_values.editEnable = true;
49 		addElement(checkBox_Globals);
50 		checkBox_Globals.onToggle = &checkBox_Globals_onToggle;
51 		addElement(listView_values);
52 		listView_values.onItemSelect = &listView_values_onSelect;
53 		listView_values.onTextInput = &listView_values_onTextEdit;
54 		foreach (SmallButton key; smallButtons) {
55 			addElement(key);
56 			key.onMouseLClick = &smallButtons_onClick;
57 		}
58 		this.editedModule = adk.selectedModule;
59 		this.editedModID = adk.selectedModID;
60 		this.adk = adk;
61 		params = editedModule.getParameters;
62 		loadPresets();
63 	}
64 	private void fillValues() {
65 		StyleSheet ss = globalDefaultStyle;
66 		paramIDs.length = 0;
67 		listView_values.clear();
68 		foreach (MValue key; params) {
69 			const char fc = key.name.length ? key.name[0] : ' ';
70 			if ((fc == '_' && checkBox_Globals.isChecked) || (fc != '_' && !checkBox_Globals.isChecked)) {
71 				ListViewItem.Field[] fields = 
72 						[ListViewItem.Field(new Text(toUTF32(key.name), ss.getChrFormatting("listViewItem")), null)];
73 				final switch (key.type) with (MValueType) {
74 					case init:
75 						assert(0, "Something went really wrong...");
76 					case String:
77 						dstring val = toUTF32(editedModule.readParam_string(presetID, key.id));
78 						fields ~= 
79 								ListViewItem.Field(new Text(val, ss.getChrFormatting("listViewItem")), null, TextInputFieldType.ASCIIText);
80 						break;
81 					case Int32, Boolean:
82 						dstring val = to!dstring(editedModule.readParam_int(presetID, key.id));
83 						fields ~= 
84 								ListViewItem.Field(new Text(val, ss.getChrFormatting("listViewItem")), null, TextInputFieldType.Integer);
85 						break;
86 					case Int64:
87 						dstring val = to!dstring(editedModule.readParam_long(presetID, key.id));
88 						fields ~= 
89 								ListViewItem.Field(new Text(val, ss.getChrFormatting("listViewItem")), null, TextInputFieldType.Integer);
90 						break;
91 					case Float:
92 						dstring val = to!dstring(editedModule.readParam_double(presetID, key.id));
93 						fields ~= 
94 								ListViewItem.Field(new Text(val, ss.getChrFormatting("listViewItem")), null, TextInputFieldType.Decimal);
95 						break;
96 				}
97 				listView_values ~= new ListViewItem(16, fields);
98 				paramIDs ~= key.id;
99 			}
100 		}
101 		listView_values.refresh();
102 	}
103 	private void loadPresets() {
104 		listView_presets.clear();
105 		foreach (key; adk.mcfg.getPresetList(adk.selectedModID)) {
106 			if (key.id < (1<<21))
107 				listView_presets ~= new ListViewItem(16, [(key.id>>7).to!dstring, (key.id & 127).to!dstring, toUTF32(key.name)], 
108 						[TextInputFieldType.DecimalP, TextInputFieldType.DecimalP, TextInputFieldType.Text]);
109 		}
110 		listView_presets.refresh();
111 	}
112 	protected void checkBox_Globals_onToggle(Event ev) {
113 		if (checkBox_Globals.isChecked) {
114 			presetID = 1<<21;
115 			presetName = "globals";
116 		} else if (listView_presets.selectedElement() !is null) {
117 			if (listView_presets.selectedElement()[0].getText() != "!" && listView_presets.selectedElement()[1].getText() != "!") {
118 				presetID = (to!int(listView_presets.selectedElement()[0].getText())<<7) || 
119 						(to!int(listView_presets.selectedElement()[1].getText()));
120 			}
121 			presetName = toUTF8(listView_presets.selectedElement()[2].getText());
122 		}
123 		fillValues();
124 	}
125 	protected void smallButtons_onClick(Event ev) {
126 		SmallButton sender = cast(SmallButton)ev.sender;
127 		switch (sender.getSource) {
128 			case "add":
129 				listView_presets ~= new ListViewItem(16, ["!", "!", ""], 
130 						[TextInputFieldType.DecimalP, TextInputFieldType.DecimalP, TextInputFieldType.Text]);
131 				listView_presets.refresh();
132 				break;
133 			case "remove":
134 				if (presetID == 1<<21)
135 					adk.eventStack.addToTop(new RemovePresetEvent(adk.mcfg, editedModID, presetID));
136 				break;
137 			default:
138 				break;
139 		}
140 	}
141 	protected void listView_presets_onSelect(Event ev) {
142 		import midi2.types.structs;
143 		import midi2.types.enums;
144 		ListViewItem item = cast(ListViewItem)ev.aux;
145 		if (item[0].getText != "!" && item[1].getText != "!") {
146 			const uint bank = item[0].getText().to!uint;
147 			const uint preset = item[1].getText().to!uint;
148 			presetID = preset | (bank<<7);
149 			presetName = item[2].getText().toUTF8;
150 			fillValues();
151 			editedModule.midiReceive(UMP(MessageType.MIDI2, 0, MIDI2_0Cmd.PrgCh, 0), 
152 					(preset<<24) | (bank & 0x7F) | ((bank>>7)<<8));
153 			/* editedModule.midiReceive(UMP(MessageType.MIDI2, 0, MIDI2_0Cmd.PrgCh, 0), 
154 					((presetID & 127)<<24) | ((presetID>>7) & 0x7F) | ((presetID>>14)<<8)); */
155 		}
156 	}
157 	protected void listView_presets_onTextEdit(Event ev) {
158 		ListViewItem item = cast(ListViewItem)ev.aux;
159 		if (item[0].getText != "!" && item[1].getText != "!") {
160 			const uint bank = item[0].getText().to!uint;
161 			const uint preset = item[1].getText().to!uint;
162 			presetID = preset | (bank<<7);
163 			presetName = item[2].getText().toUTF8;
164 		}
165 	}
166 	protected void listView_values_onSelect(Event ev) {
167 
168 	}
169 	protected void listView_values_onTextEdit(Event ev) {
170 		CellEditEvent cee = cast(CellEditEvent)ev;
171 		MValue currparam = params[countUntil!"a.id == b"(params, paramIDs[cee.row])];
172 		dstring str = listView_values[cee.row][1].text.toDString;
173 		ModuleConfig mcfg = adk.mcfg;
174 		final switch (currparam.type) with (MValueType) {
175 			case init:
176 				break;
177 			case String:
178 				editedModule.writeParam_string(presetID, currparam.id, toUTF8(str));
179 				string newVal = editedModule.readParam_string(presetID, currparam.id); //str = toUTF32(editedModule.readParam_string(presetID, currparam.id));
180 				str = toUTF32(newVal);
181 				listView_values[cee.row] = new ListViewItem(16, [toUTF32(currparam.name), str], 
182 						[TextInputFieldType.None, TextInputFieldType.Text]);
183 				if (currparam.idType)
184 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.id, editedModID, presetID, 
185 							presetName));
186 				else
187 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.name, editedModID, presetID, 
188 							presetName));
189 				break;
190 			case Int32, Boolean:
191 				editedModule.writeParam_int(presetID, currparam.id, to!int(str));
192 				int newVal = editedModule.readParam_int(presetID, currparam.id); //str = to!dstring(editedModule.readParam_int(presetID, currparam.id));
193 				str = to!dstring(newVal);
194 				listView_values[cee.row] = new ListViewItem(16, [toUTF32(currparam.name), str], 
195 						[TextInputFieldType.None, TextInputFieldType.Integer]);
196 				if (currparam.idType)
197 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.id, editedModID, presetID, 
198 							presetName));
199 				else
200 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.name, editedModID, presetID, 
201 							presetName));
202 				break;
203 			case Int64:
204 				editedModule.writeParam_long(presetID, currparam.id, to!long(str));
205 				long newVal = editedModule.readParam_long(presetID, currparam.id); //str = to!dstring(editedModule.readParam_long(presetID, currparam.id));
206 				str = to!dstring(newVal);
207 				listView_values[cee.row] = new ListViewItem(16, [toUTF32(currparam.name), str], 
208 						[TextInputFieldType.None, TextInputFieldType.Integer]);
209 				if (currparam.idType)
210 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.id, editedModID, presetID, 
211 							presetName));
212 				else
213 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.name, editedModID, presetID, 
214 							presetName));
215 				break;
216 			case Float:
217 				editedModule.writeParam_double(presetID, currparam.id, to!double(str));
218 				double newVal = editedModule.readParam_double(presetID, currparam.id); //str = to!dstring(editedModule.readParam_double(presetID, currparam.id));
219 				str = to!dstring(newVal);
220 				listView_values[cee.row] = new ListViewItem(16, [toUTF32(currparam.name), str], 
221 						[TextInputFieldType.None, TextInputFieldType.Decimal]);
222 				if (currparam.idType)
223 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.id, editedModID, presetID, 
224 							presetName));
225 				else
226 					adk.eventStack.addToTop(new EditPresetParameterEvent(mcfg, newVal, currparam.name, editedModID, presetID, 
227 							presetName));
228 				break;
229 		}
230 		//listView_values[cee.row][1].text.text = str;
231 		import midi2.types.structs;
232 		import midi2.types.enums;
233 		if (!checkBox_Globals.isChecked)
234 			editedModule.midiReceive(UMP(MessageType.MIDI2, 0, MIDI2_0Cmd.PrgCh, 0), 
235 					((presetID & 127)<<24) | ((presetID>>7) & 0x7F) | ((presetID>>14)<<8));
236 		//listView_values.refresh();
237 	}
238 }