Last active
April 4, 2020 01:37
-
-
Save diamondburned/bace77818568acfe5b5bd64619bea3da to your computer and use it in GitHub Desktop.
A second attempt at a better Gtk API for Golang.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
type TodoItem struct { | |
gtk.ListBoxRow | |
Entry gtk.Entry // acts as label | |
Remove gtk.Button | |
item string | |
// local, doesn't have to do with Gtk | |
todo *Todo | |
} | |
var _ Initializer = (*TodoItem)(nil) | |
func NewTodoItem(t *Todo, item string) { | |
return &TodoItem{ | |
todo: t, | |
item: item, | |
} | |
} | |
func (t *TodoItem) Initialize() error { | |
t.ListBoxRow = gtk.ListBoxRowNew() | |
// SetKey allows the parent ListBox to easily differ between old and new | |
// nodes. ReactJS does this: | |
// https://reactjs.org/docs/reconciliation.html#keys | |
t.ListBoxRow.SetKey(t.item) | |
t.Entry = gtk.EntryNew() | |
t.Entry.SetMargin(8) | |
t.Entry.Bind(&t.item) | |
t.Entry.Connect("changed", func(content string) { | |
// Manually update the key as well. Can't really think of a better way | |
// other than to use a Serial integer. | |
// Content is just a copy of t.item's value. | |
t.ListBoxRow.SetKey(content) | |
// There's no need to update again here, as we're not modifying t.item. | |
}) | |
t.Remove = gtk.ButtonNew() | |
t.Remove.Connect("clicked", t.RemoveItem) // Bind(func()) | |
// Add containers into ListBoxRow: | |
t.Add(t.Entry) | |
t.Add(t.Remove) | |
t.ShowAll() | |
return nil | |
} | |
func (t *TodoItem) RemoveItem() { | |
t.todo.remove(t.item) | |
// Update, which updates the list as well. | |
t.todo.Update() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
type Initializer interface { | |
Initialize() error // error is only in case, gets floated up. | |
} | |
func main() { | |
a := gtk.ApplicationNew("com.github.diamondburned.demo") | |
w := gtk.ApplicationWindowNew(a) | |
// The magic happens. | |
w.Add(&Todo{}) | |
w.ShowAll() | |
gtk.Main() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
type Todo struct { | |
gtk.Box | |
Entry gtk.Entry | |
Add gtk.Button | |
// local states | |
ItemContainer gtk.ListBox | |
Items []*TodoItem | |
// more local states | |
entryText string | |
} | |
var _ Initializer = (*Todo)(nil) | |
func (t *Todo) Initialize() error { | |
t.Box = gtk.BoxNew() | |
t.Entry = gtk.EntryNew() | |
t.Entry.SetMargin(10) | |
t.Entry.SetMarginRight(5) | |
// Bind changes the string's content with each edit. | |
t.Entry.Bind(&t.entryText) | |
t.Add = gtk.ButtonNew() | |
t.Add.Connect("clicked", func() { | |
t.add(t.entryText) | |
t.entryText = "" | |
// Manually update the main node. This triggers ListBox's internal | |
// pointer to the slice as well, which updates the list of Todo items. | |
// It will also trigger Entry and edit its content to nothing. | |
t.Update() | |
}) | |
t.ItemContainer = gtk.ListBoxNew() | |
t.ItemContainer.SetMargin(10) | |
t.ItemContainer.Bind(&t.Items) // allow (*gtk.ListBox).SetListCallback() | |
// This is needed to be called normally in Gtk. This draft adds an extra | |
// functionality of first-time calling mounted methods to populate the | |
// state. | |
t.ShowAll() | |
return nil | |
} | |
func (t *Todo) add(item string) { | |
t.Items = append(t.Items, NewTodoItem(t, item)) | |
} | |
// remove is called by one of the Todos. | |
func (t *Todo) remove(item string) { | |
for i, todo := range t.Items { | |
if todo.item == item { | |
t.Items = append(t.Items[:i], t.Items[i+1:]...) | |
return | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment