Fixed getting the checkmark image file.

This commit is contained in:
nathan 2017-07-03 15:19:23 +02:00
parent a6711dacb4
commit be636f1ea9

View File

@ -16,14 +16,10 @@
package dorkbox.systemTray.nativeUI;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JMenuItem;
import com.sun.jna.Pointer;
@ -37,7 +33,6 @@ import dorkbox.systemTray.peer.CheckboxPeer;
import dorkbox.systemTray.util.HeavyCheckMark;
import dorkbox.systemTray.util.ImageResizeUtil;
import dorkbox.util.OSUtil;
import dorkbox.util.SwingUtil;
@SuppressWarnings("deprecation")
class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCallback {
@ -46,18 +41,17 @@ class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCall
// here, it doesn't matter what size the image is, as long as there is an image, the text in the menu will be shifted correctly
private static final String uncheckedFile = ImageResizeUtil.getTransparentImage().getAbsolutePath();
// Note: So far, ONLY Ubuntu has managed to fail at rendering (bad layouts) checkbox menu items.
// Note: So far, ONLY Ubuntu has managed to fail at rendering (via bad layouts) checkbox menu items.
// If there are OTHER OSes that fail, checks for them should be added here
private static final boolean useFakeCheckMark;
static {
// this class is initialized on the GTK dispatch thread.
if (SystemTray.AUTO_FIX_INCONSISTENCIES &&
(SystemTray.get().getMenu() instanceof _AppIndicatorNativeTray) &&
OSUtil.Linux.isUbuntu()) {
(SystemTray.get().getMenu() instanceof _AppIndicatorNativeTray) && OSUtil.Linux.isUbuntu()) {
useFakeCheckMark = true;
} else {
useFakeCheckMark = false;
useFakeCheckMark = true;
}
if (SystemTray.DEBUG) {
@ -104,32 +98,22 @@ class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCall
if (useFakeCheckMark) {
if (checkedFile == null) {
// on GTK thread
final Color color = GtkTheme.getCurrentThemeTextColor();
final Color color = GtkTheme.getTextColor();
// have to invoke Swing components on the Swing thread! In some cases, when the UI Manager is the native one (and
// thus is GTK), the swing thread is combined with the GTK thread. This causes problems!
SwingUtil.invokeLater(new Runnable() {
@Override
public
void run() {
if (checkedFile == null) {
checkedFile = getCheckedFile(color);
}
if (checkedFile == null) {
Rectangle size = GtkTheme.getPixelTextHeight("X");
// now that the swing part is finished, we can conclude with the GTK part
Gtk.dispatch(new Runnable() {
@Override
public
void run() {
setCheckedIconForFakeCheckMarks();
}
});
if ((SystemTray.get().getMenu() instanceof _AppIndicatorNativeTray)) {
// only app indicators don't need padding, as they automatically center the icon
checkedFile = HeavyCheckMark.get(color, size.height, 0, 0, 0, 0);
} else {
Insets padding = GtkTheme.getTextPadding("X");
checkedFile = HeavyCheckMark.get(color, size.height, 0, padding.left, 0, padding.right);
}
});
} else {
setCheckedIconForFakeCheckMarks();
}
}
setCheckedIconForFakeCheckMarks();
} else {
Gobject.g_signal_handler_block(_native, handlerId);
Gtk.gtk_check_menu_item_set_active(_native, false);
@ -149,11 +133,13 @@ class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCall
return Gtk.TRUE;
}
@Override
public
boolean hasImage() {
return true;
}
@Override
public
void setSpacerImage(final boolean everyoneElseHasImages) {
// no op
@ -314,50 +300,4 @@ class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCall
}
});
}
/**
* This must always occur on the SWING thread (because stuff here is SWING related...)
*
* This saves a scalable CheckMark to a correctly sized PNG file.
*
* @param color the color of the CheckMark
*/
private static
String getCheckedFile(Color color) {
final int iconSize = 32;
String name = iconSize + "_checkMark" + HeavyCheckMark.VERSION + "_" + color.getRGB() + ".png";
final File newFile = new File(ImageResizeUtil.TEMP_DIR, name).getAbsoluteFile();
if (newFile.canRead() || newFile.length() == 0) {
try {
JMenuItem jMenuItem = new JMenuItem();
// do the same modifications that would also happen (if specified) for the actual displayed menu items
if (SystemTray.SWING_UI != null) {
jMenuItem.setUI(SystemTray.SWING_UI.getItemUI(jMenuItem, null));
}
// make sure the directory exists
if (!newFile.getParentFile()
.isDirectory()) {
boolean mkdirs = newFile.getParentFile()
.mkdirs();
if (!mkdirs) {
SystemTray.logger.error("Unable to create directory for check-mark image at: {}", newFile);
}
}
// get the largest font (based on the orig font) that can be used WITHOUT changing the size of the JMenuItem
Font fontForSpecificHeight = SwingUtil.getFontForSpecificHeight(jMenuItem.getFont(), iconSize);
BufferedImage img = HeavyCheckMark.draw(fontForSpecificHeight, color);
ImageIO.write(img, "png", newFile);
} catch (Exception e) {
SystemTray.logger.error("Error creating check-mark image.", e);
}
}
return newFile.getAbsolutePath();
}
}