Added 'hasImage()' to menu-entry. Fixed text entry alignment issues

for GTK menus
This commit is contained in:
nathan 2016-09-27 00:50:51 +02:00
parent 27fa213fc1
commit 34588de6b7
4 changed files with 78 additions and 11 deletions

View File

@ -66,9 +66,13 @@ interface MenuEntry {
*
* @param imageStream the InputStream of the image to use
*/
@Deprecated
void setImage(InputStream imageStream);
/**
* @return true if this menu entry has an image assigned to it, or is just text.
*/
boolean hasImage();
/**
* Sets a callback for a menu entry. This is the action that occurs when one clicks the menu entry
*

View File

@ -45,6 +45,10 @@ class GtkMenuEntry implements MenuEntry, GCallback {
private volatile SystemTrayMenuAction callback;
private volatile Pointer image;
// these are necessary BECAUSE GTK menus look funky as hell when there are some menu entries WITH icons and some WITHOUT
private volatile boolean hasLegitIcon = true;
private static File transparentIcon = null;
/**
* called from inside dispatch thread. ONLY creates the menu item, but DOES NOT attach it!
* this is a FLOATING reference. See: https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref
@ -56,13 +60,19 @@ class GtkMenuEntry implements MenuEntry, GCallback {
menuItem = Gtk.gtk_image_menu_item_new_with_label(label);
if (imagePath != null) {
if (transparentIcon == null) {
transparentIcon = ImageUtils.getTransparentImage(ImageUtils.ENTRY_SIZE);
}
hasLegitIcon = imagePath != null;
if (hasLegitIcon) {
// NOTE: XFCE used to use appindicator3, which DOES NOT support images in the menu. This change was reverted.
// see: https://ask.fedoraproject.org/en/question/23116/how-to-fix-missing-icons-in-program-menus-and-context-menus/
// see: https://git.gnome.org/browse/gtk+/commit/?id=627a03683f5f41efbfc86cc0f10e1b7c11e9bb25
image = Gtk.gtk_image_new_from_file(imagePath.getAbsolutePath());
Gtk.gtk_image_menu_item_set_image(menuItem, image);
// must always re-set always-show after setting the image
Gtk.gtk_image_menu_item_set_always_show_image(menuItem, Gtk.TRUE);
}
@ -70,6 +80,34 @@ class GtkMenuEntry implements MenuEntry, GCallback {
nativeLong = Gobject.g_signal_connect_object(menuItem, "activate", this, null, 0);
}
/**
* the menu entry looks FUNKY when there are a mis-match of entries WITH and WITHOUT images
*
* called on the DISPATCH thread
*/
void setSpacerImage(final boolean everyoneElseHasImages) {
if (hasLegitIcon) {
// we have a legit icon, so there is nothing else we can do.
return;
}
if (image != null) {
Gtk.gtk_widget_destroy(image);
image = null;
Gtk.gtk_widget_show_all(menuItem);
}
if (everyoneElseHasImages) {
image = Gtk.gtk_image_new_from_file(transparentIcon.getAbsolutePath());
Gtk.gtk_image_menu_item_set_image(menuItem, image);
// must always re-set always-show after setting the image
Gtk.gtk_image_menu_item_set_always_show_image(menuItem, Gtk.TRUE);
}
Gtk.gtk_widget_show_all(menuItem);
}
// called by native code
@Override
@ -105,7 +143,9 @@ class GtkMenuEntry implements MenuEntry, GCallback {
}
private
void setImage_(final File imagePath) {
void setImage_(final File imageFile) {
hasLegitIcon = imageFile != null;
Gtk.dispatch(new Runnable() {
@Override
public
@ -113,12 +153,11 @@ class GtkMenuEntry implements MenuEntry, GCallback {
if (image != null) {
Gtk.gtk_widget_destroy(image);
image = null;
Gtk.gtk_widget_show_all(menuItem);
}
Gtk.gtk_widget_show_all(menuItem);
if (imagePath != null) {
image = Gtk.gtk_image_new_from_file(imagePath.getAbsolutePath());
if (hasLegitIcon) {
image = Gtk.gtk_image_new_from_file(imageFile.getAbsolutePath());
Gtk.gtk_image_menu_item_set_image(menuItem, image);
Gobject.g_object_ref_sink(image);
@ -165,7 +204,6 @@ class GtkMenuEntry implements MenuEntry, GCallback {
}
@Override
@Deprecated
public
void setImage(final InputStream imageStream) {
if (imageStream == null) {
@ -176,6 +214,12 @@ class GtkMenuEntry implements MenuEntry, GCallback {
}
}
@Override
public
boolean hasImage() {
return hasLegitIcon;
}
@Override
public
void setCallback(final SystemTrayMenuAction callback) {

View File

@ -163,11 +163,22 @@ class GtkTypeSystemTray extends SystemTray {
Gobject.g_object_ref_sink(connectionStatusItem);
}
boolean hasImages = false;
// now add back other menu entries
synchronized (menuEntries) {
for (int i = 0; i < menuEntries.size(); i++) {
GtkMenuEntry menuEntry__ = (GtkMenuEntry) menuEntries.get(i);
hasImages |= menuEntry__.hasImage();
}
for (int i = 0; i < menuEntries.size(); i++) {
GtkMenuEntry menuEntry__ = (GtkMenuEntry) menuEntries.get(i);
// the menu entry looks FUNKY when there are a mis-match of entries WITH and WITHOUT images
menuEntry__.setSpacerImage(hasImages);
// will also get: gsignal.c:2516: signal 'child-added' is invalid for instance '0x7f1df8244080' of type 'GtkMenu'
Gtk.gtk_menu_shell_append(this.menu, menuEntry__.menuItem);
Gobject.g_object_ref_sink(menuEntry__.menuItem);
@ -264,8 +275,7 @@ class GtkTypeSystemTray extends SystemTray {
addMenuEntry_(menuText, null, callback);
}
else {
// addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
addMenuEntry_(menuText, ImageUtils.getTransparentImage(ImageUtils.ENTRY_SIZE), callback);
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
}
}

View File

@ -37,6 +37,7 @@ class SwingMenuEntry implements MenuEntry {
private final JMenuItem menuItem;
private final ActionListener swingCallback;
private volatile boolean hasLegitIcon = false;
private volatile String text;
private volatile SystemTrayMenuAction callback;
@ -61,6 +62,7 @@ class SwingMenuEntry implements MenuEntry {
menuItem.addActionListener(swingCallback);
if (imagePath != null) {
hasLegitIcon = true;
setImageIcon(imagePath);
}
@ -110,10 +112,12 @@ class SwingMenuEntry implements MenuEntry {
private
void setImageIcon(final File imagePath) {
if (imagePath != null) {
hasLegitIcon = true;
ImageIcon origIcon = new ImageIcon(imagePath.getAbsolutePath());
menuItem.setIcon(origIcon);
}
else {
hasLegitIcon = false;
menuItem.setIcon(null);
}
}
@ -152,7 +156,6 @@ class SwingMenuEntry implements MenuEntry {
}
@Override
@Deprecated
public
void setImage(final InputStream imageStream) {
if (imageStream == null) {
@ -163,6 +166,12 @@ class SwingMenuEntry implements MenuEntry {
}
}
@Override
public
boolean hasImage() {
return hasLegitIcon;
}
@Override
public
void setCallback(final SystemTrayMenuAction callback) {