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