Revision: 3154
          http://vexi.svn.sourceforge.net/vexi/?rev=3154&view=rev
Author:   clrg
Date:     2008-10-30 01:02:50 +0000 (Thu, 30 Oct 2008)

Log Message:
-----------
Share project "org.vexi.guide" into 
"https://vexi.svn.sourceforge.net/svnroot/vexi/trunk/widgets";

Added Paths:
-----------
    trunk/widgets/org.vexi.guide/.project
    trunk/widgets/org.vexi.guide/.vexipath
    trunk/widgets/org.vexi.guide/src/
    trunk/widgets/org.vexi.guide/src/main.t
    trunk/widgets/org.vexi.guide/src/org/
    trunk/widgets/org.vexi.guide/src/org/vexi/
    trunk/widgets/org.vexi.guide/src/org/vexi/guide/
    trunk/widgets/org.vexi.guide/src/org/vexi/guide/board.t
    trunk/widgets/org.vexi.guide/src/org/vexi/guide/main.t
    trunk/widgets/org.vexi.guide/src/org/vexi/guide/uiobject.t
    trunk/widgets/org.vexi.guide/src/org/vexi/guide/uioverlay.t
    trunk/widgets/org.vexi.guide/src/org/vexi/ve/

Added: trunk/widgets/org.vexi.guide/.project
===================================================================
--- trunk/widgets/org.vexi.guide/.project                               (rev 0)
+++ trunk/widgets/org.vexi.guide/.project       2008-10-30 01:02:50 UTC (rev 
3154)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.vexi.guide</name>
+       <comment></comment>
+       <projects>
+               <project>org.vexi.vunit</project>
+               <project>org.vexi.widgets</project>
+               <project>vexi.font</project>
+       </projects>
+       <buildSpec>
+       </buildSpec>
+       <natures>
+               <nature>org.vexi.vexidev.vexiNature</nature>
+       </natures>
+</projectDescription>


Property changes on: trunk/widgets/org.vexi.guide/.project
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/widgets/org.vexi.guide/.vexipath
===================================================================
--- trunk/widgets/org.vexi.guide/.vexipath                              (rev 0)
+++ trunk/widgets/org.vexi.guide/.vexipath      2008-10-30 01:02:50 UTC (rev 
3154)
@@ -0,0 +1,6 @@
+{
+  "source" : [
+    "F/org.vexi.guide/src"
+  ],
+  "projects" : [ ]
+}
\ No newline at end of file

Added: trunk/widgets/org.vexi.guide/src/main.t
===================================================================
--- trunk/widgets/org.vexi.guide/src/main.t                             (rev 0)
+++ trunk/widgets/org.vexi.guide/src/main.t     2008-10-30 01:02:50 UTC (rev 
3154)
@@ -0,0 +1,3 @@
+<vexi xmlns:ui="vexi://ui" xmlns="">
+     <org.vexi.guide.main />
+</vexi>

Added: trunk/widgets/org.vexi.guide/src/org/vexi/guide/board.t
===================================================================
--- trunk/widgets/org.vexi.guide/src/org/vexi/guide/board.t                     
        (rev 0)
+++ trunk/widgets/org.vexi.guide/src/org/vexi/guide/board.t     2008-10-30 
01:02:50 UTC (rev 3154)
@@ -0,0 +1,315 @@
+<!-- Copyright 2008 -- all rights reserved -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi.widget"
+    xmlns:lay="vexi.layout"
+    xmlns:role="org.vexi.lib.role"
+    xmlns:util="vexi.util"
+    xmlns:g="org.vexi.guide">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+        <name>GUIDE board for editing Vexi UIs</name>
+    </meta:doc>
+    
+    <role:focusable />
+    <bevel form="down" redirect=":$canvas">
+        <scrollpane autohide="true">
+            <ui:box fill="darkgray" width="20" />
+            <ui:box orient="vertical">
+                <ui:box fill="darkgray" height="20" />
+                <lay:border border="black" depth="1" layout="layer">
+                    <ui:box id="canvas" />
+                    <ui:box id="select" layout="place" />
+                </lay:border>
+                <ui:box fill="darkgray" height="20" />
+            </ui:box>
+            <ui:box fill="darkgray" width="20" />
+        </scrollpane>
+        <ui:box id="nodice" display="false" />
+        
+        // efficient reference to surface.insert
+        var insert;
+        
+        thisbox.enabled = true;
+        thisbox.selected = null;
+        thisbox.viewactual ++= function(v) { cascade = v; $canvas.viewactual = 
v; }
+        
+        thisbox.active;
+        thisbox.insertinto;
+        
+        ////////
+        // sync in background thread
+        
+        var scheduled = false;
+        var scheduleResync = function() {
+            if (scheduled) return;
+            scheduled = true;
+            vexi.thread = function() {
+                $select[0].resync();
+                scheduled = false;
+            }
+        }
+        thisbox.resync = scheduleResync;
+        
+        ////////
+        // uiobject insertion logic
+        
+        var trackInsert = function(v) {
+            cascade = v;
+            if (!insertinto or !insert) return;
+            if (!insertinto.uiwidget.redirect) return;
+            var o = insert.object;
+            var n = insertinto.overlay.numchildren;
+            // no children, place directly at 0 index
+            if (n==0) { insertinto[0] = o; return; }
+            // single child that is already insert object
+            if (n==1 and insertinto[0] == o) return;
+            // begin placing heuristics
+            var h = insertinto.uiwidget.orient == "horizontal";
+            var pos = h ? 'x' : 'y';
+            var dim = h ? 'width' : 'height';
+            // use the overlay when assessing; actual objects are most
+            // probably altered in size by the insert object by now
+            var mpos = insertinto.overlay.mouse[pos];
+            var ioff = 0;
+            for (var i=0; n>i; i++) {
+                // don't count insert.object when assessing insertion position
+                if (insertinto[i] == insert.object) { ioff++; continue; }
+                // use the overlay when assessing; actual objects are most
+                // probably altered in size by the insert object by now
+                var d = insertinto.overlay.distanceto(insertinto[i].overlay);
+                if (d[pos]+10>=mpos) {
+                    insertinto[i-ioff] = insert.object;
+                    return;
+                }
+            }
+            insertinto[n] = insert.object;
+        }
+        
+        var placeInsert = function(v) {
+            surface.insert = null;
+            trapee[trapname] --= callee;
+            return;
+        }
+        
+        thisbox.active ++= function(v) {
+            if (active) active.active = false;
+            cascade = v;
+            if (active) active.active = true;
+        }
+        
+        thisbox.insertinto ++= function(v) {
+            var i = insertinto;
+            cascade = v;
+            if (!v and i and insert) {
+                var ind = i.indexof(insert.object);
+                if (ind>=0) i[ind] = null;
+            }
+        }
+        
+        var surfaceInsertWrite = function(v) {
+            cascade = v;
+            if (v == insert) return;
+            if (v) {
+                $select.cursor = "hand";
+                $select.Leave ++= trackInsert;
+                $select._Move ++= trackInsert;
+                $select._Press1 ++= placeInsert;
+                $select._Release1 ++= placeInsert;
+                v.object.insert = true;
+            }
+            var i = insert;
+            insert = v;
+            if (i and !insert) {
+                $select.cursor = null;
+                $select.Leave --= trackInsert;
+                $select._Move --= trackInsert;
+                $select._Press1 --= placeInsert;
+                $select._Release1 --= placeInsert;
+                i.object.insert = false;
+                if (i.callback) i.callback();
+                if (i.object.visible) {
+                    i.object.overlay.display = true;
+                    i.object.active = false;
+                    selected = i.object;
+                } else {
+                    if (i.object.overlay)
+                        i.object.overlay.thisbox = null;
+                    i.object.thisbox = null;
+                }
+                scheduleResync();
+            }
+        }
+        
+        surface ++= function(v) {
+            cascade = v;
+            if (surface) surface.insert ++= surfaceInsertWrite;
+        }
+        
+        ////////
+        // normal selection logic
+        
+        var selectreq = null;
+        
+        /** assigned to uiobject._Press1 to request selection */
+        var pressWrite = function(v) {
+            cascade = v;
+            if (!insert) selectreq = trapee;
+        }
+        
+        /** set selected state on selected uiobject */
+        thisbox.selected ++= function(v) {
+            if (v == selected) return;
+            if (selected) selected.selected = false;
+            cascade = v;
+            if (selected) selected.selected = true;
+        }
+        
+        var dragObject = function(v) {
+            cascade = v;
+            if (!enabled) return;
+            trapee.display = false;
+            trapee.object.display = false;
+            $canvas.forcereflow();
+            var i = { object: trapee.object };
+            surface.insert = i;
+            trapee.Leave --= callee;
+            trapee.object.display = true;
+        }
+        
+        var selectObject = function(v) {
+            cascade = v;
+            if (selectreq == trapee) selected = trapee.object;
+            trapee.Leave --= dragObject;
+            trapee.Release1 --= callee;
+        }
+        
+        /** handles final selection and insertion */
+        $select.Press1 ++= function(v) {
+            cascade = v;
+            if (selectreq) {
+                selectreq.Leave ++= dragObject;
+                selectreq.Release1 ++= selectObject;
+            }
+            focused = true;
+        }
+        
+        /** deselect if clicking on the background */
+        Press1 ++= function(v) {
+            if (insert) surface.insert = null;
+            else selected = null;
+            return;
+        }
+        
+        ////////
+        // determine the active object (i.e. under the mouse)
+        
+        var activestack = util.vector(vexi.box);
+        
+        var activateWrite = function(v) {
+            if (v) activestack.push(trapee.object);
+            else activestack.remove(trapee.object);
+            active = activestack.last;
+            return;
+        }
+        
+        ////////
+        // determine the insertion parent (i.e. inside under the mouse)
+        
+        var insertstack = util.vector(vexi.box);
+        
+        var insertintoWrite = function(v) {
+            if (v) insertstack.push(trapee.object);
+            else insertstack.remove(trapee.object);
+            insertinto = insertstack.last;
+            return;
+        }
+        
+        var insertmodeRead = function() { return insert!=null; }
+        
+        /////////
+        // general canvas tree handling
+        
+        /** used to recursively assign the viewactual property */
+        var viewactualWrite = function(v) {
+            cascade = v;
+            var n = trapee.numchildren;
+            for (var i=0; n>i; i++) trapee[i].viewactual = v;
+        }
+        
+        // need to declare this here for reference in the below
+        // children trap, which setupOverlay also references
+        var setupOverlay = function() { };
+        
+        /** self applying Children trap - applied to all descendents */
+        var childrenWrite = function(v) {
+            if (v) {
+                setupOverlay(trapee, v, trapname);
+            } else {
+                var _v = trapee[trapname];
+                if (_v) trapee.overlay[trapname] = null;
+            }
+            cascade = v;
+        }
+        
+        setupOverlay = function(parent, child, index) {
+            child.Children ++= childrenWrite;
+            child.viewactual ++= viewactualWrite;
+            var s = child.overlay;
+            if (!s) {
+                s = g.uioverlay(vexi.box);
+                s._Press1 ++= pressWrite;
+                s.activate ++= activateWrite;
+                if (child.uiwidget.redirect) {
+                    s.insertinto ++= insertintoWrite;
+                    s.insertmode ++= insertmodeRead;
+                }
+                s.object = child;
+                child.overlay = s;
+            }
+            // do not yet display overlay for the insert object
+            s.display = insert == null or insert.object != child;
+            parent.overlay[index] = s;
+            // in case we've added a new tree of uiobjects
+            var n = child.numchildren;
+            for (var i=0; n>i; i++) {
+                if (child[i].uiwidget and !child[i].overlay)
+                    callee(child, child[i], i);
+            }
+        }
+        
+        thisbox.viewactual ++= function(v) { cascade = v; 
$canvas[0].viewactual = v; }
+        
+        /** initialise the canvas, optionally with object o */
+        thisbox.initialize = function(o) {
+            $canvas.Children ++= childrenWrite;
+            $canvas.overlay = $select;
+            if (arguments.length==0 or !o)
+                o = g.insert.item..components["vexi://ui.box"].getObject();
+            $canvas[0] = o;
+            $canvas.uiwidget = $canvas;
+        }
+        
+        KeyPressed ++= function(v) {
+            cascade = v;
+            switch (v) {
+            // remove selected object, protecting canvas[0]
+            case "delete":
+                if (selected and selected != $canvas[0]) {
+                    selected.overlay.thisbox = null;
+                    selected.thisbox = null;
+                    selected = null;
+                }
+                break;
+            // cancel an insert request, otherwise deselect
+            case "escape":
+                if (insert) surface.insert = null;
+                else selected = null;
+                break;
+            }
+        }
+        
+    </bevel>
+    
+    static.blockEvent = function(v) { return; }
+    
+</vexi>
\ No newline at end of file

Added: trunk/widgets/org.vexi.guide/src/org/vexi/guide/main.t
===================================================================
--- trunk/widgets/org.vexi.guide/src/org/vexi/guide/main.t                      
        (rev 0)
+++ trunk/widgets/org.vexi.guide/src/org/vexi/guide/main.t      2008-10-30 
01:02:50 UTC (rev 3154)
@@ -0,0 +1,237 @@
+<!-- Copyright 2008 -- all rights reserved -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi.widget"
+    xmlns:i16="vexi.icon.i16">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+    </meta:doc>
+    
+    <surface />
+    <ui:box orient="vertical" framewidth="750" frameheight="600">
+        <toolbar>
+            <menu text="Form">
+                <menuitem id="menu_save" text="Save" enabled="false" 
icon=":i16.filesave" />
+                <separator vshrink="true" />
+                <menuitem id="menu_delete" text="Delete" icon=":i16.trashcan" 
/>
+                <separator vshrink="true" />
+                <menuitem text="Quit" icon=":i16.exit">
+                    thisbox.action ++= function(v) { surface.Close = true; 
return; }
+                </menuitem>
+            </menu>
+            <menu text="Edit">
+                <menuitem text="Undo" enabled="false" icon=":i16.redo" />
+                <menuitem text="Redo" enabled="false" icon=":i16.undo" />
+                <separator vshrink="true" />
+                <menuitem text="Preferences" enabled="false" 
icon=":i16.configure" />
+            </menu>
+            <ui:box />
+            <ui:box fill=":i16.emanate5" shrink="true" />
+            <ui:box width="5" />
+            <ui:box text="Emanate5 UI Designer" shrink="true" />
+            <ui:box width="5" />
+        </toolbar>
+        <ui:box height="5" />
+        <webit:feedback layout="layer">
+            <toolbar align="topleft" form="null">
+                <separator hshrink="true" />
+                <webit:toolitem id="selectmode" icon="select" text="Select" />
+                <webit:toolitem id="saveform" icon="filesave" text="Save" />
+                <separator hshrink="true" />
+                <ui:box text=" Create: " shrink="true" />
+                <webit:toolitem id="autoform" enabled="false" 
icon="frame_spreadsheet" text="Auto-Populate" />
+                <webit:toolitem id="autolabel" enabled="false" 
icon="frame_text" text="Auto-Label" />
+                <ui:box />
+            </toolbar>
+            <tabpane>
+                th_head.align = "right";
+                <webit:card id="viewlayout" tabicon="frame_edit" tabtext="Edit 
Layout">
+                    <splitpane>
+                        <splitpane hshrink="true" orient="vertical" 
minwidth="250">
+                            <tabpane>
+                                <guide:insert.pane id="insert" />
+                                <guide:field.pane id="fields" />
+                            </tabpane>
+                            <tabpane>
+                                // note: propset must come becore propadd
+                                // as they interact using the surface obj
+                                // for which propset sets some properties
+                                <guide:propset.pane id="propset" />
+                                <guide:propadd.pane id="propadd" />
+                            </tabpane>
+                        </splitpane>
+                        <ui:box id="holdlayout">
+                            <guide:board id="board" />
+                        </ui:box>
+                    </splitpane>
+                </webit:card>
+                <webit:card id="viewactual" tabicon="display" tabtext="View 
Actual" />
+                <guide:script.pane id="script" />
+            </tabpane>
+        </webit:feedback>
+        
+        $propadd.propgroups = $propset.propgroups;
+        
+        /** the form to save to */
+        thisbox.form = arguments[0];
+        thisbox.saveForm = arguments[1];
+        
+        ////////
+        // insert request
+        
+        /** maintain the state of the insert requesting objects */
+        surface.insertreq ++= function(v) {
+            if (surface.insertreq) surface.insertreq.selected = false;
+            cascade = v;
+            if (surface.insertreq) surface.insertreq.selected = true;
+        }
+        
+        /** insert request for select mode */
+        $selectmode.Press1 ++= function(v) { surface.insertreq = $selectmode; 
cascade = v; }
+        
+        // initialize
+        surface.insertreq = $selectmode;
+        
+        ////////
+        // inter-operation for guide panes
+        
+        /** assign the requested view strategy */
+        $viewactual.display ++= function(v) {
+            cascade = v;
+            if (v) {
+                $viewactual[0] = $board;
+                $board.viewactual = true;
+            }
+        }
+        
+        /** assign the requested view strategy */
+        $viewlayout.display ++= function(v) {
+            cascade = v;
+            if (v) {
+                $holdlayout[0] = $board;
+                $board.viewactual = false;
+            }
+        }
+        
+        /** assign active ui object to properties view */
+        $board.selected ++= function(v) {
+            cascade = v;
+            surface.current = v;
+            $propset.current = v;
+            $propadd.current = v;
+        }
+        
+        /** insert object and board interaction */
+        surface.insert ++= function(v) { cascade = v; if (!v) 
surface.insertreq = $selectmode; }
+        
+        /** pass insertion request onto the board */
+        $board.Enter ++= function(v) { cascade = v; surface.insert = 
$insert.getInsertObject(); }
+        
+        ////////
+        // form loading
+        
+        { // constructor
+            var init;
+            var sobj;
+            if (form != null) {
+                titlebar = "Editing '"+form.name+"'";
+                var formobjs = form.json ? form.json : null;
+                if (typeof(formobjs)=="string") {
+                    // FIXME: wrap in try/catch
+                    formobjs = vexi.js.eval("return "+form.json+";");
+                }
+                if (formobjs) {
+                    init = guide.uiobject..unserialize(formobjs.design);
+                    sobj = formobjs.script;
+                }
+                $fields.form = form;
+                
+            }
+            $script.scriptobj = sobj ? sobj : [];
+            $board.initialize(init);
+            
+            if (form != null) {
+                $autoform.enabled = true;
+                $autoform.action ++= function(v) {
+                    var af = $fields.getForm();
+                    if (af == null) return;
+                    var fp = $board.selected ? $board.selected : $board[0];
+                    if (fp == null) throw "Invalid target for autoform";
+                    if (fp.uiwidget.forcepack)
+                        while (af.numchildren) fp[fp.numchildren] = af[0];
+                    else fp[0] = af;
+                    $board.resync();
+                }
+                
+                $autoform.enabled = true;
+                $saveform.action ++= function(v) {
+                    try {
+                        var json = {
+                            design: $board[0].serialize(),
+                            script: $script.scriptobj
+                        };
+                        form.json = vexi.js.stringify(json);
+                    } catch (e) {
+                        vexi.log.info(e);
+                        surface.showFeedback({
+                            title:"System Removal Failure",
+                            label:"There was a problem removing the system:\n" 
+ e.message,
+                            icon:"error"});
+                    }
+                    saveForm(form);
+                    return;
+                }
+            }
+            
+            vexi.ui.frame = thisbox;
+            // work around asynchronous frame sizing issues
+            vexi.thread = function(v) {
+                surface.RefreshScripts = true;
+                surface.RefreshScriptIds = true;
+            }
+        }; // end constructor
+        
+        ////////
+        // delete form dialog
+        
+        <ui:box id="delform" display="false" orient="vertical" title="Remove 
Form">
+            <label text="Are you sure you want to remove this form?" />
+            <separator vshrink="true" />
+            <ui:box>
+                <webit:link id="delform_cancel" text="Go back" icon="back" />
+                <webit:link id="delform_remove" text="Remove" icon="form" 
emblem="delete" />
+            </ui:box>
+        </ui:box>
+        
+        /** request user confirmation for relation removal */
+        $menu_delete.action ++= function(v) {
+            $delform_name.text = form.name;
+            $delform_remove.enabled = true;
+            surface.showDialog($delform);
+            return;
+        }
+        
+        /** "as you were!" */
+        $delform_cancel.action ++= function(v) { 
surface.closeDialog($delform); return; }
+        
+        // used to remove a form from the server and clean up
+        var delform = function() { getServerObj("Client").removeForm(form.id); 
}
+        
+        var delform_end = function() {
+            global.form[form.id] = null;
+            (keysof(global.form)).remove(form.id);
+            surface.closeDialog($delform);
+        }
+        
+        var delform_fail = function(err) {
+            $delform_remove.enabled = false;
+            $delform_label.text = "There was a problem deleting 
'"+form.name+"':"+err;
+        }
+        
+        /** delete a relation from the server */
+        $delform_remove.action ++= function(v) {
+            background({ call:delform, end:delform_end, fail:delform_fail });
+            return;
+        }
+        
+    </ui:box>
+</vexi>
\ No newline at end of file

Added: trunk/widgets/org.vexi.guide/src/org/vexi/guide/uiobject.t
===================================================================
--- trunk/widgets/org.vexi.guide/src/org/vexi/guide/uiobject.t                  
        (rev 0)
+++ trunk/widgets/org.vexi.guide/src/org/vexi/guide/uiobject.t  2008-10-30 
01:02:50 UTC (rev 3154)
@@ -0,0 +1,205 @@
+<!-- Copyright 2008 -- all rights reserved -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi.layout"
+    xmlns:guide="org.vexi.guide"
+    xmlns:role="org.vexi.lib.role">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+        <name>UI Object</name>
+        <desc>For placing on a GUIDE canvas</desc>
+        <usage>
+            This widget expects exactly 1 child - another widget, the
+            widget the user is placing on the canvas.  After the first
+            child write, all subsequent child writes are redirected to
+            the child which in effect assumes the role of the redirect.
+        </usage>
+    </meta:doc>
+    
+    <ui:box redirect=":$content" layout="layer">
+        <margin id="content" layout="layer" margin="5" />
+        <border id="border1" depth="1"><border id="border2" depth="1" 
/></border>
+        
+        thisbox.parent;
+        thisbox.overlay;
+        thisbox.uiwidget;
+        thisbox.viewactual;
+        
+        thisbox.scripts = { "[body]":"" };
+        thisbox.template;
+        thisbox.namespace;
+        thisbox.propgroups = [];
+        thisbox.properties = {};
+        
+        // functions for a complete redirect from $content->inner
+        var innerRead = function() { return uiwidget[trapname]; }
+        var innerWrite = function(v) { uiwidget[trapname] = v; return; }
+        var syncOverlay = function(v) { overlay.resync(); cascade = v; }
+        
+        /** first time a child is added, make it redirect target 'inner' */
+        thisbox.Children ++= function(v) {
+            cascade = v;
+            if (v) {
+                uiwidget = v;
+                v.wrapper = thisbox;
+                v.focusable = false;
+                v.layoutupdate ++= syncOverlay;
+                thisbox.distanceto ++= innerRead;
+                if (v.redirect) {
+                    thisbox.indexof ++= innerRead;
+                    thisbox.numchildren ++= innerRead;
+                    thisbox.Children ++= innerRead;
+                    thisbox.Children ++= innerWrite;
+                }
+                thisbox.Children --= callee;
+                // set like-for-like properties
+                align = v.align;
+                hshrink = v.hshrink;
+                vshrink = v.vshrink;
+                maxwidth = vexi.math.min(vexi.ui.maxdim-10, v.maxwidth)+10;
+                maxheight = vexi.math.min(vexi.ui.maxdim-10, v.maxheight)+10;
+            }
+        }
+        
+        thisbox.setProperty = function(p, v) {
+            if (!uiwidget) throw "called setProperty when uiwidget is null";
+            if (p==null) throw "called setProperty with null property";
+            switch(p) {
+            case "x":
+            case "y":
+                vexi.log.warn("setting coordinates currently not supported");
+                return;
+            case "align":
+            case "shrink":
+            case "vshrink":
+            case "hshrink":
+            case "colspan":
+            case "rowspan":
+                thisbox[p] = v;
+            default:
+                uiwidget[p] = v;
+                properties[p] = v;
+                return;
+            }
+        }
+        
+        ////////
+        // handle JSON representation
+        
+        /** serialize into objects for storage using JSON */
+        thisbox.serialize = function() {
+            if (!uiwidget) throw "cannot serialize an empty uiobject";
+            var o = {};
+            var c = [];
+            var n = uiwidget.numchildren;
+            for (var i=0; n>i; i++) {
+                var u = uiwidget[i];
+                if (!u.serialize) {
+                    vexi.trace("skipping: "+u.namespace+": "+u.template);
+                    continue;
+                }
+                vexi.trace("serializing: "+i+", "+u.namespace+": "+u.template);
+                c[c.length] = u.serialize();
+            }
+            o.children = c;
+            o.fieldinfo = fieldinfo;
+            o.properties = properties;
+            o.namespace = namespace;
+            o.template = template;
+            return o;
+        }
+        
+        ////////
+        // sets an appropriate border effect according to edit state of the ui 
object
+        
+        thisbox.active;
+        thisbox.insert;
+        thisbox.normal;
+        thisbox.selected;
+        
+        var inner = { normal: "#aaaaaa", active:"red", insert: "green", 
selected: "blue" };
+        var outer = { normal: "#666666", active:"darkred", insert: 
"darkgreen", selected: "darkblue" };
+        
+        var setborder = function(v) {
+            cascade = v;
+            if (viewactual) {
+                $border1.border = null;
+                $border2.border = null;
+            } else {
+                var state;
+                if (active) state = "active";
+                else if (insert) state = "insert";
+                else if (selected) state = "selected";
+                else state = "normal";
+                $border1.border = inner[state];
+                $border2.border = outer[state];
+            }
+        }
+        
+        active ++= setborder;
+        insert ++= setborder;
+        normal ++= setborder;
+        selected ++= setborder;
+        
+        viewactual ++= function(v) {
+            cascade = v;
+            if (v) {
+                $content.margin = 0;
+                maxwidth = uiwidget.maxwidth;
+                maxheight = uiwidget.maxheight;
+            } else {
+                $content.margin = 5;
+                maxwidth = vexi.math.min(vexi.ui.maxdim-10, 
uiwidget.maxwidth)+10;
+                maxheight = vexi.math.min(vexi.ui.maxdim-10, 
uiwidget.maxheight)+10;
+            }
+            normal = true;
+        }
+        
+        normal = true;
+        
+        var surf;
+        var surfaceWrite = function(v) {
+            if (surf and fieldinfo and surf.unregisterField)
+                surf.unregisterField(thisbox);
+            cascade = v; surf = surface;
+            if (surf and fieldinfo and surf.registerField)
+                surf.registerField(thisbox);
+        }
+        
+        fieldinfo ++= function(v) {
+            cascade = v;
+            surface ++= surfaceWrite;
+        }
+        
+    </ui:box>
+    
+    // scriptid references
+    static.scriptids = {};
+    
+    /** recursive function to build a widget tree from our js objects */
+    static.unserialize = function(o) {
+        if (o == null or (keysof(o)).size==0) return null;
+        //for (var k in o) vexi.log.info(k+": "+o[k]);
+        var c = guide.insert.item..components[o.namespace+"."+o.template];
+        if (c == null) {
+            c = guide.insert.item(vexi.box);
+            c.namespace = o.namespace;
+            c.template = o.template;
+        }
+        c = c.getObject();
+        c.fieldinfo = o.fieldinfo;
+        // set properties
+        for (var k in o.properties)
+            c.setProperty(k, o.properties[k]);
+        // scriptids reference
+        if (o.properties.scriptid)
+            static.scriptids[o.properties.scriptid] = c;
+        // iterate over children
+        var l = o.children ? o.children.length : 0;
+        for (var i=0; l>i; i++) {
+            c[i] = callee(o.children[i]);
+            c[i].parent = c;
+        }
+        return c;
+    }
+    
+</vexi>
\ No newline at end of file

Added: trunk/widgets/org.vexi.guide/src/org/vexi/guide/uioverlay.t
===================================================================
--- trunk/widgets/org.vexi.guide/src/org/vexi/guide/uioverlay.t                 
        (rev 0)
+++ trunk/widgets/org.vexi.guide/src/org/vexi/guide/uioverlay.t 2008-10-30 
01:02:50 UTC (rev 3154)
@@ -0,0 +1,57 @@
+<!-- Copyright 2008 -- all rights reserved -->
+
+<vexi xmlns:ui="vexi://ui" xmlns:meta="vexi://meta" xmlns="vexi.layout"
+    xmlns:role="org.vexi.lib.role">
+    <meta:doc>
+        <author>Charles Goodwin</author>
+        <name>UI Overlay</name>
+        <desc>Overlays a UI object on a GUIDE canvas for mouse tracking</desc>
+    </meta:doc>
+    
+    <ui:box redirect=":$content" align="topleft" layout="place">
+        <margin id="margin" margin="5"><ui:box id="content" layout="place" 
/></margin>
+        
+        thisbox.activate;
+        thisbox.insertinto;
+        thisbox.insertmode;
+        
+        Enter ++= function(v) { activate = true; return; }
+        Leave ++= function(v) { activate = false; return; }
+        
+        $content.Enter ++= function(v) { insertinto = true; return; }
+        $content.Leave ++= function(v) { insertinto = false; return; }
+        
+        var syncprop = function(v) {
+            cascade = v;
+            if (insertmode) return;
+            thisbox[trapname] = v + (trapee.viewactual ? 10 : 0);
+        }
+        
+        var syncpos = function(v) {
+            cascade = v;
+            if (insertmode) return;
+            thisbox[trapname] = trapee.parent.distanceto(trapee)[trapname];
+        }
+        
+        /** keep our size/position synchronised with the widget */
+        thisbox.object ++= function(v) {
+            cascade = v;
+            v.width ++= syncprop;
+            v.height ++= syncprop;
+            v.x ++= syncpos;
+            v.y ++= syncpos;
+        }
+        
+        /** catch up with any changes */
+        thisbox.resync = function() {
+            width  = object.width + (object.viewactual ? 10 : 0);
+            height = object.height + (object.viewactual ? 10 : 0);
+            var d = object.parent.distanceto(object);
+            x = d.x;
+            y = d.y;
+            var n = numchildren;
+            for (var i=0; n>i; i++) thisbox[i].resync();
+        }
+        
+    </ui:box>
+</vexi>
\ No newline at end of file


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to