Closed programmingkidx closed 10 months ago
To test this pull request I made several programs available.
This program loads a nib file and and displays it.
Directions: 1) Download the attached zip file and extract its nib file by double clicking on the file. MainMenu.nib.zip 2) Copy and paste the program below into a file called main.go. 3) Run the program by using this command: go run main.go.
// File: loadnib.go
// Date: 11/29/23
// Description: Uses a NIB file to display the interface
// Run directions: go run main.go
package main
import (
"fmt"
"os"
"github.com/progrium/macdriver/macos/appkit"
f "github.com/progrium/macdriver/macos/foundation"
"github.com/progrium/macdriver/objc"
"github.com/progrium/macdriver/helper/action"
"unsafe"
)
var textField appkit.TextField
func main() {
// Setup the application
app := appkit.Application_SharedApplication()
app.SetActivationPolicy(appkit.ApplicationActivationPolicyRegular)
app.ActivateIgnoringOtherApps(true)
// Get the NIB file's data
godata, err := os.ReadFile("MainMenu.nib")
if err != nil {
fmt.Println("Failed to load nib file:", err)
return
}
myNib := appkit.NewNibWithNibDataBundle(godata, nil)
var myObjects = f.Array_Array()
status := myNib.InstantiateWithOwnerTopLevelObjects(nil, unsafe.Pointer(&myObjects))
if status == false {
fmt.Println("Error: failed to instantiate nib file")
return
}
// find the window and display it
foundWindow := false
var i uint
for i = 0; i < myObjects.Count(); i++ {
theObject := myObjects.ObjectAtIndex(i)
if theObject.IsKindOfClass(objc.GetClass("NSWindow")) {
mainWindow := appkit.WindowFrom(theObject.Ptr())
mainWindow.OrderFront(nil)
foundWindow = true
aButton := mainWindow.ContentView().ViewWithTag(1)
action.Set(appkit.ButtonFrom(aButton.Ptr()), doButton)
textFieldView := mainWindow.ContentView().ViewWithTag(2)
textField = appkit.TextFieldFrom(textFieldView.Ptr())
break
}
}
if foundWindow == false {
fmt.Println("Error: Failed to find window in nib file")
return
}
app.Run()
}
// called when the user pushes the button
func doButton(sender objc.Object) {
fmt.Println("I'M ALIVE!!!")
textField.SetStringValue("OUCH!!!")
}
This program test the use of (NS)Error. It will tell you if its tests succeed or fail. Directions: 1) Create a new file called main.go. 2) Copy and paste the code below into the file. 3) Run the program like this: go run main.go
The output should look like this: Testing with problem string...pass Testing with good string...pass
// Description: test generating a NSError using the XMLDocument class
package main
import "fmt"
import f "github.com/progrium/macdriver/macos/foundation"
import "unsafe"
func main() {
testWithProblem()
testWithoutProblem()
}
// Use a bad string to try to make a XML document. It should fail to create one.
func testWithProblem() {
inputStr := "BUG<root><element>Some text</element></root>"
options := f.XMLNodePreserveWhitespace
var myError f.Error
f.NewXMLDocumentWithXMLStringOptionsError(inputStr, options, unsafe.Pointer(&myError))
if myError.IsNil() == false {
fmt.Println("Testing with problem string...pass")
//fmt.Printf("Error code: %d\t domain:%s\t userInfo:%s\n", myError.Code, myError.Domain, myError.UserInfo)
} else {
fmt.Println("Testing with problem string...fail")
}
}
// Use a good string to try to make a XML document. It should succeed
func testWithoutProblem() {
inputStr := "<root><element>Some text</element></root>"
options := f.XMLNodePreserveWhitespace
var myError f.Error
f.NewXMLDocumentWithXMLStringOptionsError(inputStr, options, unsafe.Pointer(&myError))
if myError.IsNil() == true {
fmt.Println("Testing with good string...pass")
} else {
fmt.Println("Testing with good string...fail")
}
}
I think this could be a good general solution. @tmc thoughts?
@tmc Any questions or comments?
Pointer to pointer types are commonly used to provide a method a way to communicate information to calling methods. A popular example of this is to use NSError to communicate any error information. This pull request adds the ability for DarwinKit to correctly use pointer to pointer types so they can work.
This change uses a new rule where if a parameter is a pointer to a pointer type (e.g. NSError **error), the user is to use the Go wrapper for that type and wrap the variable with unsafe.Pointer(&theVariable).
So for a parameter like NSError **err, the Go code would declare an Error instance and then use that instance in the method like this: unsafe.Pointer(&err)