mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
internal/ui: use RegisterClass API (#2442)
Updates #1162 This change uses purego's new RegisterClass API to clean up the EbitengineWindowDelegate ObjC class. Doing so makes the code easier to read and more efficient since it directly get the origResizable and origDelegate fields.
This commit is contained in:
parent
17be6eecd1
commit
8c5f525ac2
@ -31,90 +31,128 @@ import (
|
|||||||
|
|
||||||
var class_EbitengineWindowDelegate objc.Class
|
var class_EbitengineWindowDelegate objc.Class
|
||||||
|
|
||||||
func init() {
|
type windowDelgate struct {
|
||||||
class_EbitengineWindowDelegate = objc.AllocateClassPair(objc.GetClass("NSObject"), "EbitengineWindowDelegate", 0)
|
isa objc.Class `objc:"EbitengineWindowDelegate : NSObject <NSWindowDelegate>"`
|
||||||
protocol := objc.GetProtocol("NSWindowDelegate")
|
origDelegate objc.ID
|
||||||
class_EbitengineWindowDelegate.AddProtocol(protocol)
|
origResizable bool
|
||||||
// TODO: remove these Ivars and place them in Go since there is only ever one instance of this class
|
}
|
||||||
class_EbitengineWindowDelegate.AddIvar("origDelegate", objc.ID(0), "@")
|
|
||||||
class_EbitengineWindowDelegate.AddIvar("origResizable", false, "B")
|
func (w *windowDelgate) pushResizableState(win objc.ID) {
|
||||||
origDelegateOffset := class_EbitengineWindowDelegate.InstanceVariable("origDelegate").Offset()
|
window := cocoa.NSWindow{ID: win}
|
||||||
origResizableOffset := class_EbitengineWindowDelegate.InstanceVariable("origResizable").Offset()
|
w.origResizable = window.StyleMask()&cocoa.NSWindowStyleMaskResizable != 0
|
||||||
getOrigDelegate := func(self objc.ID) objc.ID {
|
if !w.origResizable {
|
||||||
selfPtr := *(**uintptr)(unsafe.Pointer(&self))
|
|
||||||
return *(*objc.ID)(unsafe.Pointer(uintptr(unsafe.Pointer(selfPtr)) + origDelegateOffset))
|
|
||||||
}
|
|
||||||
getResizable := func(self objc.ID) bool {
|
|
||||||
selfPtr := *(**uintptr)(unsafe.Pointer(&self))
|
|
||||||
return *(*bool)(unsafe.Pointer(uintptr(unsafe.Pointer(selfPtr)) + origResizableOffset))
|
|
||||||
}
|
|
||||||
setResizable := func(self objc.ID, resizable bool) {
|
|
||||||
selfPtr := *(**uintptr)(unsafe.Pointer(&self))
|
|
||||||
*(*bool)(unsafe.Pointer(uintptr(unsafe.Pointer(selfPtr)) + origResizableOffset)) = resizable
|
|
||||||
}
|
|
||||||
pushResizableState := func(self, w objc.ID) {
|
|
||||||
window := cocoa.NSWindow{ID: w}
|
|
||||||
setResizable(self, window.StyleMask()&cocoa.NSWindowStyleMaskResizable != 0)
|
|
||||||
if !getResizable(self) {
|
|
||||||
window.SetStyleMask(window.StyleMask() | cocoa.NSWindowStyleMaskResizable)
|
window.SetStyleMask(window.StyleMask() | cocoa.NSWindowStyleMaskResizable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
popResizableState := func(self, w objc.ID) {
|
|
||||||
window := cocoa.NSWindow{ID: w}
|
func (w *windowDelgate) popResizableState(win objc.ID) {
|
||||||
if !getResizable(self) {
|
if !w.origResizable {
|
||||||
|
window := cocoa.NSWindow{ID: win}
|
||||||
window.SetStyleMask(window.StyleMask() & ^uint(cocoa.NSWindowStyleMaskResizable))
|
window.SetStyleMask(window.StyleMask() & ^uint(cocoa.NSWindowStyleMaskResizable))
|
||||||
}
|
}
|
||||||
setResizable(self, false)
|
w.origResizable = false
|
||||||
}
|
}
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("initWithOrigDelegate:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, origDelegate objc.ID) objc.ID {
|
|
||||||
self = self.SendSuper(objc.RegisterName("init"))
|
func (w *windowDelgate) InitWithOrigDelegate(cmd objc.SEL, origDelegate objc.ID) objc.ID {
|
||||||
|
self := objc.ID(unsafe.Pointer(w)).SendSuper(objc.RegisterName("init"))
|
||||||
if self != 0 {
|
if self != 0 {
|
||||||
selfPtr := *(**uintptr)(unsafe.Pointer(&self))
|
w = *(**windowDelgate)(unsafe.Pointer(&self))
|
||||||
*(*objc.ID)(unsafe.Pointer(uintptr(unsafe.Pointer(selfPtr)) + origDelegateOffset)) = origDelegate
|
w.origDelegate = origDelegate
|
||||||
}
|
}
|
||||||
return self
|
return self
|
||||||
}), "@@:B")
|
}
|
||||||
// The method set of origDelegate_ must sync with GLFWWindowDelegate's implementation.
|
|
||||||
// See cocoa_window.m in GLFW.
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowShouldClose:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) int {
|
|
||||||
return int(getOrigDelegate(self).Send(objc.RegisterName("windowShouldClose:"), notification))
|
|
||||||
}), "B@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidResize:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidMove:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidMiniaturize:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidDeminiaturize:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidBecomeKey:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidResignKey:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidChangeOcclusionState:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
getOrigDelegate(self).Send(cmd, notification)
|
|
||||||
}), "v@:@")
|
|
||||||
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowWillEnterFullScreen:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
// The method set of origDelegate_ must sync with GLFWWindowDelegate's implementation.
|
||||||
pushResizableState(self, cocoa.NSNotification{ID: notification}.Object())
|
// See cocoa_window.m in GLFW.
|
||||||
}), "v@:@")
|
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidEnterFullScreen:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
func (w *windowDelgate) WindowShouldClose(cmd objc.SEL, notification objc.ID) bool {
|
||||||
popResizableState(self, cocoa.NSNotification{ID: notification}.Object())
|
return w.origDelegate.Send(cmd, notification) != 0
|
||||||
}), "v@:@")
|
}
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowWillExitFullScreen:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
|
||||||
pushResizableState(self, cocoa.NSNotification{ID: notification}.Object())
|
func (w *windowDelgate) WindowDidResize(cmd objc.SEL, notification objc.ID) {
|
||||||
}), "v@:@")
|
w.origDelegate.Send(cmd, notification)
|
||||||
class_EbitengineWindowDelegate.AddMethod(objc.RegisterName("windowDidExitFullScreen:"), objc.NewIMP(func(self objc.ID, cmd objc.SEL, notification objc.ID) {
|
}
|
||||||
popResizableState(self, cocoa.NSNotification{ID: notification}.Object())
|
|
||||||
|
func (w *windowDelgate) WindowDidMove(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.origDelegate.Send(cmd, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidMiniaturize(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.origDelegate.Send(cmd, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidDeminiaturize(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.origDelegate.Send(cmd, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidBecomeKey(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.origDelegate.Send(cmd, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidResignKey(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.origDelegate.Send(cmd, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidChangeOcclusionState(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.origDelegate.Send(cmd, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowWillEnterFullScreen(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.pushResizableState(cocoa.NSNotification{ID: notification}.Object())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidEnterFullScreen(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.popResizableState(cocoa.NSNotification{ID: notification}.Object())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowWillExitFullScreen(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.pushResizableState(cocoa.NSNotification{ID: notification}.Object())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowDelgate) WindowDidExitFullScreen(cmd objc.SEL, notification objc.ID) {
|
||||||
|
w.popResizableState(cocoa.NSNotification{ID: notification}.Object())
|
||||||
// Do not call setFrame here (#2295). setFrame here causes unexpected results.
|
// Do not call setFrame here (#2295). setFrame here causes unexpected results.
|
||||||
}), "v@:@")
|
}
|
||||||
class_EbitengineWindowDelegate.Register()
|
|
||||||
|
func (w *windowDelgate) Selector(cmd string) objc.SEL {
|
||||||
|
switch cmd {
|
||||||
|
case "InitWithOrigDelegate":
|
||||||
|
return objc.RegisterName("initWithOrigDelegate:")
|
||||||
|
case "WindowShouldClose":
|
||||||
|
return objc.RegisterName("windowShouldClose:")
|
||||||
|
case "WindowDidResize":
|
||||||
|
return objc.RegisterName("windowDidResize:")
|
||||||
|
case "WindowDidMove":
|
||||||
|
return objc.RegisterName("windowDidMove:")
|
||||||
|
case "WindowDidMiniaturize":
|
||||||
|
return objc.RegisterName("windowDidMiniaturize:")
|
||||||
|
case "WindowDidDeminiaturize":
|
||||||
|
return objc.RegisterName("windowDidDeminiaturize:")
|
||||||
|
case "WindowDidBecomeKey":
|
||||||
|
return objc.RegisterName("windowDidBecomeKey:")
|
||||||
|
case "WindowDidResignKey":
|
||||||
|
return objc.RegisterName("windowDidResignKey:")
|
||||||
|
case "WindowDidChangeOcclusionState":
|
||||||
|
return objc.RegisterName("windowDidChangeOcclusionState:")
|
||||||
|
case "WindowWillEnterFullScreen":
|
||||||
|
return objc.RegisterName("windowWillEnterFullScreen:")
|
||||||
|
case "WindowDidEnterFullScreen":
|
||||||
|
return objc.RegisterName("windowDidEnterFullScreen:")
|
||||||
|
case "WindowWillExitFullScreen":
|
||||||
|
return objc.RegisterName("windowWillExitFullScreen:")
|
||||||
|
case "WindowDidExitFullScreen":
|
||||||
|
return objc.RegisterName("windowDidExitFullScreen:")
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
class_EbitengineWindowDelegate, err = objc.RegisterClass(&windowDelgate{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type graphicsDriverCreatorImpl struct {
|
type graphicsDriverCreatorImpl struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user