How it works
This page explains, without going into the code, what happens inside a Fresnel program.
Five steps
When a Fresnel program runs, these steps are repeated whenever something changes:
You build a tree of elements
Your form contains elements: a body, some boxes (TDiv), labels, buttons, edits, a grid…
Each element has a parent, so together they form a tree. The designer creates the tree from the .lfm file,
or your code creates it, just like LCL controls: TButton.Create(Self) and setting Parent.
CSS is applied
For every element, Fresnel’s CSS engine finds all CSS rules that apply to it and decides which one wins (this is the cascade in Cascading Style Sheets). The result is the final value of every property: this color, that border, this font.
Layout: where does everything go?
The layout engine measures the elements and decides the position and the size of each one. It knows the three main ways of CSS to place things: normal flow (like text in a paragraph), flexbox (rows and columns that grow and shrink) and CSS grid (rows and columns like a table). When content does not fit, scrollbars appear.
Drawing
Every element is drawn: background, border, content (text, image, …), then its children. The drawing is done by a renderer, which is different for each platform.
Events
The platform layer delivers mouse and keyboard input to the right element. Your event handlers run, they can change the tree or the CSS classes of an element, and the cycle starts again. Fresnel only redoes the work that is needed: changing the color of a label repaints the label, it does not redo the whole layout.
The layers
Fresnel is built in layers. Your program only talks to the top layers. The bottom layers are exchangeable.
Everything above the renderer is 100% Object Pascal, and it is the same on every platform. Only the bottom layer, the backend, knows about the operating system. A backend provides two things:
- Windows and input: it creates the window of a form, and passes the mouse and keyboard events to Fresnel.
- A surface to draw on: the renderer draws the elements on it.
The Free Pascal compiler picks the right backend for the platform you compile for. You do not need to change your code.
Why draw everything yourself?
The LCL mostly uses the controls of the operating system. That gives a program the “native look” of each platform, but it also means that every platform behaves a little bit differently, and that you can only change what the operating system allows you to change.
Fresnel only asks the operating system for an empty window, and draws the rest itself. This has advantages:
- The same look and behaviour everywhere, including in the browser.
- Everything can be styled with CSS: rounded corners, gradients, text shadows, transitions, custom scrollbars.
- Modern layout: flexbox and grid adapt the form to the window size and to the length of the texts (for example, after translation).
- New platforms are easier to add: a backend is much smaller than a complete widget set.
Familiar ideas from the web, in Pascal
Some web developers’ tools work in Fresnel too, because Fresnel uses CSS:
- Existing CSS frameworks. Some controls (menus, tabs, status bar, toasts) can use the class names of Bootstrap or Bulma, so these frameworks’ stylesheets can style them.
- Developer tools. Fresnel has a CSS inspector and a layout inspector, like the developer tools of a browser. They are Fresnel controls themselves, so you can put them in your own program.
- Events that bubble. An event travels from the element where it happened up to its parents, so a parent can handle the clicks of all its children.