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	"errors"
11	"unsafe"
12
13	"github.com/gotk3/gotk3/gdk"
14	"github.com/gotk3/gotk3/glib"
15)
16
17/*
18 * GtkWidget
19 */
20
21// Widget is a representation of GTK's GtkWidget.
22type Widget struct {
23	glib.InitiallyUnowned
24}
25
26// IWidget is an interface type implemented by all structs
27// embedding a Widget.  It is meant to be used as an argument type
28// for wrapper functions that wrap around a C GTK function taking a
29// GtkWidget.
30type IWidget interface {
31	toWidget() *C.GtkWidget
32	Set(string, interface{}) error
33}
34
35type IWidgetable interface {
36	toWidget() *C.GtkWidget
37}
38
39func nullableWidget(v IWidgetable) *C.GtkWidget {
40	if v == nil {
41		return nil
42	}
43
44	return v.toWidget()
45}
46
47// native returns a pointer to the underlying GtkWidget.
48func (v *Widget) native() *C.GtkWidget {
49	if v == nil || v.GObject == nil {
50		return nil
51	}
52	p := unsafe.Pointer(v.GObject)
53	return C.toGtkWidget(p)
54}
55
56func (v *Widget) toWidget() *C.GtkWidget {
57	if v == nil {
58		return nil
59	}
60	return v.native()
61}
62
63func marshalWidget(p uintptr) (interface{}, error) {
64	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
65	obj := glib.Take(unsafe.Pointer(c))
66	return wrapWidget(obj), nil
67}
68
69func wrapWidget(obj *glib.Object) *Widget {
70	return &Widget{glib.InitiallyUnowned{obj}}
71}
72
73// Destroy is a wrapper around gtk_widget_destroy().
74func (v *Widget) Destroy() {
75	C.gtk_widget_destroy(v.native())
76}
77
78func (v *Widget) HideOnDelete() {
79	C._gtk_widget_hide_on_delete(v.native())
80}
81
82func (v *Widget) DragDestSet(flags DestDefaults, targets []TargetEntry, actions gdk.DragAction) {
83	C.gtk_drag_dest_set(v.native(), C.GtkDestDefaults(flags), (*C.GtkTargetEntry)(&targets[0]), C.gint(len(targets)), C.GdkDragAction(actions))
84}
85
86// ResetStyle is a wrapper around gtk_widget_reset_style().
87func (v *Widget) ResetStyle() {
88	C.gtk_widget_reset_style(v.native())
89}
90
91// InDestruction is a wrapper around gtk_widget_in_destruction().
92func (v *Widget) InDestruction() bool {
93	return gobool(C.gtk_widget_in_destruction(v.native()))
94}
95
96// TODO(jrick) this may require some rethinking
97/*
98func (v *Widget) Destroyed(widgetPointer **Widget) {
99}
100*/
101
102// Unparent is a wrapper around gtk_widget_unparent().
103func (v *Widget) Unparent() {
104	C.gtk_widget_unparent(v.native())
105}
106
107// Show is a wrapper around gtk_widget_show().
108func (v *Widget) Show() {
109	C.gtk_widget_show(v.native())
110}
111
112// Hide is a wrapper around gtk_widget_hide().
113func (v *Widget) Hide() {
114	C.gtk_widget_hide(v.native())
115}
116
117// GetCanFocus is a wrapper around gtk_widget_get_can_focus().
118func (v *Widget) GetCanFocus() bool {
119	c := C.gtk_widget_get_can_focus(v.native())
120	return gobool(c)
121}
122
123// SetCanFocus is a wrapper around gtk_widget_set_can_focus().
124func (v *Widget) SetCanFocus(canFocus bool) {
125	C.gtk_widget_set_can_focus(v.native(), gbool(canFocus))
126}
127
128// GetCanDefault is a wrapper around gtk_widget_get_can_default().
129func (v *Widget) GetCanDefault() bool {
130	c := C.gtk_widget_get_can_default(v.native())
131	return gobool(c)
132}
133
134// SetCanDefault is a wrapper around gtk_widget_set_can_default().
135func (v *Widget) SetCanDefault(canDefault bool) {
136	C.gtk_widget_set_can_default(v.native(), gbool(canDefault))
137}
138
139// GetMapped is a wrapper around gtk_widget_get_mapped().
140func (v *Widget) GetMapped() bool {
141	c := C.gtk_widget_get_mapped(v.native())
142	return gobool(c)
143}
144
145// SetMapped is a wrapper around gtk_widget_set_mapped().
146func (v *Widget) SetMapped(mapped bool) {
147	C.gtk_widget_set_can_focus(v.native(), gbool(mapped))
148}
149
150// GetRealized is a wrapper around gtk_widget_get_realized().
151func (v *Widget) GetRealized() bool {
152	c := C.gtk_widget_get_realized(v.native())
153	return gobool(c)
154}
155
156// SetRealized is a wrapper around gtk_widget_set_realized().
157func (v *Widget) SetRealized(realized bool) {
158	C.gtk_widget_set_realized(v.native(), gbool(realized))
159}
160
161// GetHasWindow is a wrapper around gtk_widget_get_has_window().
162func (v *Widget) GetHasWindow() bool {
163	c := C.gtk_widget_get_has_window(v.native())
164	return gobool(c)
165}
166
167// SetHasWindow is a wrapper around gtk_widget_set_has_window().
168func (v *Widget) SetHasWindow(hasWindow bool) {
169	C.gtk_widget_set_has_window(v.native(), gbool(hasWindow))
170}
171
172// ShowNow is a wrapper around gtk_widget_show_now().
173func (v *Widget) ShowNow() {
174	C.gtk_widget_show_now(v.native())
175}
176
177// ShowAll is a wrapper around gtk_widget_show_all().
178func (v *Widget) ShowAll() {
179	C.gtk_widget_show_all(v.native())
180}
181
182// SetNoShowAll is a wrapper around gtk_widget_set_no_show_all().
183func (v *Widget) SetNoShowAll(noShowAll bool) {
184	C.gtk_widget_set_no_show_all(v.native(), gbool(noShowAll))
185}
186
187// GetNoShowAll is a wrapper around gtk_widget_get_no_show_all().
188func (v *Widget) GetNoShowAll() bool {
189	c := C.gtk_widget_get_no_show_all(v.native())
190	return gobool(c)
191}
192
193// Map is a wrapper around gtk_widget_map().
194func (v *Widget) Map() {
195	C.gtk_widget_map(v.native())
196}
197
198// Unmap is a wrapper around gtk_widget_unmap().
199func (v *Widget) Unmap() {
200	C.gtk_widget_unmap(v.native())
201}
202
203// QueueDrawArea is a wrapper aroung gtk_widget_queue_draw_area().
204func (v *Widget) QueueDrawArea(x, y, w, h int) {
205	C.gtk_widget_queue_draw_area(v.native(), C.gint(x), C.gint(y), C.gint(w), C.gint(h))
206}
207
208//void gtk_widget_realize(GtkWidget *widget);
209//void gtk_widget_unrealize(GtkWidget *widget);
210//void gtk_widget_draw(GtkWidget *widget, cairo_t *cr);
211//void gtk_widget_queue_resize(GtkWidget *widget);
212//void gtk_widget_queue_resize_no_redraw(GtkWidget *widget);
213//GdkFrameClock *gtk_widget_get_frame_clock(GtkWidget *widget);
214//guint gtk_widget_add_tick_callback (GtkWidget *widget,
215//                                    GtkTickCallback callback,
216//                                    gpointer user_data,
217//                                    GDestroyNotify notify);
218//void gtk_widget_remove_tick_callback(GtkWidget *widget, guint id);
219
220// TODO(jrick) GtkAllocation
221/*
222func (v *Widget) SizeAllocate() {
223}
224*/
225
226// Allocation is a representation of GTK's GtkAllocation type.
227type Allocation struct {
228	gdk.Rectangle
229}
230
231// Native returns a pointer to the underlying GtkAllocation.
232func (v *Allocation) native() *C.GtkAllocation {
233	return (*C.GtkAllocation)(unsafe.Pointer(&v.GdkRectangle))
234}
235
236// GetAllocatedWidth() is a wrapper around gtk_widget_get_allocated_width().
237func (v *Widget) GetAllocatedWidth() int {
238	return int(C.gtk_widget_get_allocated_width(v.native()))
239}
240
241// GetAllocatedHeight() is a wrapper around gtk_widget_get_allocated_height().
242func (v *Widget) GetAllocatedHeight() int {
243	return int(C.gtk_widget_get_allocated_height(v.native()))
244}
245
246// Event() is a wrapper around gtk_widget_event().
247func (v *Widget) Event(event *gdk.Event) bool {
248	c := C.gtk_widget_event(v.native(),
249		(*C.GdkEvent)(unsafe.Pointer(event.Native())))
250	return gobool(c)
251}
252
253// Activate() is a wrapper around gtk_widget_activate().
254func (v *Widget) Activate() bool {
255	return gobool(C.gtk_widget_activate(v.native()))
256}
257
258// TODO(jrick) GdkRectangle
259/*
260func (v *Widget) Intersect() {
261}
262*/
263
264// IsFocus() is a wrapper around gtk_widget_is_focus().
265func (v *Widget) IsFocus() bool {
266	return gobool(C.gtk_widget_is_focus(v.native()))
267}
268
269// GrabFocus() is a wrapper around gtk_widget_grab_focus().
270func (v *Widget) GrabFocus() {
271	C.gtk_widget_grab_focus(v.native())
272}
273
274// GrabDefault() is a wrapper around gtk_widget_grab_default().
275func (v *Widget) GrabDefault() {
276	C.gtk_widget_grab_default(v.native())
277}
278
279// SetName() is a wrapper around gtk_widget_set_name().
280func (v *Widget) SetName(name string) {
281	cstr := C.CString(name)
282	defer C.free(unsafe.Pointer(cstr))
283	C.gtk_widget_set_name(v.native(), (*C.gchar)(cstr))
284}
285
286// GetName() is a wrapper around gtk_widget_get_name().  A non-nil
287// error is returned in the case that gtk_widget_get_name returns NULL to
288// differentiate between NULL and an empty string.
289func (v *Widget) GetName() (string, error) {
290	c := C.gtk_widget_get_name(v.native())
291	if c == nil {
292		return "", nilPtrErr
293	}
294	return C.GoString((*C.char)(c)), nil
295}
296
297// GetSensitive is a wrapper around gtk_widget_get_sensitive().
298func (v *Widget) GetSensitive() bool {
299	c := C.gtk_widget_get_sensitive(v.native())
300	return gobool(c)
301}
302
303// IsSensitive is a wrapper around gtk_widget_is_sensitive().
304func (v *Widget) IsSensitive() bool {
305	c := C.gtk_widget_is_sensitive(v.native())
306	return gobool(c)
307}
308
309// SetSensitive is a wrapper around gtk_widget_set_sensitive().
310func (v *Widget) SetSensitive(sensitive bool) {
311	C.gtk_widget_set_sensitive(v.native(), gbool(sensitive))
312}
313
314// GetVisible is a wrapper around gtk_widget_get_visible().
315func (v *Widget) GetVisible() bool {
316	c := C.gtk_widget_get_visible(v.native())
317	return gobool(c)
318}
319
320// SetVisible is a wrapper around gtk_widget_set_visible().
321func (v *Widget) SetVisible(visible bool) {
322	C.gtk_widget_set_visible(v.native(), gbool(visible))
323}
324
325// SetParent is a wrapper around gtk_widget_set_parent().
326func (v *Widget) SetParent(parent IWidget) {
327	C.gtk_widget_set_parent(v.native(), parent.toWidget())
328}
329
330// GetParent is a wrapper around gtk_widget_get_parent().
331func (v *Widget) GetParent() (*Widget, error) {
332	c := C.gtk_widget_get_parent(v.native())
333	if c == nil {
334		return nil, nilPtrErr
335	}
336	return wrapWidget(glib.Take(unsafe.Pointer(c))), nil
337}
338
339// SetSizeRequest is a wrapper around gtk_widget_set_size_request().
340func (v *Widget) SetSizeRequest(width, height int) {
341	C.gtk_widget_set_size_request(v.native(), C.gint(width), C.gint(height))
342}
343
344// GetSizeRequest is a wrapper around gtk_widget_get_size_request().
345func (v *Widget) GetSizeRequest() (width, height int) {
346	var w, h C.gint
347	C.gtk_widget_get_size_request(v.native(), &w, &h)
348	return int(w), int(h)
349}
350
351// SetParentWindow is a wrapper around gtk_widget_set_parent_window().
352func (v *Widget) SetParentWindow(parentWindow *gdk.Window) {
353	C.gtk_widget_set_parent_window(v.native(),
354		(*C.GdkWindow)(unsafe.Pointer(parentWindow.Native())))
355}
356
357// GetParentWindow is a wrapper around gtk_widget_get_parent_window().
358func (v *Widget) GetParentWindow() (*gdk.Window, error) {
359	c := C.gtk_widget_get_parent_window(v.native())
360	if v == nil {
361		return nil, nilPtrErr
362	}
363
364	w := &gdk.Window{glib.Take(unsafe.Pointer(c))}
365	return w, nil
366}
367
368// SetEvents is a wrapper around gtk_widget_set_events().
369func (v *Widget) SetEvents(events int) {
370	C.gtk_widget_set_events(v.native(), C.gint(events))
371}
372
373// GetEvents is a wrapper around gtk_widget_get_events().
374func (v *Widget) GetEvents() int {
375	return int(C.gtk_widget_get_events(v.native()))
376}
377
378// AddEvents is a wrapper around gtk_widget_add_events().
379func (v *Widget) AddEvents(events int) {
380	C.gtk_widget_add_events(v.native(), C.gint(events))
381}
382
383// FreezeChildNotify is a wrapper around gtk_widget_freeze_child_notify().
384func (v *Widget) FreezeChildNotify() {
385	C.gtk_widget_freeze_child_notify(v.native())
386}
387
388// ThawChildNotify is a wrapper around gtk_widget_thaw_child_notify().
389func (v *Widget) ThawChildNotify() {
390	C.gtk_widget_thaw_child_notify(v.native())
391}
392
393// HasDefault is a wrapper around gtk_widget_has_default().
394func (v *Widget) HasDefault() bool {
395	c := C.gtk_widget_has_default(v.native())
396	return gobool(c)
397}
398
399// HasFocus is a wrapper around gtk_widget_has_focus().
400func (v *Widget) HasFocus() bool {
401	c := C.gtk_widget_has_focus(v.native())
402	return gobool(c)
403}
404
405// HasVisibleFocus is a wrapper around gtk_widget_has_visible_focus().
406func (v *Widget) HasVisibleFocus() bool {
407	c := C.gtk_widget_has_visible_focus(v.native())
408	return gobool(c)
409}
410
411// HasGrab is a wrapper around gtk_widget_has_grab().
412func (v *Widget) HasGrab() bool {
413	c := C.gtk_widget_has_grab(v.native())
414	return gobool(c)
415}
416
417// IsDrawable is a wrapper around gtk_widget_is_drawable().
418func (v *Widget) IsDrawable() bool {
419	c := C.gtk_widget_is_drawable(v.native())
420	return gobool(c)
421}
422
423// IsToplevel is a wrapper around gtk_widget_is_toplevel().
424func (v *Widget) IsToplevel() bool {
425	c := C.gtk_widget_is_toplevel(v.native())
426	return gobool(c)
427}
428
429// TODO(jrick) GdkEventMask
430/*
431func (v *Widget) SetDeviceEvents() {
432}
433*/
434
435// TODO(jrick) GdkEventMask
436/*
437func (v *Widget) GetDeviceEvents() {
438}
439*/
440
441// TODO(jrick) GdkEventMask
442/*
443func (v *Widget) AddDeviceEvents() {
444}
445*/
446
447// SetDeviceEnabled is a wrapper around gtk_widget_set_device_enabled().
448func (v *Widget) SetDeviceEnabled(device *gdk.Device, enabled bool) {
449	C.gtk_widget_set_device_enabled(v.native(),
450		(*C.GdkDevice)(unsafe.Pointer(device.Native())), gbool(enabled))
451}
452
453// GetDeviceEnabled is a wrapper around gtk_widget_get_device_enabled().
454func (v *Widget) GetDeviceEnabled(device *gdk.Device) bool {
455	c := C.gtk_widget_get_device_enabled(v.native(),
456		(*C.GdkDevice)(unsafe.Pointer(device.Native())))
457	return gobool(c)
458}
459
460// GetToplevel is a wrapper around gtk_widget_get_toplevel().
461func (v *Widget) GetToplevel() (*Widget, error) {
462	c := C.gtk_widget_get_toplevel(v.native())
463	if c == nil {
464		return nil, nilPtrErr
465	}
466	return wrapWidget(glib.Take(unsafe.Pointer(c))), nil
467}
468
469// GetTooltipText is a wrapper around gtk_widget_get_tooltip_text().
470// A non-nil error is returned in the case that
471// gtk_widget_get_tooltip_text returns NULL to differentiate between NULL
472// and an empty string.
473func (v *Widget) GetTooltipText() (string, error) {
474	c := C.gtk_widget_get_tooltip_text(v.native())
475	if c == nil {
476		return "", nilPtrErr
477	}
478	return C.GoString((*C.char)(c)), nil
479}
480
481// SetTooltipText is a wrapper around gtk_widget_set_tooltip_text().
482func (v *Widget) SetTooltipText(text string) {
483	cstr := C.CString(text)
484	defer C.free(unsafe.Pointer(cstr))
485	C.gtk_widget_set_tooltip_text(v.native(), (*C.gchar)(cstr))
486}
487
488// GetHAlign is a wrapper around gtk_widget_get_halign().
489func (v *Widget) GetHAlign() Align {
490	c := C.gtk_widget_get_halign(v.native())
491	return Align(c)
492}
493
494// SetHAlign is a wrapper around gtk_widget_set_halign().
495func (v *Widget) SetHAlign(align Align) {
496	C.gtk_widget_set_halign(v.native(), C.GtkAlign(align))
497}
498
499// GetVAlign is a wrapper around gtk_widget_get_valign().
500func (v *Widget) GetVAlign() Align {
501	c := C.gtk_widget_get_valign(v.native())
502	return Align(c)
503}
504
505// SetVAlign is a wrapper around gtk_widget_set_valign().
506func (v *Widget) SetVAlign(align Align) {
507	C.gtk_widget_set_valign(v.native(), C.GtkAlign(align))
508}
509
510// GetMarginTop is a wrapper around gtk_widget_get_margin_top().
511func (v *Widget) GetMarginTop() int {
512	c := C.gtk_widget_get_margin_top(v.native())
513	return int(c)
514}
515
516// SetMarginTop is a wrapper around gtk_widget_set_margin_top().
517func (v *Widget) SetMarginTop(margin int) {
518	C.gtk_widget_set_margin_top(v.native(), C.gint(margin))
519}
520
521// GetMarginBottom is a wrapper around gtk_widget_get_margin_bottom().
522func (v *Widget) GetMarginBottom() int {
523	c := C.gtk_widget_get_margin_bottom(v.native())
524	return int(c)
525}
526
527// SetMarginBottom is a wrapper around gtk_widget_set_margin_bottom().
528func (v *Widget) SetMarginBottom(margin int) {
529	C.gtk_widget_set_margin_bottom(v.native(), C.gint(margin))
530}
531
532// GetHExpand is a wrapper around gtk_widget_get_hexpand().
533func (v *Widget) GetHExpand() bool {
534	c := C.gtk_widget_get_hexpand(v.native())
535	return gobool(c)
536}
537
538// SetHExpand is a wrapper around gtk_widget_set_hexpand().
539func (v *Widget) SetHExpand(expand bool) {
540	C.gtk_widget_set_hexpand(v.native(), gbool(expand))
541}
542
543// GetVExpand is a wrapper around gtk_widget_get_vexpand().
544func (v *Widget) GetVExpand() bool {
545	c := C.gtk_widget_get_vexpand(v.native())
546	return gobool(c)
547}
548
549// SetVExpand is a wrapper around gtk_widget_set_vexpand().
550func (v *Widget) SetVExpand(expand bool) {
551	C.gtk_widget_set_vexpand(v.native(), gbool(expand))
552}
553
554// TranslateCoordinates is a wrapper around gtk_widget_translate_coordinates().
555func (v *Widget) TranslateCoordinates(dest IWidget, srcX, srcY int) (destX, destY int, e error) {
556	cdest := nullableWidget(dest)
557
558	var cdestX, cdestY C.gint
559	c := C.gtk_widget_translate_coordinates(v.native(), cdest, C.gint(srcX), C.gint(srcY), &cdestX, &cdestY)
560	if !gobool(c) {
561		return 0, 0, errors.New("translate coordinates failed")
562	}
563	return int(cdestX), int(cdestY), nil
564}
565
566// SetVisual is a wrapper around gtk_widget_set_visual().
567func (v *Widget) SetVisual(visual *gdk.Visual) {
568	C.gtk_widget_set_visual(v.native(),
569		(*C.GdkVisual)(unsafe.Pointer(visual.Native())))
570}
571
572// SetAppPaintable is a wrapper around gtk_widget_set_app_paintable().
573func (v *Widget) SetAppPaintable(paintable bool) {
574	C.gtk_widget_set_app_paintable(v.native(), gbool(paintable))
575}
576
577// GetAppPaintable is a wrapper around gtk_widget_get_app_paintable().
578func (v *Widget) GetAppPaintable() bool {
579	c := C.gtk_widget_get_app_paintable(v.native())
580	return gobool(c)
581}
582
583// QueueDraw is a wrapper around gtk_widget_queue_draw().
584func (v *Widget) QueueDraw() {
585	C.gtk_widget_queue_draw(v.native())
586}
587
588// GetAllocation is a wrapper around gtk_widget_get_allocation().
589func (v *Widget) GetAllocation() *Allocation {
590	var a Allocation
591	C.gtk_widget_get_allocation(v.native(), a.native())
592	return &a
593}
594
595// SetAllocation is a wrapper around gtk_widget_set_allocation().
596func (v *Widget) SetAllocation(allocation *Allocation) {
597	C.gtk_widget_set_allocation(v.native(), allocation.native())
598}
599
600// SizeAllocate is a wrapper around gtk_widget_size_allocate().
601func (v *Widget) SizeAllocate(allocation *Allocation) {
602	C.gtk_widget_size_allocate(v.native(), allocation.native())
603}
604
605// SetStateFlags is a wrapper around gtk_widget_set_state_flags().
606func (v *Widget) SetStateFlags(stateFlags StateFlags, clear bool) {
607	C.gtk_widget_set_state_flags(v.native(), C.GtkStateFlags(stateFlags), gbool(clear))
608}
609
610// GetWindow is a wrapper around gtk_widget_get_window().
611func (v *Widget) GetWindow() (*gdk.Window, error) {
612	c := C.gtk_widget_get_window(v.native())
613	if c == nil {
614		return nil, nilPtrErr
615	}
616
617	w := &gdk.Window{glib.Take(unsafe.Pointer(c))}
618	return w, nil
619}
620
621// GetPreferredHeight is a wrapper around gtk_widget_get_preferred_height().
622func (v *Widget) GetPreferredHeight() (int, int) {
623	var minimum, natural C.gint
624	C.gtk_widget_get_preferred_height(v.native(), &minimum, &natural)
625	return int(minimum), int(natural)
626}
627
628// GetPreferredWidth is a wrapper around gtk_widget_get_preferred_width().
629func (v *Widget) GetPreferredWidth() (int, int) {
630	var minimum, natural C.gint
631	C.gtk_widget_get_preferred_width(v.native(), &minimum, &natural)
632	return int(minimum), int(natural)
633}
634
635func (v *Widget) InsertActionGroup(name string, group glib.IActionGroup) {
636	C.gtk_widget_insert_action_group(v.native(), (*C.gchar)(C.CString(name)), C.toGActionGroup(unsafe.Pointer(group.Native())))
637}
638
639// GetScreen is a wrapper around gtk_widget_get_screen().
640func (v *Widget) GetScreen() (*gdk.Screen, error) {
641	c := C.gtk_widget_get_screen(v.native())
642	if c == nil {
643		return nil, nilPtrErr
644	}
645	s := &gdk.Screen{glib.Take(unsafe.Pointer(c))}
646	return s, nil
647}
648