Revision: 4842
          http://sourceforge.net/p/vexi/code/4842
Author:   clrg
Date:     2016-01-25 23:16:57 +0000 (Mon, 25 Jan 2016)
Log Message:
-----------
Porting WIP

Modified Paths:
--------------
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Slider.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Container.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Draggable.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/FocusManager.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Focusable.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Polarized.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/PopupManager.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Popupable.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Repeater.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/SelectContainer.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Selectable.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Subsurface.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Surface.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Settings.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Tooltip.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/body.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/foot.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/head.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/lib/FocusBorder.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/progressbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Button.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/CheckBox.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/util/common.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/util/sync.t

Added Paths:
-----------
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Item.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Link.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/List.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Menu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/MenuItem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/NumberField.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Option.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadePane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadowText.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Spinner.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Submenu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tab.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tabpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ToggleButton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tree.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Aspect.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Cardpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Flow.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Grid.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Ratio.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Contextable.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/Tooltipable.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/table/
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/table/Body.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/table/Cell.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/table/Head.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/table/Row.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/table/Table.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Item.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Link.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/List.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Menu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/MenuItem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/NumberField.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Option.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/ShadePane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Submenu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Tab.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Tabpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/ToggleButton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Toolbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Toolitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/Tree.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/local/
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Item.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Link.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/List.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Menu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/MenuItem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/NumberField.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Option.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/ShadePane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Spinner.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Submenu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Tab.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Tabpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/ToggleButton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Toolbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Toolitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/Tree.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Body.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Cell.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Column.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Foot.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Head.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Row.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/Table.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/Aspect.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/Cardpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/Flow.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/Grid.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/GridLine.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/Icon.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/Ratio.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_poke/poke/gui/Link.t

Removed Paths:
-------------
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/aspect.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/cardpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/flow.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/grid.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/margin.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/pad.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/ratio.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/ContextMenuAgent.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/role/TooltipAgent.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/body.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/cell.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/head.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/item.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/list.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/menu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/menuitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/numfield.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/option.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/row.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadepane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadowtext.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/spin.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/submenu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/tab.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/table.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/tabpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/togglebutton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/toolbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/toolitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/tree.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/item.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/link.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/list.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/menu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/menuitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/numfield.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/option.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/shadepane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/submenu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/tab.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/tabpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/togglebutton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/toolbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/toolitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/theme/classic/tree.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/body.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/cell.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/column.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/foot.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/head.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/row.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/gui/table/table.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/aspect.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/cardpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/flow.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/grid.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/gridproxy.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/icon.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/margin.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/pad.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/layout/ratio.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/item.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/link.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/list.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/menu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/menuitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/numfield.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/option.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/shadepane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/spin.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/submenu.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/tab.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/table/
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/tabpane.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/togglebutton.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/toolbar.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/toolitem.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/vexi/widget/tree.t
    
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_poke/poke/widgets/link.t

Modified: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
   2016-01-09 07:31:17 UTC (rev 4841)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Button.t
   2016-01-25 23:16:57 UTC (rev 4842)
@@ -3,5 +3,5 @@
 <vexi xmlns="org.vexi.lib.role">
     <Clickable />
     <Focusable />
-    <TooltipAgent />
+    <Tooltipable />
 </vexi>

Modified: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
 2016-01-09 07:31:17 UTC (rev 4841)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/CheckBox.t
 2016-01-25 23:16:57 UTC (rev 4842)
@@ -11,7 +11,7 @@
 
     <Clickable />
     <Focusable />
-    <TooltipAgent />
+    <Tooltipable />
     <ui:Box>
         
         thisbox.selected = false;

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Item.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/item.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Item.t
                             (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Item.t
     2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,22 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <Clickable />
+    <Selectable />
+    <Tooltipable>
+        
+        if (arguments.length[0] != null) thisbox.text = arguments[0];
+        if (arguments.length[1] != null) thisbox.value = arguments[1];
+        
+        thisbox.value ++= static.valueRead;
+        
+    </Tooltipable>
+    
+    /** return value or text if no value assigned */
+    static.valueRead = function() { return cascade!=null ? cascade : 
trapee.text; }
+    
+</vexi>

Added: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Link.t
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Link.t
                             (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Link.t
     2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,71 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:meta="vexi://meta" 
+      xmlns="org.vexi.lib.role" >
+
+    <meta:doc>
+        <author>Charles Goodwin</author>
+        <name>Link</name>
+        <todo>Separate hint element as a role</todo>
+    </meta:doc>
+    
+    <Clickable />
+    <Focusable />
+    <Tooltipable>
+        
+        thisbox.v_linkbox;
+        thisbox.v_textbox;
+        
+        thisbox.hint ++= static.hintWrite;
+        thisbox.icon ++= static.iconWrite;
+        thisbox.emblem ++= static.iconWrite;
+        
+    </Tooltipable>
+    
+    static.registerHint = function(v) {
+        cascade = v;
+        var s = trapee.surface;
+        if (s==null) return;
+        if (v) { if (s.registerHint) s.registerHint(trapee); }
+        else { if (s.dropHint) s.dropHint(trapee); }
+    }
+    
+    static.surfaceWrite = function(v) {
+        var s = trapee.surface;
+        if (s and s.dropHint) s.dropHint(trapee);
+        cascade = v;
+        if (v and v.registerHint and trapee.visible)
+            v.registerHint(trapee);
+    }
+    
+    static.hintWrite = function(v) {
+        cascade = v;
+        trapee.v_textbox.hint = v;
+        trapee.surface ++= static.surfaceWrite;
+        trapee.visible ++= static.registerHint;
+    }
+    
+    static.iconWrite = function(v) {
+        if (trapee.v_iconbox==null) {
+            trapee.v_iconbox = new trapee.Icon();
+            trapee[0] = trapee.v_iconbox; 
+        }
+        cascade = v;
+        trapee.v_iconbox.display = v!=null and v!=""; 
+        trapee.v_iconbox[trapname] = v;
+    }
+    
+    static.textWrite = function(v) {
+        var i = v and trapee.hint ? v.toLowerCase().indexOf(trapee.hint) : -1;
+        if (i>=0) {
+            trapee.v_hint[1].width =
+                vexi.ui.font.width(trapee.font, trapee.fontsize, 
trapee.text.substring(i, i+1));
+            trapee.v_hint[1].x =
+                vexi.ui.font.width(trapee.font, trapee.fontsize, 
trapee.text.substring(0, i));
+        } else {
+            trapee.v_hint[1].width = 0;
+        }
+        return;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/List.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/list.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/List.t
                             (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/List.t
     2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,10 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <Focusable />
+    <SelectList />
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Menu.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/menu.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Menu.t
                             (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Menu.t
     2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,172 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.role">
+    
+    <Popupable />
+    <Selectable>
+        
+        thisbox.autogroup = true;
+        thisbox.enabled = true;
+        thisbox.v_content;
+        thisbox.v_itemgroup;
+        
+        /** popdown menu when a menu item is fired */
+        var childActionWrite = function(v) { popdown = true; cascade = v; }
+        
+        /** set up item grouping when widget is ready */
+        thisbox.v_container ++= function(v) {
+            cascade = v;
+            v_content.orient = "vertical";
+            v_content.Children ++= function(c) {
+                if (c != null) {
+                    if (c.v_separator) {
+                        // for separators
+                        c.vshrink = true;
+                    } else if (v_itemgroup) {
+                        // add to existing itemgroup
+                        c.group = v_itemgroup;
+                        v_content.Leave ++= function(l) {
+                            var s = v_itemgroup.selected;
+                            if (s and !s.popped) {
+                                s.selected = false;
+                            }
+                            cascade = l;
+                        }
+                    } else {
+                        // acquire starting itemgroup
+                        v_itemgroup = c.group;
+                    }
+                    c.action ++= childActionWrite;
+                } else {
+                    var _c = v_content[trapname];
+                    if (_c) {
+                        _c.action --= childActionWrite;
+                        _c.group = null;
+                    }
+                }
+                cascade = c;
+            }
+        }
+        
+        // assign static trap functions
+        thisbox.popdown     ++= static.popdownWrite;
+        //thisbox.popup       ++= static.popupWrite;
+        thisbox.selected    ++= static.selectedWrite;
+        thisbox.Enter       ++= static.enterWrite;
+        thisbox.Leave       ++= static.leaveWrite;
+        thisbox.KeyPressed  ++= static.keypressWrite;
+        thisbox.KeyReleased ++= static.keyreleaseWrite;
+        thisbox.Press1      ++= static.pressWrite;
+        
+    </Selectable>
+    
+    /** become active menu on Enter */
+    static.enterWrite = function(v) {
+        var t = trapee;
+        if (t.enabled and !t.selected) {
+            t.selected = true;
+        }
+        cascade = v;
+    }
+    
+    /** become inactive on leave if menu is not open */
+    static.leaveWrite = function(v) {
+        var t = trapee;
+        if (!t.popped) {
+            t.selected = false;
+        }
+        cascade = v;
+    }
+    
+    /** menu navigation via keyboard */
+    static.keypressWrite = function(v) {
+        var t = trapee;
+        var g = t.v_itemgroup;
+        var s = g?.selected;
+        switch (v) {
+        case "escape":
+            // close down menu
+            trapee.popdown = true;
+            break;
+        case "left":
+            // move menu left if appropriate
+            if (g and s and s.popped) {
+                s.KeyPressed = v;
+            } else if (trapee.prevselect) {
+                t.prevselect.selected = true;
+            }
+            break;
+        case "right":
+            // move to next menu to the right, if appropriate
+            if (g and s and s.popupable) {
+                s.KeyPressed = v;
+            } else if (t.nextselect) {
+                t.nextselect.selected = true;
+            }
+            break;
+        default:
+            // pass keypress onto selected menu entry or select a menu entry 
if none is selected
+            if (s) {
+                s.KeyPressed = v;
+            } else if (g?.first and (v=="up" or v=="down")) {
+                g.first.selected = true;
+            }
+            break;
+        }
+        cascade = v;
+    }
+    
+    /** pass key-release on as well */
+    static.keyreleaseWrite = function(v) {
+        var g = trapee.v_itemgroup;
+        if (g and g.selected) {
+            g.selected.KeyReleased = v;
+        }
+        cascade = v;
+    }
+    
+    /** open/close on mouse press */
+    static.pressWrite = function(v) {
+        var t = trapee;
+        if (t.enabled) {
+            if (t.popped) {
+                t.popdown = true;
+            } else {
+                t.popup = true;
+            }
+        }
+        cascade = v;
+    }
+    
+    /** grab key events on popup */
+    static.popupWrite = function(v) {
+        // FIXME: surface._KeyPressed ++=
+        cascade = v;
+    }
+    
+    /** popdown submenus as well */
+    static.popdownWrite = function(v) {
+        var g = trapee.v_itemgroup;
+        if (g and g.selected) {
+            g.selected.selected = false;
+        }
+        // FIXME: surface._KeyPressed --=
+        cascade = v;
+    }
+    
+    /** selected write trap */
+    static.selectedWrite = function(v) {
+        // reduce lookups
+        var t = trapee;
+        var g = t.group;
+        if (v) {
+            if (g and g.selected and g.selected.popped) {
+                t.popup = true;
+            }
+        } else {
+            t.popdown = true;
+        }        
+        cascade = v;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/MenuItem.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/menuitem.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/MenuItem.t
                         (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/MenuItem.t
 2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,57 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.role">
+    
+    <Clickable />
+    <Selectable>
+        
+        thisbox.mnemonic;
+        thisbox.selected;
+        
+        thisbox.icon  ++= static.iconWrite;
+        thisbox.Enter ++= static.enterEvent;
+        thisbox.Leave ++= static.leaveEvent;
+        
+        {
+            var arg = arguments[0];
+            if (arg) {
+                thisbox.v_ready ++= function(v) {
+                    cascade = v;
+                    text = arg.text;
+                    icon = arg.icon;
+                    action ++= arg.action;
+                    if (arg.enabled!=null)
+                        enabled = arg.enabled;
+                }
+            }
+        }
+        
+    </Selectable>
+    
+    /** simply set the icon; expects a stream */
+    static.iconWrite = function(v) {
+        cascade = v;
+        if (trapee.th_icon) {
+            trapee.th_icon.fill = v;
+        }
+    }
+    
+    /** become active menuitem on Enter */
+    static.enterEvent = function(v) {
+        var t = trapee;
+        if (t.enabled and !t.selected) {
+            t.selected = true;
+        }
+        cascade = v;
+    }
+    
+    /** deselect (become inactive) if active */
+    static.leaveEvent = function(v) {
+        var t = trapee;
+        if (t.selected) {
+            t.selected = false;
+        }
+        cascade = v;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/NumberField.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/numfield.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/NumberField.t
                              (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/NumberField.t
      2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,178 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib"
+      xmlns:sync="vexi.util.sync">
+    
+    <role.Focusable />
+    <role.Tooltipable />
+    <text.Field>
+        
+        thisbox.v_edit;    // abstract
+        
+        thisbox.enabled = true;
+        thisbox.updateValueonKeyPressed = true;
+      
+        thisbox.minvalue;
+        thisbox.maxvalue;
+        thisbox.value;     // value and the v_edit.text are synchronized
+        
+        thisbox.scale;     // if positive, number of decimal places
+                           // if negative, number of trailing 0s
+        
+        
+        KeyPressed ++= static.keypressEvent;
+        scale      ++= static.scale;
+        maxvalue   ++= static.limitvalueWrite;
+        minvalue   ++= static.limitvalueWrite;
+        focused    ++= static.focusWrite;
+        value      ++= static.valueWrite;
+        v_edit     ++= static.editWrite;
+        
+        
+        const Number = vexi.js.Number;
+        
+        /** validate a number against the parameters of this numfield */
+        thisbox.validateNumber = function(d) {
+            if (d==null) return null;
+            var d0 = d;
+            
+            if (maxvalue!=null) {
+                if (d > maxvalue) {
+                    d = maxvalue;
+                }
+            }
+            
+            if (minvalue!=null) {
+                if (minvalue > d) {
+                    d = minvalue;
+                }
+            }
+            
+            if (scale!=null) {
+                d = d.round(scale);
+            }
+            return d;
+        }
+        
+        /** convert from a string to a decimal */
+        thisbox.text2decimal = function(v) {
+            var d;
+            try {
+                d = Number.cast(v, "rational");
+            } catch(e) { }
+            if (d!=null) {
+                d = validateNumber(d);
+            }
+            return d;
+        }
+        
+        thisbox.decimal2text= function(d) {
+               if (d==null) return "";
+               return d.toDecimalString(scale);
+           }
+        
+    </text.Field>
+    
+    const Number = vexi.js.Number;
+    
+    
+    
+    /** set up sync between edit.text and numfield.value */
+    static.editWrite = function(v) {
+        cascade = v;
+        sync..syncTransform(trapee, v, "value", "text", trapee.decimal2text, 
trapee.text2decimal);
+        trapee[trapname] --= callee;
+    }
+    
+    /** when focus changes, self put text in case text content is updated */
+    static.focusWrite = function(v) {
+        if (!v and !trapee.updateValueonKeyPressed) {
+            // trigger value setting
+            trapee.v_edit.text = trapee.v_edit.text;
+        }
+        cascade = v;
+    }
+    
+    /** fire action or filter key in case of password fields */
+    static.keypressEvent = function(v) {
+        var t = trapee;
+        var e = t.v_edit;
+        var txt0 = e.text;
+        
+        switch (v) {
+        // Handle '-' specially. Toggles sign.
+        case '-': {
+            var cpos = e.getCursorCharIndex();
+            if (txt0.length==0 or txt0.charAt(0)!='-') {
+                e.text = '-'+txt0;
+                cpos++;
+            } else {
+                e.text = txt0.substring(1);
+                if (cpos!=0) cpos--;
+            }
+            e.setCursorCharIndex(cpos);
+            return;
+        }
+        case "ENTER":
+        case "enter": {
+            var cpos = e.getCursorCharIndex();
+            t.value = t.text2decimal(e.text);
+            cpos = vexi.math.max(e.text.length, cpos);
+            e.setCursorCharIndex(cpos);
+            return;
+        }
+        case ".": {
+            if (t.scale==null || t.scale>0) {
+                   var cpos = e.getCursorCharIndex();
+                   cascade = v;
+                   // If invalid revert ...        
+                   if (e.text.indexOf(".")!=e.text.lastIndexOf(".")) {
+                       e.text = txt0;
+                       e.setCursorCharIndex(cpos);
+                   }
+            }
+            return;
+        }
+        case "C-a": case "C-x": case "C-v":  
+        case "LEFT": case "RIGHT": case "UP": case "DOWN": 
+        case "left": case "right": case "up": case "down": 
+        case "HOME": case "END": 
+        case "home": case "end": 
+        case "BACK_SPACE": case "DELETE":
+        case "back_space": case "delete":
+        
+        case "0": case "1": case "2": case "3": case "4":
+        case "5": case "6": case "7": case "8": case "9": 
+            // Due to possibility of selection, not just editing a single char
+            // let the text widget handle this and correct as necessary
+            cascade = v;
+            
+            if (trapee.updateValueonKeyPressed) {
+                // trigger value setting
+                trapee.v_edit.text = trapee.v_edit.text;
+            }
+        }
+    }
+    
+    /** constrain value to min */
+    static.limitvalueWrite = function(v) {
+        v = Number.cast(v, "rational");
+        cascade = v;
+        // constrain/set validity
+        trapee.value = trapee.value; 
+    }
+    
+    /** constrain value to max */
+    static.scale = function(v) {
+        cascade = v;
+        // constrain/set validity
+        trapee.value = trapee.value; 
+    }
+    
+    /** ensure value is valid */
+    static.valueWrite = function(v) {
+        v = Number.cast(v, "rational");
+        cascade = trapee.validateNumber(v);
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Option.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/option.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Option.t
                           (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Option.t
   2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,288 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.role">
+    
+    <Focusable />
+    <Popupable />
+    <SelectList />
+    <Tooltipable>
+        
+        // public vars
+        thisbox.showvalue = false;
+        thisbox.value;
+        
+        // theme vars
+        thisbox.th_button;
+        thisbox.th_scroll;
+        
+        /** set value if a new item is selected programmatically */ 
+        thisbox.selectWrite = function(v) {
+            cascade = v;
+            if (v and !popped) {
+                value = v.value;
+            }
+        }
+        
+        // make accessible 
+        thisbox.selecteditem ++= static.selecteditemRead;
+        
+        // assign event traps
+        Children   ++= static.childrenWrite;
+        KeyPressed ++= static.keypressEvent;
+        Press1     ++= static.pressEvent;
+        
+        // assign property traps
+        //popup   ++= static.popupWrite;
+        popdown ++= static.popdownWrite;
+        enabled ++= static.enableWrite;
+        value   ++= static.valueWrite;
+        textalign ++= static.textalignWrite;
+        v_listgroup ++= static.listgroupWrite;
+        
+        // assign theme traps
+        th_button ++= static.buttonThemeWrite;
+        v_container ++= static.contentThemeWrite;
+        
+    </Tooltipable>
+    
+    /** pop up or down depending on whether option is open */
+    static.buttonActionWrite = function(v) {
+        var p_opt = trapee.v_option;
+        if (p_opt.enabled) {
+            if (p_opt.popped) {
+                p_opt.popdown = true;
+            } else {
+                p_opt.popup = true;
+            }
+        }
+        cascade = v;
+    }
+    
+    /** initializes popup button */
+    static.buttonThemeWrite = function(v) {
+        v.action ++= static.buttonActionWrite;
+        v.focusable = false;
+        v.v_option = trapee;
+        cascade = v;
+    }
+    
+    /** match item align to option textalign */
+    static.childrenWrite = function(v) {
+        cascade = v;
+        if (v) v.align = trapee.textalign?:trapee.align;
+    }
+    
+    /** applied to list container */
+    static.contentLeaveEvent = function(v) {
+        cascade = v;
+        var g = trapee.v_option.v_listgroup;
+        if (g) {
+            var s = g.selected;
+            if (s and s.selected) {
+                s.selected = false;
+            }
+        }
+    }
+    
+    /** invoke popdown when something is selected */
+    static.contentReleaseEvent = function(v) {
+        cascade = v;
+        trapee.v_option.popdown = true;
+    }
+    
+    /** initialize content list */
+    static.contentThemeWrite = function(v) {
+        cascade = v;
+        // REMARK: use v_popbox instead of v_content to allow
+        // for custom items inserted alongside normal content
+        var vc = trapee.v_content;
+        vc.Leave ++= static.contentLeaveEvent;
+        vc.Release1 ++= static.contentReleaseEvent;
+        vc.v_option = trapee;
+    }
+    
+    /** disabled option must be popped down */
+    static.enableWrite = function(v) {
+        cascade = v;
+        var t = trapee;
+        if (t.v_popbox and t.popped and !v) {
+            t.popdown = true;
+        }
+        if (t.th_button) {
+            t.th_button.enabled = v;
+        }
+    }
+    
+    /** listen to listgroup.selected */
+    static.listgroupWrite = function(v) {
+        var g = trapee.v_listgroup;
+        if (g) {
+            g.selected --= trapee.selectWrite;
+        }
+        cascade = v;
+        if (v) {
+            v.selected ++= trapee.selectWrite;
+        }
+    }
+    
+    /** set value on popdown to selected item */
+    static.popdownWrite = function(v) {
+        var t = trapee;
+        if (t.enabled) { 
+            // REMARK: must do this before cascade as 
+            var s = t.v_listgroup ? t.v_listgroup.selected : null;
+            if (s and s.selected and s!=t.value) {
+                t.value = s.value;
+            }
+        }
+        cascade = v;
+    }
+    
+    /** start with selected item on popup */
+    static.popupWrite = function(v) {
+        cascade = v;
+        var t = trapee;
+        var s = t.v_listgroup ? t.v_listgroup.selected : null;
+        if (t.value and (!s or t.value!=s.value)) {
+            for (var item = vec.first; item!=null; item = vec.after(item)) {
+                if (item.value == t.value) {
+                    item.selected = true;
+                    break;
+                }
+            }
+        }
+    }
+    
+    /** direct access to the selected item */
+    static.selecteditemRead = function() {
+        return trapee.v_listgroup?.selected;
+    }
+    
+    /** cause items to match option textalign */
+    static.textalignWrite = function(v) {
+        trapee.align = v;
+        for (var i,item in trapee) {
+            item.align = v;
+        }
+    }
+    
+    /** set display text on value write */
+    static.valueWrite = function(v) {
+        var t = trapee;
+        var g = t.v_listgroup;
+        var s = g ? g.selected : null;
+        var oldv = t.value;
+        cascade = v;
+        if (oldv != v) {
+            if (v==null) {
+                if (s and s.selected) {
+                    // clear previously selected item
+                    s.selected = false;
+                    s = null;
+                }
+            } else if ((!s or v != s.value) and g != null) {
+                // search for value matches in children
+                var vec = g.members;
+                for (var item = vec.first; item!=null; item = vec.after(item)) 
{
+                    if (item.value == t.value) {
+                        item.selected = true;
+                        if (!t.popped) {
+                            // selection re-invokes this value
+                            // trap, no need to follow through
+                            return;
+                        }
+                        s = item;
+                        break;
+                    }
+                }
+            }
+        }
+        if (s==null and oldv == v) {
+            // value has not changed but missing selected
+            if (v==null) t.text = null;
+            return;
+        }
+        // assign appropriate text content
+        t.text = t.showvalue ? t.value : s ? s.text : t.value;
+    }
+    
+    /** focusable integration */
+    static.keypressEvent = function(v) {
+        var t = trapee;
+        var s = t.v_listgroup ? t.v_listgroup.selected : null;
+        
+        switch (v) {
+        case "down":
+            // select next item on arrow down
+            if (t.popped) {
+                // if open select the next one
+                if (s) {
+                    var n = s.nextselect; 
+                    if (n) {
+                        n.selected = true;
+                    }
+                } else {
+                    t.selectFirst();
+                }
+            } else {   
+                // popup if not already popped
+                t.popup = true;
+            }
+            break;
+        
+        case "up":
+            // behaviour for up arrow
+            if (t.popped) {
+                // select previous item
+                if (s) {
+                    var p = s.prevselect; 
+                    if (p) {
+                        p.selected = true;
+                    }
+                } else {
+                    t.selectLast();
+                }
+            } else {
+                // popup if not already popped
+                t.popup = true;
+            }
+            break;
+        
+        case "enter":
+            // close positively on enter
+            if (t.popped) {
+                t.popdown = true;
+            } else {
+                t.action = true;
+            }
+            break;
+        
+        case "escape":
+            // keep original value
+            if (t.popped) {
+                if (s) {
+                    s.selected = false;
+                }
+                t.popdown = true;
+            }
+            break;
+        
+        case "back_space":
+            // clear value altogether
+            t.popdown = true;
+            t.value = null;
+            t.text = "";
+            break;
+        }
+        cascade = v;
+    }
+    
+    /** fire button action when clicked on */
+    static.pressEvent = function(v) {
+        if (!trapee.th_button.mouse.inside) {
+            trapee.th_button.action = true;
+        }
+        cascade = v;
+    }
+    
+</vexi>

Modified: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
      2016-01-09 07:31:17 UTC (rev 4841)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/RadioButton.t
      2016-01-25 23:16:57 UTC (rev 4842)
@@ -4,5 +4,5 @@
     <Clickable />
     <Selectable />
     <Focusable />
-    <TooltipAgent />
+    <Tooltipable />
 </vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadePane.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadepane.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadePane.t
                                (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadePane.t
        2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,27 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.role">
+    
+    <Focusable />
+    <Tooltipable>
+        
+        thisbox.canclose ++= static.cancloseWrite;
+        thisbox.shade ++= static.shadeWrite;
+        
+        thisbox.th_close ++= function(v) {
+            cascade = v;
+            v.display = false;
+            v.Press1 ++= function(v) { cascade = v; thisbox = null; }
+        }
+        
+        thisbox.th_titlebar ++= function(v) {
+            cascade = v;
+            v.Press1 ++= function(v) { shade = !shade; return; }
+        }
+        
+    </Tooltipable>
+    
+    static.cancloseWrite = function(v) { trapee.th_close.display = v; cascade 
= v; }
+    static.shadeWrite = function(v) { trapee.th_content.display = !v; cascade 
= v; }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadowText.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/shadowtext.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadowText.t
                               (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ShadowText.t
       2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,60 @@
+<!-- Copyright 2010 - see COPYING for details [LGPLv3] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" 
xmlns:rdt="vexi.util.redirect">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+        <usage>
+            Preapply at a theme level and set th_shadowtext/wrap
+        </usage>
+    </meta:doc>
+    
+    <ui:Box>
+        
+        thisbox.shadowtext = "";
+        thisbox.th_shadowtext;
+        thisbox.th_shadowwrap;
+        
+        thisbox.KeyPressed ++= static.keypressWrite;
+        thisbox.shadowtext ++= static.shadowtextWrite;
+        thisbox.v_container ++= static.containerWrite;
+        
+    </ui:Box>
+    
+    static.containerWrite = function(v) {
+        cascade = v;
+        trapee.font ++= static.setOnShadow;
+        trapee.fontsize ++= static.setOnShadow;
+        trapee.v_textbox.text ++= static.textWrite;
+        trapee.v_textbox.v_field = trapee;
+    }
+    
+    static.keypressWrite = function(v) {
+        cascade = v;
+        var sw = trapee.th_shadowwrap;
+        if (sw) {
+            sw.display = trapee.v_edit.text == "";
+        }
+    }
+    
+    static.setOnShadow = function(v) {
+        cascade = v;
+        trapee.th_shadowtext[trapname] = v;
+    }
+    
+    /** sets the text to display when the textfield is empty */
+    static.shadowtextWrite = function(v) {
+        cascade = v;
+        var st = trapee.th_shadowtext;
+        if (st) {
+            st.text = v;
+        }
+    }
+    
+    static.textWrite = function(v) {
+        cascade = v;
+        // only show shadowtext if field is empty
+        var f = trapee.v_field;
+        f.th_shadowwrap.display = (v == "" or v == null);
+    }
+    
+</vexi>

Modified: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Slider.t
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Slider.t
   2016-01-09 07:31:17 UTC (rev 4841)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Slider.t
   2016-01-25 23:16:57 UTC (rev 4842)
@@ -10,7 +10,7 @@
     <Draggable />
     <Focusable />
     <Polarized />
-    <TooltipAgent>
+    <Tooltipable>
         
         // public variables
         thisbox.interval = 1;   // user defined interval between steps
@@ -53,7 +53,7 @@
         value      ++= static.valueWrite;
         th_track   ++= static.trackWrite;
         
-    </TooltipAgent>
+    </Tooltipable>
     
     /** adjust step on keypress */
     static.keypressEvent = function(v) {

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Spinner.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/spin.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Spinner.t
                          (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Spinner.t
  2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,86 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns="org.vexi.lib.gui">
+    
+    <!--
+    NumberField preapplies these
+    <role.Focusable />
+    <role.Tooltipable />
+    <text.Field />
+    -->
+    <NumberField>
+        
+        // public variables
+        thisbox.interval = 1;  // interval by which up/down in/de-crement the 
result
+        
+        // assign static trap functions
+        enabled    ++= static.enableWrite;
+        KeyPressed ++= static.keypressWrite;
+        
+        /** set action on button to decrement */
+        thisbox.th_less ++= function(v) {
+            cascade = v;
+            v.focusable = false;
+            /** action: decrease value by interval if possible */
+            v.action ++= function(a) {
+                var val = value;
+                if (val or val==0) {
+                    value = minvalue==null ? val-interval : 
vexi.math.max(val-interval, minvalue);
+                } else
+                if (minvalue != null) {
+                    value = minvalue;
+                } else
+                if (maxvalue != null) {
+                    value = vexi.math.min(0, maxvalue);
+                } else {
+                    value = 0;
+                }
+                return;
+            }
+        }
+        
+        /** set action on button to increment */
+        th_more ++= function(v) {
+            cascade = v;
+            v.focusable = false;
+            /** action: increase value by interval if possible */
+            v.action ++= function(a) {
+                var val = value;
+                if (val or val==0) {
+                    value = maxvalue==null ? val+interval : 
vexi.math.min(val+interval, maxvalue);
+                } else
+                if (maxvalue != null) {
+                    value = maxvalue;
+                } else
+                if (minvalue != null) {
+                    value = vexi.math.max(0, minvalue);
+                } else {
+                    value = 0;
+                }
+                return;
+            }
+        }
+        
+    </NumberField>
+    
+    /** propogate enabled value */
+    static.enableWrite = function(v) {
+        if (trapee.th_less) trapee.th_less.enabled = v;
+        if (trapee.th_more) trapee.th_more.enabled = v;
+        cascade = v;
+    }
+    
+    /** key control */
+    static.keypressWrite = function(v) {
+        switch(v) {
+        case "down": case "DOWN":
+            trapee.th_less.action = true;
+            break;
+        case "up": case "UP":
+            trapee.th_more.action = true;
+            break;
+        }
+        cascade = v;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Submenu.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/submenu.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Submenu.t
                          (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Submenu.t
  2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,139 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:gui="org.vexi.lib.gui"
+      xmlns="org.vexi.lib.role">
+    
+    <Popupable />
+    <Selectable>
+        
+        thisbox.action;
+        thisbox.enabled = true;
+        thisbox.mnemonic;
+        thisbox.selected = false;
+        thisbox.v_itemgroup = null;
+        thisbox.v_level = 1;
+        
+        /** popdown menu when a menu item is fired */
+        var childActionWrite = function(v) { popdown = true; cascade = v; }
+        
+        /** set up item grouping when widget is ready */
+        thisbox.v_container ++= function(v) {
+            cascade = v;
+            v_content.orient = "vertical";
+            v_content.Children ++= function(c) {
+                if (c != null) {
+                    // for separators
+                    if (c.v_separator) c.vshrink = true;
+                    else if (v_itemgroup) {
+                        c.group = v_itemgroup;
+                        v_content.Leave ++= function(v) {
+                            var s = v_itemgroup.selected;
+                            if (s and !s.popped) {
+                                s.selected = false;
+                            }
+                            cascade = v;
+                        }
+                    } else {
+                        v_itemgroup = c.group;
+                    }
+                    c.action ++= childActionWrite;
+                    c.v_level = v_level+1;
+                } else {
+                    var _c = v_content[trapname];
+                    if (_c) {
+                        _c.action --= childActionWrite;
+                        _c.group = null;
+                    }
+                }
+                cascade = c;
+            }
+        }
+        
+        // assign static trap functions
+        thisbox.v_level     ++= static.v_levelWrite;
+        thisbox.v_popbox    ++= static.popboxWrite;
+        thisbox.icon        ++= gui.MenuItem..iconWrite;
+        thisbox.popdown     ++= static.popdownWrite;
+        thisbox.selected    ++= static.selectWrite;
+        thisbox.Enter       ++= gui.Menu..enterWrite;
+        thisbox.KeyPressed  ++= static.keypressWrite;
+        thisbox.KeyReleased ++= gui.Menu..keyreleaseWrite;
+        
+    </Selectable>
+    
+    /** set popgroup to appropriate subv_level */
+    static.v_levelWrite = function(v) {
+        var t = trapee;
+        var n = t.numchildren;
+        t.v_popbox.popgroup = "submenu_level" + v;
+        for (var i=0; n>i; i++) {
+            t[i].v_level = v+1;
+        }
+        cascade = v;
+    }
+    
+    /** navigate submenu on keypress */
+    static.keypressWrite = function(v) {
+        var t = trapee;
+        var g = g;
+        if (!g or !g.selected) {
+            cascade = v;
+            return;
+        }
+        switch(v) {
+        case "up":
+        case "down":
+            cascade = v;
+            break;
+        case "left":
+            if (g.selected.popped) {
+                g.selected.KeyPressed = v;
+            } else {
+                t.popdown = true;
+            }
+            break;
+        case "right":
+            if (!t.popped) {
+                t.popup = true;
+            } else {
+                g.selected.KeyPressed = v;
+            }
+            break;
+        case "default":
+            g.selected.KeyPressed = v;
+            break;
+        }
+    }
+    
+    /** deselect selected submenu item on popdown */
+    static.popdownWrite = function(v) {
+        var t = trapee;
+        var g = t.v_itemgroup;
+        if (g and g.selected) {
+            g.selected.selected = false;
+        }
+        // action causes parent (sub)menu to popdown
+        if (t.selected) {
+            t.action = true;
+        }
+        // must cascade last as action invokes popup
+        cascade = v;
+    }
+    
+    /** popup/down when selected/unselected */
+    static.selectWrite = function(v) {
+        cascade = v;
+        if (v) {
+            trapee.popup = true;
+        } else {
+            trapee.popdown = true;
+        }
+    }
+    
+    /** set up popbox */
+    static.popboxWrite = function(v) {
+        cascade = v;
+        v.popgroup = "sublevel" + trapee.v_level;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tab.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/tab.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tab.t
                              (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tab.t
      2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,84 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role"
+    xmlns:rdt="vexi.util.redirect">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <Clickable />
+    <Selectable />
+    <Focusable />
+    <Tooltipable />
+    <ui:Box>
+        
+        thisbox.closeable  ++= static.closeableWrite;
+        thisbox.th_close   ++= static.th_closeWrite;
+        thisbox.v_card     ++= static.v_cardWrite;
+        thisbox.KeyPressed ++= static.keypressWrite;
+        thisbox.Press1     ++= static.pressWrite;
+        
+        thisbox.closeTab = function(v) { v_card.thisbox = null; return; }
+        
+    </ui:Box>
+    
+    /** display close button iff closeable */
+    static.closeableWrite = function(v) {
+        cascade = v;
+        trapee.th_closewrap.display = v;
+    }
+    
+    /** assign close action to th_close */
+    static.th_closeWrite = function(v) {
+        cascade = v;
+        v.action ++= trapee.closeTab;
+    }
+    
+    /** assigning card properties and redirects */
+    static.v_cardWrite = function(v) {
+        if (trapee.v_card == v) return;
+        if (trapee.v_card) {
+            rdt..delRedirect(trapee.v_card, "closeable", "enabled", "tooltip");
+        }
+        cascade = v;
+        if (v) {
+            var c = v.closeable;
+            var e = v.enabled;
+            var t = v.tooltip;
+            // if enabled is not defined, default to true
+            trapee.enabled = e==null ? true : e;
+            // only set tooltip/closeable if set on card
+            if (c!=null) trapee.closeable = c;
+            if (t!=null) trapee.tooltip = t;
+            // now properties have been 'set' add redirects for future control
+            rdt..addRedirect(v, trapee, "closeable", "enabled", "tooltip");
+        }
+    }
+    
+    /** keyboard navigation of tabs */
+    static.keypressWrite = function(v) {
+        if (v=="left" || v=="up") {
+            var ps = trapee.prevselect;
+            if (ps) {
+                ps.selected = true;
+                ps.focused = true;
+            }
+        } else if (v=="right" or v=="down") {
+            var ns = trapee.nextselect;
+            if (ns) {
+                ns.selected = true;
+                ns.focused = true;
+            }
+        } else {
+            cascade = v;
+        }
+    }
+    
+    /** only allow tab focus on press */
+    static.pressWrite = function(v) {
+        trapee.focusable = true;
+        cascade = v;
+        trapee.focusable = false;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tabpane.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/tabpane.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tabpane.t
                          (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tabpane.t
  2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,268 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib"
+    xmlns:vec="vexi.util.vector" xmlns:wi="vexi.widget">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+
+    <role.popupable />
+    <layout.cardpane />
+    <ui:box>
+        
+        thisbox.closeable = false;
+        thisbox.hidetabs = false;
+        thisbox.maxtabsize = 0;
+        thisbox.shrinktabs = true;
+        thisbox.displayclose = false;
+        
+        thisbox.tabpolicy;
+        thisbox.taborder = new vec();
+        
+        thisbox.th_add;
+        thisbox.th_head;
+        thisbox.th_headwrap;
+        thisbox.th_tablist;
+        thisbox.v_content;
+        
+        // to be implemented by user
+        thisbox.createTab;
+        
+        var tabgroup = null;
+        
+        /** (un)displays the close buttons */
+        thisbox.closeable ++= function(v) {
+            cascade = v;
+            for (var i,child in v_content) {
+                var c = child.closeable;
+                child.v_tab.closeable = c==null ? v : c;
+            }
+        }
+        
+        /** select tab of shown card */
+        thisbox.show ++= function(v) {
+            var s = show;
+            cascade = v;
+            if (show.display and !show.v_tab.selected) {
+                show.v_tab.selected = true;
+            }
+            taborder.unshift(show);
+        }
+        
+        var updateTabList = function(v) {
+            var hw = th_headwrap.width;
+            // display as many as will fit, recently displayed first
+            var c = taborder.first;
+            for (var cw = createTab?th_add.width:0; c!=null; c = 
taborder.after(c)) {
+                if (c.v_tab.enabled == false) {
+                    c.v_tab.display = false;
+                    continue;
+                }
+                // test whether we have room to display more tabs
+                // cw = current width, hw = headwrap width
+                if (cw > 0 and cw + c.v_tab.width > hw) {
+                    // hide the rest
+                    while (c!=null) {
+                        c.v_tab.display = false;
+                        c.v_tabitem.text = c.tabtext;
+                        c = taborder.after(c);
+                    }
+                    th_tablist.display = true;
+                    return;
+                }
+                c.v_tab.display = true;
+                c.v_tabitem.text = "* "+c.tabtext;
+                cw += c.v_tab.width;
+            }
+            th_tablist.display = false;
+        }
+        
+        var tabListPolicy = function(v) {
+            cascade = v;
+            if (tabpolicy == "list")
+                updateTabList();
+        }
+        
+        var tabScrollPolicy = function(v) {
+            cascade = v;
+            th_next.display = th_head.width>th_headwrap.width;
+            th_prev.display = th_next.display;
+        }
+        
+        thisbox.tabpolicy ++= function(v) {
+            cascade = v;
+            if (!th_headwrap or !th_head) {
+                return;
+            }
+            switch(v) {
+                case "expand":
+                    // disable tablist
+                    if (th_tablist) th_list.display = false;
+                    th_headwrap.width --= tabListPolicy;
+                    show --= tabListPolicy;
+                    // disable scrolling
+                    if (th_next) th_next.display = false;
+                    if (th_prev) th_prev.display = false;
+                    th_headwrap.width --= tabScrollPolicy;
+                    th_head.width --= tabScrollPolicy;
+                    show --= tabScrollPolicy;
+                    v_content.Children --= tabListPolicy;
+                    break;
+                case "scroll":
+                    throw "not implemented";
+                    // disable tablist
+                    if (th_tablist) th_tablist.display = false;
+                    th_headwrap.width --= tabListPolicy;
+                    th_head.width --= tabListPolicy;
+                    show --= tabListPolicy;
+                    // enable scrolling
+                    th_headwrap.width ++= tabScrollPolicy;
+                    th_head.width ++= tabScrollPolicy; 
+                    show ++= tabScrollPolicy;
+                    break;
+                case "list":
+                default:
+                    // disable scrolling
+                    if (th_next) th_next.display = false;
+                    if (th_prev) th_prev.display = false;
+                    th_headwrap.width --= tabScrollPolicy;
+                    th_head.width --= tabScrollPolicy; 
+                    show --= tabListPolicy;
+                    // enable tablist
+                    th_headwrap.width ++= tabListPolicy;
+                    th_head.width ++= tabListPolicy;
+                    show ++= tabListPolicy; 
+                    break;
+            }
+        }
+        
+        /** show tab card when a tab is selected */
+        var tabselectWrite = function(v) {
+            cascade = v;
+            var t = trapee;
+            if (t.selected and !t.v_card.display) {
+                show = t.v_card;
+            }
+        }
+        
+        /** sets up the cardpane content */
+        thisbox.v_container ++= function(v) {
+            cascade = v;
+            // only assign once
+            surface --= callee;
+            if (tabpolicy==null) {
+                // set default policy
+                tabpolicy = "list";
+            }
+            
+            /** assign tabs to new cards */
+            v_content.Children ++= function(c) {
+                if (c) {
+                    var t = c.v_tab;
+                    if (t==null) {
+                        // create the tab if needed
+                        c.v_tab = new wi.tab();
+                        t = c.v_tab;
+                    }
+                    
+                    if (c.closeable == null) {
+                        // go with default closeable setting if not set
+                        t.closeable = closeable;
+                    }
+                    // group assignment
+                    if (!tabgroup) {
+                        tabgroup = t.group;
+                        t.selected = true;
+                    } else {
+                        t.group = tabgroup;
+                    }
+                    // selection
+                    t.v_card = c;
+                    t.selected ++= tabselectWrite;
+                    t.width ++= tabListPolicy;
+                    c.tabtext ++= static.tabtextWrite;
+                    if(c.tabtext!=null){
+                        c.v_tab.text = c.tabtext;
+                    }
+                    // place the tab
+                    taborder.push(c);
+                    th_head[trapname] = t;
+                    // tab overflow policy
+                    if (!c.v_tabitem) {
+                        var i = new wi.item();
+                        if(c.tabtext!=null)
+                            i.text = c.tabtext;
+                        i.value = c;
+                        c.v_tabitem = i;
+                        th_tablist.add(i);
+                    }
+                } else {
+                    // clean up tabs
+                    var _c = v_content[trapname];
+                    if (_c) {
+                        const t = _c.v_tab; 
+                        t.selected --= tabselectWrite;
+                        t.width --= tabListPolicy;
+                        t.thisbox = null;
+                        t.group = null;
+                        _c.v_tabitem.thisbox = null;
+                        taborder.remove(_c);                                   
                 
+                    }
+                    var nextc = taborder.first;
+                    if (nextc) show = nextc;
+                    
+                }
+                cascade = c;
+            }
+        }
+        
+        /** select a tab from the tablist option */
+        var tablistShow = function(v) {
+            cascade = v;
+            if (v and v!=show) {
+                show = v;
+            }
+        }
+        
+        thisbox.th_tablist ++= function(v) {
+            cascade = v;
+            if (v) {
+                v.discover();
+                v.value ++= tablistShow;
+            }
+        }
+        
+        thisbox.createTab ++= function(v) {
+            cascade = v;
+            if (th_add) {
+                th_add.display = v!=null;
+            }
+        }
+        
+        thisbox.th_add ++= function(v) {
+            cascade = v;
+            v.action ++= function(v) {
+                if (createTab) {
+                    var newtab = createTab();
+                    thisbox.add(newtab);
+                    thisbox.show = newtab;
+                }
+                return;
+            }
+        }
+        
+        thisbox.th_next ++= function(v) {
+            cascade = v;
+            v.action ++= function(v) { return; }
+        }
+        
+        thisbox.th_prev ++= function(v) {
+            cascade = v;
+            v.action ++= function(v) { return; }
+        }
+        
+    </ui:box>
+    
+    static.tabtextWrite = function(v) { trapee.v_tab.text = v; cascade = v; }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ToggleButton.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/togglebutton.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ToggleButton.t
                             (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/ToggleButton.t
     2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,24 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+      xmlns="org.vexi.lib">
+    
+    <gui.Button />
+    <role.Selectable />
+    <ui:Box>
+        
+        thisbox.Press1 ++= static.pressEvent;
+        thisbox.action ++= static.actionWrite;
+        
+    </ui:Box>
+    
+    /** override selectable action implementation */
+    static.actionWrite = function(v) { return; }
+        
+    /** select if in a group otherwise defer to clickable Press1 */
+    static.pressEvent = function(v) {
+        if (trapee.v_group) trapee.selected = true;
+        else cascade = v;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolbar.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/toolbar.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolbar.t
                          (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolbar.t
  2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,54 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <focusable />
+    <ui:box>
+        
+        var cgroup;
+        
+        thisbox.vshrink = true;
+        
+        /** set appropriate size constraint */
+        thisbox.orient ++= function(v) {
+            cascade = v;
+            var vs = (v == "horizontal");
+            vshrink = vs;
+            hshrink = !vs;
+        }
+        
+        thisbox.v_container ++= function(v) {
+            cascade = v;
+            v_content.Children ++= function(c) {
+                if (c == null) {
+                    v_content[trapname].group = null;
+                } else {
+                    // autogroup together toolbar entries
+                    if (c.autogroup) {
+                        if (trapname!=v_content.numchildren) {
+                            if (trapname>0 and 
!v_content[trapname-1].v_separator)
+                                cgroup = v_content[trapname-1].group;
+                            else if (v[trapname] and !v[trapname].v_separator)
+                                cgroup = v_content[trapname].group;
+                            else cgroup = null;
+                        }
+                        if (cgroup) c.group = cgroup;
+                        else cgroup = c.group;
+                    }
+                    // separators break tool groups
+                    if (c.v_separator) {
+                        // set opposite shrinks
+                        c.hshrink = vshrink;
+                        c.vshrink = hshrink;
+                        if (cgroup) cgroup = null;
+                    }
+                }
+                cascade = c;
+            }
+        }
+        
+    </ui:box>
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolitem.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/toolitem.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolitem.t
                         (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Toolitem.t
 2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,13 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <role.tooltipable />
+    <widget.button />
+    <ui:box>
+        thisbox.autogroup = false;
+    </ui:box>
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tree.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/widget/tree.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tree.t
                             (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/gui/Tree.t
     2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,212 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="org.vexi.lib.role">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <Focusable />
+    <Selectable />
+    <Tooltipable />
+    <ui:Box>
+        
+        thisbox.th_expand;
+        thisbox.th_handle;
+        thisbox.th_image;
+        thisbox.th_node;
+        thisbox.th_title;
+        
+        thisbox.v_iconinit = false;
+        thisbox.v_is_tree = true;
+        
+        thisbox.enabled = true;
+        thisbox.expanded = true;
+        thisbox.iconfill;
+        thisbox.icontemplate;
+        
+        /** used for closing / expanding the tree */
+        thisbox.v_flipDisplay = function(v) { expanded = !th_expand.display; 
cascade = v; }
+        
+        /** select when we mouse press on the node */
+        thisbox.v_nodePress = function(v) { if (enabled) selected = true; 
cascade = v; }
+        
+        var insertAfter = function(node) {
+            if (!node.v_is_tree) {
+                return null;
+            }
+            for (var i=node.numchildren-1; i>=0; i--) {
+                var t = insertAfter(node[i]);
+                if (t) {
+                    return t;
+                }
+            }
+            return node;
+        }
+        
+        thisbox.v_childrenWrite = function(c) {
+            if (c and c.v_is_tree) {
+                c.parent = thisbox;
+                if (!v_group) {
+                    // we have no group
+                    if (c.v_group) {
+                        // add to child group
+                        v_group = c.v_group;
+                        v_group.members.unshift(thisbox);
+                    } else {
+                        // start a new group
+                        c.group = group;
+                    }
+                } else {
+                    // we have a group - insert or merge into this
+                    var insafter = null;
+                    if (!numchildren) {
+                        // no children, insert after thisbox
+                        insafter = thisbox;
+                    } else {
+                        // try the box under the current placement
+                        insafter = v_content[trapname];
+                        if (insafter) {
+                            insafter = v_group.members.before(insafter);
+                        }
+                    }
+                    if (!insafter) {
+                        // need to find last node (nodes may be trees)
+                        insafter = insertAfter(thisbox);
+                    }
+                    if (c.v_group) {
+                        // merge groups
+                        if (c.v_group!=v_group) {
+                            v_group.merge(c.v_group, insafter);
+                        } else {
+                            throw "tree re-arranging not yet directly 
supported";
+                        }
+                    } else {
+                        // c has no group - insert it
+                        c.v_group = v_group;
+                        v_group.members.insert(c, insafter);
+                    }
+                }
+            }
+            var r = trapee[trapname];
+            if (c == null and r != null) {
+                // remove from this tree
+                if (r.v_is_tree) {
+                    // FIXME: split groups
+                }
+            }
+            cascade = c;
+            th_handle.display = (v_content.numchildren > 0);
+        }
+        
+        thisbox.expanded   ++= static.expandRead;
+        thisbox.expanded   ++= static.expandWrite;
+        thisbox.iconfill   ++= static.iconWrite;
+        thisbox.icontemplate ++= static.iconWrite;
+        thisbox.nextselect ++= static.nextselectRead;
+        thisbox.prevselect ++= static.prevselectRead;
+        thisbox.th_handle  ++= static.handleWrite;
+        thisbox.th_node    ++= static.nodeWrite;
+        thisbox.th_title   ++= static.titleWrite;
+        thisbox.visible    ++= static.visibleWrite;
+        thisbox.v_container ++= static.containerWrite;
+        thisbox.v_iconinit ++= static.iconinitWrite;
+        thisbox.KeyPressed ++= static.keypressEvent;
+        
+    </ui:Box>
+    
+    static.iconWrite = function(v) {
+        cascade = v;
+        if (trapee.visible) trapee.v_iconinit = true;
+    }
+    
+    static.iconinitWrite = function(v) {
+        var t = trapee;
+        var icon = t.th_icon;
+        if (t.icontemplate) {
+            icon.fill = null;
+            if (icon[0]) {
+                icon[0] = null;
+            }
+            icon[0] = t.icontemplate(vexi.box);
+        } else {
+            icon.fill = t.iconfill;
+            if (icon[0]) {
+                icon[0] = null;
+            }
+        }
+        cascade = v;
+    }
+    
+    static.visibleWrite = function(v) {
+        cascade = v;
+        if (v) {
+            trapee.v_iconinit = true;
+            trapee.visible --= callee;
+        }
+    }
+    
+    static.expandRead = function() { return trapee.th_expand.display; }
+    static.expandWrite = function(v) {
+        var t = trapee;
+        t.th_expand.display = v;
+        if (!v) {
+            var g = t.v_group;
+            if (g and g.selected and !g.selected.visible) {
+                t.selected = true;
+            }
+        }
+        return;
+    }
+    
+    static.nextselectRead = function() {
+        var t = trapee;
+        var c = cascade;
+        if (t.v_group.members.first == c) {
+            return t;
+        }
+        return c;
+    }
+    
+    static.prevselectRead = function() {
+        var t = trapee;
+        if (t.v_group.members.first == t) {
+            return t;
+        }
+        return cascade;
+    }
+    
+    static.containerWrite = function(v) {
+        cascade = v;
+        trapee.Children ++= trapee.v_childrenWrite;
+    }
+        
+    static.handleWrite = function(v) {
+        cascade = v;
+        v.Press1 ++= trapee.v_flipDisplay;
+    }
+    
+    /** override action write trap in selectable */
+    static.nodeWrite = function(n) {
+        cascade = n;
+        n.Press1 ++= trapee.v_nodePress;
+    }
+    
+    static.titleWrite = function(v) {
+        cascade = v;
+        v.DoubleClick1 ++= trapee.v_flipDisplay;
+    }
+    
+    static.keypressEvent = function(v) {
+        var t = trapee;
+        if (v == "left") {
+            t.th_expand.display = false;
+        } else if (v == "right") {
+            if (t.numchildren) {
+                t.th_expand.display = true;
+            }
+        } else {
+            cascade = v;
+        }
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Aspect.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/aspect.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Aspect.t
                                (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Aspect.t
        2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,44 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns:util="vexi.util">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <ui:box redirect=":$content">
+        <ui:box id="content" />
+        
+        thisbox.aspectwidth = 1;
+        thisbox.aspectheight = 1;
+        
+        thisbox.v_aspect = $content;
+        thisbox.v_content = $content;
+        thisbox.v_fillbox = $content;
+        thisbox.v_textbox = $content;
+        
+        thisbox.width ++= static.updateAspect;
+        thisbox.height ++= static.updateAspect;
+        thisbox.aspectwidth ++= static.updateAspect;
+        thisbox.aspectheight ++= static.updateAspect;
+        
+    </ui:box>
+    
+    /* maintain aspect after a width/height update */
+    static.updateAspect = function(v) {
+        cascade = v;
+        var aw = trapee.aspectwidth;
+        var ah = trapee.aspectheight;
+        var w = trapee.width / aw;
+        var h = trapee.height / ah;
+        if (h>w) {
+            // use width as limiting dimension
+            trapee.v_aspect.maxwidth = trapee.width;
+            trapee.v_aspect.maxheight = w * ah;
+        } else {
+            // use height as limiting dimension
+            trapee.v_aspect.maxwidth = h * aw;
+            trapee.v_aspect.maxheight = trapee.height;
+        }
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Cardpane.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/cardpane.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Cardpane.t
                              (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Cardpane.t
      2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,242 @@
+<!-- Copyright 2009 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+        <todo>
+            * make cardpane aware of 'enabled' cards
+        </todo>
+    </meta:doc>
+    
+    <ui:box>
+        
+        // public interface
+        
+        thisbox.nextcard;
+        thisbox.nextstep;
+        thisbox.prevcard;
+        thisbox.prevstep;
+        thisbox.show;
+        thisbox.remembersteps = false;
+        
+        // pseudo private variables
+        
+        thisbox.stepmarker = 0;
+        thisbox.stepping = false;
+        thisbox.steps = [];
+        thisbox.v_content = thisbox;
+        
+        var showlock = false;
+        
+        var displayFunc = function(v) {
+            if (showlock) {
+                cascade = v;
+                return;
+            }
+            cascade = false;
+            if (prevstep) {
+                show = prevstep;
+            } else if (prevcard) {
+                show = prevcard;
+            } else if (nextstep) {
+                show = nextstep;
+            } else if (nextcard) {
+                show = nextcard;
+            }
+        }
+        
+        /** card management */
+        thisbox.v_container ++= function(v) {
+            cascade = v;
+            // only assign once
+            surface --= callee;
+            
+            /** card management */
+            v_content.Children ++= function(c) {
+                if (c != null) {
+                    // wrap in try clause in case of exception
+                    // so we maintain only 1 card be on display
+                    try { cascade = c; }
+                    catch(e) { throw e; }
+                    finally {
+                        // show c if it is the only card
+                        if (v_content.numchildren > 1) {
+                            c.display = false;
+                        } else {
+                            show = c;
+                        }
+                    }
+                    c.display ++= displayFunc;
+                    return;
+                }
+                
+                c = v_content[arguments.trapname];
+                // if c is the shown card, attempt to show another
+                if (show == c) {
+                    if (nextcard) {
+                        nextcard = true;
+                    } else if (prevcard) {
+                        prevcard = true;
+                    }
+                }
+                
+                // clean up steps[]
+                var newsteps = [];
+                for (var i=0, j=-1; steps.length>i; i++) {
+                    if (steps[i] != c) {
+                        newsteps[j++] = steps[i];
+                    }
+                }
+                
+                // clean up traps and finish
+                c.display --= displayFunc;
+                cascade = null;
+            }
+        }
+        
+        /** write trap to show a card by box or index */
+        show ++= function(v) {
+            var card;
+            
+            // display nothing and reset stepping
+            if (v == null) {
+                showlock = true;
+                if (show) {
+                    show.display = false;
+                }
+                showlock = false;
+                stepmarker = 0;
+                stepping = false;
+                steps = [];
+                cascade = v;
+                return;
+            }
+            
+            // validate show by index
+            if (typeof(v) == "number") {
+                if (v >= v_content.numchildren) {
+                    throw "Invalid card index put to cardpane.show: "+v;
+                }
+                card = v_content[v];
+            // validate show by card
+            } else if (typeof(v) == "box") {
+                if (0 > v_content.indexof(v)) {
+                    throw "Invalid card object put to cardpane.show: "+v;
+                }
+                card = v;
+            } else {
+                throw "Put a value other than a box or box index to 
cardpane.show";
+            }
+            
+            // nothing to do
+            if (card == show) {
+                return;
+            }
+            
+            // hide the previously shown card and show the new one
+            showlock = true;
+            if (show) {
+                show.display = false;
+            }
+            card.display = true;
+            showlock = false;
+            
+            // remember where we are
+            if (remembersteps and !stepping) {
+                stepmarker ++;
+                if (stepmarker != steps.length) {
+                    steps.splice(stepmarker, steps.length - stepmarker);
+                }
+                if (stepmarker > 100) {
+                    steps.splice(0);
+                }
+                steps[stepmarker] = card;
+            }
+            
+            // remember the card, not the trap value
+            cascade = card;
+        }
+        
+        // assign static trap functions
+        nextcard ++= static.ncWriteFunc;
+        nextcard ++= static.ncReadFunc;
+        nextstep ++= static.nsWriteFunc;
+        nextstep ++= static.nsReadFunc;
+        prevcard ++= static.pcWriteFunc;
+        prevcard ++= static.pcReadFunc;
+        prevstep ++= static.psWriteFunc;
+        prevstep ++= static.psReadFunc;
+        
+    </ui:box>
+    
+    /** write trap to show the next card in the cardpane */
+    static.ncWriteFunc = function(v) {
+        if (trapee.nextcard) {
+            trapee.show = trapee.nextcard;
+        }
+        cascade = v;
+    }
+    
+    /** read trap to fetch the next card in the cardpane */
+    static.ncReadFunc = function() {
+        var ind = trapee.v_content.indexof(trapee.show);
+        if (trapee.show and trapee.v_content.numchildren-1 > ind) {
+            return trapee.v_content[ind+1];
+        }
+        return null;
+    }
+    
+    /** write trap to step forward to the next in the show-chain */
+    static.nsWriteFunc = function(v) {
+        trapee.stepping = true;
+        if (trapee.nextstep) {
+            trapee.show = trapee.nextstep;
+        }
+        trapee.stepping = false;
+        cascade = v;
+    }
+    
+    /** read trap to fetch the next step in the show-chain */
+    static.nsReadFunc = function() {
+        if (trapee.remembersteps and trapee.steps.length-1 > 
trapee.stepmarker) {
+            return trapee.steps[trapee.stepmarker+1];
+        }
+        return false;
+    }
+    
+    /** write trap to show the previous card in the cardpane */
+    static.pcWriteFunc = function(v) {
+        cascade = v;
+        if (trapee.prevcard) {
+            trapee.show = trapee.prevcard;
+        }
+    }
+    
+    /** read trap to fetch the previous card in the cardpane */
+    static.pcReadFunc = function() {
+        var ind = trapee.v_content.indexof(trapee.show);
+        if (trapee.show and ind > 0) {
+            return trapee.v_content[ind-1];
+        }
+        return false;
+    }
+    
+    /** write trap to step back to the previous in the show-chain */
+    static.psWriteFunc = function(v) {
+        trapee.stepping = true;
+        if (trapee.prevstep) {
+            trapee.show = trapee.prevstep;
+        }
+        trapee.stepping = false;
+        cascade = v;
+    }
+    
+    /** read trap to fetch the previous step in the show-chain */
+    static.psReadFunc = function() {
+        if (trapee.remembersteps and trapee.stepmarker > 0) {
+            return trapee.steps[trapee.stepmarker - 1];
+        }
+        return false;
+    }
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Flow.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/flow.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Flow.t
                          (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Flow.t
  2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,114 @@
+<!-- Copyright 2015 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+      xmlns:meta="vexi://meta"
+      xmlns="org.vexi.lib.role">
+    
+    <!--polarizable /-->
+    <ui:box layout="place" align="topleft">
+        
+        var _x;
+        var _y;
+        var _width;
+        var _height;
+    
+        var dirty;
+        var entered = false;
+        
+        const reflowTrap = function(v) {
+            if (v != trapee[trapname]) {
+                cascade = v;
+                reflow();
+            }
+        };
+        
+        const max = vexi.math.max;
+        const doReflow = function() {
+            if (entered) {
+                dirty = true;
+                return;
+            }
+            entered = true;
+            try {
+                if (!visible) {
+                    return;
+                } else {
+                    dirty = false;
+                }
+                
+                var rankSize = 0;
+                var offsetRank = 0;
+                var offset = 0;
+                for (var i, b in thisbox) {
+                    var offset0 = offset;
+                    var offsetRank1 = offsetRank; 
+                    var offset1 = offset+b[_width];
+                    if (offset1>thisbox[_width] and i!=0) {
+                        offsetRank1 += rankSize;
+                        offset0 = 0;
+                        offset1 = b[_width];
+                        rankSize = 0;
+                    }
+                    
+                    rankSize = max(rankSize, b[_height]);
+                    
+                    b[_x] = offset0;
+                    b[_y] = offsetRank1;
+//                  trace(i+" ("+b.x+","+b.y+") ("+b.width+","+b.height+")");
+                    offset = offset1;     
+                    offsetRank = offsetRank1;            
+                    
+                    b[_width]  ++= reflowTrap;
+                    b[_height] ++= reflowTrap;
+                }
+                thisbox[_height] = offsetRank + rankSize;
+//              // HACK 
+//              if (offsetRank==0 and offset==0) {
+//                  dirty = true;
+//              }
+            } finally {
+                entered = false;
+            }
+        };
+        
+        Resize ++= function(v) {
+            doReflow();
+        }
+        
+        
+        
+        thisbox.orient ++= function(v){
+            cascade = v;
+            if ("horizontal"==v) {
+                _x = "x";
+                _y = "y";
+                _width = "width";
+                _height = "height";
+            } else {
+                _x = "y";
+                _y = "x";
+                _height = "width";
+                _width = "height";
+            }
+        };
+        
+        orient = "horizontal";
+        
+        thisbox.width  ++= reflowTrap;
+        thisbox.height ++= reflowTrap;
+        
+        thisbox.Children ++= function(v) {
+            cascade = v;
+            if (v == null) {
+                const v0 = thisbox[trapname];
+                if (v0) {
+                       v0[_width]  --= reflowTrap;
+                       v0[_height] --= reflowTrap;
+                   }
+            }
+            reflow();
+        };
+        
+    </ui:box>
+    
+</vexi>

Copied: 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Grid.t
 (from rev 4785, 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/grid.t)
===================================================================
--- 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Grid.t
                          (rev 0)
+++ 
branches/vexi3_integrated_layout/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/Grid.t
  2016-01-25 23:16:57 UTC (rev 4842)
@@ -0,0 +1,670 @@
+<!-- Copyright 2013 - see COPYING for details [LGPL] -->
+
+<vexi xmlns:ui="vexi://ui"
+      xmlns:lang="vexi://lang"
+      xmlns:js="vexi://js"
+      xmlns="vexi.util">
+
+    <ui:box layout="layer">
+        <!-- no redirect; it is managed by a Children trap -->
+        <ui:box id="content" align="topleft" layout="place" />
+        
+        <lang:subtemplate property="Regions">
+            <js:Object>
+                
+                /** A region is represented primarily by 2 facets
+                 *  - the origin i.e. box.col
+                 *  - the frontier it affects i.e. box.col+box.colspan
+                 * 
+                 *  As multiple boxes may affect the same region, it is
+                 *  convenient to group them together with the region
+                 */
+                const newRegion = function(box, origin, frontier) {
+                    return { boxes:[box], origin:origin, frontier:frontier };
+                }
+                
+                thisobj.list = new vexi.js.ProxyList();
+                
+                thisobj.add = function(box, origin, frontier) {
+                    for (var i=list.length; i>0; i--) {
+                        const region = list[i-1];
+                        if (region.frontier > frontier) continue;
+                        if (frontier == region.frontier) {
+                            if (region.origin > origin)
+                                continue;
+                            if (region.origin == origin) {
+                                region.boxes.push(box);
+                                return;
+                            }
+                        }
+                        // same frontier, new region
+                        list[i] = newRegion(box, origin, frontier);
+                        return;
+                    }
+                    // reached the end (or beginning)
+                    list[0] = newRegion(box, origin, frontier);
+                };
+                
+            </js:Object>
+        </lang:subtemplate>
+        
+        /********************************
+         ******** INTERNAL LOGIC ********
+         ********************************/
+        
+        var numcols = 0; // these two vars
+        var numrows = 0; // are calcualated
+        
+        var setsize = 1;    // these two vars represent
+        var userows = true; // the user-specified break
+        
+        var pack_children = false;
+        var place_horizontal = false;
+        var place_vertical = false;
+        
+        const min = function(a, b) { return a > b ? b : a; }
+        const max = function(a, b) { return a > b ? a : b; }
+        const round = vexi.math.round;
+        
+        // container object for regions,frontiers,etc
+        const byCol = {};
+        const byRow = {};
+        
+        /* PLACING
+         *
+         * The effect of each child is measured against the region it
+         * occupies - the row/column boundary it is pushing.  If this
+         * region changes then boxes in subsequent regions shift over.
+         *
+         * Note 1: (case solve2)
+         * There is a corner case where a spanning box occupies the
+         * end of an axis, pushing the next box into a region which
+         * has an origin with no matching frontier; so use origin-1.
+         */
+        
+        const placeRegions = function(axis, fullreach, gridsize, shrink, 
contentdim, mindim, maxdim, dim, pos) {
+            const regions = axis.regions;
+            const frontiers = axis.frontiers;
+            const f2i = axis.frontier2index;
+            
+            // PHASE 1: honor min/max sizes for boxes in order of region
+            var contentMin = 0;
+            var contentMax = 0;
+            const frontierMin = {};
+            const frontierMax = {};
+            for (var i,region in regions.list) {
+                var minsize = 0;
+                var maxsize = 0;
+                for (var j,box in region.boxes) {
+                    const c = box[0];
+                    minsize = max(c[contentdim], minsize);
+                    maxsize = max((c[shrink] ? c[contentdim] : c[maxdim]), 
maxsize);
+                }
+                region.minsize = minsize;
+                region.maxsize = maxsize;
+                
+                const origin = region.origin;
+                const frontier = region.frontier;
+                // see place note (1)
+                var priorMin = origin>0 ? frontierMin[origin] : 0;
+                if (priorMin == null)
+                    priorMin = frontierMin[origin-1];
+                var priorMax = origin>0 ? frontierMax[origin] : 0;
+                if (priorMax == null)
+                    priorMax = frontierMax[origin-1];
+                const currentMin = frontierMin[frontier];
+                const currentMax = frontierMax[frontier];
+                
+                if (currentMin == null or priorMin + minsize > currentMin) {
+                    contentMin = max(priorMin + minsize, contentMin);
+                    frontierMin[frontier] = priorMin + minsize;
+                }
+                if (currentMax == null or priorMax + maxsize > currentMax) {
+                    if (contentMax != vexi.ui.maxdim) {
+                        contentMax = min(vexi.ui.maxdim, max(priorMax + 
maxsize, contentMax));
+                        frontierMax[frontier] = priorMax + maxsize;
+                    } else {
+                        frontierMax[frontier] = min(vexi.ui.maxdim, priorMax + 
maxsize);
+                    }
+                }
+            }
+            // by now we know our minimum/maximum size
+            $content[mindim] = contentMin;
+            $content[maxdim] = contentMax;
+            
+            // PHASE 2: place wrapper boxes in accordance with region/frontier 
min/max sizes
+            if (thisbox[shrink] or contentMin >= gridsize) {
+                // honor min sizes
+                for (var i,region in regions.list) {
+                    const origin = region.origin;
+                    // see place note (1)
+                    var regionPos = origin>0 ? frontierMin[origin] : 0;
+                    if (regionPos == null)
+                        regionPos = frontierMin[origin-1]; 
+                    const regionDim = frontierMin[region.frontier] - regionPos;
+                    for (var j,box in region.boxes) {
+                        box[pos] = regionPos;
+                        box[dim] = regionDim;
+                    }
+                }
+            } else
+            if (gridsize >= contentMax) {
+                // honor max sizes
+                for (var i,region in regions.list) {
+                    const origin = region.origin;
+                    // see place note (1)
+                    var regionPos = origin>0 ? frontierMax[origin] : 0;
+                    if (regionPos == null)
+                        regionPos = frontierMax[origin-1];
+                    const regionDim = frontierMax[region.frontier] - regionPos;
+                    for (var j,box in region.boxes) {
+                        box[pos] = regionPos;
+                        box[dim] = regionDim;
+                    }
+                }
+            } else {
+                // solving required; guess at a workable target col/row size,
+                // test it and adjust it up/down until it tests successfully 
+                var targetSize = gridsize / fullreach;
+                
+                // these exist outside of the loop as their
+                // contents get fully overwritten each pass
+                const frontierMin = [];
+                const frontierMax = [];
+                const frontierDim = {};
+                // this is constant
+                frontierDim[0] = 0;
+                // need this after solving
+                var lastFrontier;
+                
+                // limit solving loop to 100 iterations
+                for (var i=0; 100>i; i++) {
+                    lastFrontier = 0;
+                    for (var i,region in regions.list) {
+                        const frontier = region.frontier;
+                        const f_index = f2i[frontier];
+                        const origin = region.origin;
+                        const reach = frontier-origin;
+                        const minsize = region.minsize;
+                        const maxsize = region.maxsize;
+                        var target;
+                        
+                        if (frontier!=lastFrontier) {
+                            // reset frontierMin/Max
+                            frontierMin[f_index] = false;
+                            frontierMax[f_index] = false;
+                        }
+                        
+                        if (minsize == maxsize) {
+                            // region size fixed
+                            target = minsize;
+                        } else {
+                            target = targetSize * reach;
+                            // see place note (1)
+                            var o_index = f2i[origin];
+                            if (o_index == null)
+                                o_index = f2i[origin-1];
+                            
+                            if (target > minsize)
+                                for (var i=f_index; i>o_index; i--)
+                                    frontierMin[i] = true;
+                            else target = minsize;
+                            
+                            if (maxsize > target)
+                                for (var i=f_index; i>o_index; i--)
+                                    frontierMax[i] = true;
+                            else target = maxsize;
+                        }
+                        
+                        var originDim = frontierDim[origin];
+                        // see place note (1)
+                        if (originDim == null)
+                            originDim = frontierDim[origin-1];
+                        const frontierPush = originDim + target;
+                        if (frontier!=lastFrontier or frontierPush > 
frontierDim[frontier])
+                            frontierDim[frontier] = frontierPush;
+                        lastFrontier = frontier;
+                    }
+                    
+                    const totalSize = frontierDim[lastFrontier];
+                    if (0.5 > totalSize-gridsize and totalSize-gridsize >= 
-0.5) {
+                        // break if we were close to the target
+                        break;
+                    }
+                    
+                    // not at the target size, adjust accordingly
+                    if (totalSize > gridsize) {
+                        // too big; adjust down
+                        var reachDown = 0;
+                        for (var i,notMin in frontierMin) {
+                            if (!notMin) continue;
+                            reachDown += frontiers[i]-(i==0?0:frontiers[i-1]);
+                        }
+                        if (reachDown == 0) {
+                            // no rows to be further decreased in size
+                            //throw "Should not be possible";
+                            // FIXME: except it actually does in practise
+                            break;
+                        }
+                        var ts = targetSize;
+                        // else adjust targetRowSize according to target-total 
deficit
+                        targetSize -= ((totalSize-gridsize) / reachDown);
+                        
+                    } else {
+                        // too small; adjust up
+                        var reachUp = 0;
+                        for (var i,notMax in frontierMax) {
+                            if (!notMax) continue;
+                            reachUp += frontiers[i]-(i==0?0:frontiers[i-1]);
+                        }
+                        if (reachUp == 0) {
+                            // no rows to be further increased in size
+                            //throw "Should not be possible";
+                            // FIXME: except it actually does in practise
+                            break;
+                        }
+                        var ts = targetSize;
+                        // adjust targetRowSize according to target-total 
deficit
+                        targetSize += ((gridsize-totalSize) / reachUp);
+                    }
+                    
+                    if (i>=99) {
+                        // infinite loop prevention
+                        vexi.log.warn("failed to solve grid "+dim+" 
"+thisbox[dim]+" with rows/cols:"+fullreach);
+                    }
+                }
+                
+                // just to be sure we don't miss the edge of the grid
+                frontierDim[lastFrontier] = gridsize;
+                
+                // place our boxes
+                for (var i,region in regions.list) {
+                    const origin = region.origin;
+                    // see place note (1)
+                    var regionPos = frontierDim[origin];
+                    if (regionPos == null)
+                        regionPos = frontierDim[origin-1];
+                    const roundPos = round(regionPos);
+                    const roundDim = round(frontierDim[region.frontier]) - 
roundPos;
+                    try {
+                           for (var j,box in region.boxes) {
+                               box[pos] = roundPos;
+                               box[dim] = roundDim;
+                           }
+                       } catch (e) {
+                           trace("Error assigning "+pos+", "+dim+" to 
"+origin+": "+roundPos+", "+roundDim);
+                           trace(frontierDim);
+                           trace(e);
+                       }
+                }
+            }
+        }
+        
+        const place = function() {
+            if (!numcols or !numrows) {
+                // not yet initialized
+                return;
+            }
+            if (place_horizontal) {
+                placeRegions(byCol, numcols, width, "hshrink", "contentwidth", 
"minwidth", "maxwidth", "width", "x");
+                place_horizontal = false;
+            }
+            if (place_vertical) {
+                placeRegions(byRow, numrows, height, "vshrink", 
"contentheight", "minheight", "maxheight", "height", "y");
+                place_vertical = false;
+            }
+        }
+        
+        /* PACKING
+         *
+         * Here we pack the child boxes as close together as their row-
+         * and col-span will allow. The packing approach is determined
+         * by which grid property is the set - if 'rows' then pack the
+         * children down the number of rows and accomodate children by
+         * adding extra columns, and vice versa for 'cols'.
+         */
+        
+        /** establish an ordered list of frontiers for placing */
+        const establishFrontier = function(frontiers, frontier) {
+            for (var i = frontiers.length-1; i>=0; --i) {
+                var f = frontiers[i];
+                if (f == frontier)
+                    return;
+                if (f > frontier)
+                    continue;
+                frontiers.splice(i+1, 0, frontier);
+                return;
+            }
+            frontiers.unshift(frontier);
+        }
+        
+        /** assign child c to the pack slot specific by col,row */
+        const assignSlot = function(c, col, row) {
+            const c0 = c[0];
+            c0.v_col = col;
+            c0.v_row = row;
+            const colfrontier = userows ? col+c0.colspan : min(cols, 
col+c0.colspan);
+            const rowfrontier = userows ? min(rows, row+c0.rowspan) : 
row+c0.rowspan;
+            // update the number of in-use rows/cols
+            numcols = max(numcols, colfrontier);
+            numrows = max(numrows, rowfrontier);
+            // establish a list of frontier/from-col pairs
+            // which can be iterated over for solving
+            byCol.regions.add(c, col, colfrontier);
+            byRow.regions.add(c, row, rowfrontier);
+            establishFrontier(byCol.frontiers, colfrontier);
+            establishFrontier(byRow.frontiers, rowfrontier);
+        }
+        
+        /** pack by primary axis (e.g. column) first, expanding secondary axis 
(e.g. rows) as required */
+        const packAxis = function(mainAxis, mainSpan, v_mainAxis, growAxis, 
growSpan, v_growAxis) {
+            const frontier = new vexi.js.ProxyList();
+            var nextMain = 0;  // the next available col
+            var nextGrow = 0;  // the next available row
+            var minFront = 0;  // the minimum row past a frontier box
+            
+            // assign col/row values to packed children
+            for (var i,c in $content) {
+                const c0 = c[0];
+                
+                if (!c0.display) {
+                    // disregard hidden children
+                    c.display = false;
+                    continue;
+                } else {
+                    c.display = true;
+                }
+                
+                if ((nextMain!=0) and (nextMain+c0[mainSpan] > setsize)) {
+                    // if we don't fit on the row, jump to the next
+                    nextMain=0;
+                    nextGrow++;
+                }
+                
+                // check to see if we are making a full pass at the row
+                const fullpass = nextMain==0;
+                
+                // work through frontier boxes until a suitable position is 
found
+                PACKME: while (frontier.length>0) {
+                    var fKey = 0;
+                    var f0 = frontier[fKey];
+                    while (f0 != null) {
+                        if (nextGrow >= f0[v_growAxis]+f0[growSpan]) {
+                            // reduce frontier by removing boxes not affecting 
the frontier row
+                            frontier[fKey] = null;
+                            f0 = frontier[fKey];
+                            continue;
+                        }
+                        if ((f0[v_mainAxis] + f0[mainSpan] > nextMain) and
+                                (nextMain + c0[mainSpan] > f0[v_mainAxis])) {
+                            // frontier not accomodating current child, look 
further
+                            
+                            // establish next available col
+                            nextMain = f0[v_mainAxis] + f0[mainSpan];
+                            // establish next available row
+                            minFront = (minFront == 0) ? f0[v_growAxis] + 
f0[growSpan]
+                                : min(minFront, f0[v_growAxis] + f0[growSpan]);
+                            
+                            if (nextMain + c0[mainSpan] > setsize) {
+                                // c will not fit on nextsec
+                                if (!fullpass) {
+                                    // if not a full pass, try next immediate 
row
+                                    nextGrow++;
+                                    nextMain = 0;
+                                    minFront = 0;
+                                } else {
+                                    // try c on next available row
+                                    nextMain = 0;
+                                    nextGrow = minFront;
+                                    minFront = 0;
+                                }
+                                // try frontier again
+                                continue PACKME;
+                            }
+                        } else if (f0[v_mainAxis] >= nextMain + c0[mainSpan]) {
+                            // fit between previous frontier and this frontier
+                            break PACKME;
+                        }
+                        // next frontier
+                        f0 = frontier[++fKey];
+                    }
+                    if (setsize >= nextMain + c0[mainSpan]) {
+                        // fits in the col after frontier
+                        break;
+                    }
+                }
+                if (c0[growSpan] > 1) {
+                    // add to frontier if we affect the frontier
+                    if (f0) {
+                        frontier[fKey] = c0;
+                    } else {
+                        frontier[frontier.length] = c0;
+                    }
+                }
+                // place packed child
+                assignSlot(c, nextMain, nextGrow);
+                // prepare for next iteration
+                minFront = 0;             // reset minFront

@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to