LiveCode 9 – the final preview

by Ali Lloyd on December 22, 2017 7 comments

LiveCode 9.0.0 DP-11 (AKA the final preview) has been released! We are very excited about this release, it’s absolutely packed full of features and fixes.

Image object SVG Support

Initially, this was going to be a widget extension. But after consulting with the community, and much discussion about what to name the thing, we realised that the best option was to opt straight for what many people really wanted all along- namely adding SVG support to the existing image object. This has the advantage of, among other things, enabling you to use SVG images as button icons.

Two buttons using icons from SVG images

set the text of image 1 to drawingSvgCompileFile("tiger.svg")
set the icon of button 1 to the id of image 1
set the text of image 2 to drawingSvgCompileFile("homer-simpson.svg")
set the icon of button 2 to the id of image 2
set the icongravity of button 1 to "bottomleft"

The image object does not understand SVG directly, but instead you compress an image object to bytecode using the drawingSvgCompileFile or drawingSvgCompile functions, and then set the text. This has the advantage of reducing the size of SVG files, and moreover the compilers are written in LiveCode Script, not LCB or C++, making it possible for community members to extend LiveCode’s SVG support by adding features to the drawing library even more easily.

DataGrid 2

A few months ago, as you’ll no doubt know, we successfully crowd-funded an enhancement to the DataGrid object, plus improved accelerated rendering options which will boost the performance of the DataGrid and other scrolling elements of your app.

In a previous DP we added native mobile scrollers to the datagrid object. In this DP brings a number of improvements to the interactivity of the datagrid, including animated row swipes revealing row actions, and an edit mode in which delete and reorder actions are presented for each row.

A datagrid swipe action revealing an action control

A datagrid in edit mode

An edit mode control revealed by clicking the edit mode action icon

Edit mode drag reordering

All of the controls shown are customisable, meaning the datagrid is even more versatile than ever, enabling you to perfectly emulate native list objects. The groundwork for the improved accelerated rendering options is also done- the project is only a small step away from completion.

HTML5

Multiple stack windows

Basic support for multiple windows has been added to the HTML5 engine. The windows are implemented as canvas elements within the HTML5 page. This allows multiple stacks to be opened on the HTML5 page. Stacks other than the main stack will display in windows layered above the rest of the page. One day we may even be able to run most of the IDE in a browser!

In the meantime though, this just means you can deploy increasingly complex apps to the browser. It also allows tooltips, dialogs, and pop-up menus to work within the HTML5 engine, opening up a whole new set of UI options.

Additional parameter to files/folders function

Here is another feature that we squeezed into 9 DP 11 based on high demand from the community. We had previously added the ability to specify a folder as a parameter to the files and folders functions, allowing you to get lists of files and folders without having to change the defaultFolder (and having to remember to change it back again).

The files() and folders() function now have a second optional argument, allowing “detailed” to be specified. This enables you to get the detailed file and folder information of a particular folder without having to change the defaultFolder. Thus,

get the files(specialFolderPath("desktop"), "detailed")

is now equivalent to

local tOldDefault
put the defaultFolder into tOldDefault
get the detailed files
set the defaultFolder to tOldDefault

Objective-C foreign function interface

There have been a number of enhancements to the Objective-C foreign function interface in this release. Most of these appear quite technical, but the upshot is that now everything in the Mac and iOS SDKs is accessible from LiveCode Builder, meaning that you can wrap any native libraries and views you want.

Dynamic instance binding

Usually you must specify a class when binding to an objective-c selector; if, according to the Objective-C runtime, the class does not exist or does not respond to the selector, you will get a binding error. This is very useful for detecting mistakes, but occasionally you will need to bind to selectors that are not visible to the runtime (see for example the informal delegate support below). In this case, simply omit the class from the binding string. For example, to bind to the NSAlertDelegate method alertShowHelp:

-- bind to delegate protocol method
foreign handler NSAlertDelegateShowHelp(in pTarget as ObjcId, in pAlert as ObjcId) binds to "objc:.-alertShowHelp:"

Delegate support

An incredibly common pattern in Objective-C is the class/delegate pattern where messages triggered by user actions on an object are handled by an assigned delegate.

It is now possible to construct objective-c delegates with LCB handler callbacks. This paves the way for wrapping the NSTextView / UITextView classes to create multi-line text fields on iOS and Mac.

private foreign handler ObjC_NSTextViewSetDelegate(in pView as ObjcId, in pDelegate as ObjcId) returns nothing \
   binds to "objc:NSTextView.-setDelegate:"

private handler DidChangeSelection(in pNotification as ObjcId) returns nothing
	post "selectionChanged"
	MCEngineRunloopBreakWait()
end handler

private unsafe handler SetTextViewDelegate(in pTextView as ObjcObject)
   // Map the textViewDidChangeSelection method of the NSTextViewDelegate protocol
   // to our DidChangeSelection callback handler
   variable tDelegate as ObjcObject
   put CreateObjcDelegate("NSTextViewDelegate", \
			  {"textViewDidChangeSelection:": DidChangeSelection})
	into tDelegate
   ObjC_NSTextViewSetDelegate(pTextView, tDelegate)
end handler

Delegates are a set of implementable methods called a protocol. Some protocols have entirely optional methods, in which case they are not necessarily visible to the objective-c runtime. This will cause the above delegate construction to fail. For this situation, we have provided the ability to create an ‘informal’ delegate using a list of foreign handlers:

// Formal version
private unsafe handler SetTextViewFormalDelegate(in pTextView as ObjcObject)
   // Map the textViewDidChangeSelection method of the NSTextViewDelegate protocol
   // to our DidChangeSelection callback handler
   variable tDelegate as ObjcObject
   put CreateObjcDelegate("NSTextViewDelegate", \
			  {"textViewDidChangeSelection:": DidChangeSelection})
	into tDelegate
   ObjC_NSTextViewSetDelegate(pTextView, tDelegate)
end handler

// Informal version
// Define the protocol's 'interface' using foreign handlers
// The method won't belong to any class, so use the dynamic instance binding
foreign handler NSTextViewDelegateDidChangeSelection(in pDelegate as ObjcId, in pNotification as ObjcId) returns nothing \
   binds to "objc:.-textViewDidChangeSelection:"

private unsafe handler SetTextViewInformalDelegate(in pTextView as ObjcObject)
   // Map the textViewDidChangeSelection method of our informal protocol
   // to our DidChangeSelection callback handler
   variable tDelegate as ObjcObject
   put CreateObjcInformalDelegate([NSTextViewDelegateDidChangeSelection], \
			  {"textViewDidChangeSelection:": DidChangeSelection})
	into tDelegate
   ObjC_NSTextViewSetDelegate(pTextView, tDelegate)
end handler

Dynamic property binding

Similarly, some properties of classes are not synthesized into getters and setters. In this case, the usual way of binding to a property `myProperty` of a class `MyClass` (binding to “objc:MyClass.-myProperty” and “objc:MyClass.-setMyProperty”) would not work. It now does.

Android third-party code

AAR support

An AAR (Android archive) is a package containing various resources and code that can be included as a library in an Android application. In addition to a JAR file, an AAR can contain a ‘resource’ folder containing drawables, layouts etc, and a manifest of its own.

Building on support for JAR files, DP 11 brings support for AAR files with resources, jar files and a manifest. With jar support, it is relatively easy to wrap a third-party library. If the third-party library supports a class that derives from the View class, then that can likely be turned into a widget. For example, the MPAndroidChart library can be turned into a charting widget:

You can also compile your own Java code and access it via LCB, so literally anything that android can run is possible! AAR support means you can access Google Play services and Firebase from LCB, which means you can potentially create extensions for analytics, cloud messaging or maps. On which more later…

Android manifest merging

An android manifest merging mechanism has been added to the android standalone builder. This enables manifests to be included in an extension which are then merged into the main manifest at build time. Previously, it was possible to override the template manifest by providing a new template in a file called AndroidManifest.xml and including it in the Copy Files list. Since the merging mechanism is more general, enables multiple manifests and does not require users to update template manifests with new template replacement strings, this feature has been removed – instead any AndroidManifest.xml files included in the Copy Files list will be merged into the main manifest at build time.

This means that you can potentially have components with all sorts of separate requirements and permissions, and the standalone builder will sort them out so that they are all included in the final APK. Also, it means you don’t have to wait for the standalone builder to be patched if a manifest feature you need is missing – just create your own manifest fragment and add it to copy files!

Extension code library support

Extensions can now include compiled libraries on which they depend. This means that third-party code libraries (or indeed libraries you compile yourself) can be used and bound to from LCB. A whole world of native code libraries is now open to widget and library extension developers. It also means we can port components of the LiveCode engine to extensions, meaning they can be patched and updated ‘out of stream’, so that we can get new features and fixes into your hands faster.

Widget custom property editors

Widgets can include their own property editors. This means that instead of using one of the pre-made property editors that the IDE uses, you can present developers with property editors tailor-made for your widget’s needs. You could even use an instance of your widget as an editor for your widget properties. The Navigation Bar widget in does this in fact, presenting a navigation bar in ‘edit mode’ to allow the navigation data to be edited.

A navigation bar in ‘edit mode’ serving as a property editor

New extensions

A number of new extensions have been added in 9 DP 11, making use of all the new FFI and resource inclusion technology.

Android Toast Notification Library

A toast library has been added. This provides the ability to pop up a transient, non-modal notification to the user. You can specify the length of time the toast should appear for (or just use “short” or “long”):

mobileToast the text of widget 1, "long"

Native Map Widget  (Indy+)

Here is the native map widget on Android, iOS and Mac 64-bit, together with a screenshot of the property inspector for a list of its properties. You can specify marker points with titles and subtitles, and polyline overlays with width and color parameters. The map also post messages when the region changes, or a marker is clicked.

Signature Widget for all platforms (Indy+)

A signature widget has been added – this allows the user to draw freehand while the mouse is down to create a signature, which can then be exported as svg path instructions.

Note, this is not my real signature 😉

SecureKey Library for Mac, iOS and Android (Business)

The SecureKey library provides a way to encrypt data with a private key which is held securely on the device, and tied to the application owning it. This allows you to create apps that deal with sensitive data, which pass stringent of security checks.

Media Foundation External (Business)

A new external has been implemented to allow transcoding and basic editing of videos on Windows. The external supports Windows 8.1+.

Windows camera control (Indy)

Support has been added to the windows camera control for exposure, focus and white balance mode properties.

LCB syntax

System information

Various pieces of system information are now accessible in LiveCode Builder. Firstly, the architecture returns the current platform architecture. Also two new expressions have been added for accessing platform-specific system error status:

  • the system error code evaluates to the current numerical system error code
  • the system error message evaluates to a string describing the current system error

Also the new reset system error statement clears the current system error.

Other features

Of course, all the features in 8.x have been merged up into 9 as well, meaning this release contains support for iOS 11.2 / XCode 9.2, improved script editor autocomplete, separate edition-specific LiveCode server releases available through your account, and many more.

Bugfixes

In case all those features weren’t enough, we also have a plethora of bug fixes. Notably,

Browser widget

We have updated the CEF library that underpins the browser widget on Windows and Linux. As well as having all the latest features and improved stability that this version of CEF provides, we were also able to ensure that the browser widget works again in 64 bit Linux, and indeed that it now works in 32 bit Linux as well. Note that as windowing behaves differently on various Linux distributions and window managers, it would be very helpful to know on which systems the browser widget still doesn’t work. You never know, we might be able to figure it out. So please do retest the browser on your various Linuces (made-up plural of Linux).

Other bugfixes

DP 11 has more than 40 bugfixes alone. Moreover, more than 90 bugfixes that were fixed in LiveCode 8.1.x and 8.2.x, have been merged up.

So there we go, 9 DP 11 is a bumper release, with plenty to investigate and keep you going through the holiday period. We hope you enjoy it, and let us know particularly if you are doing anything interesting with these new features on the forums or in the comments.

Download LiveCode 9 DP11

Ali LloydLiveCode 9 – the final preview

7 comments

Join the conversation
  • Roland Hüttmann - December 22, 2017 reply

    Phantastic. Thank you. Wishing you a Happy Christmas and New Year and big thanks to such great gift! A fully admiring Indy- and Community Edition user.

  • max - December 25, 2017 reply

    datagrid2 is missing in this release, when will you add it?

    Ali Lloyd - December 25, 2017 reply

    Can you be more specific? I’ve detailed which parts are included and not in terms of the project above. In what sense do you think it is missing? Where are you looking?

  • Fredp - December 29, 2017 reply

    Also can not find Datagrid 2?
    As far as was indicated it would of been part of DP11.

  • Sphere - December 30, 2017 reply

    This is all really great! too much to explore 🙂
    Thanks! Have a great new year!

  • shaosean - January 19, 2018 reply

    In the example code above, for the new Cocoa Delegates, the sample code for Informal Delegates shows the use of “CreateObjcDelegate” shouldn’t that be “CreateObjcInformalDelegate” ?

    Ali Lloyd - January 19, 2018 reply

    Indeed it should, good catch! Now fixed.

Join the conversation

*