view dwtx/jface/resource/ColorRegistry.d @ 43:ea8ff534f622

Fix override and super aliases
author Frank Benoit <benoit@tionex.de>
date Fri, 11 Apr 2008 01:24:25 +0200
parents 6c14e54dfc11
children 46a6e0e6ccd4
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2003, 2006 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.jface.resource.ColorRegistry;

import dwtx.jface.resource.ResourceRegistry;
import dwtx.jface.resource.ColorDescriptor;

import tango.util.collection.ArraySeq;
import tango.util.collection.HashMap;
import tango.util.collection.HashSet;
import tango.util.collection.model.Map;
import tango.util.collection.model.Set;
import tango.util.collection.model.SetView;
import tango.util.collection.model.Seq;

import dwt.graphics.Color;
import dwt.graphics.RGB;
import dwt.widgets.Display;
import dwtx.core.runtime.Assert;

import dwt.dwthelper.utils;
import dwt.dwthelper.Runnable;

/**
 * A color registry maintains a mapping between symbolic color names and DWT
 * <code>Color</code>s.
 * <p>
 * A color registry owns all of the <code>Color</code> objects registered with
 * it, and automatically disposes of them when the DWT Display that creates the
 * <code>Color</code>s is disposed. Because of this, clients do not need to
 * (indeed, must not attempt to) dispose of <code>Color</code> objects
 * themselves.
 * </p>
 * <p>
 * Methods are provided for registering listeners that will be kept
 * apprised of changes to list of registed colors.
 * </p>
 * <p>
 * Clients may instantiate this class (it was not designed to be subclassed).
 * </p>
 *
 * @since 3.0
 */
public class ColorRegistry : ResourceRegistry {

    /**
     * This registries <code>Display</code>. All colors will be allocated using
     * it.
     */
    protected Display display;

    /**
     * Collection of <code>Color</code> that are now stale to be disposed when
     * it is safe to do so (i.e. on shutdown).
     */
    private Seq!(Color) staleColors;

    /**
     * Table of known colors, keyed by symbolic color name (key type: <code>String</code>,
     * value type: <code>dwt.graphics.Color</code>.
     */
    private Map!(String,Color) stringToColor;

    /**
     * Table of known color data, keyed by symbolic color name (key type:
     * <code>String</code>, value type: <code>dwt.graphics.RGB</code>).
     */
    private Map!(String,RGB) stringToRGB;

    /**
     * Runnable that cleans up the manager on disposal of the display.
     */
    protected Runnable displayRunnable;
    private void init_displayRunnable(){
        displayRunnable = new class Runnable {
            public void run() {
                clearCaches();
            }
        };
    }

    /**
     * Create a new instance of the receiver that is hooked to the current
     * display.
     *
     * @see dwt.widgets.Display#getCurrent()
     */
    public this() {
        this(Display.getCurrent(), true);
    }

    /**
     * Create a new instance of the receiver.
     *
     * @param display the <code>Display</code> to hook into.
     */
    public this(Display display) {
        this (display, true);
    }

    /**
     * Create a new instance of the receiver.
     *
     * @param display the <code>Display</code> to hook into
     * @param cleanOnDisplayDisposal
     *            whether all fonts allocated by this <code>ColorRegistry</code>
     *            should be disposed when the display is disposed
     * @since 3.1
     */
    public this(Display display, bool cleanOnDisplayDisposal) {
        staleColors = new ArraySeq!(Color);
        stringToColor = new HashMap!(String,Color);
        stringToRGB = new HashMap!(String,RGB);
        init_displayRunnable();
        Assert.isNotNull(display);
        this.display = display;
        if (cleanOnDisplayDisposal) {
            hookDisplayDispose();
        }
    }

    /**
     * Create a new <code>Color</code> on the receivers <code>Display</code>.
     *
     * @param rgb the <code>RGB</code> data for the color.
     * @return the new <code>Color</code> object.
     *
     * @since 3.1
     */
    private Color createColor(RGB rgb) {
        return new Color(display, rgb);
    }

    /**
     * Dispose of all of the <code>Color</code>s in this iterator.
     *
     * @param iterator over <code>Collection</code> of <code>Color</code>
     */
    /+
    private void disposeColors(Iterator iterator) {
        while (iterator.hasNext()) {
            Object next = iterator.next();
            ((Color) next).dispose();
        }
    }
    +/

    /**
     * Returns the <code>color</code> associated with the given symbolic color
     * name, or <code>null</code> if no such definition exists.
     *
     * @param symbolicName symbolic color name
     * @return the <code>Color</code> or <code>null</code>
     */
    public Color get(String symbolicName) {

        Assert.isNotNull(symbolicName);
        auto result1 = stringToColor.get(symbolicName);
        if (result1 !is null) {
            return result1;
        }

        Color color = null;

        auto result = stringToRGB.get(symbolicName);
        if (result is null) {
            return null;
        }

        color = createColor(result);

        stringToColor.add(symbolicName, color);

        return color;
    }

    /* (non-Javadoc)
     * @see dwtx.jface.resource.ResourceRegistry#getKeySet()
     */
    public override SetView!(String) getKeySet() {
        auto res = new HashSet!(String);
        foreach( k,v; stringToRGB ){
            res.add(k);
        }
        return res;
    }

    /**
     * Returns the color data associated with the given symbolic color name.
     *
     * @param symbolicName symbolic color name.
     * @return the <code>RGB</code> data.
     */
    public RGB getRGB(String symbolicName) {
        Assert.isNotNull(symbolicName);
        return stringToRGB.get(symbolicName);
    }

    /**
     * Returns the color descriptor associated with the given symbolic color name.
     * @since 3.1
     *
     * @param symbolicName
     * @return the color descriptor associated with the given symbolic color name.
     */
    public ColorDescriptor getColorDescriptor(String symbolicName) {
        return ColorDescriptor.createFrom(getRGB(symbolicName));
    }

    /* (non-Javadoc)
     * @see dwtx.jface.resource.ResourceRegistry#clearCaches()
     */
    protected override void clearCaches() {
        foreach( k, v; stringToColor ){
            v.dispose();
        }
        foreach( v; staleColors ){
            v.dispose();
        }
//         disposeColors(stringToColor.values().iterator());
//         disposeColors(staleColors.iterator());
        stringToColor.clear();
        staleColors.clear();
    }

    /* (non-Javadoc)
     * @see dwtx.jface.resource.ResourceRegistry#hasValueFor(java.lang.String)
     */
    public override bool hasValueFor(String colorKey) {
        return stringToRGB.containsKey(colorKey);
    }

    /**
     * Hook a dispose listener on the DWT display.
     */
    private void hookDisplayDispose() {
        display.disposeExec(displayRunnable);
    }

    /**
     * Adds (or replaces) a color to this color registry under the given
     * symbolic name.
     * <p>
     * A property change event is reported whenever the mapping from a symbolic
     * name to a color changes. The source of the event is this registry; the
     * property name is the symbolic color name.
     * </p>
     *
     * @param symbolicName the symbolic color name
     * @param colorData an <code>RGB</code> object
     */
    public void put(String symbolicName, RGB colorData) {
        put(symbolicName, colorData, true);
    }

    /**
     * Adds (or replaces) a color to this color registry under the given
     * symbolic name.
     * <p>
     * A property change event is reported whenever the mapping from a symbolic
     * name to a color changes. The source of the event is this registry; the
     * property name is the symbolic color name.
     * </p>
     *
     * @param symbolicName the symbolic color name
     * @param colorData an <code>RGB</code> object
     * @param update - fire a color mapping changed if true. False if this
     *            method is called from the get method as no setting has
     *            changed.
     */
    private void put(String symbolicName, RGB colorData, bool update) {

        Assert.isNotNull(symbolicName);
        Assert.isNotNull(colorData);

        RGB existing = stringToRGB.get(symbolicName);
        if (colorData.opEquals(existing)) {
            return;
        }

        Color oldColor = stringToColor.get(symbolicName);
        stringToColor.removeKey(symbolicName);
        stringToRGB.add(symbolicName, colorData);
        if (update) {
            fireMappingChanged(symbolicName, existing, colorData);
        }

        if (oldColor !is null) {
            staleColors.append(oldColor);
        }
    }
}