uimetrics

Metric Description
x,y
setLocation(x,y)
component coordinates relatively to its parent component
width,height
setSize(w,h)
component size and component size method setter
setBounds(x,y,w,h) component bounds (location and size) setter
getPreferredSize()
setPreferredSize(w,h)
the size the component desires to have plus border and padding gaps. The getter method returns result as "{ width:intValue, height:intValue }" data structure. The "pure" preferred size of a component is calculated by its layout manager. Layout manager implements special "calcPreferredSize(comp)" method that does the calculation. The "pure" preferred size does not include border and padding gaps.
left,right,top,botom,
setPaddings(t,l,r,b)
setPadding(v)
component paddings and appropriate setters to setup the paddings.
getLeft(),getRight()
getTop(),getBottom()
calculated gaps as amount of padding and border sizes.
border.getLeft()
border.getTop()
border.getRight()
border.getBottom()
border gaps

UI component has traditional location and size properties. Also UI component defines metrics that correspond to border decorative element. Developers can define extra paddings between border and component content by calling “setPaddings(top,left,bottom,right)” or “setPadding(p)” methods.

zebra.ready(function() {
   ...
   var l = new Label("Test");
   l.setWidth(200, 300);  // set label size
   l.width;               // access label width that equals 200
   l.height;              // access label height that equals 300
   l.setLocation(20, 20); // set label location relatively to its parent
   l.x; l.y;              // access label location 
   l.setPaddings(2,2,2,2) // set label padding
   l.left; l.right; l.top; l.bottom // paddings
   l.border.getLeft();l.border.getTop();     // border gaps
   l.border.getRight();l.border.getBottom();
   ...
}); 

UI components hierarchy

Zebra UI components are organized as hierarchy where every top level UI component can have 0 to N children UI components. To keep the hierarchy UI component API provides the following methods and fields:

Method or field Description
parent reference to parent component
kids array of children UI components
add(component) add a new children component
add(constraints, component) add a new children component with the given constraint
set(constraints, component) re-set existing children UI component with the given constraints or add new one if there is not a kid with the specified constraints
insert(index, constraints, component) insert a new kid component at the given index and constraints
removeAt(index) remove children component at the given index of "kids" array
remove(comp) remove the given children component
removeAll() remove all children components

The snippet below builds simple UI components hierarchy:

zebra.ready(function(){
    // build Zebra canvas component that adds new
    // Canvas DOM element into page with the given size
    var zCanvas = new zebra.ui.zCanvas(400,300);
    var root    = zCanvas.root; // save reference to root UI component
     
    // build the following UI Components hierarchy:
    //  root
    //   +--zebra.ui.Panel
    //        +-- zebra.ui.Label
    //        +-- zebra.ui.Button
    //        +-- zebra.ui.Panel
    //              +--- zebra.ui.TextField  
    var p = new zebra.ui.Panel(); // create panel
    p.setBounds(10,10, 380, 280); // shape panel
    p.setBackground("yellow");    // set yellow background
    root.add(p);                  // add panel to root
    var l = new zebra.ui.Label("Test Label"); // create label
    l.setBounds(10, 10, 360, 50); // shape label
    p.add(l);                     // add the label as a kid to panel
    var b = new zebra.ui.Button("Test Button"); // create button
    b.setBounds(10, 60, 360, 50); // shape button
    p.add(b);                     // add the button as a kid to panel
    var pp = new zebra.ui.Panel();  // create one more panel
    pp.setBounds(10, 120, 360, 150);// shape panel
    pp.setBackground("orange");     // set orange background
    p.add(pp);                      // add the panel as a kid of panel
    var tf = new zebra.ui.TextField("Test Text Field"); 
    tf.setBounds(10, 10, 200, 30);
    pp.add(tf);
});

You can see below Zebra live application that visualize the snippet:



Layout manager

Every UI component defines a layout manager to layout its children components. Layout manager is special class that:

  • inherits “zebra.layout.Layout” interface
  • Declare “calcPreferredSize(comp)” method to calculate component “pure” preferred size (the size that does not take in account border and padding gaps)
  • Declare “doLayout(comp)” method that knows how to place children components basing on some rules

Layout manager is mandatory. If an UI component has not defined a layout manager a default one is taken. The default layout manager doesn’t have any special rules to order children components. Actually it does nothing, what means component bounds (“x”, “y”, “width”, “height”) have effect.

Component validation

For the sake of performance UI component saves its state to avoid redundant preferred size calculation, repainting and lay outing. The state can be valid or invalid. Developer can check the component state by accessing “isValid” boolean property. The following methods allow developers to control a component state:

  • invalidate() Call to invalidate a component metric and layout.
  • validate() Call to validate a component. Validation initiates the following actions:
    • Calculate component metrics (preferred size) if it is in invalid state. Developer can declare “recalc()” method in a UI component class that will be called every time the component metric has to be re-calculated. It supposed “recalc()” method should calculate some component specific metics that have influence to component preferred size.
    • Lay outing children component if necessary
    • Call “validate()” method for all children component

In most cases developers should not care to much about UI component validation and invalidation. Proper invalidation and validation is implemented in particular UI component basing on its specific implementation. UI Component API methods do validation and invalidation when it is necessary. Just use it as is with no extra thought regarding its internal implementation.