eXTension Builder
I don't want to get into the language related discussion too much here as this topic is about Widgets, but In case you don't know... eXTension Builder (as I've been labeling it lately while thinking of adding support for the .3 filename extension to .xtb ), is a separate coding language from xTalk script. XTBuilder Serves as an alternative to creating Externals in a foreign coding language like C++, and they binds with engine internals using the same lcdi mechanism. XTBuilder has been design with an effort to making its syntax be xTalk-like and even compatible for select language keywords (the language is also extensible but not getting into that here). However, XTBuilder is still a different animal, may require learning some programming concepts more often found in a bit lower level languages such as C++ or Pascal.
Specifically you must declare variables before using them and variables can be (and usually should be) 'typed', that is to say you must provide info about what type of data the variable will contain. If you aren't sure of the data type yet you can always 'type' the variable 'as optional any' which means allow 'nothing'/void (optional) or anything (any). In general frequently in libraries you'll be using the built-in types 'String' (text), 'Number' (any sort of number) or 'Boolean' or 'Data' (a bunch of bytes) variable types, but there are quite a few more types, many of which are for use with foreign code.
There are variable types that may be defined in specific libraries, such as the Cavas drawing module. The Canvas language module includes definitions for variable types like Canvas, Color, Point, Rectangle, Oval, Path, etc. These are the types used when creating UI graphics to be drawn by libSkia into our Widget's bounding rectangle. Not to be confused with 'Native Layer' Widgets (that's a separate topic), Widgets render with Canvas should generally render identically on every platform. The exception being if the Widget allows use of user installed Fonts, which may appear different due to lack of a font's availability on the target computer (of course there's ways you could embed a copy of the font file, but that may go against a fonts distribution rights). The point is with Canvas Widgets you can get a consistent appearance on any platform.
So with that prelude said, lets look at a widget module's structure:
The module gets wrapped in a module declaration. All modules must have a unique module namespace reverse-DNS-style identifier, such as org.whatever.library.mylib or com.whatever.widget.mywidget.
Code: Select all
widget org.openxtalk.widget.oxtuikitbutton
-- YOUR WIDGET CODE GOES HERE --
end widget
We need some Metadata that will help the scripting engine know how to deal with the module, we should tell it what properties it will have when new instances of the control are created, what its properties should have as their defaults, which editor to use for a given property, etc. In short metadata is how we give our widgets properties.
A Widget should have at minimum it's name, which is different from it's extension namespace identifier (org.openxtalk.widget.whatever), this name will be used when the control is displayed in the IDE, in Tools Palette, in the Extension Manager, and in the Standalone Builder.
Code: Select all
metadata title is "Button-Widget" -- will be the displayed name for the control in the IDE.
metadata author is "Paul McClernan for OpenXTalk.org" -- writing credits
metadata version is "0.0.1" -- version num gets tracked on to the package name when an extension is packed as .lce
metadata preferredSize is "64,128" -- default Height,Width for new instance if the templateWidget has was not set
metadata _ide is "true" -- indicates module is a part of the IDE therefore is non-unloadable.
metadata userVisible is "true" --indicates if users see the module in listings or hides widgets from the Tools palette.
metadata svgicon is "M0,0v69.6c0,1.4,1.1,2.5,2.... z" -- SVG path string to use for the modules Icon in listings in the IDE.
The IDE uses a markdown format for creating documentation, the API.lcdoc that the eXTension Builder creates uses this formatting as the output which is then added to the Syntax Dictionary when an XBuilder module is loaded or installed.
The API data for the API.lcdoc is (typically) parsed from specially formatted block comments within the XTBuilder (or xTalk script) source code that was inserted by the module's author as they're coding.
The first block of these special comments usually appears before the module declaration and can contains info about the widget or library module as a whole such as copyright or license info and it typically includes a general description and uses for the widget or library module.
In a the section above the widget declaration we can add some special inline markdown for any 'messages' that the control may emit using the 'post' command. This is also a way that the IDE knows which control can emit specific messages, which is a factor in creating 'defaultScripts' for use with the control.
For a 'Button' behavior you'll at minimum need to implement mouseUp/mouseDown messages, here's what the declaration for that looks:
Code: Select all
/**
Description: A button widget that has properties commonly found in xTalk 'Button' objects.
Name: mouseMove
Type: message
Name: mouseDown
Type: message
Name: mouseUp
Type: message
Name: mouseRelease
Type: message
**/
widget org.openxtalk.widget.oxtuikitbutton
-- YOUR WIDGET CODE GOES HERE --
First we'll want to pull in any non-default languages modules from the eXTension Builder standard modules that we may want to use. This is done using the 'use' command, which is quite similar to 'include' statements you may have seen in other programming languages like C. For widgets you'll need 'com.livecode.widget', for a canvas drawn widget you're going to also want com.livecode.canvas, and there's a few others I use so often it's now cut-paste 'boiler plate' to add these for a widget as soon as I begin, but they may not all be needed depending on your code:
Code: Select all
-- dependancy declarations
use com.livecode.canvas
use com.livecode.string
use com.livecode.char
use com.livecode.array
use com.livecode.list
use com.livecode.widget
use com.livecode.engine
use com.livecode.library.widgetutils