v0.33.2 57f21d6

gtk_widgets.go RawHistoryFolder

1package layout
2
3import (
4	"sync"
5
6	"github.com/bnema/puregotk/v4/gdk"
7	"github.com/bnema/puregotk/v4/glib"
8	"github.com/bnema/puregotk/v4/gobject"
9	"github.com/bnema/puregotk/v4/graphene"
10	"github.com/bnema/puregotk/v4/gtk"
11	"github.com/bnema/puregotk/v4/pango"
12)
13
14// Ensure implementations satisfy interfaces at compile time.
15var (
16	_ Widget            = (*gtkWidget)(nil)
17	_ PanedWidget       = (*gtkPaned)(nil)
18	_ BoxWidget         = (*gtkBox)(nil)
19	_ OverlayWidget     = (*gtkOverlay)(nil)
20	_ LabelWidget       = (*gtkLabel)(nil)
21	_ ButtonWidget      = (*gtkButton)(nil)
22	_ ImageWidget       = (*gtkImage)(nil)
23	_ ProgressBarWidget = (*gtkProgressBar)(nil)
24	_ SpinnerWidget     = (*gtkSpinner)(nil)
25	_ WidgetFactory     = (*GtkWidgetFactory)(nil)
26)
27
28// gtkWidget wraps a gtk.Widget to implement the Widget interface.
29type gtkWidget struct {
30	inner *gtk.Widget
31}
32
33func (w *gtkWidget) Show()                         { w.inner.Show() }
34func (w *gtkWidget) Hide()                         { w.inner.Hide() }
35func (w *gtkWidget) SetVisible(visible bool)       { w.inner.SetVisible(visible) }
36func (w *gtkWidget) IsVisible() bool               { return w.inner.GetVisible() }
37func (w *gtkWidget) SetOpacity(opacity float64)    { w.inner.SetOpacity(opacity) }
38func (w *gtkWidget) GrabFocus() bool               { return w.inner.GrabFocus() }
39func (w *gtkWidget) HasFocus() bool                { return w.inner.HasFocus() }
40func (w *gtkWidget) SetCanFocus(canFocus bool)     { w.inner.SetCanFocus(canFocus) }
41func (w *gtkWidget) SetFocusable(focusable bool)   { w.inner.SetFocusable(focusable) }
42func (w *gtkWidget) SetFocusOnClick(focus bool)    { w.inner.SetFocusOnClick(focus) }
43func (w *gtkWidget) SetCanTarget(canTarget bool)   { w.inner.SetCanTarget(canTarget) }
44func (w *gtkWidget) SetHexpand(expand bool)        { w.inner.SetHexpand(expand) }
45func (w *gtkWidget) SetVexpand(expand bool)        { w.inner.SetVexpand(expand) }
46func (w *gtkWidget) GetHexpand() bool              { return w.inner.GetHexpand() }
47func (w *gtkWidget) GetVexpand() bool              { return w.inner.GetVexpand() }
48func (w *gtkWidget) SetHalign(align gtk.Align)     { w.inner.SetHalign(align) }
49func (w *gtkWidget) SetValign(align gtk.Align)     { w.inner.SetValign(align) }
50func (w *gtkWidget) SetSizeRequest(w2, h int)      { w.inner.SetSizeRequest(w2, h) }
51func (w *gtkWidget) AddCssClass(class string)      { w.inner.AddCssClass(class) }
52func (w *gtkWidget) RemoveCssClass(class string)   { w.inner.RemoveCssClass(class) }
53func (w *gtkWidget) HasCssClass(class string) bool { return w.inner.HasCssClass(class) }
54func (w *gtkWidget) Unparent()                     { w.inner.Unparent() }
55func (w *gtkWidget) GtkWidget() *gtk.Widget        { return w.inner }
56
57func (w *gtkWidget) GetParent() Widget {
58	parent := w.inner.GetParent()
59	if parent == nil {
60		return nil
61	}
62	return &gtkWidget{inner: parent}
63}
64
65func (w *gtkWidget) GetAllocatedWidth() int               { return w.inner.GetAllocatedWidth() }
66func (w *gtkWidget) GetAllocatedHeight() int              { return w.inner.GetAllocatedHeight() }
67func (w *gtkWidget) AddController(c *gtk.EventController) { w.inner.AddController(c) }
68
69func (w *gtkWidget) ComputePoint(target Widget) (x, y float64, ok bool) {
70	srcPoint := &graphene.Point{X: 0, Y: 0}
71	outPoint := &graphene.Point{}
72
73	var targetGtk *gtk.Widget
74	if target != nil {
75		targetGtk = target.GtkWidget()
76	}
77
78	ok = w.inner.ComputePoint(targetGtk, srcPoint, outPoint)
79	if !ok {
80		return 0, 0, false
81	}
82	return float64(outPoint.X), float64(outPoint.Y), true
83}
84
85// gtkPaned wraps gtk.Paned to implement PanedWidget.
86type gtkPaned struct {
87	inner *gtk.Paned
88
89	tickMu        sync.Mutex
90	tickCallbacks map[uint]*gtk.TickCallback
91}
92
93// unrefTickCallback is the canonical puregotk/purego callback-slot release.
94var unrefTickCallback = glib.UnrefCallback
95
96func (p *gtkPaned) Show()                         { p.inner.Show() }
97func (p *gtkPaned) Hide()                         { p.inner.Hide() }
98func (p *gtkPaned) SetVisible(visible bool)       { p.inner.SetVisible(visible) }
99func (p *gtkPaned) IsVisible() bool               { return p.inner.GetVisible() }
100func (p *gtkPaned) SetOpacity(opacity float64)    { p.inner.SetOpacity(opacity) }
101func (p *gtkPaned) GrabFocus() bool               { return p.inner.GrabFocus() }
102func (p *gtkPaned) HasFocus() bool                { return p.inner.HasFocus() }
103func (p *gtkPaned) SetCanFocus(canFocus bool)     { p.inner.SetCanFocus(canFocus) }
104func (p *gtkPaned) SetFocusable(focusable bool)   { p.inner.SetFocusable(focusable) }
105func (p *gtkPaned) SetFocusOnClick(focus bool)    { p.inner.SetFocusOnClick(focus) }
106func (p *gtkPaned) SetCanTarget(canTarget bool)   { p.inner.SetCanTarget(canTarget) }
107func (p *gtkPaned) SetHexpand(expand bool)        { p.inner.SetHexpand(expand) }
108func (p *gtkPaned) SetVexpand(expand bool)        { p.inner.SetVexpand(expand) }
109func (p *gtkPaned) GetHexpand() bool              { return p.inner.GetHexpand() }
110func (p *gtkPaned) GetVexpand() bool              { return p.inner.GetVexpand() }
111func (p *gtkPaned) SetHalign(align gtk.Align)     { p.inner.SetHalign(align) }
112func (p *gtkPaned) SetValign(align gtk.Align)     { p.inner.SetValign(align) }
113func (p *gtkPaned) SetSizeRequest(w, h int)       { p.inner.SetSizeRequest(w, h) }
114func (p *gtkPaned) AddCssClass(class string)      { p.inner.AddCssClass(class) }
115func (p *gtkPaned) RemoveCssClass(class string)   { p.inner.RemoveCssClass(class) }
116func (p *gtkPaned) HasCssClass(class string) bool { return p.inner.HasCssClass(class) }
117func (p *gtkPaned) Unparent()                     { p.inner.Unparent() }
118func (p *gtkPaned) GtkWidget() *gtk.Widget        { return &p.inner.Widget }
119
120func (p *gtkPaned) GetParent() Widget {
121	parent := p.inner.GetParent()
122	if parent == nil {
123		return nil
124	}
125	return &gtkWidget{inner: parent}
126}
127
128func (p *gtkPaned) SetStartChild(child Widget) {
129	if child == nil {
130		p.inner.SetStartChild(nil)
131		return
132	}
133	p.inner.SetStartChild(child.GtkWidget())
134}
135
136func (p *gtkPaned) SetEndChild(child Widget) {
137	if child == nil {
138		p.inner.SetEndChild(nil)
139		return
140	}
141	p.inner.SetEndChild(child.GtkWidget())
142}
143
144func (p *gtkPaned) GetStartChild() Widget {
145	child := p.inner.GetStartChild()
146	if child == nil {
147		return nil
148	}
149	return &gtkWidget{inner: child}
150}
151
152func (p *gtkPaned) GetEndChild() Widget {
153	child := p.inner.GetEndChild()
154	if child == nil {
155		return nil
156	}
157	return &gtkWidget{inner: child}
158}
159
160func (p *gtkPaned) SetPosition(pos int)        { p.inner.SetPosition(pos) }
161func (p *gtkPaned) GetPosition() int           { return p.inner.GetPosition() }
162func (p *gtkPaned) SetResizeStartChild(r bool) { p.inner.SetResizeStartChild(r) }
163func (p *gtkPaned) SetResizeEndChild(r bool)   { p.inner.SetResizeEndChild(r) }
164func (p *gtkPaned) GetResizeStartChild() bool  { return p.inner.GetResizeStartChild() }
165func (p *gtkPaned) GetResizeEndChild() bool    { return p.inner.GetResizeEndChild() }
166func (p *gtkPaned) SetShrinkStartChild(s bool) { p.inner.SetShrinkStartChild(s) }
167func (p *gtkPaned) SetShrinkEndChild(s bool)   { p.inner.SetShrinkEndChild(s) }
168func (p *gtkPaned) GetShrinkStartChild() bool  { return p.inner.GetShrinkStartChild() }
169func (p *gtkPaned) GetShrinkEndChild() bool    { return p.inner.GetShrinkEndChild() }
170func (p *gtkPaned) SetWideHandle(wide bool)    { p.inner.SetWideHandle(wide) }
171func (p *gtkPaned) GetWideHandle() bool        { return p.inner.GetWideHandle() }
172
173func (p *gtkPaned) ConnectMap(callback func()) uint {
174	cb := func(_ gtk.Widget) {
175		callback()
176	}
177	return p.inner.ConnectMap(&cb)
178}
179
180func (p *gtkPaned) ConnectNotifyPosition(callback func()) uint {
181	cb := func(_ gobject.Object, _ *gobject.ParamSpec) {
182		callback()
183	}
184	return p.inner.ConnectNotifyWithDetail("position", &cb)
185}
186
187func (p *gtkPaned) AddTickCallback(callback func() bool) uint {
188	cb := new(gtk.TickCallback)
189	var id uint
190	*cb = func(_ uintptr, _ uintptr, _ uintptr) bool {
191		keepRunning := callback()
192		if !keepRunning {
193			// GTK removes a false-returning source itself; release its matching
194			// purego slot exactly once rather than merely dropping the Go pointer.
195			p.releaseTickCallback(id)
196		}
197		return keepRunning
198	}
199	id = p.inner.AddTickCallback(cb, 0, nil)
200	if id != 0 {
201		p.tickMu.Lock()
202		if p.tickCallbacks == nil {
203			p.tickCallbacks = make(map[uint]*gtk.TickCallback)
204		}
205		p.tickCallbacks[id] = cb
206		p.tickMu.Unlock()
207	}
208	return id
209}
210
211func (p *gtkPaned) RemoveTickCallback(id uint) {
212	p.inner.RemoveTickCallback(id)
213	p.releaseTickCallback(id)
214}
215
216func (p *gtkPaned) releaseTickCallback(id uint) {
217	if id == 0 {
218		return
219	}
220	p.tickMu.Lock()
221	callback := p.tickCallbacks[id]
222	delete(p.tickCallbacks, id)
223	p.tickMu.Unlock()
224	if callback != nil {
225		_ = unrefTickCallback(callback)
226	}
227}
228
229func (p *gtkPaned) GetAllocatedWidth() int               { return p.inner.GetAllocatedWidth() }
230func (p *gtkPaned) GetAllocatedHeight() int              { return p.inner.GetAllocatedHeight() }
231func (p *gtkPaned) AddController(c *gtk.EventController) { p.inner.AddController(c) }
232
233func (p *gtkPaned) ComputePoint(target Widget) (x, y float64, ok bool) {
234	srcPoint := &graphene.Point{X: 0, Y: 0}
235	outPoint := &graphene.Point{}
236
237	var targetGtk *gtk.Widget
238	if target != nil {
239		targetGtk = target.GtkWidget()
240	}
241
242	ok = p.inner.ComputePoint(targetGtk, srcPoint, outPoint)
243	if !ok {
244		return 0, 0, false
245	}
246	return float64(outPoint.X), float64(outPoint.Y), true
247}
248
249// gtkBox wraps gtk.Box to implement BoxWidget.
250type gtkBox struct {
251	inner *gtk.Box
252}
253
254func (b *gtkBox) Show()                         { b.inner.Show() }
255func (b *gtkBox) Hide()                         { b.inner.Hide() }
256func (b *gtkBox) SetVisible(visible bool)       { b.inner.SetVisible(visible) }
257func (b *gtkBox) IsVisible() bool               { return b.inner.GetVisible() }
258func (b *gtkBox) SetOpacity(opacity float64)    { b.inner.SetOpacity(opacity) }
259func (b *gtkBox) GrabFocus() bool               { return b.inner.GrabFocus() }
260func (b *gtkBox) HasFocus() bool                { return b.inner.HasFocus() }
261func (b *gtkBox) SetCanFocus(canFocus bool)     { b.inner.SetCanFocus(canFocus) }
262func (b *gtkBox) SetFocusable(focusable bool)   { b.inner.SetFocusable(focusable) }
263func (b *gtkBox) SetFocusOnClick(focus bool)    { b.inner.SetFocusOnClick(focus) }
264func (b *gtkBox) SetCanTarget(canTarget bool)   { b.inner.SetCanTarget(canTarget) }
265func (b *gtkBox) SetHexpand(expand bool)        { b.inner.SetHexpand(expand) }
266func (b *gtkBox) SetVexpand(expand bool)        { b.inner.SetVexpand(expand) }
267func (b *gtkBox) GetHexpand() bool              { return b.inner.GetHexpand() }
268func (b *gtkBox) GetVexpand() bool              { return b.inner.GetVexpand() }
269func (b *gtkBox) SetHalign(align gtk.Align)     { b.inner.SetHalign(align) }
270func (b *gtkBox) SetValign(align gtk.Align)     { b.inner.SetValign(align) }
271func (b *gtkBox) SetSizeRequest(w, h int)       { b.inner.SetSizeRequest(w, h) }
272func (b *gtkBox) AddCssClass(class string)      { b.inner.AddCssClass(class) }
273func (b *gtkBox) RemoveCssClass(class string)   { b.inner.RemoveCssClass(class) }
274func (b *gtkBox) HasCssClass(class string) bool { return b.inner.HasCssClass(class) }
275func (b *gtkBox) Unparent()                     { b.inner.Unparent() }
276func (b *gtkBox) GtkWidget() *gtk.Widget        { return &b.inner.Widget }
277
278func (b *gtkBox) GetParent() Widget {
279	parent := b.inner.GetParent()
280	if parent == nil {
281		return nil
282	}
283	return &gtkWidget{inner: parent}
284}
285
286func (b *gtkBox) Append(child Widget) {
287	if child == nil {
288		return
289	}
290	b.inner.Append(child.GtkWidget())
291}
292
293func (b *gtkBox) Prepend(child Widget) {
294	if child == nil {
295		return
296	}
297	b.inner.Prepend(child.GtkWidget())
298}
299
300func (b *gtkBox) Remove(child Widget) {
301	if child == nil {
302		return
303	}
304	b.inner.Remove(child.GtkWidget())
305}
306
307func (b *gtkBox) InsertChildAfter(child, sibling Widget) {
308	if child == nil {
309		return
310	}
311	var sibGtk *gtk.Widget
312	if sibling != nil {
313		sibGtk = sibling.GtkWidget()
314	}
315	b.inner.InsertChildAfter(child.GtkWidget(), sibGtk)
316}
317
318func (b *gtkBox) ReorderChildAfter(child, sibling Widget) {
319	if child == nil {
320		return
321	}
322	var sibGtk *gtk.Widget
323	if sibling != nil {
324		sibGtk = sibling.GtkWidget()
325	}
326	b.inner.ReorderChildAfter(child.GtkWidget(), sibGtk)
327}
328
329func (b *gtkBox) SetHomogeneous(h bool)        { b.inner.SetHomogeneous(h) }
330func (b *gtkBox) GetHomogeneous() bool         { return b.inner.GetHomogeneous() }
331func (b *gtkBox) SetSpacing(s int)             { b.inner.SetSpacing(s) }
332func (b *gtkBox) GetSpacing() int              { return b.inner.GetSpacing() }
333func (b *gtkBox) SetOrientation(o Orientation) { b.inner.SetOrientation(o) }
334func (b *gtkBox) GetOrientation() Orientation  { return b.inner.GetOrientation() }
335
336func (b *gtkBox) GetAllocatedWidth() int               { return b.inner.GetAllocatedWidth() }
337func (b *gtkBox) GetAllocatedHeight() int              { return b.inner.GetAllocatedHeight() }
338func (b *gtkBox) AddController(c *gtk.EventController) { b.inner.AddController(c) }
339
340func (b *gtkBox) ComputePoint(target Widget) (x, y float64, ok bool) {
341	srcPoint := &graphene.Point{X: 0, Y: 0}
342	outPoint := &graphene.Point{}
343
344	var targetGtk *gtk.Widget
345	if target != nil {
346		targetGtk = target.GtkWidget()
347	}
348
349	ok = b.inner.ComputePoint(targetGtk, srcPoint, outPoint)
350	if !ok {
351		return 0, 0, false
352	}
353	return float64(outPoint.X), float64(outPoint.Y), true
354}
355
356// gtkOverlay wraps gtk.Overlay to implement OverlayWidget.
357type gtkOverlay struct {
358	inner *gtk.Overlay
359}
360
361func (o *gtkOverlay) Show()                         { o.inner.Show() }
362func (o *gtkOverlay) Hide()                         { o.inner.Hide() }
363func (o *gtkOverlay) SetVisible(visible bool)       { o.inner.SetVisible(visible) }
364func (o *gtkOverlay) IsVisible() bool               { return o.inner.GetVisible() }
365func (o *gtkOverlay) SetOpacity(opacity float64)    { o.inner.SetOpacity(opacity) }
366func (o *gtkOverlay) GrabFocus() bool               { return o.inner.GrabFocus() }
367func (o *gtkOverlay) HasFocus() bool                { return o.inner.HasFocus() }
368func (o *gtkOverlay) SetCanFocus(canFocus bool)     { o.inner.SetCanFocus(canFocus) }
369func (o *gtkOverlay) SetFocusable(focusable bool)   { o.inner.SetFocusable(focusable) }
370func (o *gtkOverlay) SetFocusOnClick(focus bool)    { o.inner.SetFocusOnClick(focus) }
371func (o *gtkOverlay) SetCanTarget(canTarget bool)   { o.inner.SetCanTarget(canTarget) }
372func (o *gtkOverlay) SetHexpand(expand bool)        { o.inner.SetHexpand(expand) }
373func (o *gtkOverlay) SetVexpand(expand bool)        { o.inner.SetVexpand(expand) }
374func (o *gtkOverlay) GetHexpand() bool              { return o.inner.GetHexpand() }
375func (o *gtkOverlay) GetVexpand() bool              { return o.inner.GetVexpand() }
376func (o *gtkOverlay) SetHalign(align gtk.Align)     { o.inner.SetHalign(align) }
377func (o *gtkOverlay) SetValign(align gtk.Align)     { o.inner.SetValign(align) }
378func (o *gtkOverlay) SetSizeRequest(w, h int)       { o.inner.SetSizeRequest(w, h) }
379func (o *gtkOverlay) AddCssClass(class string)      { o.inner.AddCssClass(class) }
380func (o *gtkOverlay) RemoveCssClass(class string)   { o.inner.RemoveCssClass(class) }
381func (o *gtkOverlay) HasCssClass(class string) bool { return o.inner.HasCssClass(class) }
382func (o *gtkOverlay) Unparent()                     { o.inner.Unparent() }
383func (o *gtkOverlay) GtkWidget() *gtk.Widget        { return &o.inner.Widget }
384
385func (o *gtkOverlay) GetParent() Widget {
386	parent := o.inner.GetParent()
387	if parent == nil {
388		return nil
389	}
390	return &gtkWidget{inner: parent}
391}
392
393func (o *gtkOverlay) SetChild(child Widget) {
394	if child == nil {
395		o.inner.SetChild(nil)
396		return
397	}
398	o.inner.SetChild(child.GtkWidget())
399}
400
401func (o *gtkOverlay) GetChild() Widget {
402	child := o.inner.GetChild()
403	if child == nil {
404		return nil
405	}
406	return &gtkWidget{inner: child}
407}
408
409func (o *gtkOverlay) AddOverlay(overlay Widget) {
410	if overlay == nil {
411		return
412	}
413	o.inner.AddOverlay(overlay.GtkWidget())
414}
415
416func (o *gtkOverlay) RemoveOverlay(overlay Widget) {
417	if overlay == nil {
418		return
419	}
420	o.inner.RemoveOverlay(overlay.GtkWidget())
421}
422
423func (o *gtkOverlay) SetClipOverlay(overlay Widget, clip bool) {
424	if overlay == nil {
425		return
426	}
427	o.inner.SetClipOverlay(overlay.GtkWidget(), clip)
428}
429
430func (o *gtkOverlay) GetClipOverlay(overlay Widget) bool {
431	if overlay == nil {
432		return false
433	}
434	return o.inner.GetClipOverlay(overlay.GtkWidget())
435}
436
437func (o *gtkOverlay) SetMeasureOverlay(overlay Widget, measure bool) {
438	if overlay == nil {
439		return
440	}
441	o.inner.SetMeasureOverlay(overlay.GtkWidget(), measure)
442}
443
444func (o *gtkOverlay) GetMeasureOverlay(overlay Widget) bool {
445	if overlay == nil {
446		return false
447	}
448	return o.inner.GetMeasureOverlay(overlay.GtkWidget())
449}
450
451func (o *gtkOverlay) GetAllocatedWidth() int               { return o.inner.GetAllocatedWidth() }
452func (o *gtkOverlay) GetAllocatedHeight() int              { return o.inner.GetAllocatedHeight() }
453func (o *gtkOverlay) AddController(c *gtk.EventController) { o.inner.AddController(c) }
454
455func (o *gtkOverlay) ComputePoint(target Widget) (x, y float64, ok bool) {
456	srcPoint := &graphene.Point{X: 0, Y: 0}
457	outPoint := &graphene.Point{}
458
459	var targetGtk *gtk.Widget
460	if target != nil {
461		targetGtk = target.GtkWidget()
462	}
463
464	ok = o.inner.ComputePoint(targetGtk, srcPoint, outPoint)
465	if !ok {
466		return 0, 0, false
467	}
468	return float64(outPoint.X), float64(outPoint.Y), true
469}
470
471// gtkLabel wraps gtk.Label to implement LabelWidget.
472type gtkLabel struct {
473	inner *gtk.Label
474}
475
476func (l *gtkLabel) Show()                         { l.inner.Show() }
477func (l *gtkLabel) Hide()                         { l.inner.Hide() }
478func (l *gtkLabel) SetVisible(visible bool)       { l.inner.SetVisible(visible) }
479func (l *gtkLabel) IsVisible() bool               { return l.inner.GetVisible() }
480func (l *gtkLabel) SetOpacity(opacity float64)    { l.inner.SetOpacity(opacity) }
481func (l *gtkLabel) GrabFocus() bool               { return l.inner.GrabFocus() }
482func (l *gtkLabel) HasFocus() bool                { return l.inner.HasFocus() }
483func (l *gtkLabel) SetCanFocus(canFocus bool)     { l.inner.SetCanFocus(canFocus) }
484func (l *gtkLabel) SetFocusable(focusable bool)   { l.inner.SetFocusable(focusable) }
485func (l *gtkLabel) SetFocusOnClick(focus bool)    { l.inner.SetFocusOnClick(focus) }
486func (l *gtkLabel) SetCanTarget(canTarget bool)   { l.inner.SetCanTarget(canTarget) }
487func (l *gtkLabel) SetHexpand(expand bool)        { l.inner.SetHexpand(expand) }
488func (l *gtkLabel) SetVexpand(expand bool)        { l.inner.SetVexpand(expand) }
489func (l *gtkLabel) GetHexpand() bool              { return l.inner.GetHexpand() }
490func (l *gtkLabel) GetVexpand() bool              { return l.inner.GetVexpand() }
491func (l *gtkLabel) SetHalign(align gtk.Align)     { l.inner.SetHalign(align) }
492func (l *gtkLabel) SetValign(align gtk.Align)     { l.inner.SetValign(align) }
493func (l *gtkLabel) SetSizeRequest(w, h int)       { l.inner.SetSizeRequest(w, h) }
494func (l *gtkLabel) AddCssClass(class string)      { l.inner.AddCssClass(class) }
495func (l *gtkLabel) RemoveCssClass(class string)   { l.inner.RemoveCssClass(class) }
496func (l *gtkLabel) HasCssClass(class string) bool { return l.inner.HasCssClass(class) }
497func (l *gtkLabel) Unparent()                     { l.inner.Unparent() }
498func (l *gtkLabel) GtkWidget() *gtk.Widget        { return &l.inner.Widget }
499
500func (l *gtkLabel) GetParent() Widget {
501	parent := l.inner.GetParent()
502	if parent == nil {
503		return nil
504	}
505	return &gtkWidget{inner: parent}
506}
507
508func (l *gtkLabel) SetText(text string)             { l.inner.SetText(text) }
509func (l *gtkLabel) GetText() string                 { return l.inner.GetText() }
510func (l *gtkLabel) SetMarkup(markup string)         { l.inner.SetMarkup(markup) }
511func (l *gtkLabel) SetEllipsize(mode EllipsizeMode) { l.inner.SetEllipsize(pango.EllipsizeMode(mode)) }
512func (l *gtkLabel) SetMaxWidthChars(n int)          { l.inner.SetMaxWidthChars(n) }
513func (l *gtkLabel) SetXalign(x float32)             { l.inner.SetXalign(x) }
514
515func (l *gtkLabel) GetAllocatedWidth() int               { return l.inner.GetAllocatedWidth() }
516func (l *gtkLabel) GetAllocatedHeight() int              { return l.inner.GetAllocatedHeight() }
517func (l *gtkLabel) AddController(c *gtk.EventController) { l.inner.AddController(c) }
518
519func (l *gtkLabel) ComputePoint(target Widget) (x, y float64, ok bool) {
520	srcPoint := &graphene.Point{X: 0, Y: 0}
521	outPoint := &graphene.Point{}
522
523	var targetGtk *gtk.Widget
524	if target != nil {
525		targetGtk = target.GtkWidget()
526	}
527
528	ok = l.inner.ComputePoint(targetGtk, srcPoint, outPoint)
529	if !ok {
530		return 0, 0, false
531	}
532	return float64(outPoint.X), float64(outPoint.Y), true
533}
534
535// gtkButton wraps gtk.Button to implement ButtonWidget.
536type gtkButton struct {
537	inner *gtk.Button
538}
539
540func (btn *gtkButton) Show()                         { btn.inner.Show() }
541func (btn *gtkButton) Hide()                         { btn.inner.Hide() }
542func (btn *gtkButton) SetVisible(visible bool)       { btn.inner.SetVisible(visible) }
543func (btn *gtkButton) IsVisible() bool               { return btn.inner.GetVisible() }
544func (btn *gtkButton) SetOpacity(opacity float64)    { btn.inner.SetOpacity(opacity) }
545func (btn *gtkButton) GrabFocus() bool               { return btn.inner.GrabFocus() }
546func (btn *gtkButton) HasFocus() bool                { return btn.inner.HasFocus() }
547func (btn *gtkButton) SetCanFocus(canFocus bool)     { btn.inner.SetCanFocus(canFocus) }
548func (btn *gtkButton) SetFocusable(focusable bool)   { btn.inner.SetFocusable(focusable) }
549func (btn *gtkButton) SetFocusOnClick(focus bool)    { btn.inner.SetFocusOnClick(focus) }
550func (btn *gtkButton) SetCanTarget(canTarget bool)   { btn.inner.SetCanTarget(canTarget) }
551func (btn *gtkButton) SetHexpand(expand bool)        { btn.inner.SetHexpand(expand) }
552func (btn *gtkButton) SetVexpand(expand bool)        { btn.inner.SetVexpand(expand) }
553func (btn *gtkButton) GetHexpand() bool              { return btn.inner.GetHexpand() }
554func (btn *gtkButton) GetVexpand() bool              { return btn.inner.GetVexpand() }
555func (btn *gtkButton) SetHalign(align gtk.Align)     { btn.inner.SetHalign(align) }
556func (btn *gtkButton) SetValign(align gtk.Align)     { btn.inner.SetValign(align) }
557func (btn *gtkButton) SetSizeRequest(w, h int)       { btn.inner.SetSizeRequest(w, h) }
558func (btn *gtkButton) AddCssClass(class string)      { btn.inner.AddCssClass(class) }
559func (btn *gtkButton) RemoveCssClass(class string)   { btn.inner.RemoveCssClass(class) }
560func (btn *gtkButton) HasCssClass(class string) bool { return btn.inner.HasCssClass(class) }
561func (btn *gtkButton) Unparent()                     { btn.inner.Unparent() }
562func (btn *gtkButton) GtkWidget() *gtk.Widget        { return &btn.inner.Widget }
563
564func (btn *gtkButton) GetParent() Widget {
565	parent := btn.inner.GetParent()
566	if parent == nil {
567		return nil
568	}
569	return &gtkWidget{inner: parent}
570}
571
572func (btn *gtkButton) SetLabel(label string)   { btn.inner.SetLabel(label) }
573func (btn *gtkButton) GetLabel() string        { return btn.inner.GetLabel() }
574func (btn *gtkButton) SetIconName(name string) { btn.inner.SetIconName(name) }
575
576func (btn *gtkButton) SetChild(child Widget) {
577	if child == nil {
578		btn.inner.SetChild(nil)
579		return
580	}
581	btn.inner.SetChild(child.GtkWidget())
582}
583
584func (btn *gtkButton) GetChild() Widget {
585	child := btn.inner.GetChild()
586	if child == nil {
587		return nil
588	}
589	return &gtkWidget{inner: child}
590}
591
592func (btn *gtkButton) ConnectClicked(callback func()) uint {
593	cb := func(_ gtk.Button) {
594		callback()
595	}
596	return btn.inner.ConnectClicked(&cb)
597}
598
599func (btn *gtkButton) GetAllocatedWidth() int               { return btn.inner.GetAllocatedWidth() }
600func (btn *gtkButton) GetAllocatedHeight() int              { return btn.inner.GetAllocatedHeight() }
601func (btn *gtkButton) AddController(c *gtk.EventController) { btn.inner.AddController(c) }
602
603func (btn *gtkButton) ComputePoint(target Widget) (x, y float64, ok bool) {
604	srcPoint := &graphene.Point{X: 0, Y: 0}
605	outPoint := &graphene.Point{}
606
607	var targetGtk *gtk.Widget
608	if target != nil {
609		targetGtk = target.GtkWidget()
610	}
611
612	ok = btn.inner.ComputePoint(targetGtk, srcPoint, outPoint)
613	if !ok {
614		return 0, 0, false
615	}
616	return float64(outPoint.X), float64(outPoint.Y), true
617}
618
619// gtkImage wraps gtk.Image to implement ImageWidget.
620type gtkImage struct {
621	inner *gtk.Image
622}
623
624func (img *gtkImage) Show()                         { img.inner.Show() }
625func (img *gtkImage) Hide()                         { img.inner.Hide() }
626func (img *gtkImage) SetVisible(visible bool)       { img.inner.SetVisible(visible) }
627func (img *gtkImage) IsVisible() bool               { return img.inner.GetVisible() }
628func (img *gtkImage) SetOpacity(opacity float64)    { img.inner.SetOpacity(opacity) }
629func (img *gtkImage) GrabFocus() bool               { return img.inner.GrabFocus() }
630func (img *gtkImage) HasFocus() bool                { return img.inner.HasFocus() }
631func (img *gtkImage) SetCanFocus(canFocus bool)     { img.inner.SetCanFocus(canFocus) }
632func (img *gtkImage) SetFocusable(focusable bool)   { img.inner.SetFocusable(focusable) }
633func (img *gtkImage) SetFocusOnClick(focus bool)    { img.inner.SetFocusOnClick(focus) }
634func (img *gtkImage) SetCanTarget(canTarget bool)   { img.inner.SetCanTarget(canTarget) }
635func (img *gtkImage) SetHexpand(expand bool)        { img.inner.SetHexpand(expand) }
636func (img *gtkImage) SetVexpand(expand bool)        { img.inner.SetVexpand(expand) }
637func (img *gtkImage) GetHexpand() bool              { return img.inner.GetHexpand() }
638func (img *gtkImage) GetVexpand() bool              { return img.inner.GetVexpand() }
639func (img *gtkImage) SetHalign(align gtk.Align)     { img.inner.SetHalign(align) }
640func (img *gtkImage) SetValign(align gtk.Align)     { img.inner.SetValign(align) }
641func (img *gtkImage) SetSizeRequest(w, h int)       { img.inner.SetSizeRequest(w, h) }
642func (img *gtkImage) AddCssClass(class string)      { img.inner.AddCssClass(class) }
643func (img *gtkImage) RemoveCssClass(class string)   { img.inner.RemoveCssClass(class) }
644func (img *gtkImage) HasCssClass(class string) bool { return img.inner.HasCssClass(class) }
645func (img *gtkImage) Unparent()                     { img.inner.Unparent() }
646func (img *gtkImage) GtkWidget() *gtk.Widget        { return &img.inner.Widget }
647
648func (img *gtkImage) GetParent() Widget {
649	parent := img.inner.GetParent()
650	if parent == nil {
651		return nil
652	}
653	return &gtkWidget{inner: parent}
654}
655
656func (img *gtkImage) SetFromIconName(name string) { img.inner.SetFromIconName(&name) }
657func (img *gtkImage) SetFromFile(filename string) { img.inner.SetFromFile(&filename) }
658func (img *gtkImage) SetFromPaintable(p Paintable) {
659	if p == nil {
660		img.inner.Clear()
661		return
662	}
663	// Create a gdk.Paintable from the pointer
664	// gdk.Texture implements gdk.Paintable
665	texture := &gdk.Texture{}
666	texture.Ptr = p.GoPointer()
667	img.inner.SetFromPaintable(texture)
668}
669func (img *gtkImage) SetPixelSize(size int) { img.inner.SetPixelSize(size) }
670func (img *gtkImage) Clear()                { img.inner.Clear() }
671
672func (img *gtkImage) GetAllocatedWidth() int               { return img.inner.GetAllocatedWidth() }
673func (img *gtkImage) GetAllocatedHeight() int              { return img.inner.GetAllocatedHeight() }
674func (img *gtkImage) AddController(c *gtk.EventController) { img.inner.AddController(c) }
675
676func (img *gtkImage) ComputePoint(target Widget) (x, y float64, ok bool) {
677	srcPoint := &graphene.Point{X: 0, Y: 0}
678	outPoint := &graphene.Point{}
679
680	var targetGtk *gtk.Widget
681	if target != nil {
682		targetGtk = target.GtkWidget()
683	}
684
685	ok = img.inner.ComputePoint(targetGtk, srcPoint, outPoint)
686	if !ok {
687		return 0, 0, false
688	}
689	return float64(outPoint.X), float64(outPoint.Y), true
690}
691
692// gtkProgressBar wraps gtk.ProgressBar to implement ProgressBarWidget.
693type gtkProgressBar struct {
694	inner *gtk.ProgressBar
695}
696
697func (p *gtkProgressBar) Show()                         { p.inner.Show() }
698func (p *gtkProgressBar) Hide()                         { p.inner.Hide() }
699func (p *gtkProgressBar) SetVisible(visible bool)       { p.inner.SetVisible(visible) }
700func (p *gtkProgressBar) IsVisible() bool               { return p.inner.GetVisible() }
701func (p *gtkProgressBar) SetOpacity(opacity float64)    { p.inner.SetOpacity(opacity) }
702func (p *gtkProgressBar) GrabFocus() bool               { return p.inner.GrabFocus() }
703func (p *gtkProgressBar) HasFocus() bool                { return p.inner.HasFocus() }
704func (p *gtkProgressBar) SetCanFocus(canFocus bool)     { p.inner.SetCanFocus(canFocus) }
705func (p *gtkProgressBar) SetFocusable(focusable bool)   { p.inner.SetFocusable(focusable) }
706func (p *gtkProgressBar) SetFocusOnClick(focus bool)    { p.inner.SetFocusOnClick(focus) }
707func (p *gtkProgressBar) SetCanTarget(canTarget bool)   { p.inner.SetCanTarget(canTarget) }
708func (p *gtkProgressBar) SetHexpand(expand bool)        { p.inner.SetHexpand(expand) }
709func (p *gtkProgressBar) SetVexpand(expand bool)        { p.inner.SetVexpand(expand) }
710func (p *gtkProgressBar) GetHexpand() bool              { return p.inner.GetHexpand() }
711func (p *gtkProgressBar) GetVexpand() bool              { return p.inner.GetVexpand() }
712func (p *gtkProgressBar) SetHalign(align gtk.Align)     { p.inner.SetHalign(align) }
713func (p *gtkProgressBar) SetValign(align gtk.Align)     { p.inner.SetValign(align) }
714func (p *gtkProgressBar) SetSizeRequest(w, h int)       { p.inner.SetSizeRequest(w, h) }
715func (p *gtkProgressBar) AddCssClass(class string)      { p.inner.AddCssClass(class) }
716func (p *gtkProgressBar) RemoveCssClass(class string)   { p.inner.RemoveCssClass(class) }
717func (p *gtkProgressBar) HasCssClass(class string) bool { return p.inner.HasCssClass(class) }
718func (p *gtkProgressBar) Unparent()                     { p.inner.Unparent() }
719func (p *gtkProgressBar) GtkWidget() *gtk.Widget        { return &p.inner.Widget }
720
721func (p *gtkProgressBar) GetParent() Widget {
722	parent := p.inner.GetParent()
723	if parent == nil {
724		return nil
725	}
726	return &gtkWidget{inner: parent}
727}
728
729func (p *gtkProgressBar) GetAllocatedWidth() int               { return p.inner.GetAllocatedWidth() }
730func (p *gtkProgressBar) GetAllocatedHeight() int              { return p.inner.GetAllocatedHeight() }
731func (p *gtkProgressBar) AddController(c *gtk.EventController) { p.inner.AddController(c) }
732
733func (p *gtkProgressBar) ComputePoint(target Widget) (x, y float64, ok bool) {
734	srcPoint := &graphene.Point{X: 0, Y: 0}
735	outPoint := &graphene.Point{}
736
737	var targetGtk *gtk.Widget
738	if target != nil {
739		targetGtk = target.GtkWidget()
740	}
741
742	ok = p.inner.ComputePoint(targetGtk, srcPoint, outPoint)
743	if !ok {
744		return 0, 0, false
745	}
746	return float64(outPoint.X), float64(outPoint.Y), true
747}
748
749func (p *gtkProgressBar) SetFraction(fraction float64) { p.inner.SetFraction(fraction) }
750func (p *gtkProgressBar) GetFraction() float64         { return p.inner.GetFraction() }
751
752// gtkSpinner wraps gtk.Spinner to implement SpinnerWidget.
753type gtkSpinner struct {
754	inner *gtk.Spinner
755}
756
757func (s *gtkSpinner) Show()                         { s.inner.Show() }
758func (s *gtkSpinner) Hide()                         { s.inner.Hide() }
759func (s *gtkSpinner) SetVisible(visible bool)       { s.inner.SetVisible(visible) }
760func (s *gtkSpinner) IsVisible() bool               { return s.inner.GetVisible() }
761func (s *gtkSpinner) SetOpacity(opacity float64)    { s.inner.SetOpacity(opacity) }
762func (s *gtkSpinner) GrabFocus() bool               { return s.inner.GrabFocus() }
763func (s *gtkSpinner) HasFocus() bool                { return s.inner.HasFocus() }
764func (s *gtkSpinner) SetCanFocus(canFocus bool)     { s.inner.SetCanFocus(canFocus) }
765func (s *gtkSpinner) SetFocusable(focusable bool)   { s.inner.SetFocusable(focusable) }
766func (s *gtkSpinner) SetFocusOnClick(focus bool)    { s.inner.SetFocusOnClick(focus) }
767func (s *gtkSpinner) SetCanTarget(canTarget bool)   { s.inner.SetCanTarget(canTarget) }
768func (s *gtkSpinner) SetHexpand(expand bool)        { s.inner.SetHexpand(expand) }
769func (s *gtkSpinner) SetVexpand(expand bool)        { s.inner.SetVexpand(expand) }
770func (s *gtkSpinner) GetHexpand() bool              { return s.inner.GetHexpand() }
771func (s *gtkSpinner) GetVexpand() bool              { return s.inner.GetVexpand() }
772func (s *gtkSpinner) SetHalign(align gtk.Align)     { s.inner.SetHalign(align) }
773func (s *gtkSpinner) SetValign(align gtk.Align)     { s.inner.SetValign(align) }
774func (s *gtkSpinner) SetSizeRequest(w, h int)       { s.inner.SetSizeRequest(w, h) }
775func (s *gtkSpinner) AddCssClass(class string)      { s.inner.AddCssClass(class) }
776func (s *gtkSpinner) RemoveCssClass(class string)   { s.inner.RemoveCssClass(class) }
777func (s *gtkSpinner) HasCssClass(class string) bool { return s.inner.HasCssClass(class) }
778func (s *gtkSpinner) Unparent()                     { s.inner.Unparent() }
779func (s *gtkSpinner) GtkWidget() *gtk.Widget        { return &s.inner.Widget }
780
781func (s *gtkSpinner) GetParent() Widget {
782	parent := s.inner.GetParent()
783	if parent == nil {
784		return nil
785	}
786	return &gtkWidget{inner: parent}
787}
788
789func (s *gtkSpinner) GetAllocatedWidth() int               { return s.inner.GetAllocatedWidth() }
790func (s *gtkSpinner) GetAllocatedHeight() int              { return s.inner.GetAllocatedHeight() }
791func (s *gtkSpinner) AddController(c *gtk.EventController) { s.inner.AddController(c) }
792
793func (s *gtkSpinner) ComputePoint(target Widget) (x, y float64, ok bool) {
794	srcPoint := &graphene.Point{X: 0, Y: 0}
795	outPoint := &graphene.Point{}
796
797	var targetGtk *gtk.Widget
798	if target != nil {
799		targetGtk = target.GtkWidget()
800	}
801
802	ok = s.inner.ComputePoint(targetGtk, srcPoint, outPoint)
803	if !ok {
804		return 0, 0, false
805	}
806	return float64(outPoint.X), float64(outPoint.Y), true
807}
808
809func (s *gtkSpinner) Start()                    { s.inner.Start() }
810func (s *gtkSpinner) Stop()                     { s.inner.Stop() }
811func (s *gtkSpinner) SetSpinning(spinning bool) { s.inner.SetSpinning(spinning) }
812func (s *gtkSpinner) GetSpinning() bool         { return s.inner.GetSpinning() }
813
814// GtkWidgetFactory creates real GTK widgets.
815type GtkWidgetFactory struct{}
816
817// NewGtkWidgetFactory creates a new factory for real GTK widgets.
818func NewGtkWidgetFactory() *GtkWidgetFactory {
819	return &GtkWidgetFactory{}
820}
821
822func (f *GtkWidgetFactory) NewPaned(orientation Orientation) PanedWidget {
823	paned := gtk.NewPaned(orientation)
824	paned.SetHexpand(true)
825	paned.SetVexpand(true)
826	return &gtkPaned{inner: paned, tickCallbacks: make(map[uint]*gtk.TickCallback)}
827}
828
829func (f *GtkWidgetFactory) NewBox(orientation Orientation, spacing int) BoxWidget {
830	box := gtk.NewBox(orientation, spacing)
831	box.SetHexpand(true)
832	box.SetVexpand(true)
833	return &gtkBox{inner: box}
834}
835
836func (f *GtkWidgetFactory) NewOverlay() OverlayWidget {
837	overlay := gtk.NewOverlay()
838	overlay.SetHexpand(true)
839	overlay.SetVexpand(true)
840	return &gtkOverlay{inner: overlay}
841}
842
843func (f *GtkWidgetFactory) NewLabel(text string) LabelWidget {
844	label := gtk.NewLabel(&text)
845	return &gtkLabel{inner: label}
846}
847
848func (f *GtkWidgetFactory) NewButton() ButtonWidget {
849	button := gtk.NewButton()
850	return &gtkButton{inner: button}
851}
852
853func (f *GtkWidgetFactory) NewImage() ImageWidget {
854	image := gtk.NewImage()
855	return &gtkImage{inner: image}
856}
857
858func (f *GtkWidgetFactory) NewProgressBar() ProgressBarWidget {
859	progressBar := gtk.NewProgressBar()
860	return &gtkProgressBar{inner: progressBar}
861}
862
863func (f *GtkWidgetFactory) NewSpinner() SpinnerWidget {
864	spinner := gtk.NewSpinner()
865	return &gtkSpinner{inner: spinner}
866}
867
868func (f *GtkWidgetFactory) WrapWidget(w *gtk.Widget) Widget {
869	if w == nil {
870		return nil
871	}
872	return &gtkWidget{inner: w}
873}
874
875func (f *GtkWidgetFactory) WrapNativeWidget(ptr uintptr) Widget {
876	if ptr == 0 {
877		return nil
878	}
879	return f.WrapWidget(gtk.WidgetNewFromInternalPtr(ptr))
880}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close