├── examples ├── screenshots.png ├── screenshots2.png ├── simple │ ├── gopher.png │ └── simple.go ├── hugelist │ └── hugelist.go ├── complex │ └── complex.go ├── splitter │ └── splitter.go └── chart │ └── chart.go ├── nk ├── nk.h ├── listview.go ├── nk.c ├── doc.go ├── style.go ├── context.go ├── font.go ├── input.go ├── etc.go ├── cgo_helpers.c ├── cgo_helpers.h ├── draw.go ├── theme.go ├── impl_glfw_common.go ├── impl_glfw_gl3.go ├── types.go └── const.go ├── Makefile ├── go.mod ├── .gitignore ├── go.sum ├── input.go ├── cmd └── gmdeploy │ ├── utils.go │ ├── assets.go │ └── main.go ├── canvas.go ├── row.go ├── LICENSE ├── textedit.go ├── util.go ├── masterwindow.go ├── nk.yml ├── window.go └── README.md /examples/screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDang/gimu/HEAD/examples/screenshots.png -------------------------------------------------------------------------------- /examples/screenshots2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDang/gimu/HEAD/examples/screenshots2.png -------------------------------------------------------------------------------- /examples/simple/gopher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AllenDang/gimu/HEAD/examples/simple/gopher.png -------------------------------------------------------------------------------- /nk/nk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nuklear.h" 4 | 5 | void nk_register_clipboard(struct nk_context *ctx); -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | c-for-go nk.yml 3 | go build 4 | 5 | clean: 6 | rm -f nk/cgo_helpers.go nk/cgo_helpers.h nk/cgo_helpers.c 7 | rm -r nk/doc.go nk/types.go nk/const.go 8 | rm -f nk/nk.go 9 | 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/AllenDang/gimu 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 7 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 8 | ) 9 | -------------------------------------------------------------------------------- /nk/listview.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | func (lv *ListView) Begin() int { 4 | return int(lv.begin) 5 | } 6 | 7 | func (lv *ListView) End() int { 8 | return int(lv.end) 9 | } 10 | 11 | func (lv *ListView) Count() int { 12 | return int(lv.count) 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | -------------------------------------------------------------------------------- /nk/nk.c: -------------------------------------------------------------------------------- 1 | #include "nk.h" 2 | 3 | extern void igClipboardPaste(nk_handle handle, struct nk_text_edit *text_edit); 4 | extern void igClipboardCopy(nk_handle handle, const char *content, int len); 5 | 6 | void nk_register_clipboard(struct nk_context *ctx) 7 | { 8 | ctx->clip.copy = igClipboardCopy; 9 | ctx->clip.paste = igClipboardPaste; 10 | } -------------------------------------------------------------------------------- /nk/doc.go: -------------------------------------------------------------------------------- 1 | // THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS. 2 | 3 | // WARNING: This file has automatically been generated on Wed, 18 Dec 2019 20:58:41 CST. 4 | // Code generated by https://git.io/c-for-go. DO NOT EDIT. 5 | 6 | /* 7 | Package nk provides Go bindings for nuklear.h — a small ANSI C gui library. 8 | */ 9 | package nk 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= 2 | github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= 3 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 h1:b+9H1GAsx5RsjvDFLoS5zkNBzIQMuVKUYQDmxU3N5XE= 4 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 5 | -------------------------------------------------------------------------------- /input.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "github.com/AllenDang/gimu/nk" 5 | ) 6 | 7 | type Input struct { 8 | input *nk.Input 9 | } 10 | 11 | func (i *Input) IsMouseHoveringRect(rect nk.Rect) bool { 12 | return nk.NkInputIsMouseHoveringRect(i.input, rect) > 0 13 | } 14 | 15 | func (i *Input) IsMousePrevHoveringRect(rect nk.Rect) bool { 16 | return nk.NkInputIsMousePrevHoveringRect(i.input, rect) > 0 17 | } 18 | 19 | func (i *Input) IsMouseDown(buttons nk.Buttons) bool { 20 | return nk.NkInputIsMouseDown(i.input, buttons) > 0 21 | } 22 | 23 | func (i *Input) Mouse() *nk.Mouse { 24 | return i.input.Mouse() 25 | } 26 | -------------------------------------------------------------------------------- /cmd/gmdeploy/utils.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "os" 7 | "os/exec" 8 | ) 9 | 10 | func Save(name, data string) { 11 | err := ioutil.WriteFile(name, []byte(data), 0644) 12 | if err != nil { 13 | log.Fatalf("Failed to save %s:%v\n", name, err) 14 | } 15 | } 16 | 17 | func MkdirAll(name string) { 18 | err := os.MkdirAll(name, 0755) 19 | if err != nil { 20 | log.Fatalf("Failed to make all dir, %s:%v\n", name, err) 21 | } 22 | } 23 | 24 | func RunCmd(cmd *exec.Cmd) { 25 | err := cmd.Run() 26 | if err != nil { 27 | log.Fatalf("Failed to execute command:%v\n", err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /nk/style.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #include "nuklear.h" 5 | */ 6 | import "C" 7 | 8 | func (t *StyleText) Color() *Color { 9 | return (*Color)(&t.color) 10 | } 11 | 12 | func (s *Style) Text() *StyleText { 13 | return (*StyleText)(&s.text) 14 | } 15 | 16 | func (s *Style) Window() *StyleWindow { 17 | return (*StyleWindow)(&s.window) 18 | } 19 | 20 | func (s *Style) Combo() *StyleCombo { 21 | return (*StyleCombo)(&s.combo) 22 | } 23 | 24 | func (w *StyleWindow) Background() *Color { 25 | return (*Color)(&w.background) 26 | } 27 | 28 | func (w *StyleWindow) Spacing() *Vec2 { 29 | return (*Vec2)(&w.spacing) 30 | } 31 | 32 | func (w *StyleWindow) Padding() *Vec2 { 33 | return (*Vec2)(&w.padding) 34 | } 35 | 36 | func (w *StyleWindow) GroupPadding() *Vec2 { 37 | return (*Vec2)(&w.group_padding) 38 | } 39 | -------------------------------------------------------------------------------- /canvas.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "image" 5 | "image/color" 6 | 7 | "github.com/AllenDang/gimu/nk" 8 | ) 9 | 10 | type Canvas struct { 11 | buffer *nk.CommandBuffer 12 | } 13 | 14 | func (c *Canvas) FillRect(rect nk.Rect, rounding float32, color color.RGBA) { 15 | nk.NkFillRect(c.buffer, rect, rounding, toNkColor(color)) 16 | } 17 | 18 | func (c *Canvas) FillCircle(rect nk.Rect, color color.RGBA) { 19 | nk.NkFillCircle(c.buffer, rect, toNkColor(color)) 20 | } 21 | 22 | func (c *Canvas) FillTriangle(p1, p2, p3 image.Point, color color.RGBA) { 23 | nk.NkFillTriangle(c.buffer, float32(p1.X), float32(p1.Y), float32(p2.X), float32(p2.Y), float32(p3.X), float32(p3.Y), toNkColor(color)) 24 | } 25 | 26 | func (c *Canvas) FillPolygon(points []float32, color color.RGBA) { 27 | nk.NkFillPolygon(c.buffer, points, int32(len(points)), toNkColor(color)) 28 | } 29 | -------------------------------------------------------------------------------- /nk/context.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | func (ctx *Context) SetClipboard(board ClipboardPlugin) { 4 | clipboardPlugin = board 5 | NkRegisterClipboard(ctx) 6 | } 7 | 8 | func (ctx *Context) Input() *Input { 9 | return (*Input)(&ctx.input) 10 | } 11 | 12 | func (ctx *Context) Current() *Window { 13 | return (*Window)(ctx.current) 14 | } 15 | 16 | func (ctx *Context) Style() *Style { 17 | return (*Style)(&ctx.style) 18 | } 19 | 20 | func (ctx *Context) Memory() *Buffer { 21 | return (*Buffer)(&ctx.memory) 22 | } 23 | 24 | func (ctx *Context) Clip() *Clipboard { 25 | return (*Clipboard)(&ctx.clip) 26 | } 27 | 28 | func (ctx *Context) LastWidgetState() Flags { 29 | return (Flags)(ctx.last_widget_state) 30 | } 31 | 32 | func (ctx *Context) DeltaTimeSeconds() float32 { 33 | return (float32)(ctx.delta_time_seconds) 34 | } 35 | 36 | func (ctx *Context) ButtonBehavior() ButtonBehavior { 37 | return (ButtonBehavior)(ctx.button_behavior) 38 | } 39 | 40 | func (ctx *Context) Stacks() *ConfigurationStacks { 41 | return (*ConfigurationStacks)(&ctx.stacks) 42 | } 43 | -------------------------------------------------------------------------------- /nk/font.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #include "nuklear.h" 5 | */ 6 | import "C" 7 | 8 | import "unsafe" 9 | 10 | func NkFontAtlasAddFromBytes(atlas *FontAtlas, data []byte, height float32, config *FontConfig) *Font { 11 | dataPtr := unsafe.Pointer((*sliceHeader)(unsafe.Pointer(&data)).Data) 12 | return NkFontAtlasAddFromMemory(atlas, dataPtr, Size(len(data)), height, config) 13 | } 14 | 15 | func (fc *FontConfig) SetPixelSnap(b bool) { 16 | var i int 17 | if b { 18 | i = 1 19 | } else { 20 | i = 0 21 | } 22 | fc.pixel_snap = (C.uchar)(i) 23 | } 24 | 25 | func (fc *FontConfig) SetOversample(v, h int) { 26 | fc.oversample_v = (C.uchar)(v) 27 | fc.oversample_h = (C.uchar)(h) 28 | } 29 | 30 | func (fc *FontConfig) SetRange(r *Rune) { 31 | fc._range = (*C.nk_rune)(r) 32 | } 33 | 34 | func (fc *FontConfig) SetRangeGoRune(r []rune) { 35 | fc._range = (*C.nk_rune)(unsafe.Pointer(&r[0])) 36 | } 37 | 38 | func (atlas *FontAtlas) DefaultFont() *Font { 39 | return (*Font)(atlas.default_font) 40 | } 41 | 42 | func (f Font) Handle() *UserFont { 43 | return NewUserFontRef(unsafe.Pointer(&f.handle)) 44 | } 45 | -------------------------------------------------------------------------------- /row.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "github.com/AllenDang/gimu/nk" 5 | ) 6 | 7 | type Row struct { 8 | win *Window 9 | ctx *nk.Context 10 | height int 11 | } 12 | 13 | func (r *Row) Dynamic(col int) { 14 | nk.NkLayoutRowDynamic(r.ctx, float32(r.height), int32(col)) 15 | } 16 | 17 | func (r *Row) Static(width ...int) { 18 | nk.NkLayoutRowTemplateBegin(r.ctx, float32(r.height)) 19 | 20 | for _, w := range width { 21 | if w == 0 { 22 | nk.NkLayoutRowTemplatePushDynamic(r.ctx) 23 | } else { 24 | nk.NkLayoutRowTemplatePushStatic(r.ctx, float32(w)) 25 | } 26 | } 27 | 28 | nk.NkLayoutRowTemplateEnd(r.ctx) 29 | } 30 | 31 | func (r *Row) Ratio(ratio ...float32) { 32 | nk.NkLayoutRowBegin(r.ctx, nk.LayoutDynamic, float32(r.height), int32(len(ratio))) 33 | 34 | for _, rt := range ratio { 35 | nk.NkLayoutRowPush(r.ctx, rt) 36 | } 37 | 38 | nk.NkLayoutRowEnd(r.ctx) 39 | 40 | } 41 | 42 | func (r *Row) Space(spaceType nk.LayoutFormat, builder BuilderFunc) { 43 | nk.NkLayoutSpaceBegin(r.ctx, spaceType, float32(r.height), 2147483647) 44 | 45 | builder(r.win) 46 | 47 | nk.NkLayoutSpaceEnd(r.ctx) 48 | } 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Allen Dang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/hugelist/hugelist.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | 7 | "github.com/AllenDang/gimu" 8 | "github.com/AllenDang/gimu/nk" 9 | ) 10 | 11 | var ( 12 | listview *nk.ListView 13 | listitem []interface{} 14 | ) 15 | 16 | func builder(w *gimu.Window) { 17 | width, height := w.MasterWindow().GetSize() 18 | bounds := nk.NkRect(0, 0, float32(width), float32(height)) 19 | w.Window("", bounds, 0, func(w *gimu.Window) { 20 | w.Row(int(height - 18)).Dynamic(1) 21 | w.ListView(listview, "huge list", nk.WindowBorder, 25, 22 | listitem, 23 | func(r *gimu.Row) { 24 | r.Dynamic(1) 25 | }, 26 | func(w *gimu.Window, i int, item interface{}) { 27 | if s, ok := item.(string); ok { 28 | w.Label(s, "LC") 29 | } 30 | }) 31 | }) 32 | } 33 | 34 | func main() { 35 | // Init the listview widget 36 | listview = &nk.ListView{} 37 | 38 | // Create list items 39 | listitem = make([]interface{}, 12345) 40 | for i := range listitem { 41 | listitem[i] = fmt.Sprintf("Label item %d", i) 42 | } 43 | 44 | runtime.LockOSThread() 45 | 46 | wnd := gimu.NewMasterWindow("Huge list", 800, 600, gimu.MasterWindowFlagNoResize) 47 | wnd.Main(builder) 48 | } 49 | -------------------------------------------------------------------------------- /nk/input.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #include "nuklear.h" 5 | */ 6 | import "C" 7 | 8 | func (input *Input) Mouse() *Mouse { 9 | return (*Mouse)(&input.mouse) 10 | } 11 | 12 | func (input *Input) Keyboard() *Keyboard { 13 | return (*Keyboard)(&input.keyboard) 14 | } 15 | 16 | func (keyboard *Keyboard) Text() string { 17 | return C.GoStringN(&keyboard.text[0], keyboard.text_len) 18 | } 19 | 20 | func (mouse *Mouse) Grab() bool { 21 | return mouse.grab == True 22 | } 23 | 24 | func (mouse *Mouse) Grabbed() bool { 25 | return mouse.grabbed == True 26 | } 27 | 28 | func (mouse *Mouse) Ungrab() bool { 29 | return mouse.ungrab == True 30 | } 31 | 32 | func (mouse *Mouse) ScrollDelta() Vec2 { 33 | return (Vec2)(mouse.scroll_delta) 34 | } 35 | 36 | func (mouse *Mouse) Pos() (int32, int32) { 37 | return (int32)(mouse.pos.x), (int32)(mouse.pos.y) 38 | } 39 | 40 | func (mouse *Mouse) SetPos(x, y int32) { 41 | mouse.pos.x = (C.float)(x) 42 | mouse.pos.y = (C.float)(y) 43 | } 44 | 45 | func (mouse *Mouse) Prev() (int32, int32) { 46 | return (int32)(mouse.prev.x), (int32)(mouse.prev.y) 47 | } 48 | 49 | func (mouse *Mouse) Delta() (int32, int32) { 50 | return (int32)(mouse.delta.x), (int32)(mouse.delta.y) 51 | } 52 | -------------------------------------------------------------------------------- /textedit.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "github.com/AllenDang/gimu/nk" 5 | ) 6 | 7 | type TextEdit struct { 8 | editor *nk.TextEdit 9 | } 10 | 11 | func NewTextEdit() *TextEdit { 12 | edt := &nk.TextEdit{} 13 | nk.NkTexteditInitDefault(edt) 14 | 15 | return &TextEdit{editor: edt} 16 | } 17 | 18 | type EditFilter func(rune) bool 19 | 20 | func EditFilterDefault(r rune) bool { 21 | return true 22 | } 23 | 24 | func EditFilterAscii(r rune) bool { 25 | return nk.NkFilterAscii(nil, toNkRune(r)) > 0 26 | } 27 | 28 | func EditFilterFloat(r rune) bool { 29 | return nk.NkFilterFloat(nil, toNkRune(r)) > 0 30 | } 31 | 32 | func EditFilterDecimal(r rune) bool { 33 | return nk.NkFilterDecimal(nil, toNkRune(r)) > 0 34 | } 35 | 36 | func EditFilterHex(r rune) bool { 37 | return nk.NkFilterHex(nil, toNkRune(r)) > 0 38 | } 39 | 40 | func EditFilterOct(r rune) bool { 41 | return nk.NkFilterOct(nil, toNkRune(r)) > 0 42 | } 43 | 44 | func EditFilterBinary(r rune) bool { 45 | return nk.NkFilterBinary(nil, toNkRune(r)) > 0 46 | } 47 | 48 | func (t *TextEdit) Edit(w *Window, flag nk.Flags, filter EditFilter) { 49 | nk.NkEditBuffer(w.ctx, flag, t.editor, toNkPluginFilter(filter)) 50 | } 51 | 52 | func (t *TextEdit) GetString() string { 53 | return t.editor.GetGoString() 54 | } 55 | -------------------------------------------------------------------------------- /cmd/gmdeploy/assets.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //darwin 6 | 7 | func darwinPlist(name string) string { 8 | return fmt.Sprintf(` 9 | 10 | 11 | 12 | CFBundleExecutable 13 | %[1]v 14 | CFBundleGetInfoString 15 | Created by Qt/QMake 16 | CFBundleIconFile 17 | %[1]v.icns 18 | CFBundleIdentifier 19 | com.yourcompany.%[1]v 20 | CFBundleName 21 | %[1]v 22 | CFBundlePackageType 23 | APPL 24 | CFBundleShortVersionString 25 | 1.0.0 26 | CFBundleSignature 27 | ???? 28 | LSMinimumSystemVersion 29 | 10.11 30 | NOTE 31 | This file was generated by Qt/QMake. 32 | NSPrincipalClass 33 | NSApplication 34 | NSHighResolutionCapable 35 | 36 | NSSupportsAutomaticGraphicsSwitching 37 | 38 | 39 | 40 | `, name) 41 | } 42 | 43 | func darwinPkginfo() string { 44 | return "APPL????\n" 45 | } 46 | -------------------------------------------------------------------------------- /nk/etc.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #include "nuklear.h" 5 | */ 6 | import "C" 7 | import "bytes" 8 | 9 | var ( 10 | clipboardPlugin ClipboardPlugin 11 | ) 12 | 13 | type ClipboardPlugin interface { 14 | GetText() string 15 | SetText(content string) 16 | } 17 | 18 | //export igClipboardPaste 19 | func igClipboardPaste(user C.nk_handle, edit *TextEdit) { 20 | if clipboardPlugin != nil { 21 | content := clipboardPlugin.GetText() 22 | NkTexteditPaste(edit, content, int32(len(content))) 23 | } 24 | } 25 | 26 | //export igClipboardCopy 27 | func igClipboardCopy(user C.nk_handle, text *C.char, len C.int) { 28 | if clipboardPlugin != nil { 29 | clipboardPlugin.SetText(C.GoStringN(text, len)) 30 | } 31 | } 32 | 33 | // Allocated is the total amount of memory allocated. 34 | func (b *Buffer) Allocated() int { 35 | return (int)(b.allocated) 36 | } 37 | 38 | // Size is the current size of the buffer. 39 | func (b *Buffer) Size() int { 40 | return (int)(b.size) 41 | } 42 | 43 | // Type is the memory management type of the buffer. 44 | func (b *Buffer) Type() AllocationType { 45 | return (AllocationType)(b._type) 46 | } 47 | 48 | func (t *TextEdit) GetGoString() string { 49 | nkstr := t.GetString() 50 | b := C.GoBytes(*nkstr.GetBuffer().GetMemory().GetPtr(), C.int(*nkstr.GetBuffer().GetSize())) 51 | r := bytes.Runes(b)[:*nkstr.GetLen()] 52 | return string(r) 53 | } 54 | -------------------------------------------------------------------------------- /examples/complex/complex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | 6 | "github.com/AllenDang/gimu" 7 | "github.com/AllenDang/gimu/nk" 8 | ) 9 | 10 | func builder(w *gimu.Window) { 11 | width, height := w.MasterWindow().GetSize() 12 | 13 | w.Window("", nk.NkRect(0, 0, float32(width), float32(height)), nk.WindowNoScrollbar, func(w *gimu.Window) { 14 | w.Row(500).Space(nk.Static, func(w *gimu.Window) { 15 | w.Push(nk.NkRect(0, 0, 150, 150)) 16 | w.Group("Group Left", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 17 | }) 18 | 19 | w.Push(nk.NkRect(160, 0, 150, 240)) 20 | w.Group("Group Top", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 21 | }) 22 | 23 | w.Push(nk.NkRect(160, 250, 150, 250)) 24 | w.Group("Group Bottom", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 25 | }) 26 | 27 | w.Push(nk.NkRect(320, 0, 150, 150)) 28 | w.Group("Group Right Top", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 29 | }) 30 | 31 | w.Push(nk.NkRect(320, 160, 150, 150)) 32 | w.Group("Group Right Center", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 33 | }) 34 | 35 | w.Push(nk.NkRect(320, 320, 150, 150)) 36 | w.Group("Group Right Center", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 37 | }) 38 | }) 39 | }) 40 | } 41 | 42 | func main() { 43 | runtime.LockOSThread() 44 | 45 | wnd := gimu.NewMasterWindow("Complex layout", 500, 600, gimu.MasterWindowFlagNoResize) 46 | 47 | wnd.Main(builder) 48 | } 49 | -------------------------------------------------------------------------------- /examples/splitter/splitter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | 6 | "github.com/AllenDang/gimu" 7 | "github.com/AllenDang/gimu/nk" 8 | ) 9 | 10 | var ( 11 | leftWidth int = 200 12 | rightWidth int 13 | splitterWidth int = 5 14 | ) 15 | 16 | func builder(w *gimu.Window) { 17 | width, height := w.MasterWindow().GetSize() 18 | 19 | w.Window("", nk.NkRect(0, 0, float32(width), float32(height)), nk.WindowNoScrollbar, func(w *gimu.Window) { 20 | rightWidth = int(width) - leftWidth - splitterWidth - 25 21 | 22 | w.Row(int(height-10)).Static(leftWidth, splitterWidth, rightWidth) 23 | w.Group("Left Group", nk.WindowTitle|nk.WindowBorder|nk.WindowNoScrollbar, func(w *gimu.Window) { 24 | w.Row(25).Dynamic(1) 25 | w.Label("Content", "LC") 26 | }) 27 | 28 | //Splitter 29 | bounds := w.WidgetBounds() 30 | w.Spacing(1) 31 | input := w.GetInput() 32 | if (input.IsMouseHoveringRect(bounds) || input.IsMousePrevHoveringRect(bounds)) && input.IsMouseDown(nk.ButtonLeft) { 33 | x, _ := input.Mouse().Delta() 34 | leftWidth += int(x) 35 | rightWidth -= int(x) 36 | } 37 | 38 | w.Group("Right Group", nk.WindowTitle|nk.WindowBorder|nk.WindowNoScrollbar, func(w *gimu.Window) { 39 | w.Row(25).Dynamic(1) 40 | w.Label("Drag the space between two group to resize", "LC") 41 | }) 42 | }) 43 | } 44 | 45 | func main() { 46 | runtime.LockOSThread() 47 | 48 | wnd := gimu.NewMasterWindow("Splitter Demo", 800, 600, gimu.MasterWindowFlagDefault) 49 | 50 | wnd.Main(builder) 51 | } 52 | -------------------------------------------------------------------------------- /nk/cgo_helpers.c: -------------------------------------------------------------------------------- 1 | // THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS. 2 | 3 | // WARNING: This file has automatically been generated on Wed, 18 Dec 2019 20:58:41 CST. 4 | // Code generated by https://git.io/c-for-go. DO NOT EDIT. 5 | 6 | #include "_cgo_export.h" 7 | #include "cgo_helpers.h" 8 | 9 | void* nk_plugin_alloc_88237ac9(nk_handle arg0, void* old, unsigned long int arg2) { 10 | return pluginAlloc88237AC9(arg0, old, arg2); 11 | } 12 | 13 | void nk_plugin_free_9e32bb09(nk_handle arg0, void* old) { 14 | pluginFree9E32BB09(arg0, old); 15 | } 16 | 17 | int nk_plugin_filter_1df5f22c(struct nk_text_edit* arg0, unsigned int unicode) { 18 | return pluginFilter1DF5F22C(arg0, unicode); 19 | } 20 | 21 | void nk_plugin_paste_70e696c4(nk_handle arg0, struct nk_text_edit* arg1) { 22 | pluginPaste70E696C4(arg0, arg1); 23 | } 24 | 25 | void nk_plugin_copy_9ea6c143(nk_handle arg0, char* arg1, int len) { 26 | pluginCopy9EA6C143(arg0, arg1, len); 27 | } 28 | 29 | float nk_text_width_f_67477c0(nk_handle arg0, float h, char* arg2, int len) { 30 | return textWidthF67477C0(arg0, h, arg2, len); 31 | } 32 | 33 | void nk_query_font_glyph_f_5ba87240(nk_handle handle, float font_height, struct nk_user_font_glyph* glyph, unsigned int codepoint, unsigned int next_codepoint) { 34 | queryFontGlyphF5BA87240(handle, font_height, glyph, codepoint, next_codepoint); 35 | } 36 | 37 | void nk_command_custom_callback_d451fdb1(void* canvas, short int x, short int y, unsigned short int w, unsigned short int h, nk_handle callback_data) { 38 | commandCustomCallbackD451FDB1(canvas, x, y, w, h, callback_data); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /nk/cgo_helpers.h: -------------------------------------------------------------------------------- 1 | // THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS. 2 | 3 | // WARNING: This file has automatically been generated on Wed, 18 Dec 2019 20:58:41 CST. 4 | // Code generated by https://git.io/c-for-go. DO NOT EDIT. 5 | 6 | #include "nk.h" 7 | #include 8 | #pragma once 9 | 10 | #define __CGOGEN 1 11 | 12 | // nk_plugin_alloc_88237ac9 is a proxy for callback nk_plugin_alloc. 13 | void* nk_plugin_alloc_88237ac9(nk_handle arg0, void* old, unsigned long int arg2); 14 | 15 | // nk_plugin_free_9e32bb09 is a proxy for callback nk_plugin_free. 16 | void nk_plugin_free_9e32bb09(nk_handle arg0, void* old); 17 | 18 | // nk_plugin_filter_1df5f22c is a proxy for callback nk_plugin_filter. 19 | int nk_plugin_filter_1df5f22c(struct nk_text_edit* arg0, unsigned int unicode); 20 | 21 | // nk_plugin_paste_70e696c4 is a proxy for callback nk_plugin_paste. 22 | void nk_plugin_paste_70e696c4(nk_handle arg0, struct nk_text_edit* arg1); 23 | 24 | // nk_plugin_copy_9ea6c143 is a proxy for callback nk_plugin_copy. 25 | void nk_plugin_copy_9ea6c143(nk_handle arg0, char* arg1, int len); 26 | 27 | // nk_text_width_f_67477c0 is a proxy for callback nk_text_width_f. 28 | float nk_text_width_f_67477c0(nk_handle arg0, float h, char* arg2, int len); 29 | 30 | // nk_query_font_glyph_f_5ba87240 is a proxy for callback nk_query_font_glyph_f. 31 | void nk_query_font_glyph_f_5ba87240(nk_handle handle, float font_height, struct nk_user_font_glyph* glyph, unsigned int codepoint, unsigned int next_codepoint); 32 | 33 | // nk_command_custom_callback_d451fdb1 is a proxy for callback nk_command_custom_callback. 34 | void nk_command_custom_callback_d451fdb1(void* canvas, short int x, short int y, unsigned short int w, unsigned short int h, nk_handle callback_data); 35 | 36 | -------------------------------------------------------------------------------- /cmd/gmdeploy/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | "runtime" 10 | ) 11 | 12 | func main() { 13 | flag.Usage = func() { 14 | fmt.Println("Usage: gmdeploy [os] [icon] [path/to/progject]") 15 | fmt.Println("Flags:") 16 | flag.PrintDefaults() 17 | 18 | os.Exit(0) 19 | } 20 | 21 | var targetOS string 22 | flag.StringVar(&targetOS, "os", "", "target deploy os [windows, darwin, linux]") 23 | 24 | var iconPath string 25 | flag.StringVar(&iconPath, "icon", "", "applicatio icon file path") 26 | 27 | flag.Parse() 28 | 29 | if len(targetOS) == 0 { 30 | targetOS = runtime.GOOS 31 | } 32 | 33 | projectPath, _ := os.Getwd() 34 | appName := filepath.Base(projectPath) 35 | 36 | // Prepare build dir 37 | outputDir := filepath.Join(projectPath, "build", targetOS) 38 | os.RemoveAll(outputDir) 39 | MkdirAll(outputDir) 40 | 41 | switch targetOS { 42 | case "darwin": 43 | // Compile 44 | cmd := exec.Command("go", "build", ".") 45 | cmd.Dir = projectPath 46 | RunCmd(cmd) 47 | 48 | // Bundle 49 | macOSPath := filepath.Join(outputDir, fmt.Sprintf("%s.app", appName), "Contents", "MacOS") 50 | MkdirAll(macOSPath) 51 | 52 | // Copy compiled executable to build folder 53 | cmd = exec.Command("mv", appName, macOSPath) 54 | RunCmd(cmd) 55 | 56 | // Prepare Info.plist 57 | contentsPath := filepath.Join(outputDir, fmt.Sprintf("%s.app", appName), "Contents") 58 | Save(filepath.Join(contentsPath, "Info.plist"), darwinPlist(appName)) 59 | 60 | // Prepare PkgInfo 61 | Save(filepath.Join(contentsPath, "PkgInfo"), darwinPkginfo()) 62 | 63 | if len(iconPath) > 0 && filepath.Ext(iconPath) == ".icns" { 64 | // Prepare icon 65 | resourcesPath := filepath.Join(contentsPath, "Resources") 66 | MkdirAll(resourcesPath) 67 | 68 | // Rename icon file name to [appName].icns 69 | cmd = exec.Command("cp", iconPath, filepath.Join(resourcesPath, fmt.Sprintf("%s.icns", appName))) 70 | RunCmd(cmd) 71 | } 72 | 73 | fmt.Printf("%s.app is generated at %s/build/%s/\n", appName, projectPath, targetOS) 74 | 75 | default: 76 | fmt.Printf("Sorry, %s is not supported yet.\n", targetOS) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /examples/chart/chart.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "math/rand" 5 | "runtime" 6 | 7 | "github.com/AllenDang/gimu" 8 | "github.com/AllenDang/gimu/nk" 9 | ) 10 | 11 | var ( 12 | lineValues []float32 13 | line2Values []float32 14 | line3Values []float32 15 | ) 16 | 17 | func builder(w *gimu.Window) { 18 | width, height := w.MasterWindow().GetSize() 19 | w.Window("", nk.NkRect(0, 0, float32(width), float32(height)), nk.WindowNoScrollbar, func(w *gimu.Window) { 20 | w.Row(25).Dynamic(1) 21 | w.Label("Simple Charts", "LC") 22 | 23 | w.Row(100).Dynamic(1) 24 | w.Chart(nk.ChartLines, 0, 100, lineValues) 25 | w.ChartColored(nk.ChartLines, nk.NkRgb(255, 0, 0), nk.NkRgb(150, 0, 0), 0, 100, line2Values) 26 | 27 | w.Chart(nk.ChartColumn, 0, 100, lineValues) 28 | w.ChartColored(nk.ChartColumn, nk.NkRgb(255, 0, 0), nk.NkRgb(150, 0, 0), 0, 100, line2Values) 29 | 30 | w.Row(25).Dynamic(1) 31 | w.Label("Mixed Charts", "LC") 32 | 33 | w.Row(100).Dynamic(1) 34 | w.ChartMixed([]gimu.ChartSeries{ 35 | gimu.ChartSeries{ 36 | ChartType: nk.ChartLines, 37 | Min: 0, 38 | Max: 100, 39 | Data: lineValues, 40 | Color: nk.NkRgb(0, 100, 0), 41 | ActiveColor: nk.NkRgb(0, 200, 0), 42 | }, 43 | gimu.ChartSeries{ 44 | ChartType: nk.ChartLines, 45 | Min: 0, 46 | Max: 100, 47 | Data: line2Values, 48 | Color: nk.NkRgb(0, 0, 100), 49 | ActiveColor: nk.NkRgb(0, 0, 200), 50 | }, 51 | gimu.ChartSeries{ 52 | ChartType: nk.ChartColumn, 53 | Min: 0, 54 | Max: 10, 55 | Data: line3Values, 56 | Color: nk.NkRgb(100, 0, 100), 57 | ActiveColor: nk.NkRgb(100, 0, 200), 58 | }, 59 | }) 60 | }) 61 | } 62 | 63 | func main() { 64 | runtime.LockOSThread() 65 | 66 | lineValues = make([]float32, 100) 67 | line2Values = make([]float32, 100) 68 | line3Values = make([]float32, 100) 69 | 70 | rand.Seed(42) 71 | for i := range lineValues { 72 | lineValues[i] = float32(rand.Intn(100)) 73 | line2Values[i] = float32(rand.Intn(100)) 74 | line3Values[i] = float32(rand.Intn(10)) 75 | } 76 | 77 | wnd := gimu.NewMasterWindow("Chart Demo", 800, 600, gimu.MasterWindowFlagNoResize) 78 | wnd.Main(builder) 79 | } 80 | -------------------------------------------------------------------------------- /util.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "image" 5 | "image/color" 6 | "image/draw" 7 | "unsafe" 8 | 9 | "github.com/AllenDang/gimu/nk" 10 | ) 11 | 12 | func toNkFlag(align string) nk.Flags { 13 | var a nk.Flags 14 | switch align { 15 | case "RT": 16 | a = nk.TextAlignRight | nk.TextAlignTop 17 | case "RC": 18 | a = nk.TextAlignRight | nk.TextAlignMiddle 19 | case "RB": 20 | a = nk.TextAlignRight | nk.TextAlignBottom 21 | case "CT": 22 | a = nk.TextAlignCentered | nk.TextAlignTop 23 | case "CC": 24 | a = nk.TextAlignCentered | nk.TextAlignMiddle 25 | case "CB": 26 | a = nk.TextAlignCentered | nk.TextAlignBottom 27 | case "LT": 28 | a = nk.TextAlignLeft | nk.TextAlignTop 29 | case "LB": 30 | a = nk.TextAlignLeft | nk.TextAlignBottom 31 | case "LC": 32 | a = nk.TextAlignLeft | nk.TextAlignMiddle 33 | default: 34 | a = nk.TextAlignLeft | nk.TextAlignMiddle 35 | } 36 | 37 | return a 38 | } 39 | 40 | func toNkColor(c color.RGBA) nk.Color { 41 | nc := nk.NewColor() 42 | nc.SetRGBA(nk.Byte(c.R), nk.Byte(c.G), nk.Byte(c.B), nk.Byte(c.A)) 43 | return *nc 44 | } 45 | 46 | func toNkRune(r rune) nk.Rune { 47 | return *(*nk.Rune)(unsafe.Pointer(&r)) 48 | } 49 | 50 | func toGoRune(r nk.Rune) rune { 51 | return *(*rune)(unsafe.Pointer(&r)) 52 | } 53 | 54 | func toNkPluginFilter(f EditFilter) func(*nk.TextEdit, nk.Rune) int32 { 55 | return func(nt *nk.TextEdit, r nk.Rune) int32 { 56 | result := f(toGoRune(r)) 57 | if result { 58 | return 1 59 | } 60 | return 0 61 | } 62 | } 63 | 64 | func toInt32(b bool) int32 { 65 | if b { 66 | return 1 67 | } 68 | return 0 69 | } 70 | 71 | func getDynamicWidth(ctx *nk.Context) float32 { 72 | bounds := nk.NkLayoutWidgetBounds(ctx) 73 | padding := ctx.Style().Window().Padding().X() 74 | return bounds.W() - (padding * 2) 75 | } 76 | 77 | func ImgToRgba(img image.Image) *image.RGBA { 78 | switch trueim := img.(type) { 79 | case *image.RGBA: 80 | return trueim 81 | default: 82 | copy := image.NewRGBA(trueim.Bounds()) 83 | draw.Draw(copy, trueim.Bounds(), trueim, image.Pt(0, 0), draw.Src) 84 | return copy 85 | } 86 | } 87 | 88 | type Texture struct { 89 | image nk.Image 90 | } 91 | 92 | func RgbaToTexture(rgba *image.RGBA) *Texture { 93 | var textureId uint32 94 | return &Texture{ 95 | image: nk.RgbaToNkImage(&textureId, rgba), 96 | } 97 | } 98 | 99 | func LoadDefaultFont() *nk.Font { 100 | atlas := nk.NewFontAtlas() 101 | nk.NkFontStashBegin(&atlas) 102 | nk.NkFontStashEnd() 103 | 104 | return atlas.DefaultFont() 105 | } 106 | 107 | func LoadFontFromFile(filePath string, size float32, config *nk.FontConfig) *nk.Font { 108 | atlas := nk.NewFontAtlas() 109 | nk.NkFontStashBegin(&atlas) 110 | f := nk.NkFontAtlasAddFromFile(atlas, filePath, size, config) 111 | nk.NkFontStashEnd() 112 | 113 | return f 114 | } 115 | 116 | func SetFont(ctx *nk.Context, font *nk.Font) { 117 | nk.NkStyleSetFont(ctx, font.Handle()) 118 | } 119 | -------------------------------------------------------------------------------- /masterwindow.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "image/color" 5 | "log" 6 | "time" 7 | 8 | "github.com/AllenDang/gimu/nk" 9 | "github.com/go-gl/gl/v3.2-core/gl" 10 | "github.com/go-gl/glfw/v3.3/glfw" 11 | ) 12 | 13 | type BuilderFunc func(w *Window) 14 | 15 | // Master window flag 16 | type MasterWindowFlag int 17 | 18 | const ( 19 | // MasterWindowFlagNoResize - Create an not resizable window 20 | MasterWindowFlagDefault MasterWindowFlag = iota 21 | MasterWindowFlagNoResize 22 | ) 23 | 24 | func (this MasterWindowFlag) HasFlag(flag MasterWindowFlag) bool { 25 | return this|flag == this 26 | } 27 | 28 | // Master window 29 | type MasterWindow struct { 30 | win *glfw.Window 31 | ctx *nk.Context 32 | maxVertexBuffer int 33 | maxElementBuffer int 34 | bgColor nk.Color 35 | defaultFont *nk.Font 36 | } 37 | 38 | func NewMasterWindow(title string, width, height int, flags MasterWindowFlag) *MasterWindow { 39 | if err := glfw.Init(); err != nil { 40 | log.Fatalln(err) 41 | } 42 | glfw.WindowHint(glfw.ContextVersionMajor, 3) 43 | glfw.WindowHint(glfw.ContextVersionMinor, 3) 44 | glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) 45 | glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) 46 | 47 | if flags.HasFlag(MasterWindowFlagNoResize) { 48 | glfw.WindowHint(glfw.Resizable, glfw.False) 49 | } 50 | 51 | win, err := glfw.CreateWindow(width, height, title, nil, nil) 52 | if err != nil { 53 | log.Fatalln(err) 54 | } 55 | win.MakeContextCurrent() 56 | 57 | if err := gl.Init(); err != nil { 58 | log.Fatalln("OpenGL init failed:", err) 59 | } 60 | gl.Viewport(0, 0, int32(width), int32(height)) 61 | 62 | ctx := nk.NkPlatformInit(win, nk.PlatformInstallCallbacks) 63 | 64 | return &MasterWindow{ 65 | win: win, 66 | ctx: ctx, 67 | maxVertexBuffer: 512 * 1024, 68 | maxElementBuffer: 128 * 1024, 69 | bgColor: nk.NkRgba(28, 48, 62, 255), 70 | } 71 | } 72 | 73 | func (w *MasterWindow) GetSize() (width, height int) { 74 | gw, gh := w.win.GetSize() 75 | return gw, gh 76 | } 77 | 78 | func (w *MasterWindow) SetBgColor(color color.RGBA) { 79 | w.bgColor = toNkColor(color) 80 | } 81 | 82 | func (w *MasterWindow) SetTitle(title string) { 83 | w.win.SetTitle(title) 84 | } 85 | 86 | func (w *MasterWindow) GetContext() *nk.Context { 87 | return w.ctx 88 | } 89 | 90 | func (w *MasterWindow) GetDefaultFont() *nk.Font { 91 | return w.defaultFont 92 | } 93 | 94 | func (w *MasterWindow) Main(builder BuilderFunc) { 95 | // Load default font 96 | w.defaultFont = LoadDefaultFont() 97 | w.GetContext().SetStyle(nk.THEME_DARK) 98 | 99 | window := Window{ 100 | ctx: w.ctx, 101 | mw: w, 102 | } 103 | 104 | for !w.win.ShouldClose() { 105 | glfw.PollEvents() 106 | nk.NkPlatformNewFrame() 107 | 108 | builder(&window) 109 | 110 | // Render 111 | bg := make([]float32, 4) 112 | nk.NkColorFv(bg, w.bgColor) 113 | width, height := w.GetSize() 114 | gl.Viewport(0, 0, int32(width), int32(height)) 115 | gl.Clear(gl.COLOR_BUFFER_BIT) 116 | gl.ClearColor(bg[0], bg[1], bg[2], bg[3]) 117 | nk.NkPlatformRender(nk.AntiAliasingOn, w.maxVertexBuffer, w.maxElementBuffer) 118 | w.win.SwapBuffers() 119 | 120 | // 30 FPS 121 | time.Sleep(time.Second / 30) 122 | } 123 | 124 | nk.NkPlatformShutdown() 125 | glfw.Terminate() 126 | } 127 | -------------------------------------------------------------------------------- /nk/draw.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #include "nuklear.h" 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "image" 10 | "unsafe" 11 | 12 | "github.com/go-gl/gl/v3.2-core/gl" 13 | ) 14 | 15 | var VertexLayoutEnd = DrawVertexLayoutElement{ 16 | Attribute: VertexAttributeCount, 17 | Format: FormatCount, 18 | Offset: 0, 19 | } 20 | 21 | func NkDrawForeach(ctx *Context, b *Buffer, fn func(cmd *DrawCommand)) { 22 | cmd := Nk_DrawBegin(ctx, b) 23 | for { 24 | if cmd == nil { 25 | break 26 | } 27 | fn(cmd) 28 | cmd = Nk_DrawNext(cmd, b, ctx) 29 | } 30 | } 31 | 32 | func (h Handle) ID() int { 33 | return int(*(*int64)(unsafe.Pointer(&h))) 34 | } 35 | 36 | func (h Handle) Ptr() uintptr { 37 | return *(*uintptr)(unsafe.Pointer(&h)) 38 | } 39 | 40 | func (c Color) R() Byte { 41 | return Byte(c.r) 42 | } 43 | 44 | func (c Color) G() Byte { 45 | return Byte(c.g) 46 | } 47 | 48 | func (c Color) B() Byte { 49 | return Byte(c.b) 50 | } 51 | 52 | func (c Color) A() Byte { 53 | return Byte(c.a) 54 | } 55 | 56 | func (c Color) RGBA() (Byte, Byte, Byte, Byte) { 57 | return Byte(c.r), Byte(c.g), Byte(c.b), Byte(c.a) 58 | } 59 | 60 | func (c Color) RGBAi() (int32, int32, int32, int32) { 61 | return int32(c.r), int32(c.g), int32(c.b), int32(c.a) 62 | } 63 | 64 | func (c *Color) SetR(r Byte) { 65 | c.r = (C.nk_byte)(r) 66 | } 67 | 68 | func (c *Color) SetG(g Byte) { 69 | c.g = (C.nk_byte)(g) 70 | } 71 | 72 | func (c *Color) SetB(b Byte) { 73 | c.b = (C.nk_byte)(b) 74 | } 75 | 76 | func (c *Color) SetA(a Byte) { 77 | c.a = (C.nk_byte)(a) 78 | } 79 | 80 | func (c *Color) SetRGBA(r, g, b, a Byte) { 81 | c.r = (C.nk_byte)(r) 82 | c.g = (C.nk_byte)(g) 83 | c.b = (C.nk_byte)(b) 84 | c.a = (C.nk_byte)(a) 85 | } 86 | 87 | func (c *Color) SetRGBAi(r, g, b, a int32) { 88 | c.r = (C.nk_byte)(r) 89 | c.g = (C.nk_byte)(g) 90 | c.b = (C.nk_byte)(b) 91 | c.a = (C.nk_byte)(a) 92 | } 93 | 94 | func (cmd *DrawCommand) ElemCount() int { 95 | return (int)(cmd.elem_count) 96 | } 97 | 98 | func (cmd *DrawCommand) Texture() Handle { 99 | return (Handle)(cmd.texture) 100 | } 101 | 102 | func (cmd *DrawCommand) ClipRect() *Rect { 103 | return (*Rect)(&cmd.clip_rect) 104 | } 105 | 106 | func (r *Rect) X() float32 { 107 | return (float32)(r.x) 108 | } 109 | 110 | func (r *Rect) Y() float32 { 111 | return (float32)(r.y) 112 | } 113 | 114 | func (r *Rect) W() float32 { 115 | return (float32)(r.w) 116 | } 117 | 118 | func (r *Rect) H() float32 { 119 | return (float32)(r.h) 120 | } 121 | 122 | func (v *Vec2) X() float32 { 123 | return (float32)(v.x) 124 | } 125 | 126 | func (v *Vec2) Y() float32 { 127 | return (float32)(v.y) 128 | } 129 | 130 | func (v *Vec2) SetX(x float32) { 131 | v.x = (C.float)(x) 132 | } 133 | 134 | func (v *Vec2) SetY(y float32) { 135 | v.y = (C.float)(y) 136 | } 137 | 138 | func (v *Vec2) Reset() { 139 | v.x = 0 140 | v.y = 0 141 | } 142 | 143 | func RgbaToNkImage(tex *uint32, rgba *image.RGBA) Image { 144 | if tex == nil { 145 | gl.GenTextures(1, tex) 146 | } 147 | gl.BindTexture(gl.TEXTURE_2D, *tex) 148 | gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST) 149 | gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_NEAREST) 150 | gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) 151 | gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) 152 | gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, int32(rgba.Bounds().Dx()), int32(rgba.Bounds().Dy()), 153 | 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&rgba.Pix[0])) 154 | gl.GenerateMipmap(gl.TEXTURE_2D) 155 | return NkImageId(int32(*tex)) 156 | } 157 | -------------------------------------------------------------------------------- /nk.yml: -------------------------------------------------------------------------------- 1 | --- 2 | GENERATOR: 3 | PackageName: nk 4 | PackageDescription: "Package nk provides Go bindings for nuklear.h — a small ANSI C gui library." 5 | PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS." 6 | Includes: ["nk.h"] 7 | Options: 8 | SafeStrings: true 9 | StructAccessors: true 10 | 11 | PARSER: 12 | IncludePaths: ["/usr/include", "/usr/local/include"] 13 | SourcesPaths: ["nk/nuklear.h", "nk/nk.h"] 14 | Defines: 15 | NK_INCLUDE_FIXED_TYPES: 1 16 | NK_INCLUDE_STANDARD_IO: 1 17 | NK_INCLUDE_DEFAULT_ALLOCATOR: 1 18 | NK_INCLUDE_VERTEX_BUFFER_OUTPUT: 1 19 | NK_INCLUDE_FONT_BAKING: 1 20 | NK_INCLUDE_DEFAULT_FONT: 1 21 | NK_KEYSTATE_BASED_INPUT: 1 22 | 23 | TRANSLATOR: 24 | ConstRules: 25 | defines: expand 26 | enum: expand 27 | MemTips: 28 | - {target: "draw_begin$", self: raw} 29 | - {target: "draw_end$", self: raw} 30 | - {target: "item_getter$", self: raw} 31 | - {target: "value_getter$", self: raw} 32 | - {target: "_user", self: bind} 33 | - {target: "_draw_vertex_layout_element", self: bind} 34 | - {target: "_convert_config", self: bind} 35 | - {target: "nk_plugin_", self: bind} 36 | - {target: "nk_text_width_f", self: bind} 37 | - {target: "nk_query_font_glyph_f", self: bind} 38 | - {target: "nk_", self: raw} 39 | TypeTips: 40 | function: 41 | - {target: _(hsv|rgb)_bv$, tips: [plain,plain,plain,0]} 42 | - {target: _(hsv|rgb)a_bv$, tips: [plain,plain,plain,0]} 43 | - {target: _(hsv|rgb)_b$, tips: [plain,plain,plain,0]} 44 | - {target: _(hsv|rgb)a_b$, tips: [plain,plain,plain,0]} 45 | PtrTips: 46 | function: 47 | - {target: "_color_fv$", tips: [arr,0]} 48 | - {target: "_color_dv$", tips: [arr,0]} 49 | - {target: "_color_hex_rgba$", tips: [arr,0]} 50 | - {target: "_color_hex_rgb$", tips: [arr,0]} 51 | - {target: "_color_hsv_iv$", tips: [arr,0]} 52 | - {target: "_color_hsv_bv$", tips: [arr,0]} 53 | - {target: "_color_hsv_fv$", tips: [arr,0]} 54 | - {target: "_color_hsva_iv$", tips: [arr,0]} 55 | - {target: "_color_hsva_bv$", tips: [arr,0]} 56 | - {target: "_color_hsva_fv$", tips: [arr,0]} 57 | - {target: "_edit_string$", tips: [ref,0,arr,ref,0,0]} 58 | - {target: "_edit_string_zero_terminated$", tips: [ref,0,arr,0,0]} 59 | - {target: "_font_atlas_add_from_memory$", tips: [ref,ref,size,0,ref]} 60 | - {target: "_convert$", tips: [ref,ref,ref,ref,ref]} 61 | - {target: "^nk_style_from_table$", tips: [sref,arr]} 62 | - {target: "^nk_stroke_polygon$", tips: [sref,arr,size,0,0]} 63 | - {target: "^nk_stroke_polyline$", tips: [sref,arr,size,0,0]} 64 | - {target: "^nk_fill_polygon$", tips: [sref,arr,size,0,0]} 65 | - {target: "^nk_draw_text$", tips: [sref,0,0,0,sref,sref,sref]} 66 | - {target: "nk_", tips: [sref,sref,sref,sref]} # defaults 67 | Rules: 68 | global: 69 | - {transform: lower} 70 | - {action: accept, from: "^nk_"} 71 | - {transform: export} 72 | const: 73 | - {action: accept, from: "(?i)^nk_"} 74 | - {action: replace, from: "(?i)^nk_", to: _} 75 | 76 | - {action: ignore, from: _INT8} 77 | - {action: ignore, from: _UINT8} 78 | - {action: ignore, from: _INT16} 79 | - {action: ignore, from: _UINT16} 80 | - {action: ignore, from: _INT32} 81 | - {action: ignore, from: _UINT32} 82 | - {action: ignore, from: _SIZE_TYPE} 83 | - {action: ignore, from: _POINTER_TYPE} 84 | - {action: ignore, from: _API} 85 | - {action: ignore, from: _INTERN} 86 | - {action: ignore, from: _STORAGE} 87 | - {action: ignore, from: _GLOBAL} 88 | - {action: ignore, from: _VERTEX_LAYOUT_END} 89 | 90 | - {action: replace, from: ^_command_, to: _command_type_} 91 | - {action: replace, from: "_rgb$", to: _color_format_RGB} 92 | - {action: replace, from: "_rgba$", to: _color_format_RGBA} 93 | function: 94 | # - {action: ignore, from: "(?i)nk_str"} 95 | - {action: ignore, from: "_plot_function$"} 96 | - {action: ignore, from: "_combo_callback$"} 97 | - {action: ignore, from: "_combobox_callback$"} 98 | - {action: ignore, from: "_input_glyph$"} 99 | - {action: ignore, from: "_draw_list_clear$"} 100 | type: 101 | - {action: replace, from: "^Nk_", to: _} 102 | - {action: replace, from: "_t$"} 103 | private: 104 | - {transform: unexport} 105 | post-global: 106 | - {action: replace, from: _$} 107 | - {load: snakecase} 108 | -------------------------------------------------------------------------------- /nk/theme.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | type Theme int 4 | 5 | const ( 6 | THEME_WHITE Theme = iota 7 | THEME_DARK 8 | THEME_RED 9 | THEME_BLUE 10 | ) 11 | 12 | func (ctx *Context) SetStyle(theme Theme) { 13 | table := make([]Color, ColorCount) 14 | 15 | switch theme { 16 | case THEME_WHITE: 17 | table[ColorText] = NkRgba(70, 70, 70, 255) 18 | table[ColorWindow] = NkRgba(175, 175, 175, 255) 19 | table[ColorHeader] = NkRgba(175, 175, 175, 255) 20 | table[ColorBorder] = NkRgba(0, 0, 0, 255) 21 | table[ColorButton] = NkRgba(185, 185, 185, 255) 22 | table[ColorButtonHover] = NkRgba(170, 170, 170, 255) 23 | table[ColorButtonActive] = NkRgba(160, 160, 160, 255) 24 | table[ColorToggle] = NkRgba(150, 150, 150, 255) 25 | table[ColorToggleHover] = NkRgba(120, 120, 120, 255) 26 | table[ColorToggleCursor] = NkRgba(175, 175, 175, 255) 27 | table[ColorSelect] = NkRgba(190, 190, 190, 255) 28 | table[ColorSelectActive] = NkRgba(175, 175, 175, 255) 29 | table[ColorSlider] = NkRgba(190, 190, 190, 255) 30 | table[ColorSliderCursor] = NkRgba(80, 80, 80, 255) 31 | table[ColorSliderCursorHover] = NkRgba(70, 70, 70, 255) 32 | table[ColorSliderCursorActive] = NkRgba(60, 60, 60, 255) 33 | table[ColorProperty] = NkRgba(175, 175, 175, 255) 34 | table[ColorEdit] = NkRgba(150, 150, 150, 255) 35 | table[ColorEditCursor] = NkRgba(0, 0, 0, 255) 36 | table[ColorCombo] = NkRgba(175, 175, 175, 255) 37 | table[ColorChart] = NkRgba(160, 160, 160, 255) 38 | table[ColorChartColor] = NkRgba(45, 45, 45, 255) 39 | table[ColorChartColorHighlight] = NkRgba(255, 0, 0, 255) 40 | table[ColorScrollbar] = NkRgba(180, 180, 180, 255) 41 | table[ColorScrollbarCursor] = NkRgba(140, 140, 140, 255) 42 | table[ColorScrollbarCursorHover] = NkRgba(150, 150, 150, 255) 43 | table[ColorScrollbarCursorActive] = NkRgba(160, 160, 160, 255) 44 | table[ColorTabHeader] = NkRgba(180, 180, 180, 255) 45 | NkStyleFromTable(ctx, table) 46 | case THEME_DARK: 47 | table[ColorText] = NkRgba(210, 210, 210, 255) 48 | table[ColorWindow] = NkRgba(57, 67, 71, 215) 49 | table[ColorHeader] = NkRgba(51, 51, 56, 220) 50 | table[ColorBorder] = NkRgba(46, 46, 46, 255) 51 | table[ColorButton] = NkRgba(48, 83, 111, 255) 52 | table[ColorButtonHover] = NkRgba(58, 93, 121, 255) 53 | table[ColorButtonActive] = NkRgba(63, 98, 126, 255) 54 | table[ColorToggle] = NkRgba(50, 58, 61, 255) 55 | table[ColorToggleHover] = NkRgba(45, 53, 56, 255) 56 | table[ColorToggleCursor] = NkRgba(48, 83, 111, 255) 57 | table[ColorSelect] = NkRgba(57, 67, 61, 255) 58 | table[ColorSelectActive] = NkRgba(48, 83, 111, 255) 59 | table[ColorSlider] = NkRgba(50, 58, 61, 255) 60 | table[ColorSliderCursor] = NkRgba(48, 83, 111, 245) 61 | table[ColorSliderCursorHover] = NkRgba(53, 88, 116, 255) 62 | table[ColorSliderCursorActive] = NkRgba(58, 93, 121, 255) 63 | table[ColorProperty] = NkRgba(50, 58, 61, 255) 64 | table[ColorEdit] = NkRgba(50, 58, 61, 225) 65 | table[ColorEditCursor] = NkRgba(210, 210, 210, 255) 66 | table[ColorCombo] = NkRgba(50, 58, 61, 255) 67 | table[ColorChart] = NkRgba(50, 58, 61, 255) 68 | table[ColorChartColor] = NkRgba(48, 83, 111, 255) 69 | table[ColorChartColorHighlight] = NkRgba(255, 0, 0, 255) 70 | table[ColorScrollbar] = NkRgba(50, 58, 61, 255) 71 | table[ColorScrollbarCursor] = NkRgba(48, 83, 111, 255) 72 | table[ColorScrollbarCursorHover] = NkRgba(53, 88, 116, 255) 73 | table[ColorScrollbarCursorActive] = NkRgba(58, 93, 121, 255) 74 | table[ColorTabHeader] = NkRgba(48, 83, 111, 255) 75 | NkStyleFromTable(ctx, table) 76 | case THEME_RED: 77 | table[ColorText] = NkRgba(190, 190, 190, 255) 78 | table[ColorWindow] = NkRgba(30, 33, 40, 215) 79 | table[ColorHeader] = NkRgba(181, 45, 69, 220) 80 | table[ColorBorder] = NkRgba(51, 55, 67, 255) 81 | table[ColorButton] = NkRgba(181, 45, 69, 255) 82 | table[ColorButtonHover] = NkRgba(190, 50, 70, 255) 83 | table[ColorButtonActive] = NkRgba(195, 55, 75, 255) 84 | table[ColorToggle] = NkRgba(51, 55, 67, 255) 85 | table[ColorToggleHover] = NkRgba(45, 60, 60, 255) 86 | table[ColorToggleCursor] = NkRgba(181, 45, 69, 255) 87 | table[ColorSelect] = NkRgba(51, 55, 67, 255) 88 | table[ColorSelectActive] = NkRgba(181, 45, 69, 255) 89 | table[ColorSlider] = NkRgba(51, 55, 67, 255) 90 | table[ColorSliderCursor] = NkRgba(181, 45, 69, 255) 91 | table[ColorSliderCursorHover] = NkRgba(186, 50, 74, 255) 92 | table[ColorSliderCursorActive] = NkRgba(191, 55, 79, 255) 93 | table[ColorProperty] = NkRgba(51, 55, 67, 255) 94 | table[ColorEdit] = NkRgba(51, 55, 67, 225) 95 | table[ColorEditCursor] = NkRgba(190, 190, 190, 255) 96 | table[ColorCombo] = NkRgba(51, 55, 67, 255) 97 | table[ColorChart] = NkRgba(51, 55, 67, 255) 98 | table[ColorChartColor] = NkRgba(170, 40, 60, 255) 99 | table[ColorChartColorHighlight] = NkRgba(255, 0, 0, 255) 100 | table[ColorScrollbar] = NkRgba(30, 33, 40, 255) 101 | table[ColorScrollbarCursor] = NkRgba(64, 84, 95, 255) 102 | table[ColorScrollbarCursorHover] = NkRgba(70, 90, 100, 255) 103 | table[ColorScrollbarCursorActive] = NkRgba(75, 95, 105, 255) 104 | table[ColorTabHeader] = NkRgba(181, 45, 69, 220) 105 | NkStyleFromTable(ctx, table) 106 | case THEME_BLUE: 107 | table[ColorText] = NkRgba(20, 20, 20, 255) 108 | table[ColorWindow] = NkRgba(202, 212, 214, 215) 109 | table[ColorHeader] = NkRgba(137, 182, 224, 220) 110 | table[ColorBorder] = NkRgba(140, 159, 173, 255) 111 | table[ColorButton] = NkRgba(137, 182, 224, 255) 112 | table[ColorButtonHover] = NkRgba(142, 187, 229, 255) 113 | table[ColorButtonActive] = NkRgba(147, 192, 234, 255) 114 | table[ColorToggle] = NkRgba(177, 210, 210, 255) 115 | table[ColorToggleHover] = NkRgba(182, 215, 215, 255) 116 | table[ColorToggleCursor] = NkRgba(137, 182, 224, 255) 117 | table[ColorSelect] = NkRgba(177, 210, 210, 255) 118 | table[ColorSelectActive] = NkRgba(137, 182, 224, 255) 119 | table[ColorSlider] = NkRgba(177, 210, 210, 255) 120 | table[ColorSliderCursor] = NkRgba(137, 182, 224, 245) 121 | table[ColorSliderCursorHover] = NkRgba(142, 188, 229, 255) 122 | table[ColorSliderCursorActive] = NkRgba(147, 193, 234, 255) 123 | table[ColorProperty] = NkRgba(210, 210, 210, 255) 124 | table[ColorEdit] = NkRgba(210, 210, 210, 225) 125 | table[ColorEditCursor] = NkRgba(20, 20, 20, 255) 126 | table[ColorCombo] = NkRgba(210, 210, 210, 255) 127 | table[ColorChart] = NkRgba(210, 210, 210, 255) 128 | table[ColorChartColor] = NkRgba(137, 182, 224, 255) 129 | table[ColorChartColorHighlight] = NkRgba(255, 0, 0, 255) 130 | table[ColorScrollbar] = NkRgba(190, 200, 200, 255) 131 | table[ColorScrollbarCursor] = NkRgba(64, 84, 95, 255) 132 | table[ColorScrollbarCursorHover] = NkRgba(70, 90, 100, 255) 133 | table[ColorScrollbarCursorActive] = NkRgba(75, 95, 105, 255) 134 | table[ColorTabHeader] = NkRgba(156, 193, 220, 255) 135 | NkStyleFromTable(ctx, table) 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /examples/simple/simple.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | "image/png" 7 | "log" 8 | "os" 9 | "runtime" 10 | 11 | "github.com/AllenDang/gimu" 12 | "github.com/AllenDang/gimu/nk" 13 | ) 14 | 15 | var ( 16 | textedit = gimu.NewTextEdit() 17 | selected int 18 | comboLabel string 19 | num1 uint = 11 20 | num2 uint = 33 21 | propertyInt int32 22 | propertyFloat float32 23 | checked bool 24 | option int = 1 25 | selected1 bool 26 | selected2 bool 27 | showPopup bool 28 | picture *gimu.Texture 29 | slider int32 = 33 30 | // customFont *nk.Font 31 | ) 32 | 33 | func msgbox(w *gimu.Window) { 34 | opened := w.Popup("Message", nk.PopupStatic, nk.WindowTitle|nk.WindowNoScrollbar|nk.WindowClosable, nk.NkRect(30, 10, 300, 100), func(w *gimu.Window) { 35 | w.Row(25).Dynamic(1) 36 | w.Label("Here is a pop up window", "LC") 37 | if w.Button("Close") { 38 | showPopup = false 39 | w.ClosePopup() 40 | } 41 | }) 42 | if !opened { 43 | showPopup = false 44 | } 45 | } 46 | 47 | func widgets(w *gimu.Window) { 48 | w.Row(25).Dynamic(1) 49 | w.Label("Hello world!", "LC") 50 | w.Label("Hello world!", "CC") 51 | w.Label("Hello world!", "RC") 52 | w.LabelColored("Colored label", color.RGBA{200, 100, 100, 255}, "LC") 53 | if w.Button("Click me to show a popup window") { 54 | showPopup = true 55 | } 56 | 57 | if showPopup { 58 | msgbox(w) 59 | } 60 | 61 | w.Label("Combobox", "LC") 62 | 63 | selected = w.ComboSimple([]string{"Item1", "Item2", "Item3"}, selected, 25, 0, 200) 64 | 65 | comboLabel = fmt.Sprintf("%d", num1+num2) 66 | w.ComboLabel(comboLabel, 0, 100, func(w *gimu.Window) { 67 | w.Row(25).Dynamic(1) 68 | w.Label("Drag progress bar to see the changes", "LC") 69 | 70 | w.Row(25).Static(0, 30) 71 | w.Progress(&num1, 100, true) 72 | w.Label(fmt.Sprintf("%d", num1), "CC") 73 | 74 | w.Progress(&num2, 100, true) 75 | w.Label(fmt.Sprintf("%d", num2), "CC") 76 | }) 77 | 78 | w.Label("Properties", "LC") 79 | w.PropertyInt("Age", 1, &propertyInt, 100, 10, 1) 80 | w.PropertyFloat("Height", 1, &propertyFloat, 10, 0.2, 1) 81 | 82 | w.Label("Slider", "LC") 83 | w.SliderInt(0, &slider, 100, 1) 84 | 85 | w.Label("Checkbox", "LC") 86 | w.Row(25).Static(0, 100) 87 | w.Checkbox("Check me", &checked) 88 | w.Label(fmt.Sprintf("%v", checked), "LC") 89 | 90 | w.Row(25).Dynamic(1) 91 | w.Label("Radio", "LC") 92 | w.Row(25).Dynamic(3) 93 | if op1 := w.Radio("Option 1", option == 1); op1 { 94 | option = 1 95 | } 96 | if op2 := w.Radio("Option 2", option == 2); op2 { 97 | option = 2 98 | } 99 | if op3 := w.Radio("Option 3", option == 3); op3 { 100 | option = 3 101 | } 102 | 103 | w.Row(25).Dynamic(1) 104 | w.Label("Selectable label", "LC") 105 | w.Row(25).Dynamic(2) 106 | w.SelectableLabel("Selectable 1", "LC", &selected1) 107 | w.SelectableLabel("Selectable 2", "LC", &selected2) 108 | w.SelectableSymbolLabel(nk.SymbolPlus, "Selectable Symbol 1", "RC", &selected1) 109 | w.SelectableSymbolLabel(nk.SymbolMinus, "Selectable Symbol 2", "RC", &selected2) 110 | 111 | w.Row(25).Static(0, 100) 112 | textedit.Edit(w, nk.EditField, gimu.EditFilterDefault) 113 | if w.Button("Print") { 114 | fmt.Println(textedit.GetString()) 115 | } 116 | } 117 | 118 | func updatefn(w *gimu.Window) { 119 | width, height := w.MasterWindow().GetSize() 120 | bounds := nk.NkRect(0, 0, float32(width), float32(height)) 121 | 122 | w.Window("Simple Demo", bounds, nk.WindowNoScrollbar, func(w *gimu.Window) { 123 | _, h := w.MasterWindow().GetSize() 124 | w.Row(int(h - 10)).Dynamic(2) 125 | w.Group("Group1", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 126 | widgets(w) 127 | }) 128 | w.Group("Group2", nk.WindowTitle|nk.WindowNoScrollbar, func(w *gimu.Window) { 129 | // Menu 130 | w.Menubar(func(w *gimu.Window) { 131 | w.Row(25).Static(60, 60) 132 | // Menu 1 133 | w.Menu("Menu1", "CC", 200, 100, func(w *gimu.Window) { 134 | w.Row(25).Dynamic(1) 135 | w.MenuItemLabel("Menu item 1", "LC") 136 | w.MenuItemLabel("Menu item 2", "LC") 137 | w.Button("Button inside menu") 138 | }) 139 | // Menu 2 140 | w.Menu("Menu2", "CC", 100, 100, func(w *gimu.Window) { 141 | w.Row(25).Dynamic(1) 142 | w.MenuItemLabel("Menu item 1", "LC") 143 | w.SliderInt(0, &slider, 100, 1) 144 | w.MenuItemLabel("Menu item 2", "LC") 145 | }) 146 | 147 | }) 148 | 149 | w.Row(int(float32(h-10)/3) - 9).Dynamic(1) 150 | 151 | w.Group("Group2-1", nk.WindowBorder, func(w *gimu.Window) { 152 | // Image 153 | w.Row(170).Static(300) 154 | if picture != nil { 155 | w.Image(picture) 156 | } 157 | 158 | // Tooltip 159 | w.Row(25).Dynamic(1) 160 | w.Tooltip("This is a tooltip") 161 | w.Button("Hover me to see tooltip") 162 | 163 | // Contextual menu 164 | w.Contextual(0, 100, 300, func(w *gimu.Window) { 165 | w.Row(25).Dynamic(1) 166 | w.ContextualLabel("Context menu 1", "LC") 167 | w.ContextualLabel("Context menu 1", "LC") 168 | w.SliderInt(0, &slider, 100, 1) 169 | }) 170 | w.Button("Right click me") 171 | 172 | // Custom font 173 | // gimu.SetFont(w.MasterWindow().GetContext(), customFont) 174 | // w.Label("你好啊!这是一行中文", "LC") 175 | // gimu.SetFont(w.MasterWindow().GetContext(), w.MasterWindow().GetDefaultFont()) 176 | 177 | }) 178 | 179 | w.Group("Group2-2", nk.WindowBorder, func(w *gimu.Window) { 180 | w.Tree(nk.TreeNode, "Tree node1", nk.Minimized, "Tree node1", 0, func(w *gimu.Window) { 181 | w.Row(25).Dynamic(1) 182 | w.Label("Label inside tree node", "LC") 183 | w.SliderInt(0, &slider, 100, 1) 184 | w.Label("Label inside tree node", "LC") 185 | w.Checkbox("Checkbox", &checked) 186 | }) 187 | w.Tree(nk.TreeNode, "Tree node2", nk.Maximized, "Tree node2", 0, func(w *gimu.Window) { 188 | w.Row(25).Dynamic(1) 189 | w.Label("Label inside tree node", "LC") 190 | w.Label("Label inside tree node", "LC") 191 | w.Label("Label inside tree node", "LC") 192 | w.Label("Label inside tree node", "LC") 193 | }) 194 | }) 195 | 196 | w.Group("Group2-3", nk.WindowBorder, func(w *gimu.Window) { 197 | w.Tree(nk.TreeTab, "Tree node21", nk.Maximized, "Tree node21", 0, func(w *gimu.Window) { 198 | w.Row(25).Dynamic(1) 199 | w.Label("Label inside tree node", "LC") 200 | w.SliderInt(0, &slider, 100, 1) 201 | w.Label("Label inside tree node", "LC") 202 | w.Checkbox("Checkbox", &checked) 203 | }) 204 | w.Tree(nk.TreeTab, "Tree node22", nk.Minimized, "Tree node22", 0, func(w *gimu.Window) { 205 | w.Row(25).Dynamic(1) 206 | w.Label("Label inside tree node", "LC") 207 | w.Label("Label inside tree node", "LC") 208 | w.Label("Label inside tree node", "LC") 209 | w.Label("Label inside tree node", "LC") 210 | }) 211 | }) 212 | }) 213 | 214 | }) 215 | } 216 | 217 | func main() { 218 | runtime.LockOSThread() 219 | 220 | // Create master window 221 | wnd := gimu.NewMasterWindow("Simple Demo", 1000, 800, gimu.MasterWindowFlagDefault) 222 | 223 | // Load font 224 | // config := nk.NkFontConfig(14) 225 | // config.SetOversample(1, 1) 226 | // config.SetRange(nk.NkFontChineseGlyphRanges()) 227 | // 228 | // customFont = gimu.LoadFontFromFile("/Library/Fonts/Microsoft/SimHei.ttf", 14, &config) 229 | 230 | // Load png image 231 | fn, err := os.Open("gopher.png") 232 | if err != nil { 233 | log.Fatal(err) 234 | } 235 | defer fn.Close() 236 | 237 | img, err := png.Decode(fn) 238 | if err != nil { 239 | log.Fatal(err) 240 | } 241 | if img != nil { 242 | rgba := gimu.ImgToRgba(img) 243 | picture = gimu.RgbaToTexture(rgba) 244 | } 245 | 246 | wnd.Main(updatefn) 247 | } 248 | -------------------------------------------------------------------------------- /nk/impl_glfw_common.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #cgo CFLAGS: -DNK_INCLUDE_FIXED_TYPES -DNK_INCLUDE_STANDARD_IO -DNK_INCLUDE_DEFAULT_ALLOCATOR -DNK_INCLUDE_FONT_BAKING -DNK_INCLUDE_DEFAULT_FONT -DNK_INCLUDE_VERTEX_BUFFER_OUTPUT -Wno-implicit-function-declaration 5 | #cgo windows LDFLAGS: -Wl,--allow-multiple-definition 6 | #include 7 | 8 | #include "nuklear.h" 9 | */ 10 | import "C" 11 | import ( 12 | "unsafe" 13 | 14 | "github.com/go-gl/glfw/v3.3/glfw" 15 | ) 16 | 17 | type PlatformInitOption int 18 | 19 | const ( 20 | PlatformDefault PlatformInitOption = iota 21 | PlatformInstallCallbacks 22 | ) 23 | 24 | type NkGLFWClipbard struct { 25 | window *glfw.Window 26 | } 27 | 28 | func NewGLFWClipboard(w *glfw.Window) *NkGLFWClipbard { 29 | return &NkGLFWClipbard{w} 30 | } 31 | 32 | func (c *NkGLFWClipbard) SetText(content string) { 33 | c.window.SetClipboardString(content) 34 | } 35 | 36 | func (c *NkGLFWClipbard) GetText() string { 37 | str := c.window.GetClipboardString() 38 | return str 39 | } 40 | 41 | func NkPlatformInit(win *glfw.Window, opt PlatformInitOption) *Context { 42 | state.win = win 43 | if opt == PlatformInstallCallbacks { 44 | win.SetScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) { 45 | state.scroll.SetX(state.scroll.X() + float32(xoff)) 46 | state.scroll.SetY(state.scroll.Y() + float32(yoff)) 47 | }) 48 | win.SetCharCallback(func(w *glfw.Window, char rune) { 49 | if len(state.text) < 256 { // NK_GLFW_TEXT_MAX 50 | state.text += string(char) 51 | } 52 | }) 53 | win.SetMouseButtonCallback(func(w *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) { 54 | if button != glfw.MouseButtonLeft { 55 | return 56 | } 57 | x, y := w.GetCursorPos() 58 | if action == glfw.Press { 59 | dt := glfw.GetTime() - lastButtonClickTime 60 | if dt > doubleClickLO && dt < doubleClickHI { 61 | isDoubleClickDown = 1 62 | doubleClickPos.SetX(float32(x)) 63 | doubleClickPos.SetY(float32(y)) 64 | } 65 | lastButtonClickTime = glfw.GetTime() 66 | } else { 67 | isDoubleClickDown = 0 68 | } 69 | }) 70 | } 71 | 72 | state.ctx = NewContext() 73 | NkInitDefault(state.ctx, nil) 74 | deviceCreate() 75 | 76 | state.ctx.SetClipboard(NewGLFWClipboard(win)) 77 | 78 | return state.ctx 79 | } 80 | 81 | func NkPlatformShutdown() { 82 | NkFontAtlasClear(state.atlas) 83 | NkFree(state.ctx) 84 | deviceDestroy() 85 | state = nil 86 | } 87 | 88 | func NkFontStashBegin(atlas **FontAtlas) { 89 | state.atlas = NewFontAtlas() 90 | NkFontAtlasInitDefault(state.atlas) 91 | NkFontAtlasBegin(state.atlas) 92 | *atlas = state.atlas 93 | } 94 | 95 | func NkFontStashEnd() { 96 | var width, height int32 97 | image := NkFontAtlasBake(state.atlas, &width, &height, FontAtlasRgba32) 98 | deviceUploadAtlas(image, width, height) 99 | NkFontAtlasEnd(state.atlas, NkHandleId(int32(state.ogl.font_tex)), &state.ogl.null) 100 | if font := state.atlas.DefaultFont(); font != nil { 101 | NkStyleSetFont(state.ctx, font.Handle()) 102 | } 103 | } 104 | 105 | func NkPlatformNewFrame() { 106 | win := state.win 107 | ctx := state.ctx 108 | state.width, state.height = win.GetSize() 109 | state.display_width, state.display_height = win.GetFramebufferSize() 110 | state.fbScaleX = float32(state.display_width) / float32(state.width) 111 | state.fbScaleY = float32(state.display_height) / float32(state.height) 112 | 113 | NkInputBegin(ctx) 114 | for _, r := range state.text { 115 | NkInputUnicode(ctx, Rune(r)) 116 | } 117 | 118 | // optional grabbing behavior 119 | m := ctx.Input().Mouse() 120 | if m.Grab() { 121 | win.SetInputMode(glfw.CursorMode, glfw.CursorHidden) 122 | } else if m.Ungrab() { 123 | win.SetInputMode(glfw.CursorMode, glfw.CursorNormal) 124 | } 125 | 126 | NkInputKey(ctx, KeyDel, keyPressed(win, glfw.KeyDelete)) 127 | NkInputKey(ctx, KeyEnter, keyPressed(win, glfw.KeyEnter)) 128 | NkInputKey(ctx, KeyTab, keyPressed(win, glfw.KeyTab)) 129 | NkInputKey(ctx, KeyBackspace, keyPressed(win, glfw.KeyBackspace)) 130 | NkInputKey(ctx, KeyUp, keyPressed(win, glfw.KeyUp)) 131 | NkInputKey(ctx, KeyDown, keyPressed(win, glfw.KeyDown)) 132 | NkInputKey(ctx, KeyTextStart, keyPressed(win, glfw.KeyHome)) 133 | NkInputKey(ctx, KeyTextEnd, keyPressed(win, glfw.KeyEnd)) 134 | NkInputKey(ctx, KeyScrollStart, keyPressed(win, glfw.KeyHome)) 135 | NkInputKey(ctx, KeyScrollEnd, keyPressed(win, glfw.KeyEnd)) 136 | NkInputKey(ctx, KeyScrollUp, keyPressed(win, glfw.KeyPageUp)) 137 | NkInputKey(ctx, KeyScrollDown, keyPressed(win, glfw.KeyPageDown)) 138 | NkInputKey(ctx, KeyShift, keysPressed(win, glfw.KeyLeftShift, glfw.KeyRightShift)) 139 | if keysPressed(win, glfw.KeyLeftControl, glfw.KeyRightControl, glfw.KeyLeftSuper, glfw.KeyRightSuper) > 0 { 140 | NkInputKey(ctx, KeyCopy, keyPressed(win, glfw.KeyC)) 141 | NkInputKey(ctx, KeyPaste, keyPressed(win, glfw.KeyV)) 142 | NkInputKey(ctx, KeyCut, keyPressed(win, glfw.KeyX)) 143 | NkInputKey(ctx, KeyTextUndo, keyPressed(win, glfw.KeyZ)) 144 | NkInputKey(ctx, KeyTextRedo, keyPressed(win, glfw.KeyR)) 145 | NkInputKey(ctx, KeyTextWordLeft, keyPressed(win, glfw.KeyLeft)) 146 | NkInputKey(ctx, KeyTextWordRight, keyPressed(win, glfw.KeyRight)) 147 | NkInputKey(ctx, KeyTextLineStart, keyPressed(win, glfw.KeyB)) 148 | NkInputKey(ctx, KeyTextLineEnd, keyPressed(win, glfw.KeyE)) 149 | NkInputKey(ctx, KeyTextSelectAll, keyPressed(win, glfw.KeyA)) 150 | } else { 151 | NkInputKey(ctx, KeyLeft, keyPressed(win, glfw.KeyLeft)) 152 | NkInputKey(ctx, KeyRight, keyPressed(win, glfw.KeyRight)) 153 | NkInputKey(ctx, KeyCopy, 0) 154 | NkInputKey(ctx, KeyPaste, 0) 155 | NkInputKey(ctx, KeyCut, 0) 156 | NkInputKey(ctx, KeyShift, 0) 157 | } 158 | x, y := win.GetCursorPos() 159 | NkInputMotion(ctx, int32(x), int32(y)) 160 | if m := ctx.Input().Mouse(); m.Grabbed() { 161 | prevX, prevY := m.Prev() 162 | win.SetCursorPos(float64(prevX), float64(prevY)) 163 | m.SetPos(prevX, prevY) 164 | } 165 | 166 | NkInputButton(ctx, ButtonLeft, int32(x), int32(y), buttonPressed(win, glfw.MouseButtonLeft)) 167 | NkInputButton(ctx, ButtonMiddle, int32(x), int32(y), buttonPressed(win, glfw.MouseButtonMiddle)) 168 | NkInputButton(ctx, ButtonRight, int32(x), int32(y), buttonPressed(win, glfw.MouseButtonRight)) 169 | NkInputButton(ctx, ButtonDouble, int32(doubleClickPos.X()), int32(doubleClickPos.Y()), isDoubleClickDown) 170 | NkInputScroll(ctx, state.scroll) 171 | NkInputEnd(ctx) 172 | state.text = "" 173 | state.scroll.Reset() 174 | } 175 | 176 | var ( 177 | sizeofDrawIndex = unsafe.Sizeof(DrawIndex(0)) 178 | emptyVertex = platformVertex{} 179 | lastButtonClickTime float64 180 | isDoubleClickDown int32 181 | doubleClickPos Vec2 182 | ) 183 | 184 | type platformVertex struct { 185 | position [2]float32 186 | uv [2]float32 187 | col [4]Byte 188 | } 189 | 190 | const ( 191 | platformVertexSize = unsafe.Sizeof(platformVertex{}) 192 | platformVertexAlign = unsafe.Alignof(platformVertex{}) 193 | doubleClickLO = 0.02 194 | doubleClickHI = 0.2 195 | ) 196 | 197 | type platformState struct { 198 | win *glfw.Window 199 | 200 | width int 201 | height int 202 | display_width int 203 | display_height int 204 | 205 | ogl *platformDevice 206 | ctx *Context 207 | atlas *FontAtlas 208 | 209 | fbScaleX float32 210 | fbScaleY float32 211 | 212 | text string 213 | scroll Vec2 214 | } 215 | 216 | func NkPlatformDisplayHandle() *glfw.Window { 217 | if state != nil { 218 | return state.win 219 | } 220 | return nil 221 | } 222 | 223 | func keyPressed(win *glfw.Window, key glfw.Key) int32 { 224 | if win.GetKey(key) == glfw.Press { 225 | return 1 226 | } 227 | return 0 228 | } 229 | 230 | func buttonPressed(win *glfw.Window, button glfw.MouseButton) int32 { 231 | if win.GetMouseButton(button) == glfw.Press { 232 | return 1 233 | } 234 | return 0 235 | } 236 | 237 | func keysPressed(win *glfw.Window, keys ...glfw.Key) int32 { 238 | for i := range keys { 239 | if win.GetKey(keys[i]) == glfw.Press { 240 | return 1 241 | } 242 | } 243 | return 0 244 | } 245 | -------------------------------------------------------------------------------- /nk/impl_glfw_gl3.go: -------------------------------------------------------------------------------- 1 | package nk 2 | 3 | /* 4 | #cgo CFLAGS: -DNK_INCLUDE_FIXED_TYPES -DNK_INCLUDE_STANDARD_IO -DNK_INCLUDE_DEFAULT_ALLOCATOR -DNK_INCLUDE_FONT_BAKING -DNK_INCLUDE_DEFAULT_FONT -DNK_INCLUDE_VERTEX_BUFFER_OUTPUT -Wno-implicit-function-declaration 5 | #cgo windows LDFLAGS: -Wl,--allow-multiple-definition 6 | #include 7 | 8 | #define NK_IMPLEMENTATION 9 | #define NK_GLFW_GL3_IMPLEMENTATION 10 | 11 | #include "nuklear.h" 12 | */ 13 | import "C" 14 | import ( 15 | "fmt" 16 | "runtime" 17 | "unsafe" 18 | 19 | "github.com/go-gl/gl/v3.2-core/gl" 20 | ) 21 | 22 | func NkPlatformRender(aa AntiAliasing, maxVertexBuffer, maxElementBuffer int) { 23 | dev := state.ogl 24 | ortho := [4][4]float32{ 25 | {2.0, 0.0, 0.0, 0.0}, 26 | {0.0, -2.0, 0.0, 0.0}, 27 | {0.0, 0.0, -1.0, 0.0}, 28 | {-1.0, 1.0, 0.0, 1.0}, 29 | } 30 | ortho[0][0] /= float32(state.width) 31 | ortho[1][1] /= float32(state.height) 32 | 33 | // setup global state 34 | gl.Enable(gl.BLEND) 35 | gl.BlendEquation(gl.FUNC_ADD) 36 | gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) 37 | gl.Disable(gl.CULL_FACE) 38 | gl.Disable(gl.DEPTH_TEST) 39 | gl.Enable(gl.SCISSOR_TEST) 40 | gl.Enable(gl.TEXTURE_2D) 41 | gl.ActiveTexture(gl.TEXTURE0) 42 | 43 | // setup program 44 | gl.UseProgram(dev.prog) 45 | gl.Uniform1i(dev.uniform_tex, 0) 46 | gl.UniformMatrix4fv(dev.uniform_proj, 1, false, &ortho[0][0]) 47 | gl.Viewport(0, 0, int32(state.display_width), int32(state.display_height)) 48 | 49 | // convert from command queue into draw list and draw to screen 50 | { 51 | // allocate vertex and element buffer 52 | gl.BindVertexArray(dev.vao) 53 | gl.BindBuffer(gl.ARRAY_BUFFER, dev.vbo) 54 | gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, dev.ebo) 55 | 56 | gl.BufferData(gl.ARRAY_BUFFER, maxVertexBuffer, nil, gl.STREAM_DRAW) 57 | gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, maxElementBuffer, nil, gl.STREAM_DRAW) 58 | 59 | // load draw vertices & elements directly into vertex + element buffer 60 | vertices := gl.MapBuffer(gl.ARRAY_BUFFER, gl.WRITE_ONLY) 61 | elements := gl.MapBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.WRITE_ONLY) 62 | config := &ConvertConfig{ 63 | VertexLayout: []DrawVertexLayoutElement{ 64 | { 65 | Attribute: VertexPosition, 66 | Format: FormatFloat, 67 | Offset: Size(unsafe.Offsetof(emptyVertex.position)), 68 | }, { 69 | Attribute: VertexTexcoord, 70 | Format: FormatFloat, 71 | Offset: Size(unsafe.Offsetof(emptyVertex.uv)), 72 | }, { 73 | Attribute: VertexColor, 74 | Format: FormatR8g8b8a8, 75 | Offset: Size(unsafe.Offsetof(emptyVertex.col)), 76 | }, VertexLayoutEnd, 77 | }, 78 | VertexSize: Size(platformVertexSize), 79 | VertexAlignment: Size(platformVertexAlign), 80 | Null: dev.null, 81 | 82 | CircleSegmentCount: 22, 83 | CurveSegmentCount: 22, 84 | ArcSegmentCount: 22, 85 | 86 | GlobalAlpha: 1.0, 87 | ShapeAa: aa, 88 | LineAa: aa, 89 | } 90 | 91 | // setup buffers to load vertices and elements 92 | vbuf := NewBuffer() 93 | ebuf := NewBuffer() 94 | NkBufferInitFixed(vbuf, vertices, Size(maxVertexBuffer)) 95 | NkBufferInitFixed(ebuf, elements, Size(maxElementBuffer)) 96 | NkConvert(state.ctx, dev.cmds, vbuf, ebuf, config) 97 | // vbuf.Free() 98 | // ebuf.Free() 99 | // config.Free() 100 | 101 | gl.UnmapBuffer(gl.ARRAY_BUFFER) 102 | gl.UnmapBuffer(gl.ELEMENT_ARRAY_BUFFER) 103 | 104 | var offset uintptr 105 | 106 | // iterate over and execute each draw command 107 | NkDrawForeach(state.ctx, dev.cmds, func(cmd *DrawCommand) { 108 | elemCount := cmd.ElemCount() 109 | if elemCount == 0 { 110 | return 111 | } 112 | clipRect := cmd.ClipRect() 113 | gl.BindTexture(gl.TEXTURE_2D, uint32(cmd.Texture().ID())) 114 | gl.Scissor( 115 | int32(clipRect.X()*state.fbScaleX), 116 | int32(float32(state.height-int(clipRect.Y()+clipRect.H()))*state.fbScaleY), 117 | int32(clipRect.W()*state.fbScaleX), 118 | int32(clipRect.H()*state.fbScaleY), 119 | ) 120 | gl.DrawElements(gl.TRIANGLES, int32(elemCount), gl.UNSIGNED_SHORT, unsafe.Pointer(offset)) 121 | offset += uintptr(elemCount) * sizeofDrawIndex 122 | }) 123 | 124 | NkClear(state.ctx) 125 | } 126 | 127 | // default GL state 128 | gl.UseProgram(0) 129 | gl.BindBuffer(gl.ARRAY_BUFFER, 0) 130 | gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) 131 | gl.BindVertexArray(0) 132 | gl.Disable(gl.BLEND) 133 | gl.Disable(gl.SCISSOR_TEST) 134 | } 135 | 136 | func deviceCreate() { 137 | dev := state.ogl 138 | dev.cmds = NewBuffer() 139 | NkBufferInitDefault(dev.cmds) 140 | dev.prog = gl.CreateProgram() 141 | 142 | dev.vert_shdr = gl.CreateShader(gl.VERTEX_SHADER) 143 | dev.frag_shdr = gl.CreateShader(gl.FRAGMENT_SHADER) 144 | assignShader(dev.vert_shdr, vertexShader) 145 | assignShader(dev.frag_shdr, fragmentShader) 146 | 147 | var status int32 148 | gl.GetShaderiv(dev.vert_shdr, gl.COMPILE_STATUS, &status) 149 | if status != gl.TRUE { 150 | panic("vert_shdr failed to compile") 151 | } 152 | gl.GetShaderiv(dev.frag_shdr, gl.COMPILE_STATUS, &status) 153 | if status != gl.TRUE { 154 | panic("frag_shdr failed to compile") 155 | } 156 | gl.AttachShader(dev.prog, dev.vert_shdr) 157 | gl.AttachShader(dev.prog, dev.frag_shdr) 158 | gl.LinkProgram(dev.prog) 159 | gl.GetProgramiv(dev.prog, gl.LINK_STATUS, &status) 160 | if status != gl.TRUE { 161 | panic("gl program failed to link") 162 | } 163 | dev.uniform_tex = gl.GetUniformLocation(dev.prog, gl.Str("Texture\x00")) 164 | dev.uniform_proj = gl.GetUniformLocation(dev.prog, gl.Str("ProjMtx\x00")) 165 | dev.attrib_pos = uint32(gl.GetAttribLocation(dev.prog, gl.Str("Position\x00"))) 166 | dev.attrib_uv = uint32(gl.GetAttribLocation(dev.prog, gl.Str("TexCoord\x00"))) 167 | dev.attrib_col = uint32(gl.GetAttribLocation(dev.prog, gl.Str("Color\x00"))) 168 | 169 | { 170 | // buffer setup 171 | vs := int32(platformVertexSize) 172 | vp := unsafe.Offsetof(emptyVertex.position) 173 | vt := unsafe.Offsetof(emptyVertex.uv) 174 | vc := unsafe.Offsetof(emptyVertex.col) 175 | gl.GenBuffers(1, &dev.vbo) 176 | gl.GenBuffers(1, &dev.ebo) 177 | gl.GenVertexArrays(1, &dev.vao) 178 | 179 | gl.BindVertexArray(dev.vao) 180 | gl.BindBuffer(gl.ARRAY_BUFFER, dev.vbo) 181 | gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, dev.ebo) 182 | 183 | gl.EnableVertexAttribArray(dev.attrib_pos) 184 | gl.EnableVertexAttribArray(dev.attrib_uv) 185 | gl.EnableVertexAttribArray(dev.attrib_col) 186 | 187 | gl.VertexAttribPointer(dev.attrib_pos, 2, gl.FLOAT, false, vs, unsafe.Pointer(vp)) 188 | gl.VertexAttribPointer(dev.attrib_uv, 2, gl.FLOAT, false, vs, unsafe.Pointer(vt)) 189 | gl.VertexAttribPointer(dev.attrib_col, 4, gl.UNSIGNED_BYTE, true, vs, unsafe.Pointer(vc)) 190 | } 191 | 192 | gl.BindTexture(gl.TEXTURE_2D, 0) 193 | gl.BindBuffer(gl.ARRAY_BUFFER, 0) 194 | gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) 195 | gl.BindVertexArray(0) 196 | } 197 | 198 | func deviceUploadAtlas(image unsafe.Pointer, width, height int32) { 199 | dev := state.ogl 200 | gl.GenTextures(1, &dev.font_tex) 201 | gl.BindTexture(gl.TEXTURE_2D, dev.font_tex) 202 | gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) 203 | gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) 204 | gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, image) 205 | } 206 | 207 | func deviceDestroy() { 208 | dev := state.ogl 209 | gl.DetachShader(dev.prog, dev.vert_shdr) 210 | gl.DetachShader(dev.prog, dev.frag_shdr) 211 | gl.DeleteShader(dev.vert_shdr) 212 | gl.DeleteShader(dev.frag_shdr) 213 | gl.DeleteProgram(dev.prog) 214 | gl.DeleteTextures(1, &dev.font_tex) 215 | gl.DeleteBuffers(1, &dev.vbo) 216 | gl.DeleteBuffers(1, &dev.ebo) 217 | NkBufferFree(dev.cmds) 218 | } 219 | 220 | func assignShader(shaderHandle uint32, shaderSource string) { 221 | var header = "#version 300 es" 222 | if runtime.GOOS == "darwin" { 223 | header = "#version 150" 224 | } 225 | shader := fmt.Sprintf("%s\n%s\x00", header, shaderSource) 226 | shaderData, free := gl.Strs(shader) 227 | gl.ShaderSource(shaderHandle, 1, shaderData, nil) 228 | gl.CompileShader(shaderHandle) 229 | free() 230 | } 231 | 232 | var vertexShader = ` 233 | uniform mat4 ProjMtx; 234 | in vec2 Position; 235 | in vec2 TexCoord; 236 | in vec4 Color; 237 | out vec2 Frag_UV; 238 | out vec4 Frag_Color; 239 | 240 | void main() { 241 | Frag_UV = TexCoord; 242 | Frag_Color = Color; 243 | gl_Position = ProjMtx * vec4(Position.xy, 0, 1); 244 | }` 245 | 246 | var fragmentShader = ` 247 | precision mediump float; 248 | uniform sampler2D Texture; 249 | in vec2 Frag_UV; 250 | in vec4 Frag_Color; 251 | out vec4 Out_Color; 252 | 253 | void main(){ 254 | Out_Color = Frag_Color * texture(Texture, Frag_UV.st); 255 | }` 256 | 257 | var state = &platformState{ 258 | ogl: &platformDevice{}, 259 | } 260 | 261 | type platformDevice struct { 262 | cmds *Buffer 263 | null DrawNullTexture 264 | 265 | vbo, vao, ebo uint32 266 | prog uint32 267 | vert_shdr uint32 268 | frag_shdr uint32 269 | 270 | attrib_pos uint32 271 | attrib_uv uint32 272 | attrib_col uint32 273 | uniform_tex int32 274 | uniform_proj int32 275 | 276 | font_tex uint32 277 | } 278 | -------------------------------------------------------------------------------- /window.go: -------------------------------------------------------------------------------- 1 | package gimu 2 | 3 | import ( 4 | "fmt" 5 | "image/color" 6 | 7 | "github.com/AllenDang/gimu/nk" 8 | ) 9 | 10 | type Window struct { 11 | ctx *nk.Context 12 | mw *MasterWindow 13 | } 14 | 15 | func (w *Window) MasterWindow() *MasterWindow { 16 | return w.mw 17 | } 18 | 19 | func (w *Window) Window(title string, bounds nk.Rect, flags nk.Flags, builder BuilderFunc) { 20 | if nk.NkBegin(w.ctx, title, bounds, flags) > 0 { 21 | builder(w) 22 | nk.NkEnd(w.ctx) 23 | } 24 | } 25 | 26 | func (w *Window) Row(height int) *Row { 27 | return &Row{ 28 | win: w, 29 | ctx: w.ctx, 30 | height: height, 31 | } 32 | } 33 | 34 | func (w *Window) Push(rect nk.Rect) { 35 | nk.NkLayoutSpacePush(w.ctx, rect) 36 | } 37 | 38 | func (w *Window) Spacing(cols int) { 39 | nk.NkSpacing(w.ctx, int32(cols)) 40 | } 41 | 42 | func (w *Window) L(content string) { 43 | w.Label(content, "LC") 44 | } 45 | 46 | func (w *Window) Label(content string, align string) { 47 | nk.NkLabel(w.ctx, content, toNkFlag(align)) 48 | } 49 | 50 | func (w *Window) LabelColored(content string, textColor color.RGBA, align string) { 51 | nk.NkLabelColored(w.ctx, content, toNkFlag(align), toNkColor(textColor)) 52 | } 53 | 54 | func (w *Window) Button(content string) bool { 55 | return nk.NkButtonLabel(w.ctx, content) > 0 56 | } 57 | 58 | func (w *Window) ButtonColor(color nk.Color) bool { 59 | return nk.NkButtonColor(w.ctx, color) > 0 60 | } 61 | 62 | func (w *Window) ButtonImage(img nk.Image) bool { 63 | return nk.NkButtonImage(w.ctx, img) > 0 64 | } 65 | 66 | func (w *Window) ButtonImageLabel(img nk.Image, label, align string) bool { 67 | return nk.NkButtonImageLabel(w.ctx, img, label, toNkFlag(align)) > 0 68 | } 69 | 70 | func (w *Window) ButtonSymbol(symbol nk.SymbolType) bool { 71 | return nk.NkButtonSymbol(w.ctx, symbol) > 0 72 | } 73 | 74 | func (w *Window) ButtonSymbolLabel(symbol nk.SymbolType, label, align string) bool { 75 | return nk.NkButtonSymbolLabel(w.ctx, symbol, label, toNkFlag(align)) > 0 76 | } 77 | 78 | func (w *Window) Progress(current *uint, max uint, modifiable bool) { 79 | nk.NkProgress(w.ctx, (*nk.Size)(current), nk.Size(max), toInt32(modifiable)) 80 | } 81 | 82 | func (w *Window) ComboSimple(labels []string, selected int, itemHeight int, dropDownWidth, dropDownHeight float32) int { 83 | if dropDownWidth == 0 { 84 | dropDownWidth = getDynamicWidth(w.ctx) 85 | } 86 | return int(nk.NkCombo(w.ctx, labels, int32(len(labels)), int32(selected), int32(itemHeight), nk.NkVec2(dropDownWidth, dropDownHeight))) 87 | } 88 | 89 | func (w *Window) ComboLabel(label string, dropDownWidth, dropDownHeight float32, itemBuilder BuilderFunc) { 90 | if dropDownWidth == 0 { 91 | dropDownWidth = getDynamicWidth(w.ctx) 92 | } 93 | 94 | if nk.NkComboBeginLabel(w.ctx, label, nk.NkVec2(dropDownWidth, dropDownHeight)) > 0 { 95 | itemBuilder(w) 96 | nk.NkComboEnd(w.ctx) 97 | } 98 | } 99 | 100 | func (w *Window) PropertyInt(label string, min int, val *int32, max int, step int, incPerPixel float32) { 101 | nk.NkPropertyInt(w.ctx, label, int32(min), val, int32(max), int32(step), incPerPixel) 102 | } 103 | 104 | func (w *Window) PropertyFloat(label string, min float32, val *float32, max float32, step float32, incPerPixel float32) { 105 | nk.NkPropertyFloat(w.ctx, label, min, val, max, step, incPerPixel) 106 | } 107 | 108 | func (w *Window) Checkbox(label string, active *bool) { 109 | i := toInt32(*active) 110 | nk.NkCheckboxLabel(w.ctx, label, &i) 111 | *active = i > 0 112 | } 113 | 114 | func (w *Window) Radio(label string, active bool) bool { 115 | return nk.NkOptionLabel(w.ctx, label, toInt32(active)) > 0 116 | } 117 | 118 | func (w *Window) SelectableLabel(label string, align string, selected *bool) { 119 | i := toInt32(*selected) 120 | nk.NkSelectableLabel(w.ctx, label, toNkFlag(align), &i) 121 | *selected = i > 0 122 | } 123 | 124 | func (w *Window) SelectableSymbolLabel(symbol nk.SymbolType, label, align string, selected *bool) { 125 | i := make([]int32, 1) 126 | i[0] = toInt32(*selected) 127 | nk.NkSelectableSymbolLabel(w.ctx, symbol, label, toNkFlag(align), i) 128 | *selected = i[0] > 0 129 | } 130 | 131 | func (w *Window) Popup(title string, popupType nk.PopupType, flag nk.Flags, bounds nk.Rect, builder BuilderFunc) bool { 132 | result := nk.NkPopupBegin(w.ctx, popupType, title, flag, bounds) 133 | if result > 0 { 134 | builder(w) 135 | nk.NkPopupEnd(w.ctx) 136 | } 137 | 138 | return result > 0 139 | } 140 | 141 | func (w *Window) ClosePopup() { 142 | nk.NkPopupClose(w.ctx) 143 | } 144 | 145 | func (w *Window) Group(title string, flag nk.Flags, builder BuilderFunc) { 146 | if nk.NkGroupBegin(w.ctx, title, flag) > 0 { 147 | builder(w) 148 | nk.NkGroupEnd(w.ctx) 149 | } 150 | } 151 | 152 | func (w *Window) Image(texture *Texture) { 153 | nk.NkImage(w.ctx, texture.image) 154 | } 155 | 156 | func (w *Window) Menubar(builder BuilderFunc) { 157 | nk.NkMenubarBegin(w.ctx) 158 | builder(w) 159 | nk.NkMenubarEnd(w.ctx) 160 | } 161 | 162 | func (w *Window) Menu(label string, align string, width, height int, builder BuilderFunc) { 163 | if nk.NkMenuBeginLabel(w.ctx, label, toNkFlag(align), nk.NkVec2(float32(width), float32(height))) > 0 { 164 | builder(w) 165 | nk.NkMenuEnd(w.ctx) 166 | } 167 | } 168 | 169 | func (w *Window) MenuItemLabel(label, align string) bool { 170 | return nk.NkMenuItemLabel(w.ctx, label, toNkFlag(align)) > 0 171 | } 172 | 173 | func (w *Window) Tooltip(label string) { 174 | bounds := nk.NkWidgetBounds(w.ctx) 175 | if nk.NkInputIsMouseHoveringRect(w.ctx.Input(), bounds) > 0 { 176 | nk.NkTooltip(w.ctx, label) 177 | } 178 | } 179 | 180 | func (w *Window) GetCanvas() *Canvas { 181 | c := nk.NkWindowGetCanvas(w.ctx) 182 | return &Canvas{buffer: c} 183 | } 184 | 185 | func (w *Window) GetStyle() *nk.Style { 186 | return w.ctx.GetStyle() 187 | } 188 | 189 | func (w *Window) Contextual(flag nk.Flags, width, height int, builder BuilderFunc) { 190 | bounds := nk.NkWidgetBounds(w.ctx) 191 | if nk.NkContextualBegin(w.ctx, flag, nk.NkVec2(float32(width), float32(height)), bounds) > 0 { 192 | builder(w) 193 | nk.NkContextualEnd(w.ctx) 194 | } 195 | } 196 | 197 | func (w *Window) ContextualLabel(label, align string) bool { 198 | return nk.NkContextualItemLabel(w.ctx, label, toNkFlag(align)) > 0 199 | } 200 | 201 | func (w *Window) SliderInt(min int32, val *int32, max int32, step int32) { 202 | nk.NkSliderInt(w.ctx, min, val, max, step) 203 | } 204 | 205 | func (w *Window) SliderFloat(min float32, val *float32, max float32, step float32) { 206 | nk.NkSliderFloat(w.ctx, min, val, max, step) 207 | } 208 | 209 | func (w *Window) Tree(treeType nk.TreeType, title string, initialState nk.CollapseStates, hash string, seed int32, builder BuilderFunc) { 210 | if nk.NkTreePushHashed(w.ctx, treeType, title, initialState, hash, int32(len(hash)), seed) > 0 { 211 | builder(w) 212 | nk.NkTreePop(w.ctx) 213 | } 214 | } 215 | 216 | func (w *Window) WidgetBounds() nk.Rect { 217 | return nk.NkWidgetBounds(w.ctx) 218 | } 219 | 220 | func (w *Window) GetInput() *Input { 221 | return &Input{input: w.ctx.Input()} 222 | } 223 | 224 | type ListViewItemBuilder func(w *Window, i int, item interface{}) 225 | 226 | // Should only called in ListView to define the row layout. 227 | type RowLayoutFunc func(r *Row) 228 | 229 | func (w *Window) ListView(view *nk.ListView, id string, flags nk.Flags, rowHeight int, items []interface{}, rowLayoutFunc RowLayoutFunc, builder ListViewItemBuilder) { 230 | if nk.NkListViewBegin(w.ctx, view, id, flags, int32(rowHeight), int32(len(items))) > 0 { 231 | rowLayoutFunc(w.Row(rowHeight)) 232 | 233 | for i := 0; i < view.Count(); i++ { 234 | builder(w, i, items[view.Begin()+i]) 235 | } 236 | nk.NkListViewEnd(view) 237 | } 238 | } 239 | 240 | func (w *Window) Chart(chartType nk.ChartType, min, max float32, data []float32) { 241 | selected := -1 242 | 243 | if nk.NkChartBegin(w.ctx, chartType, int32(len(data)), min, max) > 0 { 244 | for i, d := range data { 245 | res := nk.NkChartPush(w.ctx, d) 246 | if res == nk.ChartHovering { 247 | selected = i 248 | } 249 | } 250 | nk.NkChartEnd(w.ctx) 251 | } 252 | 253 | // Show tooltip on mouse hovering 254 | if selected != -1 { 255 | nk.NkTooltip(w.ctx, fmt.Sprintf("%.2f", data[selected])) 256 | } 257 | } 258 | 259 | func (w *Window) ChartColored(chartType nk.ChartType, color, activeColor nk.Color, min, max float32, data []float32) { 260 | selected := -1 261 | if nk.NkChartBeginColored(w.ctx, chartType, color, activeColor, int32(len(data)), min, max) > 0 { 262 | for i, d := range data { 263 | res := nk.NkChartPush(w.ctx, d) 264 | if res == nk.ChartHovering { 265 | selected = i 266 | } 267 | } 268 | nk.NkChartEnd(w.ctx) 269 | } 270 | 271 | // Show tooltip on mouse hovering 272 | if selected != -1 { 273 | nk.NkTooltip(w.ctx, fmt.Sprintf("%.2f", data[selected])) 274 | } 275 | } 276 | 277 | type ChartSeries struct { 278 | ChartType nk.ChartType 279 | Min, Max float32 280 | Data []float32 281 | Color nk.Color 282 | ActiveColor nk.Color 283 | } 284 | 285 | func (w *Window) ChartMixed(series []ChartSeries) { 286 | if len(series) > 0 { 287 | first := series[0] 288 | if nk.NkChartBeginColored(w.ctx, first.ChartType, first.Color, first.ActiveColor, int32(len(first.Data)), first.Min, first.Max) > 0 { 289 | 290 | for i, s := range series { 291 | if i > 0 { 292 | nk.NkChartAddSlotColored(w.ctx, s.ChartType, s.Color, s.ActiveColor, int32(len(s.Data)), s.Min, s.Max) 293 | } 294 | } 295 | 296 | for i, s := range series { 297 | selected := -1 298 | for di, d := range s.Data { 299 | res := nk.NkChartPushSlot(w.ctx, d, int32(i)) 300 | if res == nk.ChartHovering { 301 | selected = di 302 | } 303 | } 304 | 305 | if selected != -1 { 306 | nk.NkTooltip(w.ctx, fmt.Sprintf("%.2f", s.Data[selected])) 307 | } 308 | } 309 | 310 | nk.NkChartEnd(w.ctx) 311 | } 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gimu 2 | 3 | Strongly suggest NOT to use this project anymore, the auto-generated cgo wrapper of Nuklear has a random crash issue which is hard to fix (because cgo doesn't provide detail information about where the crash exactly happened). 4 | 5 | Please consider to use [giu](https://github.com/AllenDang/giu) instead. It's very stable and actively developed. 6 | 7 | Cross-platform GUI for go based on nuklear. 8 | 9 | Package nk provides Go bindings for nuklear.h — a small ANSI C gui library. See [github.com/Immediate-Mode-UI/Nuklear](https://github.com/Immediate-Mode-UI/Nuklear). 10 | 11 | All the binding code has automatically been generated with rules defined in [nk.yml](/nk.yml). 12 | 13 | This package provides a go-style idiomatic wrapper for nuklear. 14 | 15 | ## Screenshots 16 | 17 | Simple demo screen shots 18 | 19 | Chart demo screen shots 20 | 21 | ## Overview 22 | 23 | Supported platforms are: 24 | 25 | * Windows 32-bit 26 | * Windows 64-bit 27 | * OS X 28 | * Linux 29 | 30 | The desktop support is achieved using [GLFW](https://github.com/go-gl/glfw) and there are backends written in Go for OpenGL 3.2. 31 | 32 | ### Installation 33 | 34 | Just go get it and everythings ready to work. 35 | 36 | ``` 37 | go get -u github.com/AllenDang/gimu 38 | ``` 39 | 40 | ### Getting start 41 | 42 | Let's create a simple demo. 43 | 44 | ```go 45 | package main 46 | 47 | import ( 48 | "fmt" 49 | "image" 50 | "runtime" 51 | 52 | "github.com/AllenDang/gimu" 53 | ) 54 | 55 | func builder(w *gimu.Window) { 56 | // Create a new window inside master window 57 | width, height := w.MasterWindow().GetSize() 58 | bounds := nk.NkRect(0, 0, float32(width), float32(height)) 59 | 60 | w.Window("Simple Demo", bounds, nk.WindowNoScrollbar, func(w *gimu.Window) { 61 | // Define the row with 25px height, and contains one widget for each row. 62 | w.Row(25).Dynamic(1) 63 | // Let's create a label first, note the second parameter "LC" means the text alignment is left-center. 64 | w.Label("I'm a label", "LC") 65 | // Create a button. 66 | clicked := w.Button("Click Me") 67 | if clicked { 68 | fmt.Println("The button is clicked") 69 | } 70 | }) 71 | } 72 | 73 | func main() { 74 | runtime.LockOSThread() 75 | 76 | // Create master window 77 | wnd := gimu.NewMasterWindow("Simple Demo", 200, 100, gimu.MasterWindowFlagDefault) 78 | 79 | wnd.Main(builder) 80 | } 81 | ``` 82 | 83 | Save and run. 84 | 85 | ### Deploy 86 | 87 | gimu provides a tool to pack compiled executable for several platform to enable app icon and etc. 88 | 89 | ``` 90 | go get -u github.com/AllenDang/gimu/cmd/gmdeploy 91 | ``` 92 | 93 | Run gmdeploy in your project folder. 94 | 95 | ``` 96 | gmdeploy -icon AppIcon.icns . 97 | ``` 98 | 99 | Then you can find bundled executable in [PROJECTDIR]/build/[OS]/ 100 | 101 | Note: 102 | 103 | Currently only MacOS is supported. Windows and linux is WIP. 104 | 105 | ### Layout system 106 | 107 | Layouting in general describes placing widget inside a window with position and size. While in this particular implementation there are two different APIs for layouting 108 | 109 | All layouting methods in this library are based around the concept of a row. 110 | 111 | A row has a height the window content grows by and a number of columns and each layouting method specifies how each widget is placed inside the row. 112 | 113 | After a row has been allocated by calling a layouting functions and then filled with widgets will advance an internal pointer over the allocated row. 114 | 115 | To actually define a layout you just call the appropriate layouting function and each subsequent widget call will place the widget as specified. Important here is that if you define more widgets then columns defined inside the layout functions it will allocate the next row without you having to make another layouting call. 116 | 117 | #### Static layout 118 | 119 | Define a row with 25px height with two widgets. 120 | 121 | ```go 122 | w.Row(25).Static(50, 50) 123 | ``` 124 | 125 | Use the magic number 0 to define a widget will auto expand if there is enough space. 126 | 127 | ```go 128 | w.Row(25).Static(0, 50) 129 | w.Label("I'm a auto growth label", "LC") 130 | w.Button("I'm a button with fixed width") 131 | ``` 132 | 133 | #### Dynamic layout 134 | 135 | It provides each widgets with same horizontal space inside the row and dynamically grows if the owning window grows in width. 136 | 137 | Define a row with two widgets each of them will have same width. 138 | 139 | ```go 140 | w.Row(25).Dynamic(2) 141 | ``` 142 | 143 | #### Flexible Layout 144 | 145 | Finally the most flexible API directly allows you to place widgets inside the window. The space layout API is an immediate mode API which does not support row auto repeat and directly sets position and size of a widget. Position and size hereby can be either specified as ratio of allocated space or allocated space local position and pixel size. Since this API is quite powerful there are a number of utility functions to get the available space and convert between local allocated space and screen space. 146 | 147 | ```go 148 | w.Row(500).Space(nk.Static, func(w *gimu.Window) { 149 | w.Push(nk.NkRect(0, 0, 150, 150)) 150 | w.Group("Group Left", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 151 | }) 152 | 153 | w.Push(nk.NkRect(160, 0, 150, 240)) 154 | w.Group("Group Top", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 155 | }) 156 | 157 | w.Push(nk.NkRect(160, 250, 150, 250)) 158 | w.Group("Group Bottom", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 159 | }) 160 | 161 | w.Push(nk.NkRect(320, 0, 150, 150)) 162 | w.Group("Group Right Top", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 163 | }) 164 | 165 | w.Push(nk.NkRect(320, 160, 150, 150)) 166 | w.Group("Group Right Center", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 167 | }) 168 | 169 | w.Push(nk.NkRect(320, 320, 150, 150)) 170 | w.Group("Group Right Center", nk.WindowBorder|nk.WindowTitle, func(w *gimu.Window) { 171 | }) 172 | }) 173 | ``` 174 | 175 | ## Widgets usage 176 | 177 | Most of the widget's usage are very straight forward. 178 | 179 | ### Common widgets 180 | 181 | #### Label 182 | 183 | The second parameter of label indicates the text alignment. 184 | 185 | ```go 186 | w.Label("Label caption", "LC") 187 | ``` 188 | 189 | "LC" means horizontally left and vertically center. 190 | 191 | "LT" means horizontally left and vertically top. 192 | 193 | The alignment char layout is listed below, you could use any combinations of those. 194 | 195 | T 196 | 197 | L-C-R 198 | 199 | B 200 | 201 | #### Selectable Label 202 | 203 | Label can be toggled by mouse click. 204 | 205 | ```go 206 | var selected bool 207 | w.SelectableLabel("Selectable 1", "LC", &selected1) 208 | ``` 209 | 210 | #### Button 211 | 212 | Button function will return a bool to indicate whether it was clicked. 213 | 214 | ```go 215 | clicked := w.Button("Click Me") 216 | if clicked { 217 | // Do something here 218 | } 219 | ``` 220 | 221 | #### Progressbar 222 | 223 | Progress could be readonly or modifiable. 224 | 225 | ```go 226 | progress := 0 227 | // Modifiable 228 | w.Progress(&progress, 100, true) 229 | // Readonly 230 | w.Progress(&progress, 100, false) 231 | ``` 232 | 233 | To read current progress or update progress bar, just set the progress variable. 234 | 235 | #### Slider 236 | 237 | Slider behaves like progress bar but step control. 238 | 239 | ```go 240 | var slider int 241 | w.SliderInt(0, &slider, 100, 1) 242 | ``` 243 | 244 | #### Property widgets 245 | 246 | It contains a label and a adjustable control to modify int or float variable. 247 | 248 | ``` go 249 | var propertyInt int 250 | var propertyFloat float32 251 | w.PropertyInt("Age", 1, &propertyInt, 100, 10, 1) 252 | w.PropertyFloat("Height", 1, &propertyFloat, 10, 0.2, 1) 253 | ``` 254 | 255 | #### Checkbox 256 | 257 | ```go 258 | var checked bool 259 | w.Checkbox("Check me", &checked) 260 | ``` 261 | 262 | #### Radio 263 | 264 | ```go 265 | option := 1 266 | if op1 := w.Radio("Option 1", option == 1); op1 { 267 | option = 1 268 | } 269 | if op2 := w.Radio("Option 2", option == 2); op2 { 270 | option = 2 271 | } 272 | if op3 := w.Radio("Option 3", option == 3); op3 { 273 | option = 3 274 | } 275 | ``` 276 | 277 | #### Textedit 278 | 279 | Textedit is special because it will retain the input string, so you will have to explicitly create it and call the Edit() function in BuilderFunc. 280 | 281 | ```go 282 | textedit := gimu.NewTextEdit() 283 | 284 | func builder(w *gimu.Window) { 285 | textedit.Edit(w, gimu.EditField, gimu.EditFilterDefault) 286 | } 287 | ``` 288 | 289 | #### ListView 290 | 291 | ListView is designed to display very huge amount of data and only render visible items. 292 | 293 | ```go 294 | var ( 295 | listview *nk.ListView 296 | listitem []interface{} 297 | ) 298 | 299 | func builder(w *gimu.Window) { 300 | width, height := w.MasterWindow().GetSize() 301 | bounds := nk.NkRect(0, 0, float32(width), float32(height)) 302 | w.Window("", bounds, 0, func(w *gimu.Window) { 303 | w.Row(int(height - 18)).Dynamic(1) 304 | w.ListView(listview, "huge list", nk.WindowBorder, 25, 305 | listitem, 306 | func(r *gimu.Row) { 307 | r.Dynamic(1) 308 | }, 309 | func(w *gimu.Window, i int, item interface{}) { 310 | if s, ok := item.(string); ok { 311 | w.Label(s, "LC") 312 | } 313 | }) 314 | }) 315 | } 316 | 317 | func main() { 318 | // Init the listview widget 319 | listview = &nk.ListView{} 320 | 321 | // Create list items 322 | listitem = make([]interface{}, 12345) 323 | for i := range listitem { 324 | listitem[i] = fmt.Sprintf("Label item %d", i) 325 | } 326 | 327 | runtime.LockOSThread() 328 | 329 | wnd := gimu.NewMasterWindow("Huge list", 800, 600, gimu.MasterWindowFlagNoResize) 330 | wnd.Main(builder) 331 | } 332 | ``` 333 | 334 | ### Popups 335 | 336 | #### Tooltip 337 | 338 | **Note: Tooltip has to be placed above the widget which wants a tooltip when mouse hovering.** 339 | 340 | ```go 341 | w.Tooltip("This is a tooltip") 342 | w.Button("Hover me to see tooltip") 343 | ``` 344 | 345 | #### Popup Window 346 | 347 | ```go 348 | func msgbox(w *gimu.Window) { 349 | opened := w.Popup( 350 | "Message", 351 | gimu.PopupStatic, 352 | nk.WindowTitle|nk.WindowNoScrollbar|nk.WindowClosable, 353 | nk.NkRect(30, 10, 300, 100), 354 | func(w *gimu.Window) { 355 | w.Row(25).Dynamic(1) 356 | w.Label("Here is a pop up window", "LC") 357 | if w.Button("Close") { 358 | showPopup = false 359 | w.ClosePopup() 360 | } 361 | }) 362 | if !opened { 363 | showPopup = false 364 | } 365 | } 366 | ``` 367 | 368 | ### Menu 369 | 370 | #### Window Menu 371 | 372 | **Note: window menu bar has to be the first widget in the builder method.** 373 | 374 | ```go 375 | // Menu 376 | w.Menubar(func(w *gimu.Window) { 377 | w.Row(25).Static(60, 60) 378 | // Menu 1 379 | w.Menu("Menu1", "CC", 200, 100, func(w *gimu.Window) { 380 | w.Row(25).Dynamic(1) 381 | w.MenuItemLabel("Menu item 1", "LC") 382 | w.MenuItemLabel("Menu item 2", "LC") 383 | w.Button("Button inside menu") 384 | }) 385 | // Menu 2 386 | w.Menu("Menu2", "CC", 100, 100, func(w *gimu.Window) { 387 | w.Row(25).Dynamic(1) 388 | w.MenuItemLabel("Menu item 1", "LC") 389 | w.SliderInt(0, &slider, 100, 1) 390 | w.MenuItemLabel("Menu item 2", "LC") 391 | }) 392 | }) 393 | ``` 394 | 395 | #### Contextual Menu 396 | 397 | **Note: Contextual menu has to be placed above the widget which wants a tooltip when right click.** 398 | 399 | You could put any kind of widgets inside the contextual menu. 400 | 401 | ```go 402 | w.Contextual(0, 100, 300, func(w *gimu.Window) { 403 | w.Row(25).Dynamic(1) 404 | w.ContextualLabel("Context menu 1", "LC") 405 | w.ContextualLabel("Context menu 1", "LC") 406 | w.SliderInt(0, &slider, 100, 1) 407 | }) 408 | w.Button("Right click me") 409 | ``` 410 | 411 | ## License 412 | 413 | All the code except when stated otherwise is licensed under the [MIT license](https://xlab.mit-license.org). 414 | Nuklear (ANSI C version) is in public domain, authored from 2015-2016 by Micha Mettke. 415 | 416 | -------------------------------------------------------------------------------- /nk/types.go: -------------------------------------------------------------------------------- 1 | // THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS. 2 | 3 | // WARNING: This file has automatically been generated on Wed, 18 Dec 2019 20:58:41 CST. 4 | // Code generated by https://git.io/c-for-go. DO NOT EDIT. 5 | 6 | package nk 7 | 8 | /* 9 | #include "nk.h" 10 | #include 11 | #include "cgo_helpers.h" 12 | */ 13 | import "C" 14 | import "unsafe" 15 | 16 | // Char type as declared in nk/nuklear.h:398 17 | type Char byte 18 | 19 | // Uchar type as declared in nk/nuklear.h:399 20 | type Uchar byte 21 | 22 | // Byte type as declared in nk/nuklear.h:400 23 | type Byte byte 24 | 25 | // Short type as declared in nk/nuklear.h:401 26 | type Short int16 27 | 28 | // Ushort type as declared in nk/nuklear.h:402 29 | type Ushort uint16 30 | 31 | // Int type as declared in nk/nuklear.h:403 32 | type Int int32 33 | 34 | // Uint type as declared in nk/nuklear.h:404 35 | type Uint uint32 36 | 37 | // Size type as declared in nk/nuklear.h:405 38 | type Size uint 39 | 40 | // Ptr type as declared in nk/nuklear.h:406 41 | type Ptr uint 42 | 43 | // Hash type as declared in nk/nuklear.h:408 44 | type Hash uint32 45 | 46 | // Flags type as declared in nk/nuklear.h:409 47 | type Flags uint32 48 | 49 | // Rune type as declared in nk/nuklear.h:410 50 | type Rune uint32 51 | 52 | // Glyph type as declared in nk/nuklear.h:463 53 | type Glyph [4]byte 54 | 55 | // Handle as declared in nk/nuklear.h:464 56 | const sizeofHandle = unsafe.Sizeof(C.nk_handle{}) 57 | 58 | type Handle [sizeofHandle]byte 59 | 60 | // PluginAlloc type as declared in nk/nuklear.h:482 61 | type PluginAlloc func(arg0 Handle, old unsafe.Pointer, arg2 Size) unsafe.Pointer 62 | 63 | // PluginFree type as declared in nk/nuklear.h:483 64 | type PluginFree func(arg0 Handle, old unsafe.Pointer) 65 | 66 | // PluginFilter type as declared in nk/nuklear.h:484 67 | type PluginFilter func(arg0 *TextEdit, unicode Rune) int32 68 | 69 | // PluginPaste type as declared in nk/nuklear.h:485 70 | type PluginPaste func(arg0 Handle, arg1 *TextEdit) 71 | 72 | // PluginCopy type as declared in nk/nuklear.h:486 73 | type PluginCopy func(arg0 Handle, arg1 string, len int32) 74 | 75 | // TextWidthF type as declared in nk/nuklear.h:3896 76 | type TextWidthF func(arg0 Handle, h float32, arg2 string, len int32) float32 77 | 78 | // QueryFontGlyphF type as declared in nk/nuklear.h:3897 79 | type QueryFontGlyphF func(handle Handle, fontHeight float32, glyph *UserFontGlyph, codepoint Rune, nextCodepoint Rune) 80 | 81 | // CommandCustomCallback type as declared in nk/nuklear.h:4535 82 | type CommandCustomCallback func(canvas unsafe.Pointer, x int16, y int16, w uint16, h uint16, callbackData Handle) 83 | 84 | // DrawIndex type as declared in nk/nuklear.h:4668 85 | type DrawIndex uint16 86 | 87 | // Allocator as declared in nk/nuklear.h:431 88 | type Allocator C.struct_nk_allocator 89 | 90 | // BakedFont as declared in nk/nuklear.h:3936 91 | type BakedFont C.struct_nk_baked_font 92 | 93 | // Buffer as declared in nk/nuklear.h:430 94 | type Buffer C.struct_nk_buffer 95 | 96 | // BufferMarker as declared in nk/nuklear.h:4112 97 | type BufferMarker C.struct_nk_buffer_marker 98 | 99 | // Chart as declared in nk/nuklear.h:5278 100 | type Chart C.struct_nk_chart 101 | 102 | // ChartSlot as declared in nk/nuklear.h:5268 103 | type ChartSlot C.struct_nk_chart_slot 104 | 105 | // Clipboard as declared in nk/nuklear.h:4247 106 | type Clipboard C.struct_nk_clipboard 107 | 108 | // Color as declared in nk/nuklear.h:457 109 | type Color C.struct_nk_color 110 | 111 | // Colorf as declared in nk/nuklear.h:458 112 | type Colorf C.struct_nk_colorf 113 | 114 | // Command as declared in nk/nuklear.h:4397 115 | type Command C.struct_nk_command 116 | 117 | // CommandArc as declared in nk/nuklear.h:4487 118 | type CommandArc C.struct_nk_command_arc 119 | 120 | // CommandArcFilled as declared in nk/nuklear.h:4496 121 | type CommandArcFilled C.struct_nk_command_arc_filled 122 | 123 | // CommandBuffer as declared in nk/nuklear.h:432 124 | type CommandBuffer C.struct_nk_command_buffer 125 | 126 | // CommandCircle as declared in nk/nuklear.h:4472 127 | type CommandCircle C.struct_nk_command_circle 128 | 129 | // CommandCircleFilled as declared in nk/nuklear.h:4480 130 | type CommandCircleFilled C.struct_nk_command_circle_filled 131 | 132 | // CommandCurve as declared in nk/nuklear.h:4419 133 | type CommandCurve C.struct_nk_command_curve 134 | 135 | // CommandCustom as declared in nk/nuklear.h:4537 136 | type CommandCustom C.struct_nk_command_custom 137 | 138 | // CommandImage as declared in nk/nuklear.h:4527 139 | type CommandImage C.struct_nk_command_image 140 | 141 | // CommandLine as declared in nk/nuklear.h:4411 142 | type CommandLine C.struct_nk_command_line 143 | 144 | // CommandPolygon as declared in nk/nuklear.h:4504 145 | type CommandPolygon C.struct_nk_command_polygon 146 | 147 | // CommandPolygonFilled as declared in nk/nuklear.h:4512 148 | type CommandPolygonFilled C.struct_nk_command_polygon_filled 149 | 150 | // CommandPolyline as declared in nk/nuklear.h:4519 151 | type CommandPolyline C.struct_nk_command_polyline 152 | 153 | // CommandRect as declared in nk/nuklear.h:4428 154 | type CommandRect C.struct_nk_command_rect 155 | 156 | // CommandRectFilled as declared in nk/nuklear.h:4437 157 | type CommandRectFilled C.struct_nk_command_rect_filled 158 | 159 | // CommandRectMultiColor as declared in nk/nuklear.h:4445 160 | type CommandRectMultiColor C.struct_nk_command_rect_multi_color 161 | 162 | // CommandScissor as declared in nk/nuklear.h:4405 163 | type CommandScissor C.struct_nk_command_scissor 164 | 165 | // CommandText as declared in nk/nuklear.h:4545 166 | type CommandText C.struct_nk_command_text 167 | 168 | // CommandTriangle as declared in nk/nuklear.h:4455 169 | type CommandTriangle C.struct_nk_command_triangle 170 | 171 | // CommandTriangleFilled as declared in nk/nuklear.h:4464 172 | type CommandTriangleFilled C.struct_nk_command_triangle_filled 173 | 174 | // ConfigStackButtonBehavior as declared in nk/nuklear.h:5514 175 | type ConfigStackButtonBehavior C.struct_nk_config_stack_button_behavior 176 | 177 | // ConfigStackButtonBehaviorElement as declared in nk/nuklear.h:5506 178 | type ConfigStackButtonBehaviorElement C.struct_nk_config_stack_button_behavior_element 179 | 180 | // ConfigStackColor as declared in nk/nuklear.h:5512 181 | type ConfigStackColor C.struct_nk_config_stack_color 182 | 183 | // ConfigStackColorElement as declared in nk/nuklear.h:5504 184 | type ConfigStackColorElement C.struct_nk_config_stack_color_element 185 | 186 | // ConfigStackFlags as declared in nk/nuklear.h:5511 187 | type ConfigStackFlags C.struct_nk_config_stack_flags 188 | 189 | // ConfigStackFlagsElement as declared in nk/nuklear.h:5503 190 | type ConfigStackFlagsElement C.struct_nk_config_stack_flags_element 191 | 192 | // ConfigStackFloat as declared in nk/nuklear.h:5509 193 | type ConfigStackFloat C.struct_nk_config_stack_float 194 | 195 | // ConfigStackFloatElement as declared in nk/nuklear.h:5501 196 | type ConfigStackFloatElement C.struct_nk_config_stack_float_element 197 | 198 | // ConfigStackStyleItem as declared in nk/nuklear.h:5508 199 | type ConfigStackStyleItem C.struct_nk_config_stack_style_item 200 | 201 | // ConfigStackStyleItemElement as declared in nk/nuklear.h:5500 202 | type ConfigStackStyleItemElement C.struct_nk_config_stack_style_item_element 203 | 204 | // ConfigStackUserFont as declared in nk/nuklear.h:5513 205 | type ConfigStackUserFont struct { 206 | Head int32 207 | Elements [8]ConfigStackUserFontElement 208 | refa664861d *C.struct_nk_config_stack_user_font 209 | allocsa664861d interface{} 210 | } 211 | 212 | // ConfigStackUserFontElement as declared in nk/nuklear.h:5505 213 | type ConfigStackUserFontElement struct { 214 | Address [][]UserFont 215 | OldValue []UserFont 216 | ref5572630c *C.struct_nk_config_stack_user_font_element 217 | allocs5572630c interface{} 218 | } 219 | 220 | // ConfigStackVec2 as declared in nk/nuklear.h:5510 221 | type ConfigStackVec2 C.struct_nk_config_stack_vec2 222 | 223 | // ConfigStackVec2Element as declared in nk/nuklear.h:5502 224 | type ConfigStackVec2Element C.struct_nk_config_stack_vec2_element 225 | 226 | // ConfigurationStacks as declared in nk/nuklear.h:5516 227 | type ConfigurationStacks C.struct_nk_configuration_stacks 228 | 229 | // Context as declared in nk/nuklear.h:440 230 | type Context C.struct_nk_context 231 | 232 | // ConvertConfig as declared in nk/nuklear.h:434 233 | type ConvertConfig struct { 234 | GlobalAlpha float32 235 | LineAa AntiAliasing 236 | ShapeAa AntiAliasing 237 | CircleSegmentCount uint32 238 | ArcSegmentCount uint32 239 | CurveSegmentCount uint32 240 | Null DrawNullTexture 241 | VertexLayout []DrawVertexLayoutElement 242 | VertexSize Size 243 | VertexAlignment Size 244 | ref82bf4c25 *C.struct_nk_convert_config 245 | allocs82bf4c25 interface{} 246 | } 247 | 248 | // Cursor as declared in nk/nuklear.h:466 249 | type Cursor C.struct_nk_cursor 250 | 251 | // DrawCommand as declared in nk/nuklear.h:433 252 | type DrawCommand C.struct_nk_draw_command 253 | 254 | // DrawList as declared in nk/nuklear.h:437 255 | type DrawList C.struct_nk_draw_list 256 | 257 | // DrawNullTexture as declared in nk/nuklear.h:1150 258 | type DrawNullTexture C.struct_nk_draw_null_texture 259 | 260 | // DrawVertexLayoutElement as declared in nk/nuklear.h:441 261 | type DrawVertexLayoutElement struct { 262 | Attribute DrawVertexLayoutAttribute 263 | Format DrawVertexLayoutFormat 264 | Offset Size 265 | refeb0614d6 *C.struct_nk_draw_vertex_layout_element 266 | allocseb0614d6 interface{} 267 | } 268 | 269 | // EditState as declared in nk/nuklear.h:5382 270 | type EditState C.struct_nk_edit_state 271 | 272 | // Font as declared in nk/nuklear.h:3935 273 | type Font C.struct_nk_font 274 | 275 | // FontAtlas as declared in nk/nuklear.h:4009 276 | type FontAtlas C.struct_nk_font_atlas 277 | 278 | // FontConfig as declared in nk/nuklear.h:3949 279 | type FontConfig C.struct_nk_font_config 280 | 281 | // FontGlyph as declared in nk/nuklear.h:3985 282 | type FontGlyph C.struct_nk_font_glyph 283 | 284 | // Image as declared in nk/nuklear.h:465 285 | type Image C.struct_nk_image 286 | 287 | // Input as declared in nk/nuklear.h:4625 288 | type Input C.struct_nk_input 289 | 290 | // Key as declared in nk/nuklear.h:4615 291 | type Key C.struct_nk_key 292 | 293 | // Keyboard as declared in nk/nuklear.h:4619 294 | type Keyboard C.struct_nk_keyboard 295 | 296 | // ListView as declared in nk/nuklear.h:3025 297 | type ListView C.struct_nk_list_view 298 | 299 | // Memory as declared in nk/nuklear.h:4117 300 | type Memory C.struct_nk_memory 301 | 302 | // MemoryStatus as declared in nk/nuklear.h:4092 303 | type MemoryStatus C.struct_nk_memory_status 304 | 305 | // MenuState as declared in nk/nuklear.h:5320 306 | type MenuState C.struct_nk_menu_state 307 | 308 | // Mouse as declared in nk/nuklear.h:4604 309 | type Mouse C.struct_nk_mouse 310 | 311 | // MouseButton as declared in nk/nuklear.h:4599 312 | type MouseButton C.struct_nk_mouse_button 313 | 314 | // Page as declared in nk/nuklear.h:5552 315 | type Page C.struct_nk_page 316 | 317 | // PageData as declared in nk/nuklear.h:5540 318 | const sizeofPageData = unsafe.Sizeof(C.union_nk_page_data{}) 319 | 320 | type PageData [sizeofPageData]byte 321 | 322 | // PageElement as declared in nk/nuklear.h:5546 323 | type PageElement C.struct_nk_page_element 324 | 325 | // Panel as declared in nk/nuklear.h:439 326 | type Panel C.struct_nk_panel 327 | 328 | // Pool as declared in nk/nuklear.h:5558 329 | type Pool C.struct_nk_pool 330 | 331 | // PopupBuffer as declared in nk/nuklear.h:5312 332 | type PopupBuffer C.struct_nk_popup_buffer 333 | 334 | // PopupState as declared in nk/nuklear.h:5370 335 | type PopupState C.struct_nk_popup_state 336 | 337 | // PropertyState as declared in nk/nuklear.h:5395 338 | type PropertyState C.struct_nk_property_state 339 | 340 | // Rect as declared in nk/nuklear.h:461 341 | type Rect C.struct_nk_rect 342 | 343 | // Recti as declared in nk/nuklear.h:462 344 | type Recti C.struct_nk_recti 345 | 346 | // RowLayout as declared in nk/nuklear.h:5296 347 | type RowLayout C.struct_nk_row_layout 348 | 349 | // Scroll as declared in nk/nuklear.h:467 350 | type Scroll C.struct_nk_scroll 351 | 352 | // Str as declared in nk/nuklear.h:4164 353 | type Str C.struct_nk_str 354 | 355 | // Style as declared in nk/nuklear.h:5212 356 | type Style C.struct_nk_style 357 | 358 | // StyleButton as declared in nk/nuklear.h:442 359 | type StyleButton C.struct_nk_style_button 360 | 361 | // StyleChart as declared in nk/nuklear.h:450 362 | type StyleChart C.struct_nk_style_chart 363 | 364 | // StyleCombo as declared in nk/nuklear.h:451 365 | type StyleCombo C.struct_nk_style_combo 366 | 367 | // StyleEdit as declared in nk/nuklear.h:448 368 | type StyleEdit C.struct_nk_style_edit 369 | 370 | // StyleItem as declared in nk/nuklear.h:435 371 | type StyleItem C.struct_nk_style_item 372 | 373 | // StyleItemData as declared in nk/nuklear.h:4810 374 | const sizeofStyleItemData = unsafe.Sizeof(C.union_nk_style_item_data{}) 375 | 376 | type StyleItemData [sizeofStyleItemData]byte 377 | 378 | // StyleProgress as declared in nk/nuklear.h:446 379 | type StyleProgress C.struct_nk_style_progress 380 | 381 | // StyleProperty as declared in nk/nuklear.h:449 382 | type StyleProperty C.struct_nk_style_property 383 | 384 | // StyleScrollbar as declared in nk/nuklear.h:447 385 | type StyleScrollbar C.struct_nk_style_scrollbar 386 | 387 | // StyleSelectable as declared in nk/nuklear.h:444 388 | type StyleSelectable C.struct_nk_style_selectable 389 | 390 | // StyleSlide as declared in nk/nuklear.h:445 391 | type StyleSlide C.struct_nk_style_slide 392 | 393 | // StyleSlider as declared in nk/nuklear.h:4917 394 | type StyleSlider C.struct_nk_style_slider 395 | 396 | // StyleTab as declared in nk/nuklear.h:452 397 | type StyleTab C.struct_nk_style_tab 398 | 399 | // StyleText as declared in nk/nuklear.h:4820 400 | type StyleText C.struct_nk_style_text 401 | 402 | // StyleToggle as declared in nk/nuklear.h:443 403 | type StyleToggle C.struct_nk_style_toggle 404 | 405 | // StyleWindow as declared in nk/nuklear.h:454 406 | type StyleWindow C.struct_nk_style_window 407 | 408 | // StyleWindowHeader as declared in nk/nuklear.h:453 409 | type StyleWindowHeader C.struct_nk_style_window_header 410 | 411 | // Table as declared in nk/nuklear.h:5351 412 | type Table C.struct_nk_table 413 | 414 | // TextEdit as declared in nk/nuklear.h:436 415 | type TextEdit C.struct_nk_text_edit 416 | 417 | // TextUndoRecord as declared in nk/nuklear.h:4253 418 | type TextUndoRecord C.struct_nk_text_undo_record 419 | 420 | // TextUndoState as declared in nk/nuklear.h:4260 421 | type TextUndoState C.struct_nk_text_undo_state 422 | 423 | // UserFont as declared in nk/nuklear.h:438 424 | type UserFont struct { 425 | Userdata Handle 426 | Height float32 427 | Width TextWidthF 428 | Query QueryFontGlyphF 429 | Texture Handle 430 | ref738ce62e *C.struct_nk_user_font 431 | allocs738ce62e interface{} 432 | } 433 | 434 | // UserFontGlyph as declared in nk/nuklear.h:3895 435 | type UserFontGlyph struct { 436 | Uv [2]Vec2 437 | Offset Vec2 438 | Width float32 439 | Height float32 440 | Xadvance float32 441 | ref4a84b297 *C.struct_nk_user_font_glyph 442 | allocs4a84b297 interface{} 443 | } 444 | 445 | // Vec2 as declared in nk/nuklear.h:459 446 | type Vec2 C.struct_nk_vec2 447 | 448 | // Vec2i as declared in nk/nuklear.h:460 449 | type Vec2i C.struct_nk_vec2i 450 | 451 | // Window as declared in nk/nuklear.h:5408 452 | type Window C.struct_nk_window 453 | -------------------------------------------------------------------------------- /nk/const.go: -------------------------------------------------------------------------------- 1 | // THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS. 2 | 3 | // WARNING: This file has automatically been generated on Wed, 18 Dec 2019 20:58:41 CST. 4 | // Code generated by https://git.io/c-for-go. DO NOT EDIT. 5 | 6 | package nk 7 | 8 | /* 9 | #include "nk.h" 10 | #include 11 | #include "cgo_helpers.h" 12 | */ 13 | import "C" 14 | 15 | const ( 16 | // IncludeFixedTypes as defined in gimu/:24 17 | IncludeFixedTypes = 1 18 | // IncludeStandardIo as defined in gimu/:25 19 | IncludeStandardIo = 1 20 | // IncludeDefaultAllocator as defined in gimu/:26 21 | IncludeDefaultAllocator = 1 22 | // IncludeVertexBufferOutput as defined in gimu/:27 23 | IncludeVertexBufferOutput = 1 24 | // IncludeFontBaking as defined in gimu/:28 25 | IncludeFontBaking = 1 26 | // IncludeDefaultFont as defined in gimu/:29 27 | IncludeDefaultFont = 1 28 | // KeystateBasedInput as defined in gimu/:30 29 | KeystateBasedInput = 1 30 | // Undefined as defined in nk/nuklear.h:233 31 | Undefined = (-1.0) 32 | // UtfInvalid as defined in nk/nuklear.h:234 33 | UtfInvalid = 0xFFFD 34 | // UtfSize as defined in nk/nuklear.h:235 35 | UtfSize = 4 36 | // InputMax as defined in nk/nuklear.h:237 37 | InputMax = 16 38 | // MaxNumberBuffer as defined in nk/nuklear.h:240 39 | MaxNumberBuffer = 64 40 | // ScrollbarHidingTimeout as defined in nk/nuklear.h:243 41 | ScrollbarHidingTimeout = 4.0 42 | // Lib as defined in nk/nuklear.h:267 43 | Lib = 0 44 | // TexteditUndostatecount as defined in nk/nuklear.h:4239 45 | TexteditUndostatecount = 99 46 | // TexteditUndocharcount as defined in nk/nuklear.h:4243 47 | TexteditUndocharcount = 999 48 | // MaxLayoutRowTemplateColumns as defined in nk/nuklear.h:5246 49 | MaxLayoutRowTemplateColumns = 16 50 | // ChartMaxSlot as defined in nk/nuklear.h:5249 51 | ChartMaxSlot = 4 52 | // WindowMaxName as defined in nk/nuklear.h:5348 53 | WindowMaxName = 64 54 | // ButtonBehaviorStackSize as defined in nk/nuklear.h:5461 55 | ButtonBehaviorStackSize = 8 56 | // FontStackSize as defined in nk/nuklear.h:5465 57 | FontStackSize = 8 58 | // StyleItemStackSize as defined in nk/nuklear.h:5469 59 | StyleItemStackSize = 16 60 | // FloatStackSize as defined in nk/nuklear.h:5473 61 | FloatStackSize = 32 62 | // VectorStackSize as defined in nk/nuklear.h:5477 63 | VectorStackSize = 16 64 | // FlagsStackSize as defined in nk/nuklear.h:5481 65 | FlagsStackSize = 32 66 | // ColorStackSize as defined in nk/nuklear.h:5485 67 | ColorStackSize = 32 68 | // Float as defined in nk/nuklear.h:5499 69 | Float = 0 70 | // Pi as defined in nk/nuklear.h:5613 71 | Pi = 3.141592654 72 | // MaxFloatPrecision as defined in nk/nuklear.h:5615 73 | MaxFloatPrecision = 2 74 | ) 75 | 76 | // Heading as declared in nk/nuklear.h:469 77 | type Heading int32 78 | 79 | // Heading enumeration from nk/nuklear.h:469 80 | const ( 81 | Up = iota 82 | Right = 1 83 | Down = 2 84 | Left = 3 85 | ) 86 | 87 | // ButtonBehavior as declared in nk/nuklear.h:470 88 | type ButtonBehavior int32 89 | 90 | // ButtonBehavior enumeration from nk/nuklear.h:470 91 | const ( 92 | ButtonDefault = iota 93 | ButtonRepeater = 1 94 | ) 95 | 96 | // Modify as declared in nk/nuklear.h:471 97 | type Modify int32 98 | 99 | // Modify enumeration from nk/nuklear.h:471 100 | const ( 101 | Fixed = False 102 | Modifiable = True 103 | ) 104 | 105 | // Orientation as declared in nk/nuklear.h:472 106 | type Orientation int32 107 | 108 | // Orientation enumeration from nk/nuklear.h:472 109 | const ( 110 | Vertical = iota 111 | Horizontal = 1 112 | ) 113 | 114 | // CollapseStates as declared in nk/nuklear.h:473 115 | type CollapseStates int32 116 | 117 | // CollapseStates enumeration from nk/nuklear.h:473 118 | const ( 119 | Minimized = False 120 | Maximized = True 121 | ) 122 | 123 | // ShowStates as declared in nk/nuklear.h:474 124 | type ShowStates int32 125 | 126 | // ShowStates enumeration from nk/nuklear.h:474 127 | const ( 128 | Hidden = False 129 | Shown = True 130 | ) 131 | 132 | // ChartType as declared in nk/nuklear.h:475 133 | type ChartType int32 134 | 135 | // ChartType enumeration from nk/nuklear.h:475 136 | const ( 137 | ChartLines = iota 138 | ChartColumn = 1 139 | ChartMax = 2 140 | ) 141 | 142 | // ChartEvent as declared in nk/nuklear.h:476 143 | type ChartEvent int32 144 | 145 | // ChartEvent enumeration from nk/nuklear.h:476 146 | const ( 147 | ChartHovering = 0x01 148 | ChartClicked = 0x02 149 | ) 150 | 151 | // ColorFormat as declared in nk/nuklear.h:477 152 | type ColorFormat int32 153 | 154 | // ColorFormat enumeration from nk/nuklear.h:477 155 | const ( 156 | ColorFormatRGB = iota 157 | ColorFormatRGBA = 1 158 | ) 159 | 160 | // PopupType as declared in nk/nuklear.h:478 161 | type PopupType int32 162 | 163 | // PopupType enumeration from nk/nuklear.h:478 164 | const ( 165 | PopupStatic = iota 166 | PopupDynamic = 1 167 | ) 168 | 169 | // LayoutFormat as declared in nk/nuklear.h:479 170 | type LayoutFormat int32 171 | 172 | // LayoutFormat enumeration from nk/nuklear.h:479 173 | const ( 174 | Dynamic = iota 175 | Static = 1 176 | ) 177 | 178 | // TreeType as declared in nk/nuklear.h:480 179 | type TreeType int32 180 | 181 | // TreeType enumeration from nk/nuklear.h:480 182 | const ( 183 | TreeNode = iota 184 | TreeTab = 1 185 | ) 186 | 187 | // SymbolType as declared in nk/nuklear.h:493 188 | type SymbolType int32 189 | 190 | // SymbolType enumeration from nk/nuklear.h:493 191 | const ( 192 | SymbolNone = iota 193 | SymbolX = 1 194 | SymbolUnderscore = 2 195 | SymbolCircleSolid = 3 196 | SymbolCircleOutline = 4 197 | SymbolRectSolid = 5 198 | SymbolRectOutline = 6 199 | SymbolTriangleUp = 7 200 | SymbolTriangleDown = 8 201 | SymbolTriangleLeft = 9 202 | SymbolTriangleRight = 10 203 | SymbolPlus = 11 204 | SymbolMinus = 12 205 | SymbolMax = 13 206 | ) 207 | 208 | // Keys as declared in nk/nuklear.h:735 209 | type Keys int32 210 | 211 | // Keys enumeration from nk/nuklear.h:735 212 | const ( 213 | KeyNone = iota 214 | KeyShift = 1 215 | KeyCtrl = 2 216 | KeyDel = 3 217 | KeyEnter = 4 218 | KeyTab = 5 219 | KeyBackspace = 6 220 | KeyCopy = 7 221 | KeyCut = 8 222 | KeyPaste = 9 223 | KeyUp = 10 224 | KeyDown = 11 225 | KeyLeft = 12 226 | KeyRight = 13 227 | KeyTextInsertMode = 14 228 | KeyTextReplaceMode = 15 229 | KeyTextResetMode = 16 230 | KeyTextLineStart = 17 231 | KeyTextLineEnd = 18 232 | KeyTextStart = 19 233 | KeyTextEnd = 20 234 | KeyTextUndo = 21 235 | KeyTextRedo = 22 236 | KeyTextSelectAll = 23 237 | KeyTextWordLeft = 24 238 | KeyTextWordRight = 25 239 | KeyScrollStart = 26 240 | KeyScrollEnd = 27 241 | KeyScrollDown = 28 242 | KeyScrollUp = 29 243 | KeyMax = 30 244 | ) 245 | 246 | // Buttons as declared in nk/nuklear.h:770 247 | type Buttons int32 248 | 249 | // Buttons enumeration from nk/nuklear.h:770 250 | const ( 251 | ButtonLeft = iota 252 | ButtonMiddle = 1 253 | ButtonRight = 2 254 | ButtonDouble = 3 255 | ButtonMax = 4 256 | ) 257 | 258 | // AntiAliasing as declared in nk/nuklear.h:1142 259 | type AntiAliasing int32 260 | 261 | // AntiAliasing enumeration from nk/nuklear.h:1142 262 | const ( 263 | AntiAliasingOff = iota 264 | AntiAliasingOn = 1 265 | ) 266 | 267 | // ConvertResult as declared in nk/nuklear.h:1143 268 | type ConvertResult int32 269 | 270 | // ConvertResult enumeration from nk/nuklear.h:1143 271 | const ( 272 | ConvertSuccess = iota 273 | ConvertInvalidParam = 1 274 | ConvertCommandBufferFull = (1 << (1)) 275 | ConvertVertexBufferFull = (1 << (2)) 276 | ConvertElementBufferFull = (1 << (3)) 277 | ) 278 | 279 | // PanelFlags as declared in nk/nuklear.h:1450 280 | type PanelFlags int32 281 | 282 | // PanelFlags enumeration from nk/nuklear.h:1450 283 | const ( 284 | WindowBorder = (1 << (0)) 285 | WindowMovable = (1 << (1)) 286 | WindowScalable = (1 << (2)) 287 | WindowClosable = (1 << (3)) 288 | WindowMinimizable = (1 << (4)) 289 | WindowNoScrollbar = (1 << (5)) 290 | WindowTitle = (1 << (6)) 291 | WindowScrollAutoHide = (1 << (7)) 292 | WindowBackground = (1 << (8)) 293 | WindowScaleLeft = (1 << (9)) 294 | WindowNoInput = (1 << (10)) 295 | ) 296 | 297 | // WidgetLayoutStates as declared in nk/nuklear.h:3041 298 | type WidgetLayoutStates int32 299 | 300 | // WidgetLayoutStates enumeration from nk/nuklear.h:3041 301 | const ( 302 | WidgetInvalid = iota 303 | WidgetValid = 1 304 | WidgetRom = 2 305 | ) 306 | 307 | // WidgetStates as declared in nk/nuklear.h:3046 308 | type WidgetStates int32 309 | 310 | // WidgetStates enumeration from nk/nuklear.h:3046 311 | const ( 312 | WidgetStateModified = (1 << (1)) 313 | WidgetStateInactive = (1 << (2)) 314 | WidgetStateEntered = (1 << (3)) 315 | WidgetStateHover = (1 << (4)) 316 | WidgetStateActived = (1 << (5)) 317 | WidgetStateLeft = (1 << (6)) 318 | WidgetStateHovered = WidgetStateHover | WidgetStateModified 319 | WidgetStateActive = WidgetStateActived | WidgetStateModified 320 | ) 321 | 322 | // TextAlign as declared in nk/nuklear.h:3072 323 | type TextAlign int32 324 | 325 | // TextAlign enumeration from nk/nuklear.h:3072 326 | const ( 327 | TextAlignLeft = 0x01 328 | TextAlignCentered = 0x02 329 | TextAlignRight = 0x04 330 | TextAlignTop = 0x08 331 | TextAlignMiddle = 0x10 332 | TextAlignBottom = 0x20 333 | ) 334 | 335 | // TextAlignment as declared in nk/nuklear.h:3080 336 | type TextAlignment int32 337 | 338 | // TextAlignment enumeration from nk/nuklear.h:3080 339 | const ( 340 | TextLeft = TextAlignMiddle | TextAlignLeft 341 | TextCentered = TextAlignMiddle | TextAlignCentered 342 | TextRight = TextAlignMiddle | TextAlignRight 343 | ) 344 | 345 | // EditFlags as declared in nk/nuklear.h:3415 346 | type EditFlags int32 347 | 348 | // EditFlags enumeration from nk/nuklear.h:3415 349 | const ( 350 | EditDefault = iota 351 | EditReadOnly = (1 << (0)) 352 | EditAutoSelect = (1 << (1)) 353 | EditSigEnter = (1 << (2)) 354 | EditAllowTab = (1 << (3)) 355 | EditNoCursor = (1 << (4)) 356 | EditSelectable = (1 << (5)) 357 | EditClipboard = (1 << (6)) 358 | EditCtrlEnterNewline = (1 << (7)) 359 | EditNoHorizontalScroll = (1 << (8)) 360 | EditAlwaysInsertMode = (1 << (9)) 361 | EditMultiline = (1 << (10)) 362 | EditGotoEndOnActivate = (1 << (11)) 363 | ) 364 | 365 | // EditTypes as declared in nk/nuklear.h:3430 366 | type EditTypes int32 367 | 368 | // EditTypes enumeration from nk/nuklear.h:3430 369 | const ( 370 | EditSimple = EditAlwaysInsertMode 371 | EditField = EditSimple | EditSelectable | EditClipboard 372 | EditBox = EditAlwaysInsertMode | EditSelectable | EditMultiline | EditAllowTab | EditClipboard 373 | EditEditor = EditSelectable | EditMultiline | EditAllowTab | EditClipboard 374 | ) 375 | 376 | // EditEvents as declared in nk/nuklear.h:3436 377 | type EditEvents int32 378 | 379 | // EditEvents enumeration from nk/nuklear.h:3436 380 | const ( 381 | EditActive = (1 << (0)) 382 | EditInactive = (1 << (1)) 383 | EditActivated = (1 << (2)) 384 | EditDeactivated = (1 << (3)) 385 | EditCommited = (1 << (4)) 386 | ) 387 | 388 | // StyleColors as declared in nk/nuklear.h:3561 389 | type StyleColors int32 390 | 391 | // StyleColors enumeration from nk/nuklear.h:3561 392 | const ( 393 | ColorText = iota 394 | ColorWindow = 1 395 | ColorHeader = 2 396 | ColorBorder = 3 397 | ColorButton = 4 398 | ColorButtonHover = 5 399 | ColorButtonActive = 6 400 | ColorToggle = 7 401 | ColorToggleHover = 8 402 | ColorToggleCursor = 9 403 | ColorSelect = 10 404 | ColorSelectActive = 11 405 | ColorSlider = 12 406 | ColorSliderCursor = 13 407 | ColorSliderCursorHover = 14 408 | ColorSliderCursorActive = 15 409 | ColorProperty = 16 410 | ColorEdit = 17 411 | ColorEditCursor = 18 412 | ColorCombo = 19 413 | ColorChart = 20 414 | ColorChartColor = 21 415 | ColorChartColorHighlight = 22 416 | ColorScrollbar = 23 417 | ColorScrollbarCursor = 24 418 | ColorScrollbarCursorHover = 25 419 | ColorScrollbarCursorActive = 26 420 | ColorTabHeader = 27 421 | ColorCount = 28 422 | ) 423 | 424 | // StyleCursor as declared in nk/nuklear.h:3592 425 | type StyleCursor int32 426 | 427 | // StyleCursor enumeration from nk/nuklear.h:3592 428 | const ( 429 | CursorArrow = iota 430 | CursorText = 1 431 | CursorMove = 2 432 | CursorResizeVertical = 3 433 | CursorResizeHorizontal = 4 434 | CursorResizeTopLeftDownRight = 5 435 | CursorResizeTopRightDownLeft = 6 436 | CursorCount = 7 437 | ) 438 | 439 | // FontCoordType as declared in nk/nuklear.h:3930 440 | type FontCoordType int32 441 | 442 | // FontCoordType enumeration from nk/nuklear.h:3930 443 | const ( 444 | CoordUv = iota 445 | CoordPixel = 1 446 | ) 447 | 448 | // FontAtlasFormat as declared in nk/nuklear.h:4004 449 | type FontAtlasFormat int32 450 | 451 | // FontAtlasFormat enumeration from nk/nuklear.h:4004 452 | const ( 453 | FontAtlasAlpha8 = iota 454 | FontAtlasRgba32 = 1 455 | ) 456 | 457 | // AllocationType as declared in nk/nuklear.h:4101 458 | type AllocationType int32 459 | 460 | // AllocationType enumeration from nk/nuklear.h:4101 461 | const ( 462 | BufferFixed = iota 463 | BufferDynamic = 1 464 | ) 465 | 466 | // BufferAllocationType as declared in nk/nuklear.h:4106 467 | type BufferAllocationType int32 468 | 469 | // BufferAllocationType enumeration from nk/nuklear.h:4106 470 | const ( 471 | BufferFront = iota 472 | BufferBack = 1 473 | BufferMax = 2 474 | ) 475 | 476 | // TextEditType as declared in nk/nuklear.h:4269 477 | type TextEditType int32 478 | 479 | // TextEditType enumeration from nk/nuklear.h:4269 480 | const ( 481 | TextEditSingleLine = iota 482 | TextEditMultiLine = 1 483 | ) 484 | 485 | // TextEditMode as declared in nk/nuklear.h:4274 486 | type TextEditMode int32 487 | 488 | // TextEditMode enumeration from nk/nuklear.h:4274 489 | const ( 490 | TextEditModeView = iota 491 | TextEditModeInsert = 1 492 | TextEditModeReplace = 2 493 | ) 494 | 495 | // CommandType as declared in nk/nuklear.h:4374 496 | type CommandType int32 497 | 498 | // CommandType enumeration from nk/nuklear.h:4374 499 | const ( 500 | CommandTypeNop = iota 501 | CommandTypeScissor = 1 502 | CommandTypeLine = 2 503 | CommandTypeCurve = 3 504 | CommandTypeRect = 4 505 | CommandTypeRectFilled = 5 506 | CommandTypeRectMultiColor = 6 507 | CommandTypeCircle = 7 508 | CommandTypeCircleFilled = 8 509 | CommandTypeArc = 9 510 | CommandTypeArcFilled = 10 511 | CommandTypeTriangle = 11 512 | CommandTypeTriangleFilled = 12 513 | CommandTypePolygon = 13 514 | CommandTypePolygonFilled = 14 515 | CommandTypePolyline = 15 516 | CommandTypeText = 16 517 | CommandTypeImage = 17 518 | CommandTypeCustom = 18 519 | ) 520 | 521 | // CommandClipping as declared in nk/nuklear.h:4557 522 | type CommandClipping int32 523 | 524 | // CommandClipping enumeration from nk/nuklear.h:4557 525 | const ( 526 | ClippingOff = False 527 | ClippingOn = True 528 | ) 529 | 530 | // DrawListStroke as declared in nk/nuklear.h:4670 531 | type DrawListStroke int32 532 | 533 | // DrawListStroke enumeration from nk/nuklear.h:4670 534 | const ( 535 | StrokeOpen = False 536 | StrokeClosed = True 537 | ) 538 | 539 | // DrawVertexLayoutAttribute as declared in nk/nuklear.h:4677 540 | type DrawVertexLayoutAttribute int32 541 | 542 | // DrawVertexLayoutAttribute enumeration from nk/nuklear.h:4677 543 | const ( 544 | VertexPosition = iota 545 | VertexColor = 1 546 | VertexTexcoord = 2 547 | VertexAttributeCount = 3 548 | ) 549 | 550 | // DrawVertexLayoutFormat as declared in nk/nuklear.h:4684 551 | type DrawVertexLayoutFormat int32 552 | 553 | // DrawVertexLayoutFormat enumeration from nk/nuklear.h:4684 554 | const ( 555 | FormatSchar = iota 556 | FormatSshort = 1 557 | FormatSint = 2 558 | FormatUchar = 3 559 | FormatUshort = 4 560 | FormatUint = 5 561 | FormatFloat = 6 562 | FormatDouble = 7 563 | FormatColorBegin = 8 564 | FormatR8g8b8 = FormatColorBegin 565 | FormatR16g15b16 = 9 566 | FormatR32g32b32 = 10 567 | FormatR8g8b8a8 = 11 568 | FormatB8g8r8a8 = 12 569 | FormatR16g15b16a16 = 13 570 | FormatR32g32b32a32 = 14 571 | FormatR32g32b32a32Float = 15 572 | FormatR32g32b32a32Double = 16 573 | FormatRgb32 = 17 574 | FormatRgba32 = 18 575 | FormatColorEnd = FormatRgba32 576 | FormatCount = 19 577 | ) 578 | 579 | // StyleItemType as declared in nk/nuklear.h:4805 580 | type StyleItemType int32 581 | 582 | // StyleItemType enumeration from nk/nuklear.h:4805 583 | const ( 584 | StyleItemColor = iota 585 | StyleItemImage = 1 586 | ) 587 | 588 | // StyleHeaderAlign as declared in nk/nuklear.h:5146 589 | type StyleHeaderAlign int32 590 | 591 | // StyleHeaderAlign enumeration from nk/nuklear.h:5146 592 | const ( 593 | HeaderLeft = iota 594 | HeaderRight = 1 595 | ) 596 | 597 | // PanelType as declared in nk/nuklear.h:5252 598 | type PanelType int32 599 | 600 | // PanelType enumeration from nk/nuklear.h:5252 601 | const ( 602 | PanelNone = iota 603 | PanelWindow = (1 << (0)) 604 | PanelGroup = (1 << (1)) 605 | PanelPopup = (1 << (2)) 606 | PanelContextual = (1 << (4)) 607 | PanelCombo = (1 << (5)) 608 | PanelMenu = (1 << (6)) 609 | PanelTooltip = (1 << (7)) 610 | ) 611 | 612 | // PanelSet as declared in nk/nuklear.h:5262 613 | type PanelSet int32 614 | 615 | // PanelSet enumeration from nk/nuklear.h:5262 616 | const ( 617 | PanelSetNonblock = PanelContextual | PanelCombo | PanelMenu | PanelTooltip 618 | PanelSetPopup = PanelSetNonblock | PanelPopup 619 | PanelSetSub = PanelSetPopup | PanelGroup 620 | ) 621 | 622 | // PanelRowLayoutType as declared in nk/nuklear.h:5284 623 | type PanelRowLayoutType int32 624 | 625 | // PanelRowLayoutType enumeration from nk/nuklear.h:5284 626 | const ( 627 | LayoutDynamicFixed = iota 628 | LayoutDynamicRow = 1 629 | LayoutDynamicFree = 2 630 | LayoutDynamic = 3 631 | LayoutStaticFixed = 4 632 | LayoutStaticRow = 5 633 | LayoutStaticFree = 6 634 | LayoutStatic = 7 635 | LayoutTemplate = 8 636 | LayoutCount = 9 637 | ) 638 | 639 | // WindowFlags as declared in nk/nuklear.h:5352 640 | type WindowFlags int32 641 | 642 | // WindowFlags enumeration from nk/nuklear.h:5352 643 | const ( 644 | WindowPrivate = (1 << (11)) 645 | WindowDynamic = WindowPrivate 646 | WindowRom = (1 << (12)) 647 | WindowNotInteractive = WindowRom | WindowNoInput 648 | WindowHidden = (1 << (13)) 649 | WindowClosed = (1 << (14)) 650 | WindowMinimized = (1 << (15)) 651 | WindowRemoveRom = (1 << (16)) 652 | ) 653 | 654 | const ( 655 | // False as declared in nk/nuklear.h:456 656 | False = iota 657 | // True as declared in nk/nuklear.h:456 658 | True = 1 659 | ) 660 | --------------------------------------------------------------------------------