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