{"id":20279169,"url":"https://github.com/peterhellberg/gui","last_synced_at":"2025-04-11T06:15:11.758Z","repository":{"id":57485426,"uuid":"185470502","full_name":"peterhellberg/gui","owner":"peterhellberg","description":"Minimal GUI in Go initially based on https://github.com/faiface/gui","archived":false,"fork":false,"pushed_at":"2020-03-01T23:02:22.000Z","size":74,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T06:15:05.247Z","etag":null,"topics":["go","gui"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peterhellberg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-07T20:06:00.000Z","updated_at":"2022-10-08T08:14:22.000Z","dependencies_parsed_at":"2022-09-02T00:02:18.568Z","dependency_job_id":null,"html_url":"https://github.com/peterhellberg/gui","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterhellberg%2Fgui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterhellberg%2Fgui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterhellberg%2Fgui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterhellberg%2Fgui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peterhellberg","download_url":"https://codeload.github.com/peterhellberg/gui/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248351393,"owners_count":21089272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","gui"],"created_at":"2024-11-14T13:28:41.738Z","updated_at":"2025-04-11T06:15:11.723Z","avatar_url":"https://github.com/peterhellberg.png","language":"Go","readme":"# peterhellberg/gui\n\n[![Build Status](https://travis-ci.org/peterhellberg/gui.svg?branch=master)](https://travis-ci.org/peterhellberg/gui)\n[![Go Report Card](https://goreportcard.com/badge/github.com/peterhellberg/gui?style=flat)](https://goreportcard.com/report/github.com/peterhellberg/gui)\n[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/peterhellberg/gui)\n\nMinimal GUI in Go, it was initially based on \u003chttps://github.com/faiface/gui\u003e but has since diverged from the original project.\n\n## Dependencies\n\nThis package has a few third party dependencies:\n\n- \u003chttps://github.com/faiface/mainthread\u003e - Run stuff on the main thread in Go\n- \u003chttps://github.com/go-gl/gl\u003e - Go bindings for OpenGL (generated via glow)\n- \u003chttps://github.com/go-gl/glfw\u003e - Go bindings for GLFW 3\n\n## Examples\n\n### Minimal\n\n![gui-minimal](https://user-images.githubusercontent.com/565124/57968481-83ba5880-796b-11e9-8339-934a8d7a542c.png)\n\n[embedmd]:# (examples/gui-example-minimal/gui-example-minimal.go)\n```go\npackage main\n\nimport (\n\t\"image\"\n\t\"image/draw\"\n\n\t\"github.com/peterhellberg/gui\"\n)\n\nfunc main() {\n\tgui.Run(func() {\n\t\twin, err := gui.Open(gui.Title(\"gui-minimal\"))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tfor event := range win.Events() {\n\t\t\tswitch event.(type) {\n\t\t\tcase gui.EventClose:\n\t\t\t\twin.Close()\n\t\t\tcase gui.EventResize:\n\t\t\t\twin.Draw(func(dst draw.Image) image.Rectangle {\n\t\t\t\t\treturn dst.Bounds()\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t})\n}\n```\n\n### XOR\n\n![gui-xor](https://user-images.githubusercontent.com/565124/57329314-d007cc00-7113-11e9-892b-e4c75401004f.png)\n\n[embedmd]:# (examples/gui-example-xor/gui-example-xor.go)\n```go\npackage main\n\nimport (\n\t\"image\"\n\t\"image/color\"\n\t\"image/draw\"\n\n\t\"github.com/peterhellberg/gui\"\n)\n\nfunc main() {\n\tgui.Run(loop)\n}\n\nfunc loop() {\n\twin, err := gui.Open(\n\t\tgui.Title(\"gui-xor\"),\n\t\tgui.Size(512, 512),\n\t\tgui.Decorated(true),\n\t\tgui.Resizable(true),\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfor event := range win.Events() {\n\t\tswitch event := event.(type) {\n\t\tcase gui.EventClose:\n\t\t\twin.Close()\n\t\tcase gui.EventKeyboardDown:\n\t\t\tif event.Key == \"escape\" {\n\t\t\t\twin.Close()\n\t\t\t}\n\t\tcase gui.EventKeyboardChar:\n\t\t\tif event.Char == 'q' {\n\t\t\t\twin.Close()\n\t\t\t}\n\t\tcase gui.EventResize:\n\t\t\twin.Draw(update)\n\t\t}\n\n\t\tgui.Log(\"Event: %+v\", event)\n\t}\n}\n\nfunc update(dst draw.Image) image.Rectangle {\n\tbounds := dst.Bounds()\n\n\tfor x := 0; x \u003c bounds.Max.X; x++ {\n\t\tfor y := 0; y \u003c bounds.Max.Y; y++ {\n\t\t\tc := uint8(x ^ y)\n\n\t\t\tdst.Set(x, y, color.NRGBA{c, c % 192, c, 255})\n\t\t}\n\t}\n\n\treturn bounds\n}\n```\n## Blinker\n\n![gui-blinker](https://user-images.githubusercontent.com/565124/57541634-c10d5d80-734f-11e9-8774-14c71ea920f1.png)\n\n[embedmd]:# (examples/gui-example-blinker/gui-example-blinker.go)\n```go\npackage main\n\nimport (\n\t\"image\"\n\t\"image/draw\"\n\t\"time\"\n\n\t\"github.com/peterhellberg/gui\"\n)\n\nfunc main() {\n\tgui.Run(loop)\n}\n\nfunc loop() {\n\twin, err := gui.Open(\n\t\tgui.Title(\"gui-blinker\"),\n\t\tgui.Size(800, 600),\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tmux, env := gui.NewMux(win)\n\n\t// we create four blinkers, each with its own Env from the mux\n\tgo blinker(mux.Env(), image.Rect(100, 100, 350, 250))\n\tgo blinker(mux.Env(), image.Rect(450, 100, 700, 250))\n\tgo blinker(mux.Env(), image.Rect(100, 350, 350, 500))\n\tgo blinker(mux.Env(), image.Rect(450, 350, 700, 500))\n\n\t// we use the master env now, win is used by the mux\n\tfor event := range env.Events() {\n\t\tswitch event := event.(type) {\n\t\tcase gui.EventClose:\n\t\t\twin.Close()\n\t\tcase gui.EventKeyboardDown:\n\t\t\tif event.Key == \"escape\" {\n\t\t\t\twin.Close()\n\t\t\t}\n\t\tcase gui.EventKeyboardChar:\n\t\t\tif event.Char == 'q' {\n\t\t\t\twin.Close()\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc blinker(env gui.Env, r image.Rectangle) {\n\t// redraw takes a bool and produces a draw command\n\tredraw := func(visible bool) func(draw.Image) image.Rectangle {\n\t\treturn func(dst draw.Image) image.Rectangle {\n\t\t\tif visible {\n\t\t\t\tdraw.Draw(dst, r, image.White, image.ZP, draw.Src)\n\t\t\t} else {\n\t\t\t\tdraw.Draw(dst, r, image.Black, image.ZP, draw.Src)\n\t\t\t}\n\n\t\t\treturn r\n\t\t}\n\t}\n\n\t// first we draw a white rectangle\n\tenv.Draw(redraw(true))\n\n\tfor event := range env.Events() {\n\t\tswitch event := event.(type) {\n\t\tcase gui.EventMouseLeftDown:\n\t\t\tif event.In(r) {\n\t\t\t\t// user clicked on the rectangle we blink 3 times\n\t\t\t\tfor i := 0; i \u003c 3; i++ {\n\t\t\t\t\tenv.Draw(redraw(false))\n\t\t\t\t\ttime.Sleep(time.Second / 3)\n\n\t\t\t\t\tenv.Draw(redraw(true))\n\t\t\t\t\ttime.Sleep(time.Second / 3)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tenv.Close()\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterhellberg%2Fgui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeterhellberg%2Fgui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterhellberg%2Fgui/lists"}