+ /**
+ * Close window. Note that the window's destructor is NOT called by this
+ * method, instead the GC is assumed to do the cleanup.
+ *
+ * @param window the window to remove
+ */
+ public final void closeWindow(final TWindow window) {
+ /*
+ TODO
+
+ uint z = window.z;
+ window.z = -1;
+ windows.sort;
+ windows = windows[1 .. $];
+ TWindow activeWindow = null;
+ foreach (w; windows) {
+ if (w.z > z) {
+ w.z--;
+ if (w.z == 0) {
+ w.active = true;
+ assert(activeWindow is null);
+ activeWindow = w;
+ } else {
+ w.active = false;
+ }
+ }
+ }
+
+ // Perform window cleanup
+ window.onClose();
+
+ // Refresh screen
+ repaint = true;
+
+ // Check if we are closing a TMessageBox or similar
+ if (secondaryEventReceiver !is null) {
+ assert(secondaryEventFiber !is null);
+
+ // Do not send events to the secondaryEventReceiver anymore, the
+ // window is closed.
+ secondaryEventReceiver = null;
+
+ // Special case: if this is called while executing on a
+ // secondaryEventFiber, call it so that widgetEventHandler() can
+ // terminate.
+ if (secondaryEventFiber.state == Fiber.State.HOLD) {
+ secondaryEventFiber.call();
+ }
+ secondaryEventFiber = null;
+
+ // Unfreeze the logic in handleEvent()
+ if (primaryEventFiber.state == Fiber.State.HOLD) {
+ primaryEventFiber.call();
+ }
+ }
+ */
+ }
+
+ /**
+ * Switch to the next window.
+ *
+ * @param forward if true, then switch to the next window in the list,
+ * otherwise switch to the previous window in the list
+ */
+ public final void switchWindow(final boolean forward) {
+ /*
+ TODO
+
+ // Only switch if there are multiple windows
+ if (windows.length < 2) {
+ return;
+ }
+
+ // Swap z/active between active window and the next in the
+ // list
+ ptrdiff_t activeWindowI = -1;
+ for (auto i = 0; i < windows.length; i++) {
+ if (windows[i].active) {
+ activeWindowI = i;
+ break;
+ }
+ }
+ assert(activeWindowI >= 0);
+
+ // Do not switch if a window is modal
+ if (windows[activeWindowI].isModal()) {
+ return;
+ }
+
+ size_t nextWindowI;
+ if (forward) {
+ nextWindowI = (activeWindowI + 1) % windows.length;
+ } else {
+ if (activeWindowI == 0) {
+ nextWindowI = windows.length - 1;
+ } else {
+ nextWindowI = activeWindowI - 1;
+ }
+ }
+ windows[activeWindowI].active = false;
+ windows[activeWindowI].z = windows[nextWindowI].z;
+ windows[nextWindowI].z = 0;
+ windows[nextWindowI].active = true;
+
+ // Refresh
+ repaint = true;
+ */
+ }
+
+ /**
+ * Add a window to my window list and make it active.
+ *
+ * @param window new window to add
+ */
+ public final void addWindow(final TWindow window) {
+ // Do not allow a modal window to spawn a non-modal window
+ if ((windows.size() > 0) && (windows.get(0).isModal())) {
+ assert (window.isModal());
+ }
+ for (TWindow w: windows) {
+ w.active = false;
+ w.setZ(w.getZ() + 1);
+ }
+ windows.add(window);
+ window.active = true;
+ window.setZ(0);
+ }
+
+