source: EcnlProtoTool/trunk/webapp/webmrbc/MainMenuView.cs@ 273

Last change on this file since 273 was 273, checked in by coas-nagasima, 7 years ago

ソフトウェア情報を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 11.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Bridge;
6using Bridge.Bootstrap3;
7using Bridge.Html5;
8using Bridge.jQuery2;
9using Bridge.Text.RegularExpressions;
10
11namespace WebMrbc
12{
13 public class MainMenuView
14 {
15 private Tuple<string, string>[] _BlockIds;
16 private Dictionary<string, string> _Files = new Dictionary<string, string>();
17 private Uint8Array _CFile;
18 private Uint8Array _MrbFile;
19 private string filename;
20 jQuery el;
21 IClassWorkspace current;
22
23 public MainMenuView()
24 {
25 el = new jQuery("#main-menu");
26
27 var filedialog = (HTMLInputElement)Document.GetElementById("load-file");
28 filedialog.OnChange += (ele) => {
29 if (filedialog.Value == null)
30 return;
31
32 onUpload(filedialog);
33 };
34
35 // HACK: if don't do below, can't open submenu on Chromium on Raspberry Pi
36 jQuery.Select(".dropdown-toggle").Dropdown();
37
38 Views.ClassSelectorView.Selected += ClassSelectorView1_Selected;
39 Views.ClassSelectorView.Removed += ClassSelectorView1_Removed;
40 Views.ClassSelectorView.MarkClicked += ClassSelectorView1_MarkClicked;
41
42 current = Views.ClassSelectorView.Current;
43 }
44
45 private void ToRubyAll()
46 {
47 foreach (var item in Collections.ClassWorkspaces) {
48 var view = item.View;
49 if (view.Changed || item.RubyCode == null) {
50 var rubyfile = item.Identifier + ".rb";
51 var workspace = item.Workspace;
52 var code = item.ToCode(rubyfile);
53
54 _Files[rubyfile] = code;
55 }
56 }
57 }
58
59 private void GetCompileArgs(string[] rubyfiles, string path, string ext, ref string outfile)
60 {
61 var i = rubyfiles.Length;
62 rubyfiles.Push("placeholder.out");
63
64 if (!path.EndsWith("/"))
65 path = path + "/";
66
67 ToRubyAll();
68
69 var list = new IClassWorkspace[0];
70 list.Push(Collections.LocalNode);
71 foreach (var item in Collections.ClassWorkspaces) {
72 if ((item == Collections.LocalNode)
73 || (item == Collections.EcnlTaskWorkspace)
74 || (item == Collections.MainLoopWorkspace))
75 continue;
76 list.Push(item);
77 }
78 list.Push(Collections.EcnlTaskWorkspace);
79 list.Push(Collections.MainLoopWorkspace);
80
81 foreach (var file in list) {
82 rubyfiles.Push(path + file.Identifier + ".rb");
83 }
84
85 if (String.IsNullOrEmpty(outfile) && (i + 1 < rubyfiles.Length))
86 outfile = rubyfiles[i + 1].Replace(new Regex(".rb$", "g"), ext.StartsWith(".") ? ext : ("." + ext));
87 rubyfiles[i] = outfile;
88 }
89
90 public void onHelp()
91 {
92 App.Module = new Mruby();
93
94 var args = new[] { "mrbc", "--help" };
95 App.Module.run(args);
96 onOutputMode();
97 }
98
99 public void onVersion()
100 {
101 App.Module = new Mruby();
102
103 var args = new[] { "mrbc", "--version" };
104 App.Module.run(args);
105 onOutputMode();
106 }
107
108 void Mruby_PreRun()
109 {
110 var FS = App.Module.GetFileSystem();
111
112 FS.createFolder("/", "src", true, false);
113 FS.createFolder("/", "build", true, true);
114
115 foreach (var f in _Files) {
116 FS.writeFile("/src/" + f.Key, f.Value);
117 }
118 }
119
120 void Mruby_ToCPostRun()
121 {
122 var FS = App.Module.GetFileSystem();
123
124 var filename = "/build/main_rb.c";
125 var stt = FS.stat(filename);
126 var stream = FS.open(filename, "r");
127 var buf = new Uint8Array(stt.size);
128 FS.read(stream, buf, 0, stt.size, 0);
129 FS.close(stream);
130
131 _CFile = buf;
132 }
133
134 void Mruby_ToMrbPostRun()
135 {
136 var FS = App.Module.GetFileSystem();
137
138 var filename = "/build/main_rb.mrb";
139 var stt = FS.stat(filename);
140 var stream = FS.open(filename, "r");
141 var buf = new Uint8Array(stt.size);
142 FS.read(stream, buf, 0, stt.size, 0);
143 FS.close(stream);
144
145 _MrbFile = buf;
146 }
147
148 public void onCompileToC()
149 {
150 var args = new[] { "mrbc", "-Bmain_rb_code", "-e", "-o" };
151 string mrbfile = "/build/main_rb.c";
152 GetCompileArgs(args, "/src/", "c", ref mrbfile);
153
154 _CFile = null;
155 App.Module = new Mruby();
156 App.Module.preRun.Push(new Action(Mruby_PreRun));
157 App.Module.postRun.Push(new Action(() => {
158 Mruby_ToCPostRun();
159
160 if (_CFile != null) {
161 App.WriteLine(App.Module.UTF8ArrayToString(_CFile, 0));
162
163 var blob = new Blob(new BlobDataObject[] { _CFile.Buffer },
164 new BlobPropertyBag() { Type = "text/plain;charset=utf-8" });
165 Script.Call("saveAs", blob, "main_rb.c");
166 }
167 }));
168 App.Module.run(args);
169 onOutputMode();
170 }
171
172 public void onCompileToMrb()
173 {
174 var args = new[] { "mrbc", "-e", "-o" };
175 string mrbfile = "/build/main_rb.mrb";
176 GetCompileArgs(args, "/src/", "mrb", ref mrbfile);
177
178 _MrbFile = null;
179 App.Module = new Mruby();
180 App.Module.preRun.Push(new Action(Mruby_PreRun));
181 App.Module.postRun.Push(new Action(() => {
182 Mruby_ToMrbPostRun();
183
184 if (_MrbFile != null) {
185 App.WriteLine((new HexDump(_MrbFile, 16)).ToString());
186
187 var blob = new Blob(new BlobDataObject[] { _MrbFile.Buffer },
188 new BlobPropertyBag() { Type = "application/octet-stream" });
189 Script.Call("saveAs", blob, "main_rb.mrb");
190 }
191 }));
192 App.Module.run(args);
193 onOutputMode();
194 }
195
196 public void onBlockMode()
197 {
198 SelectBlockTab();
199 }
200
201 public void onRubyMode()
202 {
203 UpdateCode();
204
205 SelectRubyTab();
206 }
207
208 public void onOutputMode()
209 {
210 SelectOutputTab();
211 App.Term.fit();
212 }
213
214 public void onLoad()
215 {
216 var filedialog = (HTMLInputElement)Document.GetElementById("load-file");
217 filedialog.Value = null;
218 filedialog.Click();
219 }
220
221 private void onUpload(HTMLInputElement filedialog)
222 {
223 var view = Views.ClassSelectorView.Current;
224 if (view == null)
225 return;
226
227 var file = filedialog.Files[0];
228 try {
229 var reader = Script.Write<dynamic>("new FileReader()");
230 reader.onload = new Action<object>((e) => {
231 var xml = Blockly.Xml.textToDom(reader.result);
232 Blockly.Xml.domToWorkspace(xml, view.Workspace);
233 });
234 reader.readAsText(file);
235 }
236 catch (Exception e) {
237 App.WriteLine(e.ToString());
238 }
239 }
240
241 public void onSaveWorkspace()
242 {
243 var zip = Script.Write<dynamic>("new JSZip()");
244 foreach (var e in Collections.ClassWorkspaces) {
245 var xml = Blockly.Xml.workspaceToDom(e.Workspace);
246 zip.file(e.Identifier + ".xml", xml.OuterHTML);
247 }
248 var blob = Script.Write<object>("zip.generate({ type: \"blob\" })");
249 Script.Call("saveAs", blob, "Workspace.zip");
250 }
251
252 public void onSaveRuby()
253 {
254 ToRubyAll();
255
256 var zip = Script.Write<dynamic>("new JSZip()");
257 foreach (var f in _Files) {
258 zip.file(f.Key, f.Value);
259 }
260 var blob = Script.Write<object>("zip.generate({ type: \"blob\" })");
261 Script.Call("saveAs", blob, "Workspace.zip");
262 }
263
264 public void onReset()
265 {
266 }
267
268 public void onRun()
269 {
270 var args = new[] { "mrbc", "-e", "-o" };
271 string mrbfile = "/build/main_rb.mrb";
272 GetCompileArgs(args, "/src/", "mrb", ref mrbfile);
273
274 _MrbFile = null;
275 App.Module = new Mruby();
276 App.Module.preRun.Push(new Action(Mruby_PreRun));
277 App.Module.postRun.Push(new Action(() => {
278 Mruby_ToMrbPostRun();
279
280 if (_MrbFile == null)
281 return;
282
283 App.WriteLine((new HexDump(_MrbFile, 16)).ToString());
284
285 var btn = jQuery.Select("#message-button");
286 btn.Hide();
287 var el = jQuery.Select("#message-modal");
288 el.Modal(new ModalOptions() {
289 Backdrop = "static",
290 Show = true
291 });
292 var textel = jQuery.Select("#message-text");
293 textel.Text("実行ファイルを転送しています。");
294
295 jQuery.Ajax(new AjaxOptions() {
296 Url = "/upload/main.mrb",
297 Type = "POST",
298 DataType = "*",
299 Data = _MrbFile.Buffer,
300 ProcessData = false,
301 ContentType = false,
302 Success = (data, textStatus, request) => {
303 btn.Show();
304 App.WriteLine(textStatus);
305 textel.Text("実行を開始しました。");
306 },
307 Error = (request, textStatus, error) => {
308 btn.Show();
309 App.WriteLine(textStatus);
310 textel.Text("実行に失敗しました。");
311 }
312 });
313 }));
314 App.Module.run(args);
315 }
316
317 public void onMessageClose()
318 {
319 var el = jQuery.Select("#message-modal");
320 el.Modal(ModalOperation.Hide);
321 }
322
323 public void onInformationOpen()
324 {
325 jQuery.Ajax(new AjaxOptions() {
326 Url = "/information.json",
327 DataType = "json",
328 Success = (data, textStatus, request) => {
329 var items = (dynamic[])data;
330
331 var listview = jQuery.Select("#software-list");
332 listview.Html("");
333
334 foreach (var item in items) {
335 string title = item.title;
336 string version = item.version;
337 string link = item.link;
338 string note = item.note;
339
340 var a = new jQuery("<a>").Attr("class", "list-group-item");
341 a.Append(new jQuery("<h4>").Attr("class", "list-group-item-heading").Text(title));
342 if (String.IsNullOrEmpty(link)) {
343 a.Attr("href", "#");
344 }
345 else {
346 a.Attr("href", link);
347 a.Attr("target", "_blank");
348 }
349 a.Append(new jQuery("<p>").Attr("class", "list-group-item-text").Text("Version " + version));
350 if (!String.IsNullOrEmpty(note))
351 a.Append(new jQuery("<p>").Attr("class", "list-group-item-text").Text(note));
352 listview.Append(a);
353 }
354
355 var el = jQuery.Select("#information-modal");
356 el.Modal(ModalOperation.Show);
357 },
358 Error = (request, textStatus, error) => {
359 },
360 });
361 }
362
363 public void onInformationClose()
364 {
365 var el = jQuery.Select("#information-modal");
366 el.Modal(ModalOperation.Hide);
367 }
368
369 private static void SelectBlockTab()
370 {
371 jQuery.Select("#tabs a[href='#block-tab']").Tab(TabOperation.Show);
372 //jQuery.Select(".blocklyToolboxDiv").Show();
373 }
374
375 private static void SelectRubyTab()
376 {
377 jQuery.Select("#tabs a[href='#ruby-tab']").Tab(TabOperation.Show);
378 //jQuery.Select(".blocklyToolboxDiv").Hide();
379 }
380
381 private static void SelectOutputTab()
382 {
383 jQuery.Select("#tabs a[href='#output-tab']").Tab(TabOperation.Show);
384 //jQuery.Select(".blocklyToolboxDiv").Hide();
385 }
386
387 private void ClassSelectorView1_Selected(object sender, EventArgs e)
388 {
389 var item = Views.ClassSelectorView.Current;
390 if (item == null) {
391 UpdateCode();
392
393 SelectRubyTab();
394 }
395 else {
396 var view = item.View;
397 view.Show();
398
399 SelectBlockTab();
400
401 foreach (var i in Collections.ClassWorkspaces) {
402 if (i != item) {
403 i.View.Hide();
404 }
405 }
406 }
407
408 if (current != item) {
409 current?.View.Hide();
410 }
411 current = item;
412 }
413
414 private void ClassSelectorView1_Removed(object sender, ItemRemovedEventArgs e)
415 {
416 var view = e.Item.View;
417 view.Dispose();
418 }
419
420 private void ClassSelectorView1_MarkClicked(object sender, EventArgs e)
421 {
422 }
423
424 private void UpdateCode()
425 {
426 string code = "";
427 var item = Views.ClassSelectorView.Current;
428 if (item != null) {
429 var view = item.View;
430 if (view.Changed || item.RubyCode == null) {
431 var rubyfile = item.Identifier + ".rb";
432 var workspace = item.Workspace;
433 code = item.ToCode(rubyfile);
434
435 _Files[rubyfile] = code;
436 this.filename = rubyfile;
437 }
438 else {
439 code = _Files[item.RubyCode.filename];
440 this.filename = item.RubyCode.filename;
441 }
442 }
443 App.CodeEditor.setValue(code);
444 App.CodeEditor.gotoLine(0, 0);
445 }
446
447 internal BlocklyView NewBlocklyView(string identifier)
448 {
449 return new BlocklyView(identifier);
450 }
451
452 internal void RemoveEObjectWorkspace(IClassWorkspace item)
453 {
454 var view = item.View;
455 view.Dispose();
456 }
457 }
458}
Note: See TracBrowser for help on using the repository browser.