Skip to content

Commit

Permalink
feat(pkg/gtools): Add FetchObjects
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom5521 committed Jul 22, 2024
1 parent cb600e9 commit 76e803f
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 12 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/Tom5521/gtk4tools

go 1.22.4
go 1.22

require github.com/diamondburned/gotk4/pkg v0.3.0

Expand Down
41 changes: 41 additions & 0 deletions internal/walk/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package walk

import "reflect"

type Iteration func(reflect.Value, reflect.StructField) bool

func Into(t any, action Iteration) {
value := reflect.ValueOf(t)
if v := value.Kind(); v == reflect.Pointer || v == reflect.Interface {
value = value.Elem()
}

rtype := reflect.TypeOf(t)
if rtype.Kind() == reflect.Pointer {
rtype = rtype.Elem()
}
Struct(value, rtype, action)
}

func Struct(
value reflect.Value,
str reflect.Type,
action Iteration,
) {
for i := range str.NumField() {
v := value.Field(i)
t := str.Field(i)

if !t.IsExported() {
continue
}

if t.Type.Kind() == reflect.Struct {
Struct(v, t.Type, action)
continue
}
if !action(v, t) {
break
}
}
}
42 changes: 42 additions & 0 deletions internal/walk/walk_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package walk_test

import (
"fmt"
"reflect"
"testing"

"github.com/Tom5521/gtk4tools/internal/walk"
)

type A struct {
F1 string
F2 bool
F3 int
B struct {
F1 string
C struct {
F1 string
}
}
}

func TestUnmarshall(_ *testing.T) {
str := A{
F1: "Meow in A",
F2: true,
F3: 20,
}
str.B.F1 = "Meow in B"
str.B.C.F1 = "Meow in C"

walk.Into(
&str,
func(v reflect.Value, _ reflect.StructField) bool {
if v.String() == "Meow in C" {
v.Set(reflect.ValueOf(v.String() + " | Edited"))
}
fmt.Println(v)
return true
},
)
}
27 changes: 27 additions & 0 deletions pkg/gtools/examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package gtools_test

import (
"fmt"

"github.com/Tom5521/gtk4tools/pkg/gtools"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

func ExampleFetchObjects() {
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkWindow" id="window">
<property name="title">Hello World</property>
</object>
</interface>`

type ui struct {
Window *gtk.Window `gtk:"window"`
}

w := new(ui)
gtools.FetchObjects(w, xml)

fmt.Println(w.Window.Title()) // Hello World
}
26 changes: 26 additions & 0 deletions pkg/gtools/fetch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package gtools

import (
"reflect"

"github.com/Tom5521/gtk4tools/internal/walk"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

// What this function does is to obtain the tags of the provided structure
// and with the content of the tag call gtk.Builder.GetObject
// and assign it to its corresponding field,
// if the field has no tag it will be skipped and if it is another sub struct
// it will continue until it reaches the end.
func FetchObjects(str any, builder string) {
b := gtk.NewBuilderFromString(builder)
walk.Into(str, func(v reflect.Value, sf reflect.StructField) bool {
tag, ok := sf.Tag.Lookup("gtk")
if !ok {
return true
}
obj := b.GetObject(tag).Cast()
v.Set(reflect.ValueOf(obj))
return true
})
}
18 changes: 13 additions & 5 deletions pkg/gtools/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import (
"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

var _ Appender = (*gtk.Box)(nil)

// It is simply an interface of a glib.Objector that has the append method.
type Appender interface {
glib.Objector
Append(gtk.Widgetter)
}

var (
_ ListItem = (*gtk.ListItem)(nil)
_ ListItem = (*gtk.ColumnViewCell)(nil)
)

type ListItem interface {
glib.Objector

Expand All @@ -25,8 +38,3 @@ type ListItem interface {
SetFocusable(focusable bool)
SetSelectable(selectable bool)
}

var (
_ ListItem = (*gtk.ListItem)(nil)
_ ListItem = (*gtk.ColumnViewCell)(nil)
)
6 changes: 0 additions & 6 deletions pkg/gtools/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ func ToWidgetter[T gtk.Widgetter](items []T) []gtk.Widgetter {
return widgets
}

// It is simply an interface of a gtk.widgetter that has the append function.
type Appender interface {
gtk.Widgetter
Append(gtk.Widgetter)
}

func Append(parent Appender, widgets ...gtk.Widgetter) {
for _, w := range widgets {
parent.Append(w)
Expand Down

0 comments on commit 76e803f

Please sign in to comment.