Mercurial > projects > dwt-addons
view 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 source
/******************************************************************************* * 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; } }