Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Wahlbrink2021-07-31 22:06:12 +0000
committerStephan Wahlbrink2021-08-03 10:15:10 +0000
commit1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5 (patch)
treeb2d9a47ca4d4066d72567fc0c71440831d0c8312
parent80becb6f5488b4e54de129ce5be1772b263ec24d (diff)
downloadorg.eclipse.statet-commons-1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5.tar.gz
org.eclipse.statet-commons-1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5.tar.xz
org.eclipse.statet-commons-1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5.zip
Bug 546324, Bug 575176: [UI-SWT] Improve AccessibleArrowImage
- Improve rendering for high dpi devices - Improve rendering for dark theme Change-Id: Ie446fe7101231628c59be97d0931ac723c38d465
-rw-r--r--ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java2
-rw-r--r--ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java2
-rw-r--r--ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/swt/AccessibleArrowImage.java246
-rw-r--r--ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/viewers/breadcrumb/BreadcrumbItemDropDown.java2
-rw-r--r--ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImage.java190
-rw-r--r--ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImageTest.java22
6 files changed, 263 insertions, 201 deletions
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java
index 229afa73..443d7f73 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java
@@ -33,8 +33,8 @@ import org.eclipse.swt.widgets.Menu;
import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
+import org.eclipse.statet.ecommons.ui.swt.AccessibleArrowImage;
import org.eclipse.statet.ecommons.ui.util.MenuUtils;
-import org.eclipse.statet.internal.ecommons.ui.AccessibleArrowImage;
import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin;
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java
index a8b6405d..8dcfbd16 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java
@@ -51,7 +51,7 @@ import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.TypedListener;
import org.eclipse.swt.widgets.Widget;
-import org.eclipse.statet.internal.ecommons.ui.AccessibleArrowImage;
+import org.eclipse.statet.ecommons.ui.swt.AccessibleArrowImage;
import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin;
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/swt/AccessibleArrowImage.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/swt/AccessibleArrowImage.java
new file mode 100644
index 00000000..27703420
--- /dev/null
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/swt/AccessibleArrowImage.java
@@ -0,0 +1,246 @@
+/*=============================================================================#
+ # Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ecommons.ui.swt;
+
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+
+import java.util.Arrays;
+
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageDataProvider;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+
+/**
+ * An arrow image descriptor, e.g. for drop down buttons.
+ *
+ * <p>Using the foreground and background colors of the widget makes the arrow visible even in high
+ * contrast too.</p>
+ */
+@NonNullByDefault
+public final class AccessibleArrowImage extends CompositeImageDescriptor {
+
+
+ public final static int DEFAULT_SIZE= 5;
+
+
+ private final int direction;
+
+ private final int size;
+
+ private final RGB foregroundColor;
+ private final RGB backgroundColor;
+
+
+ public AccessibleArrowImage(final int direction, final int size,
+ final RGB foregroundColor, final RGB backgroundColor) {
+ switch (direction) {
+ case SWT.UP:
+ case SWT.DOWN:
+ case SWT.LEFT:
+ case SWT.RIGHT:
+ this.direction= direction;
+ break;
+ default:
+ throw new IllegalArgumentException("direction: " + direction); //$NON-NLS-1$
+ }
+
+ this.foregroundColor= nonNullAssert(foregroundColor);
+ this.backgroundColor= nonNullAssert(backgroundColor);
+ this.size= (size == SWT.DEFAULT) ? DEFAULT_SIZE : size;
+ }
+
+
+ @Override
+ protected void drawCompositeImage(final int width, final int height) {
+ final int xOffset;
+ final int yOffset;
+ final int imgWidth;
+ final int imgHeight;
+ switch (this.direction) {
+ case SWT.UP:
+ xOffset= 0;
+ yOffset= 0;
+ imgWidth= this.size * 2 - 1;
+ imgHeight= this.size;
+ break;
+ case SWT.DOWN:
+ xOffset= 0;
+ yOffset= this.size % 2;
+ imgWidth= this.size * 2 - 1;
+ imgHeight= this.size;
+ break;
+ case SWT.LEFT:
+ xOffset= 0;
+ yOffset= 0;
+ imgWidth= this.size;
+ imgHeight= this.size * 2 - 1;
+ break;
+ case SWT.RIGHT:
+ xOffset= this.size % 2;
+ yOffset= 0;
+ imgWidth= this.size;
+ imgHeight= this.size * 2 - 1;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+
+ final ImageDataProvider imageProvider= (final int zoom) -> {
+ final Display display= Display.getCurrent();
+
+ final ImageData imageData;
+ final Image image= new Image(display, imgWidth, imgHeight);
+ try {
+ imageData= image.getImageData(zoom);
+ }
+ finally {
+ image.dispose();
+ }
+
+ if (imageData.alphaData == null) {
+ imageData.alphaData= new byte[imageData.width * imageData.height];
+ }
+ else if (imageData.alphaData[0] != 0) {
+ Arrays.fill(imageData.alphaData, (byte)0);
+ }
+
+ final int foreground= imageData.palette.getPixel(
+ ColorUtils.blend(this.foregroundColor, this.backgroundColor, 0.80f) );
+ final int size1;
+ final int size2;
+ switch (this.direction) {
+ case SWT.UP:
+ size1= (imageData.width) / 2 + imageData.width % 2 - 1;
+ size2= size1 * 2;
+ for (int i= 0; i <= size1; i++) {
+ final int fix1= size1 - i;
+ final int last2= size2 - i;
+ imageData.setPixel(i, fix1, foreground);
+ imageData.setAlpha(i, fix1, 191);
+ for (int j= i + 1; j < last2; j++) {
+ imageData.setPixel(j, fix1, foreground);
+ imageData.setAlpha(j, fix1, 255);
+ }
+ imageData.setPixel(last2, fix1, foreground);
+ imageData.setAlpha(last2, fix1, 191);
+ }
+ break;
+ case SWT.DOWN:
+ size1= (imageData.width) / 2 + imageData.width % 2 - 1;
+ size2= size1 * 2;
+ for (int i= 0; i <= size1; i++) {
+ final int fix1= i;
+ final int last2= size2 - i;
+ imageData.setPixel(i, fix1, foreground);
+ imageData.setAlpha(i, fix1, 191);
+ for (int j= i + 1; j < last2; j++) {
+ imageData.setPixel(j, fix1, foreground);
+ imageData.setAlpha(j, fix1, 255);
+ }
+ imageData.setPixel(last2, fix1, foreground);
+ imageData.setAlpha(last2, fix1, 191);
+ }
+ break;
+ case SWT.LEFT:
+ size1= (imageData.height) / 2 + imageData.height % 2 - 1;
+ size2= size1 * 2;
+ for (int i= 0; i <= size1; i++) {
+ final int fix1= size1 - i;
+ final int last2= size2 - i;
+ imageData.setPixel(fix1, i, foreground);
+ imageData.setAlpha(fix1, i, 191);
+ for (int j= i + 1; j < last2; j++) {
+ imageData.setPixel(fix1, j, foreground);
+ imageData.setAlpha(fix1, j, 255);
+ }
+ imageData.setPixel(fix1, last2, foreground);
+ imageData.setAlpha(fix1, last2, 191);
+ }
+ break;
+ case SWT.RIGHT:
+ size1= (imageData.height) / 2 + imageData.height % 2 - 1;
+ size2= size1 * 2;
+ for (int i= 0; i <= size1; i++) {
+ final int fix1= i;
+ final int last2= size2 - i;
+ imageData.setPixel(fix1, i, foreground);
+ imageData.setAlpha(fix1, i, 191);
+ for (int j= i + 1; j < last2; j++) {
+ imageData.setPixel(fix1, j, foreground);
+ imageData.setAlpha(fix1, j, 255);
+ }
+ imageData.setPixel(fix1, last2, foreground);
+ imageData.setAlpha(fix1, last2, 191);
+ }
+ break;
+ }
+
+ return imageData;
+ };
+
+ drawImage(imageProvider,
+ xOffset + (width - imgWidth) / 2,
+ yOffset + (height - imgHeight) / 2 );
+ }
+
+ @Override
+ protected Point getSize() {
+ final int corr= ((this.size % 2) == 0) ? -1 : 0;
+ switch (this.direction) {
+ case SWT.UP:
+ case SWT.DOWN:
+ return new Point(this.size * 3 + corr, this.size * 2);
+ case SWT.LEFT:
+ case SWT.RIGHT:
+ return new Point(this.size * 2, this.size * 3 + corr);
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+
+ @Override
+ public int hashCode() {
+ return this.direction * 7
+ + this.size * 3460
+ + this.foregroundColor.hashCode() * 343629
+ + this.backgroundColor.hashCode() * 987972;
+ }
+
+ @Override
+ public boolean equals(final @Nullable Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof AccessibleArrowImage) {
+ final AccessibleArrowImage other= (AccessibleArrowImage)obj;
+ return (this.direction == other.direction
+ && this.size == other.size
+ && this.foregroundColor.equals(other.foregroundColor)
+ && this.backgroundColor.equals(other.backgroundColor) );
+ }
+ return false;
+ }
+
+}
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/viewers/breadcrumb/BreadcrumbItemDropDown.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/viewers/breadcrumb/BreadcrumbItemDropDown.java
index a1f9985b..17f3df8c 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/viewers/breadcrumb/BreadcrumbItemDropDown.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/viewers/breadcrumb/BreadcrumbItemDropDown.java
@@ -67,7 +67,7 @@ import org.eclipse.swt.widgets.Widget;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
-import org.eclipse.statet.internal.ecommons.ui.AccessibleArrowImage;
+import org.eclipse.statet.ecommons.ui.swt.AccessibleArrowImage;
/**
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImage.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImage.java
deleted file mode 100644
index 1c362ab5..00000000
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImage.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*=============================================================================#
- # Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
- #
- # This program and the accompanying materials are made available under the
- # terms of the Eclipse Public License 2.0 which is available at
- # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
- # which is available at https://www.apache.org/licenses/LICENSE-2.0.
- #
- # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
- #
- # Contributors:
- # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
- #=============================================================================*/
-
-package org.eclipse.statet.internal.ecommons.ui;
-
-import org.eclipse.jface.resource.CompositeImageDescriptor;
-import org.eclipse.swt.SWT;
-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.widgets.Display;
-
-import org.eclipse.statet.ecommons.ui.swt.ColorUtils;
-
-
-/**
- * An arrow image descriptor, e.g. for drop down buttons.
- * Using the foreground and background colors of the widget makes the arrow visible even in high
- * contrast too.
- */
-public class AccessibleArrowImage extends CompositeImageDescriptor {
-
-
- public final static int DEFAULT_SIZE= 5;
-
-
- private final int fDirection;
-
- private final RGB fForegroundColor;
- private final RGB fBackgroundColor;
-
- private final int fSize;
-
-
- public AccessibleArrowImage(final int direction, final int size,
- final RGB foregroundColor, final RGB backgroundColor) {
- switch (direction) {
- case SWT.UP:
- case SWT.DOWN:
- case SWT.LEFT:
- case SWT.RIGHT:
- break;
- default:
- throw new IllegalArgumentException("direction: " + direction); //$NON-NLS-1$
- }
- if (foregroundColor == null) {
- throw new NullPointerException("foregroundColor");
- }
- if (backgroundColor == null) {
- throw new NullPointerException("backgroundColor");
- }
- fDirection = direction;
- fForegroundColor = foregroundColor;
- fBackgroundColor = backgroundColor;
- fSize = (size == -1) ? DEFAULT_SIZE : size;
- }
-
-
- @Override
- protected void drawCompositeImage(final int width, final int height) {
- final Display display= Display.getCurrent();
-
- final Image image= (fDirection == SWT.LEFT || fDirection == SWT.RIGHT) ?
- new Image(display, fSize, fSize * 2 - 1) :
- new Image(display, fSize * 2 - 1, fSize);
-
- final ImageData imageData= image.getImageData();
- final int foreground = imageData.palette.getPixel(
- ColorUtils.blend(fForegroundColor, fBackgroundColor, 0.80f) );
- final int aliasing = imageData.palette.getPixel(
- ColorUtils.blend(fForegroundColor, fBackgroundColor, 0.60f) );
-
- final int size1 = fSize - 1;
- int xOffset = 0;
- int yOffset = 0;
- switch (fDirection) {
- case SWT.UP:
- for (int i = 0; i <= size1; i++) {
- final int last = size1 * 2 - i;
- imageData.setPixel(i, size1 - i, aliasing);
- imageData.setAlpha(i, size1 - i, 255);
- imageData.setPixel(last, size1 - i, aliasing);
- imageData.setAlpha(last, size1 - i, 255);
- for (int j = i + 1; j < last; j++) {
- imageData.setPixel(j, size1 - i, foreground);
- imageData.setAlpha(j, size1 - i, 255);
- }
- }
- break;
- case SWT.DOWN:
- for (int i = 0; i <= size1; i++) {
- final int last = size1 * 2 - i;
- imageData.setPixel(i, i, aliasing);
- imageData.setAlpha(i, i, 255);
- imageData.setPixel(last, i, aliasing);
- imageData.setAlpha(last, i, 255);
- for (int j = i + 1; j < last; j++) {
- imageData.setPixel(j, i, foreground);
- imageData.setAlpha(j, i, 255);
- }
- }
- yOffset = 1;
- break;
- case SWT.LEFT:
- for (int i = 0; i <= size1; i++) {
- final int last = size1 * 2 - i;
- imageData.setPixel(size1 - i, i, aliasing);
- imageData.setAlpha(size1 - i, i, 255);
- imageData.setPixel(size1 - i, last, aliasing);
- imageData.setAlpha(size1 - i, last, 255);
- for (int j = i + 1; j < last; j++) {
- imageData.setPixel(size1 - i, j, foreground);
- imageData.setAlpha(size1 - i, j, 255);
- }
- }
- break;
- case SWT.RIGHT:
- for (int i = 0; i <= size1; i++) {
- final int last = size1 * 2 - i;
- imageData.setPixel(i, i, aliasing);
- imageData.setAlpha(i, i, 255);
- imageData.setPixel(i, last, aliasing);
- imageData.setAlpha(i, last, 255);
- for (int j = i + 1; j < last; j++) {
- imageData.setPixel(i, j, foreground);
- imageData.setAlpha(i, j, 255);
- }
- }
- xOffset = 1;
- break;
- }
-
- drawImage(imageData,
- (width - imageData.width) / 2 + xOffset,
- (height - imageData.height) / 2 + yOffset);
-
- image.dispose();
- }
-
- @Override
- protected Point getSize() {
- final int corr = ((fSize % 2) == 0) ? -1 : 0;
- switch (fDirection) {
- case SWT.UP:
- case SWT.DOWN:
- return new Point(fSize * 3 + corr, fSize * 2);
- case SWT.LEFT:
- case SWT.RIGHT:
- return new Point(fSize * 2, fSize * 3 + corr);
- default:
- throw new IllegalStateException();
- }
- }
-
-
- @Override
- public int hashCode() {
- return fDirection * 7 + fSize * 3460
- + fForegroundColor.hashCode() * 343629
- + fBackgroundColor.hashCode() * 987972;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AccessibleArrowImage other = (AccessibleArrowImage) obj;
- return (fDirection == other.fDirection
- && fSize == other.fSize
- && fForegroundColor.equals(other.fForegroundColor)
- && fBackgroundColor.equals(other.fBackgroundColor) );
- }
-
-}
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImageTest.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImageTest.java
index e6c7506a..a18df004 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImageTest.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/AccessibleArrowImageTest.java
@@ -20,26 +20,32 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.ecommons.ui.swt.AccessibleArrowImage;
+
+
+@NonNullByDefault
public class AccessibleArrowImageTest {
public static void main(final String[] args) {
- final int[] directions = new int[] { SWT.UP, SWT.DOWN, SWT.LEFT, SWT.RIGHT };
- final int size = 4;
+ final int[] directions= new int[] { SWT.UP, SWT.DOWN, SWT.LEFT, SWT.RIGHT };
+ final int size= AccessibleArrowImage.DEFAULT_SIZE;
- final Display display = new Display();
- final Shell shell = new Shell(display);
+ final Display display= new Display();
+ final Shell shell= new Shell(display);
shell.setLayout (new GridLayout(directions.length, false));
- for (int i = 0; i < directions.length; i++) {
- final AccessibleArrowImage image = new AccessibleArrowImage(directions[i], size,
+ for (int i= 0; i < directions.length; i++) {
+ final AccessibleArrowImage image= new AccessibleArrowImage(directions[i], size,
display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND).getRGB(),
display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB() );
- final Button button = new Button(shell, SWT.PUSH);
+ final Button button= new Button(shell, SWT.PUSH);
+ button.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
button.setImage(image.createImage());
}
- shell.setSize(300, 300);
+ shell.setSize((size + 8) * 8 + 100, (size + 8) * 2 + 100);
shell.open();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) {

Back to the top