egra: test cosmetix
[iv.d.git] / egra / test.d
blob5bdbdb76a11825e112b205156bdb044b973db38c
1 /* E-Mail Client
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module test /*is aliced*/;
19 import arsd.simpledisplay;
21 import iv.bclamp;
22 import iv.cmdcon;
23 import iv.cmdcongl;
24 import iv.strex;
25 import iv.utfutil;
26 import iv.vfs.io;
27 import iv.vfs.util;
29 import iv.egra;
32 // ////////////////////////////////////////////////////////////////////////// //
33 static immutable string TestStyle = `
34 MainPaneWindow {
35 grouplist-divline: white;
36 grouplist-back: #222;
38 threadlist-divline: white;
39 threadlist-back: #222;
42 TitlerWindow {
43 frame: white;
44 title-back: white;
45 title-text: black;
47 back: rgb(0, 92, 0);
48 text: #7f0;
49 hotline: #7f0;
54 // ////////////////////////////////////////////////////////////////////////// //
55 //__gshared int lastWinWidth, lastWinHeight;
58 // ////////////////////////////////////////////////////////////////////////// //
59 public class TitlerWindow : SubWindow {
60 public:
61 LineEditWidget edtTitle;
62 LineEditWidget fromName;
63 LineEditWidget fromMail;
65 protected:
66 dynstring name;
67 dynstring mail;
68 dynstring folder;
69 dynstring title;
71 bool delegate (dynstring name, dynstring mail, dynstring folder, dynstring title) onSelected;
73 override void createWidgets () {
74 new SpacerWidget(2);
76 version(none) {
77 fromName = new LineEditWidget("Name:");
78 fromName.flex = 1;
80 new SpacerWidget(1);
81 fromMail = new LineEditWidget("Mail:");
82 fromMail.flex = 1;
84 new SpacerWidget(1);
85 edtTitle = new LineEditWidget("Title:");
86 edtTitle.flex = 1;
87 } else {
88 (new HBoxWidget).enter{
89 with (new HotLabelWidget("&Name:", LabelWidget.HAlign.Right)) { width = width+2; hsizeId = "editors"; }
90 new SpacerWidget(4);
91 fromName = new LineEditWidget();
92 fromName.flex = 1;
93 }.flex = 1;
95 new SpacerWidget(1);
96 (new HBoxWidget).enter{
97 with (new HotLabelWidget("&Mail:", LabelWidget.HAlign.Right)) { width = width+2; hsizeId = "editors"; }
98 new SpacerWidget(4);
99 fromMail = new LineEditWidget();
100 fromMail.flex = 1;
101 }.flex = 1;
103 new SpacerWidget(1);
104 (new HBoxWidget).enter{
105 with (new HotLabelWidget("&Title:", LabelWidget.HAlign.Right)) { width = width+2; hsizeId = "editors"; }
106 new SpacerWidget(4);
107 edtTitle = new LineEditWidget();
108 edtTitle.flex = 1;
109 }.flex = 1;
112 new SpacerWidget(4);
113 (new HBoxWidget).enter{
114 new SpacerWidget(2);
115 new SpringWidget(1);
116 with (new ButtonWidget(" O&k ")) {
117 hsizeId = "okcancel";
118 deftype = Default.Accept;
119 onAction = delegate (self) {
120 if (onSelected !is null) {
121 if (!onSelected(fromName.str, fromMail.str, folder, edtTitle.str)) return;
123 close();
126 new SpacerWidget(2);
127 with (new ButtonWidget(" Cancel ")) {
128 hsizeId = "okcancel";
129 deftype = Default.Cancel;
130 onAction = delegate (self) {
131 close();
134 new SpacerWidget(4);
135 with (new ButtonWidget(" ... ")) {
136 hsizeId = "okcancel";
137 hotkey = "M-L";
138 disabled = true;
140 new SpringWidget(1);
141 new SpacerWidget(2);
143 new SpacerWidget(4);
145 fromName.str = name;
146 fromMail.str = mail;
147 edtTitle.str = title;
149 relayoutResize();
150 centerWindow();
152 edtTitle.focus();
155 this (const(char)[] aname, const(char)[] amail, const(char)[] afolder, const(char)[] atitle) {
156 dynstring caption = "Title for "~aname~" <"~amail~">";
157 name = aname;
158 mail = amail;
159 folder = afolder;
160 title = atitle;
161 super(caption);
166 // ////////////////////////////////////////////////////////////////////////// //
167 public class TagOptionsWindow : SubWindow {
168 dynstring tagname;
170 void delegate (const(char)[] tagname) onUpdated;
172 this (const(char)[] atagname) {
173 tagname = atagname;
174 dynstring caption = "options for '"~atagname~"'";
175 super(caption);
178 override void createWidgets () {
179 LabelWidget optPath = new LabelWidget("", LabelWidget.HAlign.Center);
180 optPath.flex = 1;
182 LineEditWidget optMonthes;
183 (new HBoxWidget).enter{
184 with (new HotLabelWidget("&Monthes:", LabelWidget.HAlign.Right)) { width = width+2; /*hsizeId = "editors";*/ }
185 new SpacerWidget(4);
186 optMonthes = new LineEditWidget();
187 //optMonthes.flex = 1;
188 optMonthes.width = gxTextWidthUtf("96669");
189 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" Widget#. "));
190 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" HBoxWidget LineEditWidget#. "));
191 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" HBoxWidget> #. "));
192 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" SubWindow HBoxWidget LineEditWidget#. "));
193 //new SpringWidget(1);
194 }.flex = 1;
196 CheckboxWidget optThreaded = new CheckboxWidget("&Threaded");
197 optThreaded.flex = 1;
199 CheckboxWidget optAttaches = new CheckboxWidget("&Attaches");
200 optAttaches.flex = 1;
202 with (new RadioWidget("Radio &1")) {
203 rgroup = "rg1";
204 flex = 1;
205 id = "r1";
208 with (new RadioWidget("Radio &2")) {
209 rgroup = "rg1";
210 flex = 1;
211 checked = true;
212 id = "r2";
215 new SpacerWidget(4);
216 (new HBoxWidget).enter{
217 new SpacerWidget(2);
218 new SpringWidget(1);
219 with (new ButtonWidget(" O&k ")) {
220 hsizeId = "okcancel";
221 deftype = Default.Accept;
222 onAction = delegate (self) {
223 if (onUpdated !is null) onUpdated(tagname);
224 close();
225 auto rw = self.getSelectedRadio("rg1");
226 if (rw !is null) conwriteln("SELECTED RADIO: <", rw.id, ">");
229 new SpacerWidget(4);
230 with (new ButtonWidget(" Cancel ")) {
231 hsizeId = "okcancel";
232 deftype = Default.Cancel;
233 onAction = delegate (self) {
234 close();
237 new SpacerWidget(4);
238 with (new ButtonWidget(" ... ")) {
239 hsizeId = "okcancel";
240 hotkey = "M-L";
241 onAction = delegate (self) {
242 (new SelectCompletionWindow("", buildAutoCompletion("/home/ketmar/"), aspath:true)).onSelected = (str) {
243 conwriteln("SELECTED: <", str.getData, ">");
245 //close();
247 //disabled = true;
249 new SpringWidget(1);
250 new SpacerWidget(2);
252 new SpacerWidget(4);
254 optMonthes.focus();
256 optPath.text = "booPath";
257 optMonthes.str = "666";
259 optThreaded.enabled = false;
260 optAttaches.enabled = true;
262 optMonthes.killTextOnChar = true;
264 relayoutResize();
265 centerWindow();
266 //add(); // for "focused"
268 forEachSelector("SubWindow > RootWidget CheckboxWidget", (EgraStyledClass w) {
269 import iv.vfs.io; writeln("LEW=", typeid(w).name, "; text=", (cast(CheckboxWidget)w).title.getData);
270 //return false;
273 forEachSelector("SubWindow > RootWidget :focused", (EgraStyledClass w) {
274 import iv.vfs.io; writeln("FOCUSED=", typeid(w).name);
275 //return false;
278 foreach (HotLabelWidget c; querySelectorAll!HotLabelWidget("SubWindow > RootWidget HotLabelWidget")) {
279 import iv.vfs.io;
280 writeln("LBL: <", c.text.getData, ">");
283 { import iv.vfs.io;
284 Widget qf = querySelector(":focused");
285 if (qf !is null) writeln("QFOCUSED=", typeid(qf).name); else writeln("FUCK!");
290 // ////////////////////////////////////////////////////////////////////////// //
291 void initConsole () {
292 // //////////////////////////////////////////////////////////////////// //
293 conRegFunc!(() {
294 import core.memory : GC;
295 conwriteln("starting GC collection...");
296 GC.collect();
297 GC.minimize();
298 conwriteln("GC collection complete.");
299 })("gc_collect", "force GC collection cycle");
302 // //////////////////////////////////////////////////////////////////// //
303 conRegFunc!(() {
304 auto qww = new YesNoWindow("Quit?", "Do you really want to quit?", true);
305 qww.onYes = () { concmd("quit"); };
306 qww.addModal();
307 })("quit_prompt", "quit with prompt");
309 conRegFunc!(() {
310 new TitlerWindow("name", "mail", "folder", "title");
311 })("window_titler", "titler window test");
313 conRegFunc!(() {
314 new TagOptionsWindow("xtag");
315 })("window_tagoptions", "tag options window test");
319 // ////////////////////////////////////////////////////////////////////////// //
320 __gshared MainPaneWindow mainPane;
323 final class MainPaneWindow : SubWindow {
324 ProgressBarWidget pbar;
325 int tessType = -1;
326 AGGTesselation deftess;
327 bool timetest;
328 int lastMX = -10000, lastMY = -10000;
330 this () {
331 super(null, GxPoint(0, 0), GxSize(screenWidth, screenHeight));
332 mType = Type.OnBottom;
334 pbar = new ProgressBarWidget(rootWidget, "progress bar");
335 pbar.setMinMax(0, 100);
336 pbar.width = clientWidth-64;
337 pbar.current = 50;
338 pbar.posy = clientHeight-pbar.height-8;
339 pbar.posx = (clientWidth-pbar.width)/2;
341 deftess = gxagg.tesselator;
343 add();
346 // //////////////////////////////////////////////////////////////////// //
347 override void onPaint () {
348 if (closed) return;
350 enum guiGroupListWidth = 128;
351 enum guiThreadListHeight = 520;
353 gxFillRect(0, 0, guiGroupListWidth, screenHeight, getColor("grouplist-back"));
354 gxVLine(guiGroupListWidth, 0, screenHeight, getColor("grouplist-divline"));
356 gxFillRect(guiGroupListWidth+1, 0, screenWidth, guiThreadListHeight, getColor("threadlist-back"));
357 gxHLine(guiGroupListWidth+1, guiThreadListHeight, screenWidth, getColor("threadlist-divline"));
359 version(all) {
360 import core.stdc.math : roundf;
362 if (tessType >= 0) {
363 if (tessType > AGGTesselation.max) tessType = AGGTesselation.max;
364 gxagg.tesselator = cast(AGGTesselation)tessType;
365 } else {
366 gxagg.tesselator = deftess;
369 gxagg.beginFrame();
370 gxagg.params.width = 1.4f;
371 //gxagg.width = 1.0f;
373 float baphx = roundf((screenWidth-gxagg.BaphometDims)*0.5f)+0.5f;
374 float baphy = roundf((screenHeight-gxagg.BaphometDims)*0.5f)+0.5f;
376 import iv.pxclock;
377 ulong estt;
378 ubyte hit = 0;
379 if (timetest) {
380 timetest = false;
381 estt = 0;
382 foreach (; 0..1000) {
383 gxagg.beginFrame();
384 immutable tstt = clockMicro();
385 gxagg.renderBaphomet(baphx, baphy);
386 estt += (clockMicro()-tstt);
388 estt /= 1000;
389 gxagg.beginFrame();
390 gxagg.renderBaphomet(baphx, baphy);
391 } else {
392 immutable tstt = clockMicro();
393 gxagg.renderBaphomet(baphx, baphy);
394 estt = clockMicro()-tstt;
397 version(none) {
398 gxagg
399 .moveTo(baphx-1, baphy-1)
400 .lineTo(baphx+gxagg.BaphometDims, baphy-1)
401 .lineTo(baphx+gxagg.BaphometDims, baphy+gxagg.BaphometDims)
402 .lineTo(baphx-1, baphy+gxagg.BaphometDims)
403 .lineTo(baphx-1, baphy-1);
405 version(all) {
406 gxagg.roundedRect(baphx-1, baphy-1, gxagg.BaphometDims+1, gxagg.BaphometDims+1, 16.0f);
408 gxagg.stroke();
409 //gxagg.contour();
410 //gxagg.fill();
412 version(none) {
413 gxagg
414 .beginPath();
415 .moveTo(10, 10);
416 .lineTo(30, 20);
417 .width = 1.0f;
418 gxagg.contour();
421 hit = gxagg.hitTest(lastMX, lastMY);
424 immutable rstt = clockMicro();
425 gxagg.render(gxrgba(255, 0, 0, (tessType >= 0 ? 255 : 66)));
426 immutable fstt = clockMicro()-rstt;
427 import core.stdc.stdio; printf("total Baphomet render microsecs: %u\n", cast(uint)fstt);
430 //gxagg.endFrame(gxrgba(255, 0, 0, (tessType >= 0 ? 255 : 66)));
431 gxagg.endFrame();
434 import std.format : format;
435 string s = "tess: %s level: %d; mcsecs: %s".format(gxagg.tesselator, gxagg.bezierLimit, estt);
436 gxDrawTextUtf(200, 20, s, GxColors.k8orange);
437 if (hit) {
438 s = "hit: %3s".format(hit);
439 gxDrawTextUtf(200, 40, s, GxColors.k8orange);
444 ulong accstt = 0, fstt;
446 version(all) {
447 gxagg.beginFrame();
448 AGGMatrix tmt;
449 version(all) {
451 .rotate(deg2rad(35.0f))
452 .translate(20, 100);
453 assert(!tmt.isIdentity);
457 .translate(0.5f, 0.5f)
458 .translate(-160, 0);
460 gxagg.withTransform(tmt, {
461 gxagg.moveTo(50, 50);
462 gxagg.lineTo(60, 60);
463 gxagg.moveTo(100, 100);
464 gxagg.lineTo(140, 120);
465 version(none) {
466 // CW (because logical coords are upwards)
467 gxagg.moveTo(200, 200);
468 gxagg.lineTo(200, 100);
469 gxagg.lineTo(100, 100);
470 gxagg.lineTo(100, 200);
471 gxagg.lineTo(200, 200);
472 } else {
473 // CCW (because logical coords are upwards)
474 gxagg.moveTo(100, 100);
475 gxagg.lineTo(200, 100);
476 gxagg.lineTo(200, 200);
477 gxagg.lineTo(100, 200);
479 gxagg.closePoly();
480 //gxagg.flipOrientation = true;
481 //gxagg.dumpVertices();
484 version(all) {
485 gxagg.fill();
486 fstt = clockMicro();
487 gxagg.render(gxrgba(0, 127, 0, 127));
488 accstt += clockMicro()-fstt;
490 version(all) {
491 //gxagg.dumpVertices();
492 gxagg.stroke();
493 fstt = clockMicro();
494 gxagg.render(gxrgba(127, 0, 0, 255));
495 accstt += clockMicro()-fstt;
498 version(all) {
499 gxagg.resetDashes();
500 gxagg.addDash(4, 4);
501 gxagg.addDash(8, 8);
502 gxagg.dashStroke();
503 //gxagg.dashContour();
504 fstt = clockMicro();
505 gxagg.render(gxrgba(255, 255, 0, 255));
506 accstt += clockMicro()-fstt;
509 version(all) {
510 gxagg.paramsContour.width = 6;
511 gxagg.contour();
512 fstt = clockMicro();
513 gxagg.render(gxrgba(255, 255, 255, 255));
514 accstt += clockMicro()-fstt;
517 version(all) {
518 gxagg.flipOrientation = true;
519 gxagg.contour();
520 fstt = clockMicro();
521 gxagg.render(gxrgba(0, 255, 0, 255));
522 accstt += clockMicro()-fstt;
523 gxagg.flipOrientation = false;
526 { import core.stdc.stdio; printf("total rect render microsecs: %u\n", cast(uint)accstt); }
528 //gxagg.render(gxrgba(0, 127, 0, 127));
530 version(all) {
531 AGGVGradient3 grad;
532 gxagg
533 .beginPath()
534 .roundedRect(400.5f, 600.5f, 96, 28, 8)
535 .fill()
536 //.render(gxRGB!(192, 192, 192));
538 .render(AGGVGradient3(gxagg.rasterMinY, gxRGB!(127, 127, 127),
539 gxagg.rasterMaxY, gxRGB!(142, 142, 142),
540 20, gxRGB!(196, 196, 196)));
543 .render(AGGVGradient3(gxagg.rasterMinY, gxRGB!(255, 0, 0),
544 gxagg.rasterMaxY, gxRGB!(0, 255, 0),
545 20, gxRGB!(0, 0, 255)));
547 .render(AGGHGradient(gxagg.rasterMinX, gxRGBA!(255, 0, 0, 127),
548 gxagg.rasterMaxX, gxRGBA!(0, 255, 0, 90)));
551 version(all) {
552 accstt = 0;
553 float[4] bounds;
554 dchar dch = '@';
555 if (gxFontCharPathBounds(dch, bounds[])) {
556 //conwriteln("bounds: (", bounds[0], ",", bounds[1], ")-(", bounds[2], ",", bounds[3], ")");
557 float desthgt = 96;
558 immutable float gwdt = bounds[2]-bounds[0];
559 immutable float ghgt = bounds[3]-bounds[1];
560 float scale = desthgt/ghgt;
561 AGGMatrix tmx;
563 .scale(scale, scale)
564 .translate(-bounds[0]*scale+100.5f, -bounds[1]*scale+100.5f);
565 gxagg.withTransform(tmx, {
566 gxagg
567 .resetParams()
568 .beginPath();
569 if (gxFontCharToPath(dch)) {
570 gxagg
571 //.stroke()
572 .fill()
573 //.render(GxColors.k8orange);
574 .noop();
575 fstt = clockMicro();
576 gxagg.render(AGGVGradient3(gxagg.rasterMinY, gxRGB!(200, 73, 0),
577 gxagg.rasterMaxY, gxRGB!(255, 128, 0)));
578 accstt += clockMicro()-fstt;
580 int emb = cast(int)(4/scale);
581 float[4] ebounds;
582 gxagg
583 .beginPath();
584 if (gxFontCharPathEmboldenBounds(dch, emb, ebounds[])) {
585 immutable float ewdt = ebounds[2]-ebounds[0];
586 immutable float ehgt = ebounds[3]-ebounds[1];
587 gxagg.transform.translate(-(ewdt-gwdt)*0.5f*scale, (ehgt-ghgt)*0.5f*scale);
588 if (gxFontCharToPathEmbolden(dch, emb)) {
589 gxagg
590 .stroke()
591 .noop();
592 fstt = clockMicro();
593 gxagg.render(GxColors.green);
594 accstt += clockMicro()-fstt;
598 { import core.stdc.stdio; printf("total glyph render microsecs: %u\n", cast(uint)accstt); }
602 static if (is(typeof({immutable string s = import("xbnd.d");}))) {
603 mixin(import("xbnd.d"));
604 enum hasxbnd = true;
605 } else {
606 enum hasxbnd = false;
609 version(all) {
610 float[4] gbounds;
611 dchar gdch = '@';
612 if (gxFontCharPathBounds(gdch, gbounds[])) {
613 float desthgt = 196;
614 immutable float gwdt = gbounds[2]-gbounds[0];
615 immutable float ghgt = gbounds[3]-gbounds[1];
616 float scale = desthgt/ghgt;
617 AGGMatrix tmx;
619 .scale(scale, scale)
620 .translate(-bounds[0]*scale+200.5f, -bounds[1]*scale+200.5f);
621 gxagg.withTransform(tmx, {
622 gxagg.resetParams().beginPath();
623 if (gxFontCharToPath(gdch)) {
624 //gxagg.flipOrientation = true;
625 gxagg.paramsContour.width = 8;
626 gxagg.contourFill();
627 //gxagg.render(gxrgba(0, 155, 0, 255));
628 gxagg.render(gxagg.vgradient(gxrgb(0, 38, 0), gxrgb(0, 98, 0)));
629 gxagg.flipOrientation = false;
631 gxagg.resetParams().beginPath();
632 if (gxFontCharToPath(gdch)) {
633 gxagg.fill();
634 static if (hasxbnd) {
635 gxagg.render(AGGImgFill(0, 0, 32));
636 } else {
637 gxagg.render(gxagg.vgradient(gxrgb(255, 127, 0), gxrgb(155, 27, 0)));
644 static if (hasxbnd) xbnd();
646 gxagg.endFrame();
649 version(test_round_rect) {
650 gxClipReset();
651 gxFillRoundedRect(lastMouseX-16, lastMouseY-16, 128, 96, rrad, /*gxSolidWhite*/gxRGBA!(0, 255, 0, 127));
652 //gxDrawRoundedRect(lastMouseX-16, lastMouseY-16, 128, 96, rrad, gxRGBA!(0, 255, 0, 127));
655 drawWidgets();
658 version(test_round_rect) {
659 int rrad = 16;
662 override bool onKeyBubble (KeyEvent event) {
663 if (event.pressed) {
664 version(test_round_rect) {
665 if (event == "Plus") { ++rrad; return true; }
666 if (event == "Minus") { --rrad; return true; }
668 if (event == "C-Q") { concmd("quit_prompt"); return true; }
669 if (event == "1") { concmd("window_titler"); return true; }
670 if (event == "2") { concmd("window_tagoptions"); return true; }
671 if (event == "Minus") { pbar.current = pbar.current-1; return true; }
672 if (event == "Plus") { pbar.current = pbar.current+1; return true; }
674 if (event == "Q") { if (gxagg.bezierLimit > 1) { --gxagg.bezierLimit; widgetChanged(); } return true; }
675 if (event == "W") { if (gxagg.bezierLimit < 1000) { ++gxagg.bezierLimit; widgetChanged(); } return true; }
677 if (event == "Z") { --tessType; if (tessType < -1) tessType = -1; widgetChanged(); return true; }
678 if (event == "X") { ++tessType; widgetChanged(); return true; }
680 if (event == "T") { timetest = true; widgetChanged(); return true; }
681 //if (dbg_dump_keynames) conwriteln("key: ", event.toStr, ": ", event.modifierState&ModifierState.windows);
682 //foreach (const ref kv; mainAppKeyBindings.byKeyValue) if (event == kv.key) concmd(kv.value);
684 return false;
687 // returning `false` to avoid screen rebuilding by dispatcher
688 override bool onMouseBubble (MouseEvent event) {
689 if (event.type == MouseEventType.buttonPressed || event.type == MouseEventType.buttonReleased) {
690 if (lastMX != event.x || lastMY != event.y) {
691 lastMX = event.x;
692 lastMY = event.y;
693 //widgetChanged();
695 widgetChanged();
696 } else if (event.modifierState) {
697 // for OpenGL, this rebuilds the whole screen anyway
698 lastMX = event.x;
699 lastMY = event.y;
700 widgetChanged();
702 return false;
707 // ////////////////////////////////////////////////////////////////////////// //
708 void main (string[] args) {
709 //egraFontName = "PT Sans:pixelsize=16";
711 defaultColorStyle.parseStyle(TestStyle);
712 //egraDefaultFontSize = 48;
714 glconAllowOpenGLRender = false;
716 sdpyWindowClass = "EGRATest";
717 //glconShowKey = "M-Grave";
719 initConsole();
721 conProcessQueue();
722 conProcessArgs!true(args);
724 egraCreateSystemWindow("EGRA Test", allowResize:false);
726 vbwin.addEventListener((QuitEvent evt) {
727 if (vbwin.closed) return;
728 if (isQuitRequested) { vbwin.close(); return; }
729 vbwin.close();
732 static if (is(typeof(&vbwin.closeQuery))) {
733 vbwin.closeQuery = delegate () { concmd("quit"); egraPostDoConCommands(); };
736 mainPane = new MainPaneWindow();
737 //egraSkipScreenClear = true; // main pane is fullscreen
739 postScreenRebuild();
740 repostHideMouse();
742 vbwin.eventLoop(1000*10,
743 delegate () {
744 egraProcessConsole();
746 delegate (KeyEvent event) {
747 if (egraOnKey(event)) return;
749 delegate (MouseEvent event) {
750 if (egraOnMouse(event)) return;
752 delegate (dchar ch) {
753 if (egraOnChar(ch)) return;
757 flushGui();
758 conProcessQueue(int.max/4);