Mercurial > projects > dwt-addons
diff dwtx/draw2d/AncestorHelper.d @ 98:95307ad235d9
Added Draw2d code, still work in progress
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 03 Aug 2008 00:52:14 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/draw2d/AncestorHelper.d Sun Aug 03 00:52:14 2008 +0200 @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation 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.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.draw2d.AncestorHelper; + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Bean; + +import dwtx.draw2d.IFigure; +import dwtx.draw2d.FigureListener; +import dwtx.draw2d.AncestorListener; + +/** + * A helper object which tracks the parent chain hierarchy. + * @since 2.1 + */ +class AncestorHelper + : PropertyChangeListener, FigureListener +{ + +/** + * The base figure whose ancestor chain is being observed. + */ +protected final IFigure base; +/** + * The array of ancestor listeners. + */ +protected AncestorListener[] listeners; + +/** + * Constructs a new helper on the given base figure and starts listening to figure and + * property changes on the base figure's parent chain. When no longer needed, the helper + * should be disposed. + * @since 2.1 + * @param baseFigure + */ +public this(IFigure baseFigure) { + this.base = baseFigure; + addAncestors(baseFigure); +} + +/** + * Appends a new listener to the list of listeners. + * @param listener the listener + */ +public void addAncestorListener(AncestorListener listener) { + if (listeners is null) { + listeners = new AncestorListener[1]; + listeners[0] = listener; + } else { + int oldSize = listeners.length; + AncestorListener newListeners[] = new AncestorListener[oldSize + 1]; + SimpleType!(AncestorListener).arraycopy(listeners, 0, newListeners, 0, oldSize); + newListeners[oldSize] = listener; + listeners = newListeners; + } +} + +/** + * Hooks up internal listeners used for maintaining the proper figure listeners. + * @param rootFigure the root figure + */ +protected void addAncestors(IFigure rootFigure) { + for (IFigure ancestor = rootFigure; + ancestor !is null; + ancestor = ancestor.getParent()) { + ancestor.addFigureListener(this); + ancestor.addPropertyChangeListener("parent", this); //$NON-NLS-1$ + } +} + +/** + * Removes all internal listeners. + */ +public void dispose() { + removeAncestors(base); + listeners = null; +} + +/** + * @see dwtx.draw2d.FigureListener#figureMoved(dwtx.draw2d.IFigure) + */ +public void figureMoved(IFigure ancestor) { + fireAncestorMoved(ancestor); +} + +/** + * Fires notification to the listener list + * @param ancestor the figure which moved + */ +protected void fireAncestorMoved(IFigure ancestor) { + if (listeners is null) + return; + for (int i = 0; i < listeners.length; i++) + listeners[i].ancestorMoved(ancestor); +} + +/** + * Fires notification to the listener list + * @param ancestor the figure which moved + */ +protected void fireAncestorAdded(IFigure ancestor) { + if (listeners is null) + return; + for (int i = 0; i < listeners.length; i++) + listeners[i].ancestorAdded(ancestor); +} + +/** + * Fires notification to the listener list + * @param ancestor the figure which moved + */ +protected void fireAncestorRemoved(IFigure ancestor) { + if (listeners is null) + return; + for (int i = 0; i < listeners.length; i++) + listeners[i].ancestorRemoved(ancestor); +} + +/** + * Returns the total number of listeners. + * @return the number of listeners + */ +public bool isEmpty() { + return listeners is null; +} + +/** + * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) + */ +public void propertyChange(PropertyChangeEvent event) { + if (event.getPropertyName().equals("parent")) { //$NON-NLS-1$ + IFigure oldParent = cast(IFigure)event.getOldValue(); + IFigure newParent = cast(IFigure)event.getNewValue(); + if (oldParent !is null) { + removeAncestors(oldParent); + fireAncestorRemoved(oldParent); + } + if (newParent !is null) { + addAncestors(newParent); + fireAncestorAdded(newParent); + } + } +} + +/** + * Removes the first occurence of the given listener + * @param listener the listener to remove + */ +public void removeAncestorListener(AncestorListener listener) { + if (listeners is null) + return; + for (int index = 0; index < listeners.length; index++) + if (listeners[index] is listener) { + int newSize = listeners.length - 1; + AncestorListener newListeners[] = null; + if (newSize !is 0) { + newListeners = new AncestorListener[newSize]; + SimpleType!(AncestorListener).arraycopy(listeners, 0, newListeners, 0, index); + SimpleType!(AncestorListener).arraycopy(listeners, index + 1, newListeners, index, newSize - index); + } + listeners = newListeners; + return; + } +} + +/** + * Unhooks listeners starting at the given figure + * @param rootFigure + */ +protected void removeAncestors(IFigure rootFigure) { + for (IFigure ancestor = rootFigure; + ancestor !is null; + ancestor = ancestor.getParent()) { + ancestor.removeFigureListener(this); + ancestor.removePropertyChangeListener("parent", this); //$NON-NLS-1$ + } +} + +}