blob: 5b9abcb90bf0fb93f455cd6898ab28e80d572969 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package org.eclipse.jface.commands;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.commands.common.EventManager;
import org.eclipse.jface.resource.ImageDescriptor;
/**
* <p>
* A central lookup facility for images for commands. Images can be associated
* with commands using this manager.
* </p>
* <p>
* Clients may instantiate, but must not extend.
* </p>
* <p>
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is a guarantee neither that this API will
* work nor that it will remain the same. Please do not use this API without
* consulting with the Platform/UI team.
* </p>
*
* @since 3.2
*/
public final class CommandImageManager extends EventManager {
/**
* The type of image to display in the default case.
*/
public static final int TYPE_DEFAULT = 0;
/**
* The type of image to display if the corresponding command is disabled.
*/
public static final int TYPE_DISABLED = 1;
/**
* The type of image to display if the mouse is hovering over the command
* and the command is enabled.
*/
public static final int TYPE_HOVER = 2;
/**
* The map of command identifiers (<code>String</code>) to images. The
* images are an array indexed by type. The values in the array are either
* an <code>ImageDescriptor</code> or a <code>Map</code> of style (<code>String</code>)
* to <code>ImageDescriptor</code>.
*/
private final Map imagesById = new HashMap();
/**
* Adds a listener to this command image manager. The listener will be
* notified when the set of image bindings changes. This can be used to
* track the global appearance and disappearance of image bindings.
*
* @param listener
* The listener to attach; must not be <code>null</code>.
*/
public final void addCommandImageManagerListener(
final ICommandImageManagerListener listener) {
addListenerObject(listener);
}
/**
* Binds a particular image path to a command id, type and style triple
*
* @param commandId
* The identifier of the command to which the image should be
* bound; must not be <code>null</code>.
* @param type
* The type of image to retrieve. This value must be one of the
* <code>TYPE</code> constants defined in this class.
* @param style
* The style of the image; may be <code>null</code>.
* @param url
* The URL to the image. Should not be <code>null</code>.
*/
public final void bind(final String commandId, final int type,
final String style, final URL url) {
final ImageDescriptor descriptor = ImageDescriptor.createFromURL(url);
bind(commandId, type, style, descriptor);
}
/**
* Binds a particular image path to a command id, type and style triple
*
* @param commandId
* The identifier of the command to which the image should be
* bound; must not be <code>null</code>.
* @param type
* The type of image to retrieve. This value must be one of the
* <code>TYPE</code> constants defined in this class.
* @param style
* The style of the image; may be <code>null</code>.
* @param descriptor
* The image descriptor. Should not be <code>null</code>.
*/
public final void bind(final String commandId, final int type,
final String style, final ImageDescriptor descriptor) {
Object[] images = (Object[]) imagesById.get(commandId);
if (images == null) {
images = new Object[3];
imagesById.put(commandId, images);
}
if ((type < 0) || (type >= images.length)) {
throw new IllegalArgumentException(
"The type must be one of TYPE_DEFAULT, TYPE_DISABLED and TYPE_HOVER."); //$NON-NLS-1$
}
final Object typedImage = images[type];
if (style == null) {
if ((typedImage == null) || (typedImage instanceof ImageDescriptor)) {
images[type] = descriptor;
} else if (typedImage instanceof Map) {
final Map styleMap = (Map) typedImage;
styleMap.put(style, descriptor);
}
} else {
if (typedImage instanceof Map) {
final Map styleMap = (Map) typedImage;
styleMap.put(style, descriptor);
} else if (typedImage instanceof ImageDescriptor) {
final Map styleMap = new HashMap();
styleMap.put(null, typedImage);
styleMap.put(style, descriptor);
images[type] = descriptor;
}
}
fireManagerChanged(new CommandImageManagerEvent(this,
new String[] { commandId }, type, style));
}
/**
* Removes all of the images from this manager.
*/
public final void clear() {
imagesById.clear();
if (isListenerAttached()) {
final String[] commandIds = (String[]) imagesById.keySet().toArray(
new String[imagesById.size()]);
fireManagerChanged(new CommandImageManagerEvent(this, commandIds,
TYPE_DEFAULT, null));
}
}
/**
* Notifies all of the listeners to this manager that the image bindings
* have changed.
*
* @param event
* The event to send to all of the listeners; must not be
* <code>null</code>.
*/
private final void fireManagerChanged(final CommandImageManagerEvent event) {
if (event == null)
throw new NullPointerException();
final Object[] listeners = getListeners();
for (int i = 0; i < listeners.length; i++) {
final ICommandImageManagerListener listener = (ICommandImageManagerListener) listeners[i];
listener.commandImageManagerChanged(event);
}
}
/**
* Generates a style tag that is not currently used for the given command.
* This can be used by applications trying to create a unique style for a
* new set of images.
*
* @param commandId
* The identifier of the command for which a unique style is
* required; must not be <code>null</code>.
* @return A style tag that is not currently used; may be <code>null</code>.
*/
public final String generateUnusedStyle(final String commandId) {
final Object[] existingImages = (Object[]) imagesById.get(commandId);
if (existingImages == null) {
return null;
}
final Set existingStyles = new HashSet(3);
for (int type = 0; type < existingImages.length; type++) {
final Object styledImages = existingImages[type];
if (styledImages instanceof ImageDescriptor) {
existingStyles.add(null);
} else if (styledImages instanceof Map) {
final Map styleMap = (Map) styledImages;
existingStyles.addAll(styleMap.keySet());
}
}
if (!existingStyles.contains(null)) {
return null;
}
String generatedStyle = "AUTOGEN:::"; //$NON-NLS-1$
int index = 0;
while (existingStyles.contains(generatedStyle)) {
generatedStyle += (index++ % 10);
}
return generatedStyle;
}
/**
* Retrieves the default image associated with the given command in the
* default style.
*
* @param commandId
* The identifier to find; must not be <code>null</code>.
* @return An image appropriate for the given command; never
* <code>null</code>.
*/
public final ImageDescriptor getImageDescriptor(final String commandId) {
return getImageDescriptor(commandId, TYPE_DEFAULT, null);
}
/**
* Retrieves the image of the given type associated with the given command
* in the default style.
*
* @param commandId
* The identifier to find; must not be <code>null</code>.
* @param type
* The type of image to retrieve. This value must be one of the
* <code>TYPE</code> constants defined in this class.
* @return An image appropriate for the given command; <code>null</code>
* if the given image type cannot be found.
*/
public final ImageDescriptor getImageDescriptor(final String commandId,
final int type) {
return getImageDescriptor(commandId, type, null);
}
/**
* Retrieves the image of the given type associated with the given command
* in the given style.
*
* @param commandId
* The identifier to find; must not be <code>null</code>.
* @param type
* The type of image to retrieve. This value must be one of the
* <code>TYPE</code> constants defined in this class.
* @param style
* The style of the image to retrieve; may be <code>null</code>.
* @return An image appropriate for the given command; <code>null</code>
* if the given image style and type cannot be found.
*/
public final ImageDescriptor getImageDescriptor(final String commandId,
final int type, final String style) {
if (commandId == null)
throw new NullPointerException();
final Object[] images = (Object[]) imagesById.get(commandId);
if (images == null) {
return null;
}
if ((type < 0) || (type >= images.length)) {
throw new IllegalArgumentException(
"The type must be one of TYPE_DEFAULT, TYPE_DISABLED and TYPE_HOVER."); //$NON-NLS-1$
}
Object typedImage = images[type];
if (typedImage == null) {
typedImage = images[TYPE_DEFAULT];
}
if (typedImage instanceof ImageDescriptor) {
return (ImageDescriptor) typedImage;
}
if (typedImage instanceof Map) {
final Map styleMap = (Map) typedImage;
Object styledImage = styleMap.get(style);
if (styledImage instanceof ImageDescriptor) {
return (ImageDescriptor) styledImage;
}
if (style != null) {
styledImage = styleMap.get(null);
if (styledImage instanceof ImageDescriptor) {
return (ImageDescriptor) styledImage;
}
}
}
return null;
}
/**
* Retrieves the default image associated with the given command in the
* given style.
*
* @param commandId
* The identifier to find; must not be <code>null</code>.
* @param style
* The style of the image to retrieve; may be <code>null</code>.
* @return An image appropriate for the given command; <code>null</code>
* if the given image style cannot be found.
*/
public final ImageDescriptor getImageDescriptor(final String commandId,
final String style) {
return getImageDescriptor(commandId, TYPE_DEFAULT, style);
}
/**
* Removes a listener from this command image manager.
*
* @param listener
* The listener to be removed; must not be <code>null</code>.
*/
public final void removeCommandImageManagerListener(
final ICommandImageManagerListener listener) {
removeListenerObject(listener);
}
}