Mercurial > projects > mde
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 |