1// Same copyright and license as the rest of the files in this project
2// This file contains accelerator related functions and structures
3
4package gtk
5
6// #include <gtk/gtk.h>
7// #include "gtk.go.h"
8import "C"
9import (
10	"unsafe"
11
12	"github.com/gotk3/gotk3/gdk"
13	"github.com/gotk3/gotk3/glib"
14)
15
16// AccelFlags is a representation of GTK's GtkAccelFlags
17type AccelFlags int
18
19const (
20	ACCEL_VISIBLE AccelFlags = C.GTK_ACCEL_VISIBLE
21	ACCEL_LOCKED  AccelFlags = C.GTK_ACCEL_LOCKED
22	ACCEL_MASK    AccelFlags = C.GTK_ACCEL_MASK
23)
24
25func marshalAccelFlags(p uintptr) (interface{}, error) {
26	c := C.g_value_get_enum((*C.GValue)(unsafe.Pointer(p)))
27	return AccelFlags(c), nil
28}
29
30// AcceleratorName is a wrapper around gtk_accelerator_name().
31func AcceleratorName(key uint, mods gdk.ModifierType) string {
32	c := C.gtk_accelerator_name(C.guint(key), C.GdkModifierType(mods))
33	defer C.free(unsafe.Pointer(c))
34	return C.GoString((*C.char)(c))
35}
36
37// AcceleratorValid is a wrapper around gtk_accelerator_valid().
38func AcceleratorValid(key uint, mods gdk.ModifierType) bool {
39	return gobool(C.gtk_accelerator_valid(C.guint(key), C.GdkModifierType(mods)))
40}
41
42// AcceleratorGetDefaultModMask is a wrapper around gtk_accelerator_get_default_mod_mask().
43func AcceleratorGetDefaultModMask() gdk.ModifierType {
44	return gdk.ModifierType(C.gtk_accelerator_get_default_mod_mask())
45}
46
47// AcceleratorParse is a wrapper around gtk_accelerator_parse().
48func AcceleratorParse(acc string) (key uint, mods gdk.ModifierType) {
49	cstr := C.CString(acc)
50	defer C.free(unsafe.Pointer(cstr))
51
52	k := C.guint(0)
53	m := C.GdkModifierType(0)
54
55	C.gtk_accelerator_parse((*C.gchar)(cstr), &k, &m)
56	return uint(k), gdk.ModifierType(m)
57}
58
59// AcceleratorGetLabel is a wrapper around gtk_accelerator_get_label().
60func AcceleratorGetLabel(key uint, mods gdk.ModifierType) string {
61	c := C.gtk_accelerator_get_label(C.guint(key), C.GdkModifierType(mods))
62	defer C.free(unsafe.Pointer(c))
63	return C.GoString((*C.char)(c))
64}
65
66// AcceleratorSetDefaultModMask is a wrapper around gtk_accelerator_set_default_mod_mask().
67func AcceleratorSetDefaultModMask(mods gdk.ModifierType) {
68	C.gtk_accelerator_set_default_mod_mask(C.GdkModifierType(mods))
69}
70
71/*
72 * GtkAccelLabel
73 */
74
75// TODO:
76// gtk_accel_label_new().
77// gtk_accel_label_set_accel_closure().
78// gtk_accel_label_get_accel_widget().
79// gtk_accel_label_set_accel_widget().
80// gtk_accel_label_get_accel_width().
81// gtk_accel_label_set_accel(). since GTK 3.6
82// gtk_accel_label_get_accel(). since GTK 3.12
83// gtk_accel_label_refetch().
84
85/*
86 * GtkAccelGroup
87 */
88
89// AccelGroup is a representation of GTK's GtkAccelGroup.
90type AccelGroup struct {
91	*glib.Object
92}
93
94// native returns a pointer to the underlying GtkAccelGroup.
95func (v *AccelGroup) native() *C.GtkAccelGroup {
96	if v == nil || v.GObject == nil {
97		return nil
98	}
99	p := unsafe.Pointer(v.GObject)
100	return C.toGtkAccelGroup(p)
101}
102
103func marshalAccelGroup(p uintptr) (interface{}, error) {
104	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
105	obj := glib.Take(unsafe.Pointer(c))
106	return wrapAccelGroup(obj), nil
107}
108
109func wrapAccelGroup(obj *glib.Object) *AccelGroup {
110	if obj == nil {
111		return nil
112	}
113
114	return &AccelGroup{obj}
115}
116
117// AccelGroup is a wrapper around gtk_accel_group_new().
118func AccelGroupNew() (*AccelGroup, error) {
119	c := C.gtk_accel_group_new()
120	if c == nil {
121		return nil, nilPtrErr
122	}
123	obj := glib.Take(unsafe.Pointer(c))
124	return wrapAccelGroup(obj), nil
125}
126
127// Connect is a wrapper around gtk_accel_group_connect().
128func (v *AccelGroup) Connect(key uint, mods gdk.ModifierType, flags AccelFlags, f interface{}) {
129	closure, _ := glib.ClosureNew(f)
130	cl := (*C.struct__GClosure)(unsafe.Pointer(closure))
131	C.gtk_accel_group_connect(
132		v.native(),
133		C.guint(key),
134		C.GdkModifierType(mods),
135		C.GtkAccelFlags(flags),
136		cl)
137}
138
139// ConnectByPath is a wrapper around gtk_accel_group_connect_by_path().
140func (v *AccelGroup) ConnectByPath(path string, f interface{}) {
141	closure, _ := glib.ClosureNew(f)
142	cl := (*C.struct__GClosure)(unsafe.Pointer(closure))
143
144	cstr := C.CString(path)
145	defer C.free(unsafe.Pointer(cstr))
146
147	C.gtk_accel_group_connect_by_path(
148		v.native(),
149		(*C.gchar)(cstr),
150		cl)
151}
152
153// Disconnect is a wrapper around gtk_accel_group_disconnect().
154func (v *AccelGroup) Disconnect(f interface{}) {
155	closure, _ := glib.ClosureNew(f)
156	cl := (*C.struct__GClosure)(unsafe.Pointer(closure))
157	C.gtk_accel_group_disconnect(v.native(), cl)
158}
159
160// DisconnectKey is a wrapper around gtk_accel_group_disconnect_key().
161func (v *AccelGroup) DisconnectKey(key uint, mods gdk.ModifierType) {
162	C.gtk_accel_group_disconnect_key(v.native(), C.guint(key), C.GdkModifierType(mods))
163}
164
165// Lock is a wrapper around gtk_accel_group_lock().
166func (v *AccelGroup) Lock() {
167	C.gtk_accel_group_lock(v.native())
168}
169
170// Unlock is a wrapper around gtk_accel_group_unlock().
171func (v *AccelGroup) Unlock() {
172	C.gtk_accel_group_unlock(v.native())
173}
174
175// IsLocked is a wrapper around gtk_accel_group_get_is_locked().
176func (v *AccelGroup) IsLocked() bool {
177	return gobool(C.gtk_accel_group_get_is_locked(v.native()))
178}
179
180// AccelGroupFromClosure is a wrapper around gtk_accel_group_from_accel_closure().
181func AccelGroupFromClosure(f interface{}) *AccelGroup {
182	closure, _ := glib.ClosureNew(f)
183	cl := (*C.struct__GClosure)(unsafe.Pointer(closure))
184	c := C.gtk_accel_group_from_accel_closure(cl)
185	if c == nil {
186		return nil
187	}
188	return wrapAccelGroup(glib.Take(unsafe.Pointer(c)))
189}
190
191// GetModifierMask is a wrapper around gtk_accel_group_get_modifier_mask().
192func (v *AccelGroup) GetModifierMask() gdk.ModifierType {
193	return gdk.ModifierType(C.gtk_accel_group_get_modifier_mask(v.native()))
194}
195
196// AccelGroupsActivate is a wrapper around gtk_accel_groups_activate().
197func AccelGroupsActivate(obj *glib.Object, key uint, mods gdk.ModifierType) bool {
198	return gobool(C.gtk_accel_groups_activate((*C.GObject)(unsafe.Pointer(obj.Native())), C.guint(key), C.GdkModifierType(mods)))
199}
200
201// Activate is a wrapper around gtk_accel_group_activate().
202func (v *AccelGroup) Activate(quark glib.Quark, acceleratable *glib.Object, key uint, mods gdk.ModifierType) bool {
203	return gobool(C.gtk_accel_group_activate(v.native(), C.GQuark(quark), (*C.GObject)(unsafe.Pointer(acceleratable.Native())), C.guint(key), C.GdkModifierType(mods)))
204}
205
206// AccelGroupsFromObject is a wrapper around gtk_accel_groups_from_object().
207func AccelGroupsFromObject(obj *glib.Object) *glib.SList {
208	res := C.gtk_accel_groups_from_object((*C.GObject)(unsafe.Pointer(obj.Native())))
209	if res == nil {
210		return nil
211	}
212
213	// TODO: call DataWrapper on SList and wrap them to gtk.AccelGroup
214
215	return (*glib.SList)(unsafe.Pointer(res))
216}
217
218/*
219 * GtkAccelMap
220 */
221
222// AccelMap is a representation of GTK's GtkAccelMap.
223type AccelMap struct {
224	*glib.Object
225}
226
227// native returns a pointer to the underlying GtkAccelMap.
228func (v *AccelMap) native() *C.GtkAccelMap {
229	if v == nil || v.GObject == nil {
230		return nil
231	}
232	p := unsafe.Pointer(v.GObject)
233	return C.toGtkAccelMap(p)
234}
235
236func marshalAccelMap(p uintptr) (interface{}, error) {
237	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
238	obj := glib.Take(unsafe.Pointer(c))
239	return wrapAccelMap(obj), nil
240}
241
242func wrapAccelMap(obj *glib.Object) *AccelMap {
243	if obj == nil {
244		return nil
245	}
246
247	return &AccelMap{obj}
248}
249
250// AccelMapAddEntry is a wrapper around gtk_accel_map_add_entry().
251func AccelMapAddEntry(path string, key uint, mods gdk.ModifierType) {
252	cstr := C.CString(path)
253	defer C.free(unsafe.Pointer(cstr))
254
255	C.gtk_accel_map_add_entry((*C.gchar)(cstr), C.guint(key), C.GdkModifierType(mods))
256}
257
258type AccelKey C.GtkAccelKey
259
260func (v *AccelKey) native() *C.GtkAccelKey {
261	if v == nil {
262		return nil
263	}
264	return (*C.GtkAccelKey)(v)
265}
266
267// AccelMapLookupEntry is a wrapper around gtk_accel_map_lookup_entry().
268func AccelMapLookupEntry(path string) *AccelKey {
269	cstr := C.CString(path)
270	defer C.free(unsafe.Pointer(cstr))
271
272	var v = new(AccelKey)
273
274	C.gtk_accel_map_lookup_entry((*C.gchar)(cstr), v.native())
275	return v
276}
277
278// AccelMapChangeEntry is a wrapper around gtk_accel_map_change_entry().
279func AccelMapChangeEntry(path string, key uint, mods gdk.ModifierType, replace bool) bool {
280	cstr := C.CString(path)
281	defer C.free(unsafe.Pointer(cstr))
282
283	return gobool(C.gtk_accel_map_change_entry((*C.gchar)(cstr), C.guint(key), C.GdkModifierType(mods), gbool(replace)))
284}
285
286// AccelMapLoad is a wrapper around gtk_accel_map_load().
287func AccelMapLoad(fileName string) {
288	cstr := C.CString(fileName)
289	defer C.free(unsafe.Pointer(cstr))
290
291	C.gtk_accel_map_load((*C.gchar)(cstr))
292}
293
294// AccelMapSave is a wrapper around gtk_accel_map_save().
295func AccelMapSave(fileName string) {
296	cstr := C.CString(fileName)
297	defer C.free(unsafe.Pointer(cstr))
298
299	C.gtk_accel_map_save((*C.gchar)(cstr))
300}
301
302// AccelMapLoadFD is a wrapper around gtk_accel_map_load_fd().
303func AccelMapLoadFD(fd int) {
304	C.gtk_accel_map_load_fd(C.gint(fd))
305}
306
307// AccelMapSaveFD is a wrapper around gtk_accel_map_save_fd().
308func AccelMapSaveFD(fd int) {
309	C.gtk_accel_map_save_fd(C.gint(fd))
310}
311
312// AccelMapAddFilter is a wrapper around gtk_accel_map_add_filter().
313func AccelMapAddFilter(filter string) {
314	cstr := C.CString(filter)
315	defer C.free(unsafe.Pointer(cstr))
316
317	C.gtk_accel_map_add_filter((*C.gchar)(cstr))
318}
319
320// AccelMapGet is a wrapper around gtk_accel_map_get().
321func AccelMapGet() *AccelMap {
322	c := C.gtk_accel_map_get()
323	if c == nil {
324		return nil
325	}
326	return wrapAccelMap(glib.Take(unsafe.Pointer(c)))
327}
328
329// AccelMapLockPath is a wrapper around gtk_accel_map_lock_path().
330func AccelMapLockPath(path string) {
331	cstr := C.CString(path)
332	defer C.free(unsafe.Pointer(cstr))
333
334	C.gtk_accel_map_lock_path((*C.gchar)(cstr))
335}
336
337// AccelMapUnlockPath is a wrapper around gtk_accel_map_unlock_path().
338func AccelMapUnlockPath(path string) {
339	cstr := C.CString(path)
340	defer C.free(unsafe.Pointer(cstr))
341
342	C.gtk_accel_map_unlock_path((*C.gchar)(cstr))
343}
344
345// SetAccelGroup is a wrapper around gtk_menu_set_accel_group().
346func (v *Menu) SetAccelGroup(accelGroup *AccelGroup) {
347	C.gtk_menu_set_accel_group(v.native(), accelGroup.native())
348}
349
350// GetAccelGroup is a wrapper around gtk_menu_get_accel_group().
351func (v *Menu) GetAccelGroup() *AccelGroup {
352	c := C.gtk_menu_get_accel_group(v.native())
353	if c == nil {
354		return nil
355	}
356	return wrapAccelGroup(glib.Take(unsafe.Pointer(c)))
357}
358
359// SetAccelPath is a wrapper around gtk_menu_set_accel_path().
360func (v *Menu) SetAccelPath(path string) {
361	cstr := C.CString(path)
362	defer C.free(unsafe.Pointer(cstr))
363
364	C.gtk_menu_set_accel_path(v.native(), (*C.gchar)(cstr))
365}
366
367// GetAccelPath is a wrapper around gtk_menu_get_accel_path().
368func (v *Menu) GetAccelPath() string {
369	c := C.gtk_menu_get_accel_path(v.native())
370	return C.GoString((*C.char)(c))
371}
372
373// SetAccelPath is a wrapper around gtk_menu_item_set_accel_path().
374func (v *MenuItem) SetAccelPath(path string) {
375	cstr := C.CString(path)
376	defer C.free(unsafe.Pointer(cstr))
377
378	C.gtk_menu_item_set_accel_path(v.native(), (*C.gchar)(cstr))
379}
380
381// GetAccelPath is a wrapper around gtk_menu_item_get_accel_path().
382func (v *MenuItem) GetAccelPath() string {
383	c := C.gtk_menu_item_get_accel_path(v.native())
384	return C.GoString((*C.char)(c))
385}
386
387// AddAccelerator is a wrapper around gtk_widget_add_accelerator().
388func (v *Widget) AddAccelerator(signal string, group *AccelGroup, key uint, mods gdk.ModifierType, flags AccelFlags) {
389	csignal := (*C.gchar)(C.CString(signal))
390	defer C.free(unsafe.Pointer(csignal))
391
392	C.gtk_widget_add_accelerator(v.native(),
393		csignal,
394		group.native(),
395		C.guint(key),
396		C.GdkModifierType(mods),
397		C.GtkAccelFlags(flags))
398}
399
400// RemoveAccelerator is a wrapper around gtk_widget_remove_accelerator().
401func (v *Widget) RemoveAccelerator(group *AccelGroup, key uint, mods gdk.ModifierType) bool {
402	return gobool(C.gtk_widget_remove_accelerator(v.native(),
403		group.native(),
404		C.guint(key),
405		C.GdkModifierType(mods)))
406}
407
408// SetAccelPath is a wrapper around gtk_widget_set_accel_path().
409func (v *Widget) SetAccelPath(path string, group *AccelGroup) {
410	cstr := (*C.gchar)(C.CString(path))
411	defer C.free(unsafe.Pointer(cstr))
412
413	C.gtk_widget_set_accel_path(v.native(), cstr, group.native())
414}
415
416// CanActivateAccel is a wrapper around gtk_widget_can_activate_accel().
417func (v *Widget) CanActivateAccel(signalId uint) bool {
418	return gobool(C.gtk_widget_can_activate_accel(v.native(), C.guint(signalId)))
419}
420
421// AddAccelGroup() is a wrapper around gtk_window_add_accel_group().
422func (v *Window) AddAccelGroup(accelGroup *AccelGroup) {
423	C.gtk_window_add_accel_group(v.native(), accelGroup.native())
424}
425
426// RemoveAccelGroup() is a wrapper around gtk_window_remove_accel_group().
427func (v *Window) RemoveAccelGroup(accelGroup *AccelGroup) {
428	C.gtk_window_remove_accel_group(v.native(), accelGroup.native())
429}
430
431// These three functions are for system level access - thus not as high priority to implement
432// TODO: void 	gtk_accelerator_parse_with_keycode ()
433// TODO: gchar * 	gtk_accelerator_name_with_keycode ()
434// TODO: gchar * 	gtk_accelerator_get_label_with_keycode ()
435
436// TODO: GtkAccelKey * 	gtk_accel_group_find ()   - this function uses a function type - I don't know how to represent it in cgo
437// TODO: gtk_accel_map_foreach_unfiltered  - can't be done without a function type
438// TODO: gtk_accel_map_foreach  - can't be done without a function type
439
440// TODO: gtk_accel_map_load_scanner
441
442/*
443 * GtkWidget
444 */
445
446// TODO:
447// gtk_widget_list_accel_closures
448