I will now explain what I expect that gui separation to be able of. What part of the gui is in the core, and so on. First of all, we'll assume the gui is static, i.e. no sudden window creation and other stuff.
Note that I am writing this so that I myself understand how I will code the AlMuist's API (Which does not yet exist), so it might look a bit obscure for now ;-)
What we want is to allow a graphical user interface to be designed after compilation, and let the programmer choose what communications are possible through the gui.
I will define a special kind of invisible gui component which are, precisely, objects inside the gui hierarchy, but that have no visible counterpart.
Then, the gui will be separated into two distinct parts:
A notification is a kind of link between two objects (a source and a destination); when the source is modified, a message is sent to the destination, usually asking it to reflect the changes of the source.
As you should be used to if you've already coded with Mui, you can specify notifications between the attributes of the components of the gui. So you can have notification links between hardcoded components, and you can have notifications from some external component to anything else.
Notifications for the program (i.e., when something must trigger some action of the program, and not just an attribute transfer) can only be generated by the hardcoded components (as the program does not know what is in the gui!)
To sum up, when the user wants to trigger some action of the program, either he accesses directely a component of the model (which is then connected to the program), or he accesses a component of the added gui, which is itself connected to a component of the model, which, in turn, will send the command to the program.
I said above that the program can define some components, in the model, and that the external
gui was simply added to it.
If you want to have real core-gui separation, The Model Should Only Contain Invisible Components.
Thus, a proper user interface can be defined like this:
I'll speak some more of these invisible objects.
As already implied, an invisible object exists for holding some data, as well as communicating between the core and the added interface, using notification
A program must be able to communicate any kind of data with
the user, and this must be specified in the model.
Furthermore, I think it is useful to say not only the size of the data (is it an array, a long, a char...), but also something about the kind of data. For instance, it is important for the gui to know that some given long must be a number between 0 and 9, or a power of two (a number of colours), any positive long, ..., even if they are handled pretty much the same way. In the same way, the gui must make a difference between a number between zero and 255, and a character, and the intensity of a colour...
It would be a good thing if the invisible objects checked the compatibility between the object they are linked to and themselves.
A user of some program that has a separated gui must be able to modify that gui
To allow that, the gui definition will be Amool code and will be read by the program at startup, through some Amool library.
I will make a gui hierarchy, in the same way as there was a language hierarchy, where the highest class merely describes what is a gui (ie what you can put in it), and describes those invisible components (there is no reason why an invisible component should depend on the gui-system). Subclassing that will come classes that describe the capabilities of concrete gui-system, like AWT or Swing for Java, Easy-GUI or MUI for E, and so on.
Now, when you are actually making a program with a gui, you will subclass one of these, describing what your
specific gui must be able of. (In a child of your program, something like @gui
And if you are making a 'really abstract' gui, then you will make your gui composed of only invisible components, and subclass that abstract gui system mentionned above (which means that your program will not know what gui-system it is using to communicate with the user, as it is handled externally!)