Archive
Quartex Media Desktop, new compiler and general progress
It’s been a few weeks since my last update on the project. The reason I dont blog that often about Quartex Media Desktop (QTXMD), is because the official user-group has grown to 2000+ members. So it’s easier for me to post developer updates directly to the audience rather than writing articles about it.
If you haven’t bothered digging into the project, let me try to sum it up for you quickly.
Quick recap on Quartex Media Desktop
To understand what makes this project special, first consider the relationship between Microsoft Windows and a desktop program. The operating system, be it Windows, Linux or OSX – provides an infrastructure that makes complex applications possible. The operating-system offers functions and services that programs can rely on.
The most obvious being:
- A filesystem and the ability to save and load data
- A windowing toolkit so programs can be displayed and have a UI
- A message system so programs can communicate with the OS
- A service stack that takes care of background tasks
- Authorization and identity management (security)
I have just described what the Quartex Media Desktop is all about. The goal is simple:
to provide for JavaScript what Windows and OS X provides for ordinary programs.
Just stop and think about this. Every “web application” you have ever seen, have all lacked these fundamental features. Sure you have libraries that gives you a windowing environment for Javascript, like Embarcadero Sencha; but im talking about something a bit more elaborate. Creating windows and buttons is easy, but what about ownership? A runtime environment has to keep track of the resources a program allocates, and make sure that security applies at every step.
Target audience and purpose
Take a second and think about how many services you use that have a web interface. In your house you probably have a router, and all routers can be administered via the browser. Sadly, most routers operate with a crude design and that leaves much to be desired.

Router interfaces for web are typically very limited and plain looking. Imagine what NetGear could do with Quartex Media Desktop instead
If you like to watch movies you probably have a Plex or Kodi system running somewhere in your house; perhaps you access that directly via your TV – or via a modern media system like Playstation 4 or XBox one. Both Plex and Kodi have web-based interfaces.
Netflix is now omnipresent and have practically become an institution in it’s own right. Netflix is often installed as an app – but the app is just a thin wrapper around a web-interface. That way they dont have to code apps for every possible device and OS out there.
If you commute via train in Scandinavia, chances are you buy tickets on a kiosk booth. Most of these booths run embedded software and the interface is again web based. That way they can update the whole interface without manually installing new software on each device.
These are just examples of web based interfaces you might know and use; devices that leverage web technology. As a developer, wouldn’t it be cool if there was a system that could be forked, adapted and provide advanced functionality out of the box?
Just imagine a cheap Jensen router with a Quartex Media Desktop interface! It could provide a proper UI interface with applications that run in a windowing environment. They could disable ordinary desktop functionality and run their single application in kiosk mode. Taking full advantage of the underlying functionality without loss of security.
And the same is true for you. If you have a great idea for a web based application, you can fork the system, adjust it to suit your needs – and deploy a cutting edge cloud system in days rather than months!
New compiler?
Up until recently I used Smart Mobile Studio. But since I have left that company, the matter became somewhat pressing. I mean, QTXMD is an open-source system and cant really rely on third-party intellectual property. Eventually I fired up Delphi, forked the latest DWScript, and used that to roll a new command-line compiler.

Web technology has reached a level of performance that rivals native applications. You can pretty much retire Photoshop in favour of web based applications these days
But with a new compiler I also need a new RTL. Thankfully I have been coding away on the new RTL for over a year, but there is still a lot of work to do. I essentially have to implement the same functionality from scratch.
There will be more info on the new compiler / codegen when its production ready.
Progress
If I was to list all the work I have done since my last post, this article would be a small book. But to sum up the good stuff:
- Authentication has been moved into it’s own service
- The core (the main server) now delegates login messages to said service
- We no longer rely on the Smart Pascal filesystem drivers, but use the raw node.js functions instead (faster)
- The desktop now use the Smart Theme engine. This means that we can style the desktop to whatever we like. The OS4 theme that was hardcoded will be moved into its own proper theme-file. This means the user can select between OS4, iOS, Android and Ubuntu styling. Creating your own theme-files is also possible. The Smart theme-engine will be replaced by a more elaborate system in QTX later
- Ragnarok (the message api) messages now supports routing. If a routing structure is provided, the core will relay the message to the process in question (providing security allows said routing for the user)
- The desktop now checks for .info files when listing a directory. If a file is accompanied by an .info file, the icon is extracted and shown for that file
- Most of the service layer now relies on the QTX RTL files. We still have some dependencies on the Smart Pascal RTL, but we are making good progress on QTX. Eventually the whole system will have no dependencies outside QTX – and can thus be compiled without any financial obligations.
- QTX has it’s own node.js classes, including server and client base-classes
- Http(s) client and server classes are added to QTX
- Websocket and WebSocket-Secure are added to QTX
- TQTXHybridServer unifies http and websocket. Meaning that this server type can handle both orinary http requests – but also websocket connections on the same network socket. This is highly efficient for websocket based services
- UDP classes for node.js are implemented, both client and server
- Zero-Config classes are now added. This is used by the core for service discovery. Meaning that the child services hosted on another machine will automatically locate the core without knowing the IP. This is very important for machine clustering (optional, you can define a clear IP in the core preferences file)
- Fixed a bug where the scrollbars would corrupt widget states
- Added API functions for setting the scrollbars from hosted applications (so applications can tell the desktop that it needs scrollbar, and set the values)
- .. and much, much more
I will keep you all posted about the progress — the core (the fundamental system) is set for release in december – so time is of the essence! Im allocating more or less all my free time to this, and it will be ready to rock around xmas.
When the core is out, I can focus solely on the applications. Everything from Notepad to Calculator needs to be there, and more importantly — the developer tools. The CloudForge IDE for developers is set for 2020. With that in place you can write applications for iOS, Android, Windows, OS X and Linux directly from Quartex Media Desktop. Nothing to install, you just need a modern browser and a QTX account.
The system is brilliant for small teams and companies. They can setup their own instance, communicate directly via the server (text chat and video chat is scheduled) and work on their products in concert.
Getting into Node.js from Delphi
Delphi is one of the best development toolchains for Windows. I have been an avid fan of Delphi since it was first released, and before that – Turbo Pascal too. Delphi has a healthy following – and despite popular belief, Delphi scores quite well on the Tiobe Index.
As cool and efficient as Delphi might be, there are situations where native code wont work. Or at the very least, be less efficient than the alternatives. Delphi has a broad wingspan, from low-level assembler all the way to classes and generics. But JavaScript and emerging web technology is based on a completely different philosophy, one where native code is regarded as negative since it binds you to hardware.
Getting to grips with the whole JavaScript phenomenon, be it for mobile, embedded or back-end services, can be daunting if all you know is native code. But thankfully there are alternatives that can help you become productive quickly, something I will brush over in this post.
JavaScript without JavaScript
Before we dig into the tools of the trade, I want to cover alternative ways of enjoying the power of node.js and Javascript. Namely by using compilers that can convert code from a traditional language – and emit fully working JavaScript. There are a lot more options than you think:

Quartex Media Desktop is a complete environment written purely in JavaScript. Both Server, Cluster and front-end is pure JavaScript. A good example of what can be done.
- Swift compiles for JavaScript, and Apple is doing some amazing things with the new and sexy SwiftUI tookit. If you know your way around Swift, you can compile for Javascript
- Go can likewise be compiled to JS:
- C/C++ can be compiled to asm.js courtesy of EmScripten. It uses clang to first compile your code to llvm bitcode, and then it converts that into asm.js. You have probably seen games like Quake run in the browser? That was asm.js, a kind of precursor to WebAssembly.
- NS Basic compiles for JavaScript, this is a Visual Basic 6 style environment with its own IDE even
For those coming straight from Delphi, there are a couple of options to pick from:
- Freepascal (pas2js project)
- DWScript compiles code to JavaScript, this is the same compiler that we used in Smart Pascal earlier
- Oxygene, the next generation object-pascal from RemObjects compiles to WebAssembly. This is by far the best option of them all.

I strongly urge you to have a look at Elements, here running in Visual Studio
JavaScript, Asm.js or WebAssembly?
Asm.js is by far the most misunderstood technology in the JavaScript ecosystem, so let me just cover that before we move on:
A few years back JavaScript gained support for memory buffers and typed arrays. This might not sound very exciting, but in terms of speed – the difference is tremendous. The default variable type in JavaScript is what Delphi developers know as Variant. It assumes the datatype of the values you assign to it. Needless to say, there is a lot of overhead when working with variants – so JavaScript suddenly getting proper typed arrays was a huge deal.
It was then discovered that JavaScript could manipulate these arrays and buffers at high speed, providing it only used a subset of the language. A subset that the JavaScript runtime could JIT compile more easily (turn into machine-code).
So what the EmScripten team did was to implement a bytecode based virtual-machine in Javascript, and then they compile C/C++ to bytecodes. I know, it’s a huge project, but the results speak for themselves — before WebAssembly, this was as fast as it got with JavaScript.
WebAssembly
WebAssembly is different from both vanilla JavaScript and Asm.js. First of all, it’s executed at high speed by the browser itself. Not like asm.js where these bytecodes were executed by JavaScript code.

Water is a fast, slick and platform independent IDE for Elements. The same IDE for OS X is called Fire. You can use RemObjects Elements from either Visual Studio or Water
Secondly, WebAssembly is completely JIT compiled by the browser or node.js when loading. It’s not like Asm.js where some parts are compiled, others are interpreted. WebAssembly runs at full speed and have nothing to do with traditional JavaScript. It’s actually a completely separate engine.
Out of all the options on the table, WebAssembly is the technology with the best performance.
Kits and strategies
The first thing you need to be clear about, is what you want to work with. The needs and requirements of a game developer will be very different from a system service developer.
Here are a couple of kits to think about:
- Mobile developer
- Implement your mobile applications using Oxygene, compiling for WebAssembly (Elements)
- RemObjects Remoting SDK for client / server communication
- Use Freepascal for vanilla JavaScript scaffolding when needed
- Service developer
- Implement libraries in Oxygene to benefit from the speed of WebAssembly
- Use RemObjects Data Abstract to make data-access uniform and fast
- Use Freepascal for boilerplate node.js logic
- Desktop developer
- For platform independent desktop applications, WebAssembly is the way to go. You will need some scaffolding (plain Javascript) to communicate with the application host – but the 99.9% of your code will be better under WebAssembly.
- Use Cordova / Phonegap to “bundle” your WebAssembly, HTML5 files and CSS styling into a single, final executable.
The most important part to think about when getting into JavaScript, is to look closely at the benefits and limitation of each technology.
WebAssembly is fast, wicked fast, and let’s you write code like you are used to from Delphi. Things like pointers etc are supported in Elements, which means ordinary code that use pointers will port over with ease. You are also not bound on hand-and-feet to a particular framework.
For example, EmScripten for C/C++ have almost nothing in terms of UI functionality. The visual part is a custom build of SDL (simple directmedia layer), which fakes the graphics onto an ordinary HTML5 canvas. This makes EmScripten a good candidate for porting games written in C/C++ to the web — but it’s less than optimal for writing serious applications.
Setting up the common tools
So far we have looked at a couple of alternatives for getting into the wonderful world of JavaScript in lieu of other languages. But what if you just want to get started with the typical tools JS developers use?

Visual Studio Code is a pretty amazing code-editor
The first “must have” is Visual Studio Code. This is actually a great example of what you can achieve with JavaScript, because the entire editor and program is written in JavaScript. But I want to stress that this editor is THE editor to get. The way you work with files in JS is very different from Delphi, C# and Java. JavaScript projects are often more fragmented, with less code in each file – organized by name.

TypeScript was invented by Anders Hejlsberg, who also made Delphi and C#
The next “must have” is without a doubt TypeScript. Personally im not too fond of TypeScript, but if ordinary JavaScript makes your head hurt and you want classes and ordinary inheritance, then TypeScript is a step up.
Next on the list is AssemblyScript. This is a post-processor for TypeScript that converts your code into WebAssembly. It lacks much of the charm and elegance of Oxygene, but I suspect that has to do with old habits. When you have been reading object-pascal for 20 years, you feel more at home there.
You will also need to install node.js, which is the runtime engine for running JavaScript as services. Node.js is heavily optimized for writing server software, but it’s actually a brilliant way to write services that are multi-platform. Because Node.js delivers the same behavior regardless of underlying operating system.
And finally, since you definitely want to convert your JavaScript and/or WebAssembly into a stand-alone executable: you will need Adobe Phonegap.
Visual Studio
No matter if you want to enter JavaScript via Elements or something else, Visual Studio will save you a lot of time, especially if you plan on targeting Azure or Amazon services. Downloading and installing the community edition is a good idea, and you can use that while exploring your options.
When it comes to writing system services, you also want to check out NPM, the node.js package manager. The JavaScript ecosystem is heavily package oriented – and npm gives you some 800.000 packages to play with free of charge.
Just to be clear, npm is a shell command you use to install or remove packages. NPM is also a online repository of said packages, where you can search and find what you need. Most packages are hosted on github, but when you install a package locally into your application folder – npm figures out dependencies etc. automatically for you.
Books, glorious books
Last but not least, get some good books. Seriously, it will save you so much time and frustration. Amazon have tons of great books, be it vanilla JavaScript, TypeScript, Node.js — pick some good ones and take the time to consume the material.
And again, I strongly urge you to have a look at Elements when it comes to WebAssembly. WebAssembly is a harsh and barren canvas, and being able to use the Elements RTL is a huge boost.
But regardless of path you pick, you will always benefit from learning vanilla JavaScript.
Smart Mobile Studio: Q&A about v3.0 and beyond
A couple of days back I posted a sneak-peek of our upcoming Smart Mobile Studio 3.0 web desktop framework; as a consequence my Facebook messenger app has practically exploded with questions.
As you can imagine, the questions people ask are often very similar; so similar in fact that I will answer the hottest topics here. Hopefully that will make it easier for everyone.
If you have further questions then either ask them on our product forums or the Delphi Developer group on Facebook.
Generics
Yes indeed we have generics running in the labs. We havent set a date on when we will merge the new compiler-core, but it’s not going to happen until (at the earliest) v3.4. So it’s very much a part of Smart’s future but we have a couple of steps left on our time-line for v3.0 through v3.4.
RTTI access
RTTI is actually in the current version, but sadly there is a bug there that causes the code generator to throw a fit. The fix for this depends on a lot of the sub-strata in the new compiler-core, so it will be available when generics is available.
Associative arrays
This is ready and waiting in the new core, so it will appear together with generics and RTTI.
Databases
We have supported databases since day 1, but the challenge with JavaScript is that there are no “standards” like we are used to from established systems like Delphi or Lazarus.
Under the browser we support WebSQL and our own TW3Dataset. We also compiled SQLite from native C to JavaScript so we can provide a fast, lightweight SQL engine for the browser regardless of what the W3C might do (WebSQL has been deprecated but will be around for many years still).
Server side it’s a whole different ballgame. There you have drivers (or modules) for every possible database you can think of, even Firebird. But each module is implemented as the authors see fit. This is where our Database framework comes in, sets a standard, and we then inherit out classes and implement the engines we want.
This framework and standard is being written now, but it wont be introduced until v3.1 and v3.2. In the meantime you have sqlite both server-side and client-side, WebSQL and TW3Dataset.
Attributes
This question is often asked separately from RTTI, but it’s ultimately an essential part of what RTTI delivers.
So same answer: it will arrive with the new compiler-core / infrastructure.
Server-side scripting
While we do see how this could be useful, it requires a substantial body of work to make a reality. Not only would we have to implement the whole “system” namespace from scratch since JavaScript would not be present, but we would also have to introduce a a secondary namespace; one that would be incompatible with the whole RTL at a fundamental level. Instead of going down this route we opted for Node.js where creating the server itself is the norm.
If we ever add server-side scripting it would be JavaScript support under node.js by compiling the V8 engine from C to asm.js. But right now our focus is not on server-side-scripting, but on cloud building-blocks.
Bytecode compilation
I implemented the assembler and runtime for our bytecode system (LDef) this winter / early spring; So we actually have the means to create a pure bytecode compiler and runtime.
But this is not a priority for us at this time. Smart Mobile Studio was made for JavaScript and while it would be cool to compile Delphi sourcecode to portable bytecodes, such a project would require not just a couple of namespaces – but a complete rewrite of the RTL. The assembler source-code and parser can be found in the “Next Generation Demos” folder (Smart Mobile Studio 3.0 demos). Feel free to build on the codebase if you fancy creating your own language;Get creative and enjoy! **Note: Using the assembler in your own projects requires a valid Smart Mobile license.
Native Apps
It’s interesting that people still ask this, since its one of our central advantages. We already generate native apps via the Phonegap post-processor.

Phonegap turns your JS apps into native apps
Phonegap takes your compiled Smart (visual projects only) compiled code, processes it, and spits out native apps for every mobile OS on the market (and more). So you don’t have to compile especially for iOS, Android, Tizen or FireOS — Phonegap generates one for each system you need, ready for AppStore.
So we have native covered by proxy. And with millions of users Phonegap is not going anywhere.
Release date
We are going over the last beta as I type this, and Smart Mobile Studio 3.0 should be available next week. Which day is not easy to say, but at least before next weekend if all goes accoring to plan.
Make sure you visit www.smartmobilestudio.com and buy your license!
HTML5 Attributes, learn how to trigger conditional styling with Smart Mobile Studio
Im not sure if I have written about Attributes before; Probably, because they are so awesome to work with. But today I’m going to show you something that makes it even more awesome, bordering on unbelievable.
What are HTML attributes again?
Before we dig into the juicy stuff, let’s talk about attributes. For those that dont know much about HTML or CSS, here is a quick and dirty overview. A lot of people use Smart Mobile Studio because they dont know CSS or HTML beyond the basics (or even because they dont want to learn it, quite a few cant stand JavaScript and CSS). Well that is not a problem.
Note-1: While not a vital prerequisite, I do suggest you buy a good book on JavaScript, HTML and CSS. If you are serious about using web technology (like node.js on the server) your Smart skills will benefit greatly by knowing how things work “under the hood” so to speak. You will make better Smart Mobile Studio applications and you will understand the RTL at a deeper level than the average user.
OK, back to attributes. You know how HTML tags have parameters right? For example, a link to another webpage looks like this:
<a href="http://blablabla">This is a link</a>
Note-2: I dont have time to teach you HTML from scratch, so if you have no idea what the “A” tag is then please google it.
Focus here is not on the “a” part, but rather on the “href” parameter. That is actually not a parameter but a tag-attribute (which must not be confused with a tag-property btw).
Back in the day attributes used to be exclusive; Meaning that if you tried to set some attribute value the tag didnt support – nothing would happen. The browser would just ignore it and the information would be deleted.
Around HTML4 all of that changed. Suddenly we got the freedom to declare our own attributes, regardless of tag. The only catch is that the attribute name must be prefixed with “data-“. Which makes sense because the browser needs to tell the difference between valid attributes, junk and intrinsic (supported) attributes.
Storing information outside the pascal instance
When you create a visual control, the control internally creates a DOM element (or tag object, same thing) that it manages. Most visual controls in our RTL manages a DIV element because that is just a square block that can be easily molded and shaped into whatever you like.
But, when you create a Smart Pascal class you dont just get a DOM element in return. You get a Smart Pascal object instance. This is the same as Delphi and Lazarus: a class is a blueprint of an object. You dont create classes you create instances.
The same thing happens when you use Smart Pascal: the JSVM (JavaScript virtual machine) delivers a JavaScript object instance – and that is what your code operates on. When you create a visual class instance, that in turn will create a DOM element and manage that until you release the Smart Pascal instance.
Storing information in a class is easy. It’s one of the fundamental aspects of object oriented programming and there really isnt that much to say about that. But what if you need to store information in a control you dont own? Perhaps you have installed a package you bought, or that a friend shared with you – and you cant change the class (or perhaps dont want to change the class). What then?
This is where the attribute object comes to the rescue. Because now you can store information directly in the DOM element rather than altering the class itself (!)
That is so powerful I dont even know where to start, because you can write libraries that can do amazing things without fields or demanding the user to change their controls (and in some cases, avoid forcing the user to inherit from a particular custom-control).
A real-life example
Our special effect unit, SmartCL.Effects.pas, uses this technique to keep track of effect state. When you execute an effect on a control a busy-flag is written as an attribute to the managed DOM object. And when the effect is finished the busy-flag is reset.
If you execute 10 effects on a control, it’s this busy flag that stops all of them running at the same time (which would cause havoc). While this attribute is set any queued effects wait their turn.
This would be impossible to achieve without declaring a busy property, or doing some form of stacking behind the scene; both of them expensive codewise. But with attributes it’s a piece of cake.
And now for the juicy parts
Now that you know what attributes do and how awesome they are, what can possibly make them even more awesome? In short: “CSS attribute pseudo selectors” (phew, that is a mouthful isnt it!).
So what the heck is a pseudo selector? Again its a long story, so im just going to call it “states”. It allows you to define styles that should be activated when a particular state occurs. The most typical state is the :active state. When you press a button the DOM element is said to be active. This allows us to write CSS styles that are applied when you press the button (like changing the background, border or font-color).
But did you know you can also define styles that react to attribute changes?
Just stop and think about this for a moment:
- You can define your own attributes
- You can read, write and check for attributes
- Attributes are part of the DOM element, not the JS instance
- You can define CSS that apply when an element has an attribute
- You can define CSS that apply if an attribute has a particular value
If you are still wondering what the heck this is good for, imagine the following:
With this, you can do the following:
- Write an event-handler for TW3Application.OnOrientationChange (an event that fires when the user rotate the mobile device horizontally or vertically).
- Store the orientation as a attribute value
- Define CSS especially for the orientation attribute values
The browser will automatically notice the attribute change and apply the corresponding CSS. This is probably one of the coolest CSS features ever.
Other things that come to mind:
- You can write CSS that colors the rows in a grid or listbox based on the data-type the row contains. So an integer can have a different background from a float, boolean or string. And all of it can be automated with no code required on your part. You just need to write the CSS rule once and that’s it.
- You can use attributes it to trigger pre-defined animations. In fact, you could pre define 100 different animations, and based on the attribute-name you can trigger the correct one. Again all of it can be neatly implemented as CSS.
Let’s make a button that triggers a style
While simple, the following example should serve as a good example. It’s easy to build on and not to complex. Let’s start with the CSS:
button[data-funky="this rocks"] { background: none; background-color: #FF00FF; font-color: #FFFFFF; font-size: 22px; font-weight: bold; }
The CSS above should be easy to understand. First we define the name of the DOM element, which in my case is a button. Next we define the attribute, and like mentioned it has to be prefxed with “data-” (our attributes class does this automatically in the RTL, so you dont need to prefix it when you code). And finally we define the value the style should trigger on, “this rocks”.
Right, let’s write some code:
var MyButton := TW3Button.Create(self); MyButton.SetBounds(100,280, 100, 44); MyButton.Caption := 'Click me!'; MyButton.OnClick := procedure (Sender: TObject) begin var Text := MyButton.Attributes.Read('funky'); if Text <> 'this rocks' then MyButton.Attributes.Write('funky','this rocks') else MyButton.Attributes.Write('funky',''); end;
The code is very simple, we read the value of the attribute and then we do a toggle based on the content. So when you click the button it will just toggle the trigger value.
This is how the button looks before we click it:
And when we click the button the attribute is written to, and it’s automatically styled:
How cool is that! The things you can automate with this is almost endless. It is a huge boon for anyone writing mobile applications with Smart Mobile Studio and it makes what would otherwise be a difficult task ridiculously easy.
Cheers!
ClientRect, BoundsRect and adventures in Smart Pascal layout land
HTML really is the kitchen sink of ideas. Some of them are good, others are bad – but all them have valid reason for being there.
When coming from Delphi or C++ builder to web development you really feel like you have tumbled down the rabbit hole from time to time. Especially when it comes to things like margins, padding and clientrect values.
You would imagine that BoundsRect gives you the full size of a control. In fact BoundsRect() should just be the same as putting left, top, width, height into a TRect structure right? Same with ClientRect, it should be the same as putting 0, 0, ClientWidth, ClientHeight into a TRect structure right?
Smart Mobile Studio uses absolute positioning, which means that you can layout controls at ordinary cartesian coordinate values. If you place a button at position 10, 10 – that means 10 pixels from the left edge and 10 pixels from the top edge. This is what we are used to from Delphi and other native languages.
But the browser have different boxing models, or box-sizing modes if you like. We are using the one best suited for per-pixel-positioning, namely “border-box”. This means that the width and height values for the control will include the size of the content, it’s padding and the size of the border. It excludes things like margin since that is just empty air the browser adds to the final co-ordinates of a visual control.
Doing it by the book
Since we are taking Smart out of the homebrew production style these days, there had to come a time where this must be dealt with.
If you don’t care about making your own controls then this wont effect you at all. You will always be able to drag & drop some controls on the form-designer, or (like most of us does) create them from code and perform layout during the Resize() method.
But .. if you want to make controls that conforms to our theme engine, that actually give a damn about margins, padding and wants give CSS the power to change existing controls the way it deserves, then you better pay attention.
Having experimented with this for a while now, here are the two cardinal rules you must follow if you want your controls to take height for the margin, padding and border-sizes defined in our CSS theme files:
- Margins only apply when positioning child elements with margins
- When doing layout of child elements, padding only apply from the parent or container of content, not the content itself.
Example for rule #1
Imagine you have a panel on a form. You want to populate that panel with 10 child elements and you want to do it properly, taking height for whatever padding the panel may have – and also whatever margin’s may exist for some child elements.
var dx := W3Panel1.Border.Left.Padding; var dy := W3Panel1.Border.Top.Padding; for var x := 0 to 9 do begin var Item := FItems[x]; var ItemRect := TRect.Create(dx, dy, Item.width, item. height); ItemRect.right -= (Item.Border.Margin.Left + Item.Border.Margin.Right); ItemRect.bottom -= (Item.Border.Margin.Top + Item.Border.Margin.Bottom); Item.SetBounds(ItemRect); end;
Look at the code above. Notice that we dont initialize dx and dy to 0 (zero). We could ofcourse but that would defeat the purpose of being CSS friendsly.
Also notice that we dont add the left and top margin to the final rectangle, this is because the browser automatically does this for us. Instead, we need to scale the right and bottom edge of the rectangle by subtracting the size of the left and right / top and bottom margins.
So if you want theme friendly layout’s, you have to go the extra mile and include these things.
Note: The above was just an example, our ClientRect() function already deals with padding for us, so you would set dx and dy to ClientRect.left and ClientRect.top.
ClientWidth and ClientHeight methods however, remain unaffected by padding. Because there will be cases where you want full control and non-conformity.
Example of rule #2
Think of a text-editor. You want to add a bit of margin to the document and simply drag the left-margin widget to where you need it. Padding for HTML elements works pretty much the same way.
To demonstrate I will create a test container class and a test child class.
First, create a new visual application to play with. Drop a TW3Panel control on the form and size it to full the form (with a bit of air from the edges naturally).
Next, go into project options and check the “use custom stylesheet”. That way Smart will clone whatever style you are using and create a new node in your project manager. Add the following CSS to the stylesheet:
.TTestOwner { margin: 20px; padding: 4px; border: 3px solid #FFFF00; background-color: #FF0000; } .TTestChild { margin: 10px; padding: 4px; border: 3px solid #000000; background-color: #FFFFFF; }
With the CSS in place, add the following pascal classes to your mainform code, just below the “type” keyword:
TTestChild = class(TW3CustomControl) end; TTestOwner = class(TW3CustomControl) end;
Now, prior to writing this article I make a couple of helper functions. If you are using Alpha 1 (which most of you are), add the following class and code to your form1 unit:
TW3Theme = class public class function AdjustRectToLayoutFactors(const ThisControl: TW3MovableControl; const Rect: TRect): TRect; class function GetPaddedClientRect(const ThisControl: TW3MovableControl): TRect; end; class function TW3Theme.GetPaddedClientRect(const ThisControl: TW3MovableControl): TRect; begin if ThisControl <> nil then begin result := TRect.Create(0, 0, ThisControl.ClientWidth, ThisControl.ClientHeight); result.Left += ThisControl.Border.Left.Padding; result.Top += ThisControl.Border.Top.Padding; result.Right -= ThisControl.Border.Right.Padding; result.Bottom -= ThisControl.Border.Bottom.Padding; end else result := TRect.NullRect; end; class function TW3Theme.AdjustRectToLayoutFactors(const ThisControl: TW3MovableControl; const Rect: TRect): TRect; begin if ThisControl <> nil then begin (* Rule #1, "margins should only be added when dealing with child elements" Since we are usins "border-box" as our size model, padding and border is already included in the clientwidth / clientheight values we get from the system. More importantly, margin only affect left and top edge of a rectangle because those are the only factors that affect MoveTo() type functionality in the browser itself. So when the browser moves an element to position 10px, 10px, it automatically adds the margin. If you have a margin of 10 pixels - the result will be (visually) that the control ends up at 20px, 20px instead. *) // Start with a carbon copy of the rectangle we were given result := Rect; (* Note: The browser can only know about the left and top edge when placing elements. It cannot see into the future to know the exact height of an element, or if the content will suddenly grow. So we have to calculate the right and bottom based on our knowledge from the Rect parameter *) result.right -= (ThisControl.border.left.margin + ThisControl.border.right.margin); result.bottom -= (ThisControl.border.top.margin + ThisControl.border.bottom.margin); (* Rule #2: Padding should only be applied from a control's padding when calculating a position for that child. This is recursive, so a parent will apply this to their children, which each child will force it's padding on any children it may house. *) if ThisControl.parent <> nil then begin var Owner := TW3MovableControl(ThisControl.Parent); result.left += Owner.border.left.padding; result.top += owner.border.top.padding; result.right -= owner.border.right.padding; result.bottom -= owner.border.bottom.padding; end; end; end;
With both styling and the pascal classes out-of-the-way, lets add some code to get the magic working.
So copy & paste this into your W3Form1.InitializeForm() procedure:
var LRect: TRect; var Box: TTestOwner; var Child: TTestChild; // Create parent container Box := TTestOwner.Create(W3Panel1); LRect := TRect.Create(0, 0, W3Panel1.ClientWidth, 300); LRect := TW3Theme.AdjustRectToLayoutFactors(Box, LRect); Box.SetBounds(LRect); // create child element for our test-owner Child := TTestChild.Create(Box); LRect := TRect.Create(0, 0, box.ClientWidth, box.ClientHeight); LRect := TW3Theme.AdjustRectToLayoutFactors(Child, LRect); Child.SetBounds(LRect);
Note: The TW3Theme class is a part of Alpha 2 which should hit the download section next week. But you should now have everything you need to get this working, no matter what version of Smart Mobile Studio you are using.
Putting it all together
OK, lets run our application and have a look at the results. What we should see is a panel on a form – inside that should be a box that is 20 pixels from the edges (since the CSS defines 20 pixel margins). The box also has 4 pixel padding defined, so the total offset from the edges should be 24 pixels.
The child control inside the box likewise has margin and padding. It operates with 10 pixels of margin and 4 pixels padding. It also sports a 3 pixel border. So let’s see what we have so far:
As you can see it’s not that hard to deal with; just a bit of a brain teaser. Those that write custom controls for Delphi are used to dealing with stuff like this all the time. The difference is that native languages are less cryptic about things, and they also make width / height return the full size of the control. Regardless of what the content may be.
You might have noticed that Delphi has a new “Align with margin” property? Not sure when it came into the system but somewhere around Delphi XE I believe (?). There you define the size of the margin – and Delphi does the rest. You don’t have to think about the size of the margin, and it only comes into play when the Align property is activated.
Final notes
We are doing some brainstorming on how to best deal with these things right now. Personally I think the code I have shown so far, especially the helper code, goes a long way to make this easy to work with.
Some have voiced that ClientRect should always start at zero, but why is that? Where does it say that Clientrect should always be “0,0, width-1, height-1” ? That is not the voice of reason, that is the sound of old habits! The whole point of having a ClientRect, be it in Delphi, Lazarus, C++ or C# is because this can change. It would be equally futile to demand that ClipRect should always be the same as client-rect. That is to utterly miss the whole point of sequential rendering and fast graphics.
So the lesson is: If you play by the rules and never use hard-coded values, then your code wont be affected. And if you want to adjust so your code is 100% theme compatible (and again, this only is valuable for component writers) then calling a simple function to get the rectangle adjusted for margin etc. is not exactly rocket science. It’s a one-liner.
Well, hope it helps!
Custom dialog and loading data from JSON in Smart Pascal
Right now we are putting the finishing touches on our next update, which contains our new theme engine. As mentioned earlier (especially if you follow us on Facebook) the new system builds on the older – but we have separated border and background from the basic element styling.
When working with the new theme system, I needed an application that could demonstrate and show all the different border and background types, most of our visual controls – but also information about what Smart Mobile Studio is, what it’s features are and where you can buy it.
So it started as a personal application just to get a good overview of the CSS themes I was working on; but it has become an example in it’s own right.
Dont hardcode, just dont
If you look at the picture above, there is a MenuList with the options: “Introduction”, “Features” and “Where to buy”. When you click these I naturally want to inform the user about these things by displaying information.
I could have hardcoded the information text into the application; in many ways that would have been simpler (considering the data requirements here is practically insignificant). but all that text within the source? I hate mess like that.
Secondly, how exactly was I going to show this information? Would I use the modal framework already in place, or code something more lightweight?
As always I ended up making a new and more lightweight system. A reader style dialog appears and allows you to scroll vertically. The header contains the title of the information and a close button.

Typical “reader” style dialog with scrolling
I also used a block-box to prevent the user from reaching the UI until they click the close-button. You notice that the form, toolbar and header in the back is darkened. This is actually a control that is semi-transparent that does one thing: prevent anyone from clicking or interacting with the UI while the dialog is active.
The JSON file structure
The structure I needed was very simple: our records would have a unique ID that we use to fetch and recognize content; It would also have a Title and Text property. It really doesnt have to be more difficult than that.
To work with the JSON i used the online JSON editor JSonEditorOnline, which is actually really good! It allows you to write your JSON and then format it so that special characters (like CR+LF) is properly encoded.
Putting it all together
Having coded the dialog thing first, I now sat down and finished a sort of “Turbo Pascal” record database system for this particular file format. It’s not very big nor extremely advanced – but that’s the entire point! Throwing in SQLite or MongoDB for something as simple as a few records of data – especially when the data is so simple, is just a complete waste of time and effort.
Right, let’s have a peek at the code shall we!
unit infodialog; interface uses System.Types, System.Types.Convert, System.Types.Graphics, System.Colors, System.JSON, SmartCL.Theme, SmartCL.FileUtils, SmartCL.System, SmartCL.Effects, SmartCL.Components, SmartCL.Scroll, SmartCL.Controls.Panel, SmartCL.Controls.Scrollbox, SmartCL.Controls.Header; type TInfoDialog = class(TW3Panel) private FHead: TW3HeaderControl; FBox: TW3Scrollbox; protected procedure InitializeObject; override; procedure FinalizeObject; override; procedure Resize; override; public property Header: TW3HeaderControl read FHead; property Content: TW3Scrollbox read FBox; class function ShowDialog(Title, Content: string): TInfoDialog; end; TAppInfoRecord = record iiId: string; iiTitle: string; iiText: string; procedure Clear; class function Create(const Id, Title, Text: string): TAppInfoRecord; end; TAppInfoDB = class(TObject) private FStack: array of TStdCallback; FItems: array of TAppInfoRecord; procedure Parse(DBText: string); procedure HandleDataLoaded(const FromUrl: string; const TextData: string; const Success: boolean); public property Empty: boolean read ( (FItems.Count < 1) ); property Count: integer read (FItems.Count); property Items[index: integer]: TAppInfoRecord read (FItems[index]) write (FItems[index] := Value); function GetRecById(Id: string; var Info: TAppInfoRecord): boolean; procedure LoadFrom(Url: string; const CB: TStdCallback); procedure Clear; destructor Destroy; override; end; implementation uses SmartCL.Application; //############################################################################# // TAppInfoRecord //############################################################################# class function TAppInfoRecord.Create(const Id, Title, Text: string): TAppInfoRecord; begin result.iiId := id.trim(); result.iiTitle := Title.trim(); result.iiText := Text; end; procedure TAppInfoRecord.Clear; begin iiId := ''; iiTitle := ''; iiText := ''; end; //############################################################################# // TAppInfoDB //############################################################################# destructor TAppInfoDB.Destroy; begin if FItems.Count > 0 then Clear(); inherited; end; procedure TAppInfoDB.Clear; begin FItems.Clear(); end; function TAppInfoDB.GetRecById(Id: string; var Info: TAppInfoRecord): boolean; begin Info.Clear(); if not Empty then begin Id := Id.trim().ToLower(); if id.length > 0 then begin for var x := 0 to Count-1 do begin result := Items[x].iiId.ToLower() = Id; if result then begin Info := Items[x]; break; end; end; end; end; end; procedure TAppInfoDB.Parse(DBText: string); var vId: variant; vTitle: variant; vText: variant; begin Clear(); DbText := DbText.trim(); if DbText.length > 0 then begin var FDb := TJSONObject.Create; FDb.FromJSON(DbText); if FDb.Exists('infotext') then begin // get the infotext-> [] array of JS objects var Root: TJSInstanceArray := TJSInstanceArray( FDb.Values['infotext'] ); for var x := 0 to Root.Count-1 do begin var node := TJSONObject.Create(Root[x]); if node <> nil then begin Node .Read('id', vid) .Read('title', vtitle) .Read('text', vtext); FItems.add( TAppInfoRecord.Create(vId, vTitle, vText) ); end; end; end; end; end; procedure TAppInfoDB.LoadFrom(Url: string; const CB: TStdCallback); begin if assigned(CB) then FStack.push(CB); TW3Storage.LoadFile(Url, @HandleDataLoaded); end; procedure TAppInfoDB.HandleDataLoaded(const FromUrl: string; const TextData: string; const Success: boolean); begin try // Parse if data ready if Success then Parse(TextData); finally // Perform callbacks while FStack.Count>0 do begin var CB := FStack.pop(); if assigned(CB) then CB(Success); end; end; end; //############################################################################# // TInfoDialog //############################################################################# procedure TInfoDialog.InitializeObject; begin inherited; FHead := TW3HeaderControl.Create(self); FHead.BackButton.Visible := false; FHead.NextButton.Caption := 'Close'; // By default the header text is centered within the space allocated for it, // which by default is 2/4. This can look a bit off when we never show // the left-button. So we force text-align to the left [normal]. FHead.Title.Handle.style['text-align'] := 'left'; FBox := TW3Scrollbox.Create(self); FBox.Background.FromColor(clWhite); FBox.ScrollBars := sbIndicator; end; procedure TInfoDialog.FinalizeObject; begin FHead.free; FBox.free; inherited; end; procedure TInfoDialog.Resize; begin inherited; var LBounds := ClientRect; var dy := LBounds.top; if FHead <> nil then begin FHead.SetBounds(LBounds.left, LBounds.top, LBounds.width, 32); inc(dy, FHead.Height +1); end; if FBox <> nil then FBox.SetBounds(LBounds.left, dy, LBounds.width, LBounds.height - dy); end; class function TInfoDialog.ShowDialog(Title, Content: string): TInfoDialog; begin var Host := Application.Display; var Shade := TW3BlockBox.Create(Host); Shade.SizeToParent(); var wd := Host.Width * 90 div 100; var hd := Host.Height * 80 div 100; var dx := (Host.Width div 2) - (wd div 2); var dy := (Host.Height div 2) - (hd div 2); var Dialog := TInfoDialog.Create(Shade); Dialog.Header.Title.Caption := Title; Dialog.SetBounds(dx, dy, wd, hd); Dialog.fxZoomIn(0.3, procedure () begin Dialog.Content.Content.InnerHTML := Content; Dialog.Content.UpdateContent(); Dialog.SetFocus(); end); Dialog.Header.NextButton.OnClick := procedure (Sender: TObject) begin Dialog.fxFadeOut(0.2, procedure () begin TW3Dispatch.Execute( procedure () begin Dialog.free; Shade.free; end, 100); end); end; result := Dialog; end; end.
Using the code
The first thing you want to do is to create an instance of TAppInfoDb when your application starts. Remember to add your JSON file and that it’s formatted property, and then use the LoadFrom() method to load in the data:
// Create our info database and load in the // introduction, features etc. JSON datafile FInfoDb := TAppInfoDB.Create; FInfoDb.LoadFrom('res/JSON1', nil);
The final parameter in the LoadFrom() method is a callback. So if you want to be notified when the file has loaded, just put an anonymous procedure there if you need it.
Showing a dialog with the information is then reduced to looking up the text you need by it’s ID, and firing up the reader dialog for it:
W3Button1.OnClick := procedure (Sender: TObject) begin var LInfo: TAppInfoRecord; if FInfoDb.GetRecById('introduction', LInfo) then TInfoDialog.ShowDialog(LInfo.iiTitle, LInfo.iiText); end;
And that’s it! Simple, effective and ready to be dropped into any application. Enjoy!
Smart Mobile Studio and CSS: part 2
In my previous article we had a quick look at some fundamental concepts regarding CSS. These concepts are not unique to Smart Mobile Studio, but simply just the way things work with CSS in general. The exception being the way Smart maps your pascal class-name to a CSS style of the same name.
To sum up what we covered last time:
- Smart maps a control’s class-name to a CSS style with the same name. So if your control is called TMyControl, it expects to find a CSS style cleverly named “.TMyControl”. This works very well and is easy to apply.
- CSS can affect elements recursively, so you can write CSS that changes the appearance and behavior of child controls. This technique is typically used if you inject HTML directly via the InnerHTML property
- CSS is cascading, meaning that you can add multiple styles to the same control. The browser will merge them into a final, computed style. The rule of thumb is to avoid styles that affect the same properties
- CSS can define more than colors; things like animations, gradients, animated gradients and whatnot can all be defined in CSS
- Smart Mobile Studio ships with units for creating, applying and working with CSS from your pascal code. It also ships with effect classes that can trigger defined CSS animations.
- Smart Mobile Studio has a special effect unit (SmartCL.Effects) that when added to the uses list, adds quite a few effect procedures to TW3MovableControl. These effect methods are prefixed with Fx (ex: fxMoveTo, fxFadeOut, fxScaleTo).
Best practices
When you write your own controls, don’t cheat. I have seen a lot of code where people create instances of TW3CustomControl for instance, and then jump through hoops trying to make that look good. TW3CustomControl is a base-class, it’s designed to be inherited from – not used “as is”. I can understand the confusion to some extent, I mean since TW3CustomControl manage a DIV by default – people with some HTML background probably think creating one of these is the same as making a DIV. But by doing so they essentially short-circuit the whole theme-system since (as underlined above) all pascal classes will use a style with the same name. And TW3CustomControl is just a transparent block of nothing.
No matter how small a thing you are creating, always inherit out your own classes and give them distinct names. This is extremely important with regards to styling, but also as a discipline of writing readable, maintainable code. Using TW3CustomControl all over the place will make the code a mess to maintain – let alone share with others who don’t have a clue what you are doing.
A practical example
To show how easy it is to style things once you have written code that uses distinct class names and clear-cut structure, let’s take the time to write a little list-box. Nothing fancy, just a control that can take X number of child rows, style them and display the items vertically like a list. Let’s begin with the class code:
type // Define an exception especially for our control EMyControl = class(EW3Exception); // Define a baseclass, that way we can grow in the future TMyChild = class(TW3CustomControl) end; // Define a class type, good when working with lists or // collections of elements that share ancestors TMyChildClass = class of TMyChild; // Define a clear child class, that way we can apply // styling without problems TMyChildRed = class(TMyChild) end; // Create a custom version with sensitive properties only // available to ancestors. Here we place these in the protected // section (items and count) TCustomMyControl = class(TW3CustomControl) protected property Items[const index: integer]: TMyChild read ( TMyChild(GetChildObject(Index)) ); default; property Count: integer read ( GetChildCount ); procedure Resize; override; public function Add(const NewItem: TMyChild): TMyChild; overload; function Add(const &Type: TMyChildClass): TMyChild; overload; end; // The actual control we use, this is the one we write // CSS code for and that we create and use in our applications. // This step is optional ofcourse, but it has it's perks TMyControl = class(TCustomMyControl) public property Items; property Count; end; Implementation procedure TCustomMyControl.Resize; var LCount: integer; bl, bt, br, bb: integer; wd, dy: integer; LItem: TMyChild; begin inherited; // Avoid doing work if there is nothing there LCount := GetChildCount(); if LCount > 0 then begin // Get the values of the borders/padding etc from CSS // We need to respect these when working in the client-rect bl := Border.Left.Width + Border.Left.Padding + Border.Left.Margin; bt := Border.Top.Width + Border.Top.Padding + Border.Top.Margin; br := Border.Right.Width + Border.Right.Padding + Border.Right.Margin; bb := Border.Bottom.Width + Border.Bottom.Padding + Border.Bottom.Margin; // This is the maximum width an element can have without // bleeding over whatever styling is present wd := ClientWidth - (bl + br); // Start at the top dy := bt; // Now layout each element vertically for var x := 0 to LCount-1 do begin LItem := Items[x]; LItem.SetBounds(bl, dy, wd, LItem.Height); inc(dy, LItem.Height); end; end; end; function TCustomMyControl.Add(const &Type: TMyChildClass): TMyChild; begin if &Type <> nil then begin // Start update BeginUpdate(); // Create our control & return it result := &Type.Create(self); // Define that a resize must be issued AddToComponentState([csSized]); // End update. If update was not called elsewhere // the resize will happen now. If not, it will happen // when the last EndUpdate() is called (clever stuff!) EndUpdate(); end else raise EMyControl.Create('Failed to add item, classtype was nil error'); end; function TCustomMyControl.Add(const NewItem: TMyChild): TMyChild; begin result := NewItem; if NewItem <> nil then begin // Are we the current parent? if not Handle.Contains(NewItem.Handle) then begin // Remove from other parent NewItem.RemoveFrom(); // Start update BeginUpdate(); // Add child to ourselves RegisterChild(NewItem); // Define that a resize must be issued AddToComponentState([csSized]); // End update. If update was not called elsewhere // the resize will happen now. If not, it will happen // when the last EndUpdate() is called (clever stuff!) EndUpdate(); end; end else raise EMyControl.Create('Failed to add item, instance was nil error'); end;
If you are wondering about the strange property getter’s, where we don’t call a function but instead have some code inside (), that is another perk of Smart Pascal. The GetChildObject() method is a part of TW3TagContainer which ultimately TW3CustomControl inherits from, so we simply typecast and call that. This is perfectly legal in Smart as long as it’s a simple function or expression with matching type.
And now lets look at the CSS for our new control and its red child:
.TMyChildRed { padding: 2px; background-color: #FF0000; font-family: "Ubuntu", "Helvetica Neue", Helvetica, Verdana; color: #FFFFFF; border-bottom: 1px solid #AA0000; } .TMyControl { padding: 4px; background-color: #FFFFFF; border: 1px solid #000000; border-radius: 4px; margin: 1px; }
We need to populate the list before we can see anything of course, so if we add the following code to InitializeForm() things will start to happen:
// Lets create our control. We use an inline variable // here since this is just an example and I wont be // accessing it later. Otherwise you want to define it // as a form field in the form-class var LTemp := TMyControl.Create(self); LTemp.SetBounds(100, 100, 300, 245); // We call beginupdate here to prevent the // control calling Resize() for every elements. // It will only resize when the last EndUpdate (below) // is called. Also see how we use this inside the // procedures that needs to force a change LTemp.BeginUpdate(); for var x := 1 to 10 do begin // Create a new "red" child var NewItem := LTemp.Add(TMyChildRed); // Fill the content with something NewItem.InnerHTML := 'Item number ' + x.ToString(); end; LTemp.EndUpdate;
The end result might not look fancy but it demonstrates some very basic concepts that is fundamental to working with Smart Mobile Studio. Namely how to define CSS that map to your classes, and also how to use BeginUpdate() and EndUpdate() to prevent a ton of calls to Resize() when adding multiple items.

It wont win any prices for looks, but it demonstrates some very important principles when writing controls
Effects
Being able to style and layout child elements in your own controls is cool, but applications can quickly become dull and static without visual feedback. This is why I wrote the effect unit, namely to make it so easy to use GPU powered effects in your applications that anyone can make stuff move around.
So let’s make a little change to our mini-list control. When a user press one of the items, we want the item to scale up while the mouse is pressed, and then gracefully shrink back to normal size when you let go of the mouse. We could make it spin around for that matter, but let’s start with something a bit more down to earth.
This is where defining our own classes comes into play. We are going to add some code to our root child class, TW3MyChild, because this behavior should be universal. For sake of simplicity im just going to use the controls own events for this purpose. So Let’s expand our ancestor class to the following:
TMyChild = class(TW3CustomControl) private FDown: boolean; procedure HandleMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer); procedure HandleMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer); protected procedure InitializeObject; override; end;
The implementation needs to keep track of when a scale is in process, otherwise we can scale the element out of sync with the UI. Again this is just an example, there are many ways to keep track of things but let’s keep it simple:
procedure TMyChild.InitializeObject; begin inherited; self.OnMouseDown := HandleMouseDown; self.OnMouseUp := HandleMouseUp; end; procedure TMyChild.HandleMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer); begin if Button = TMouseButton.mbLeft then begin if not FDown then begin FDown := true; fxScaleUp(1.0, 1.5, 0.3); end; end; end; procedure TMyChild.HandleMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer); begin if Button=TMouseButton.mbLeft then begin if FDown then begin fxScaleDown(1.5, 1.0, 0.3, procedure () begin FDown := false; end); end; end; end;
The result? Well, when we press one of the items in our list that items grows to 1.5 of it’s original size (the parameter names for the effects are easy to understand). So we scale from 1.0 (normal size) to 1.5, and we tell the system to execute this transition in 0.3 seconds.
All the effect methods have an optional callback procedure you can use (anonymous procedure) that will fire when the effect is finished. As you can see in the HandleMouseUp() method we use this to reset the FDown field, allowing the effect to be executed again on the next click.

Smooth scaling via hardware
Next time
Hopefully the past two articles have been interesting. In our next article we will look at some of the stuff we are building in our labs. That means talking about styling and how we are working to improving this (read: not yet available but in the process).
In the meantime, have a peek at what you can do with proper use of CSS effects
Happy coding!
Smart Pascal: Amibian vs. FriendOS
This is not a new question, and despite my earlier post I still get hammered with these on a weekly basis – so lets dig into this subject and clean it up.
I fully understand that for non-developers suddenly having two Amiga like web desktops can be a bit confusing; especially since they superficially at least do many of the same things. But there is actually a lot of co-incidence surrounding all this, as well as evolution of the general topic. People who work with a topic will naturally come up with the same ideas from time to time.
But ok, lets dig into this and clear away any confusion
You know about FriendOS right? It looks a lot like Amibian
“A lot” is probably stretching it. But ok: FriendOS is a custom server system with a sexy desktop front-end written in HTML5. So you have a server that is custom written to interact with the browser in a special way. This might sound like a revolution to non-developers but it’s actually an established technology; its been a part of Delphi and C++ builder for at least 12 years now (Intraweb being the best example, Raudus another). So if you are wondering why im not dazzled, it’s because this has been there for a while.
The whole point of Amibian.js is to demonstrate a different path; to get away from the native back-end and to make the whole system portable and platform independent. So in that regard the systems are diametrically different.

Custom web servers that talk to your web-app is old news. Delphi developers have done this for a decade at least and it’s not really interesting at this point. Node.js holds much greater promise.
What FriendOS has done that is unique, and that I think is super cool – is to couple their server with RDP (remote desktop protocol) and some nice video streaming for smooth video chat. Again these are off the shelves parts that anyone can add once you have a native back-end, it’s not really hard to code but time-consuming; especially when you are potentially dealing with large number of users spawning threads all over the place. I think Friend-Labs have done an exceptional good job here.
When you combine these features it creates the impression of an operating system like environment. And this is perfectly fine for ordinary users. It all depends on your needs and what exactly you use the computer for.
And just to set the war-mongers straight: FriendOS is not going up against Amibian. it’s going up against ChromeOS, Nayu and and a ton of similar systems; all of them with deep pockets and an established software portfolio. We focus on software development. Not even in the same ballpark.
To be perfectly frank: I see no real purpose for a web desktop except when connected to a context. There has to be an advantage beyond isolating web functions in one place. You need something special that your system does better than others, or different than others. Amibian has been about UAE.js and to run retro games in a familiar environment. And thus create a base that Amiga lovers can build on and play with. Again based on our prefab for customers that make embedded systems and use our compiler and RTL for that.
If you have a hardware product like a NAS, a ticket system or a retro-game machine and want to have a nice web front-end for it: then it makes sense. But there is absolutely nothing in both our systems that you can’t whip-up using Intraweb or Raudus in a few weeks. If you have the luxury of a native back-end, then adding Active Directory support is a matter of dropping a component. You can even share printers and USB devices over the wire if you like, this has been available to Delphi and c++ developers for ages. The “new” factor here, which FriendOS does very well i might add, is connectivity.
This might sound like criticism but it’s really not. It’s honesty and facts. They are going to need some serious cash to take on Google, Samsung, LG and various other players that have been doing similar things for a long time (or about to jump on the same concepts) — Amibian.js is for Amiga fans and people who use Smart Pascal to write embedded applications. We don’t see anything to compete with because Amibian is a prefab connected to a programming language. FriendOS is a unification system.
A programming language doesnt have the aspirations of a communication company. So the whole “oh who is best” or “are you the same” is just wrong.
Ok you say it’s not competing, but why not?
To understand Amibian.js you first need to understand Smart Pascal (see Wikipedia article on Smart Pascal). Smart Pascal (smartmobilestudio.com) is a software development studio for writing software using web technology rather than native machine-code. It allows you to create whatever you like, from games to servers, or kiosk software to the next Facebook clone.
Our focus is on enabling our customers to quickly program robust mobile applications, servers, kiosk software, games or large JavaScript projects; products that would otherwise be hard to manage if all you have is vanilla JavaScript. I mean why spend 2 years coding something when you can do it in 2 months using Smart? So a web desktop is just ridicules when you understand how large our codebase is and the scope of the product.
Under Smart Pascal what people know as Amibian.js is just a project type. There is no competition between FriendOS and Amibian because a web desktop represents a ridicules small piece of our examples; it’s literally mistaking the car for the factory. Amibian is not our product, it is a small demo and prefab (pre fabricated system that others can download and build on) project that people use to save time. So under Smart, creating your own web desktop is a piece of cake, it’s a click, and then you can brand it, expand it and do whatever you like with it. Just like you would any project you create in Visual Studio, Delphi or C++ builder.
So we are not in competition with FriendOS because we create and deliver development tools. Our customers use Smart Pascal to create web environments both large and small, and naturally we deliver what they need. You could easily create a FriendOS clone in Smart if you got the skill, but again – that is but a tiny particle in our codebase.
Really? Amibian.js is just a project under Smart Pascal?
Indeed. Our product delivers a full object-oriented pascal compiler, debugger and IDE. So you can write classes, use inheritance and enjoy all the perks of a high-level language — and then compile this to JavaScript.
You can target node.js, the browser and about 90+ embedded devices out of the box. The whole point of Smart Pascal is to avoid the PITA that is writing large applications in JavaScript. And we do this by giving you a classical programming language that was made especially for application authoring, and then compile that to JavaScript instead.

Amibian.js is just a tiny, tiny part of what Smart Pascal is all about
This is a massive undertaking that started back in 2009/2010 and involves a high-quality compiler, linker, debugger and code generator; a full IDE with a ton of capabilities and last but not least: a huge run-time library that allows you to work with the DOM (document object model, or HTML) and node.js from the vantage point of a programmer.
Most people approach web development as a designer. They write html and then style them using a stylesheet. They work with colors, aspects and pages. Which means people who traditionally write programs falls between two chairs: first they must learn about html and css, and secondly a language which is ill equipped for large scale applications (imagine writing adobe photoshop in nothing but JS. Sure it’s possible, but wouldnt you rather spend a month coding that than a year? In a language that actually makes sense?).
With Smart you approach web development like you do writing programs. You work with visual controls, change properties, write code in response to events. Even writing your own visual controls that you can re-use and inherit from later is both fun and easy. So rather than ending up with a huge was of spaghetti code, which sadly is the fate of most large-scale JavaScript projects — Smart lets you work like you are used to. In a language better suited for the task.
And yes, I was not kidding when I said this was a huge undertaking. The source code in our codebase is close to 2.5 gigabytes. And keep in mind that this is source-code and libraries. So it’s not something you slap together over the weekend.

The Smart source-code is close to 2.5 gigabytes. It has taken years to complete
But why do Amibian and FriendOS both focus on the Amiga?
That is pure co-incidence. The guys over at Friend Labs started out on the Amiga just like we did. So when I updated our desktop project (previously called Quartex Media Desktop) the Amiga look and feel came natural to me.
I’m a huge retro-computing fan that loves the Amiga. When I sat down to rewrite our window manager I loved the way Amiga OS 4.x looked, so I decided to implement an UI inspired by that.
People have to remember that the Amiga was a huge success in Scandinavia, so finding developers that are in their late 30s or early 40s that didn’t own an Amiga is harder than you think.
So the fact that we all root our ideas back to the Amiga is both co-incidence and a mutual passion for a great platform. One that really should have survived the financial onslaught of fat CEO’s and thir minions in the board.
But Amibian does a lot of what FriendOS does?
Probably. JavaScript is multi-tasking by default so if loading external URL’s into window containers, doing live resize and other things is what you refer to then yes. But that is the nature of web programming. Its like creating a bucket if you want to carry water; it is a natural first step of an evolutionary pattern. It’s not like FriendOS is copying us I would imagine.
For the record Smart started back in 2010 and the media desktop came in with the first hotfix, so its been available years before Friend-Labs even existed. Creating a desktop has not been a huge part of what we do because mobile applications, building a rich and solid run-time-library with hundreds of classes for our customers – and making an IDE that is great to use, that is our primary job.
We didn’t even know FriendOS existed. Let alone that it was a Norwegian product.
But you posted that you worked for FriendOS earlier?
Yes I did, very briefly. I was offered a position and I worked there for a month. It was a chance to work side by side with legends like David John Pleasance, ex head of Commodore for europe; and also my childhood hero Francois Lionet, author of Amos Basic for the Amiga way back in the 80’s and 90s.

We never forget our childhood heroes
Sadly we had our wires crossed. I am an awesome object pascal developer, while the guys at Friend-Labs are awesome C developers. I work primarily on Windows while they work mostly on Linux. So in essence they hired a Delphi developer to work in a language he doesn’t know on a platform he havent used.
They simply took for granted that I worked in C/C++, while I took for granted that they used object pascal. Its an easy mistake to make and its not the first time; and probably not the last.
Needless to say the learning curve would be extremely high for any developer (learning a new operating-system and programming language at the same time as you are supposed to be productive).
When my girlfriend suddenly faced a life threatening illness the situation became worse. It was impossible for me to commute or leave her side for the unforeseeable future; so when you add the six months learning curve to this situation; six months of not being able to contribute on the level I am used to; well I am old enough to know how that ends. So I did what was best for everyone and resigned.
Besides, I am a damn good Delphi developer with standing invitation to many companies; so it made more sense to just take a step backwards. Which was not fun because I really enjoyed the short time I was there. But, it was not meant to be.
And that is basically all there is to it.
Ok. But if Smart is a development tool, will it support Friend-OS ?
This is something that I really want to do. But since The Smart Company is a proper company with stocks, shareholders and investors – it’s not a decision I can take on my own. It is something that must be debated by the board. But personally yeah, I would love that.

As they grow, so does the need for proper development tools
One of the reasons I hope FriendOS succeeds is because it’s a win-win situation. The more they expand the more relevant Smart becomes. Say what you will about JavaScript but writing large and complex applications is not easy by any measure.
So the moment we introduce Smart Pascal for Friend, their users will be able to write large applications rapidly, with better time-to-market and consequent ROI. So it’s a win-win. If they succeed then we get a bigger market; If they don’t we havent lost anything.
This may sound extremely self-serving, but Friend-Labs have had the same chance as everyone else to invest in Smart; our investor plans have been available for quite some time, and we have to do what is best for our company.
But what about Amibian, was it just a short thing?
Not at all. It is put on hold for a few months while we release the next generation RTL. Which is probably the biggest update in the history of Smart Pascal. We have a very clear agenda ahead of us and Amibian.js is (as underlined) a very small part of what we do.
But Amibian is written using our next generation RTL, and without that our customers cant really do much with it. So it’s important to get the RTL out first and then work on the IDE to reflect its many new features. After that – Amibian.js development will continue.
The primary target for Amibian.js is embedded devices and kiosk systems, coupled with full-screen web applications and hardware front-ends (NAS and backup devices being great examples). So the desktop will run on affordable, off the shelves hardware starting at $40 and all the way up to the most powerful and expensive x86 boards on the market. Cheap solutions like Raspberry PI, ODroid XU4 and Tinkerboard will deliver what you today need a dedicated $120 x86 board to achieve.

Our desktop will run on many targets and is platform independent by design
This means that our deskop has a wildly different modus operandi. We will not require a constant connection to a remote server. Amibian will happily boot up on a single device, regardless of processor type.
Had we coded our backend using Delphi or C++ builder (native like FriendOS have done) we would have been finished months ago. And I could have caught up with FriendOS in a couple of months if I wanted to. But that is not in our agenda. We have written our server framework for node.js as we coded the desktop – which means it’s platform and OS agnostic by design. If node.js runs, Amibian will run. It wont care if you are running on a $40 embedded board or the latest Intel i9 cpu.
Last words
I really hope this has helped and that the confusion between Amibian.js and our agenda, versus what Friend-Labs is doing, is now clearer.

From Norway with love
I wish Friend-Labs the very best and hope they are successful in their endeavour. They have worked very hard on the product and deserve that. And while I might come over as arrogant at times, im really not.
Web desktops have been around for a long time now (Asustor is my favorite) through Delphi and C++ builder and that is just facts. But that doesn’t mean you can’t put things together in new and interesting ways! Smart itself was first put together by existing technology. It was said to be impossible by many because JavaScript and object pascal are unthinkable companions. But it turned out to be a perfect match.
As for the future – personally I don’t believe in the web-desktop outside a specific context, something to give it purpose if you like. I believe for instance that Amibian.js will be awesome for Amiga users when its running on a $99 ARM laptop. Where the system boots straight into a full-screen desktop and where UAE.js is fully integrated into the core, making retro-gaming and running old programs close to seamless. That I can believe in.
But it would make no sense running Amibian or FriendOS in a browser on top of a Windows desktop or a full Ubuntu X session. Unless the virtual desktop functions as your corporate window with access to company mail, documents and essentially what every web-based intranet already does. So once again we end up with the fact that this has already been done. And unless you create a unique context for it, it just wont have any appeal. This is also why I havent pursued the same tech Friend-Labs have, because that’s not where the exciting stuff is happening.
But I will happily be proven wrong, because that means an even bigger market for us should we decide to support the platform.
Smart Pascal: Busting browser storage limits
Sessionstorage is the name for a browser’s in-memory only storage. Meaning that it’s essentially a ram-disk that is just deleted when you navigate away from the website or close the browser.
Sessionstorage has also been deprecated, so you should avoid using it and go for Localstorage, or just use a raw, untyped uint8 array instead.
Or should you?
Ensuring 64 megabytes minimum
Browsers do not behave identically across devices. Try to get a concurrent reading of something as simple as drawing sprites, and you will quickly notice that even the same device families (Android, iOS and Microsoft) can behave differently between versions – and even builds (revisions).
On embedded systems or thin clients with very little memory, allocating large chunks ot uint8 arrays is not going to work. One of my test thin-client machines has only 512 megabyte ram – and it would throw an exception if I tried to allocate more than 20 megabyte of continuous memory (again, as an array of uint8 bytes).
Using the dark side of the force

Offline means the system boots from a local cache disk
While testing Smart code on this little device, I noticed that quite large images loaded just fine. So where I was not allowed to allocate more than 20 megabytes, the browser would happily load in pictures taking up over 50 megabyte of pixel data?
It then struck me that the maximum limit of a picture, which is enforced by the DIB Api (at least on Windows desktop and embedded), is 4000 x 4000 pixels. Since each pixel is 32 bits (4 bytes, RGBA) that my friend is 64 megabytes right there!
I created a new class that inherits from the virtual-filesystem that Smart Pascal uses, created an off-screen image object in the constructor – and then made a simple but effective “bytes to scan line” calculation routine. So whenever the need for more data grew, it would first grow the picture so it could hold the data (and shrink it again) on demand.
Humble but meaningful
Now 64 megabytes might not seem like much in our day and age, but if you are on holiday and want to connect to your home NAS – 64 megabytes of available ram makes a huge difference. Remember that localstorage only allows between 5 and 10 megabytes.
I should mention that using an image as a buffer makes little sense on a full Windows PC, a Mac or a Linux box. These system will page memory to disk and you will most likely never encounter the 20 megabyte barrier I experienced on this low-end Dell thin client device. But considering that hotels, motels and b&b often have thin clients setup for their customers (read: you) – The Smart desktop has to take height for it.
For those about to scroll, we salute you
Came up with a better solution to the scrolling problem for Smart Mobile Studio. While I hate having to write code for Internet Explorer, it is nice to have a system that works everywhere. But that means more abstraction and “drivers” type classes.
The scrolling model
TW3Scrollbox and it’s variation(s) implement different types of scrolling. TW3Scrollbox has a very fast non-momentum scroll, making it perfect for displaying detailed information. But it would be nice if we could choose right?
The model I have come up with is super simple, especially in the upcoming RTL where we finally have non-visual components. I give you – TW3ScrollController
In the present model, TW3Scrollbox deals with scrolling directly. Actually the scrolling is implemented in the TW3ScrollContent control, mapping touch and mouse events directly. This turned out to be a remarkably fast way of moving things around. I really did not expect IE to keep up, but it’s perfectly pristine!
In the momentum-scroll example I posted, control of scrolling is handled by the container rather than content. This is very fast on webkit, and I also tried it on Microsoft mobile and Windows 10 mobile – and it’s very fast there. But for some reason the desktop Internet Explorer is slow and the content jitters a bit.
The culprit is not my code or approach, it’s actually something else. Internet Explorer and Edge are the only browsers that implements OnReSize() events. No other browser has this. In the SMS RTL we have to manually figure out when to call ReSize (based on the BeginUpdate, AddControlState, EndUpdate methods).
In the momentum scroller I use SetBounds() to keep the content within the horizontal bounds of the control. This causes an extra call to Resize every time the content moves even a pixel (even though it shouldnt, because the size doesnt change). So yeah, fixing that will make all the difference. I’m going to nail this thing once and for all, just like I did with font measurements way back.
TW3ScrollController
But isolating the code that actually deals with scrolling in separate, non visual components that you can attach to the TW3ScrollBox makes sense. Rather than hardcoding everything into a huge, spaghetti monster unit — we can now isolate different scroll methods in their own units (keeping those bytes down).
Normal per-pixel scrolling, momentum scrolling, CSS3 animation based scrolling, tween based (cpu) scrolling. It gives us some options – and allows you to implement your own variations if you find mine lacking.
I’m also giving the browser driver a much deserved overhaul. Getting the browser type and version info should be easy (and humanly readable). And since you may want to pick different scroll methods depending on the browser type — being able to check if your running on Edge for the desktop, or IE on a mobile device… well, it should be there. End of story.
iScroll
I really want iScroll to be the standard scroll library for Smart Mobile Studio, but since people feel it’s hard to use and adapt to — I may end up doing the unthinkable and re-write it in object pascal from scratch. But iScroll5 really is so much better. It has been developed and tested on a plethora of devices for six years now.
It even does things the built-in browser scrolling (for the browsers that allows this, yeah im looking at you Safari!) doesn’t deal with.
But I have enough on my plate right now, so iScroll porting will have to wait.
Selecting text, Smart Mobile Studio
A really good question came my way regarding text selection and why ordinary browser behavior is disabled in Smart Mobile Studio applications. It was Jarto Tarpio that posted it on the SMS Facebook page, and I was a little surpriced at first to say the least.
Now the VJL was designed to look and feel more or less identical to any ordinary, native UI framework. This means that ordinary HTML text selection (marking text with your mouse) is something you dont want to have.
But what Jarto pointed out was that there is something fishy about how it’s implemented in Smart at the moment, because even when he removed the CSS rules that disables this, selecting text is still not possible.
That one line ..
Two RTL updates ago I remember dealing with this exact topic. I was happy to find that CSS had a couple of universal rules you could use, which meant that i could remove the code I was using to avoid selection ever taking place.
Sadly, I must have forgotten all about it (or it got accidentally filtered out during a manual unit merge) because it was till there (!) In other words not only did the CSS make sure you couldnt enable text selection, the startup code for all TW3TagObj derived classes kidnaps the OnSelectStart event — effectively killing initializing a selection at all.
Patching the RTL yourself
The change you need is basically a “one liner”, and it wont affect your programs at all. If you open up SmartCL.Components (right click the unit in your units clause), hit ALT + F which brings up the search dialog and then enter “TW3CustomControl.HookEvents” that’s where the problem lies:
procedure TW3CustomControl.HookEvents; begin inherited; Handle['onclick'] := @CBClick; //w3_bind2(Handle, 'onselectstart', CBNoBehavior); //Remove this line !! w3_bind2(Handle, 'onfocus', CBFocused); w3_bind2(Handle, 'onblur', CBLostFocus); end;
So simply delete the first “w3_bind2” call, the one that assigns OnSelectStart to the “no operation” event handler CBNoBehavior — now go to your main form unit, type something and then click Save.
Note: The editor doesnt monitor RTL files for edit-changes since these units are not meant to be edited. So you have to alter something in your project and force the IDE to allow your change to be saved.
Making selection an option
With that nasty (and no longer needed) line of code out of the way – I have added two new methods to the VJL that gives you 100% control over content selection. This will be in the next update but for those that cant wait, the following methods have been added to TW3MovableControl:
function GetContentSelectionMode: TW3ContentSelectionMode;virtual; procedure SetContentSelectionMode(const NewMode: TW3ContentSelectionMode);virtual;
Here is the code if you want to get these features straight away:
type TW3ContentSelectionMode = ( tsmNone, tsmAuto, tsmText, tsmAll, tsmElement ); function TW3MovableControl.GetContentSelectionMode: TW3ContentSelectionMode; begin var CurrentMode := Handle.style[BrowserAPI.PrefixDef("user-select")]; if (CurrentMode) then begin case TVariant.AsString(CurrentMode).ToLower() of 'auto': result := tsmAuto; 'text': result := tsmText; 'all': result := tsmAll; 'element': result := tsmElement; else result := tsmNone; end; end else begin Handle.style[w3_CSSPrefixDef("user-select")] := 'none'; result := tsmNone; end; end; procedure TW3MovableControl.SetContentSelectionMode (const NewMode: TW3ContentSelectionMode); begin case NewMode of tsmAuto: Handle.style[w3_CSSPrefixDef("user-select")] := 'auto'; tsmAll: Handle.style[w3_CSSPrefixDef("user-select")] := 'all'; tsmText: Handle.style[w3_CSSPrefixDef("user-select")] := 'text'; tsmNone: Handle.style[w3_CSSPrefixDef("user-select")] := 'none'; tsmElement: Handle.style[w3_CSSPrefixDef("user-select")] := 'element'; end; end;
Writing your custom controls with selection turned on
Ok, first let’s write a class that allows text-selection. We are going to use a DIB, which is the default element of TW3CustomControl, so this will be a short example:
type TSelectTestControl = class(TW3CustomControl) protected procedure ObjectReady;override; public property Text:string read (GetInnerText) write (SetInnerText(Value)); end; procedure TSelectTestControl.ObjectReady; begin inherited; SetContentSelectionMode(tsmText); end;
Since user-select is set to “none” in all our CSS style themes, enabling editing means telling the DOM (document object model) that this control does allow text selection. In the above example I do that in the ObjectReady method, just to make sure the DIV TSelectTestControl represent is in the clear and has been created successfully and injected into the DOM.
So lets go back to our main form and create an instance of our new control. You should also drop a TW3DIVHtmlElement on the form first, so we have something to compare with.
Ok, here is the form unit completed:
unit Form1; interface uses System.Colors, SmartCL.Controls.Elements, SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, SmartCL.Fonts, SmartCL.Borders, SmartCL.Application; type (* our spanking new control. Not a TW3DIVHtmlElement in sight! *) TSelectTestControl = class(TW3CustomControl) protected procedure ObjectReady;override; public property Text:string read (GetInnerText) write (SetInnerText(Value)); end; TForm1 = class(TW3Form) private {$I 'Form1:intf'} protected procedure InitializeForm; override; procedure InitializeObject; override; procedure Resize; override; end; implementation { TForm1 } uses system.types, system.time; procedure TSelectTestControl.ObjectReady; begin inherited; SetContentSelectionMode(tsmText); end; procedure TForm1.InitializeForm; begin inherited; // this is a good place to initialize components var LTemp := TSelectTestControl.Create(self); LTemp.background.fromColor(clRed); LTemp.Text:="this is some text"; LTemp.setBounds(10,10,200,200); W3DivHTMLElement1.innerhtml := "<i>This is some text"; end; procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} end; procedure TForm1.Resize; begin inherited; end; initialization Forms.RegisterForm({$I %FILE%}, TForm1); end.
And the results are exactly what we wanted:

The red box is our control, as you can see you can now mark the text
Final words
I know this has been a topic many people have asked about in the past. But this time we have made sure this is possible (and possible per individual control).
Well what are you waiting for! Go patch that RTL right now and get cracking 🙂
Smart Pascal, what’s next?
For those of you who have been following my developer’s log over the years, both here (and on www.smartmobilestudio.com), I have a tradition to write a few words about where we are heading next after each release. So with the release of version 2.2 here is a peek of the future and what we will be cooking up in the lab next. Just for you!

The secret lab where all the magic happens
As a team we have worked hard for the past years, actually I started on it back in 2010, Eric joined in early, somewhere between 2010 and 2011 – at the same time as Jørn E. Angeltveit (owner and CEO of Optimale Systemer AS, the original publishing company). And together with solid developers like Primoz Gabrielcic, Christian Budde and Andre Mussche, we formed the OP4JS consortium in 2012. Dedicated to a new object pascal for a new age.
That was 4 years ago. And today Smart Pascal is not only a distinct dialect of object pascal, it is also a licensed, stock based company: The Smart Company AS. Standing on its own two feet and continuing to grow.
We have seen Smart Mobile Studio (SMS) go from being an “Adobe Flash” like programming environment, into a fully fledged IDE with a decent form designer, support for packages (yes you can create packages and register components just like Lazarus and Delphi).
But is that all it’s ever going to be? Hardly. And I know people have a lot of questions about where we are heading, so I figured it’s time to shed some light on the subject.
Platform independence
In our recent release we have given our customers a whole year worth of research and development. I know people expected more frequent updates, perhaps 4 updates which was our initial goal – but had we done so, the RTL would have seen incomplete for 3 of those, so we decided to wait until the foundation was solid and in place.

The NodeJS service editor will make its debug very soon
To demonstrate: take something simple; Let’s take TMemoryStream. Easy right? Its been with Delphi since day 1, its one of the first things you learn about in DIY programming books, and considering we live in 2016 streams is something you take for granted.
Well guess what, that could not be further from the truth when it comes to JavaScript. The wonderful language itself may hold 51% of the global computing markedshare, but like the author himself has stated on numerous occasions: it was slapped together in record time and was nowhere near complete when Netscape pushed it. So streams, strong type checking, datatype conversion, sandboxed memory management and all the stuff we would expect a modern language to support — it just isn’t there. It has slowly appeared in various unfriendly forms (and Typescript naturally, which imitates aspects of Smart Pascal, cheeky Anders Hejlsberg), but to overcome these shortcomings we have had to implement even the most fundamental functionality from scratch, in Smart Pascal itself.
Something as trivial as converting a 32 bit integer into 4 bytes, or turning a TDateTime (64 bit float) into an 8 byte array is something JavaScript developers have struggled with for quite some time (using bit-shift is the typical solution, we use a faster method). They have been reduced to cheap hacks, like packing bytes as character data; the proverbial assault on the heap.
So before we could even begin to introduce stuff like TStream, we first had to research and implement consistent behavior between platforms. What platform you may ask? Doesnt Smart Pascal target normal browsers? Absolutely, but there is a difference between browser, engine and renderer. And we also have much larger ambitions than just browser apps.
Browsers render, engines execute
Browsers may look the same but beneath the hood they can be as different as Delphi is from Pearl or Python. The list of browsers we want to support is long and growing, separated by builds (age of mobile device, type of device and even PC graphics card capabilities):
- There is Mozilla Firefox
- Safari, extended version of webkit
- Chrome, standard webkit
- Internet Explorer
- Microsoft Spartan browser
- Opera
- Epiphany
- Midori, customized webkit
And those are just for desktop PC’s or embedded systems (like the Raspberry PI) running Windows , OS X or Linux in some form or another. Six of these browsers are further separated by desktop and mobile editions where differences can be monumental (like CSS gradients suddenly altering direction and syntax between CEF2 and CEF3).
Technically speaking each browser and engine (where engine means the JavaScript execution module, like Webkit V8, Mozilla Spidermonkey or IO.JS) have both subtle and radical differences which we have to care about. Tiny but important details like timing issues, synchronization differences, priorities for dispatching and performance considerations.
Now throw NodeJS and IO.JS (initially a fork of NodeJS which has gone in a slightly new direction) into the mix; combine with embedded SoC running JavaScript natively (more and more hardware support JS as their primary automation language) and you get the idea of just how much our work is involved. Things like converting integers to bytes and back again seem trivial, child like even, but they are of utmost importance. Something as simple as using UInt8ClampedArray instead of UInt8Array on the wrong engine, browser or build can kill your application before it even starts.
So streams, just to get back to that, involves a little more than just slapping together a class. To get streams working we first had to build the foundation for streams to exist in the first place:
- Replicate object pascal strict types
- Research fastest and most efficient way of doing binary conversion
- Implement native type conversion in JavaScript itself
- Implement real memory handling:
- The ability to allocate memory (TAllocation)
- The ability to modify memory (TBinaryData)
- Differentiate between various encoding standards
- Implement marshaled pointers (offset references)
Take a moment to reflect on how much research, testing, prototyping and solution finding these simple concepts represents. Things Delphi has had over 21 years to reach, evolve and perfect.
And before Delphi became the product we all use and love today, it first went through 4 year of evolution as “Turbo Pascal for Windows”, releasing a grand total of 4 editions before that amalgamated into Delphi. And before that, seven years of Turbo Pascal earning Borland millions of dollars.
Engine and platform standard library
With version 2.2 just out the door, you get to enjoy elegant solutions to things JavaScript developers struggle with to this very day. Streams, memory management, writing custom controls with full inheritance, composite layout — all with rich support for NodeJS and various mobile and embedded platforms. But we are not done, not by a long-shot.
Writing object pascal services using standard RTL classes, running on affordable NodeJS hosting servers – from small vendors to giants like Microsoft Azure and Amazon cloud service is the next big goal.
NodeJS and IO.JS may look like plain old JavaScript but they are worlds apart from the environment you find in a browser. We are already hard at work separating the RTL into 3 distinct namespaces. This complete picture will appear later, most likely in version 2.2.5 or even 2.3. And with it you will enjoy many of the top-level benefits Delphi and Lazarus have in their native codebase. But this time, you can run it anywhere, even on your TV which no doubt have a browser!
- Unified standard classes between namespaces
- Node and IO Service application type
- Command server
- WebSocket server
- DB server (and drivers)
- Unified DB API
- Non visual components
- Assets management (pre-loading of resources for easy distribution)
- TActions for visual elements
- IDE Embedded development
Embedded development
This is being worked on by a third-party and will be exciting for IOT programmers using the Raspberry PI (for example). A version of ARM Ubuntu is being tailored to communicate with our IDE. The Linux image will run NodeJS services you write in Smart Mobile Studio and can also (as a bonus) render a visual front-end application directly to the framebuffer.

With the internet of things (IOT) you need a language that connects
In other words: you will have full control over the entire device, and can use SMS as the tool to create single-application IOT devices. Examples of products you can create with this technology are Apple TV or Plex devices, ChromeStick, NetFlix, kiosk systems; Development from A-Z will can be done directly inSmart Mobile Studio. The IDE will also communicate with the IOT device, uploading your compiled NodeJS services, databases, assets and visual project UI code.

The Smart Desktop runs on Raspberry PI on boot, with NodeJS dealing with system level operations in the background. So much fun to work with!
While I love all things Smart Pascal, this is by far my favorite. IOT is important and allows you to create just about everything you can imagine.
And the beauty? It’s all done using standard protocols. Your NodeJS service can be hosted on Azure or Amazon, or just run quietly on your Raspberry PI or Beaglebone. It makes no difference. The code and classes will be exactly the same.
You are going to love it.
You must be logged in to post a comment.