2019-05-06 13:21:36 -04:00
|
|
|
package main
|
2019-06-11 12:38:22 -04:00
|
|
|
|
2019-05-07 14:48:06 -04:00
|
|
|
//go:generate nswrap
|
2019-05-06 13:21:36 -04:00
|
|
|
|
|
|
|
import (
|
2019-05-09 22:05:04 -04:00
|
|
|
"fmt"
|
2019-05-29 12:57:53 -04:00
|
|
|
"git.wow.st/gmp/nswrap/examples/app/ns"
|
2019-06-11 12:38:22 -04:00
|
|
|
"runtime"
|
2019-06-18 09:15:46 -04:00
|
|
|
"time"
|
2019-05-06 13:21:36 -04:00
|
|
|
)
|
|
|
|
|
2019-05-23 16:31:47 -04:00
|
|
|
//Shortcut for literal NSStrings
|
2019-05-21 16:26:52 -04:00
|
|
|
var nst = ns.NSStringWithGoString
|
|
|
|
|
2019-05-24 15:40:01 -04:00
|
|
|
func pb1() {
|
|
|
|
fmt.Println("Pushed button 1")
|
|
|
|
}
|
|
|
|
|
|
|
|
func pb2() {
|
|
|
|
fmt.Println("Pushed button 2")
|
|
|
|
a.Terminate(a)
|
|
|
|
}
|
|
|
|
|
2019-06-27 11:41:58 -04:00
|
|
|
func db() {
|
|
|
|
fmt.Println("button deallocated")
|
|
|
|
}
|
|
|
|
|
2019-06-13 09:25:53 -04:00
|
|
|
func didFinishLaunching(n *ns.NSNotification) {
|
2019-05-09 22:05:04 -04:00
|
|
|
fmt.Println("Go: did finish launching")
|
2019-06-11 12:38:22 -04:00
|
|
|
fmt.Printf("Notification: %s\n", n.Name().UTF8String())
|
2019-05-09 22:05:04 -04:00
|
|
|
//Set up an NSWindow
|
2019-05-28 13:03:23 -04:00
|
|
|
win = ns.NSWindowAlloc().InitWithContentRectStyleMask(
|
2019-06-11 12:38:22 -04:00
|
|
|
ns.NSMakeRect(200, 200, 600, 600),
|
|
|
|
ns.NSWindowStyleMaskTitled|ns.NSWindowStyleMaskClosable|
|
|
|
|
ns.NSWindowStyleMaskResizable,
|
2019-05-06 13:21:36 -04:00
|
|
|
ns.NSBackingStoreBuffered,
|
|
|
|
0,
|
|
|
|
)
|
2019-06-18 09:15:46 -04:00
|
|
|
// We do not need to retain this because we are in garbage collection mode
|
|
|
|
// and have assigned it to a global variable.
|
|
|
|
//win.Retain()
|
2019-05-23 16:31:47 -04:00
|
|
|
|
2019-05-21 16:26:52 -04:00
|
|
|
win.SetTitle(nst("Hi World"))
|
|
|
|
win.MakeKeyAndOrderFront(win)
|
|
|
|
win.SetAlphaValue(0.85)
|
2019-05-09 22:05:04 -04:00
|
|
|
|
|
|
|
//Build a basic menu
|
2019-05-09 08:52:35 -04:00
|
|
|
m1 := ns.NSMenuAlloc().InitWithTitle(nst("Main"))
|
2019-05-07 14:48:06 -04:00
|
|
|
appItem := ns.NSMenuItemAlloc()
|
|
|
|
fileItem := ns.NSMenuItemAlloc()
|
|
|
|
m1.AddItem(appItem)
|
|
|
|
m1.AddItem(fileItem)
|
|
|
|
|
2019-05-09 08:52:35 -04:00
|
|
|
appMenu := ns.NSMenuAlloc().InitWithTitle(nst("App"))
|
|
|
|
fileMenu := ns.NSMenuAlloc().InitWithTitle(nst("File"))
|
2019-05-07 14:48:06 -04:00
|
|
|
m1.SetSubmenu(appMenu, appItem)
|
|
|
|
m1.SetSubmenu(fileMenu, fileItem)
|
|
|
|
|
2019-05-21 16:26:52 -04:00
|
|
|
appMenu.AddItemWithTitle(nst("About"), nil, nst(""))
|
|
|
|
appMenu.AddItemWithTitle(nst("Preferences"), nil, nst(""))
|
2019-06-11 12:38:22 -04:00
|
|
|
appMenu.AddItemWithTitle(nst("Quit"), ns.Selector("terminate:"), nst("q"))
|
2019-05-07 14:48:06 -04:00
|
|
|
a.SetMainMenu(m1)
|
2019-05-21 16:26:52 -04:00
|
|
|
fileMenu.AddItemWithTitle(nst("Open"), nil, nst(""))
|
|
|
|
fileMenu.AddItemWithTitle(nst("New"), nil, nst(""))
|
2019-05-07 14:48:06 -04:00
|
|
|
|
|
|
|
a.SetMainMenu(m1)
|
2019-05-07 15:49:43 -04:00
|
|
|
|
2019-05-24 15:40:01 -04:00
|
|
|
//add some custom buttons
|
|
|
|
|
|
|
|
b1 := ns.GButtonAlloc()
|
|
|
|
b2 := ns.GButtonAlloc()
|
|
|
|
|
|
|
|
b1.Init()
|
|
|
|
b1.PressedCallback(pb1)
|
2019-06-27 11:41:58 -04:00
|
|
|
b1.DeallocCallback(db)
|
2019-05-24 15:40:01 -04:00
|
|
|
b1.SetAction(ns.Selector("pressed"))
|
|
|
|
b1.SetTarget(b1)
|
|
|
|
b1.SetTitle(nst("PUSH"))
|
|
|
|
|
|
|
|
b2.Init()
|
|
|
|
b2.PressedCallback(pb2)
|
2019-06-27 11:41:58 -04:00
|
|
|
b2.DeallocCallback(db)
|
2019-05-24 15:40:01 -04:00
|
|
|
b2.SetTarget(b2)
|
|
|
|
b2.SetAction(ns.Selector("pressed"))
|
|
|
|
b2.SetTitle(nst("QUIT"))
|
2019-05-23 16:31:47 -04:00
|
|
|
|
2019-05-24 15:40:01 -04:00
|
|
|
//add some layout constraints
|
2019-05-23 16:31:47 -04:00
|
|
|
|
|
|
|
b1.SetTranslatesAutoresizingMaskIntoConstraints(0)
|
|
|
|
b2.SetTranslatesAutoresizingMaskIntoConstraints(0)
|
|
|
|
|
|
|
|
cv := win.ContentView()
|
|
|
|
|
2019-06-13 09:25:53 -04:00
|
|
|
cv.AddSubview(&b1.NSView)
|
|
|
|
cv.AddSubview(&b2.NSView)
|
2019-05-23 16:31:47 -04:00
|
|
|
|
2019-05-28 13:03:23 -04:00
|
|
|
viewmap := ns.NSDictionaryWithObjectsForKeys(
|
2019-06-11 12:38:22 -04:00
|
|
|
ns.NSArrayWithObjects(b1, b2),
|
|
|
|
ns.NSArrayWithObjects(nst("b1"), nst("b2")))
|
2019-05-23 16:31:47 -04:00
|
|
|
|
|
|
|
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
2019-06-13 09:25:53 -04:00
|
|
|
nst("V:|-[b1]"), 0, nil, viewmap))
|
2019-05-23 16:31:47 -04:00
|
|
|
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
2019-06-13 09:25:53 -04:00
|
|
|
nst("H:|-[b1]"), 0, nil, viewmap))
|
2019-05-23 16:31:47 -04:00
|
|
|
cv.AddConstraints(ns.NSLayoutConstraintsWithVisualFormat(
|
2019-06-13 09:25:53 -04:00
|
|
|
nst("H:[b1]-[b2]"), ns.NSLayoutFormatAlignAllBaseline, nil, viewmap))
|
2019-05-29 22:36:49 -04:00
|
|
|
|
|
|
|
a.ActivateIgnoringOtherApps(1)
|
2019-05-23 16:31:47 -04:00
|
|
|
}
|
|
|
|
|
2019-06-13 09:25:53 -04:00
|
|
|
func shouldTerminateAfterLastWindowClosed(s *ns.NSApplication) ns.BOOL {
|
2019-06-27 11:41:58 -04:00
|
|
|
fmt.Println("Go: should terminate after last window closed")
|
2019-05-23 16:31:47 -04:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2019-06-13 09:25:53 -04:00
|
|
|
func willTerminate(n *ns.NSNotification) {
|
2019-05-23 16:31:47 -04:00
|
|
|
fmt.Println("Go: will terminate")
|
|
|
|
}
|
|
|
|
|
2019-06-13 09:25:53 -04:00
|
|
|
func didBecomeActive(n *ns.NSNotification) {
|
2019-05-23 16:31:47 -04:00
|
|
|
fmt.Println("Go: did become active")
|
2019-06-11 12:38:22 -04:00
|
|
|
fmt.Printf("Notification: %s\n", n.Name().UTF8String())
|
2019-05-23 16:31:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
2019-06-13 09:25:53 -04:00
|
|
|
a *ns.NSApplication
|
2019-06-27 11:41:58 -04:00
|
|
|
del *ns.AppDelegate
|
2019-06-13 09:25:53 -04:00
|
|
|
win *ns.NSWindow
|
2019-05-23 16:31:47 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
func app() {
|
2019-06-18 09:15:46 -04:00
|
|
|
// Lock OS thread because Cocoa uses thread-local storage
|
2019-05-23 16:31:47 -04:00
|
|
|
runtime.LockOSThread()
|
|
|
|
a = ns.NSApplicationSharedApplication()
|
|
|
|
a.SetActivationPolicy(ns.NSApplicationActivationPolicyRegular)
|
|
|
|
|
2019-06-18 09:15:46 -04:00
|
|
|
// Set up an AppDelegate
|
2019-06-27 11:41:58 -04:00
|
|
|
// assign it to a global variable so it doesn't get garbage collected
|
|
|
|
del = ns.AppDelegateAlloc()
|
2019-05-23 16:31:47 -04:00
|
|
|
del.ApplicationDidFinishLaunchingCallback(didFinishLaunching)
|
|
|
|
del.ApplicationShouldTerminateAfterLastWindowClosedCallback(shouldTerminateAfterLastWindowClosed)
|
|
|
|
del.ApplicationWillTerminateCallback(willTerminate)
|
|
|
|
del.ApplicationDidBecomeActiveCallback(didBecomeActive)
|
|
|
|
|
|
|
|
a.SetDelegate(del)
|
|
|
|
|
2019-06-18 09:15:46 -04:00
|
|
|
// Run the app
|
2019-05-06 13:21:36 -04:00
|
|
|
a.Run()
|
|
|
|
}
|
|
|
|
|
2019-05-07 14:48:06 -04:00
|
|
|
func main() {
|
2019-06-18 09:15:46 -04:00
|
|
|
// Run GC every second to ensure pointers are not being prematurely released.
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
runtime.GC()
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
// Run our app in an autorelease pool just for fun
|
2019-06-27 11:41:58 -04:00
|
|
|
go app()
|
2019-06-11 12:38:22 -04:00
|
|
|
select {}
|
2019-05-07 14:48:06 -04:00
|
|
|
}
|