I can certainly see the ObjC bindings being useful when it comes to using advanced features of iOS.
I’ve been wanting the ability to create folders directly for some time now and within a couple of hours I’ve got it working and WebRepo is making use of it already.
I think with the arrival of Swift Playgrounds 4, Codea now has some serious competition so this is a big step in the right direction for Codea in my opinion.
Speaking of WorkingCopy, it has been losing connections to Codea projects and sometimes cannot recover. Anders has reproduced the bug. However, it would be Very Useful if Codea projects were more like folders and less like documents, if that’s a description of why WorkingCopy has to jump through its own orifice to deal with Codea … and might also let us use other simpler approaches for Codea project version backup.
@UberGoober I’ll probably drop you a private note inquiring how you have WorkingCopy hooked up and whether you ever lose connection.
@RonJeffries it seems to me it might be a useful conversation at least to some degree for John and Simeon to be able to see. Yes I lose connection often. I have Working Copy synced to Codea projects and (usually) their GitHub repos too.
Mouse & Keyboard examples using the ObjC bindings (Also available as ‘MKInput’ on WebRepo):
-- Enums
MOUSELEFT = 1
MOUSERIGHT = 2
MOUSEMIDDLE = 3
-- Initial funcs used when no Keyboard or Mouse is detected
function ismousedown()
return false
end
function hidecursor() end
function iskeydown()
return false
end
-- Mouse callbacks
local mouse = objc.cls.GCMouse.current
if mouse then
local mouseInput = mouse.mouseInput
mouseInput.mouseMovedHandler = function(objMouse, floatDeltaX, floatDeltaY)
mousemove(floatDeltaX, floatDeltaY)
end
mouseInput.leftButton.pressedChangedHandler = function(objButton, floatValue, boolPressed)
if boolPressed then
mousedown(MOUSELEFT)
else
mouseup(MOUSELEFT)
end
end
-- right mouse button is optional
if mouseInput.rightButton then
mouseInput.rightButton.pressedChangedHandler = function(objButton, floatValue, boolPressed)
if boolPressed then
mousedown(MOUSERIGHT)
else
mouseup(MOUSERIGHT)
end
end
end
-- left mouse button is optional
if mouseInput.middleButton then
mouseInput.middleButton.pressedChangedHandler = function(objButton, floatValue, boolPressed)
if boolPressed then
mousedown(MOUSEMIDDLE)
else
mouseup(MOUSEMIDDLE)
end
end
end
function ismousedown(bttn)
local mi = nil
if bttn == MOUSELEFT then
mi = mouseInput.leftButton
elseif bttn == MOUSECENTER then
mi = mouseInput.centerButton
elseif bttn == MOUSERIGHT then
mi = mouseInput.rightButton
end
-- Return nil if the button isn't available
if mi == nil then
return nil
end
return (mi.value == 1.0)
end
function hidecursor(shouldHide)
local application = objc.cls.UIApplication.sharedApplication
local window = application.keyWindow
local root = window.rootViewController
local controller = root.presentedViewController.presentedViewController
controller.prefersPointerLocked = shouldHide
end
end
-- Keyboard callbacks
local keyboard = objc.cls.GCKeyboard.coalescedKeyboard
if keyboard then
local keyboardInput = keyboard.keyboardInput
keyboardInput.keyChangedHandler = function(objKeyboard, objKey, intKeyCode, boolPressed)
if boolPressed then
keydown(intKeyCode)
else
keyup(intKeyCode)
end
end
function iskeydown(key)
local k = keyboardInput:buttonForKeyCode_(key)
return (k and (k.value == 1.0)) or false
end
end
-- User callback definitions
function mousemove(dx, dy) end
function mousedown(bttn) end
function mouseup(bttn) end
function keydown(key) end
function keyup(key) end
@Simeon It would be much appreciated if you could make preferspointerlocked available in some form so we can properly hide the cursor to avoid activating system gestures with the mouse.
Edit: Updated with preferspointerlocked & to correct for changes during beta.
@Steppers You should already be able to change the value of preferspointerlocked, but I’m not sure on which UIViewController it must be changed. Maybe try this one?
local application = objc.cls.UIApplication:sharedApplication()
local root = application.keyWindow.rootViewController
local controller = root.presentedViewController.presentedViewController
@jfperusse It’s a readonly property unfortunately. When I’ve used it in the past I’ve had to back it with a variable that can be changed instead and have the accessor just read that.
@Steppers In version 3.5 (322), it is now possible to set the value of preferspointerlocked on our view controller. I used MKInput to test and was able to toggle visibility of the cursor. Let us know if it works for you!
@jfperusse Is there any chance we can check for the presence of a property or method without displaying the warning in the output when it doesn’t exist?
For example if mouseInput.middleButton then displays a warning when I’m using a trackpad with no middle mouse button.
I’d rather it just return nil and not mention it tbh.
Hey everyone, @Steppers! Just wanted to let you know that the latest beta version includes a breaking change which will require minor modifications to your projects using objc.
In previous versions, some property getters had to be accessed through a method. The most common example was objc.cls.UIApplication:sharedApplication(), where sharedApplication is actually a property. This was because of a limitation in Objective-C reflection which does not always allow us to differentiate between a property and a method.
Thanks to @Simeon, we found a better way to support this by considering non-void, parameterless methods as properties, with the exception of new, alloc and init methods.
TL;DR, in your samples, you will need to change some code to access those properties using the dot syntax instead of the colon syntax. For example, this line from MKInput:
objc.cls.GCMouse.current.mouseInput
Note also that we’ve added objc.app (objc.cls.UIApplication.sharedApplication), and objc.viewer (objc.cls.UIApplication.sharedApplication.keyWindow.rootViewController
local controller = root.presentedViewController.presentedViewController).
That’s an odd one, as the property should exist regardless of whether the middle button is supported on the device. It’s declared as an optional GCControllerButtonInput in the SDK
@Steppers Do you still have the warning with 326? That’s an issue I fixed last minute this morning, and I wasn’t getting the warning anymore with MKInput.
#Steppers - probably seen this before but installation of 2 and latest version, from your gist site, rrrored at times with VFS error in line 77. Tied deleting relevant files and commenting out without success. Best I got was a hang up with blank grey screen. This with version 426 Codea and previous version. Suspect I am not installing properly - any ideas?
@Simeon, if my Codea program is running and then i drag right from the left edge to see the code but i do not complete the action i.e. i drag the left edge back- it causes Codea to exit to the desktop.
@piinthesky Does it exit to the desktop without crashing Codea. When I do the above test on my iPad, I go back to the iPad home screen with a Codea crash popup.
@dave1707 thanks for the report, I made this change to fix a different but, but I was aware it could make things slow. I’ll have to look into an alternate fix
@Bri_G I’ve just tried a clean install of WebRepo 2.1.1 using Codea 326 without issue.
Delete the WebRepo project & the folder ‘webrepocache_vfs’ in Codea’s documents folder (using the files app) and try a fresh install again. If it’s a VFS issue I suspect the cache folder has got corrupted somehow. If that doesn’t help let me know.