erga: use `widgetChanged()` instead of direct screen rebuild posting; fixes to editor...
[iv.d.git] / egra / test.d
blob87630b1e13242d5f319890203c3d003eaa6e92fd
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.cmdcon;
22 import iv.cmdcongl;
23 import iv.strex;
24 import iv.utfutil;
25 import iv.vfs.io;
26 import iv.vfs.util;
28 import iv.egra;
31 // ////////////////////////////////////////////////////////////////////////// //
32 static immutable string TestStyle = `
33 MainPaneWindow {
34 grouplist-divline: white;
35 grouplist-back: #222;
37 threadlist-divline: white;
38 threadlist-back: #222;
41 TitlerWindow {
42 frame: white;
43 title-back: white;
44 title-text: black;
46 back: rgb(0, 92, 0);
47 text: #7f0;
48 hotline: #7f0;
53 // ////////////////////////////////////////////////////////////////////////// //
54 //__gshared int lastWinWidth, lastWinHeight;
57 // ////////////////////////////////////////////////////////////////////////// //
58 public class TitlerWindow : SubWindow {
59 public:
60 LineEditWidget edtTitle;
61 LineEditWidget fromName;
62 LineEditWidget fromMail;
64 protected:
65 dynstring name;
66 dynstring mail;
67 dynstring folder;
68 dynstring title;
70 bool delegate (dynstring name, dynstring mail, dynstring folder, dynstring title) onSelected;
72 override void createWidgets () {
73 new SpacerWidget(2);
75 version(none) {
76 fromName = new LineEditWidget("Name:");
77 fromName.flex = 1;
79 new SpacerWidget(1);
80 fromMail = new LineEditWidget("Mail:");
81 fromMail.flex = 1;
83 new SpacerWidget(1);
84 edtTitle = new LineEditWidget("Title:");
85 edtTitle.flex = 1;
86 } else {
87 (new HBoxWidget).enter{
88 with (new HotLabelWidget("&Name:", LabelWidget.HAlign.Right)) { width = width+2; hsizeId = "editors"; }
89 new SpacerWidget(4);
90 fromName = new LineEditWidget();
91 fromName.flex = 1;
92 }.flex = 1;
94 new SpacerWidget(1);
95 (new HBoxWidget).enter{
96 with (new HotLabelWidget("&Mail:", LabelWidget.HAlign.Right)) { width = width+2; hsizeId = "editors"; }
97 new SpacerWidget(4);
98 fromMail = new LineEditWidget();
99 fromMail.flex = 1;
100 }.flex = 1;
102 new SpacerWidget(1);
103 (new HBoxWidget).enter{
104 with (new HotLabelWidget("&Title:", LabelWidget.HAlign.Right)) { width = width+2; hsizeId = "editors"; }
105 new SpacerWidget(4);
106 edtTitle = new LineEditWidget();
107 edtTitle.flex = 1;
108 }.flex = 1;
111 new SpacerWidget(4);
112 (new HBoxWidget).enter{
113 new SpacerWidget(2);
114 new SpringWidget(1);
115 with (new ButtonWidget(" O&k ")) {
116 hsizeId = "okcancel";
117 deftype = Default.Accept;
118 onAction = delegate (self) {
119 if (onSelected !is null) {
120 if (!onSelected(fromName.str, fromMail.str, folder, edtTitle.str)) return;
122 close();
125 new SpacerWidget(2);
126 with (new ButtonWidget(" Cancel ")) {
127 hsizeId = "okcancel";
128 deftype = Default.Cancel;
129 onAction = delegate (self) {
130 close();
133 new SpringWidget(1);
134 new SpacerWidget(2);
136 new SpacerWidget(4);
138 fromName.str = name;
139 fromMail.str = mail;
140 edtTitle.str = title;
142 relayoutResize();
143 centerWindow();
145 edtTitle.focus();
148 this (const(char)[] aname, const(char)[] amail, const(char)[] afolder, const(char)[] atitle) {
149 dynstring caption = "Title for "~aname~" <"~amail~">";
150 name = aname;
151 mail = amail;
152 folder = afolder;
153 title = atitle;
154 super(caption);
159 // ////////////////////////////////////////////////////////////////////////// //
160 public class TagOptionsWindow : SubWindow {
161 LabelWidget optPath; // real path
162 LineEditWidget optMonthes;
163 CheckboxWidget optThreaded;
164 CheckboxWidget optAttaches;
165 dynstring tagname;
167 void delegate (const(char)[] tagname) onUpdated;
169 this (const(char)[] atagname) {
170 tagname = atagname;
171 dynstring caption = "options for '"~atagname~"'";
172 super(caption);
175 override void createWidgets () {
176 optPath = new LabelWidget("", LabelWidget.HAlign.Center);
177 optPath.flex = 1;
179 version(none) {
180 optMonthes = new LineEditWidget("Monthes:");
181 optMonthes.flex = 1;
182 optMonthes.width = optMonthes.titwdt+64;
183 } else {
184 (new HBoxWidget).enter{
185 with (new HotLabelWidget("&Monthes:", LabelWidget.HAlign.Right)) { width = width+2; /*hsizeId = "editors";*/ }
186 new SpacerWidget(4);
187 optMonthes = new LineEditWidget();
188 //optMonthes.flex = 1;
189 optMonthes.width = gxTextWidthUtf("96669");
190 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" Widget#. "));
191 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" HBoxWidget LineEditWidget#. "));
192 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" HBoxWidget> #. "));
193 conwriteln("ISMYSEL: ", optMonthes.isMySelector(" SubWindow HBoxWidget LineEditWidget#. "));
194 //new SpringWidget(1);
195 }.flex = 1;
198 optThreaded = new CheckboxWidget("&Threaded");
199 optThreaded.flex = 1;
201 optAttaches = new CheckboxWidget("&Attaches");
202 optAttaches.flex = 1;
204 new SpacerWidget(4);
205 (new HBoxWidget).enter{
206 new SpacerWidget(2);
207 new SpringWidget(1);
208 with (new ButtonWidget(" O&k ")) {
209 hsizeId = "okcancel";
210 deftype = Default.Accept;
211 onAction = delegate (self) {
212 if (onUpdated !is null) onUpdated(tagname);
213 close();
216 new SpacerWidget(2);
217 with (new ButtonWidget(" Cancel ")) {
218 hsizeId = "okcancel";
219 deftype = Default.Cancel;
220 onAction = delegate (self) {
221 close();
224 new SpringWidget(1);
225 new SpacerWidget(2);
227 new SpacerWidget(4);
229 optMonthes.focus();
231 optPath.text = "booPath";
232 optMonthes.str = "666";
234 optThreaded.enabled = false;
235 optAttaches.enabled = true;
237 optMonthes.killTextOnChar = true;
239 relayoutResize();
240 centerWindow();
241 //add(); // for "focused"
243 forEachSelector("SubWindow > RootWidget CheckboxWidget", (EgraStyledClass w) {
244 import iv.vfs.io; writeln("LEW=", typeid(w).name, "; text=", (cast(CheckboxWidget)w).title.getData);
245 //return false;
248 forEachSelector("SubWindow > RootWidget :focused", (EgraStyledClass w) {
249 import iv.vfs.io; writeln("FOCUSED=", typeid(w).name);
250 //return false;
253 foreach (EgraStyledClass c; querySelectorAll("SubWindow > RootWidget HotLabelWidget")) {
254 import iv.vfs.io;
255 writeln("LBL: <", (cast(HotLabelWidget)c).text.getData, ">");
258 { import iv.vfs.io;
259 auto qf = querySelector(":focused");
260 if (qf !is null) writeln("QFOCUSED=", typeid(qf).name); else writeln("FUCK!");
265 // ////////////////////////////////////////////////////////////////////////// //
266 void initConsole () {
267 // //////////////////////////////////////////////////////////////////// //
268 conRegFunc!(() {
269 import core.memory : GC;
270 conwriteln("starting GC collection...");
271 GC.collect();
272 GC.minimize();
273 conwriteln("GC collection complete.");
274 })("gc_collect", "force GC collection cycle");
277 // //////////////////////////////////////////////////////////////////// //
278 conRegFunc!(() {
279 auto qww = new YesNoWindow("Quit?", "Do you really want to quit?", true);
280 qww.onYes = () { concmd("quit"); };
281 qww.addModal();
282 })("quit_prompt", "quit with prompt");
284 conRegFunc!(() {
285 new TitlerWindow("name", "mail", "folder", "title");
286 })("window_titler", "titler window test");
288 conRegFunc!(() {
289 new TagOptionsWindow("xtag");
290 })("window_tagoptions", "tag options window test");
294 // ////////////////////////////////////////////////////////////////////////// //
295 __gshared MainPaneWindow mainPane;
298 final class MainPaneWindow : SubWindow {
299 ProgressBarWidget pbar;
301 this () {
302 super(null, GxPoint(0, 0), GxSize(screenWidth, screenHeight));
303 mType = Type.OnBottom;
305 pbar = new ProgressBarWidget(rootWidget, "progress bar");
306 pbar.setMinMax(0, 100);
307 pbar.width = clientWidth-64;
308 pbar.current = 50;
309 pbar.posy = clientHeight-pbar.height-8;
310 pbar.posx = (clientWidth-pbar.width)/2;
312 add();
315 // //////////////////////////////////////////////////////////////////// //
316 override void onPaint () {
317 if (closed) return;
319 enum guiGroupListWidth = 128;
320 enum guiThreadListHeight = 520;
322 gxFillRect(0, 0, guiGroupListWidth, screenHeight, getColor("grouplist-back"));
323 gxVLine(guiGroupListWidth, 0, screenHeight, getColor("grouplist-divline"));
325 gxFillRect(guiGroupListWidth+1, 0, screenWidth, guiThreadListHeight, getColor("threadlist-back"));
326 gxHLine(guiGroupListWidth+1, guiThreadListHeight, screenWidth, getColor("threadlist-divline"));
328 version(test_round_rect) {
329 gxClipReset();
330 gxFillRoundedRect(lastMouseX-16, lastMouseY-16, 128, 96, rrad, /*gxSolidWhite*/gxRGBA!(0, 255, 0, 127));
331 //gxDrawRoundedRect(lastMouseX-16, lastMouseY-16, 128, 96, rrad, gxRGBA!(0, 255, 0, 127));
334 drawWidgets();
337 version(test_round_rect) {
338 int rrad = 16;
341 override bool onKeyBubble (KeyEvent event) {
342 if (event.pressed) {
343 version(test_round_rect) {
344 if (event == "Plus") { ++rrad; return true; }
345 if (event == "Minus") { --rrad; return true; }
347 if (event == "C-Q") { concmd("quit_prompt"); return true; }
348 if (event == "1") { concmd("window_titler"); return true; }
349 if (event == "2") { concmd("window_tagoptions"); return true; }
350 if (event == "Minus") { pbar.current = pbar.current-1; return true; }
351 if (event == "Plus") { pbar.current = pbar.current+1; return true; }
352 //if (dbg_dump_keynames) conwriteln("key: ", event.toStr, ": ", event.modifierState&ModifierState.windows);
353 //foreach (const ref kv; mainAppKeyBindings.byKeyValue) if (event == kv.key) concmd(kv.value);
355 return false;
358 // returning `false` to avoid screen rebuilding by dispatcher
359 override bool onMouseBubble (MouseEvent event) {
360 if (event.type == MouseEventType.buttonPressed || event.type == MouseEventType.buttonReleased) {
361 postScreenRebuild();
362 } else {
363 // for OpenGL, this rebuilds the whole screen anyway
364 postScreenRepaint();
366 return false;
371 // ////////////////////////////////////////////////////////////////////////// //
372 void main (string[] args) {
373 defaultColorStyle.parseStyle(TestStyle);
374 //egraDefaultFontSize = 48;
376 glconAllowOpenGLRender = false;
378 sdpyWindowClass = "EGUITest";
379 //glconShowKey = "M-Grave";
381 initConsole();
383 conProcessQueue();
384 conProcessArgs!true(args);
386 egraCreateSystemWindow("EGRA Test", allowResize:false);
388 vbwin.addEventListener((QuitEvent evt) {
389 if (vbwin.closed) return;
390 if (isQuitRequested) { vbwin.close(); return; }
391 vbwin.close();
394 static if (is(typeof(&vbwin.closeQuery))) {
395 vbwin.closeQuery = delegate () { concmd("quit"); egraPostDoConCommands(); };
398 mainPane = new MainPaneWindow();
399 //egraSkipScreenClear = true; // main pane is fullscreen
401 postScreenRebuild();
402 repostHideMouse();
404 vbwin.eventLoop(1000*10,
405 delegate () {
406 egraProcessConsole();
408 delegate (KeyEvent event) {
409 if (egraOnKey(event)) return;
411 delegate (MouseEvent event) {
412 if (egraOnMouse(event)) return;
414 delegate (dchar ch) {
415 if (egraOnChar(ch)) return;
419 flushGui();
420 conProcessQueue(int.max/4);