Cleaned up caching - now is based on file hash, instead of cache
names, which could lead to heisenbugs. Everything always caches now based on hash of input
This commit is contained in:
parent
146afbf949
commit
568fb95ee6
@ -21,6 +21,8 @@ import java.io.File;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
|
||||||
import dorkbox.systemTray.peer.MenuItemPeer;
|
import dorkbox.systemTray.peer.MenuItemPeer;
|
||||||
import dorkbox.systemTray.util.ImageUtils;
|
import dorkbox.systemTray.util.ImageUtils;
|
||||||
|
|
||||||
@ -80,27 +82,32 @@ class MenuItem extends Entry {
|
|||||||
|
|
||||||
public
|
public
|
||||||
MenuItem(final String text, final String imagePath, final ActionListener callback) {
|
MenuItem(final String text, final String imagePath, final ActionListener callback) {
|
||||||
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath, true), callback, false);
|
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath), callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
MenuItem(final String text, final File imageFile, final ActionListener callback) {
|
MenuItem(final String text, final File imageFile, final ActionListener callback) {
|
||||||
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageFile, true), callback, false);
|
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageFile), callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
MenuItem(final String text, final URL imageUrl, final ActionListener callback) {
|
MenuItem(final String text, final URL imageUrl, final ActionListener callback) {
|
||||||
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl, true), callback, false);
|
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
MenuItem(final String text, final InputStream imageStream, final ActionListener callback) {
|
MenuItem(final String text, final InputStream imageStream, final ActionListener callback) {
|
||||||
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream, true), callback, false);
|
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream), callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
MenuItem(final String text, final Image image, final ActionListener callback) {
|
MenuItem(final String text, final Image image, final ActionListener callback) {
|
||||||
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, image, true), callback, false);
|
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, image), callback, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public
|
||||||
|
MenuItem(final String text, final ImageInputStream imageStream, final ActionListener callback) {
|
||||||
|
this(text, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream), callback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the last parameter (unused) is there so the signature is different
|
// the last parameter (unused) is there so the signature is different
|
||||||
@ -205,18 +212,7 @@ class MenuItem extends Entry {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final File imageFile) {
|
void setImage(final File imageFile) {
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageFile, true));
|
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageFile));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image.
|
|
||||||
*
|
|
||||||
* @param imageFile the file of the image to use or null
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final File imageFile, final boolean cacheImage) {
|
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageFile, cacheImage));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,18 +224,7 @@ class MenuItem extends Entry {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final String imagePath) {
|
void setImage(final String imagePath) {
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath, true));
|
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imagePath the full path of the image to use or null
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final String imagePath, final boolean cacheImage) {
|
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath, cacheImage));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -251,18 +236,7 @@ class MenuItem extends Entry {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final URL imageUrl) {
|
void setImage(final URL imageUrl) {
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl, true));
|
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imageUrl the URL of the image to use or null
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final URL imageUrl, final boolean cacheImage) {
|
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl, cacheImage));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -274,18 +248,7 @@ class MenuItem extends Entry {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final InputStream imageStream) {
|
void setImage(final InputStream imageStream) {
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream, true));
|
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imageStream the InputStream of the image to use
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final InputStream imageStream, final boolean cacheImage) {
|
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream, cacheImage));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -297,20 +260,22 @@ class MenuItem extends Entry {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final Image image) {
|
void setImage(final Image image) {
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, image, true));
|
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, image));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
* Specifies the new image to set for a menu entry, NULL to delete the image
|
||||||
|
* <p>
|
||||||
|
* This method will cache the image if it needs to be resized to fit.
|
||||||
*
|
*
|
||||||
* @param image the image of the image to use
|
* @param imageStream the ImageInputStream of the image to use
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final Image image, final boolean cacheImage) {
|
void setImage(final ImageInputStream imageStream) {
|
||||||
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, image, cacheImage));
|
setImage_(ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this menu entry has an image assigned to it, or is just text.
|
* @return true if this menu entry has an image assigned to it, or is just text.
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +27,7 @@ import java.io.PrintStream;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -748,24 +749,13 @@ class SystemTray {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final File imageFile) {
|
void setImage(final File imageFile) {
|
||||||
setImage(imageFile, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imageFile the file of the image to use or null
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final File imageFile, final boolean cacheImage) {
|
|
||||||
if (imageFile == null) {
|
if (imageFile == null) {
|
||||||
throw new NullPointerException("imageFile cannot be null!");
|
throw new NullPointerException("imageFile cannot be null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
final Menu menu = systemTrayMenu;
|
final Menu menu = systemTrayMenu;
|
||||||
if (menu != null) {
|
if (menu != null) {
|
||||||
menu.setImage(imageFile, cacheImage);
|
menu.setImage(imageFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,24 +768,13 @@ class SystemTray {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final String imagePath) {
|
void setImage(final String imagePath) {
|
||||||
setImage(imagePath, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imagePath the full path of the image to use or null
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final String imagePath, final boolean cacheImage) {
|
|
||||||
if (imagePath == null) {
|
if (imagePath == null) {
|
||||||
throw new NullPointerException("imagePath cannot be null!");
|
throw new NullPointerException("imagePath cannot be null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
final Menu menu = systemTrayMenu;
|
final Menu menu = systemTrayMenu;
|
||||||
if (menu != null) {
|
if (menu != null) {
|
||||||
menu.setImage(imagePath, cacheImage);
|
menu.setImage(imagePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,17 +787,6 @@ class SystemTray {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final URL imageUrl) {
|
void setImage(final URL imageUrl) {
|
||||||
setImage(imageUrl, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imageUrl the URL of the image to use or null
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final URL imageUrl, final boolean cacheImage) {
|
|
||||||
if (imageUrl == null) {
|
if (imageUrl == null) {
|
||||||
throw new NullPointerException("imageUrl cannot be null!");
|
throw new NullPointerException("imageUrl cannot be null!");
|
||||||
}
|
}
|
||||||
@ -838,17 +806,6 @@ class SystemTray {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final InputStream imageStream) {
|
void setImage(final InputStream imageStream) {
|
||||||
setImage(imageStream, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param imageStream the InputStream of the image to use
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final InputStream imageStream, final boolean cacheImage) {
|
|
||||||
if (imageStream == null) {
|
if (imageStream == null) {
|
||||||
throw new NullPointerException("imageStream cannot be null!");
|
throw new NullPointerException("imageStream cannot be null!");
|
||||||
}
|
}
|
||||||
@ -868,25 +825,32 @@ class SystemTray {
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void setImage(final Image image) {
|
void setImage(final Image image) {
|
||||||
setImage(image, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the new image to set for a menu entry, NULL to delete the image
|
|
||||||
*
|
|
||||||
* @param image the image of the image to use
|
|
||||||
* @param cacheImage true to cache the image (only if the image is resized as necessary)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public
|
|
||||||
void setImage(final Image image, final boolean cacheImage) {
|
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
throw new NullPointerException("image cannot be null!");
|
throw new NullPointerException("image cannot be null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
final Menu menu = systemTrayMenu;
|
final Menu menu = systemTrayMenu;
|
||||||
if (menu != null) {
|
if (menu != null) {
|
||||||
menu.setImage(image, cacheImage);
|
menu.setImage(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the new image to set for a menu entry, NULL to delete the image
|
||||||
|
* <p>
|
||||||
|
* This method will cache the image if it needs to be resized to fit.
|
||||||
|
*
|
||||||
|
*@param imageStream the ImageInputStream of the image to use
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
void setImage(final ImageInputStream imageStream) {
|
||||||
|
if (imageStream == null) {
|
||||||
|
throw new NullPointerException("image cannot be null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Menu menu = systemTrayMenu;
|
||||||
|
if (menu != null) {
|
||||||
|
menu.setImage(imageStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class SwingMenuItemCheckbox implements CheckboxPeer {
|
|||||||
|
|
||||||
if (checkedIcon == null) {
|
if (checkedIcon == null) {
|
||||||
// from Brankic1979, public domain
|
// from Brankic1979, public domain
|
||||||
File checkedFile = ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, ImageUtils.class.getResource("checked_32.png"), true);
|
File checkedFile = ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, ImageUtils.class.getResource("checked_32.png"));
|
||||||
checkedIcon = new ImageIcon(checkedFile.getAbsolutePath());
|
checkedIcon = new ImageIcon(checkedFile.getAbsolutePath());
|
||||||
|
|
||||||
File uncheckedFile = ImageUtils.getTransparentImage(ImageUtils.ENTRY_SIZE);
|
File uncheckedFile = ImageUtils.getTransparentImage(ImageUtils.ENTRY_SIZE);
|
||||||
|
@ -63,7 +63,8 @@ class ImageUtils {
|
|||||||
|
|
||||||
public static
|
public static
|
||||||
void determineIconSize() {
|
void determineIconSize() {
|
||||||
int scalingFactor = 0;
|
int trayScalingFactor = 0;
|
||||||
|
int menuScalingFactor = 0;
|
||||||
|
|
||||||
if (SystemTray.AUTO_TRAY_SIZE) {
|
if (SystemTray.AUTO_TRAY_SIZE) {
|
||||||
if (OS.isWindows()) {
|
if (OS.isWindows()) {
|
||||||
@ -109,57 +110,71 @@ class ImageUtils {
|
|||||||
|
|
||||||
if (windowsVersion.startsWith("5.1")) {
|
if (windowsVersion.startsWith("5.1")) {
|
||||||
// Windows XP 5.1.2600
|
// Windows XP 5.1.2600
|
||||||
scalingFactor = 1;
|
trayScalingFactor = 1;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("5.1")) {
|
} else if (windowsVersion.startsWith("5.1")) {
|
||||||
// Windows Server 2003 5.2.3790.1218
|
// Windows Server 2003 5.2.3790.1218
|
||||||
scalingFactor = 1;
|
trayScalingFactor = 1;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("6.0")) {
|
} else if (windowsVersion.startsWith("6.0")) {
|
||||||
// Windows Vista 6.0.6000
|
// Windows Vista 6.0.6000
|
||||||
// Windows Server 2008 SP1 6.0.6001
|
// Windows Server 2008 SP1 6.0.6001
|
||||||
// Windows Server 2008 SP2 6.0.6002
|
// Windows Server 2008 SP2 6.0.6002
|
||||||
scalingFactor = 1;
|
trayScalingFactor = 1;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("6.1")) {
|
} else if (windowsVersion.startsWith("6.1")) {
|
||||||
// Windows 7
|
// Windows 7
|
||||||
// Windows Server 2008 R2 6.1.7600
|
// Windows Server 2008 R2 6.1.7600
|
||||||
// Windows Server 2008 R2 SP1 6.1.7601
|
// Windows Server 2008 R2 SP1 6.1.7601
|
||||||
scalingFactor = 2;
|
trayScalingFactor = 2;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("6.2")) {
|
} else if (windowsVersion.startsWith("6.2")) {
|
||||||
// Windows 8
|
// Windows 8
|
||||||
// Windows Server 2012 6.2.9200
|
// Windows Server 2012 6.2.9200
|
||||||
scalingFactor = 2;
|
trayScalingFactor = 2;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("6.3")) {
|
} else if (windowsVersion.startsWith("6.3")) {
|
||||||
// Windows 8.1
|
// Windows 8.1
|
||||||
// Windows Server 2012 6.3.9200
|
// Windows Server 2012 6.3.9200
|
||||||
scalingFactor = 4;
|
trayScalingFactor = 4;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("6.4")) {
|
} else if (windowsVersion.startsWith("6.4")) {
|
||||||
// Windows 10 Technical Preview 1 6.4.9841
|
// Windows 10 Technical Preview 1 6.4.9841
|
||||||
scalingFactor = 4;
|
trayScalingFactor = 4;
|
||||||
|
|
||||||
} else if (windowsVersion.startsWith("10.0")) {
|
} else if (windowsVersion.startsWith("10.0")) {
|
||||||
// Windows 10 Technical Preview 4 10.0.9926
|
// Windows 10 Technical Preview 4 10.0.9926
|
||||||
// Windows 10 Insider Preview 10.0.14915
|
// Windows 10 Insider Preview 10.0.14915
|
||||||
scalingFactor = 4;
|
trayScalingFactor = 4;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// dunnno, but i'm going to assume HiDPI for this...
|
// dunnno, but i'm going to assume HiDPI for this...
|
||||||
scalingFactor = 8;
|
trayScalingFactor = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointer screen = User32.GetDC(null);
|
Pointer screen = User32.GetDC(null);
|
||||||
int dpiX = GetDeviceCaps (screen, LOGPIXELSX);
|
int dpiX = GetDeviceCaps (screen, LOGPIXELSX);
|
||||||
User32.ReleaseDC(null, screen);
|
User32.ReleaseDC(null, screen);
|
||||||
|
|
||||||
System.err.println("DPI : " + dpiX);
|
// 96 DPI = 100% scaling
|
||||||
|
// 120 DPI = 125% scaling
|
||||||
|
// 144 DPI = 150% scaling
|
||||||
|
// 192 DPI = 200% scaling
|
||||||
|
|
||||||
|
// just a note on scaling...
|
||||||
|
// We want to scale the image as best we can beforehand, so there is an attempt to have it look good
|
||||||
|
if (dpiX != 96) {
|
||||||
|
// so there are additional scaling settings...
|
||||||
|
// casting around for rounding/math stuff
|
||||||
|
// *2 because we want a 2x scale to be 64, not 32.
|
||||||
|
trayScalingFactor = (int) (((double) dpiX) / ((double) 96)) * 2;
|
||||||
|
menuScalingFactor = trayScalingFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (SystemTray.DEBUG) {
|
if (SystemTray.DEBUG) {
|
||||||
SystemTray.logger.debug("Windows version (partial): '{}'", windowsVersion);
|
SystemTray.logger.debug("Windows version (partial): '{}'", windowsVersion);
|
||||||
|
SystemTray.logger.debug("Windows DPI settings: '{}'", dpiX);
|
||||||
}
|
}
|
||||||
} else if (OS.isLinux()) {
|
} else if (OS.isLinux()) {
|
||||||
// GtkStatusIcon will USUALLY automatically scale the icon
|
// GtkStatusIcon will USUALLY automatically scale the icon
|
||||||
@ -197,12 +212,12 @@ class ImageUtils {
|
|||||||
// 4 = 64
|
// 4 = 64
|
||||||
// 8 = 128
|
// 8 = 128
|
||||||
if (value.startsWith("4")) {
|
if (value.startsWith("4")) {
|
||||||
scalingFactor = 2;
|
trayScalingFactor = 2;
|
||||||
} else if (value.startsWith("5")) {
|
} else if (value.startsWith("5")) {
|
||||||
scalingFactor = 8; // it is insane how large the icon is
|
trayScalingFactor = 8; // it is insane how large the icon is
|
||||||
} else {
|
} else {
|
||||||
// assume very low version of plasmashell, default 32
|
// assume very low version of plasmashell, default 32
|
||||||
scalingFactor = 2;
|
trayScalingFactor = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +252,7 @@ class ImageUtils {
|
|||||||
// should be: uint32 0 or something
|
// should be: uint32 0 or something
|
||||||
if (output.contains("uint32")) {
|
if (output.contains("uint32")) {
|
||||||
String value = output.substring(output.indexOf("uint")+7, output.length()-1);
|
String value = output.substring(output.indexOf("uint")+7, output.length()-1);
|
||||||
scalingFactor = Integer.parseInt(value);
|
trayScalingFactor = Integer.parseInt(value);
|
||||||
|
|
||||||
// 0 is disabled (no scaling)
|
// 0 is disabled (no scaling)
|
||||||
// 1 is enabled (default scale)
|
// 1 is enabled (default scale)
|
||||||
@ -265,16 +280,16 @@ class ImageUtils {
|
|||||||
|
|
||||||
if (height < 32) {
|
if (height < 32) {
|
||||||
// lock in at 32
|
// lock in at 32
|
||||||
scalingFactor = 2;
|
trayScalingFactor = 2;
|
||||||
}
|
}
|
||||||
else if ((height & (height - 1)) == 0) {
|
else if ((height & (height - 1)) == 0) {
|
||||||
// is this a power of 2 number? If so, we can use it
|
// is this a power of 2 number? If so, we can use it
|
||||||
scalingFactor = height/SystemTray.DEFAULT_TRAY_SIZE;
|
trayScalingFactor = height/SystemTray.DEFAULT_TRAY_SIZE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// don't know how exactly to determine this, but we are going to assume very high "HiDPI" for this...
|
// don't know how exactly to determine this, but we are going to assume very high "HiDPI" for this...
|
||||||
// the OS should go up/down as needed.
|
// the OS should go up/down as needed.
|
||||||
scalingFactor = 8;
|
trayScalingFactor = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,16 +299,20 @@ class ImageUtils {
|
|||||||
// we want to make sure our "scaled" size is appropriate for the OS.
|
// we want to make sure our "scaled" size is appropriate for the OS.
|
||||||
|
|
||||||
// the DEFAULT scale is 16
|
// the DEFAULT scale is 16
|
||||||
if (scalingFactor > 1) {
|
if (trayScalingFactor > 1) {
|
||||||
TRAY_SIZE = SystemTray.DEFAULT_TRAY_SIZE * scalingFactor;
|
TRAY_SIZE = SystemTray.DEFAULT_TRAY_SIZE * trayScalingFactor;
|
||||||
ENTRY_SIZE = SystemTray.DEFAULT_MENU_SIZE;
|
|
||||||
|
|
||||||
if (SystemTray.DEBUG) {
|
|
||||||
SystemTray.logger.debug("Scaling Factor factor is '{}', tray size is '{}'.", scalingFactor, TRAY_SIZE);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
TRAY_SIZE = SystemTray.DEFAULT_TRAY_SIZE;
|
TRAY_SIZE = SystemTray.DEFAULT_TRAY_SIZE;
|
||||||
ENTRY_SIZE = SystemTray.DEFAULT_MENU_SIZE;
|
}
|
||||||
|
|
||||||
|
if (menuScalingFactor > 1) {
|
||||||
|
ENTRY_SIZE = SystemTray.DEFAULT_MENU_SIZE * menuScalingFactor;
|
||||||
|
}
|
||||||
|
ENTRY_SIZE = SystemTray.DEFAULT_MENU_SIZE;
|
||||||
|
|
||||||
|
if (SystemTray.DEBUG) {
|
||||||
|
SystemTray.logger.debug("Scaling Factor factor is '{}', tray size is '{}'.", trayScalingFactor, TRAY_SIZE);
|
||||||
|
SystemTray.logger.debug("Scaling Factor factor is '{}', tray size is '{}'.", menuScalingFactor, ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,189 +378,112 @@ class ImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized
|
public static synchronized
|
||||||
File resizeAndCache(final int size, final File file, final boolean cacheResult) {
|
File resizeAndCache(final int size, final File file) {
|
||||||
return resizeAndCache(size, file.getAbsolutePath(), cacheResult);
|
return resizeAndCache(size, file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized
|
public static synchronized
|
||||||
File resizeAndCache(final int size, final String fileName, final boolean cacheResult) {
|
File resizeAndCache(final int size, final String fileName) {
|
||||||
if (fileName == null) {
|
if (fileName == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we already have this file information saved to disk, based on size
|
|
||||||
final String cacheName = size + "_" + fileName;
|
|
||||||
|
|
||||||
// if we already have this fileName, reuse it
|
|
||||||
File check = getIfCachedOrError(cacheName);
|
|
||||||
if (check != null) {
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no cached file, so we resize then save the new one.
|
|
||||||
String newFileOnDisk;
|
|
||||||
try {
|
try {
|
||||||
newFileOnDisk = resizeFile(size, fileName);
|
FileInputStream fileInputStream = new FileInputStream(fileName);
|
||||||
|
File file = resizeAndCache(size, fileInputStream);
|
||||||
|
fileInputStream.close();
|
||||||
|
|
||||||
|
return file;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// have to serve up the error image instead.
|
// have to serve up the error image instead.
|
||||||
SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
SystemTray.logger.error("Error reading image. Using error icon instead", e);
|
||||||
return getErrorImage(cacheName);
|
return getErrorImage(size + "default");
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return CacheUtil.save(cacheName, newFileOnDisk);
|
|
||||||
} catch (IOException e) {
|
|
||||||
// have to serve up the error image instead.
|
|
||||||
SystemTray.logger.error("Error caching image. Using error icon instead", e);
|
|
||||||
return getErrorImage(cacheName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public static synchronized
|
public static synchronized
|
||||||
File resizeAndCache(final int size, final URL imageUrl, final boolean cacheResult) {
|
File resizeAndCache(final int size, final URL imageUrl) {
|
||||||
if (imageUrl == null) {
|
if (imageUrl == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String cacheName = size + "_" + imageUrl.getPath();
|
|
||||||
|
|
||||||
// if we already have this fileName, reuse it
|
|
||||||
final File check = getIfCachedOrError(cacheName);
|
|
||||||
if (check != null) {
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no cached file, so we resize then save the new one.
|
|
||||||
boolean needsResize = true;
|
|
||||||
try {
|
try {
|
||||||
InputStream inputStream = imageUrl.openStream();
|
InputStream inputStream = imageUrl.openStream();
|
||||||
Dimension imageSize = getImageSize(inputStream);
|
File file = resizeAndCache(size, inputStream);
|
||||||
//noinspection NumericCastThatLosesPrecision
|
inputStream.close();
|
||||||
if (size == ((int) imageSize.getWidth()) && size == ((int) imageSize.getHeight())) {
|
|
||||||
// we can reuse this URL (it's the correct size).
|
return file;
|
||||||
needsResize = false;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// have to serve up the error image instead.
|
// have to serve up the error image instead.
|
||||||
SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
SystemTray.logger.error("Error reading image. Using error icon instead", e);
|
||||||
return getErrorImage(cacheName);
|
return getErrorImage(size + "default");
|
||||||
}
|
|
||||||
|
|
||||||
if (needsResize) {
|
|
||||||
// we have to hop through hoops.
|
|
||||||
try {
|
|
||||||
File resizedFile = resizeFileNoCheck(size, imageUrl);
|
|
||||||
|
|
||||||
// now cache that file
|
|
||||||
try {
|
|
||||||
return CacheUtil.save(cacheName, resizedFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
// have to serve up the error image instead.
|
|
||||||
SystemTray.logger.error("Error caching image. Using error icon instead", e);
|
|
||||||
return getErrorImage(cacheName);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
// have to serve up the error image instead.
|
|
||||||
SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
|
||||||
return getErrorImage(cacheName);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// no resize necessary, just cache as is.
|
|
||||||
try {
|
|
||||||
return CacheUtil.save(cacheName, imageUrl);
|
|
||||||
} catch (IOException e) {
|
|
||||||
// have to serve up the error image instead.
|
|
||||||
SystemTray.logger.error("Error caching image. Using error icon instead", e);
|
|
||||||
return getErrorImage(cacheName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public static synchronized
|
public static synchronized
|
||||||
File resizeAndCache(final int size, final Image image, final boolean cacheResult) {
|
File resizeAndCache(final int size, final Image image) {
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stupid java won't scale it right away, so we have to do this twice to get the correct size
|
||||||
|
final Image trayImage = new ImageIcon(image).getImage();
|
||||||
|
trayImage.flush();
|
||||||
|
|
||||||
// final String cacheName = size + "_" + imageUrl.getPath();
|
try {
|
||||||
//
|
ImageInputStream imageInputStream = ImageIO.createImageInputStream(image);
|
||||||
// // if we already have this fileName, reuse it
|
File file = resizeAndCache(size, imageInputStream);
|
||||||
// final File check = getIfCachedOrError(cacheName);
|
imageInputStream.close();
|
||||||
// if (check != null) {
|
|
||||||
// return check;
|
return file;
|
||||||
// }
|
} catch (IOException e) {
|
||||||
//
|
// have to serve up the error image instead.
|
||||||
// // no cached file, so we resize then save the new one.
|
SystemTray.logger.error("Error reading image. Using error icon instead", e);
|
||||||
// boolean needsResize = true;
|
return getErrorImage(size + "default");
|
||||||
// try {
|
}
|
||||||
// InputStream inputStream = imageUrl.openStream();
|
|
||||||
// Dimension imageSize = getImageSize(inputStream);
|
|
||||||
// //noinspection NumericCastThatLosesPrecision
|
|
||||||
// if (size == ((int) imageSize.getWidth()) && size == ((int) imageSize.getHeight())) {
|
|
||||||
// // we can reuse this URL (it's the correct size).
|
|
||||||
// needsResize = false;
|
|
||||||
// }
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // have to serve up the error image instead.
|
|
||||||
// SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
|
||||||
// return getErrorImage(cacheName);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (needsResize) {
|
|
||||||
// // we have to hop through hoops.
|
|
||||||
// try {
|
|
||||||
// File resizedFile = resizeFileNoCheck(size, imageUrl);
|
|
||||||
//
|
|
||||||
// // now cache that file
|
|
||||||
// try {
|
|
||||||
// return CacheUtil.save(cacheName, resizedFile);
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // have to serve up the error image instead.
|
|
||||||
// SystemTray.logger.error("Error caching image. Using error icon instead", e);
|
|
||||||
// return getErrorImage(cacheName);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // have to serve up the error image instead.
|
|
||||||
// SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
|
||||||
// return getErrorImage(cacheName);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
// // no resize necessary, just cache as is.
|
|
||||||
// try {
|
|
||||||
// return CacheUtil.save(cacheName, imageUrl);
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // have to serve up the error image instead.
|
|
||||||
// SystemTray.logger.error("Error caching image. Using error icon instead", e);
|
|
||||||
// return getErrorImage(cacheName);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public static synchronized
|
public static synchronized
|
||||||
File resizeAndCache(final int size, InputStream imageStream, final boolean cacheResult) {
|
File resizeAndCache(final int size, final ImageInputStream imageStream) {
|
||||||
if (imageStream == null) {
|
if (imageStream == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// have to make a copy of the inputStream.
|
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream byteArrayOutputStream = IO.copyStream(imageStream);
|
ByteArrayOutputStream byteArrayOutputStream = IO.copyStream(imageStream);
|
||||||
imageStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
return resizeAndCache(size, new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Unable to read from inputStream.", e);
|
// have to serve up the error image instead.
|
||||||
|
SystemTray.logger.error("Error reading image. Using error icon instead", e);
|
||||||
|
return getErrorImage(size + "default");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public static synchronized
|
||||||
|
File resizeAndCache(final int size, InputStream imageStream) {
|
||||||
|
if (imageStream == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we already have this file information saved to disk, based on size
|
if (!(imageStream instanceof ByteArrayInputStream)) {
|
||||||
|
// have to make a copy of the inputStream, but only if necessary
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = IO.copyStream(imageStream);
|
||||||
|
imageStream.close();
|
||||||
|
|
||||||
|
imageStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Unable to read from inputStream.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageStream.mark(0);
|
||||||
|
|
||||||
|
// check if we already have this file information saved to disk, based on size + hash of data
|
||||||
final String cacheName = size + "_" + CacheUtil.createNameAsHash(imageStream);
|
final String cacheName = size + "_" + CacheUtil.createNameAsHash(imageStream);
|
||||||
((ByteArrayInputStream) imageStream).reset();
|
((ByteArrayInputStream) imageStream).reset(); // casting to avoid unnecessary try/catch for IOException
|
||||||
|
|
||||||
|
|
||||||
// if we already have this fileName, reuse it
|
// if we already have this fileName, reuse it
|
||||||
@ -553,6 +495,7 @@ class ImageUtils {
|
|||||||
// no cached file, so we resize then save the new one.
|
// no cached file, so we resize then save the new one.
|
||||||
boolean needsResize = true;
|
boolean needsResize = true;
|
||||||
try {
|
try {
|
||||||
|
imageStream.mark(0);
|
||||||
Dimension imageSize = getImageSize(imageStream);
|
Dimension imageSize = getImageSize(imageStream);
|
||||||
//noinspection NumericCastThatLosesPrecision
|
//noinspection NumericCastThatLosesPrecision
|
||||||
if (size == ((int) imageSize.getWidth()) && size == ((int) imageSize.getHeight())) {
|
if (size == ((int) imageSize.getWidth()) && size == ((int) imageSize.getHeight())) {
|
||||||
@ -563,6 +506,8 @@ class ImageUtils {
|
|||||||
// have to serve up the error image instead.
|
// have to serve up the error image instead.
|
||||||
SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
SystemTray.logger.error("Error resizing image. Using error icon instead", e);
|
||||||
return getErrorImage(cacheName);
|
return getErrorImage(cacheName);
|
||||||
|
} finally {
|
||||||
|
((ByteArrayInputStream) imageStream).reset(); // casting to avoid unnecessary try/catch for IOException
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsResize) {
|
if (needsResize) {
|
||||||
@ -641,7 +586,7 @@ class ImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the given URL to the specified size. No checks are performed if it's the correct size to begin with.
|
* Resizes the given InputStream to the specified size. No checks are performed if it's the correct size to begin with.
|
||||||
*
|
*
|
||||||
* @return the file on disk that is the resized icon
|
* @return the file on disk that is the resized icon
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user