1 module editor;
2 
3 import types;
4 import serializer;
5 import editorEvents;
6 import listviewedit;
7 
8 import pixelperfectengine.concrete.window;
9 import pixelperfectengine.system.input;
10 import pixelperfectengine.system.etc : csvParser;
11 import pixelperfectengine.graphics.layers;
12 import pixelperfectengine.graphics.raster;
13 import pixelperfectengine.graphics.outputscreen;
14 import pixelperfectengine.system.config;
15 import std.bitmanip : bitfields;
16 public import collections.linkedhashmap;
17 
18 import conv = std.conv;
19 import stdio = std.stdio;
20 
21 public class TopLevelWindow : Window {
22 	public ListView objectList, propList;
23 	MenuBar mb;
24 	Editor editor;
25 	public this(int width, int height, Editor e) {
26 		import pixelperfectengine.graphics.draw;
27 		super(Box(0, 0, width, height), ""d, [], null);
28 		editor = e;
29 		PopUpMenuElement[] menuElements;
30 
31 		menuElements ~= new PopUpMenuElement("file", "File");
32 
33 		menuElements[0] ~= new PopUpMenuElement("new", "New window");
34 		menuElements[0] ~= new PopUpMenuElement("load", "Load window");
35 		menuElements[0] ~= new PopUpMenuElement("save", "Save window");
36 		menuElements[0] ~= new PopUpMenuElement("saveAs", "Save window as");
37 		menuElements[0] ~= new PopUpMenuElement("export", "Export window as D code" );
38 		menuElements[0] ~= new PopUpMenuElement("exit", "Exit application", "Alt + F4");
39 
40 		menuElements ~= new PopUpMenuElement("edit", "Edit");
41 
42 		menuElements[1] ~= new PopUpMenuElement("undo", "Undo");
43 		menuElements[1] ~= new PopUpMenuElement("redo", "Redo");
44 		Text nulltext = null;
45 		menuElements[1] ~= new PopUpMenuElement("\\separator\\", nulltext, nulltext);
46 		menuElements[1] ~= new PopUpMenuElement("copy", "Copy");
47 		menuElements[1] ~= new PopUpMenuElement("cut", "Cut");
48 		menuElements[1] ~= new PopUpMenuElement("paste", "Paste");
49 
50 		menuElements ~= new PopUpMenuElement("elements", "Elements");
51 
52 		menuElements[2] ~= new PopUpMenuElement("Label", "Label");
53 		menuElements[2] ~= new PopUpMenuElement("Button", "Button");
54 		menuElements[2] ~= new PopUpMenuElement("TextBox", "TextBox");
55 		menuElements[2] ~= new PopUpMenuElement("ListView", "ListView");
56 		menuElements[2] ~= new PopUpMenuElement("CheckBox", "CheckBox");
57 		menuElements[2] ~= new PopUpMenuElement("RadioButton", "RadioButton");
58 		//menuElements[2] ~= new PopUpMenuElement("MenuBar", pt("MenuBar"), st("Ctrl + F7"));
59 		menuElements[2] ~= new PopUpMenuElement("HSlider", "HSlider");
60 		menuElements[2] ~= new PopUpMenuElement("VSlider", "VSlider");
61 
62 		menuElements ~= new PopUpMenuElement("help", "Help");
63 
64 		menuElements[3] ~= new PopUpMenuElement("helpFile", "Content");
65 		menuElements[3] ~= new PopUpMenuElement("about", "About");
66 
67 		mb = new MenuBar("mb", Box(0, 0, width-1, 15), menuElements);
68 		objectList = new ListView(new ListViewHeader(16, [128, 128], ["type"d, "name"d]), [], "objectList", 
69 				Box(644,20,width - 5,238));
70 		propList = new ListView(new ListViewHeader(16, [128,256], ["Prop"d,"Val"d]), [], "propList",
71 				Box(644,242,width - 5,477));
72 
73 		propList.editEnable = true;
74 
75 		addElement(mb);
76 		addElement(objectList);
77 		addElement(propList);
78 
79 		mb.onMenuEvent = &e.menuEvent;
80 		objectList.onItemSelect = &e.onObjectListSelect;
81 		propList.onTextInput = &e.onAttributeEdit;
82 		propList.onItemSelect = &e.onAttributeOpen;
83 	}
84 	public override void draw(bool drawHeaderOnly = false) {
85 		if(output.output.width != position.width || output.output.height != position.height)
86 			output = new BitmapDrawer(position.width(), position.height());
87 		
88 		StyleSheet ss = getStyleSheet();
89 		const Box bodyarea = Box(0, 0, position.width - 1, position.height - 1);
90 		drawFilledBox(bodyarea, ss.getColor("window"));
91 
92 		foreach (WindowElement we; elements) {
93 			we.draw();
94 		}
95 		
96 	}
97 }
98 /**
99  * Window to display the current layout.
100  */
101 public class DummyWindow : Window {
102 	Editor ed;
103 	public this(Box coordinates, dstring name, Editor ed) {
104 		super(coordinates, name);
105 		this.ed = ed;
106 	}
107 	///Passes mouse click event
108 	override public void passMCE(MouseEventCommons mec, MouseClickEvent mce) {
109 		//super.passMouseEvent(x,y,state,button);
110 		mce.x -= position.left;
111 		mce.y -= position.top;
112 		if(mce.button == MouseButton.Left){
113 			ed.clickEvent(mce.x, mce.y, mce.state);
114 		}else if(mce.button == MouseButton.Right){
115 			foreach(we; elements){
116 				const Box c = we.getPosition;
117 				if(c.isBetween(mce.x, mce.y))
118 					ed.selectEvent(we);
119 			}
120 		}
121 	}
122 	public void setWidth(int val) {
123 		position.width = val;
124 		draw();
125 	}
126 	public void setHeight(int val) {
127 		position.height = val;
128 		draw();
129 	}
130 	public void setSize(int width, int height) {
131 		position.width = width;
132 		position.height = height;
133 		draw();
134 	}
135 	override public void close() {
136 	//super.close;
137 	}
138 	/+override public void passMouseMotionEvent(int x, int y, int relX, int relY, ubyte button) {
139 
140 	}+/
141 	override public void passMME(MouseEventCommons mec, MouseMotionEvent mme) {
142 		if (mme.buttonState) {
143 			mme.x -= position.left;
144 			mme.y -= position.top;
145 			ed.dragEvent(mme.x, mme.y, mme.relX, mme.relY, mme.buttonState);
146 		}
147 	}
148 	public void drawSelection(Box box, bool crossHair = false) {
149 		draw();
150 		//stdio.writeln(box);
151 		drawBox(box, 17);
152 		if (crossHair) {
153 			const int width = position.width - 1, height = position.height - 1;
154 			
155 			drawLine(Point(0, box.top), box.cornerUL, 18);
156 			drawLine(Point(box.left, 0), box.cornerUL, 18);
157 
158 			drawLine(Point(width, box.top), box.cornerUR, 18);
159 			drawLine(Point(box.right, 0), box.cornerUR, 18);
160 
161 			drawLine(Point(0, box.bottom), box.cornerLL, 18);
162 			drawLine(Point(box.left, height), box.cornerLL, 18);
163 
164 			drawLine(Point(width, box.bottom), box.cornerLR, 18);
165 			drawLine(Point(box.right, height), box.cornerLR, 18);
166 		}
167 	}
168 }
169 
170 
171 
172 public class Editor : SystemEventListener, InputListener{
173 	WindowHandler		ewh;
174 	DummyWindow 		dw;
175 	SpriteLayer			sprtL;
176 	Raster				mainRaster;
177 	OutputScreen		outScrn;
178 	InputHandler		inputH;
179 	EditMode			mode;
180 	mixin(bitfields!(
181 		bool, "onExit", 1,
182 		bool, "undoPressed", 1,
183 		bool, "redoPressed", 1,
184 		bool, "delPressed", 1,
185 		bool, "moveElemMode", 1,
186 		bool, "resizeMode", 1,
187 		ubyte, "", 2,
188 	));
189 	Box					moveElemOrig;
190 	int					x0, y0;
191 	ElementType			typeSel;
192 	UndoableStack		eventStack;
193 	/+WindowElement[string] elements;
194 	string[string]		elementTypes;+/
195 	alias ElementInfoMap = LinkedHashMap!(string, ElementInfo);
196 	ElementInfoMap		elements;
197 	string				selection;
198 	ConfigurationProfile	config;
199 	TopLevelWindow		tlw;
200 
201 	static string[ElementType] nameBases;
202 	public this(){
203 		import pixelperfectengine.system.systemutility;
204 		import pixelperfectengine.system.file;
205 		
206 		sprtL = new SpriteLayer(RenderingMode.Copy);
207 		outScrn = new OutputScreen("WindowMaker for PPE/Concrete",1696,960);
208 		mainRaster = new Raster(848,480,outScrn,0);
209 		mainRaster.addLayer(sprtL,0);
210 		typeSel = ElementType.NULL;
211 
212 		ewh = new WindowHandler(1696,960,848,480,sprtL);
213 		mainRaster.loadPalette(loadPaletteFromFile("../system/concreteGUIE1.tga"));
214 		INIT_CONCRETE();
215 		inputH = new InputHandler();
216 		inputH.systemEventListener = this;
217 		inputH.inputListener = this;
218 		inputH.mouseListener = ewh;
219 		
220 		//ewh.setBaseWindow(new TopLevelWindow(848, 480, this));
221 		config = new ConfigurationProfile("config_wmfc.sdl", "../system/config_wmfc.sdl");
222 		{
223 			import pixelperfectengine.system.input.scancode;
224 			inputH.addBinding(BindingCode(ScanCode.ESCAPE, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("sysesc"));
225 		}
226 		config.loadBindings(inputH);
227 
228 		PopUpElement.inputhandler = inputH;
229 		WindowElement.inputHandler = inputH;
230 		
231 		dw = new DummyWindow(Coordinate(0,16,640,480), "New Window"d, this);
232 		ewh.addWindow(dw);
233 		tlw = new TopLevelWindow(848, 480, this);
234 		ewh.setBaseWindow(tlw);
235 		eventStack = new UndoableStack(10);
236 		wserializer = new WindowSerializer();
237 		dwtarget = dw;
238 		editorTarget = this;
239 		//ewh.objectList.onItemSelect = &onObjectListSelect;
240 		//ewh.propList.onTextInput = &onAttributeEdit;
241 		updateElementList;
242 	}
243 	static this(){
244 		nameBases[ElementType.Label] = "label";
245 		nameBases[ElementType.Button] = "button";
246 		nameBases[ElementType.SmallButton] = "smallButton";
247 		nameBases[ElementType.TextBox] = "textBox";
248 		nameBases[ElementType.ListView] = "listView";
249 		nameBases[ElementType.RadioButton] = "radioButton";
250 		nameBases[ElementType.CheckBox] = "checkBox";
251 		nameBases[ElementType.HSlider] = "hSlider";
252 		nameBases[ElementType.VSlider] = "vSlider";
253 		nameBases[ElementType.MenuBar] = "menuBar";
254 	}
255 	public string getNextName(string input){
256 		for(int i ; true ; i++){
257 			//if(elements.get(input ~ conv.to!string(i), null) is null)
258 			string newname = input ~ conv.to!string(i);
259 			if(!elements.getPtr(newname))
260 				return newname;
261 		}
262 	}
263 	public void onObjectListSelect(Event ev){
264 		deinitElemMove;
265 		ListViewItem lbi = cast(ListViewItem)ev.aux;
266 		if(lbi[0].text.text != "Window"){
267 			selection = conv.to!string(lbi[1].text.text);
268 		}else{//Fill attribute list with data related to the window
269 			selection = "Window";
270 		}
271 		updatePropertyList;
272 	}
273 	public void onLoadFile(Event ev){
274 		FileEvent ev0 = cast(FileEvent)ev;
275 		wserializer = new WindowSerializer(ev0.getFullPath);
276 		wserializer.deserialize(dw, this);
277 	}
278 	public void onSaveFileAs(Event ev){
279 		FileEvent ev0 = cast(FileEvent)ev;
280 		wserializer.store(ev0.getFullPath);
281 	}
282 	public void onExportWindow(Event ev){
283 		FileEvent ev0 = cast(FileEvent)ev;
284 		wserializer.generateDCode(ev0.getFullPath);
285 	}
286 	public void onAttributeEdit(Event ev){
287 		import std.utf : toUTF8;
288 		CellEditEvent ev0 = cast(CellEditEvent)ev;
289 		dstring t = ev0.text.text;
290 		ListViewItem lbi = cast(ListViewItem) ev.aux;
291 		if(selection == "Window"){
292 			switch(lbi[0].text.text) {
293 				case "name":
294 					eventStack.addToTop(new WindowRenameEvent(conv.to!string(t)));
295 					return;
296 				case "title":
297 					eventStack.addToTop(new WindowRetitleEvent(t));
298 					return;
299 				case "size:x":
300 					eventStack.addToTop(new WindowWidthChangeEvent(conv.to!int(t)));
301 					return;
302 				case "size:y":
303 					eventStack.addToTop(new WindowHeightChangeEvent(conv.to!int(t)));
304 					return;
305 				default:
306 					return;
307 			}
308 		}else{
309 			switch(lbi[0].text.text){
310 				case "text":
311 					eventStack.addToTop(new TextEditEvent(t, selection));
312 					return;
313 				case "name":
314 					eventStack.addToTop(new RenameEvent(selection, conv.to!string(t)));
315 					selection = conv.to!string(t);
316 					return;
317 				case "position":
318 					dstring[] src = csvParser(t, ';');
319 					if(src.length == 4){
320 						Coordinate c;
321 						try {
322 							c.left = conv.to!int(src[0]);
323 							c.top = conv.to!int(src[1]);
324 							c.right = conv.to!int(src[2]);
325 							c.bottom = conv.to!int(src[3]);
326 							eventStack.addToTop(new PositionEditEvent(c, selection));
327 						} catch (Exception e) {
328 							ewh.message("Format Error!", "Value is not integer!");
329 							return;
330 						}
331 					}else{
332 						ewh.message("Format Error!", "Correct format is: [int];[int];[int];[int];");
333 					}
334 					return;
335 				case "source":
336 					eventStack.addToTop(new SourceEditEvent(selection, conv.to!string(t)));
337 					return;
338 				default:
339 					return;
340 			}
341 		}
342 	}
343 	public void onAttributeOpen(Event ev) {
344 		ListViewItem lbi = cast(ListViewItem)ev.aux;
345 		switch (tlw.objectList.selectedElement[0].text.text) {
346 			case "ListView":
347 				if (lbi[0].text.text == "header") {
348 					ewh.addWindow(new ListViewEditor(selection));
349 				}
350 				break;
351 			default:
352 				break;
353 		}
354 	}
355 	public void clickEvent(int x, int y, bool state) {
356 		if(typeSel != ElementType.NULL) {
357 			if(state) {
358 				x0 = x;
359 				y0 = y;
360 			}else{
361 				Box c;
362 				if(x > x0){
363 					c.left = x0;
364 					c.right = x;
365 				}else{
366 					c.left = x;
367 					c.right = x0;
368 				}
369 				if(y > y0){
370 					c.top = y0;
371 					c.bottom = y;
372 				}else{
373 					c.top = y;
374 					c.bottom = y0;
375 				}
376 				WindowElement we;
377 				string s, type;
378 				switch(typeSel){
379 					case ElementType.Label:
380 						s = getNextName("label");
381 						type = "Label";
382 						we = new Label(conv.to!dstring(s),s,c);
383 						break;
384 					case ElementType.Button:
385 						s = getNextName("button");
386 						type = "Button";
387 						we = new Button(conv.to!dstring(s),s,c);
388 						break;
389 					case ElementType.TextBox:
390 						s = getNextName("textBox");
391 						type = "TextBox";
392 						we = new TextBox(conv.to!dstring(s),s,c);
393 						break;
394 					case ElementType.ListView:
395 						s = getNextName("listView");
396 						type = "ListView";
397 						we = new ListView(new ListViewHeader(16, [40, 40], ["col0", "col1"]), [], s, c);
398 						break;
399 					case ElementType.CheckBox:
400 						s = getNextName("CheckBox");
401 						type = "CheckBox";
402 						we = new CheckBox(conv.to!dstring(s),s,c);
403 						break;
404 					case ElementType.RadioButton:
405 						s = getNextName("radioButton");
406 						type = "RadioButton";
407 						we = new RadioButton(conv.to!dstring(s),s,c);
408 						break;
409 					/+case ElementType.MenuBar:
410 						s = getNextName("menuBar");
411 						we = new MenuBar(s,c,[new PopUpMenuElement("menu0","menu0")]);+/
412 						//break;
413 					case ElementType.HSlider:
414 						s = getNextName("horizScrollBar");
415 						type = "HorizScrollBar";
416 						we = new HorizScrollBar(16,s,c);
417 						break;
418 					case ElementType.VSlider:
419 						s = getNextName("vertScrollBar");
420 						type = "VertScrollBar";
421 						we = new VertScrollBar(16,s,c);
422 						break;
423 					default:
424 						break;
425 				}
426 				eventStack.addToTop(new PlacementEvent(we, type, s));
427 				typeSel = ElementType.NULL;
428 				//updateElementList;
429 			}
430 		} else {
431 			if (state == ButtonState.Pressed) {
432 				if(!moveElemMode && elements.getPtr(selection)) {
433 					if (elements[selection].element.getPosition.isBetween(x,y)) {
434 						initElemMove;
435 						
436 					} else if (elements[selection].element.getPosition.right <= x + 1 && elements[selection].element.getPosition.bottom <= y + 1) {
437 						initElemResize;
438 						
439 					}
440 				}
441 			} else {
442 				finalizeElemMove;
443 				finalizeElemResize;
444 			}
445 		}
446 	}
447 	public void dragEvent(int x, int y, int relX, int relY, uint button) {
448 		if (moveElemMode) {
449 			Box temp = elements[selection].element.getPosition;
450 			if(temp.left + relX < 0) relX -= temp.left + relX;
451 			if(temp.right + relX >= dw.getPosition.width) relX -= (temp.right + relX) - dw.getPosition.width;
452 			if(temp.top + relY < 0) relY -= temp.top + relY;
453 			if(temp.bottom + relY >= dw.getPosition.height) relY -= (temp.bottom + relY) - dw.getPosition.height;
454 			temp.relMove(relX, relY);
455 			elements[selection].element.setPosition(temp);
456 			dw.draw();
457 		} else if (resizeMode) {
458 			x0 = x;
459 			y0 = y;
460 			dw.drawSelection(Box(elements[selection].element.getPosition.left, elements[selection].element.getPosition.top, x0, y0));
461 		} else if (typeSel != ElementType.NULL) {
462 			dw.drawSelection(Box(x0, y0, x, y), true);
463 		}
464 	}
465 
466 	public void updateElementList(){
467 		tlw.objectList.clear();
468 		tlw.objectList ~= new ListViewItem(16, ["Window"d, ""d]);
469 		foreach(s; elements){
470 			tlw.objectList ~= new ListViewItem(16, [conv.to!dstring(s.type), conv.to!dstring(s.name)]);
471 		}
472 		tlw.objectList.refresh();
473 	}
474 	public void updatePropertyList(){
475 		import sdlang;
476 		import std.utf;
477 		tlw.propList.clear();
478 		if(elements.getPtr(selection) !is null){
479 			string classname = elements[selection].type;
480 			tlw.propList ~= [new ListViewItem(16, ["name"d, conv.to!dstring(selection)], [TextInputFieldType.None, 
481 					TextInputFieldType.Text]), new ListViewItem(16, ["source"d, conv.to!dstring(wserializer.getValue(selection, 
482 					"source")[0].get!string())], [TextInputFieldType.None, TextInputFieldType.Text])];
483 			if(classname == "Label" || classname == "TextBox" || classname == "Button" || classname == "CheckBox" ||
484 					classname == "RadioButton"){
485 				tlw.propList ~= new ListViewItem(16, ["text", toUTF32(wserializer.getValue(selection, "text")[0].get!string())], 
486 						[TextInputFieldType.None, TextInputFieldType.Text]);
487 			}
488 			Value[] pos0 = wserializer.getValue(selection, "position");
489 			dstring pos1 = conv.to!dstring(pos0[0].get!int) ~ ";" ~ conv.to!dstring(pos0[1].get!int) ~ ";" ~
490 					conv.to!dstring(pos0[2].get!int) ~ ";" ~ conv.to!dstring(pos0[3].get!int) ~ ";";
491 			tlw.propList ~= new ListViewItem(16, ["position", pos1], [TextInputFieldType.None, TextInputFieldType.Text]);
492 			switch(classname){
493 				/+case "SmallButton", "SmallCheckBox", "SmallRadioButton", "CheckBox", "RadioButton":
494 					tlw.propList ~= new ListViewItem(16, [
495 							"iconPressed", conv.to!dstring(wserializer.getValue(selection, "iconPressed")[0].get!string())],
496 							[TextInputFieldType.None, TextInputFieldType.Text]);
497 					tlw.propList ~= new ListViewItem(16, [
498 							"iconUnpressed", conv.to!dstring(wserializer.getValue(selection, "iconUnpressed")[0].get!string())],
499 							[TextInputFieldType.None, TextInputFieldType.Text]);
500 					break;+/
501 				case "ListView":
502 					tlw.propList ~= new ListViewItem(16, ["header", "[...]"]);
503 					break;
504 				case "HorizScrollBar", "VertScrollBar":
505 					tlw.propList ~= [
506 							new ListViewItem(16, ["maxValue",conv.to!dstring(wserializer.getValue(selection,"maxValue")[0].get!int())],
507 							[TextInputFieldType.None, TextInputFieldType.Integer])];
508 					break;
509 				default:
510 					break;
511 			}
512 			
513 		}else{
514 			tlw.propList ~= [new ListViewItem(16, ["name", conv.to!dstring(wserializer.getWindowName)], 
515 					[TextInputFieldType.None, TextInputFieldType.Text]),
516 					new ListViewItem(16, ["title", toUTF32(wserializer.getWindowValue("title")[0].get!string())], 
517 					[TextInputFieldType.None, TextInputFieldType.Text]),
518 					new ListViewItem(16, ["size:x", conv.to!dstring(wserializer.getWindowValue("size:x")[0].get!int())], 
519 					[TextInputFieldType.None, TextInputFieldType.Integer]),
520 					new ListViewItem(16, ["size:y", conv.to!dstring(wserializer.getWindowValue("size:y")[0].get!int())], 
521 					[TextInputFieldType.None, TextInputFieldType.Integer])];
522 
523 			
524 		}
525 		tlw.propList.refresh();
526 	}
527 
528 	public void selectEvent(WindowElement we){
529 		foreach (s; elements) {
530 			if (s.element is we) {
531 				selection = s.name;
532 				updatePropertyList;
533 				return;
534 			}
535 		}
536 	}
537 
538 	public void menuEvent(Event ev){
539 		import pixelperfectengine.concrete.dialogs.filedialog : FileDialog;
540 		string source = (cast(MenuEvent)ev).itemSource;
541 		switch(source){
542 			case "export":
543 				ewh.addWindow(new FileDialog("Export Window"d, "export", &onExportWindow,
544 						[FileDialog.FileAssociationDescriptor("D file"d, ["*.d"])], "./", true));
545 				break;
546 			case "saveAs":
547 				ewh.addWindow(new FileDialog("Save Window as"d, "windowsaver", &onSaveFileAs,
548 						[FileDialog.FileAssociationDescriptor("SDL file"d, ["*.sdl"])], "./", true));
549 				break;
550 			case "save":
551 				if(wserializer.getFilename){
552 					wserializer.store;
553 				}else{
554 					ewh.addWindow(new FileDialog("Save Window as"d, "windowsaver", &onSaveFileAs,
555 							[FileDialog.FileAssociationDescriptor("SDL file"d, ["*.sdl"])], "./", true));
556 				}
557 				break;
558 			case "load":
559 				//stdio.writeln(&onLoadFile);
560 				ewh.addWindow(new FileDialog("Load Window"d, "windowloader", &onLoadFile,
561 						[FileDialog.FileAssociationDescriptor("SDL file"d, ["*.sdl"])], "./"));
562 				break;
563 			case "undo":
564 				eventStack.undo;
565 				break;
566 			case "redo":
567 				eventStack.redo;
568 				break;
569 			case "exit":
570 				onQuit;
571 				break;
572 			case "Label":
573 				typeSel = ElementType.Label;
574 				break;
575 			case "Button":
576 				typeSel = ElementType.Button;
577 				break;
578 			case "TextBox":
579 				typeSel = ElementType.TextBox;
580 				break;
581 			case "ListView":
582 				typeSel = ElementType.ListView;
583 				break;
584 			case "CheckBox":
585 				typeSel = ElementType.CheckBox;
586 				break;
587 			case "RadioButton":
588 				typeSel = ElementType.RadioButton;
589 				break;
590 			case "MenuBar":
591 				typeSel = ElementType.MenuBar;
592 				break;
593 			case "HSlider":
594 				typeSel = ElementType.HSlider;
595 				break;
596 			case "VSlider":
597 				typeSel = ElementType.VSlider;
598 				break;
599 			default:
600 				break;
601 		}
602 	}
603 	public void delElement() {
604 		if(selection != "Window" && selection.length) {
605 			eventStack.addToTop(new DeleteEvent(elements[selection]));
606 			selection = "Window";
607 		}
608 	}
609 	public void initElemMove() {
610 		if(selection != "Window" && selection.length) {
611 			moveElemMode = true;
612 			moveElemOrig = elements[selection].element.getPosition;
613 		}
614 	}
615 	public void deinitElemMove() {
616 		if(moveElemMode) {
617 			moveElemMode = false;
618 			elements[selection].element.setPosition(moveElemOrig);
619 			dw.draw();
620 		}
621 	}
622 	public void finalizeElemMove() {
623 		if(moveElemMode) {
624 			moveElemMode = false;
625 			eventStack.addToTop(new MoveElemEvent(elements[selection].element.getPosition, moveElemOrig, selection));
626 		}
627 	}
628 	public void initElemResize() {
629 		if(selection == "Window") {
630 			
631 			
632 		} else if(selection.length) {
633 			resizeMode = true;
634 		}
635 	}
636 	public void deinitElemResize() {
637 		if(resizeMode) {
638 			resizeMode = false;
639 		}
640 	}
641 	public void finalizeElemResize() {
642 		if(resizeMode) {
643 			resizeMode = false;
644 			if(selection == "Window") {
645 
646 			} else if (selection.length) {
647 				if (x0 <= elements[selection].element.getPosition.left || y0 <= elements[selection].element.getPosition.top) {
648 					ewh.message("Resize error!", "Out of bound resizing!");
649 				} else {
650 					const Box newPos = Box(elements[selection].element.getPosition.left, elements[selection].element.getPosition.top, x0, y0);
651 					eventStack.addToTop(new MoveElemEvent(newPos, selection));
652 				}
653 			}
654 		}
655 	}
656 	public void whereTheMagicHappens(){
657 		while(!onExit){
658 			mainRaster.refresh();
659 			inputH.test();
660 		}
661 	}
662 	public void onQuit(){
663 		onExit = true;
664 	}
665 	public void controllerRemoved(uint ID){}
666 	public void controllerAdded(uint ID){}
667 	//public void keyPressed(string ID, uint timestamp, uint devicenumber, uint devicetype) {
668 	public void axisEvent(uint id, BindingCode code, uint timestamp, float value) {
669 
670 	}
671 	public void keyEvent(uint id, BindingCode code, uint timestamp, bool isPressed) {
672 		import pixelperfectengine.system.etc : hashCalc;
673 		if (isPressed) {
674 			switch(id){
675 				case hashCalc("undo"):
676 					eventStack.undo;
677 					break;
678 				case hashCalc("redo"):
679 					eventStack.redo;
680 					break;
681 				case hashCalc("delete"):
682 					delElement();
683 
684 					break;
685 				case hashCalc("sysesc"):
686 					deinitElemMove;
687 					deinitElemResize;
688 					typeSel = ElementType.NULL;
689 					break;
690 				case hashCalc("Label"):
691 					typeSel = ElementType.Label;
692 					break;
693 				case hashCalc("Button"):
694 					typeSel = ElementType.Button;
695 					break;
696 				case hashCalc("TextBox"):
697 					typeSel = ElementType.TextBox;
698 					break;
699 				case hashCalc("ListView"):
700 					typeSel = ElementType.ListView;
701 					break;
702 				case hashCalc("CheckBox"):
703 					typeSel = ElementType.CheckBox;
704 					break;
705 				case hashCalc("RadioButton"):
706 					typeSel = ElementType.RadioButton;
707 					break;
708 				case hashCalc("MenuBar"):
709 					typeSel = ElementType.MenuBar;
710 					break;
711 				case hashCalc("HSlider"):
712 					typeSel = ElementType.HSlider;
713 					break;
714 				case hashCalc("VSlider"):
715 					typeSel = ElementType.VSlider;
716 					break;
717 				default:
718 					break;
719 			}
720 		}
721 	}
722 	
723 }