From 117a55835805938033459cd44f362950d5fb3d16 Mon Sep 17 00:00:00 2001 From: Robin Rosenberg Date: Thu, 21 Aug 2008 22:29:42 +0200 Subject: [PATCH] Provide a checkbox component for embedding in a table. This is needed by the Refspecs page. Unfortunately the code does not work fine with Eclipse 3.3 (no image show) and the screen scraping approach flickers horribly under OSX so we provide our own icon (stolen from the Eclipse CVS archive at pde-incubator/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/images) plus some graying out for the disbled version, thereby solving the licensing issue. Set the system property egit.swt.checkboxhack to switch behavior. -Degit.swt.checkboxhack=hardwired will use the supplied icons without regard for look and feel. -Degit.swt.checkboxhack=screenshot will grab the L&F from the native SWT checkbox. Signed-off-by: Robin Rosenberg --- .../icons/checkboxes/disabled_checked.gif | Bin 0 -> 106 bytes .../icons/checkboxes/disabled_unchecked.gif | Bin 0 -> 96 bytes .../icons/checkboxes/enabled_checked.gif | Bin 0 -> 874 bytes .../icons/checkboxes/enabled_unchecked.gif | Bin 0 -> 856 bytes .../src/org/spearce/egit/ui/UIIcons.java | 13 ++ .../components/CenteredImageLabelProvider.java | 52 +++++++ .../internal/components/CheckboxLabelProvider.java | 155 +++++++++++++++++++++ 7 files changed, 220 insertions(+) create mode 100644 org.spearce.egit.ui/icons/checkboxes/disabled_checked.gif create mode 100644 org.spearce.egit.ui/icons/checkboxes/disabled_unchecked.gif create mode 100644 org.spearce.egit.ui/icons/checkboxes/enabled_checked.gif create mode 100644 org.spearce.egit.ui/icons/checkboxes/enabled_unchecked.gif create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CenteredImageLabelProvider.java create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CheckboxLabelProvider.java diff --git a/org.spearce.egit.ui/icons/checkboxes/disabled_checked.gif b/org.spearce.egit.ui/icons/checkboxes/disabled_checked.gif new file mode 100644 index 0000000000000000000000000000000000000000..47b9e321da2e01222a3a13bc70fb3fcae393fe59 GIT binary patch literal 106 zcwTe&bhEHbGBE3FY`Ei~ zaKe+7MGBB%ZY`Ei~ oaKe+7Mz~O)DJU>l0|4NC6x;v+ literal 0 HcwPel00001 diff --git a/org.spearce.egit.ui/icons/checkboxes/enabled_unchecked.gif b/org.spearce.egit.ui/icons/checkboxes/enabled_unchecked.gif new file mode 100644 index 0000000000000000000000000000000000000000..4399d9105f6f8a27d2fabf4f4b8c26f4c912c05c GIT binary patch literal 856 zcwTe&bhEHb(+DU&Rx59?*Awl1tSdTFaQB4FEDV}GO)5pcx*^u zU}9v@h&d6!;Kab95Fr2n literal 0 HcwPel00001 diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java index ba14df37..7fe6e36e 100644 --- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIIcons.java @@ -56,6 +56,15 @@ public class UIIcons { /** Clear icon */ public static final ImageDescriptor ELCL16_CLEAR; + /** Enabled, checked, checkbox image */ + public static final ImageDescriptor CHECKBOX_ENABLED_CHECKED; + /** Enabled, unchecked, checkbox image */ + public static final ImageDescriptor CHECKBOX_ENABLED_UNCHECKED; + /** Disabled, checked, checkbox image */ + public static final ImageDescriptor CHECKBOX_DISABLED_CHECKED; + /** Disabled, unchecked, checkbox image */ + public static final ImageDescriptor CHECKBOX_DISABLED_UNCHECKED; + /** Import Wizard banner */ public static final ImageDescriptor WIZBAN_IMPORT_REPO; @@ -80,6 +89,10 @@ public class UIIcons { ELCL16_ADD = map("elcl16/add.gif"); ELCL16_TRASH = map("elcl16/trash.gif"); ELCL16_CLEAR = map("elcl16/clear.gif"); + CHECKBOX_ENABLED_CHECKED = map("checkboxes/enabled_checked.gif"); + CHECKBOX_ENABLED_UNCHECKED = map("checkboxes/enabled_unchecked.gif"); + CHECKBOX_DISABLED_CHECKED = map("checkboxes/disabled_checked.gif"); + CHECKBOX_DISABLED_UNCHECKED = map("checkboxes/disabled_unchecked.gif"); } private static ImageDescriptor map(final String icon) { diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CenteredImageLabelProvider.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CenteredImageLabelProvider.java new file mode 100644 index 00000000..8752a608 --- /dev/null +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CenteredImageLabelProvider.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (C) 2008, Marek Zawirski + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * See LICENSE for the full license text, also available. + *******************************************************************************/ +package org.spearce.egit.ui.internal.components; + +import org.eclipse.jface.viewers.OwnerDrawLabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.TableItem; + +/** + * Label provider displaying image centered. + *

+ * This implementation is actually workaround for lacking SWT/JFace features. + * Code is based on official snippet found on Internet. + */ +// FIXME: doesn't work on Mac OS X 10.5 / Eclipse 3.3 +public abstract class CenteredImageLabelProvider extends OwnerDrawLabelProvider { + /** + * @param element + * element to provide label for. + * @return image for provided element. + */ + protected abstract Image getImage(final Object element); + + @Override + protected void measure(Event event, Object element) { + // empty + } + + @Override + protected void paint(final Event event, final Object element) { + final Image image = getImage(element); + final Rectangle bounds = ((TableItem) event.item) + .getBounds(event.index); + final Rectangle imgBounds = image.getBounds(); + bounds.width /= 2; + bounds.width -= imgBounds.width / 2; + bounds.height /= 2; + bounds.height -= imgBounds.height / 2; + + final int x = bounds.width > 0 ? bounds.x + bounds.width : bounds.x; + final int y = bounds.height > 0 ? bounds.y + bounds.height : bounds.y; + + event.gc.drawImage(image, x, y); + } +} diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CheckboxLabelProvider.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CheckboxLabelProvider.java new file mode 100644 index 00000000..75970ea0 --- /dev/null +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/components/CheckboxLabelProvider.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (C) 2008, Marek Zawirski + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * See LICENSE for the full license text, also available. + *******************************************************************************/ +package org.spearce.egit.ui.internal.components; + +import org.eclipse.core.runtime.Platform; +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.widgets.Button; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.spearce.egit.ui.UIIcons; + +/** + * Label provider displaying native check boxes images for boolean values. + * Label-image is centralized. + *

+ * Concrete implementations must provide object to boolean mapping. + *

+ * 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 Image createCheckboxImage(final Control control, + boolean checked, boolean enabled) { + + String checkboxhack = System.getProperty("egit.swt.checkboxhack"); + if (checkboxhack == null) + if (Platform.getOS().equals(Platform.OS_MACOSX)) + checkboxhack = "hardwired"; + else + checkboxhack = "screenshot"; + + if (checkboxhack == "hardwired") { + if (enabled) { + if (checked) + return UIIcons.CHECKBOX_ENABLED_CHECKED.createImage(); + return UIIcons.CHECKBOX_ENABLED_UNCHECKED.createImage(); + } + if (checked) + return UIIcons.CHECKBOX_DISABLED_CHECKED.createImage(); + return UIIcons.CHECKBOX_DISABLED_UNCHECKED.createImage(); + } + + // else if checkboxhack = "screenshot"; + + // FIXME: Shawn says that blinking shell caused by below code is very + // annoying...(at least on Mac) - anyone knows better workaround? + final Shell s = new Shell(control.getShell(), SWT.NO_TRIM); + // Hopefully no platform uses exactly this color because we'll make + // it transparent in the image. + final Color greenScreen = new Color(control.getDisplay(), 222, 223, 224); + + // otherwise we have a default gray color + s.setBackground(greenScreen); + + final Button b = new Button(s, SWT.CHECK); + b.setSelection(checked); + b.setEnabled(enabled); + b.setBackground(greenScreen); + + // otherwise an image is located in a corner + b.setLocation(0, 0); + final Point bSize = b.computeSize(SWT.DEFAULT, SWT.DEFAULT); + // otherwise an image is stretched by width + bSize.x = Math.max(bSize.x, bSize.y); + bSize.y = Math.max(bSize.x, bSize.y); + b.setSize(bSize); + s.setSize(bSize); + s.open(); + + final GC gc = new GC(b); + final Image image = new Image(control.getShell().getDisplay(), bSize.x, + bSize.y); + gc.copyArea(image, 0, 0); + gc.dispose(); + s.close(); + + final ImageData imageData = image.getImageData(); + imageData.transparentPixel = imageData.palette.getPixel(greenScreen + .getRGB()); + return new Image(control.getDisplay(), imageData); + } + + private final Image imageCheckedEnabled; + + private final Image imageUncheckedEnabled; + + private final Image imageCheckedDisabled; + + private final Image imageUncheckedDisabled; + + /** + * Create label provider for provided viewer. + * + * @param control + * viewer where label provided is used. + */ + public CheckboxLabelProvider(final Control control) { + imageCheckedEnabled = createCheckboxImage(control, true, true); + imageUncheckedEnabled = createCheckboxImage(control, false, true); + imageCheckedDisabled = createCheckboxImage(control, true, false); + imageUncheckedDisabled = createCheckboxImage(control, false, false); + } + + @Override + public void dispose() { + super.dispose(); + imageCheckedEnabled.dispose(); + imageUncheckedEnabled.dispose(); + imageCheckedDisabled.dispose(); + imageUncheckedDisabled.dispose(); + } + + @Override + protected Image getImage(final Object element) { + if (isEnabled(element)) { + if (isChecked(element)) + return imageCheckedEnabled; + return imageUncheckedEnabled; + } else { + if (isChecked(element)) + return imageCheckedDisabled; + return imageUncheckedDisabled; + } + } + + /** + * @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; + } +} -- 2.11.4.GIT