1 module windows.resizemap;
2 
3 import PixelPerfectEngine.concrete.window;
4 import PixelPerfectEngine.graphics.common;
5 import PixelPerfectEngine.map.mapformat;
6 import std.conv;
7 import document;
8 
9 public class ResizeMap : Window {
10 	Label label1;
11 	Label label2;
12 	Label label3;
13 	Label label4;
14 	CheckBox checkBox_repeat;
15 	RadioButtonGroup origin;
16 	RadioButton[9] originSelectors;
17 	Panel originPanel;
18 	TextBox mX;
19 	TextBox mY;
20 	TextBox offsetX;
21 	TextBox offsetY;
22 	Button button_ok;
23 	int x, y, targetLayer;
24 	MapDocument targetDoc;
25 	this(MapDocument targetDoc) {
26 		import PixelPerfectEngine.graphics.layers : ITileLayer;
27 		super(Coordinate(0, 0, 195, 120), "Resize Map");
28 		targetLayer = targetDoc.selectedLayer;
29 		ITileLayer layer = cast(ITileLayer)targetDoc.mainDoc.layeroutput[targetLayer];
30 		x = layer.getMX;
31 		y = layer.getMY;
32 		
33 		this.targetDoc = targetDoc;
34 		label1 = new Label("mX:", "", Coordinate(5, 22, 80, 38));
35 		addElement(label1);
36 		label2 = new Label("mY:", "", Coordinate(5, 42, 80, 58));
37 		addElement(label2);
38 		label3 = new Label("offsetX:", "", Coordinate(5, 62, 80, 78));
39 		addElement(label3);
40 		label4 = new Label("offsetY:", "", Coordinate(5, 82, 80, 98));
41 		addElement(label4);
42 		checkBox_repeat = new CheckBox("Pattern repeat", "repeat", Coordinate(5, 102, 135, 118));
43 		addElement(checkBox_repeat);
44 		mX = new TextBox(to!dstring(x), "mX", Coordinate(80, 20, 135, 38));
45 		addElement(mX);
46 		mX.onTextInput = &checkTextInput;
47 		mY = new TextBox(to!dstring(y), "mY", Coordinate(80, 40, 135, 58));
48 		addElement(mY);
49 		mY.onTextInput = &checkTextInput;
50 		offsetX = new TextBox("0", "offsetX", Coordinate(80, 60, 135, 78));
51 		addElement(offsetX);
52 		offsetX.onTextInput = &checkTextInput;
53 		offsetY = new TextBox("0", "offsetY", Coordinate(80, 80, 135, 98));
54 		addElement(offsetY);
55 		offsetY.onTextInput = &checkTextInput;
56 		button_ok = new Button("Ok", "button_ok", Coordinate(140, 102, 190, 118));
57 		addElement(button_ok);
58 		button_ok.onMouseLClick = &button_ok_onClick;
59 		//originPanel = new Panel("Origin:", "", Coordinate(140, 20, 190, 100));
60 		//addElement(originPanel);
61 		origin = new RadioButtonGroup();
62 		for(int iy ; iy < 3 ; iy++) {
63 			for(int ix ; ix < 3 ; ix++) {
64 				const Coordinate rbPos = Coordinate(142 + (16*ix), 40 + (16*iy), 142 + 16 + (16*ix), 40 + 16 + (16*iy));
65 				RadioButton rb = new RadioButton("radioButtonB", "radioButtonA",to!string(ix) ~ to!string(iy), rbPos, origin);
66 				originSelectors[ix + (iy * 3)] = rb;
67 				addElement(rb);
68 			}
69 		}
70 		origin.latch(originSelectors[0]);
71 	}
72 	private void checkTextInput(Event ev) {
73 		import std..string : isNumeric;
74 		WindowElement src = cast(WindowElement)ev.sender;
75 		dstring str = src.getText.text;
76 		if(str[$-1] == '%') str = str[0..$-1];
77 		if(!isNumeric(str)) {
78 			switch (src.getSource) {
79 				case "mX":
80 					mX.setText(to!dstring(x));
81 					break;
82 				case "mY":
83 					mY.setText(to!dstring(y));
84 					break;
85 				case "offsetX":
86 					offsetX.setText("0");
87 					break;
88 				case "offsetY":
89 					offsetY.setText("0");
90 					break;
91 				default:
92 					debug assert(0, "Wrong source value");
93 					else break;
94 			}
95 			handler.message("Invalid data!", "Please enter numeric values with optional \'%\' symbol at the end!");
96 		}
97 	}
98 	private void button_ok_onClick(Event ev) {
99 		import editorevents : ResizeTileMapEvent;
100 		int calcMValue(int offset, int oldSize, int newSize) @safe pure nothrow @nogc {
101 			return offset + (newSize/2 - oldSize/2);
102 		}
103 		int calcRValue(int offset, int oldSize, int newSize) @safe pure nothrow @nogc {
104 			return offset + (newSize - oldSize);
105 		}
106 		int oX = to!int(offsetX.getText.text), oY = to!int(offsetY.getText.text);
107 		//int tX = to!int(this.mX.getText.text), tY = to!int(this.mY.getText.text);
108 		int tX, tY;
109 		if(offsetX.getText.text[$-1] == '%') 
110 			tX = cast(int)(x * (to!double(offsetX.getText.text[0..$-1]) / 100.0));
111 		else tX = to!int(mX.getText.text);
112 		if(offsetY.getText.text[$-1] == '%') 
113 			tX = cast(int)(y * (to!double(offsetY.getText.text[0..$-1]) / 100.0));
114 		else tY = to!int(mY.getText.text);
115 		switch(origin.value[0]) {
116 			case '1':
117 				oX = calcMValue(oX,x,tX);
118 				break;
119 			case '2':
120 				oX = calcRValue(oX,x,tX);
121 				break;
122 			default: break;
123 		}
124 		switch(origin.value[1]) {
125 			case '1':
126 				oY = calcMValue(oY,y,tY);
127 				break;
128 			case '2':
129 				oY = calcRValue(oY,y,tY);
130 				break;
131 			default: break;
132 		}
133 		ResizeTileMapEvent rtme = new ResizeTileMapEvent([x, y, oX, oY, tX, tY], targetDoc, targetLayer, 
134 				checkBox_repeat.isChecked);
135 		targetDoc.events.addToTop(rtme);
136 		targetDoc.outputWindow.updateRaster();
137 		this.close();
138 	}
139 }