Menu entry font size is also adjusted (if necessary) based on scaling
of UI. This impact is specifically for swing menus, notably windows.
This commit is contained in:
parent
1d3b65f4c4
commit
9abc2bdc5f
|
@ -695,7 +695,7 @@ class SystemTray {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageUtils.determineIconSize();
|
ImageUtils.determineIconSize(!useNativeMenus);
|
||||||
|
|
||||||
final AtomicReference<Tray> reference = new AtomicReference<Tray>();
|
final AtomicReference<Tray> reference = new AtomicReference<Tray>();
|
||||||
|
|
||||||
|
|
|
@ -15,27 +15,18 @@
|
||||||
*/
|
*/
|
||||||
package dorkbox.systemTray.swingUI;
|
package dorkbox.systemTray.swingUI;
|
||||||
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
import dorkbox.systemTray.SystemTray;
|
|
||||||
import dorkbox.systemTray.util.ImageUtils;
|
import dorkbox.systemTray.util.ImageUtils;
|
||||||
|
|
||||||
class AdjustedJMenu extends JMenu {
|
class AdjustedJMenu extends JMenu {
|
||||||
// get the scale (and multiply it to our font size) to get the new font size
|
|
||||||
private static int scale = ImageUtils.ENTRY_SIZE / SystemTray.DEFAULT_MENU_SIZE;
|
|
||||||
|
|
||||||
AdjustedJMenu() {
|
AdjustedJMenu() {
|
||||||
super();
|
super();
|
||||||
|
setFont(ImageUtils.ENTRY_FONT);
|
||||||
Font font = getFont();
|
|
||||||
int size = font.getSize();
|
|
||||||
size = size * scale;
|
|
||||||
setFont(new Font(font.getName(), font.getStyle(), size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,25 +15,17 @@
|
||||||
*/
|
*/
|
||||||
package dorkbox.systemTray.swingUI;
|
package dorkbox.systemTray.swingUI;
|
||||||
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
|
||||||
import dorkbox.systemTray.SystemTray;
|
|
||||||
import dorkbox.systemTray.util.ImageUtils;
|
import dorkbox.systemTray.util.ImageUtils;
|
||||||
|
|
||||||
class AdjustedJMenuItem extends JMenuItem {
|
class AdjustedJMenuItem extends JMenuItem {
|
||||||
// get the scale (and multiply it to our font size) to get the new font size
|
|
||||||
private static int scale = ImageUtils.ENTRY_SIZE / SystemTray.DEFAULT_MENU_SIZE;
|
|
||||||
|
|
||||||
AdjustedJMenuItem() {
|
AdjustedJMenuItem() {
|
||||||
super();
|
super();
|
||||||
|
setFont(ImageUtils.ENTRY_FONT);
|
||||||
Font font = getFont();
|
|
||||||
int size = font.getSize();
|
|
||||||
size = size * scale;
|
|
||||||
setFont(new Font(font.getName(), font.getStyle(), size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,9 +20,12 @@ import static dorkbox.systemTray.jna.windows.Gdi32.LOGPIXELSX;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
@ -40,6 +43,7 @@ import javax.imageio.ImageIO;
|
||||||
import javax.imageio.ImageReader;
|
import javax.imageio.ImageReader;
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
@ -66,8 +70,12 @@ class ImageUtils {
|
||||||
public static volatile int TRAY_SIZE = 0;
|
public static volatile int TRAY_SIZE = 0;
|
||||||
public static volatile int ENTRY_SIZE = 0;
|
public static volatile int ENTRY_SIZE = 0;
|
||||||
|
|
||||||
|
// the menu entry font size ALSO must be detected, and it is a little bit tricky to figure this out.
|
||||||
|
// Only exists (and is necessary) for SWING menus
|
||||||
|
public static volatile Font ENTRY_FONT = null;
|
||||||
|
|
||||||
public static
|
public static
|
||||||
void determineIconSize() {
|
void determineIconSize(boolean trayHasSwingMenus) {
|
||||||
double trayScalingFactor = 0;
|
double trayScalingFactor = 0;
|
||||||
double menuScalingFactor = 0;
|
double menuScalingFactor = 0;
|
||||||
|
|
||||||
|
@ -75,7 +83,8 @@ class ImageUtils {
|
||||||
if (OS.isWindows()) {
|
if (OS.isWindows()) {
|
||||||
int[] version = OSUtil.Windows.getVersion();
|
int[] version = OSUtil.Windows.getVersion();
|
||||||
|
|
||||||
// if windows 8.1/10 - default size is x2
|
// windows 8/8.1/10 are the only windows OSes to do scaling properly (XP/Vista/7 do DPI scaling, which is terrible anyways)
|
||||||
|
// we are going to let windows manage scaling the icon correctly, but we are BY DEFAULT going to give it a large size to scale
|
||||||
|
|
||||||
// vista - 8.0 - only global DPI settings
|
// vista - 8.0 - only global DPI settings
|
||||||
// 8.1 - 10 - global + per-monitor DPI settings
|
// 8.1 - 10 - global + per-monitor DPI settings
|
||||||
|
@ -90,12 +99,12 @@ class ImageUtils {
|
||||||
// Windows XP 5.1.2600 (2001-10-25)
|
// Windows XP 5.1.2600 (2001-10-25)
|
||||||
// Windows Server 2003 5.2.3790 (2003-04-24)
|
// Windows Server 2003 5.2.3790 (2003-04-24)
|
||||||
// Windows Home Server 5.2.3790 (2007-06-16)
|
// Windows Home Server 5.2.3790 (2007-06-16)
|
||||||
trayScalingFactor = 1;
|
trayScalingFactor = 2;
|
||||||
} else if (version[0] == 6 && version[1] == 0) {
|
} else if (version[0] == 6 && version[1] == 0) {
|
||||||
// Windows Vista 6.0.6000 (2006-11-08)
|
// Windows Vista 6.0.6000 (2006-11-08)
|
||||||
// Windows Server 2008 SP1 6.0.6001 (2008-02-27)
|
// Windows Server 2008 SP1 6.0.6001 (2008-02-27)
|
||||||
// Windows Server 2008 SP2 6.0.6002 (2009-04-28)
|
// Windows Server 2008 SP2 6.0.6002 (2009-04-28)
|
||||||
trayScalingFactor = 1;
|
trayScalingFactor = 2;
|
||||||
|
|
||||||
} else if (version[0] == 6 && version[1] <= 2) {
|
} else if (version[0] == 6 && version[1] <= 2) {
|
||||||
// Windows 7 6.1.7600 (2009-10-22)
|
// Windows 7 6.1.7600 (2009-10-22)
|
||||||
|
@ -106,8 +115,8 @@ class ImageUtils {
|
||||||
//
|
//
|
||||||
// Windows 8 6.2.9200 (2012-10-26)
|
// Windows 8 6.2.9200 (2012-10-26)
|
||||||
// Windows Server 2012 6.2.9200 (2012-09-04)
|
// Windows Server 2012 6.2.9200 (2012-09-04)
|
||||||
trayScalingFactor = 2;
|
trayScalingFactor = 4;
|
||||||
} else if (version[0] == 6 || (version[0] == 10 && version[1] == 0)) {
|
} else {
|
||||||
// Windows 8.1 6.3.9600 (2013-10-18)
|
// Windows 8.1 6.3.9600 (2013-10-18)
|
||||||
// Windows Server 2012 R2 6.3.9600 (2013-10-18)
|
// Windows Server 2012 R2 6.3.9600 (2013-10-18)
|
||||||
//
|
//
|
||||||
|
@ -117,11 +126,10 @@ class ImageUtils {
|
||||||
//
|
//
|
||||||
// Windows Server 2016 10.0.14393 (2016-10-12)
|
// Windows Server 2016 10.0.14393 (2016-10-12)
|
||||||
trayScalingFactor = 4;
|
trayScalingFactor = 4;
|
||||||
} else {
|
|
||||||
// dunnno, but i'm going to assume really HiDPI for this...
|
|
||||||
trayScalingFactor = 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get's the HARDWARE DEVICE logical resolution. This will be set by the monitor, and will never change - even if
|
||||||
|
// scaling is changed via the control panel
|
||||||
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);
|
||||||
|
@ -132,13 +140,12 @@ class ImageUtils {
|
||||||
// 192 DPI = 200% scaling
|
// 192 DPI = 200% scaling
|
||||||
|
|
||||||
// just a note on 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
|
// We want to scale the image as best we can beforehand, so there is an attempt to have it look good. Java by default
|
||||||
|
// does not scale this correctly.
|
||||||
if (dpiX != 96) {
|
if (dpiX != 96) {
|
||||||
// so there are additional scaling settings...
|
// so there are additional scaling settings...
|
||||||
// casting around for rounding/math stuff
|
// casting around for rounding/math stuff
|
||||||
// *2 because we want a 2x scale to be 64, not 32.
|
menuScalingFactor = ((double) dpiX) / 96.0;
|
||||||
trayScalingFactor = (int) (((double) dpiX) / ((double) 96)) * 2;
|
|
||||||
menuScalingFactor = (((double) dpiX) / ((double) 96));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,12 +294,63 @@ class ImageUtils {
|
||||||
ENTRY_SIZE = SystemTray.DEFAULT_MENU_SIZE;
|
ENTRY_SIZE = SystemTray.DEFAULT_MENU_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this must be a JMenuItem component, because that is the component we are setting the font on.
|
||||||
|
// this is only important to do if we are a swing tray type
|
||||||
|
if (trayHasSwingMenus) {
|
||||||
|
// must be a plain style font
|
||||||
|
Font font = new JMenuItem().getFont().deriveFont(Font.PLAIN);
|
||||||
|
|
||||||
|
if (menuScalingFactor > 1) {
|
||||||
|
font = ImageUtils.getFontForSpecificHeight(font, ENTRY_SIZE);
|
||||||
if (SystemTray.DEBUG) {
|
if (SystemTray.DEBUG) {
|
||||||
SystemTray.logger.debug("Scaling Factor factor is '{}', tray icon size is '{}'.", trayScalingFactor, TRAY_SIZE);
|
SystemTray.logger.debug("Menu entry font size '{}' found for requested size '{}'", font.getSize(), ENTRY_SIZE);
|
||||||
SystemTray.logger.debug("Scaling Factor factor is '{}', tray menu size is '{}'.", menuScalingFactor, ENTRY_SIZE);
|
}
|
||||||
|
} else if (SystemTray.DEBUG) {
|
||||||
|
SystemTray.logger.debug("Menu entry font size '{}'. Not scaling for requested size '{}'", font.getSize(), ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY_FONT = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SystemTray.DEBUG) {
|
||||||
|
SystemTray.logger.debug("ScalingFactor is '{}', tray icon size is '{}'.", trayScalingFactor, TRAY_SIZE);
|
||||||
|
SystemTray.logger.debug("ScalingFactor is '{}', tray menu size is '{}'.", menuScalingFactor, ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the correct font (in GENERAL) for a specified pixel height.
|
||||||
|
* @param font the font we are checking
|
||||||
|
* @param height the height in pixels we want to get as close as possible to
|
||||||
|
*
|
||||||
|
* @return the font (derived from the specified font) that is as close as possible to the requested height
|
||||||
|
*/
|
||||||
|
private static
|
||||||
|
Font getFontForSpecificHeight(final Font font, final int height) {
|
||||||
|
int size = font.getSize();
|
||||||
|
Boolean lastAction = null;
|
||||||
|
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D g = image.createGraphics();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Font fontCheck = new Font(font.getName(), Font.PLAIN, size);
|
||||||
|
|
||||||
|
FontMetrics metrics = g.getFontMetrics(fontCheck);
|
||||||
|
Rectangle2D rect = metrics.getStringBounds("Tj|", g);
|
||||||
|
int testHeight = (int) rect.getHeight();
|
||||||
|
|
||||||
|
if (testHeight < height && lastAction != Boolean.FALSE) {
|
||||||
|
size++;
|
||||||
|
lastAction = Boolean.TRUE;
|
||||||
|
} else if (testHeight > height && lastAction != Boolean.TRUE) {
|
||||||
|
size--;
|
||||||
|
lastAction = Boolean.FALSE;
|
||||||
|
} else {
|
||||||
|
// either we are the exact size, or we are ONE font size to big/small (depending on what our initial guess was)
|
||||||
|
return fontCheck;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
public static
|
public static
|
||||||
|
|
Loading…
Reference in New Issue
Block a user