1 module gui;
2 
3 import qte5;
4 
5 import wireworld;
6 
7 // состояние мира
8 WireWorld!(200,85) wireWorld;
9 
10 extern(C)
11 {
12     void onTimerTick(MainForm* mainFormPointer) 
13     {
14         (*mainFormPointer).runTimer;
15     }
16 
17      void onStartButton(MainForm* mainFormPointer) 
18     {
19         (*mainFormPointer).runStart;
20     }
21 
22     void onStopButton(MainForm* mainFormPointer) 
23     {
24         (*mainFormPointer).runStop;
25     }
26 
27     void onLoadButton(MainForm* mainFormPointer) 
28     {
29         (*mainFormPointer).runLoad;
30     }
31 }
32 
33 extern(C)
34 {
35     void onDrawStep(QWireWorld* wireWorldPointer, void* eventPointer, void* painterPointer) 
36     { 
37         (*wireWorldPointer).runDraw(eventPointer, painterPointer);
38     }
39 }
40 
41 class QWireWorld : QWidget
42 {
43     private
44     {
45         QWidget parent;
46     }
47 
48     this(QWidget parent)
49     {
50         wireWorld = new WireWorld!(200,85);
51         super(parent);
52         this.parent = parent;
53         setStyleSheet(`background : white`);
54         setPaintEvent(&onDrawStep, aThis);
55         
56     }
57 
58     void runDraw(void* eventPointer, void* painterPointer)
59     {
60       
61         QPainter painter = new QPainter('+', painterPointer);
62 
63         wireWorld.drawWorld(painter, 10, 10);
64        
65         painter.end;
66     }
67 }
68  
69 // псевдонимы под Qt'шные типы
70 alias WindowType = QtE.WindowType;
71 
72 // основное окно
73 class MainForm : QWidget
74 {
75     private
76     {
77         QVBoxLayout mainBox;
78         QWireWorld box0;
79         QPushButton button, button0, button1;
80         QTimer timer;
81         QAction action, action0, action1, action2;
82     }
83 
84    
85     this(QWidget parent, WindowType windowType) 
86 	{
87 		super(parent, windowType); 
88 		resize(700, 500);
89 		setWindowTitle("QWireWorld");
90 
91         mainBox = new QVBoxLayout(this);
92 
93         box0 = new QWireWorld(this);
94         box0.saveThis(&box0);
95 
96 
97        	button = new QPushButton("Load world", this);
98         button0 = new QPushButton("Start", this);
99         button1 = new QPushButton("Stop", this);
100         
101         timer = new QTimer(this);
102         timer.setInterval(100); 
103 
104         action = new QAction(this, &onLoadButton, aThis);
105         connects(button, "clicked()", action, "Slot()");
106 
107         action0 = new QAction(this, &onTimerTick, aThis);
108         connects(timer, "timeout()", action0, "Slot()");
109 
110         action1 = new QAction(null, &onStartButton, aThis);
111         action2 = new QAction(null, &onStopButton, aThis);
112         
113         connects(button0, "clicked()", action1, "Slot()");
114         connects(button1, "clicked()", action2, "Slot()");
115         connects(button0, "clicked()", timer, "start()");
116         connects(button1, "clicked()", timer, "stop()");
117 
118         mainBox
119             .addWidget(box0)
120             .addWidget(button)
121             .addWidget(button0)
122             .addWidget(button1);
123 
124         setLayout(mainBox);
125     }
126 
127     void runTimer()
128     {
129     	wireWorld.execute;
130         box0.update;
131     }
132 
133     void runStart()
134     {
135         button0.setEnabled(false);
136         button1.setEnabled(true);
137     }
138 
139     void runStop()
140     {
141         button0.setEnabled(true);
142         button1.setEnabled(false);
143     }
144 
145     void runLoad()
146     {
147     	import std.algorithm;
148     	import std.file;
149     	import std.range;
150 		import std.stdio;
151 		import std..string;
152 
153     	QFileDialog fileDialog = new QFileDialog('+', null);
154         string filename = fileDialog.getOpenFileNameSt("Open WireWorld File", "", "*.csv *.txt");
155 
156         if (!filename.empty)
157         {
158         	
159         	wireWorld.clearWorld;
160 
161         	auto formatCSVString(string s)
162 			{
163 				import std.algorithm;
164 				import std..string;
165 
166 				string replaceByE(string s)
167 				{
168 					return (s == "") ? "e" : s;
169 				}
170 
171 				return s
172 						.split(";")
173 						.map!(a => replaceByE(a))
174 						.join;
175 			}
176 
177         	auto content = (cast(string) std.file.read(filename))
178         								.splitLines
179         								.map!(a => formatCSVString(a))
180         								.map!(a => toLower(a))
181         								.array;
182 
183 
184 
185 	        foreach (index, s; content)
186 	        {
187 	        	for (int i = 0; i < s.length; i++)
188 	        	{
189 	        		Element element;
190 	        		
191 	        		switch (s[i])
192 	        		{
193 	        			case 'e':
194 	        				element = Element.Empty;
195 	        				break;
196 	        			case 'h':
197 	        				element = Element.Head;
198 	        				break;
199 	        			case 't':
200 	        				element = Element.Tail;
201 	        				break;
202 	        			case 'c':
203 	        				element = Element.Conductor;
204 	        				break;
205 	        			default:
206 	        				break;
207 	        		}
208 	        		wireWorld[i, index] = element;
209 	        	}
210 	        }
211         }
212     }
213 }