Mercurial > projects > mde
comparison mde/gui/WidgetManager.d @ 111:1655693702fc
Resolved ticket #4, allowing widgets to reload strings and recalculate sizes mid-run.
Removed prefinalize and finalize and added setup as the new second initialization phase, which can be re-run.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Sat, 06 Dec 2008 17:41:42 +0000 |
parents | 6acd96f8685f |
children | fe061009029d |
comparison
equal
deleted
inserted
replaced
110:6acd96f8685f | 111:1655693702fc |
---|---|
171 IRenderer renderer () { | 171 IRenderer renderer () { |
172 assert (rend !is null, "WidgetManager.renderer: rend is null"); | 172 assert (rend !is null, "WidgetManager.renderer: rend is null"); |
173 return rend; | 173 return rend; |
174 } | 174 } |
175 | 175 |
176 /** Place a pop-up widget near px,py. | |
177 * | |
178 * WidgetManager sets its position, draws it, passes it click events and removes it; other | |
179 * functionality should be handled by the widget's parent. */ | |
176 void addPopup (wdabs px, wdabs py, IChildWidget widg) { | 180 void addPopup (wdabs px, wdabs py, IChildWidget widg) { |
177 ActivePopup popup; | 181 ActivePopup popup; |
178 with (popup) { | 182 with (popup) { |
179 widget = widg; | 183 widget = widg; |
180 w = widg.width; | 184 w = widg.width; |
212 if (rend is null) | 216 if (rend is null) |
213 rend = createRenderer (rendName); | 217 rend = createRenderer (rendName); |
214 popups = new CircularList!(ActivePopup); | 218 popups = new CircularList!(ActivePopup); |
215 | 219 |
216 child = makeWidget ("root"); | 220 child = makeWidget ("root"); |
217 finalize; | 221 child.setup (0, 3); |
218 | 222 |
219 mw = child.minWidth; | 223 mw = child.minWidth; |
220 mh = child.minHeight; | 224 mh = child.minHeight; |
221 | 225 |
222 if (w < mw || h < mh) | 226 if (w < mw || h < mh) |
442 } | 446 } |
443 | 447 |
444 /** Called when translation strings have been reloaded. */ | 448 /** Called when translation strings have been reloaded. */ |
445 void reloadStrings (AContent c) { | 449 void reloadStrings (AContent c) { |
446 Items.loadTranslation; | 450 Items.loadTranslation; |
447 child.reloadStrings; //FIXME : all widgets, resize | 451 child.setup (++setupN, 2); |
452 child.setPosition (0,0); | |
448 requestRedraw; | 453 requestRedraw; |
449 } | 454 } |
450 | 455 |
451 protected: | 456 protected: |
452 /** Second stage of loading the widgets. | 457 /** Second stage of loading the widgets. |
453 * | 458 * |
454 * loadDesign handles the data; this method needs to: | 459 * loadDesign handles the data; this method needs to: |
455 * --- | 460 * --- |
456 * // 1. Create the root widget: | 461 * // 1. Create the root widget: |
457 * child = makeWidget ("root"); | 462 * child = makeWidget ("root"); |
458 * finalize; | 463 * child.setup (0, 3); |
459 * // 2. Set the setSize, e.g.: | 464 * // 2. Set the size: |
460 * child.setWidth (child.minWidth, 1); | 465 * child.setWidth (child.minWidth, 1); |
461 * child.setHeight (child.minHeight, 1); | 466 * child.setHeight (child.minHeight, 1); |
467 * // 3. Set the position (necessary part of initialization): | |
468 * child.setPosition (0,0); | |
462 * --- | 469 * --- |
463 */ | 470 */ |
464 void createRootWidget(); | 471 void createRootWidget(); |
465 | |
466 /** Runs finalize for all descendants, in a deepest first order. */ | |
467 /* NOTE: The way this function works may seem a little odd, but it's designed to allow | |
468 * shared alignments to be initialized properly: | |
469 * 1. all sharing members need to know their children's min size | |
470 * 2. all sharing members need to add their children's min size to the alignment | |
471 * 3. all sharing members can only then get their min size | |
472 * This method will fail if alignment members are not all of the same generation. An alternate | |
473 * method without this drawback would be to have shared alignments created with a list of | |
474 * pointers to their members, and once all members have been created the alignment could | |
475 * initialize itself, first making sure each members' children have been initialized. */ | |
476 void finalize () { | |
477 IChildWidget[][] descendants; // first index: depth; is a list of widgets at each depth | |
478 | |
479 void recurseChildren (size_t depth, IChildWidget widget) { | |
480 foreach (child; widget.children) | |
481 recurseChildren (depth+1, child); | |
482 | |
483 if (descendants.length <= depth) | |
484 descendants.length = depth * 2 + 1; | |
485 descendants[depth] ~= widget; | |
486 } | |
487 | |
488 recurseChildren (0, child); | |
489 foreach_reverse (generation; descendants) { | |
490 foreach (widget; generation) | |
491 widget.prefinalize; | |
492 foreach (widget; generation) | |
493 widget.finalize; | |
494 } | |
495 } | |
496 | 472 |
497 /** Called before saving (usually when the GUI is about to be destroyed, although not | 473 /** Called before saving (usually when the GUI is about to be destroyed, although not |
498 * necessarily). */ | 474 * necessarily). */ |
499 void preSave (); | 475 void preSave (); |
500 | 476 |
532 WidgetDataChanges changes; // Changes for the current design. | 508 WidgetDataChanges changes; // Changes for the current design. |
533 scope mt.DataSet changesDS; // changes and sections from user file (used for saving) | 509 scope mt.DataSet changesDS; // changes and sections from user file (used for saving) |
534 bool loadUserFile = true; // still need to load user file for saving? | 510 bool loadUserFile = true; // still need to load user file for saving? |
535 | 511 |
536 scope IChildWidget child; // The primary widget. | 512 scope IChildWidget child; // The primary widget. |
513 uint setupN; // n to pass to IChildWidget.setup | |
537 | 514 |
538 Mutex mutex; // lock on methods for use outside the package. | 515 Mutex mutex; // lock on methods for use outside the package. |
539 } | 516 } |