5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 06:39:30 +08:00
wails/v2/internal/frontend/desktop/linux/gtk.go
Lea Anthony 642fa42f25
Feature/v2 linux menus (#1114)
* Render menubar + text menu items

* Support disabled menuitems + callbacks

* Support checkboxes

* Support reusing checkboxes

* Support submenus

* Support Radio menuitems

* Support Menu Accelerators
2022-01-29 07:19:14 +11:00

74 lines
2.2 KiB
Go

package linux
/*
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0
#include "gtk/gtk.h"
static GtkCheckMenuItem *toGtkCheckMenuItem(void *pointer) { return (GTK_CHECK_MENU_ITEM(pointer)); }
extern void blockClick(GtkWidget* menuItem, gulong handler_id);
extern void unblockClick(GtkWidget* menuItem, gulong handler_id);
*/
import "C"
import "unsafe"
import "github.com/wailsapp/wails/v2/pkg/menu"
func GtkMenuItemWithLabel(label string) *C.GtkWidget {
cLabel := C.CString(label)
result := C.gtk_menu_item_new_with_label(cLabel)
C.free(unsafe.Pointer(cLabel))
return result
}
func GtkCheckMenuItemWithLabel(label string) *C.GtkWidget {
cLabel := C.CString(label)
result := C.gtk_check_menu_item_new_with_label(cLabel)
C.free(unsafe.Pointer(cLabel))
return result
}
func GtkRadioMenuItemWithLabel(label string, group *C.GSList) *C.GtkWidget {
cLabel := C.CString(label)
result := C.gtk_radio_menu_item_new_with_label(group, cLabel)
C.free(unsafe.Pointer(cLabel))
return result
}
//export handleMenuItemClick
func handleMenuItemClick(gtkWidget unsafe.Pointer) {
item := gtkSignalToMenuItem[(*C.GtkWidget)(gtkWidget)]
switch item.Type {
case menu.CheckboxType:
item.Checked = !item.Checked
checked := C.int(0)
if item.Checked {
checked = C.int(1)
}
for _, gtkCheckbox := range gtkCheckboxCache[item] {
handler := gtkSignalHandlers[gtkCheckbox]
C.blockClick(gtkCheckbox, handler)
C.gtk_check_menu_item_set_active(C.toGtkCheckMenuItem(unsafe.Pointer(gtkCheckbox)), checked)
C.unblockClick(gtkCheckbox, handler)
}
item.Click(&menu.CallbackData{MenuItem: item})
case menu.RadioType:
gtkRadioItems := gtkRadioMenuCache[item]
active := C.gtk_check_menu_item_get_active(C.toGtkCheckMenuItem(gtkWidget))
if int(active) == 1 {
for _, gtkRadioItem := range gtkRadioItems {
handler := gtkSignalHandlers[gtkRadioItem]
C.blockClick(gtkRadioItem, handler)
C.gtk_check_menu_item_set_active(C.toGtkCheckMenuItem(unsafe.Pointer(gtkRadioItem)), 1)
C.unblockClick(gtkRadioItem, handler)
}
item.Checked = true
item.Click(&menu.CallbackData{MenuItem: item})
} else {
item.Checked = false
}
default:
item.Click(&menu.CallbackData{MenuItem: item})
}
}