Theme styling: A primer

One of the major benefits HTML5 / JavaScript holds over native applications is the power of CSS (cascading style-sheets). CSS is a simple way of describing the visual attributes of something, from the size and color of the font to the thickness of borders and even animations. You can even position elements in 3D space if you like using nothing but CSS.

The TQTXWindow class is a highly complex, multi composite widget. Since it’s styling is quite complex, I am considering moving it’s CSS to a separate file. This way we can support multiple visual styles that are not dictated by the application theme.

A CSS file contains the definitions of such styles called style-rules, and once defined you can change everything about your UI with barely any effort. A style rule simply defines a list of attributes and the values you want them to have. Here is an example of a style-rule:

.ExampleStyleRule{
margin: 2px;
padding: 4px;
font-color: red;
}

Note: While the technical term for such a definition is style-rule, most people simply say style. So when I refer to a style in this article, unless otherwise stated I am referring to a single style-rule definition.

A HTML application can load and use any number of CSS files, which makes it easier for developers to organize and manage styling for their applications. You can have animations in one file, widget styles in another and color definitions in a third. There are some very good CSS visual editors online as well, that you can use to generate complex CSS. Then you can copy and paste the result into a CSS file and use it in your QTX projects.

CSS is vast and covers a plethora of attributes, but for sake of brevity we group the attributes involved into four distinct categories:

  • Visual attributes: border, background, shadows, visibility, opacity; anything visual
  • Behavioral attributes: width, height, padding, margin, clipping and layout
  • Animation attributes: rotating, flipping or moving an element using hardware acceleration, or moving an element in 3D space
  • Typeface attributes: font names, families, their weight and orientation (note that I did not list color, since that is a visual attribute)

There is much more to CSS than these four categories, but if you are unfamiliar with CSS – these four gives you a rough overview of the terrain. Every inch of a HTML element can be altered in some way through CSS, the question really comes down to how do we organize this in a system that makes sense.

This is where the QTX theme ( or scheme ) comes in.

The theme file might look very complex if you are unfamiliar with CSS, but the takeaway is that borders, backgrounds etc are all defined as separate styles with a known name. New theme files must provide the same names, but with different content if you like.

QTX Style Guidelines

In order to bring uniformity and structure to how component writers work, the IDE operates with a few basic laws or guidelines for using or creating your own themes. These laws are simple and non-intrusive.

If you want to deal with the styling yourself and ignore how QTX does things, that is not a problem! It is very important that QTX don’t get in the way of whatever styling developers write themselves, or collide with existing JavaScript frameworks and their styling schemes. But let’s look at how the RTL is rigged to work with theme-files, which is just a normal CSS file with a set of pre-defined, named style-rules.

As long as you follow the “laws” of how the theme file operates, your application will look good should you apply a different theme. As of writing only a single theme is provided (Ubuntu Blue) but more will be written in the near future

First, these are the guidelines for those that wish to create their own theme files. These guidelines must be followed since the RTL and IDE expects this scheme to be in place.

The theme-files divides the styling of a widget into 4 parts: border, background, font and behavior. We dont have styles that mix the attribute groups I mentioned earlier. A border style should just affect the border, a background style should just affect the background. In the RTL we apply multiple styles to a single widget, this is how you can change the border without affecting anything else (!).

  • Border styles must only affect how a border is visually represented
  • Background styles must only affect the background
  • Font styles only affect the font size, weight and pitch. You can set the name of the font if you wish, but the theme-file defines a font for the entire theme, which the rules inherit from. But you are free to override this if you wish.
  • Behavior, size and layout should exclusively be defined in a style that match the Pascal class-name of a widget. TQTXToolbar, TQTXButton and so on all have corresponding style-rules in the themefile.
  • All TQTXWidget based controls will add their own pascal class name to the style-collection of it’s HTML element (all widgets create and maintain a HTML element, in most cases this is a DIV) during initialization of the widget.
  • Widget writers should provide a CSS file in their package that contains style-rules for their Pascal widget class-names. This ensures that element + basic behavior is established instantaneously on creation.

The last 3 items of these guidelines will be confusing to anyone unfamiliar with CSS, they mostly affect advanced developers that write their own packages

Ad-Hoc example

Let us have a look at a direct example of the style mapping mentioned above. First, let us write the smallest possible TQTXWidget we can think of:

You can ignore the [RegisterWidget] and [RegisterInfo] pascal attributes, those just ensure that the IDE registers the widget on the component palette in the IDE when the package loads. Just focus on the class definition for now. And yes, this is a fully working widget, albeit a bit useless.

With the pascal code in place, we need a matching CSS style-rule. Like mentioned already, the widget will add it’s own Pascal name to the list of styles it uses – so all we need now is to have a CSS rule with the same name (note: user styles are prefixed by a dot [.], this is not custom for QTX but a part of the CSS standard).

The above CSS is a fair starting point, and like the guidelines explains, automatically mapped styles should only define behavior essential to the widget. Attributes like padding, margin, minimum size, anything that helps setup the structure of the widget rather than it’s visual attributes.

With our pascal widget and CSS setup, let’s provide a default border and background for the widget. This is done by overriding the StyleObject() method and setting the ThemeBorder and ThemeBackground properties there:

Putting it all together, our new widget is now ready to be registered with the widget palette and be placed in a package file for easier deployment and re-use by other QTX developers. Pretty damn cool if I say so myself!

Widget writers who deliver packages with new and cool widgets for developers to use, just have to provide a CSS file inside the package. When a project using that package compiles, the data-files are copied into the current project automatically by the IDE. The user just have to add the styles to his index.html document. This is literally a one liner operation.

This is the beauty of the QTX scheme. The extreme ease of use, letting the browser deal with as much composing as possible, and try to match things up through logic rather than brute force.

The new qtx.dom.theme unit

The theme system operates with a set of named styles that all widgets must follow. Sure, you can roll your own and ignore the system, that is perfectly fine, but the RTL based widgets are all rigged to use the QTX scheme.

A fair bit of thought has gone into this system, and the borders, backgrounds and colors are made to compliment each other. Developers making their own CSS theme files obviously should ensure they pick colors that go well with each other. For example, the border TThemeBorder.tbButton is made to work well with TThemeBackground.bgButton background type.

In the upcoming release a new unit has been added to the QTX.DOM namespace, namely qtx.dom.theme.pas, which contains the enum types used by the theme files and IDE scheme.

Most importantly is that TQTXWidget has been expanded with two new properties:

  • ThemeBorder: TThemeBorder
  • ThemeBackground: TThemeBackground

These enum types are straight forward in what they represent, and they are simply used as keys into a series of lookup tables in the unit dealing with name-to-type conversion.

You don’t really have to deal with this unit directly unless you want to. The new TQTXWidget properties are available from the form designer and widget inspector.

The enums are used as keys into various lookup tables for quickly setting a theme style

From the form designer and widget inspector, it’s straight forward. You can change the border and background of any widget.

Each widget will set the default border and background they use as a part of their creation, but you can override this and select whatever border or background you wish. Some times it can look good to mix things up a bit.

Windowing is special

The windowing UI that QTX ships with requires a bit more than just border and background styling, so that is somewhat bolted into the theme-file. However, a window is clearly defined in parts (header, footer, content region etc.) so new theme files will definitively contain new look and feel moving windows too.

I am considering separating the window styling into a separate file, so that it’s not subject to whatever color preferences has been set by a single theme. This will require a bit of contemplation before I change it since the window structure is far more complex than a simple, composite widget.

Well, I hope this was informative! More info will be available shortly!

An IoT scenario: Looking at hardware

This article was published on our Patreon site and was available to backers in May of 2022. It is re-published here as part of the drip from what backers have access to and what non-backers have access to.

I dont often write about hardware on this page, but as we near code-freeze to the IDE and development tools- my thoughts return back to our original project, namely the Quartex Media Desktop (codename: Amibian.js).

Just to underline: You dont need a SBC (single board computer) to work with Quartex Pascal. JavaScript runs anywhere, which is the point of making a development toolchain like this to begin with. This article is about working with IoT and embedded devices, which is completely optional.

Since I have written about Quartex Media Desktop before, hopefully everyone understands the value and power that brings. So instead of going into a pitch about that, let’s instead define a use-case where getting a dedicated IoT board makes sense. (Note: If you are not familiar with the Quartex Media Desktop, below is a video that demonstrates the prototype).

The ticket booth scenario

Let us for sake of argument say that you get hired by a large company to deliver a ticket system. The company provides you with a touch display and casing (booth) to house whatever hardware you request to finish this project. Your job is to sort out operating system, back-end technology, commercial dependencies like software licenses -and further, to implement the ecosystem that the customer will see and interact with.

This is where things start to get interesting, because such a ticket system has to scale. There wont just be one such device in use, but rather hundreds – if not thousands nation wide. As a growing business the company hopes to take the product internationally, which could result in hundreds of thousands of devices being deployed around the world.

Above: Amibian.js provides the infrastructure for your JS applications. Things like filesystem, security, IPC, and above all – a windowed environment and process isolation. For Kiosk style applications, your application is run in fullscreen (no windowing borders).

There are many factors to take into account here. In a distributed system that needs to scale, most of the pressure will be on the back-end (server) side of things. I would not attempt to simply “roll my own” back-end for a project of this magnitude, but instead make full use of Docker and Kubernetes to deal with the scaling aspect, while I would write the QTX server to make full use of available CPU cores and process clustering.

Define your products life-cycle

While the back-end will by far be the most complex piece to engineer, it ultimately holds less surprises. Like i mentioned above, technologies like Docker and Kubernetes pretty much solves everything with regards to scaling and meeting demand. What is more important for our ticket booth system, is to make sure we pick an SBC that performs well, and that will continue to perform well as our software grows in complexity.

This period of time is simply called the a products life cycle, with the EOL (end of life) marking the date where a company must upgrade their hardware. What duration we end up with ultimately boils down to growth in complexity, the amount of data that must be represented, and underlying non-visual complexity. For sake of argument, let us define a lifecycle of 3 years. Personally I would try to find devices that can deliver 5 years, but the difference in cost can be very high between the two.

Right out of the gates the Raspberry PI falls short. The first thing on my mind would be to find an SBC that can handle temperatures well, especially cold weather. If you plan to deploy the device to a region with cold winters then you can forget about the Raspberry Pi. You will need insulation in your booth, but for devices not designed for -30 degrees celsius, you also need an expensive regulator and heating elements. It will be more affordable to pick an SBC that can operate at -35c degrees celsius, and instead make sure you have good insulation. With active cooling the board will make sure the insulation doesn’t cause over heating in warm weather.

But for performance, which is ultimately where your code comes in, the Raspberry Pi is not quite up for the job. Sure, it will run Amibian.js just fine, but the performance will always lack “bite” to deal with demanding tasks, especially graphics intensive applications. A ticket booth system will obviously not be “intensive” compared to say, running Quake in the browser – but you dont want something as simple as a few video elements to potentially ruin the customer experience.

Define your low-end mark

Running Quartex Media Desktop (read: amibian.js) doesn’t require that much CPU power for the core system. The system is based on 5 node.js services where only 3 of them are critical for operation, the other 2 are optional. These services can either be installed separately on their own SBC (hardware cluster) or collectively on a single SBC. The node.js services use exceptionally little memory and they are just as fast as any service written in native languages like Delphi (or .Net C# for that matter).

When running a kiosk system with Amibian.js, you adapt the Linux setup to only run your software. You dont actually boot into the Linux desktop, instead you boot into Chrome in it’s own X-window session. Chrome will then run fullscreen in Kiosk mode and load the desktop from localhost. Once loaded into the browser the desktop connects back to localhost via websocket, and use Ragnarok messages to invoke API functions, perform file operations and run programs.

So the boot sequence for our SBC will look something like this:

  • Bootstrap loads kernel
  • Kernel loads Linux drivers, services and initialize
  • PM2 loads our node.js services and starts them
  • Our Node.js services use ZConfig to find each other
  • Each of our services register with the Amibian.js core service
  • Chrome is started in Kiosk mode with URL set to localhost where the Amibian.js core service hosts a webserver supporting websocket
  • Desktop connects back via websocket. All API calls happens via Ragnarok messages over websocket. The core service automatically routes API messages to whatever service is registered to deal with them, and likewise routes the response back to the desktop instance that issues them. In many ways the services act as distributed library files.

So if you install Amibian.js on a single SBC, the experience is indistinguishable from booting a normal, native Linux desktop.

The thing you want to factor in, is the graphical performance of the SBC. While you can run the services on any cheap board, the one hosting the desktop display must by necessity have enough muscle to render the display without issues. This means first and foremost a beefy GPU, but also a processor and RAM enough to delegate everything. A browser is perhaps the single most demanding piece of software in existence today.

As a bare minimum I would recommend:

  • 4 GB of memory
  • ARM v7 (Quad core A73 at 2.4 GHz)
  • SATA interface and boot support
  • eMMc boot support
  • RF / Bluetooth support

The Raspberry PI v4 does hit these marks, or at least it can easily be expanded to cover this list. But keep in mind that this defines our lowest point. This is the absolute minimum that I would recommend for using Amibian.js as your software delivery platform.

As of writing the prices for SBC’s have gone through the roof, and even a Raspberry PI v4 with 4Gb of ram retails for over $100. Which is ridiculous, it’s not worth that by any means unless you have some very narrow educational criteria hanging over you.

A much better buy, one that I picked out two years ago, is the ODroid N2. Not only does it check all the criteria, it actually has 2 extra CPU cores (based on the little-big architecture, where you have 4 powerful CPU cores, and 2 weaker cores). Not long ago the ODroid N2 was replaced with the ODroid N2+ which is roughly 30% faster than the original N2 yet retails at the same price. You can pick up this device for $83 at Hardkernel. And it’s worth every penny for general purpose development. It also acts as one hell of a games system if you want to give your kids a system to play Playstation 1, Sega Saturn and Gameboy Advance type retro games on.

But would I pick the N2+ for a ticket booth with a 5 year lifecycle?

The new breed of SBC’s

Most SBC’s are based on tech created for the mobile phone marked. Meaning that mobile phones drive the development of these SoC’s (system on a chip). The companies that deliver these SoCs want to capitalize on the production infrastructure they have setup, so after the contract for a phone expires, they usually offer the same SoC to embedded and IoT companies – which builds an SBC around them.

There is usually a 5 year delay between a SoC being used in a phone, and the time it becomes available as a fancy new SBC in the IoT sphere. A good example of this is the Snapdragon 880 series which powers expensive phones like Samsung Galaxy Note 9. The 880 series delivers performance comparable to an Intel i5 (first generation), which is incredible value for money.

The coolest board right now is the newly released Firefly SBC. This is not based on the Snapdragon, but rather a brand new RockChip CPU design – but it delivers performance better than Snapdragon 880. It is fitted with a powerful GPU that can handle 8k video and display modes, and you can buy a model with up to 32Gb of RAM (!) – which is a first for SBC’s I believe. I have never seen an IoT SBC with more than 8Gb.

Since manufacturing parts are scarce right now, I was not surprised to see that it retails at well over $200. But when you consider that a Snapdragon 880 development board sells for $2000 – I wouldn’t think twice about giving the Firefly a testdrive. And yes, it ticks all the boxes in our list (it’s way ahead of our minimum). First of all It’s based on ARM v8 (a whole generation ahead of our lowest mark), it has NPU chip which is used to run A.I models, it’s data transfer speeds is astronomical compared to our lowest specs – and you can fit it to an ATX motherboard and use standard PC cases if needed.

So if I was to pick a board right now for our 5 year lifecycle, I would go for the Firefly. If we lower the lifecycle to 3 years, the ODroid N2+ is just impossible to beat. I should underline that GPU support for X has been an issue for the ODroid N2, but that was solved via the Bifrost driver update a while back. But I would make absolutely sure and test it early if you plan on using it.

An alternative to the Firefly board, is Radxa: Rock 5b. This is based on the same RockChip RK3588 SoC that the Firefly uses. Price is significantly lower, especially if you pre-order, but to stay below the $200 mark you are limited to the 16Gb model.

So right now we are in that sweet 5 year spot where the previous generation of SoC’s are being repurposed for IoT devices. Although the RockChip 3588 is the exception rather than the rule. It is either way miles ahead of all the other board out there – and I would not buy anything below this is performance, unless your menu system will only see moderate improvements in the years to come.

Never buy boards for today, always try to think 5 years into the future.

Why not use X86?

You are probably wondering why ARM is the preferred platform in my articles, why not opt for a cheap and affordable x86 board? Intel in particular has dropped it’s prices and there is a lot of good SBC’s that are powered by overclocked Atom CPU’s out there.

Well, there is nothing in the way of using x86, at least at first glance.

A while back there was a movement in the US called “the right to repair” movement. They actually took Apple to court because Apple has consistently gone out of their way to stop people repairing their own machines. Apple even went as far as to fill machines with glue, just to make absolutely sure that nobody could repair, optimize or alter their own devices.

During that trial, which Apple lost, a lot of information was presented about ordinary x86 hardware, information that shocked a lot of people (myself included). Where everything from the firmware to the actual, physical hardware is rigged in in their favor. Microsoft especially has made it damn near impossible to buy a PC without Windows. There are some that allow you to install Ubuntu and pick between the two, but the whole marked is so heavily dominated by third parties that I dont see this changing any time soon.

When you add to this the facts that surfaced about Intel’s SoC’s, namely that they have several back-doors in the SoC design, bolted into the very hardware, that allows them to access your computer remotely – typically in concert with government agencies, suddenly x86 becomes a security risk because these back-doors were first discovered by hackers.

My reluctance for x86 has nothing to do with my personal activities, my digital life hardly warrants interest enough for any remote system incursion, be it the government or Intel. The point here is the principle of the matter, what people do with their computers is nobody’s business. And companies using “financial incentives” to dominate a marked that should be based on fair competition, is not something I will support of condone. Tese tech giants have even gone so far as to have legislation changed to suit their criteria. You dont have to be a rocket scientist to see where this is going, and what that means for consumers.

I should add, this is the real reason why Apple decided to create their own hardware. They have sold their new SoC as being about performance, but it’s actually about getting away from the legislation surrounding x86, parts and repair laws (especially here in Europe). By bolting as much as possible into a single part (SoC) they can ensure that customers are 100% dependent on them, and have to buy a new device. After all, If there are no parts to buy, you cant argue for any rights to repair either.

That’s the kind of people you are helping to fund when you buy their products. I haven’t bought an Apple device in over a decade, and I never will. Nor will i ever buy an Intel PC.

Bricked x86 SBCs

A good example of how controlled the the x86 marked has become – is to have a look at the x86 based UP board. Out of the box this is a good value for money board with the same form-factor and ports as a Raspberry PI. It used to sell for around $120 and is more than capable or running Amibian.js and tick all our boxes. It even has an on-board eMMc drive.

The problem is that their Firmware is bricked to only run two operating systems, namely Windows 10 or Ubuntu. When I asked them how I could boot other operating systems, such as Aros, Android or Haiku (a modern, open source re-implementation of BeOS), they simply dismissed me and referred to their documentation. There is nothing in the way technically for the board to run these alternatives, they would even run exceptionally well – but it boils down to financial incentives: they get paid by Microsoft for each license installed.

So to be perfectly honest: Companies dictating what type of OS you are “allowed” to run on your own device are persona non grata in my book. I simply ignore them and never buy anything from them.

Besides, with so much power and freedom in ARM these days – why on earth would you want to use an x86? The power consumption alone should be enough to say no thank you!

Next article

In this article we went through some of the boards available out there, and had a peek at thinking in life-cycles. I am going to continue writing about this scenario, and in my next article we will have a look at PM2, the process manager we use to run our node.js services in the background when your device starts!

Quartex Pascal version 0.17.2 released

This build contains fixes for bugs that has been lurking around the RTL and IDE for some time. Each revision unveils less and less items to fix, and I believe we are only a couple of builds away to mark the binary as a release candidate! It was a bit sad that the latest DWScript that was going to ship with this build was unstable, but rest assured that we will fork the latest and greatest once the DWScript codebase has been stabilized again. Eric is not one to leave bugs hanging for long.

Quartex IDE now has an RSS feed view to the forum on this website (top-right in the welcome tab)

Fixes for this build

  • Rolled back to previous DWScript which is stable
  • IDE now fetches the RSS feed from our forum (here at quartexdeveloper.com)
  • Fixed a problem with TQTXDynamicApplication model where the ShowForm() failed due to mistaken reintroduction
  • Fixed a problem with TQTXBoxedApplication model where a similar reintroduce caused issue. Both of these further affected the “ShowForm” method, so it was very fortunate that we fixed these now
  • The codegen omitted width when emitting code for TQTXBoxedApplication forms, which it should — this has now been fixed
  • Gave all widgets in the RTL icons. The default green puzzle piece is now reserved for clean HTML definition components (e.g 1:1 wrappers over direct HTML tags, like <Table> or <option> style elements). It also remains as a default glyph in case someone register a widget without a glyph
  • All widgets have been given a [DefaultName(‘<name here>’)] attribute, so that when you add a widget it is not named “widget1” or “Widget2” but rather “button1” or “listbox1” — which is what you expect and have in both Delphi and Lazarus.
  • Added a clean TQTXLeafletMap example, which demonstrates RT’s leaflet map package. Also gave that widget a google maps glyph (not sure it actually uses Google maps, that that is easy to fix).
  • Fixed a problem where WWR (web worker units) was not properly parsed and thus had no unit overview
  • Went over the code that resolves unit-file names, so it’s faster and more maintainable
  • .. and much, much more!

Future changes

With the TQTXBoxedApplicationModel finished, it is time to add that model to the projects menu. So in the next build I hope to have the new project template in place. With that however, the application object’s constructor (which is currently exposed in app.entrypoint.pas) will be consumed by the {$I “app::form.init”} code generator insertion point. Why? Because the application model for a project should not be changed by code, but rather in the build-config. If you change from say, a boxed model to a dynamic model, the only way the IDE can alter the constructor of the application object – is if it controls that snippet of code.

This means that examples have to be gone over, and I also need to adjust the project templates. It is an annoying thing to do in the 11th hour but will do a lot to the user-friendliness of the product, and also leave less confusion as to how to switch model in an already existing project.

Download

Backers can download the latest binary from Patreon

Update to latest DWS in the works

Like I mentioned in the previous posts in Patreon (backers only), we have precious little tickets left! And I have started on the last big change, which is to update DWS (Delphi Web Script) to the absolute latest, bleeding edge version.

This brings us a number of advantages, most notable is the fancy new async and await keywords. So you will be able to define a procedure as purely async, and further define code that waits for that particular condition to finish or fail. The mechanism behind this is called a promise, which is a common JavaScript technology by now – implemented at the lowest levels of JSVM both for the browser and Node.js.

This will have a profound effect on how we write wrapper code for external libraries. At the moment we have to use a bit of inline javascript in ASM sections to pascalify these mechanisms — so it will be a great to finally be able to work directly with promises as a part of the pascal language.

A pseudo example is when downloading a file via the fetch() browser method:

await fetch(url, procedure (data: JByteArray)
begin
// Success code here, bytes in the data param
end,
procedure (error: JError)
begin
// Error handling here
end);

Timeframe

Since we forked DWS some 3 years ago, there have been a lot of internal changes to the compiler and infrastructure. This includes name changes that, while superficial, affects more or less every inch of the IDE code. I cant just do a mass-rename inside the source-code either, since there have been subtle changes in a few public elements that are now protected.

In short, this will take a week more to get to grips with — but it will be worth the wait!

Website, forum and gearing up for RC1

As we are nearing RC1 with only a handful of tickets left, there are about to be some serious changes to our infrastructure.

So far we have operated with Patreon as our means to finance the development, and Facebook as our daily driver for live status, quick feedback and general community talk. This model has served the project well, except that Facebook really is a terrible place to run a group that is 100% dependent on a single person.

Facebook supports multiple account, and you would imagine that you could establish a business account and a personal account – and that these would be completely separate from each other. Sadly that is not the case, and should my personal account be blocked for whatever reason the Facebook A.I decides that day, the business account becomes locked as well.

It was never a long term plan to stick with Facebook, so it was time to bite the bullet and purchase a professional installation of WordPress with a forum plugin. And this is exactly what I have done. I was aiming to wait with that step until after version 1.0 was out the door, but Facebook has made it difficult to have both a personal life and professional life (which I consider separate) on the same platform. I have outlined at length how absurd the Facebook A.I operates, how it mistakes Norwegian words for English (with disastrous results) and so fourth. You can read that article here.

New model

Before x-mas I did a couple of polls in our Facebook group regarding how we should proceed. Regardless of the above mentioned debacle, Facebook as a platform is really only suited for user-groups and keeping track of friends. There is also the financial aspect of the product to consider. We need a stable income to ensure stable development of future versions. If we manage to secure enough, I would be able to work full time on this rather than just weekends. That would be much more effective for everyone and I would be able to expand the range and power of the product a thousand fold compared to what we have today.

The result of the polls were quite simple:

  1. We continue to use Patreon for handling backing and donations
  2. The Facebook group will become public (read: anyone can join, not just backers) much like Delphi Developer, FPC Developer and the other groups I run in the same family.
  3. New binaries will exclusively be issued via Patreon
  4. Community edition will be available on this website, but that will only be major releases (LTS). Those that wish to have running updates, patches and cutting edge documentation must subscribe to a Patreon tier. This is what everyone else is doing and it makes more sense. There has to be an incentive to get the cutting edge stuff (and yes, the tiers will be adjusted to better suit this model).

To give you some idea of cost, a year worth of $25 a month backing, which gets you binary updates (including docs) and articles is exactly $300. Keep in mind that this also includes the cluster environment, a ton of new components I will write, and all the fancy stuff that is lined up for version 1.1 and 1.2 (like database components, filesystem over WebSocket and so on). The hard work with the IDE is done, and we can polish and make sure the details get better – but all in all the IDE infrastructure is ready to rock. Focus after version 1.0 will be more on content, demos, articles, ready to use project templates, new packages, utility features and drop-in protocols (yes you read that right). This is where the fun begins.

This is a product that we can aggressively expand to consume pretty much whatever we want of the JSVM / React / Node.js world. We don’t have to wait for Idera or Embarcadero or anyone else. QTX is a free agent and answers to nobody but the backers. Once we agree on a tech, I get to work and make it a part of the IDE and RTL. And this also includes exciting stuff like bytecode assembly, WASM and baking native executables via Phonegap and React directly from the IDE.

In plain English: We can’t keep going like we have up to now, because we are financially nowhere near where I can jump over full time (or 50% for that matter). The only way to get anywhere close to a 50% position, is to get everyone over on Patreon. Even if it’s just the lowest Tier (I will adjust the tiers) that would radically change things. It’s a long term goal, but it’s there.

There is also something to be said about simplicity. Having to re-post the same news in 3 places is a bit much. At least now we have this website as the main focal point and Patreon for backers and “subscriptions”. So feel free to post to the forums here on this website (you probably need to register first).

QTX reaches code freeze

I am happy to report that Quartex Pascal has reached code-freeze. This is the stage where we stop researching and adding new features, and instead focus on what has already been added. Basically this is where we polish, refactor and make the codebase production ready.

Its been a journey but I am finally getting close to RC1

During the research phase of the development system there were several tickets that I left in semi-working condition. Features that I know how to solve and roughly how much time they would take to complete. The worst thing you can do is to push the difficult and truly challenging features towards the end of a project, because you risk ending up with a product that simply don’t work as expected.

Code-Freeze is the timeframe where all the unknown factors have been solved, and I systematically go through the project step by step, completing the tasks that I left in semi-working condition. It is also this phase where backers and testers report findings back to me so they can be corrected.

Tickets and latest fixes

There have been a ton of fixes since the last post on this website. If you want to get up-to date information, please see the Patreon website. Backers get access to both Patreon downloads and our Facebook user-group where we post daily and weekly. Below are the highlights for the past 4 months:

  • Code suggestions
  • Parameter hints
  • Mouse-over hints
  • Project templates
  • Externalized graphics
  • Delegates
  • Automatic form creation
  • Ragnarok protocol designer
  • Remaining tickets
Code suggestion

Two features that is considered common for all IDE’s (integrated development environments) is without a doubt automatic code suggestion and parameter hints. No matter what language you work with you expect the IDE to perform live code analysis and present you with available members, properties, fields and bindings at language specific junctions. In Object Pascal whenever you type a fieldname or variable followed by “.” (punctuation), the IDE presents you with a pop-up dialog with suggestions.

Code suggestions now work brilliantly, and very fast I might add
Parameter hints

The same is true for parameters. Whenever you have typed a function or member name, followed by “(“, the IDE is expected to present a hint box that displays the parameters of that member. If the member is overloaded and have multiple parameter options – it should display them in a top-down list fashion. It is also common that these hints remain visible while you type, highlighting the parameter item you are typing.

Parameter hints now work as expected

These two features are actually very, very difficult to create. They require that the IDE parses and maintains an AST (abstract symbol tree) in the background that is queried live with regards to relevance and visibility of whatever symbol you are addressing. Without getting into the nitty gritty of it all, these features were quite difficult to get right, but they are finally in place.

Mouse-over hints

I also finished the mouse-over information, where you move your mouse over a keyword or symbol and information about it is displayed in a standard tool-tip. These features all rely on more or less the same functionality, so once I had a working model it was relatively easy to kill three birds with one stone.

Mouse-over hints are now in place. This feature has room for future improvement, but its a solid start
Project templates

The IDE operates with project templates much like Embarcadero Delphi or Lazarus. This means that I have prepared a particular project which is registered with the IDE when it starts. When you create said project, the folder that makes up that project is cloned and saved as your new project.

The project cloning tool simplifies creating your own project types

Since the RTL (runtime library) spans both HTML5 (browser) and Node.js (server side scripting), the IDE recognizes different project types. When a template is registered the type of project is very important, otherwise the IDE wont be able to distinguish the rules for each type. For example, a form based HTML5 project cannot contain code that is designed to run on the server, and obviously server-side code wont work in the browser.

This is further complicated by the distinction between forms and windows. A window is technically a form, but it has a title-bar, close, minimize and maximize gadgets, can be resized by the user and moved around. Without a correct template type during registration this system would be a complete mess.

The project templates have been made up-to-date. There were a few mistakes that had sadly been replicated between dynamic, tabbed and windowed project types, but there are now fixed.

The IDE also allows anyone to create their own project types without leaving the IDE. If you right-click a project in the “New project” dialog you can select “clone” and you are presented with a dialog that helps you. This feature is handy if you have wrapped a JavaScript API and want to simplify projects based on that API.

Externalized graphics

At the moment we are using free glyphs (icons) from Icon8 which look good in both light and dark theme (imho). But having these hardcoded into the IDE executable seems less than ideal considering that we support themes for the IDE. As such I have implemented a glyph manager which loads the graphics from disk when the IDE starts.

The glyphs and icons used by the IDE are now purely loaded from disk and can be replaced

This means that people can replace these glyphs themselves if they so want to. The IDE now supports both 24×24 and 48×48 pixel glyphs. By default the IDE uses the 24×24 glyph size. The larger glyphs can be handy for people that suffer from poor eyesight, which is why I included them.

The icons for the code-suggestion dialog is likewise loaded from disk. As of writing these are 16×16 pixel in size, but the IDE operates with a row-height of 24 pixels (smaller glyphs are vertically centered), so these glyphs too can be replaced.

Delegates

The IDE now supports visual delegates for all widgets (visual controls). Delegates is a concept that Delphi and Freepascal developers might not be too familiar with, the closest thing in the pascal world is an earlier COM concept called multi-cast events.

All visual widgets can have delegates added to them, as many as you like per-event

In traditional Object Pascal each event can only have one handler procedure. This is because pascal events are essentially just a pointer that glues caller and called together. Delegates however are objects that wrap an event and offer multiple handlers to be registered. In short, if you want 10 event handlers to fire in response to your OnClick event, you can register 10 handlers to the same delegate and they will fire in the sequence they were added.

Note: Quartex Pascal still supports ordinary pascal events, but these are used purely by code. They are still the fastest in terms of execution and very efficient. But since HTML5 and Node.js relies heavily on delegates – it makes much more sense to use that for UI elements.

Adding 3 separate delegate handlers that all fire in response to an OnClick event

When you add a delegate to a widget on your form or window, you can double-click the delegate handler and the IDE injects a procedure handler for you (just like Delphi does for common events). If you double-click on an existing delegate handler, the IDE switches to the edit-tab, locates the handler, and places the cursor on the first line.

Automatic form creation

This was added quite early but due to a bug in how I encoded information we had a build where the form-path was stored rather than the form name. Needless to say this caused havoc as no forms were created when applications started.

This was easily fixed and the projects affected by it were cleaned up. You can check each of the forms you wish the application to auto-create when it starts inside the project options.

Project options will list the forms in your project and you can check the ones you want created on startup
Ragnarok protocol designer

Ragnarok is a JSON based message format that simplifies message dispatching between client and server, as well as routing messages in a cluster architecture. It is lightweight and simple in terms of data.

As is the case with all communication, it is the scaffolding that is time consuming. The code that parses a message, that recognizes it, that delegates the message to its handler – and that makes sure the response is issued to the correct recipient. Keeping track of messages in an asynchronous environment can be tricky if you dont build the correct infrastructure — which is where Ragnarok comes in.

When you add a protocol to your project, you can double-click and edit the protocol in the IDE

The IDE now has a built-in protocol designer. This is where you can define datatypes and messages that will be shipped between client and server (or between processes for that matter).

Once designed, the IDE will automatically convert the protocol file (*.rrp) to pascal code. Which means you don’t have to waste time writing message envelope code and instead focus on populating and working with the messages. These messages are exceptionally well suited for WebSocket, but the RTL also comes with an UDP server (node.js) and client that can likewise be the medium.

Ragnarok as a format is not bound to the actual transport of the messages. You can ship these messages via any medium you like, be it HTTP, WebSocket, UDP, TCP or IPC (inter process communication). The Quartex Media Desktop actually uses Ragnarok as the default protocol system between host (desktop) and applications. All “soft-kernel” calls are done purely via messages.

Note: This system will grow considerably as Quartex Pascal is further developed. There is a lot of room for expansion and we can implement some amazing technology here.

Remaining tickets

As of writing we have only a few tickets left. There will always be more as we dig into the codebase, small things that we have forgotten – or sloppy mistakes like not setting the tab-stop correctly, but all in all we are in good shape!

Right now I am working on the Besen2 Javascript provider class. The IDE has a provider class for each filetype it supports. This provider class deals with parsing and maintaining the TTreeview (unit overview).

After that it’s time to finally give the Search & Replace dialog some love, this has been waiting for quite some time. But after that, it’s pretty much done in terms of core features. There will always be minor adjustments and tickets to fill, but based on what we aimed to deliver in version 1.0 — we have reached our goal.

These are the tickets remaining

Better information pages!

This website is meant as an information page for those interested in Quartex Pascal or the Quartex Media Desktop projects. The idea of this website is that, once version 1.0 is out – this is where people can go to download binaries and the community edition. But until that is the case, news is posted weekly to Patreon and ad-hoc to our Facebook group.

The Facebook group is for backers only at this point, but once version 1.0 is out we will open it up for everyone. It will become an interest group much like Delphi Developer or many of the other language groups on Facebook.

Anyways, I have spent some time writing more about Quartex Pascal and it’s features here. I also updated the Quartex Media desktop so that this has it’s own page and menu item too, making it easier to get familiar with both.

I will continue to write and add more and more information (and split the page into sub-sections rather than one massive document) as we move forward.

Getting involved

If you find Quartex Pascal interesting and want to back it, head over to Patreon and sign up there. After you have signed up, head over to Facebook and join our group there for chat and questions. New binaries are published mostly weekly, but some times it can take two weeks between drops. The latest binary is always pinned at the top of our Facebook group, and you will find it on Patreon as well.

Cheers!

This week’s fixes and build

A few bugs were reported on the last build, which have now been promptly fixed. I have also updated our to-do list so that everyone knows where we are with regards to the first beta release. It might look much, but keep in mind that most of these task take 1 hour tops each. Only the most elaborate tasks will take longer.

Note: This post is 3 days late. I came down with a nasty cold on thursday and pretty much spent the entire weekend in bed. A national holiday started on monday, and it was my time to take the kids on a trip. So it’s been a less than productive weekend, but that’s just how it has to be. I always make up for lost time.

Ok, let’s go through the tasks for this build.

Bugfix list

  • A bug where starting two instances of the IDE caused the latter to throw an access violation
  • A strange case where the resize grab-handles for a selected widget suddenly would not render
  • The caption property was not set on windows (TQTXWindow) in windowed projects. This turned out to be quite critical
  • Windowed project file was missing the {$I “app::form.init”} compiler injection point, meaning that forms would not be automatically created. Instead the windowed default project operated with code that created windows manually

Multiple instances of the IDE

It was suggested that we use a Mutex to make sure only one instance of the IDE is running. However, the IDE should be able to run in multiple instances by design. The reason for this is because it simplifies writing client / server solutions on the same machine.

After the fixes mentioned below, you can now run multiple instances of the IDE simultaneously

The IDE is initially designed to handle multiple projects simultaneously, but to save time I decided to push that feature into the future. It’s not a critical thing at this point. Not as critical as getting the first version out the door in good condition is.

Log4Delphi

When inspecting what caused the problem I discovered that it was in fact the logging system that was the first culprit. We use Log4Delphi which is a 1:1 conversion of Log4Java. All in all a very simple system that I could have written better myself, but again – time is a factor here since we are overdue by almost 2 months. Hence I just picked a ready to use logging system that we could use without much hassle.

Turns out that Log4Delphi opens a permanent filestream without any sharing flags (meaning that it locks the file for read and write access by other processes). Since the Log4Delphi is open-source I simply went in and added the fmShareDenyNone if the log is opened in either fmOpenRead or fmOpenWrite modes.

The IDE now creates logfiles with filenames based on date and time, each instance thus operates with its own logfile

I decided to make it more bullet-proof, so I implemented a filename function that generates a filename based on date and time. This ensures that two instances will never try to own the same file – at the cost of each IDE operating with separate logfiles. Not a huge deal I feel, since the logfile is not a permanent fixture – we will be logging to standard WinAPI after the release candidate.

TZipfile and packages

The next culprit that prevented multiple instances to run was the package loader. Quartex Pascal uses ordinary zip-files as the package format. Zip-files are almost universal and natively supported by Windows, so using that for packages makes a lot of sense. This way developers can easily create package-files for their components ready for distribution.

QTX packages are just ordinary zip-files with whatever resources your widgets need. Widgets are registered via Attributes.

The problem was, again, that TZipFile’s Open() method does add the fmShareDenyNone flag, effectively locking the package for the entire IDE session. Since TZipFile is a part of the Delphi RTL I can’t simply copy the code and change it to better suit our needs. But as luck would have it there was an overload for Open() that takes a TStream. So I just modified the Zipfile filesystem driver to open the package file via a TFileStream with fmShareDenyWrite flag (allowing reading but refusing other processes to write to the file).

With this change, you can now run multiple instances of the IDE without problems.

Form designer grab handles

Before the previous release I more or less re-coded the selection logic for our form-editor. A form editor that supports the features we do is not easy to write, especially since the widgets are not Delphi TCustomControl’s (like most other designers operate with), but are drawn and represented purely via TCanvas.

The code had reached a level of complexity where, if we continued, it would have grown into a spectacular mess. So I decided to refactor the entire selection system, which is spread out over the 3 common mouse handling methods (mousedown, mousemove and mouseup).

Grab handles for widgets and the form is now back. The logic for these will likewise be refactored

For some reason I had forgotten to create the TProxyResizeIndicators instance in the selection situation code (all actions you can do like select a single widget, multiple select, add or remove from a selection — these all make up specific “situations” that the designer must check for and respond to). I also needed a call to __ImmediateRedraw(). Once these were in place, the resize-bars were back as they should be.

The missing caption

When I implemented the code for the last build I was quite tired, but how I managed to miss this puzzles me. The codegen that converts the prototype (a “prototype” is an object that contains all the published properties for widget. The IDE scans each widget when it boots, and whenever you drop a widget on a form, it clones out the properties that the inspector can work with) for a widget into code at compile-time, a process which is recursive and has zero room for errors.

For some strange reason the TViewImplementationCodegen was missing a call to EmitPropertiesFor() where the properties for the form was generated for the TQTXForm or TQTXWindow itself. This is obviously due to the fact that we waited with that part of the RTL until we had delegates added to the codegen.

The properties for TQTXWindow and TQTXForm are now written in full, solving the caption issue

It is a good thing we noticed this, because the code was only emitting properties like width, height and name. This meant that the Caption property was effectively never set! It would also mean that none of the other properties would be generated. A bit sloppy, but the code we are talking about here is very dense. Recursive code on this level is easy to get wrong, believe you me. You have to take account for every situation, and distinguish between subtle differences.

For example, if the project is of type dynamic, the height property should never be written (otherwise the page would have fixed sizes on the content and not scale). Windowed projects are different and must have width, height etc. set early in the constructor code — so there are a lot of levels to this type of code.

Updates the Windowed project template

The code for windowed projects is old and was written just before we got delegates into the mix. At that time the IDE did not recognize TQTXWindow as a form, and would only deal with TQTXForm. As such the windowed project type would have code to manually create a TQTXWindow, and there was no DFM file to house the design – and consequently no way for the IDE to automatically create windows added to the program.

With the IDE now aware of TQTXWindow, the standard “$APP::form.init” injection point works as expected

This has now been updated and the new windowed application type works exactly like a normal dynamic project.

What is left before we can enter beta?

There are quite a few minor additions and changes we have to implement before we go into beta. The “bugs” above are good examples of smaller tasks that can be found here and there throughout the codebase. Nothing critical or overly complex, but they have to be dealt with.

Right now I am operating with the following task list:

  1. Delegate event code. When you double click on a delegate the IDE should either inject the event handler (like Delphi does) if it does not exist, and consequently switch to the code-tab and goto the procedure.
  2. Delegate add dialog. The “new delegate” must have a name-field and also be simplified, right now the design makes little sense.
  3. Delegate edit dialog. This is essentially the same dialog as above, but without the code for adding anything, it should be edit only, allowing you to change the delegate class-type and name. This is more elaborate since it also requires the form code to be changed automatically by the IDE.
  4. The TRagnarokProtocolImplementationCodegen class must be completed. Right now the codegen for ragnarok protocols emits the interface, but not the implementation. Again this type of code can be complex due to its recursive native, but I estimate a full work-day to get it done and ready for testing.
  5. Ragnarok project types: we need to make it easy to create ragnarok based projects. This includes node.js servers, node.js system service, dynamic and windowed client. Ragnarok does not impose itself, so you can add a protocol to any project and the IDE will spit out the code for it, but having ready to rock project types will make it easier to get to grips with.
  6. The preferences dialog has a lot of options that must be finished. Also, the layout needs a refactoring, especially for the SynEdit color palette stuff. It is less than intuitive.
  7. The HTML dialog must be refactored. Right now we are using the default HTMLComponents editor with toolbars, and the toolbars dont really work well in a dialog form. A traditional toolbar must be implemented. This should not take long since all toolbar features are isolated as TActions
  8. The IDE must have dialogs for all supported dialog types (around 10), right now we have 2. Thankfully a lot of this is boilerplate and functionality is largely displaying options and writing them to the widget prototype
  9. TQTXMainMenu editor. Not critical but I think this is a very important feature. Being able to create windowed applications easily for HTML5, mobile, embedded etc. requires a good menu editor. We might push this to version 1.1 is we dont have time.
  10. Probably 100 little things and tweaks, but thankfully nothing fancy or huge, one-liners mostly and smaller graphical adjustments.

As always, the latest build will be available on Patreon and for our backers on Facebook in Quartex Developer.

New Build 0.15.6.9b

A somewhat curious bug had appeared in the latest build, where *.wwr files (web worker files) were no longer recognized by the IDE. Turned out I had somehow typed “.wrk” when refactoring the file-type association code, resulting in the IDE delegating the task to WinAPI.

This has been promptly fixed and a new build can be download from Patreon.

New website, easier access

Quartex Pascal has been in active development for the past 18 months. The project is overdue by a few months due to covid and associated factors, but we are quickly closing in on the release of version 1.0 (hurray!)

Since Quartex Pascal has been a sort of sub-community-under-the-radar kind of project for so long (bordering on a skunkworks project), becoming more public and easily available is more than overdue. It is important to make things easier for new backers and users as they come along, and having an official website achieves that.

Patreon and Paypal

The project is still a Patreon project, just to underline that. This website here has no means to accept funding or donations, so if you feel like helping out then we have two ways you can do that:

  1. Visit the Patreon page and pick a tier to support
  2. For donations and single-shot gifts, use Paypal (if you donate 100€ or more, you have full access to our invite-only Facebook group. A thriving community of backers and developers. Simply PM me on Facebook afterwards to get access).

While version 1.0 will be out in a little while, that is by no means the end of Quartex Pascal. We have a lot of technology just waiting to be included in the IDE and RTL! Things like data aware controls, a full database editor, REST and SOAP protocol support, full NAS OS (the Quartex Media Desktop) deployment, ASM.JS and Webassembly, building native applications for desktop and mobile via Phonegap and similar technology — and much, much more!

Update for Customers Using PhoneGap and PhoneGap Build | by Adobe I/O |  PhoneGap
We have so much cool stuff lined up for the next versions, it will make mobile and embedded development ridiculously easy

The way I look at it, Quartex Pascal version 1.0 represents the foundation stone. It is the foundation that we construct better and more elaborate technologies on. The world of web technology has so many exciting avenues that object pascal developers can make use of – the sky literally is the limit here.

Easier access to material

This website will also serve as an easy access point for media. I have several presentations that I have held regarding QTX and it’s associated cluster technology, and putting everything in one place for easy access is the way to go. We are slowly moving from our garage days into a more office like modus operandi, so bear with me as go forward – it will be awesome once all the dots align.