UI programming you said?

Usually business applications are split in three tiers: user interface layer (UI), business logic layer (BLL) and data access layer (DAL). That split is also known as Model-view-controller architectural pattern.

Ideally each layer should be isolated from the rest. For many good reasons. In any case each layer operates using its own vocabulary (namespace if you wish). For example “Account” in UI means some set of fields (<fieldset> literally). In BLL it is an instance of some class with attributes and methods describing logic. And in DAL it could be just a record in DB with associated triggers and stored procedures.

Code that works on each layer(domain) is serving different tasks. Ideally each such layer may require different programming languages that are optimal for each particular layer. E.g. DB layer as a rule uses TSQL as it better suits DB manipulation needs.

The same thing is about UI. Usually UI tasks are just sequence of rules like “if user clicks here than enable that thing over there”. Such tasks may or may not be handled equally well by universal languages like C++.

Ideally UI layer should have its own language that is better suitable for UI needs. In the same way as DB has its own language (couple of them actually: DB schema definition language and transaction definition language).

Consider following task: you have toolbar with “save” button and two widgets that do different things in onSave() methods. In C++/htmlayout you would need to create separate dispatcher that knows about “current” element and reroutes “save” button clicks to different widgets. That will require separate external entity for these two widgets.

And in Sciter you would write this as:

class MyWidget: Behavior
{
  function onFocus()
  {
    var me = this;
    // bind toolbar buttons to this widget methods:
    self.$("button#save").onClick = function() { me.doSave(); }
    self.$("button#new").onClick = function() { me.doNew(); }
    self.$("button#open").onClick = function() { me.doOpen(); }
  }
  function doSave() { ... }
}

when MyWidget gets focus the code in onFocus() replaces onClick event handlers of the toolbar buttons by new functions like function() { me.doSave(); } that will call methods of this particular widget.

You can simulate things like this in C++ of course but it will be significantly more complex. Try to imagine how you would do this in WTL or MFC or any other GUI toolkit. Less code – less errors and so on.

After many years of designing various UI and UI toolkits I shall admit that UI automation/programming is not quite OOP task in general. Usually it is better describable in terms of something close to functional programming but with the ability to define classes/objects.

UI is an assembly of sometimes very different UI components/controls. That requires language that is flexible enough to glue them together. That is my vision on TIScript in Sciter.

And of course markup and CSS are also Good Things for the UI. Especially CSS.

2 Replies to “UI programming you said?”

  1. Your Sciter example seems nasty for me. The trick with event processor substitution is example of “unwanted cleverness”. Somebody will read code for years to understand why simple saving function behaves so differently in different times.

    Why not just do once:
    $("button#save").onClick = function(){getFocusWidget.doSave();}

    It is clear, simple and flexible enough. And, btw, makes unwanted you “functional trick” 😉

  2. Your code will not work as getFocusWidget() will return that button#save element itself – the one that was clicked. To make such things working it should be a concept of “active view”.
    Something like

    self.$("button#save").onClick = 
         function(){ if(getActiveView()) getActiveView().doSave(); }

    which is definitely more “noisy”.

    In any case when view is getting activated (receives input focus) it should do many things on setting up the environment – enable/disable buttons, even showing/hiding elements of toolbars and other observers around it. So it is not only a matter of attaching event handlers like:

    self.$("button#save").onClick = function() { me.doSave(); }

    but also updating many other things. Say you have an editor that has “WYSIWYG” and “Source” views on the same document. While switching between these two you need show/hide some UI elements that make no sense in one of the views. You can automate this task by using CSS with attribute switch:

    toolbar[mode="wysiwyg"] .only-for-source-view { display:none; }
    toolbar[mode="source"] .only-for-wysiwyg-view { display:none; }
    

    but still it needs to be some code that will change value of the mode attribute.

Comments are closed.