We have an important change to one of our most important concepts: states (
TUIState descendants) are now called views (and descend from
It’s a change in terminology, and a change in API. While previously you were changing states using class functions and properties, like
TUIState.Current := Xxx, now you should use regular container methods, like
Container.View := Xxx.
Oh, and to this we add a new slick UI when opening the project 🙂
It addresses two things:
The name “state” was too generic and thus meaningless. Almost every variable and object instance in your application can be called some “state”.
It made sense if you think “user interface state” or “state of a state machine“… but the sole word “state” is too generic.
TUIStateclass name is not consistent with CGE naming. And
TCastleUiStateare too convoluted. So for a long time I knew it will have to be renamed to
TCastleView. I finally finished the work to go with
“View” doesn’t seem too bad name. It clearly communicates it’s something visual and is a way to “see” CGE stuff. And, view isn’t that often used as a noun, so when someone says “This view is amazing” you can fairly safely assume they talk about
TCastleView(assuming you’re in the middle of CGE manual, not on a hiking trip 🙂 ).
It is consistent e.g. with React view.
The way we changed states, using
TUIStateclass methods/properties, could be improved to use simple methods on
This way there’s often no need to know what is the “central” container (
TCastleControl.MainControlis now deprecated) and every container has it’s own, separate, state stack (or rather: view stack now). This makes things simpler if you try to use multiple containers or
TCastleControl(whether for LCL, VCL or FMX). You can just do
MyControl.Container.View := PlayGame;
TCastleControl.MainControl := MyControl; TUIState.Current := PlayGame;
This is already reflected in new TCastleControl docs.
This change is 100% backward-compatible. The old code will continue to work, though we advise you to upgrade to new names and container methods/properties.
In total, the upgrade path in typical applications is rather straightforward, although it will require to do a lot of replacements (I recommend to commit everything to your version control before doing the upgrade, and then have a nice diff to audit with state->view upgrade):
CastleUIStateunit from your uses clause. Make sure unit
CastleUIControlsis there (it likely is there already).
Change in ApplicationInitialize:
TUIState.Current := ...
Window.Container.View := ...
Change in various states (views):
TUIState.Current := ... TUIState.Push(...) TUIState.Pop(...)
Container.View := ... Container.PushView(...) Container.PopView(...)
Optionally, as a final touch: rename your units and designs.
Previously we called them
gamestatexxx. With class like
TStateXxx, with variable like
Now we advise to call them
gameviewxxx. With class like
TViewXxx, with variable like
ViewXxx. If you choose to go with rename, you will likely find that a general interactive rename
view, and accepting 99% of the replacements, it the way to go.
You can just rename them everywhere. Remember that the unit also refers to the design, doing something like
DesignUrl := 'castle-data:/gamestatemain.castle-user-interface';
So if you rename both the unit and design (which we recommend, to keep F12 working nicely in CGE editor) then change also that line of code to
DesignUrl := 'castle-data:/gameviewmain.castle-user-interface';
New editor UI when opening new project
This is accompanied by a cool upgrade to our CGE editor UI. It happened because of independent reasons (I did UX testing on a live human at Christmas :), and came back with lots of nice conclusions) but it is nicely connected with the whole views terminology.
Now, when opening any project, you will be greeted with a UI to
- compile and run / stop the project
- create a new view (Pascal unit and design)
- open an existing view
This UI emphasizes your most recommended actions after opening the project.
Our examples are also fully upgraded now to use view terminology everywhere.