diff options
| author | Stephan Wahlbrink | 2021-07-31 22:06:12 +0000 |
|---|---|---|
| committer | Stephan Wahlbrink | 2021-08-03 10:15:10 +0000 |
| commit | 1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5 (patch) | |
| tree | b2d9a47ca4d4066d72567fc0c71440831d0c8312 | |
| parent | 80becb6f5488b4e54de129ce5be1772b263ec24d (diff) | |
| download | org.eclipse.statet-commons-1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5.tar.gz org.eclipse.statet-commons-1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5.tar.xz org.eclipse.statet-commons-1c8d45b70a72acae8fc0bb1ee5b82b77419a56d5.zip | |
- Improve rendering for high dpi devices
- Improve rendering for dark theme
Change-Id: Ie446fe7101231628c59be97d0931ac723c38d465
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 ()) { |
