comparison mde/gui/WidgetManager.d @ 133:9fd705793568

Fixed menu popup bug, improved recursion detection. Menu popups can now determine whether or not they are sub-menus. Recursion detection can now also check content (if not the same, there's not a risk of infinite recursion).
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 23 Jan 2009 16:05:05 +0000
parents 264028f4115a
children 7ababdf97748
comparison
equal deleted inserted replaced
132:264028f4115a 133:9fd705793568
266 // They are not necessarily thread-safe: 266 // They are not necessarily thread-safe:
267 267
268 //BEGIN IParentWidget methods 268 //BEGIN IParentWidget methods
269 // If call reaches the widget manager there isn't any recursion. 269 // If call reaches the widget manager there isn't any recursion.
270 //NOTE: should be override 270 //NOTE: should be override
271 final void recursionCheck (widgetID) {} 271 final void recursionCheck (widgetID, IContent) {}
272 272
273 override void minWChange (IChildWidget widget, wdim nmw) { 273 override void minWChange (IChildWidget widget, wdim nmw) {
274 debug assert (widget is child, "WM.mSC (code error)"); 274 debug assert (widget is child, "WM.mSC (code error)");
275 mw = nmw; 275 mw = nmw;
276 if (w < nmw) { 276 if (w < nmw) {
317 if (childIPPW) 317 if (childIPPW)
318 childIPPW.menuActive = mA; 318 childIPPW.menuActive = mA;
319 } 319 }
320 override bool menuActive () { 320 override bool menuActive () {
321 return mAIPPW; 321 return mAIPPW;
322 }
323 override bool parentMenuActive () {
324 return false;
322 } 325 }
323 326
324 // Don't do anything. E.g. can get called by non-popup buttons. 327 // Don't do anything. E.g. can get called by non-popup buttons.
325 override void menuDone () {} 328 override void menuDone () {}
326 329
471 private static { 474 private static {
472 /// Widget types. Items match widget names without the "Widget" suffix. 475 /// Widget types. Items match widget names without the "Widget" suffix.
473 enum WIDGET_TYPE : int { 476 enum WIDGET_TYPE : int {
474 FUNCTION = 0x2000, // Function called instead of widget created (no "Widget" appended to fct name) 477 FUNCTION = 0x2000, // Function called instead of widget created (no "Widget" appended to fct name)
475 TAKES_CONTENT = 0x4000, // Flag indicates widget's this should be passed an IContent reference. 478 TAKES_CONTENT = 0x4000, // Flag indicates widget's this should be passed an IContent reference.
476 SAFE_RECURSION = 0x8000, // Safe to instantiate recursively without infinite looping.
477 479
478 // Use widget names rather than usual capitals convention 480 // Use widget names rather than usual capitals convention
479 Unnamed = 0x0, // Only for use by widgets not created with createWidget 481 Unnamed = 0x0, // Only for use by widgets not created with createWidget
480 482
481 // blank: 0x1 483 // blank: 0x1
489 // labels: 0x20 491 // labels: 0x20
490 ContentLabel = TAKES_CONTENT | 0x20, 492 ContentLabel = TAKES_CONTENT | 0x20,
491 TextLabel = 0x21, 493 TextLabel = 0x21,
492 494
493 // content functions: 0x30 495 // content functions: 0x30
494 editContent = FUNCTION | TAKES_CONTENT | SAFE_RECURSION | 0x30, 496 editContent = FUNCTION | TAKES_CONTENT | 0x30,
495 addContent = FUNCTION | 0x31, 497 addContent = FUNCTION | 0x31,
496 popupListContent = FUNCTION | TAKES_CONTENT | 0x33, 498 popupListContent = FUNCTION | TAKES_CONTENT | 0x33,
497 499
498 // content widgets: 0x40 500 // content widgets: 0x40
499 DisplayContent = TAKES_CONTENT | 0x40, 501 DisplayContent = TAKES_CONTENT | 0x40,
500 BoolContent = TAKES_CONTENT | 0x41, 502 BoolContent = TAKES_CONTENT | 0x41,
501 AStringContent = TAKES_CONTENT | 0x42, 503 AStringContent = TAKES_CONTENT | 0x42,
502 ButtonContent = TAKES_CONTENT | 0x43, 504 ButtonContent = TAKES_CONTENT | 0x43,
503 505
504 GridLayout = TAKES_CONTENT | 0x100, 506 GridLayout = TAKES_CONTENT | 0x100,
505 ContentList = TAKES_CONTENT | SAFE_RECURSION | 0x110, 507 ContentList = TAKES_CONTENT | 0x110,
506 508
507 FloatingArea = TAKES_CONTENT | 0x200, 509 FloatingArea = TAKES_CONTENT | 0x200,
508 Switch = TAKES_CONTENT | 0x210, 510 Switch = TAKES_CONTENT | 0x210,
509 } 511 }
510 512
520 "DisplayContent", 522 "DisplayContent",
521 "BoolContent", 523 "BoolContent",
522 "AStringContent", 524 "AStringContent",
523 "ButtonContent", 525 "ButtonContent",
524 "GridLayout", 526 "GridLayout",
527 "ContentList",
525 "FloatingArea", 528 "FloatingArea",
526 "Switch", 529 "Switch",
527 "popupListContent", 530 "editContent",
528 "ContentList", 531 "popupListContent"];
529 "editContent"];
530 532
531 /* Generates a binary search algorithm for makeWidget. */ 533 /* Generates a binary search algorithm for makeWidget. */
532 char[] binarySearch (char[] var, char[][] consts) { 534 char[] binarySearch (char[] var, char[][] consts) {
533 if (consts.length > 3) { 535 if (consts.length > 3) {
534 return `if (`~var~` <= WIDGET_TYPE.`~consts[$/2 - 1]~`) {` ~ 536 return `if (`~var~` <= WIDGET_TYPE.`~consts[$/2 - 1]~`) {` ~
539 } else { 541 } else {
540 char[] ret; 542 char[] ret;
541 foreach (c; consts) { 543 foreach (c; consts) {
542 ret ~= `if (` ~ var ~ ` == WIDGET_TYPE.` ~ c ~ `) { 544 ret ~= `if (` ~ var ~ ` == WIDGET_TYPE.` ~ c ~ `) {
543 debug (mdeWidgets) logger.trace ("Creating new `~c~`."); 545 debug (mdeWidgets) logger.trace ("Creating new `~c~`.");
544 if (!(WIDGET_TYPE.`~c~` & WIDGET_TYPE.SAFE_RECURSION)) 546 parent.recursionCheck (id, content);
545 parent.recursionCheck (id);
546 static if (WIDGET_TYPE.`~c~` & WIDGET_TYPE.FUNCTION) 547 static if (WIDGET_TYPE.`~c~` & WIDGET_TYPE.FUNCTION)
547 return `~c~` (this, parent, id, data, content); 548 return `~c~` (this, parent, id, data, content);
548 else static if (WIDGET_TYPE.`~c~` & WIDGET_TYPE.TAKES_CONTENT) 549 else static if (WIDGET_TYPE.`~c~` & WIDGET_TYPE.TAKES_CONTENT)
549 return new `~c~`Widget (this, parent, id, data, content); 550 return new `~c~`Widget (this, parent, id, data, content);
550 else 551 else