Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul D'Pong2021-05-13 20:18:19 +0000
committerAlexander Kurtakov2021-07-15 13:09:01 +0000
commit1cdf6ba2a7deeb6c460b72fff42f89b6259ef714 (patch)
tree656a810a1cca2b04ddc63ca0e44549021deebcb5
parentc3467d0e91d24b386f87e3ec0802d3fb02fdd9e7 (diff)
downloadeclipse.platform.swt-1cdf6ba2a7deeb6c460b72fff42f89b6259ef714.tar.gz
eclipse.platform.swt-1cdf6ba2a7deeb6c460b72fff42f89b6259ef714.tar.xz
eclipse.platform.swt-1cdf6ba2a7deeb6c460b72fff42f89b6259ef714.zip
Bug 567258 - [GTK4] Convert Menus, GtkMenuBar, MenuItems to
GtkPopoverMenuBar - GTK4 dynamic addition fixes - Added Section class in order to keep track of menu separators in GTK4 - Fix previous GTK4 port by taking into account indexed insertion for both items & separators - Added SWT.CHECK menu item - Proper GTK4 deletion, taking account separators - One prominent problem is the SHOW and HIDE signals which doesn't exist with the model system Change-Id: I0130c7aab32c1998d7c204b73a23b97856004a31 Signed-off-by: Paul D'Pong <sdamrong@redhat.com> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/182420 Tested-by: Platform Bot <platform-bot@eclipse.org> Reviewed-by: Alexander Kurtakov <akurtako@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c26
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java36
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java82
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java217
9 files changed, 252 insertions, 126 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
index 26172e7bd5..d2275c0553 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
@@ -11359,6 +11359,20 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1action_1map_1add_1action)
}
#endif
+#ifndef NO_g_1action_1map_1remove_1action
+JNIEXPORT void JNICALL OS_NATIVE(g_1action_1map_1remove_1action)
+ (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1)
+{
+ jbyte *lparg1=NULL;
+ OS_NATIVE_ENTER(env, that, g_1action_1map_1remove_1action_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+ g_action_map_remove_action((GActionMap *)arg0, (const gchar *)lparg1);
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+ OS_NATIVE_EXIT(env, that, g_1action_1map_1remove_1action_FUNC);
+}
+#endif
+
#ifndef NO_g_1app_1info_1create_1from_1commandline
JNIEXPORT jlong JNICALL OS_NATIVE(g_1app_1info_1create_1from_1commandline)
(JNIEnv *env, jclass that, jbyteArray arg0, jbyteArray arg1, jlong arg2, jlong arg3)
@@ -12725,18 +12739,6 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1menu_1item_1set_1submenu)
}
#endif
-#ifndef NO_g_1menu_1model_1get_1n_1items
-JNIEXPORT jint JNICALL OS_NATIVE(g_1menu_1model_1get_1n_1items)
- (JNIEnv *env, jclass that, jlong arg0)
-{
- jint rc = 0;
- OS_NATIVE_ENTER(env, that, g_1menu_1model_1get_1n_1items_FUNC);
- rc = (jint)g_menu_model_get_n_items((GMenuModel *)arg0);
- OS_NATIVE_EXIT(env, that, g_1menu_1model_1get_1n_1items_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_g_1menu_1new
JNIEXPORT jlong JNICALL OS_NATIVE(g_1menu_1new)
(JNIEnv *env, jclass that)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
index 949de4d580..29cba343cf 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
@@ -965,6 +965,7 @@ char * OS_nativeFunctionNames[] = {
"g_1action_1get_1enabled",
"g_1action_1get_1state",
"g_1action_1map_1add_1action",
+ "g_1action_1map_1remove_1action",
"g_1app_1info_1create_1from_1commandline",
"g_1app_1info_1get_1all",
"g_1app_1info_1get_1default_1for_1type",
@@ -1062,7 +1063,6 @@ char * OS_nativeFunctionNames[] = {
"g_1menu_1item_1set_1attribute",
"g_1menu_1item_1set_1label",
"g_1menu_1item_1set_1submenu",
- "g_1menu_1model_1get_1n_1items",
"g_1menu_1new",
"g_1menu_1remove",
"g_1object_1get__J_3B_3IJ",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
index 1870a76e40..bc6c632dce 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
@@ -939,6 +939,7 @@ typedef enum {
g_1action_1get_1enabled_FUNC,
g_1action_1get_1state_FUNC,
g_1action_1map_1add_1action_FUNC,
+ g_1action_1map_1remove_1action_FUNC,
g_1app_1info_1create_1from_1commandline_FUNC,
g_1app_1info_1get_1all_FUNC,
g_1app_1info_1get_1default_1for_1type_FUNC,
@@ -1036,7 +1037,6 @@ typedef enum {
g_1menu_1item_1set_1attribute_FUNC,
g_1menu_1item_1set_1label_FUNC,
g_1menu_1item_1set_1submenu_FUNC,
- g_1menu_1model_1get_1n_1items_FUNC,
g_1menu_1new_FUNC,
g_1menu_1remove_FUNC,
g_1object_1get__J_3B_3IJ_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java
index c83814ea62..9444eb4b1a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java
@@ -87,7 +87,8 @@ public class GTK extends OS {
public static final int GTK_PHASE_CAPTURE = 1;
public static final int GTK_PHASE_BUBBLE = 2;
public static final int GTK_PHASE_TARGET = 3;
- public static final int GTK_POPOVER_MENU_NESTED = 1;
+ public static final int GTK_PROGRESS_LEFT_TO_RIGHT = 0x0;
+ public static final int GTK_PROGRESS_BOTTOM_TO_TOP = 0x2;
public static final int GTK_RESPONSE_CANCEL = 0xfffffffa;
public static final int GTK_RESPONSE_OK = 0xfffffffb;
public static final int GTK_RESPONSE_ACCEPT = -3;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index 436ddd60cc..4b905b498c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -2385,14 +2385,10 @@ public static final native void g_menu_item_set_label(long menu_item, byte[] lab
*/
public static final native void g_menu_item_set_attribute(long menu_item, byte[] attribute, byte[] format_string, long data);
-
-/* GMenuModel */
-/** @param model cast=(GMenuModel *) */
-public static final native int g_menu_model_get_n_items(long model);
-
-
-/* GAction */
+/* GSimpleActionGroup */
public static final native long g_simple_action_group_new();
+
+/* GSimpleAction */
/**
* @param name cast=(const gchar *)
* @param parameter_type cast=(const GVariantType *)
@@ -2405,22 +2401,30 @@ public static final native long g_simple_action_new(byte[] name, long parameter_
*/
public static final native long g_simple_action_new_stateful(byte[] name, long parameter_type, long initial_state);
/**
- * @param action_map cast=(GActionMap *)
- * @param action cast=(GAction *)
+ * @param simple_action cast=(GSimpleAction *)
+ * @param value cast=(GVariant *)
*/
-public static final native void g_action_map_add_action(long action_map, long action);
-/** @param action cast=(GAction *) */
-public static final native boolean g_action_get_enabled(long action);
+public static final native void g_simple_action_set_state(long simple_action, long value);
/** @param simple_action cast=(GSimpleAction *) */
public static final native void g_simple_action_set_enabled(long simple_action, boolean enabled);
+
+/* GAction */
+/** @param action cast=(GAction *) */
+public static final native boolean g_action_get_enabled(long action);
/** @param action cast=(GAction *) */
public static final native long g_action_get_state(long action);
+
+/* GActionMap */
/**
- * @param simple_action cast=(GSimpleAction *)
- * @param value cast=(GVariant *)
+ * @param action_map cast=(GActionMap *)
+ * @param action cast=(GAction *)
*/
-public static final native void g_simple_action_set_state(long simple_action, long value);
-
+public static final native void g_action_map_add_action(long action_map, long action);
+/**
+ * @param action_map cast=(GActionMap *)
+ * @param action_name cast=(const gchar *)
+ */
+public static final native void g_action_map_remove_action(long action_map, byte[] action_name);
/* GListModel */
/** @param list cast=(GListModel *) */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
index eceff5cdf3..fcfe80a81c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
@@ -17,6 +17,9 @@ package org.eclipse.swt.internal.gtk4;
* This class contains native functions that are present in GTK4 only.
*/
public class GTK4 {
+
+ public static final int GTK_POPOVER_MENU_NESTED = 1 << 0;
+
/**
* @param context cast=(GtkIMContext *)
* @param event cast=(GdkEvent *)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
index fe5e7e92c8..db560c04e5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
@@ -5792,8 +5792,11 @@ public boolean setParent (Composite parent) {
Menu [] menus = oldShell.findMenus (this);
if (oldShell != newShell || oldDecorations != newDecorations) {
fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus);
- newDecorations.fixAccelGroup ();
- oldDecorations.fixAccelGroup ();
+
+ if (!GTK.GTK4) {
+ newDecorations.fixAccelGroup ();
+ oldDecorations.fixAccelGroup ();
+ }
}
long newParent = parent.parentingHandle();
gtk_widget_reparent(this, newParent);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
index 89430d5420..b072f5e3d5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
@@ -54,8 +54,47 @@ public class Menu extends Widget {
int poppedUpCount;
/** GTK4 only fields */
- long modelHandle, actionGroup, shortcutController, sectionModelHandle;
- ArrayList<MenuItem> items;
+ long modelHandle, actionGroup, shortcutController;
+
+ class Section {
+ LinkedList<MenuItem> sectionItems;
+ private MenuItem separator;
+ private long sectionHandle;
+
+ public Section() {
+ this.sectionItems = new LinkedList<>();
+ }
+
+ public Section(MenuItem separator) {
+ this();
+ this.separator = separator;
+ }
+
+ public Section(long sectionHandle) {
+ this();
+
+ this.sectionHandle = sectionHandle;
+ }
+
+ public long getSectionHandle() {
+ return sectionHandle != 0 ? sectionHandle : separator.modelHandle;
+ }
+
+ public int getItemPosition(MenuItem item) {
+ return sectionItems.indexOf(item);
+ }
+
+ public int getSectionSize() {
+ return sectionItems.size();
+ }
+
+ public int getSectionPosition() {
+ return items.indexOf(separator);
+ }
+ }
+
+ LinkedList<Section> sections;
+ LinkedList<MenuItem> items;
/**
* Constructs a new instance of this class given its parent,
@@ -451,7 +490,8 @@ void createHandle (int index) {
modelHandle = OS.g_menu_new();
if (modelHandle == 0) error(SWT.ERROR_NO_HANDLES);
- items = new ArrayList<>();
+ items = new LinkedList<>();
+ sections = new LinkedList<>();
switch (style & bits) {
case SWT.BAR:
@@ -465,7 +505,7 @@ void createHandle (int index) {
break;
case SWT.POP_UP:
default:
- handle = GTK4.gtk_popover_menu_new_from_model_full(modelHandle, GTK.GTK_POPOVER_MENU_NESTED);
+ handle = GTK4.gtk_popover_menu_new_from_model_full(modelHandle, GTK4.GTK_POPOVER_MENU_NESTED);
GTK.gtk_widget_set_parent(handle, parent.handle);
GTK.gtk_popover_set_position(handle, GTK.GTK_POS_BOTTOM);
GTK4.gtk_popover_set_has_arrow(handle, false);
@@ -473,20 +513,20 @@ void createHandle (int index) {
if (handle == 0) error(SWT.ERROR_NO_HANDLES);
}
- sectionModelHandle = OS.g_menu_new();
- if (sectionModelHandle == 0) error(SWT.ERROR_NO_HANDLES);
+ // Create first section
+ long firstSection = OS.g_menu_new();
+ if (firstSection == 0) error(SWT.ERROR_NO_HANDLES);
+ sections.add(new Section(firstSection));
- long defaultSection = OS.g_menu_item_new_section(null, sectionModelHandle);
- OS.g_menu_insert_item(modelHandle, index, defaultSection);
+ long defaultSection = OS.g_menu_item_new_section(null, firstSection);
+ OS.g_menu_insert_item(modelHandle, 0, defaultSection);
OS.g_object_unref(defaultSection);
- if ((style & SWT.DROP_DOWN) == 0) {
- actionGroup = OS.g_simple_action_group_new();
- if (actionGroup == 0) error(SWT.ERROR_NO_HANDLES);
+ actionGroup = OS.g_simple_action_group_new();
+ if (actionGroup == 0) error(SWT.ERROR_NO_HANDLES);
- long shellHandle = parent.getShell().topHandle();
- GTK.gtk_widget_insert_action_group(shellHandle, Converter.javaStringToCString(String.valueOf(this.hashCode())), actionGroup);
- }
+ long shellHandle = parent.getShell().topHandle();
+ GTK.gtk_widget_insert_action_group(shellHandle, Converter.javaStringToCString(String.valueOf(this.hashCode())), actionGroup);
} else {
if ((style & SWT.BAR) != 0) {
handle = GTK3.gtk_menu_bar_new();
@@ -623,7 +663,7 @@ public int getItemCount () {
checkWidget();
if (GTK.GTK4) {
- return OS.g_menu_model_get_n_items(sectionModelHandle);
+ return items.size();
} else {
int count = 0;
long list = GTK3.gtk_container_get_children (handle);
@@ -896,6 +936,12 @@ void hookEvents() {
if (shortcutController == 0) error(SWT.ERROR_NO_HANDLES);
GTK4.gtk_shortcut_controller_set_scope(shortcutController, GTK.GTK_SHORTCUT_SCOPE_GLOBAL);
GTK4.gtk_widget_add_controller(parent.handle, shortcutController);
+
+ if ((style & SWT.DROP_DOWN) == 0) {
+ OS.g_signal_connect_closure_by_id(handle, display.signalIds[SHOW], 0, display.getClosure(SHOW), false);
+ OS.g_signal_connect_closure_by_id(handle, display.signalIds[HIDE], 0, display.getClosure(HIDE), false);
+ }
+
} else {
OS.g_signal_connect_closure_by_id(handle, display.signalIds[SHOW_HELP], 0, display.getClosure(SHOW_HELP), false);
@@ -903,10 +949,10 @@ void hookEvents() {
if (GTK.GTK_VERSION >= OS.VERSION(3, 22, 0) && OS.SWT_MENU_LOCATION_DEBUGGING) {
OS.g_signal_connect_closure_by_id(handle, display.signalIds[POPPED_UP], 0, display.getClosure(POPPED_UP), false);
}
- }
- OS.g_signal_connect_closure_by_id(handle, display.signalIds[SHOW], 0, display.getClosure(SHOW), false);
- OS.g_signal_connect_closure_by_id(handle, display.signalIds[HIDE], 0, display.getClosure(HIDE), false);
+ OS.g_signal_connect_closure_by_id(handle, display.signalIds[SHOW], 0, display.getClosure(SHOW), false);
+ OS.g_signal_connect_closure_by_id(handle, display.signalIds[HIDE], 0, display.getClosure(HIDE), false);
+ }
}
/**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java
index ede812b657..14dcc50e6b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java
@@ -21,6 +21,7 @@ import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.gtk3.*;
import org.eclipse.swt.internal.gtk4.*;
+import org.eclipse.swt.widgets.Menu.*;
/**
* Instances of this class represent a selectable user interface object
@@ -63,7 +64,7 @@ public class MenuItem extends Item {
/** GTK4 only fields */
long modelHandle, actionHandle, shortcutHandle;
- int parentMenuPosition;
+ Section section;
String actionName;
/**
@@ -261,61 +262,90 @@ protected void checkSubclass () {
}
@Override
-void createHandle (int index) {
+void createHandle(int index) {
state |= HANDLE;
- byte [] buffer = new byte [1];
int bits = SWT.CHECK | SWT.RADIO | SWT.PUSH | SWT.SEPARATOR | SWT.CASCADE;
if (GTK.GTK4) {
- modelHandle = OS.g_menu_new();
-
switch (style & bits) {
case SWT.SEPARATOR:
+ modelHandle = OS.g_menu_new();
handle = OS.g_menu_item_new_section(null, modelHandle);
- parent.sectionModelHandle = modelHandle;
break;
case SWT.RADIO:
- Menu popoverMenuWidget = parent;
- while (popoverMenuWidget.actionGroup == 0) {
- popoverMenuWidget = popoverMenuWidget.cascade.parent;
- }
-
long stringVariantType = OS.g_variant_type_new(OS.G_VARIANT_TYPE_STRING);
actionHandle = OS.g_simple_action_new_stateful(
- Converter.javaStringToCString(String.valueOf(this.hashCode())),
- stringVariantType,
- OS.g_variant_new_string(Converter.javaStringToCString("untoggled")));
- OS.g_action_map_add_action(popoverMenuWidget.actionGroup, actionHandle);
- actionName = String.valueOf(popoverMenuWidget.hashCode()) + "." + String.valueOf(this.hashCode()) + "::toggled";
+ Converter.javaStringToCString(String.valueOf(this.hashCode())),
+ stringVariantType,
+ OS.g_variant_new_string(Converter.javaStringToCString("untoggled")));
+ OS.g_action_map_add_action(parent.actionGroup, actionHandle);
+ actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode()) + "::toggled";
handle = OS.g_menu_item_new(null, Converter.javaStringToCString(actionName));
OS.g_variant_type_free(stringVariantType);
break;
+ case SWT.CHECK:
+ long boolVariantType = OS.g_variant_type_new(OS.G_VARIANT_TYPE_BOOLEAN);
+ actionHandle = OS.g_simple_action_new_stateful(
+ Converter.javaStringToCString(String.valueOf(this.hashCode())),
+ 0,
+ OS.g_variant_new_boolean(false));
+ OS.g_action_map_add_action(parent.actionGroup, actionHandle);
+ actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode());
+ handle = OS.g_menu_item_new(null, Converter.javaStringToCString(actionName));
+ OS.g_variant_type_free(boolVariantType);
+ break;
case SWT.CASCADE:
- handle = OS.g_menu_item_new_submenu(null, modelHandle);
+ modelHandle = OS.g_menu_new();
+ handle = OS.g_menu_item_new_submenu(Converter.javaStringToCString(""), modelHandle);
break;
case SWT.PUSH:
default:
- popoverMenuWidget = parent;
- while (popoverMenuWidget.actionGroup == 0) {
- popoverMenuWidget = popoverMenuWidget.cascade.parent;
- }
-
actionHandle = OS.g_simple_action_new(Converter.javaStringToCString(String.valueOf(this.hashCode())), 0);
- OS.g_action_map_add_action(popoverMenuWidget.actionGroup, actionHandle);
- actionName = String.valueOf(popoverMenuWidget.hashCode()) + "." + String.valueOf(this.hashCode());
+ OS.g_action_map_add_action(parent.actionGroup, actionHandle);
+ actionName = String.valueOf(parent.hashCode()) + "." + String.valueOf(this.hashCode());
handle = OS.g_menu_item_new(null, Converter.javaStringToCString(actionName));
break;
}
+
+ Section selectedSection = parent.sections.getLast();
+ for (Section section : parent.sections) {
+ int sectionPosition = section.getSectionPosition();
+ int sectionLength = section.getSectionSize();
+
+ if (index > sectionPosition && index <= sectionPosition + sectionLength + 1) {
+ selectedSection = section;
+ break;
+ }
+ }
+
+ int sectionRelativeIndex = index - (selectedSection.getSectionPosition() + 1);
if ((style & SWT.SEPARATOR) != 0) {
- OS.g_menu_insert_item(parent.modelHandle, index, handle);
+ section = parent.new Section(this);
+
+ int itemsToMove = selectedSection.sectionItems.size() - sectionRelativeIndex;
+ for (int i = 0; i < itemsToMove; i++) {
+ MenuItem removedItem = selectedSection.sectionItems.remove(sectionRelativeIndex);
+ section.sectionItems.add(removedItem);
+
+ OS.g_menu_remove(selectedSection.getSectionHandle(), sectionRelativeIndex);
+ OS.g_menu_insert_item(modelHandle, section.sectionItems.indexOf(removedItem), removedItem.handle);
+ removedItem.section = section;
+ }
+
+ int sectionInsertIndex = parent.sections.indexOf(selectedSection) + 1;
+ parent.sections.add(sectionInsertIndex, section);
+ OS.g_menu_insert_item(parent.modelHandle, sectionInsertIndex, handle);
} else {
- OS.g_menu_insert_item(parent.sectionModelHandle, index, handle);
+ section = selectedSection;
+ selectedSection.sectionItems.add(sectionRelativeIndex, this);
+ OS.g_menu_insert_item(selectedSection.getSectionHandle(), sectionRelativeIndex, handle);
}
- parentMenuPosition = index;
- parent.items.add(this);
+ parent.items.add(index, this);
} else {
+ byte[] buffer = new byte[1];
+
switch (style & bits) {
case SWT.SEPARATOR:
handle = GTK3.gtk_separator_menu_item_new ();
@@ -403,37 +433,35 @@ void createHandle (int index) {
}
break;
}
+
if (imageHandle != 0) {
if (OS.SWT_PADDED_MENU_ITEMS) {
GTK.gtk_image_set_pixel_size (imageHandle, 16);
}
- if (GTK.GTK4) {
- GTK4.gtk_box_append(boxHandle, imageHandle);
- } else {
- GTK3.gtk_container_add (boxHandle, imageHandle);
- GTK.gtk_widget_show (imageHandle);
- }
+
+ GTK3.gtk_container_add (boxHandle, imageHandle);
+ GTK.gtk_widget_show (imageHandle);
}
+
if (labelHandle != 0) {
GTK.gtk_label_set_xalign (labelHandle, 0);
GTK.gtk_widget_set_halign (labelHandle, GTK.GTK_ALIGN_FILL);
gtk_box_pack_end (boxHandle, labelHandle, true, true, 0);
GTK.gtk_widget_show (labelHandle);
}
+
if (boxHandle != 0) {
- if (GTK.GTK4) {
- // TODO: need to implement how menu items will be populated, currently no value for handle
- } else {
- GTK3.gtk_container_add (handle, boxHandle);
- GTK.gtk_widget_show (boxHandle);
- }
+ GTK3.gtk_container_add (handle, boxHandle);
+ GTK.gtk_widget_show (boxHandle);
}
+
if ((style & SWT.SEPARATOR) == 0) {
if (boxHandle == 0) {
labelHandle = GTK3.gtk_bin_get_child (handle);
}
GTK3.gtk_accel_label_set_accel_widget (labelHandle, 0);
}
+
long parentHandle = parent.handle;
boolean enabled = GTK.gtk_widget_get_sensitive (parentHandle);
if (!enabled) GTK.gtk_widget_set_sensitive (parentHandle, true);
@@ -477,20 +505,6 @@ long getAccelGroup () {
return shell.menuBar == menu ? shell.accelGroup : 0;
}
-/*public*/ Rectangle getBounds () {
- checkWidget();
- if (!GTK.gtk_widget_get_mapped (handle)) {
- return new Rectangle (0, 0, 0, 0);
- }
- GtkAllocation allocation = new GtkAllocation ();
- GTK.gtk_widget_get_allocation (handle, allocation);
- int x = allocation.x;
- int y = allocation.y;
- int width = allocation.width;
- int height = allocation.height;
- return new Rectangle (x, y, width, height);
-}
-
/**
* Returns <code>true</code> if the receiver is enabled, and
* <code>false</code> otherwise. A disabled menu item is typically
@@ -510,6 +524,10 @@ public boolean getEnabled () {
checkWidget();
if (GTK.GTK4) {
+ if ((style & SWT.CASCADE) != 0) {
+ return true;
+ }
+
return OS.g_action_get_enabled(actionHandle);
} else {
return GTK.gtk_widget_get_sensitive(handle);
@@ -593,8 +611,12 @@ public boolean getSelection () {
if (GTK.GTK4) {
long gVariantState = OS.g_action_get_state(actionHandle);
- String stateString = Converter.cCharPtrToJavaString(OS.g_variant_get_string(gVariantState, null), false);
- return stateString.equals("toggled");
+ if ((style & SWT.CHECK) != 0) {
+ return OS.g_variant_get_boolean(gVariantState);
+ } else {
+ String stateString = Converter.cCharPtrToJavaString(OS.g_variant_get_string(gVariantState, null), false);
+ return stateString.equals("toggled");
+ }
} else {
return GTK3.gtk_check_menu_item_get_active(handle);
}
@@ -669,8 +691,7 @@ void hookEvents() {
super.hookEvents();
if (GTK.GTK4) {
- // Bind activate signal only for menu items with actions (SWT.CHECK and SWT.RADIO)
- if (actionHandle != 0) {
+ if ((style & SWT.PUSH) != 0 || (style & SWT.RADIO) != 0) {
OS.g_signal_connect(actionHandle, OS.activate, display.activateProc, handle);
}
} else {
@@ -709,24 +730,64 @@ void releaseChildren (boolean destroy) {
}
@Override
-void releaseParent () {
- super.releaseParent ();
+void releaseParent() {
+ super.releaseParent();
+
if (menu != null) {
if (menu.selectedItem == this) menu.selectedItem = null;
- menu.dispose ();
+ menu.dispose();
+
+ menu = null;
}
- menu = null;
}
@Override
-void releaseWidget () {
- super.releaseWidget ();
- long accelGroup = getAccelGroup ();
- if (accelGroup != 0) removeAccelerator (accelGroup);
- if (groupHandle != 0) OS.g_object_unref (groupHandle);
- groupHandle = 0;
+void releaseWidget() {
+ super.releaseWidget();
+
+ if (GTK.GTK4) {
+ if (parent.actionGroup != 0 && actionName != null) OS.g_action_map_remove_action(parent.actionGroup, Converter.javaStringToCString(actionName));
+ } else {
+ long accelGroup = getAccelGroup();
+ if (accelGroup != 0) removeAccelerator(accelGroup);
+
+ if (groupHandle != 0) OS.g_object_unref(groupHandle);
+ groupHandle = 0;
+ parent = null;
+ }
+
accelerator = 0;
- parent = null;
+}
+
+@Override
+void destroyWidget() {
+ if (GTK.GTK4) {
+ if ((style & SWT.SEPARATOR) != 0) {
+ Section aboveSection = parent.sections.get(parent.sections.indexOf(section) - 1);
+ aboveSection.sectionItems.addAll(section.sectionItems);
+
+ for (MenuItem item : section.sectionItems) {
+ OS.g_menu_insert_item(aboveSection.getSectionHandle(), aboveSection.sectionItems.indexOf(item), item.handle);
+ }
+
+ OS.g_menu_remove(parent.modelHandle, parent.sections.indexOf(section));
+
+ parent.sections.remove(section);
+ } else {
+ OS.g_menu_remove(section.getSectionHandle(), section.sectionItems.indexOf(this));
+ section.sectionItems.remove(this);
+ }
+
+ parent.items.remove(this);
+ parent = null;
+
+ if (modelHandle != 0) OS.g_object_unref(modelHandle);
+ OS.g_object_unref(handle);
+
+ releaseHandle();
+ } else {
+ super.destroyWidget();
+ }
}
void removeAccelerator (long accelGroup) {
@@ -908,7 +969,7 @@ public void setEnabled (boolean enabled) {
checkWidget();
if (GTK.GTK4) {
- OS.g_simple_action_set_enabled(actionHandle, enabled);
+ if (actionHandle != 0) OS.g_simple_action_set_enabled(actionHandle, enabled);
} else {
if (GTK.gtk_widget_get_sensitive(handle) == enabled) return;
long accelGroup = getAccelGroup();
@@ -1065,8 +1126,8 @@ public void setMenu (Menu menu) {
OS.g_menu_item_set_submenu(handle, 0);
}
- OS.g_menu_remove(parent.sectionModelHandle, parentMenuPosition);
- OS.g_menu_insert_item(parent.sectionModelHandle, parentMenuPosition, handle);
+ OS.g_menu_remove(section.getSectionHandle(), section.getItemPosition(this));
+ OS.g_menu_insert_item(section.getSectionHandle(), section.getItemPosition(this), handle);
} else {
long accelGroup = getAccelGroup ();
if (accelGroup != 0) removeAccelerators (accelGroup);
@@ -1125,7 +1186,11 @@ public void setSelection (boolean selected) {
if ((style & (SWT.CHECK | SWT.RADIO)) == 0) return;
if (GTK.GTK4) {
- OS.g_simple_action_set_state(actionHandle, OS.g_variant_new_string(Converter.javaStringToCString(selected ? "toggled" : "untoggled")));
+ if ((style & SWT.CHECK) != 0) {
+ OS.g_simple_action_set_state(actionHandle, OS.g_variant_new_boolean(selected));
+ } else {
+ OS.g_simple_action_set_state(actionHandle, OS.g_variant_new_string(Converter.javaStringToCString(selected ? "toggled" : "untoggled")));
+ }
} else {
OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, ACTIVATE);
GTK3.gtk_check_menu_item_set_active (handle, selected);
@@ -1196,8 +1261,8 @@ public void setText (String string) {
GTK.gtk_accelerator_name(maskKeysym.keysym, maskKeysym.mask)
);
}
- OS.g_menu_remove(parent.sectionModelHandle, parentMenuPosition);
- OS.g_menu_insert_item(parent.sectionModelHandle, parentMenuPosition, handle);
+ OS.g_menu_remove(section.getSectionHandle(), section.getItemPosition(this));
+ OS.g_menu_insert_item(section.getSectionHandle(), section.getItemPosition(this), handle);
} else {
if (labelHandle != 0 && GTK.GTK_IS_LABEL (labelHandle)) {
GTK.gtk_label_set_text_with_mnemonic (labelHandle, buffer);
@@ -1247,6 +1312,8 @@ public void setText (String string) {
*/
public void setToolTipText(String toolTip) {
checkWidget();
+ if (GTK.GTK4) return; // GTK4 does not support tooltips within menus
+
if (toolTip != null && (toolTip.trim().length() == 0 || toolTip.equals(toolTipText))) return;
toolTipText = toolTip;

Back to the top