diff dwtx/novocode/ishell/DesktopForm.d @ 190:df4e66472aff

novocode line endings, indention
author Frank Benoit <benoit@tionex.de>
date Sun, 26 Oct 2008 15:04:41 +0100
parents e3780acbbf80
children
line wrap: on
line diff
--- a/dwtx/novocode/ishell/DesktopForm.d	Sun Oct 26 14:57:25 2008 +0100
+++ b/dwtx/novocode/ishell/DesktopForm.d	Sun Oct 26 15:04:41 2008 +0100
@@ -1,512 +1,512 @@
-/*******************************************************************************
- * Copyright (c) 2005 Stefan Zeiger and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.novocode.com/legal/epl-v10.html
- * 
- * Contributors:
- *     Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
- *******************************************************************************/
-
-module dwtx.novocode.ishell.DesktopForm;
-
-import dwt.DWT;
-import dwt.graphics.Color;
-import dwt.graphics.Rectangle;
-import dwt.widgets.Composite;
-import dwt.widgets.Control;
-import dwt.widgets.Display;
-import dwt.widgets.Event;
-import dwt.widgets.Listener;
-import dwt.widgets.Shell;
-
-import dwtx.novocode.ishell.internal.DesktopListener;
-import dwtx.novocode.ishell.InternalShell;
-
-import tango.core.Array;
-
-
-/**
- * A desktop which manages internal shells.
- *
- * @author Stefan Zeiger (szeiger@novocode.com)
- * @since Jan 21, 2005
- * @version $Id: DesktopForm.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $
- */
-
-class DesktopForm : Composite
-{
-  private static const InternalShell[] EMPTY_INTERNALSHELL_ARRAY/** = new InternalShell[0]*/;
-  private static const int FIRST_SHELL_LOCATION = 32;
-  private static const int SHELL_LOCATION_OFFSET = 16;
-
-  private InternalShell activeShell;
-  private DesktopListener[] desktopListeners;
-  private InternalShell[] allShells;
-  private InternalShell[] visibleShells;
-  private int nextShellLocation = FIRST_SHELL_LOCATION;
-  private bool showMaximizedTitle;
-  private bool autoMaximize = true;
-  private bool enableCtrlTab = true;
-  private bool allowDeactivate;
-  private Shell shell;
-  private InternalShell ishell;
-  private Listener mouseDownFilter, focusInFilter, traverseFilter;
-
-
-  this(Composite parent, int style)
-  {
-    super(parent, style);
-    Display display = getDisplay();
-    shell = getShell();
-
-    Color bg = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND);
-    setBackground(bg);
-    int brightness = bg.getRed() + bg.getGreen() + bg.getBlue();
-    setForeground(display.getSystemColor(brightness > 400 ? DWT.COLOR_BLACK : DWT.COLOR_WHITE));
-    
-    addListener(DWT.Resize, dgListener(&onResize));
-    
-    mouseDownFilter = dgListener(&onMouseDownFilter);
-    focusInFilter = dgListener(&onFocusInFilter);
-    traverseFilter = dgListener(&onTraverseFilter);
-    
-    display.addFilter(DWT.MouseDown, mouseDownFilter);
-    display.addFilter(DWT.FocusIn, focusInFilter);
-    display.addFilter(DWT.Traverse, traverseFilter);
-    
-    addListener(DWT.Dispose, dgListener(&onDispose));
-  }
-  
-  
-  private void onResize(Event event)
-  {
-        Rectangle ca = getClientArea();
-        foreach(c; getChildren())
-        {
-          if(cast(InternalShell)c !is null)
-            (cast(InternalShell)c).desktopResized(ca);
-        }
-  }
-
-
-  private void onMouseDownFilter(Event event)
-  {
-        if(!(cast(Control)event.widget !is null)) return;
-        Control c = cast(Control)event.widget;
-        if(c.getShell() !is shell) return;
-        bool[] desktopHit = new bool[1];
-        InternalShell ishell = getInternalShell(c, desktopHit);
-        if(desktopHit[0] && allowDeactivate) activate(null);
-        if(ishell is null) return;
-        activate(ishell);
-  }
-
-
-  private void onFocusInFilter(Event event)
-  {
-        if(!(cast(Control)event.widget !is null)) return;
-        Control c = cast(Control)event.widget;
-        if(c.getShell() !is shell) return;
-        bool[] desktopHit = new bool[1];
-        ishell = getInternalShell(c, desktopHit);
-        if(desktopHit[0] && allowDeactivate) activate(null);
-        if(ishell is null) return;
-        ishell.focusControl = c;
-  }
-
-
-  private void onTraverseFilter(Event event)
-  {
-        if(!enableCtrlTab) return;
-        if(!event.doit) return; // don't steal traverse event if a control wants to handle it directly
-        if((event.stateMask & DWT.CTRL) is 0) return;
-        if(event.detail !is DWT.TRAVERSE_TAB_NEXT && event.detail !is DWT.TRAVERSE_TAB_PREVIOUS) return;
-        if(!(cast(Control)event.widget !is null)) return;
-        Control c = cast(Control)event.widget;
-        if(c.getShell() !is shell) return;
-        bool[] desktopHit = new bool[1];
-        InternalShell ishell = getInternalShell(c, desktopHit);
-        if(ishell !is null || desktopHit[0])
-        {
-          if(event.detail is DWT.TRAVERSE_TAB_NEXT) activateNextShell();
-          else activatePreviousShell();
-          event.doit = false;
-        }
-  }
-
-
-  private void onDispose(Event event)
-  {
-        display.removeFilter(DWT.MouseDown, mouseDownFilter);
-        display.removeFilter(DWT.FocusIn, focusInFilter);
-        display.removeFilter(DWT.Traverse, traverseFilter);
-  }
-
-
-  void manage(InternalShell ishell)
-  {
-    Rectangle bounds = getBounds();
-    if(nextShellLocation > bounds.height-100 || nextShellLocation > bounds.width-100)
-      nextShellLocation = FIRST_SHELL_LOCATION;
-    ishell.setLocation(bounds.x+nextShellLocation, bounds.y+nextShellLocation);
-    nextShellLocation += SHELL_LOCATION_OFFSET;
-
-    ishell.addListener(DWT.Dispose, dgListener(&onIshellDispose));
-    allShells ~= ishell;
-    if(ishell.isVisible()) visibleShells ~= ishell;
-    notifyDesktopListenersCreate(ishell);
-  }
-  
-  
-  private void onIshellDispose(Event event)
-  {
-        allShells.remove(ishell);
-        visibleShells.remove(ishell);
-        if(ishell is activeShell)
-        {
-          activateTopmostVisibleShellExcept(ishell);
-          if(autoMaximize && !hasVisibleMaximizedShell())
-            setAllVisibleMaximized(false);
-        }
-        notifyDesktopListenersDispose(ishell);
-  }
-
-
-  private InternalShell activateTopmostVisibleShellExcept(InternalShell except)
-  {
-    Control[] children = getChildren();
-    for(int i=0; i<children.length; i++)
-    {
-      Control c = children[i];
-      if(c is except) continue;
-      if(cast(InternalShell)c !is null && c.isVisible())
-      {
-        InternalShell ishell = cast(InternalShell)c;
-        activate(ishell);
-        return ishell;
-      }
-    }
-    activeShell = null;
-    notifyDesktopListenersActivate(null);
-    return null;
-  }
-  
-  
-  void activate(InternalShell ishell)
-  {
-    if(ishell is activeShell) return;
-    checkWidget();
-    if(ishell !is null)
-    {
-      if(!ishell.isVisible()) ishell.setVisible(true);
-      if((ishell.getStyle() & DWT.ON_TOP) !is 0)
-        ishell.moveAbove(null);
-      else
-      {
-        InternalShell firstRegular = getTopmostRegularShell();
-        if(firstRegular !is null && firstRegular !is ishell) ishell.moveAbove(firstRegular);
-        else
-        {
-          Control[] children = getChildren();
-          if(children.length > 0) ishell.moveAbove(children[0]);
-        }
-      }
-    }
-    InternalShell oldActiveShell = activeShell;
-    activeShell = ishell;
-    if(oldActiveShell !is null) oldActiveShell.redrawDecorationsAfterActivityChange();
-    if(ishell !is null)
-    {
-      if(activeShell.isVisible()) activeShell.redrawDecorationsAfterActivityChange();
-      setTabList(/**new Control[] { activeShell }*/[ activeShell ]);
-      activeShell.setFocus();
-    }
-    else
-    {
-      setTabList(/**new Control[] {}*/[]);
-      forceFocus();
-    }
-    notifyDesktopListenersActivate(ishell);
-  }
-  
-  
-  private InternalShell getTopmostRegularShell()
-  {
-    foreach(c; getChildren())
-    {
-      if(!(cast(InternalShell)c !is null)) continue;
-      if((c.getStyle() & DWT.ON_TOP) is 0) return cast(InternalShell)c;
-    }
-    return null;
-  }
-  
-  
-  private InternalShell getBottommostOnTopShell()
-  {
-    Control[] ch = getChildren();
-    for(int i=ch.length-1; i>=0; i--)
-    {
-      Control c = ch[i];
-      if(!(cast(InternalShell)c !is null)) continue;
-      if((c.getStyle() & DWT.ON_TOP) !is 0) return cast(InternalShell)c;
-    }
-    return null;
-  }
-  
-  
-  void shellVisibilityChanged(InternalShell ishell, bool visible)
-  {
-    if(visible)
-    {
-      if(!contains(visibleShells, ishell))
-      {
-        visibleShells ~= ishell;
-        if(autoMaximize && !ishell.getMaximized() && (ishell.getStyle() & DWT.MAX) !is 0 && hasVisibleMaximizedShell())
-          ishell.setMaximizedWithoutNotification(true);
-      }
-      if(ishell.getMaximized())
-        ishell.desktopResized(getClientArea());
-    }
-    else
-    {
-      visibleShells.remove(ishell);
-      if(ishell is activeShell)
-      {
-        activateTopmostVisibleShellExcept(ishell);
-        if(autoMaximize && !hasVisibleMaximizedShell())
-          setAllVisibleMaximized(false);
-      }
-    }
-  }
-  
-  
-  private InternalShell getInternalShell(Control c, bool[] desktopHit)
-  {
-    while(c !is null && c !is /**DesktopForm.*/this)
-    {
-      if(cast(InternalShell)c !is null && (cast(InternalShell)c).getParent() is this)
-        return cast(InternalShell)c;
-      c = c.getParent();
-    }
-    if(desktopHit !is null && c is /**DesktopForm.*/this) desktopHit[0] = true;
-    return null;
-  }
-  
-  
-  public InternalShell getActiveShell()
-  {
-    return activeShell;
-  }
-  
-  
-  public InternalShell[] getVisibleShells()
-  {
-    checkWidget();
-    return visibleShells;
-  }
-  
-  
-  public InternalShell[] getShells()
-  {
-    checkWidget();
-    return allShells;
-  }
-  
-  
-  public void setShowMaximizedTitle(bool b)
-  {
-    checkWidget();
-    showMaximizedTitle = b;
-    Rectangle ca = getClientArea();
-    foreach(c; getChildren())
-    {
-      if(cast(InternalShell)c !is null)
-        (cast(InternalShell)c).desktopResized(ca);
-    }
-  }
-
-
-  public bool getShowMaximizedTitle()
-  {
-    checkWidget();
-    return showMaximizedTitle;
-  }
-
-  
-  public void setAutoMaximize(bool b)
-  {
-    checkWidget();
-    autoMaximize = b;
-    bool hasMax = false;
-    foreach(ins; visibleShells)
-    {
-      if(ins.getMaximized())
-      {
-        hasMax = true;
-        break;
-      }
-    }
-    if(hasMax)
-    {
-      // Maximize all shells
-      foreach(ins; visibleShells)
-      {
-        if((ins.getStyle() & DWT.MAX) !is 0) ins.setMaximized(true);
-      }
-    }
-  }
-
-
-  public bool getAutoMaximize()
-  {
-    checkWidget();
-    return autoMaximize;
-  }
-  
-  
-  public void setEnableCtrlTab(bool b)
-  {
-    checkWidget();
-    this.enableCtrlTab = b;
-  }
-  
-  
-  public bool getEnableCtrlTab()
-  {
-    return enableCtrlTab;
-  }
-
-  
-  public void setAllowDeactivate(bool b)
-  {
-    checkWidget();
-    this.allowDeactivate = b;
-    if(!allowDeactivate && activeShell is null)
-      activateTopmostVisibleShellExcept(null);
-  }
-  
-  
-  public bool getAllowDeactivate()
-  {
-    return allowDeactivate;
-  }
-
-  
-  void shellMaximizedOrRestored(InternalShell ishell, bool maximized)
-  {
-    setAllVisibleMaximized(maximized);
-  }
-
-
-  private void setAllVisibleMaximized(bool maximized)
-  {
-    if(autoMaximize) // maximize or restore all shells
-    {
-      foreach(c; getChildren())
-      {
-        if(cast(InternalShell)c !is null)
-        {
-          InternalShell ishell = cast(InternalShell)c;
-          if((ishell.getStyle() & DWT.MAX) !is 0 && ishell.isVisible())
-            (cast(InternalShell)c).setMaximizedWithoutNotification(maximized);
-        }
-      }
-    }
-  }
-
-
-  private void activateNextShell()
-  {
-    if(activeShell is null)
-    {
-      activateTopmostVisibleShellExcept(null);
-      return;
-    }
-    if(visibleShells.length < 2) return;
-    InternalShell topReg = getTopmostRegularShell();
-    InternalShell botTop = getBottommostOnTopShell();
-    if((activeShell.getStyle() & DWT.ON_TOP) !is 0)
-    {
-      activeShell.moveBelow(botTop);
-      if(topReg !is null) activate(topReg);
-      else activateTopmostVisibleShellExcept(null);
-    }
-    else
-    {
-      activeShell.moveBelow(null);
-      activateTopmostVisibleShellExcept(null);
-    }
-  }
-
-
-  private void activatePreviousShell()
-  {
-    if(activeShell is null)
-    {
-      activateTopmostVisibleShellExcept(null);
-      return;
-    }
-    if(visibleShells.length < 2) return;
-    InternalShell topReg = getTopmostRegularShell();
-    InternalShell botTop = getBottommostOnTopShell();
-    if(activeShell is topReg && botTop !is null) activate(botTop);
-    else
-    {
-      Control[] ch = getChildren();
-      for(int i=ch.length-1; i>=0; i--)
-      {
-        if(cast(InternalShell)ch[i] !is null && ch[i].isVisible())
-        {
-          activate(cast(InternalShell)ch[i]);
-          break;
-        }
-      }
-    }
-  }
-
-
-  public void addDesktopListener(DesktopListener l)
-  {
-    desktopListeners ~= l;
-  }
-
-
-  public void removeDesktopListener(DesktopListener l)
-  {
-    desktopListeners.remove(l);
-  }
-
-
-  private void notifyDesktopListenersCreate(InternalShell ishell)
-  {
-    Event event = new Event();
-    event.widget = ishell;
-    foreach(l; desktopListeners) l.shellCreated(event);
-  }
-  
-  
-  private void notifyDesktopListenersDispose(InternalShell ishell)
-  {
-    Event event = new Event();
-    event.widget = ishell;
-    foreach(l; desktopListeners) l.shellDisposed(event);
-  }
-  
-  
-  private void notifyDesktopListenersActivate(InternalShell ishell)
-  {
-    Event event = new Event();
-    event.widget = ishell;
-    foreach(l; desktopListeners) l.shellActivated(event);
-  }
-  
-  
-  private bool hasVisibleMaximizedShell()
-  {
-    foreach(ins; visibleShells)
-      if(ins.getMaximized()) return true;
-    return false;
-  }
-}
+/*******************************************************************************
+ * Copyright (c) 2005 Stefan Zeiger and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.novocode.com/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
+ *******************************************************************************/
+
+module dwtx.novocode.ishell.DesktopForm;
+
+import dwt.DWT;
+import dwt.graphics.Color;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Shell;
+
+import dwtx.novocode.ishell.internal.DesktopListener;
+import dwtx.novocode.ishell.InternalShell;
+
+import tango.core.Array;
+
+
+/**
+ * A desktop which manages internal shells.
+ *
+ * @author Stefan Zeiger (szeiger@novocode.com)
+ * @since Jan 21, 2005
+ * @version $Id: DesktopForm.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $
+ */
+
+class DesktopForm : Composite
+{
+    private static const InternalShell[] EMPTY_INTERNALSHELL_ARRAY/** = new InternalShell[0]*/;
+    private static const int FIRST_SHELL_LOCATION = 32;
+    private static const int SHELL_LOCATION_OFFSET = 16;
+
+    private InternalShell activeShell;
+    private DesktopListener[] desktopListeners;
+    private InternalShell[] allShells;
+    private InternalShell[] visibleShells;
+    private int nextShellLocation = FIRST_SHELL_LOCATION;
+    private bool showMaximizedTitle;
+    private bool autoMaximize = true;
+    private bool enableCtrlTab = true;
+    private bool allowDeactivate;
+    private Shell shell;
+    private InternalShell ishell;
+    private Listener mouseDownFilter, focusInFilter, traverseFilter;
+
+
+    this(Composite parent, int style)
+    {
+        super(parent, style);
+        Display display = getDisplay();
+        shell = getShell();
+
+        Color bg = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND);
+        setBackground(bg);
+        int brightness = bg.getRed() + bg.getGreen() + bg.getBlue();
+        setForeground(display.getSystemColor(brightness > 400 ? DWT.COLOR_BLACK : DWT.COLOR_WHITE));
+
+        addListener(DWT.Resize, dgListener(&onResize));
+
+        mouseDownFilter = dgListener(&onMouseDownFilter);
+        focusInFilter = dgListener(&onFocusInFilter);
+        traverseFilter = dgListener(&onTraverseFilter);
+
+        display.addFilter(DWT.MouseDown, mouseDownFilter);
+        display.addFilter(DWT.FocusIn, focusInFilter);
+        display.addFilter(DWT.Traverse, traverseFilter);
+
+        addListener(DWT.Dispose, dgListener(&onDispose));
+    }
+
+
+    private void onResize(Event event)
+    {
+        Rectangle ca = getClientArea();
+        foreach(c; getChildren())
+        {
+            if(cast(InternalShell)c !is null)
+                (cast(InternalShell)c).desktopResized(ca);
+        }
+    }
+
+
+    private void onMouseDownFilter(Event event)
+    {
+        if(!(cast(Control)event.widget !is null)) return;
+        Control c = cast(Control)event.widget;
+        if(c.getShell() !is shell) return;
+        bool[] desktopHit = new bool[1];
+        InternalShell ishell = getInternalShell(c, desktopHit);
+        if(desktopHit[0] && allowDeactivate) activate(null);
+        if(ishell is null) return;
+        activate(ishell);
+    }
+
+
+    private void onFocusInFilter(Event event)
+    {
+        if(!(cast(Control)event.widget !is null)) return;
+        Control c = cast(Control)event.widget;
+        if(c.getShell() !is shell) return;
+        bool[] desktopHit = new bool[1];
+        ishell = getInternalShell(c, desktopHit);
+        if(desktopHit[0] && allowDeactivate) activate(null);
+        if(ishell is null) return;
+        ishell.focusControl = c;
+    }
+
+
+    private void onTraverseFilter(Event event)
+    {
+        if(!enableCtrlTab) return;
+        if(!event.doit) return; // don't steal traverse event if a control wants to handle it directly
+        if((event.stateMask & DWT.CTRL) is 0) return;
+        if(event.detail !is DWT.TRAVERSE_TAB_NEXT && event.detail !is DWT.TRAVERSE_TAB_PREVIOUS) return;
+        if(!(cast(Control)event.widget !is null)) return;
+        Control c = cast(Control)event.widget;
+        if(c.getShell() !is shell) return;
+        bool[] desktopHit = new bool[1];
+        InternalShell ishell = getInternalShell(c, desktopHit);
+        if(ishell !is null || desktopHit[0])
+        {
+            if(event.detail is DWT.TRAVERSE_TAB_NEXT) activateNextShell();
+            else activatePreviousShell();
+            event.doit = false;
+        }
+    }
+
+
+    private void onDispose(Event event)
+    {
+        display.removeFilter(DWT.MouseDown, mouseDownFilter);
+        display.removeFilter(DWT.FocusIn, focusInFilter);
+        display.removeFilter(DWT.Traverse, traverseFilter);
+    }
+
+
+    void manage(InternalShell ishell)
+    {
+        Rectangle bounds = getBounds();
+        if(nextShellLocation > bounds.height-100 || nextShellLocation > bounds.width-100)
+            nextShellLocation = FIRST_SHELL_LOCATION;
+        ishell.setLocation(bounds.x+nextShellLocation, bounds.y+nextShellLocation);
+        nextShellLocation += SHELL_LOCATION_OFFSET;
+
+        ishell.addListener(DWT.Dispose, dgListener(&onIshellDispose));
+        allShells ~= ishell;
+        if(ishell.isVisible()) visibleShells ~= ishell;
+        notifyDesktopListenersCreate(ishell);
+    }
+
+
+    private void onIshellDispose(Event event)
+    {
+        allShells.remove(ishell);
+        visibleShells.remove(ishell);
+        if(ishell is activeShell)
+        {
+            activateTopmostVisibleShellExcept(ishell);
+            if(autoMaximize && !hasVisibleMaximizedShell())
+                setAllVisibleMaximized(false);
+        }
+        notifyDesktopListenersDispose(ishell);
+    }
+
+
+    private InternalShell activateTopmostVisibleShellExcept(InternalShell except)
+    {
+        Control[] children = getChildren();
+        for(int i=0; i<children.length; i++)
+        {
+            Control c = children[i];
+            if(c is except) continue;
+            if(cast(InternalShell)c !is null && c.isVisible())
+            {
+                InternalShell ishell = cast(InternalShell)c;
+                activate(ishell);
+                return ishell;
+            }
+        }
+        activeShell = null;
+        notifyDesktopListenersActivate(null);
+        return null;
+    }
+
+
+    void activate(InternalShell ishell)
+    {
+        if(ishell is activeShell) return;
+        checkWidget();
+        if(ishell !is null)
+        {
+            if(!ishell.isVisible()) ishell.setVisible(true);
+            if((ishell.getStyle() & DWT.ON_TOP) !is 0)
+                ishell.moveAbove(null);
+            else
+            {
+                InternalShell firstRegular = getTopmostRegularShell();
+                if(firstRegular !is null && firstRegular !is ishell) ishell.moveAbove(firstRegular);
+                else
+                {
+                    Control[] children = getChildren();
+                    if(children.length > 0) ishell.moveAbove(children[0]);
+                }
+            }
+        }
+        InternalShell oldActiveShell = activeShell;
+        activeShell = ishell;
+        if(oldActiveShell !is null) oldActiveShell.redrawDecorationsAfterActivityChange();
+        if(ishell !is null)
+        {
+            if(activeShell.isVisible()) activeShell.redrawDecorationsAfterActivityChange();
+            setTabList(/**new Control[] { activeShell }*/[ activeShell ]);
+            activeShell.setFocus();
+        }
+        else
+        {
+            setTabList(/**new Control[] {}*/[]);
+            forceFocus();
+        }
+        notifyDesktopListenersActivate(ishell);
+    }
+
+
+    private InternalShell getTopmostRegularShell()
+    {
+        foreach(c; getChildren())
+        {
+            if(!(cast(InternalShell)c !is null)) continue;
+            if((c.getStyle() & DWT.ON_TOP) is 0) return cast(InternalShell)c;
+        }
+        return null;
+    }
+
+
+    private InternalShell getBottommostOnTopShell()
+    {
+        Control[] ch = getChildren();
+        for(int i=ch.length-1; i>=0; i--)
+        {
+            Control c = ch[i];
+            if(!(cast(InternalShell)c !is null)) continue;
+            if((c.getStyle() & DWT.ON_TOP) !is 0) return cast(InternalShell)c;
+        }
+        return null;
+    }
+
+
+    void shellVisibilityChanged(InternalShell ishell, bool visible)
+    {
+        if(visible)
+        {
+            if(!contains(visibleShells, ishell))
+            {
+                visibleShells ~= ishell;
+                if(autoMaximize && !ishell.getMaximized() && (ishell.getStyle() & DWT.MAX) !is 0 && hasVisibleMaximizedShell())
+                    ishell.setMaximizedWithoutNotification(true);
+            }
+            if(ishell.getMaximized())
+                ishell.desktopResized(getClientArea());
+        }
+        else
+        {
+            visibleShells.remove(ishell);
+            if(ishell is activeShell)
+            {
+                activateTopmostVisibleShellExcept(ishell);
+                if(autoMaximize && !hasVisibleMaximizedShell())
+                    setAllVisibleMaximized(false);
+            }
+        }
+    }
+
+
+    private InternalShell getInternalShell(Control c, bool[] desktopHit)
+    {
+        while(c !is null && c !is /**DesktopForm.*/this)
+        {
+            if(cast(InternalShell)c !is null && (cast(InternalShell)c).getParent() is this)
+                return cast(InternalShell)c;
+            c = c.getParent();
+        }
+        if(desktopHit !is null && c is /**DesktopForm.*/this) desktopHit[0] = true;
+        return null;
+    }
+
+
+    public InternalShell getActiveShell()
+    {
+        return activeShell;
+    }
+
+
+    public InternalShell[] getVisibleShells()
+    {
+        checkWidget();
+        return visibleShells;
+    }
+
+
+    public InternalShell[] getShells()
+    {
+        checkWidget();
+        return allShells;
+    }
+
+
+    public void setShowMaximizedTitle(bool b)
+    {
+        checkWidget();
+        showMaximizedTitle = b;
+        Rectangle ca = getClientArea();
+        foreach(c; getChildren())
+        {
+            if(cast(InternalShell)c !is null)
+                (cast(InternalShell)c).desktopResized(ca);
+        }
+    }
+
+
+    public bool getShowMaximizedTitle()
+    {
+        checkWidget();
+        return showMaximizedTitle;
+    }
+
+
+    public void setAutoMaximize(bool b)
+    {
+        checkWidget();
+        autoMaximize = b;
+        bool hasMax = false;
+        foreach(ins; visibleShells)
+        {
+            if(ins.getMaximized())
+            {
+                hasMax = true;
+                break;
+            }
+        }
+        if(hasMax)
+        {
+            // Maximize all shells
+            foreach(ins; visibleShells)
+            {
+                if((ins.getStyle() & DWT.MAX) !is 0) ins.setMaximized(true);
+            }
+        }
+    }
+
+
+    public bool getAutoMaximize()
+    {
+        checkWidget();
+        return autoMaximize;
+    }
+
+
+    public void setEnableCtrlTab(bool b)
+    {
+        checkWidget();
+        this.enableCtrlTab = b;
+    }
+
+
+    public bool getEnableCtrlTab()
+    {
+        return enableCtrlTab;
+    }
+
+
+    public void setAllowDeactivate(bool b)
+    {
+        checkWidget();
+        this.allowDeactivate = b;
+        if(!allowDeactivate && activeShell is null)
+            activateTopmostVisibleShellExcept(null);
+    }
+
+
+    public bool getAllowDeactivate()
+    {
+        return allowDeactivate;
+    }
+
+
+    void shellMaximizedOrRestored(InternalShell ishell, bool maximized)
+    {
+        setAllVisibleMaximized(maximized);
+    }
+
+
+    private void setAllVisibleMaximized(bool maximized)
+    {
+        if(autoMaximize) // maximize or restore all shells
+        {
+            foreach(c; getChildren())
+            {
+                if(cast(InternalShell)c !is null)
+                {
+                    InternalShell ishell = cast(InternalShell)c;
+                    if((ishell.getStyle() & DWT.MAX) !is 0 && ishell.isVisible())
+                        (cast(InternalShell)c).setMaximizedWithoutNotification(maximized);
+                }
+            }
+        }
+    }
+
+
+    private void activateNextShell()
+    {
+        if(activeShell is null)
+        {
+            activateTopmostVisibleShellExcept(null);
+            return;
+        }
+        if(visibleShells.length < 2) return;
+        InternalShell topReg = getTopmostRegularShell();
+        InternalShell botTop = getBottommostOnTopShell();
+        if((activeShell.getStyle() & DWT.ON_TOP) !is 0)
+        {
+            activeShell.moveBelow(botTop);
+            if(topReg !is null) activate(topReg);
+            else activateTopmostVisibleShellExcept(null);
+        }
+        else
+        {
+            activeShell.moveBelow(null);
+            activateTopmostVisibleShellExcept(null);
+        }
+    }
+
+
+    private void activatePreviousShell()
+    {
+        if(activeShell is null)
+        {
+            activateTopmostVisibleShellExcept(null);
+            return;
+        }
+        if(visibleShells.length < 2) return;
+        InternalShell topReg = getTopmostRegularShell();
+        InternalShell botTop = getBottommostOnTopShell();
+        if(activeShell is topReg && botTop !is null) activate(botTop);
+        else
+        {
+            Control[] ch = getChildren();
+            for(int i=ch.length-1; i>=0; i--)
+            {
+                if(cast(InternalShell)ch[i] !is null && ch[i].isVisible())
+                {
+                    activate(cast(InternalShell)ch[i]);
+                    break;
+                }
+            }
+        }
+    }
+
+
+    public void addDesktopListener(DesktopListener l)
+    {
+        desktopListeners ~= l;
+    }
+
+
+    public void removeDesktopListener(DesktopListener l)
+    {
+        desktopListeners.remove(l);
+    }
+
+
+    private void notifyDesktopListenersCreate(InternalShell ishell)
+    {
+        Event event = new Event();
+        event.widget = ishell;
+        foreach(l; desktopListeners) l.shellCreated(event);
+    }
+
+
+    private void notifyDesktopListenersDispose(InternalShell ishell)
+    {
+        Event event = new Event();
+        event.widget = ishell;
+        foreach(l; desktopListeners) l.shellDisposed(event);
+    }
+
+
+    private void notifyDesktopListenersActivate(InternalShell ishell)
+    {
+        Event event = new Event();
+        event.widget = ishell;
+        foreach(l; desktopListeners) l.shellActivated(event);
+    }
+
+
+    private bool hasVisibleMaximizedShell()
+    {
+        foreach(ins; visibleShells)
+            if(ins.getMaximized()) return true;
+        return false;
+    }
+}