/******************************************************************************* * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com> * Copyright (C) 2011, Dariusz Luksza <dariusz.luksza@gmail.com> * * 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 *******************************************************************************/ package org.eclipse.egit.ui.internal.components; import static org.eclipse.jface.resource.ImageDescriptor.createFromImageData; import static org.eclipse.jface.resource.JFaceResources.getResources; import org.eclipse.core.runtime.Platform; import org.eclipse.egit.ui.internal.UIIcons; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** * Label provider displaying native check boxes images for boolean values. * Label-image is centralized. * <p> * Concrete implementations must provide object to boolean mapping. * <p> * This implementation is actually workaround for lacking features in * TableViewer. It is based on (workaround) snippets&tricks found on Internet. */ public abstract class CheckboxLabelProvider extends CenteredImageLabelProvider { private static class CheckBoxImages { private final Image checkedEnabled; private final Image uncheckedEnabled; private final Image checkedDisabled; private final Image uncheckedDisabled; public CheckBoxImages(Image checkedEnabled, Image uncheckedEnabled, Image checkedDisabled, Image uncheckedDisabled) { this.checkedEnabled = checkedEnabled; this.uncheckedEnabled = uncheckedEnabled; this.checkedDisabled = checkedDisabled; this.uncheckedDisabled = uncheckedDisabled; } } private final CheckBoxImages checkBoxes; private final LocalResourceManager resourceManager; private static CheckBoxImages createCheckboxImage( ResourceManager resourceManager, Control control) { String checkboxhack = System.getProperty("egit.swt.checkboxhack"); //$NON-NLS-1$ if (checkboxhack == null) if (Platform.getOS().equals(Platform.OS_MACOSX)) checkboxhack = "hardwired"; //$NON-NLS-1$ else checkboxhack = "screenshot"; //$NON-NLS-1$ if ("hardwired".equals(checkboxhack)) //$NON-NLS-1$ return new CheckBoxImages( UIIcons.CHECKBOX_ENABLED_CHECKED.createImage(), UIIcons.CHECKBOX_ENABLED_UNCHECKED.createImage(), UIIcons.CHECKBOX_DISABLED_CHECKED.createImage(), UIIcons.CHECKBOX_DISABLED_UNCHECKED.createImage()); Shell shell = new Shell(control.getShell(), SWT.NO_TRIM); // Hopefully no platform uses exactly this color because we'll make // it transparent in the image. Color gray = resourceManager.createColor(new RGB(222, 223, 224)); Composite composite = new Composite(shell, SWT.NONE); RowLayout layout = new RowLayout(); layout.marginTop = 0; layout.marginLeft = 0; layout.marginBottom = 0; layout.marginRight = 0; layout.spacing = 0; composite.setLayout(layout); createButton(composite, gray, true, true); createButton(composite, gray, false, true); createButton(composite, gray, true, false); createButton(composite, gray, false, false); Point cSize = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); composite.setSize(cSize); shell.setBackground(gray); shell.setLocation(0, 0); shell.setSize(cSize); Display display = shell.getShell().getDisplay(); shell.open(); Image canvas = new Image(display, cSize.x, cSize.y); GC gc = new GC(canvas); composite.print(gc); int buttonX = cSize.x / 4; Image[] images = new Image[4]; for (int i = 0; i < 4; i++) { Image image = new Image(display, buttonX, cSize.y); gc.copyArea(image, buttonX * i, 0); images[i] = getImage(resourceManager, gray, image); } canvas.dispose(); gc.dispose(); shell.close(); return new CheckBoxImages(images[0], images[1], images[2], images[3]); } private static void createButton(Composite parent, Color bgColor, boolean checked, boolean enabled) { Button button = new Button(parent, SWT.CHECK); button.setSelection(checked); button.setEnabled(enabled); button.setBackground(bgColor); Point bSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT); button.setSize(bSize); } private static Image getImage(ResourceManager rm, Color bgColor, Image img) { ImageData imageData = img.getImageData(); imageData.transparentPixel = imageData.palette.getPixel(bgColor .getRGB()); Image image = rm.createImage(createFromImageData(imageData)); img.dispose(); return image; } /** * Create label provider for provided viewer. * * @param control * viewer where label provided is used. */ public CheckboxLabelProvider(final Control control) { resourceManager = new LocalResourceManager(getResources()); checkBoxes = createCheckboxImage(resourceManager, control); } @Override protected Image getImage(final Object element) { if (isEnabled(element)) { if (isChecked(element)) return checkBoxes.checkedEnabled; return checkBoxes.uncheckedEnabled; } else { if (isChecked(element)) return checkBoxes.checkedDisabled; return checkBoxes.uncheckedDisabled; } } @Override public void dispose() { resourceManager.dispose(); super.dispose(); } /** * @param element * element to provide label for. * @return true if checkbox label should be checked for this element, false * otherwise. */ protected abstract boolean isChecked(Object element); /** * Default implementation always return true. * * @param element * element to provide label for. * @return true if checkbox label should be enabled for this element, false * otherwise. */ protected boolean isEnabled(final Object element) { return true; } }