We have an important change to one of our most important concepts: states (TUIState
descendants) are now called views (and descend from TCastleView
).
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 🙂
Why?
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.
Moreover, TUIState
class name is not consistent with CGE naming. And TCastleUIState
or TCastleUiState
are too convoluted. So for a long time I knew it will have to be renamed to TCastleState
or TCastleView
. I finally finished the work to go with TCastleView
.
“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 TUIState
class methods/properties, could be improved to use simple methods on Container
.
This way there’s often no need to know what is the “central” container (TCastleControl.MainControl
is 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; |
MyControl.Container.View := PlayGame;
instead of
TCastleControl.MainControl := MyControl;
TUIState.Current := PlayGame; |
TCastleControl.MainControl := MyControl;
TUIState.Current := PlayGame;
This is already reflected in new TCastleControl docs.
Upgrading
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):
-
Rename
TUIState
-> TCastleView
.
-
Remove CastleUIState
unit from your uses clause. Make sure unit CastleUIControls
is there (it likely is there already).
-
Change in ApplicationInitialize:
to
Window.Container.View := ... |
Window.Container.View := ...
-
Change in various states (views):
TUIState.Current := ...
TUIState.Push(...)
TUIState.Pop(...) |
TUIState.Current := ...
TUIState.Push(...)
TUIState.Pop(...)
to (respectively)
Container.View := ...
Container.PushView(...)
Container.PopView(...) |
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 StateXxx
.
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 state
->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'; |
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'; |
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.
Docs
Our documentation, including important chapters about view events and managing views, has been upgraded to new terminology.
Our examples are also fully upgraded now to use view terminology everywhere.