diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-02-06 01:06:46 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-02-06 01:06:46 +0000 |
commit | 3e1309dbb69d64d91c328763c7a2dd4a6bcf9427 (patch) | |
tree | 4383fcd49cfe9ca131c34a2efd8d69e911b4aeed /sca-cpp/trunk/modules/edit/htdocs | |
parent | ce4092ca7f7e16a9a9b9b67da22055012e895c25 (diff) |
Support for changing component names and properties, and some edit improvements.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1067563 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/app/app.html | 24 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/app/index.html | 5 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html | 33 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/dash/index.html | 3 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/graph/graph.html | 40 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/graph/graph.js | 326 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/graph/index.html | 5 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/index.html | 5 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/main.html | 11 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/index.html | 5 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/page.html | 48 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/page.js | 173 |
12 files changed, 563 insertions, 115 deletions
diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/app.html b/sca-cpp/trunk/modules/edit/htdocs/app/app.html index 7a6330102a..7d95dcdd63 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/app/app.html +++ b/sca-cpp/trunk/modules/edit/htdocs/app/app.html @@ -29,18 +29,31 @@ </head> <body> -<div style="position: absolute; top: 0px; left: 0px; right: 0px;"> +<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;"> -<table width="100%"> -<tr><th><span id="appname"></span><span style="padding-top: 0px; padding-bottom:0px; position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr> +<table style="width: 100%;"> +<tr> +<th class="thl thr">Properties</th> + +<th class="thl thr" style="padding-top: 0px; padding-bottom: 0px; padding-right: 0px; text-align: right;"> +<span id="source" style="font-weight: normal;">[atom]</span> +<input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/> +</th> +</tr> </table> <br> <div> <form id="appForm"> -<table width="100%"> +<table style="width: 100%;"> <tr><tr><td><b>App Title:</b></td></tr> <tr><td><input type="text" id="appTitle" size="30"/></td></tr> +<tr><tr><td><b>Category:</b></td></tr> +<tr><td><input type="text" id="appCategory" size="15" value="Cool Apps"/></td></tr> +<tr><tr><td><b>Updated:</b></td></tr> +<tr><td><span id="appUpdated">Feb 4, 2011</span></td></tr> +<tr><tr><td><b>Description:</b></td></tr> +<tr><td><textarea id="appDescription" cols="30" rows="5">Enter a short description of your app here</textarea></td></tr> </table> </form> </div> @@ -48,6 +61,7 @@ </div> <script type="text/javascript"> +if (ui.isIE()) $('bodydiv').style.right = -20; // Init service references var editWidget = sca.component("EditWidget"); @@ -57,7 +71,7 @@ var dashboard = sca.reference(editWidget, "dashboard"); * The current app name. */ var appname = ui.queryParams()['app']; -$('appname').innerHTML = 'App: ' + appname; +$('source').innerHTML = '[<a href="/apps/' + appname + '">atom</a>]'; /** * Get and display an app. diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/index.html b/sca-cpp/trunk/modules/edit/htdocs/app/index.html index f79229d17e..b4478dc8dd 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/app/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/app/index.html @@ -38,6 +38,9 @@ var appname = ui.queryParams()['app']; ui.loadwidget('menu', '/menu.html?app=' + appname); </script> +<h1>App Edit <span id="appNameHeader" style="font-weight: normal;"></span></h1> +<br/> + <div id="app"></div> <script type="text/javascript"> @@ -52,6 +55,8 @@ function editapp(name) { } // Display the editor for the current app +document.title = 'App - ' + appname; +$('appNameHeader').innerHTML = ' - ' + appname; editapp(appname); </script> diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html index 5b5d758f31..11c0b95979 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html +++ b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html @@ -29,21 +29,22 @@ </head> <body> -<div style="position: absolute; top: 0px; left: 0px; right: 0px;"> +<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;"> <div id="apps"></div> <br/> <input type="button" id="createAppButton" value="Create App"/> +<br/> +<br/> <div id="newApp" style="visibility: hidden;"> -<form id="newAppForm"> -<table width="100%"> -<tr><th>Create an App</th></tr> +<table style="width: 100%;"> +<tr><th class="thl thr">Create an App</th></tr> <tr><td></td></tr> </table> -<br> +<br/> -<table width="100%"> +<table style="width: 100%;"> <tr><td><b>App Name:</b></td></tr> <tr><td><input type="text" id="appName" size="10"/></td></tr> <tr><tr><td><b>App Title:</b></td></tr> @@ -53,12 +54,13 @@ <input id="createAppCancelButton" type="button" value="Cancel"/> </td></tr> </table> -</form> </div> </div> <script type="text/javascript"> +if (ui.isIE()) $('bodydiv').style.right = -20; + // Init service references var editWidget = sca.component("EditWidget"); var dashboard = sca.reference(editWidget, "dashboard"); @@ -68,8 +70,13 @@ var dashboard = sca.reference(editWidget, "dashboard"); */ function getapps(sync) { function display(doc) { - var apps = '<table width="100%">'; - apps += '<tr><th>App</th><th>Title</th></tr>'; + var apps = '<table style="width: 100%;">'; + apps += '<tr><th class="thl thr">App</th>' + + '<th class="thr thl">Title</th>' + + '<th class="thr thl" style="padding-top: 4px; padding-bottom: 4px; padding-right: 2px; text-align: right;">' + + '<span style="font-weight: normal;">' + + '[<a href="/dashboard">atom</a> <a href="/dashboardcache/joe@localhost">json</a>]' + + '</span></th></tr>'; var entries = cddr(atom.readATOMFeedDocument(doc)); for (var i = 0; i < length(entries); i++) { @@ -84,7 +91,7 @@ function getapps(sync) { apps += '<tr>'; //apps += '<td><input name="apps" type="checkbox" value="' + name + '">' + '<a href=\"' + '/app/?app=' + name + '\">' + name + '</a></td>'; apps += '<td><a href=\"' + '/app/?app=' + name + '\" target=\"_parent\">' + name + '</a></td>'; - apps += '<td class="tdw">' + title + '</td>'; + apps += '<td class="tdw" colspan="2">' + title + '</td>'; apps += '</tr>'; } apps += '</table>'; @@ -104,8 +111,7 @@ function getapps(sync) { * Display create app form. */ $('createAppButton').onclick = function() { - var div = $('newApp'); - div.style.visibility = 'visible'; + $('newApp').style.visibility = 'visible'; $('appName').focus(); return false; }; @@ -130,8 +136,7 @@ $('createAppOKButton').onclick = function() { * Cancel creating an app. */ $('createAppCancelButton').onclick = function() { - var div = $('newApp'); - div.style.visibility = 'hidden'; + $('newApp').style.visibility = 'hidden'; $('appName').value = ''; $('appTitle').title = ''; return false; diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html index d3add792d6..834bca6201 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html @@ -35,6 +35,9 @@ ui.loadwidget('menu', '/menu.html'); </script> +<h1>App Edit</h1> +<br/> + <div id="dashboard"></div> <script type="text/javascript"> diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html index 1572262627..3ca104a122 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html @@ -30,15 +30,31 @@ </head> <body> -<div style="position: absolute; top: 0px; left: 0px; right: 0px;"> +<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;"> -<table width="100%"> -<tr><th style="width: 338px;">Components</th><th style="padding-top: 0px; padding-bottom: 0px;"><span id="appname"></span><span style="position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr> +<table style="width: 100%;"> +<tr> +<th class="thl" style="width: 330px; min-width: 330px;">Palette</th><th class="ths" style="width: 3px; min-width: 3px;"></th> + +<th class="thr" style="padding-top: 0px; padding-bottom: 0px;"> +<input id="compName" type="text" value="component name" style="position: relative; width: 200px;"/> +<input id="propValue" type="text" value="property value" style="position: relative; width: 300px;"/> +</th> + +<th class="thl thr" style="padding-top: 0px; padding-bottom: 0px; padding-right: 0px; text-align: right;"> +<span id="source" style="font-weight: normal;">[atom json]</span> +<input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/> +</th> +</tr> + +<tr style="height: 5000px;"><td class="tdl"></td><th class="ths"></th><td class="tdr" colspan="2"></td></tr> </table> </div> <script type="text/javascript"> +if (ui.isIE()) $('bodydiv').style.right = -20; + var editWidget = sca.component("EditWidget"); var palettes = sca.reference(editWidget, "palettes"); var apps = sca.reference(editWidget, "apps"); @@ -50,7 +66,7 @@ var apps = sca.reference(editWidget, "apps"); * The current app name. */ var appname = ui.queryParams()['app']; -$('appname').innerHTML = 'Composition: ' + appname; +$('source').innerHTML = '[<a href="/apps/' + appname + '">atom</a> <a href="/appcache/' + appname + '/app.composite">json</a>]'; /** * The current app composite. @@ -122,17 +138,17 @@ $('saveButton').onclick = function(e) { }; // Create editor graph area -var g = graph.mkgraph(graph.mkpath().move(0,50)); +var g = graph.mkgraph(graph.mkpath().move(0,40), $('compName'), $('propValue')); var bg = graph.mkgroup(graph.mkpath()); -// Install the palettes. +// Install the palettes var gpalettes = new Array(); -var spalette = 'variables'; -installpalette('variables', graph.mkpath().move(0,10), g, bg, spalette, gpalettes); -installpalette('control', graph.mkpath().move(0,80), g, bg, spalette, gpalettes); -installpalette('operators', graph.mkpath().move(0,150), g, bg, spalette, gpalettes); -installpalette('social', graph.mkpath().move(0,220), g, bg, spalette, gpalettes); -installpalette('sensors', graph.mkpath().move(0,290), g, bg, spalette, gpalettes); +var spalette = 'values'; +installpalette('values', graph.mkpath().move(0,10), g, bg, spalette, gpalettes); +installpalette('control', graph.mkpath().move(0,60), g, bg, spalette, gpalettes); +installpalette('operators', graph.mkpath().move(0,110), g, bg, spalette, gpalettes); +installpalette('social', graph.mkpath().move(0,160), g, bg, spalette, gpalettes); +installpalette('sensors', graph.mkpath().move(0,210), g, bg, spalette, gpalettes); // Get and display the current app getapp(appname, g); diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js index 8c0419c8bd..e73c178267 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js @@ -31,6 +31,7 @@ graph.colors.black = '#000000'; graph.colors.blue = '#0000ff'; graph.colors.cyan = '#00ffff'; graph.colors.gray = '#808080' +graph.colors.lightgray = '#dcdcdc' graph.colors.green = '#00ff00'; graph.colors.magenta = '#ff00ff'; graph.colors.orange = '#ffa500'; @@ -101,7 +102,7 @@ if (ui.isIE()) { /** * Make a VML graph. */ - graph.mkgraph = function(pos) { + graph.mkgraph = function(pos, cname, pvalue) { // Create div element to host the graph var div = document.createElement('div'); @@ -118,8 +119,9 @@ if (ui.isIE()) { vmlg.coordsize = '5000,5000'; div.appendChild(vmlg); - // Keep track of the current dragged element + // Track element dragging and selection graph.dragging = null; + graph.selected = null; /** * Find the first draggable element in a hierarchy of elements. @@ -140,18 +142,25 @@ if (ui.isIE()) { // Find draggable element graph.dragging = draggable(window.event.srcElement); - if (graph.dragging == null) + graph.selected = graph.dragging; + if (graph.dragging == null) { + + // Reset current selection + cname.value = ''; + pvalue.value = ''; return false; + } // Clone component from the palette - if (graph.dragging.id.substring(0, 8) == 'palette:') - graph.dragging = graph.clonepalette(graph.dragging); + var compos = scdl.composite(vmlg.compos); + if (graph.dragging.id.substring(0, 8) == 'palette:') { + graph.dragging = graph.clonepalette(graph.dragging, compos); + graph.selected = graph.dragging; + } // Cut wire to component - if (graph.dragging.parentNode != vmlg) { - var compos = scdl.composite(vmlg.compos); + if (graph.dragging.parentNode != vmlg) setElement(compos, graph.cutwire(graph.dragging, compos, vmlg)); - } // Bring component to the top graph.bringtotop(graph.dragging, vmlg); @@ -160,6 +169,10 @@ if (ui.isIE()) { graph.dragX = window.event.clientX; graph.dragY = window.event.clientY; vmlg.setCapture(); + + // Update the component name and property value fields + cname.value = graph.selected.id; + pvalue.value = graph.property(graph.selected.comp); return false; }; @@ -172,7 +185,11 @@ if (ui.isIE()) { if (graph.dragging.parentNode == vmlg && graph.dragging.id.substring(0, 8) != 'palette:') { var gpos = graph.relpos(graph.dragging); - if (pos.xpos() >= 350) { + if (gpos.xpos() >= 330) { + + // If component close enough to editing area, move it there + if (gpos.xpos() < 350) + graph.move(graph.dragging, graph.mkpath().move(350, gpos.ypos())); // Add new dragged component to the composite if (isNil(graph.dragging.compos)) { @@ -198,6 +215,11 @@ if (ui.isIE()) { var compos = scdl.composite(vmlg.compos); setElement(compos, graph.removecomp(graph.dragging.comp, compos)); } + + // Reset current selection + graph.selected = null; + cname.value = ''; + pvalue.value = ''; } } @@ -205,10 +227,8 @@ if (ui.isIE()) { graph.dragging = null; vmlg.releaseCapture(); - // Remove and refresh the composite - map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { vmlg.removeChild(n); } return n; }, nodeList(vmlg.childNodes)); - graph.display(graph.composite(vmlg.compos, graph.mkpath().move(350,0)), vmlg); - + // Refresh the composite + graph.refresh(vmlg); return false; }; @@ -238,8 +258,38 @@ if (ui.isIE()) { return false; }; + /** + * Handle field on change events. + */ + cname.onchange = function() { + if (graph.selected == null) + return false; + + // Change component name and refactor references to it + var compos = scdl.composite(svg.compos); + cname.value = graph.ucid(cname.value, compos); + graph.selected.id = cname.value; + setElement(compos, graph.renamecomp(graph.selected.comp, compos, cname.value)); + + // Refresh the composite + graph.refresh(svg); + return false; + }; + + pvalue.onchange = function() { + if (graph.selected == null) + return false; + + // Change the component property value + graph.setproperty(graph.selected.comp, pvalue.value); + + // Refresh the composite + graph.refresh(svg); + return false; + }; + // Create hidden spans to help compute the width of - // component and reference titles + // component, reference and property titles graph.comptitlewidthdiv = document.createElement('span'); graph.comptitlewidthdiv.style.visibility = 'hidden' graph.comptitlewidthdiv.style.fontWeight = 'bold' @@ -249,6 +299,10 @@ if (ui.isIE()) { graph.reftitlewidthdiv.style.visibility = 'hidden' div.appendChild(graph.reftitlewidthdiv); + graph.proptitlewidthdiv = document.createElement('span'); + graph.proptitlewidthdiv.style.visibility = 'hidden' + div.appendChild(graph.proptitlewidthdiv); + return vmlg; }; @@ -293,9 +347,10 @@ if (ui.isIE()) { */ graph.mktitle = function(t, bold, pos) { var title = document.createElement('v:textbox'); + title.style.position = 'absolute'; title.style.left = pos.xpos(); title.style.top = pos.ypos(); - title.style.position = 'absolute'; + title.inset = '' + 4 + 'px ' + pos.ypos() + 'px 0px 0px'; if (bold) title.style.fontWeight = 'bold'; var tnode = document.createTextNode(t); @@ -325,6 +380,27 @@ if (ui.isIE()) { }; /** + * Return an element representing the value of a property. + */ + graph.proptitle = function(comp) { + var tsvcs = graph.tsvcs(comp); + var lsvcs = graph.lsvcs(comp); + var pos = graph.mkpath().move(isNil(lsvcs)? 5 : 25, isNil(tsvcs)? 20 : 40); + return graph.mktitle(graph.property(comp), false, pos); + }; + + /** + * Return the width of the value of a property. + */ + graph.proptitlewidth = function(comp) { + var t = graph.property(comp); + graph.proptitlewidthdiv.innerHTML = t; + var twidth = graph.proptitlewidthdiv.offsetWidth; + graph.proptitlewidthdiv.innerHTML = ''; + return twidth; + }; + + /** * Return an element representing the title of a reference. */ graph.reftitle = function(ref) { @@ -347,8 +423,9 @@ if (ui.isIE()) { */ graph.compnode = function(comp, cassoc, pos) { - // Make the component title element + // Make the component and property title elements var title = graph.comptitle(comp); + var prop = graph.proptitle(comp); // Compute the component shape path var path = graph.comppath(comp, cassoc); @@ -388,13 +465,14 @@ if (ui.isIE()) { g.style.top = pos.ypos(); g.appendChild(shape); shape.appendChild(title); + shape.appendChild(prop); g.appendChild(contour) // Store the component and the positions of its services // and references in the component shape g.comp = comp; - g.refpos = path.refpos; - g.svcpos = path.svcpos; + g.refpos = reverse(path.refpos); + g.svcpos = reverse(path.svcpos); return g; }; @@ -426,7 +504,7 @@ if (ui.isIE()) { shape.style.height = 5000; shape.coordsize = '5000,5000'; shape.path = path; - shape.fillcolor = graph.colors.blue1; + shape.fillcolor = graph.colors.lightgray; shape.stroked = 'false'; // Create an overlay contour shape @@ -484,7 +562,7 @@ if (ui.isIE()) { /** * Make an SVG graph. */ - graph.mkgraph = function(pos) { + graph.mkgraph = function(pos, cname, pvalue) { // Create a div element to host the graph var div = document.createElement('div'); @@ -501,8 +579,9 @@ if (ui.isIE()) { svg.style.width = 5000; div.appendChild(svg); - // Keep track of current dragged element + // Track element dragging and selection graph.dragging = null; + graph.selected = null; /** * Find the first draggable element in a hierarchy of elements. @@ -526,18 +605,25 @@ if (ui.isIE()) { // Find draggable component graph.dragging = draggable(e.target); - if (graph.dragging == null) + graph.selected = graph.dragging; + if (graph.dragging == null) { + + // Reset current selection + cname.value = ''; + pvalue.value = ''; return false; + } // Clone component from the palette - if (graph.dragging.id.substring(0, 8) == 'palette:') - graph.dragging = graph.clonepalette(graph.dragging); + var compos = scdl.composite(svg.compos); + if (graph.dragging.id.substring(0, 8) == 'palette:') { + graph.dragging = graph.clonepalette(graph.dragging, compos); + graph.selected = graph.dragging; + } // Cut wire to component - if (graph.dragging.parentNode != svg) { - var compos = scdl.composite(svg.compos); + if (graph.dragging.parentNode != svg) setElement(compos, graph.cutwire(graph.dragging, compos, svg)); - } // Bring component to the top graph.bringtotop(graph.dragging, svg); @@ -546,6 +632,10 @@ if (ui.isIE()) { var pos = typeof e.touches != "undefined" ? e.touches[0] : e; graph.dragX = pos.screenX; graph.dragY = pos.screenY; + + // Update the component name and property value fields + cname.value = graph.selected.id; + pvalue.value = graph.property(graph.selected.comp); return false; }; @@ -561,7 +651,11 @@ if (ui.isIE()) { if (graph.dragging.parentNode == svg && graph.dragging.id.substring(0, 8) != 'palette:') { var gpos = graph.relpos(graph.dragging); - if (gpos.xpos() >= 350) { + if (gpos.xpos() >= 330) { + + // If component close enough to editing area, move it there + if (gpos.xpos() < 350) + graph.move(graph.dragging, graph.mkpath().move(350, gpos.ypos())); // Add new dragged component to the composite if (isNil(graph.dragging.compos)) { @@ -587,16 +681,19 @@ if (ui.isIE()) { var compos = scdl.composite(svg.compos); setElement(compos, graph.removecomp(graph.dragging.comp, compos)); } + + // Reset current selection + graph.selected = null; + cname.value = ''; + pvalue.value = ''; } } // Forget current dragged component graph.dragging = null; - // Remove and refresh the composite - map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { svg.removeChild(n); } return n; }, nodeList(svg.childNodes)); - graph.display(graph.composite(svg.compos, graph.mkpath().move(350,0)), svg); - + // Refresh the composite + graph.refresh(svg); return false; }; @@ -645,6 +742,36 @@ if (ui.isIE()) { window.ontouchmove = window.onmousemove; window.top.ontouchmove = window.onmousemove; + /** + * Handle field on change events. + */ + cname.onchange = function() { + if (graph.selected == null) + return false; + + // Change component name and refactor references to it + var compos = scdl.composite(svg.compos); + cname.value = graph.ucid(cname.value, compos); + graph.selected.id = cname.value; + setElement(compos, graph.renamecomp(graph.selected.comp, compos, cname.value)); + + // Refresh the composite + graph.refresh(svg); + return false; + }; + + pvalue.onchange = function() { + if (graph.selected == null) + return false; + + // Change the component property value + graph.setproperty(graph.selected.comp, pvalue.value); + + // Refresh the composite + graph.refresh(svg); + return false; + }; + // Create a hidden SVG element to help compute the width // of component and reference titles graph.titlewidthsvg = document.createElementNS(graph.svgns, 'svg'); @@ -743,12 +870,33 @@ if (ui.isIE()) { }; /** + * Return an element representing the value of a property. + */ + graph.proptitle = function(comp) { + var title = graph.mktitle(graph.property(comp), false); + title.setAttribute('y', 30); + return title; + }; + + /** + * Return the width of the title of a property. + */ + graph.proptitlewidth = function(comp) { + var title = graph.proptitle(comp); + graph.titlewidthsvg.appendChild(title); + var width = title.getBBox().width; + graph.titlewidthsvg.removeChild(title); + return width; + }; + + /** * Return a node representing a component. */ graph.compnode = function(comp, cassoc, pos) { - // Make the component title + // Make the component and property title elements var title = graph.comptitle(comp); + var prop = graph.proptitle(comp); // Compute the path of the component shape var path = graph.comppath(comp, cassoc); @@ -775,6 +923,7 @@ if (ui.isIE()) { g.appendChild(shape); g.appendChild(contour); g.appendChild(title); + g.appendChild(prop); // Store the component and the positions of its services // and references in the component shape @@ -808,7 +957,7 @@ if (ui.isIE()) { // Create the main button shape var shape = document.createElementNS(graph.svgns, 'path'); shape.setAttribute('d', path); - shape.setAttribute('fill', graph.colors.blue1); + shape.setAttribute('fill', graph.colors.lightgray); // Create an overlay contour shape var contour = document.createElementNS(graph.svgns, 'path'); @@ -873,7 +1022,30 @@ graph.bringtotop = function(n, g) { */ graph.title = function(e) { var d = scdl.documentation(e); - return d != null? d : scdl.name(e); + if (d != null) + return d; + return scdl.name(e); +}; + +/** + * Return the property value of a SCDL component. + */ +graph.property = function(e) { + var p = scdl.properties(e); + if (isNil(p)) + return ''; + return scdl.propertyValue(car(p)); +}; + +/** + * Change the property value of a SCDL component. + */ +graph.setproperty = function(e, value) { + var p = scdl.properties(e); + if (isNil(p)) + return ''; + setElement(car(p), mklist(element, "'property", mklist(attribute, "'name", "property"), value)); + return value; }; /** @@ -1040,7 +1212,7 @@ graph.rrefswidth = function(refs, cassoc) { */ graph.compwidth = function(comp, cassoc) { return memo(comp, 'width', function() { - var twidth = graph.comptitlewidth(comp) + 20; + var twidth = Math.max(graph.comptitlewidth(comp), graph.proptitlewidth(comp)) + 20; var tsvcs = graph.tsvcs(comp); var tsvcsw = Math.max(1, length(tsvcs)) * 60 + 20; var brefs = graph.brefs(comp); @@ -1176,7 +1348,7 @@ graph.comppath = function(comp, cassoc) { * Return a path representing a button node. */ graph.buttonpath = function(t) { - var height = 60; + var height = 40; var width = 120; var path = graph.mkpath().move(10,0); path = path.line(width - 10,path.ypos()).rcurve(10,0,0,10); @@ -1352,14 +1524,39 @@ graph.composite = function(compos, pos) { }; /** + * Return a component unique id. + */ +graph.ucid = function(prefix, compos) { + + // Build an assoc list keyed by component name + var comps = map(function(c) { return mklist(scdl.name(c), c); }, namedElementChildren("'component", compos)); + + /** + * Find a free component id. + */ + function ucid(p, id) { + if (isNil(assoc(p + id, comps))) + return p + id; + return ucid(p, id + 1); + } + + if (isNil(assoc(prefix, comps))) + return prefix; + + return ucid(prefix == ''? 'comp' : prefix, 2); +}; + +/** * Clone a palette component node. */ -graph.clones = 0; -graph.clonepalette = function(e) { +graph.clonepalette = function(e, compos) { // Clone the SCDL component and give it a unique name - var comp = append(mklist(element, "'component", mklist(attribute, "'name", scdl.name(e.comp) + (++graph.clones))), + var comp = append(mklist(element, "'component", mklist(attribute, "'name", graph.ucid(scdl.name(e.comp), compos))), filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e.comp))); + var x = '<composite xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1">' + writeXML(mklist(comp), false) + '</composite>'; + var compos = readXML(mklist(x)); + comp = car(scdl.components(compos)); // Make a component node var gcomp = graph.compnode(comp, mklist(), graph.mkpath()); @@ -1396,6 +1593,41 @@ graph.removecomp = function(comp, compos) { }; /** + * Rename a component. + */ +graph.renamecomp = function(comp, compos, name) { + + /** + * Refactor references to a component. + */ + function refactorrefs(refs, oname, nname) { + if (isNil(refs)) + return true; + var ref = car(refs); + if (scdl.target(ref) != oname) + return refactorrefs(cdr(refs), oname, nname); + + // Change the reference's target attribute + setElement(ref, append(mklist(element, "'reference"), append(filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'target"); }, elementChildren(ref)), mklist(mklist(attribute, "'target", nname))))); + + return refactorrefs(cdr(refs), oname, nname); + } + + // Refactor all the references to the renamed component + var oname = scdl.name(comp); + map(function(c) { return refactorrefs(scdl.references(c), oname, name); }, namedElementChildren("'component", compos)); + + // Rename the SCDL promoted service and component + var proms = filter(function(s) { return scdl.name(s) == oname }, scdl.services(compos)); + if (!isNil(proms)) { + setElement(car(proms), mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name))); + } + setElement(comp, append(mklist(element, "'component"), cons(mklist(attribute, "'name", name), filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'name"); }, elementChildren(comp))))); + + return append(mklist(element, "'composite"), elementChildren(compos)); +}; + +/** * Cut the wire to a component node and make that node a * top level component node. */ @@ -1429,7 +1661,6 @@ graph.cutwire = function(node, compos, g) { return append(mklist(element, "'composite"), append(filter(function(c) {return !(isElement(c) && scdl.name(c) == name); }, elementChildren(compos)), mklist(prom, comp))); } - /** * Wire a component to the closest neighbor reference. */ @@ -1513,10 +1744,21 @@ graph.display = function(nodes, g) { }; /** + * Refresh a graph. + */ +graph.refresh = function(g) { + + // Remove nodes and redisplay the composite associated with the graph + map(function(n) { if (!isNil(n.comp) && n.id.substr(0, 8) != 'palette:') { g.removeChild(n); } return n; }, nodeList(g.childNodes)); + graph.display(graph.composite(g.compos, graph.mkpath().move(350,0)), g); + return g; +}; + +/** * Display and enable editing of a composite and the graphical * nodes that represent it. */ -graph.edit = function(compos, nodes, g) { +graph.edit = function(compos, nodes, g, cname, pvalue) { // Store the composite in the graphical canvas g.compos = compos; diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html index dbe16d06bf..ac9cf2f3b1 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html @@ -38,6 +38,9 @@ var appname = ui.queryParams()['app']; ui.loadwidget('menu', '/menu.html?app=' + appname); </script> +<h1>App Edit <span id="appNameHeader" style="font-weight: normal;"></span></h1> +<br/> + <div id="graph"></div> <script type="text/javascript"> @@ -55,6 +58,8 @@ function editapp(name) { } // Display the editor for the current app +document.title = 'Composition - ' + appname; +$('appNameHeader').innerHTML = ' - ' + appname; editapp(appname); </script> diff --git a/sca-cpp/trunk/modules/edit/htdocs/index.html b/sca-cpp/trunk/modules/edit/htdocs/index.html index db5764781a..6a4c055295 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/index.html @@ -18,7 +18,7 @@ --> <html> <head> -<title>App Edit Tools</title> +<title>App Edit</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/> <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/> @@ -35,8 +35,7 @@ ui.loadwidget('menu', '/menu.html'); </script> -<br/> -<h1>App Edit Tools</h1> +<h1>App Edit</h1> <br/> <div id="main"></div> diff --git a/sca-cpp/trunk/modules/edit/htdocs/main.html b/sca-cpp/trunk/modules/edit/htdocs/main.html index 65909c1a94..819af53c52 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/main.html +++ b/sca-cpp/trunk/modules/edit/htdocs/main.html @@ -24,9 +24,10 @@ </head> <body> -<div style="position: absolute; top: 0px; left: 0px; right: 0px;"> +<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;"> -<div>This module implements simple tools to help you create Tuscany apps.</div> +<div>This module implements simple App editing tools to help you create Tuscany apps.</div> +<div>The user interface is minimalistic, by design.</div> <br/> <h2>App Dashboard</h2> @@ -36,12 +37,16 @@ <p>Try the <a href="app/?app=store" target="_parent">App Editor</a> to edit an app.</p> <h2>Composition Editor</h2> -<p>Try the <a href="graph/?app=store" target="_parent">Composition Editor</a> to compose an app.</p> +<p>Try the <a href="graph/?app=store" target="_parent">Composition Editor</a> to compose the logic of an app.</p> <h2>Page Editor</h2> <p>Try the <a href="page/?app=store" target="_parent">Page Editor</a> to draw an app page.</p> </div> +<script type="text/javascript"> +if (ui.isIE()) $('bodydiv').style.right = -20; +</script> + </body> </html> diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/index.html b/sca-cpp/trunk/modules/edit/htdocs/page/index.html index f8bfa273c7..23aeeb9e2a 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html @@ -38,6 +38,9 @@ var appname = ui.queryParams()['app']; ui.loadwidget('menu', '/menu.html?app=' + appname); </script> +<h1>App Edit <span id="appNameHeader" style="font-weight: normal;"></span></h1> +<br/> + <div id="page"></div> <script type="text/javascript"> @@ -55,6 +58,8 @@ function editapp(name) { } // Display the editor for the current app +document.title = 'Page - ' + appname; +$('appNameHeader').innerHTML = ' - ' + appname; editapp(appname); </script> diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.html b/sca-cpp/trunk/modules/edit/htdocs/page/page.html index d0a26fdad0..f3fdb9def7 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.html @@ -30,24 +30,38 @@ </head> <body> -<div style="position: absolute; top: 0px; left: 0px; right: 0px;"> +<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;"> -<table width="100%"> -<tr><th style="width: 338px;">Widgets</th><th style="padding-top: 0px; padding-bottom: 0px;"><span id="appname"></span><span style="position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr> +<table style="width: 100%;"> +<tr> +<th class="thl thr" style="width: 330px; min-width: 330px;">Palette</th><th class="ths" style="width: 3px; min-width: 3px;"></th> + +<th class="thl thr" style="padding-top: 0px; padding-bottom: 0px;"> +<input id="widgetName" type="text" value="widget name" style="position: relative; width: 150px;"/> +<input id="widgetText" type="text" value="widget text" style="position: relative; width: 300px;"/> +</th> + +<th class="thl thr" style="padding-top: 0px; padding-bottom: 0px; padding-right: 0px; text-align: right;"> +<span id="source" style="font-weight: normal;">[atom json]</span> +<input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/> +</th> +</tr> + +<tr style="height: 5000px;"><td class="tdl"></td><th class="ths"></th><td class="tdr" colspan="2"></td></tr> </table> -<div id="page" style="position: absolute; top: 60px; left: 0px; width: 5000px; height: 5000px;"> +<div id="page" style="position: absolute; top: 40px; left: 0px; width: 5000px; height: 5000px;"> -<span id="palette:h1" style="position: absolute; left: 0px; top: 0px;"><h1>Header1</h1></span> -<span id="palette:h2" style="position: absolute; left: 0px; top: 40px;"><h2>Header2</h2></span> -<span id="palette:button" style="position: absolute; left: 0px; top: 80px;"><input type="button" value="button"/></span> -<span id="palette:entry" style="position: absolute; left: 0px; top: 120px;"><input type="text" value="field" size="5"/></span> -<span id="palette:password" style="position: absolute; left: 0px; top: 160px;"><input type="password" value="password" size="5"/></span> -<span id="palette:checkbox" style="position: absolute; left: 0px; top: 200px;"><input type="checkbox" value="checkbox"></input><span>checkbox</span></span> -<span id="palette:select" style="position: absolute; left: 0px; top: 240px;"><select><option value="list">list</option></select></span> -<span id="palette:link" style="position: absolute; left: 0px; top: 280px;"><a href="/"><span>link</span></a></span> -<span id="palette:text" style="position: absolute; left: 0px; top: 320px;"><span>text</span></span> -<span id="palette:img" style="position: absolute; left: 0px; top: 360px;"><img/></span> +<span class="h1" id="palette:h1" style="position: absolute; left: 0px; top: 0px;"><h1>Header1</h1></span> +<span class="h2" id="palette:h2" style="position: absolute; left: 0px; top: 40px;"><h2>Header2</h2></span> +<span class="button" id="palette:button" style="position: absolute; left: 0px; top: 80px;"><input type="button" value="button"/></span> +<span class="entry" id="palette:entry" style="position: absolute; left: 0px; top: 120px;"><input type="text" value="field" size="5"/></span> +<span class="password" id="palette:password" style="position: absolute; left: 0px; top: 160px;"><input type="password" value="password" size="5"/></span> +<span class="checkbox" id="palette:checkbox" style="position: absolute; left: 0px; top: 200px;"><input type="checkbox" value="checkbox"></input><span>checkbox</span></span> +<span class="list" id="palette:list" style="position: absolute; left: 0px; top: 240px;"><select><option value="list">list</option></select></span> +<span class="link" id="palette:link" style="position: absolute; left: 0px; top: 280px;"><a href="/"><span>link</span></a></span> +<span class="text" id="palette:text" style="position: absolute; left: 0px; top: 320px;"><span>text</span></span> +<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 360px;"><img src=""/></span> </div> @@ -57,6 +71,8 @@ </div> <script type="text/javascript"> +if (ui.isIE()) $('bodydiv').style.right = -20; + var editWidget = sca.component("EditWidget"); var pages = sca.reference(editWidget, "pages"); @@ -64,7 +80,7 @@ var pages = sca.reference(editWidget, "pages"); * The current app name. */ var appname = ui.queryParams()['app']; -$('appname').innerHTML = 'Page: ' + appname; +$('source').innerHTML = '[<a href="/pages/' + appname + '">atom</a> <a href="/appcache/' + appname + '/app.html">json</a>]'; /** * Return the page in an ATOM entry. @@ -142,7 +158,7 @@ $('saveButton').onclick = function(e) { // Initialize the page editor var edit = $('page'); -page.initpage(edit); +page.edit(edit, $('widgetName'), $('widgetText')); // Get and display the current app page getpage(appname, edit); diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.js b/sca-cpp/trunk/modules/edit/htdocs/page/page.js index 4628ec1235..41273d9824 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.js +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js @@ -27,10 +27,11 @@ if (ui.isIE()) { /** * Init a page editor. IE-specific implementation. */ - page.initpage = function(elem) { + page.edit = function(elem, wname, wtext) { - // Keep track of the current dragged element + // Track element dragging and selection page.dragging = null; + page.selected = null; /** * Handle a mouse down event. @@ -40,8 +41,20 @@ if (ui.isIE()) { // Find a draggable element page.dragging = page.draggable(window.event.srcElement, elem); - if (page.dragging == null) + page.selected = page.dragging; + if (page.dragging == null) { + + // Reset current selection + wname.value = ''; + wtext.value = ''; return false; + } + + // Clone element dragged from palette + if (page.dragging.id.substring(0, 8) == 'palette:') { + page.dragging = page.clone(page.dragging); + page.selected = page.dragging; + } // Bring it to the top page.bringtotop(page.dragging); @@ -50,6 +63,10 @@ if (ui.isIE()) { page.dragX = window.event.clientX; page.dragY = window.event.clientY; elem.setCapture(); + + // Update the widget name and text fields + wname.value = page.selected.id; + wtext.value = page.text(page.selected); return false; }; @@ -61,8 +78,21 @@ if (ui.isIE()) { return false; // Discard element dragged out of page area - if (ui.csspos(page.dragging.style.left) < 350 && page.dragging.id.substring(0, 8) != 'palette:') - page.dragging.parentNode.removeChild(page.dragging); + if (ui.csspos(page.dragging.style.left) < 350 && page.dragging.id.substring(0, 8) != 'palette:') { + if (ui.csspos(page.dragging.style.left) >= 330) { + + // Unless it's close enough to page area, then move it there + page.dragging.style.left = 350; + page.dragging.cover.style.left = 350; + } else { + page.dragging.parentNode.removeChild(page.dragging); + + // Reset current selection + page.selected = null; + wname.value = ''; + wtext.value = ''; + } + } // Forget current dragged element page.dragging = null; @@ -91,16 +121,29 @@ if (ui.isIE()) { else newY = 0; - // Clone element dragged from palette - if (page.dragging.id.substring(0, 8) == 'palette:') - page.dragging = page.clone(page.dragging); - // Move dragged element page.dragging.style.left = newX; page.dragging.style.top = newY; page.dragging.cover.style.left = newX; page.dragging.cover.style.top = newY; + return false; + }; + + /** + * Handle field on change events. + */ + wname.onchange = wname.onblur = function() { + if (page.selected == null) + return false; + page.selected.id = wname.value; + return false; + }; + wtext.onchange = wtext.onblur = function() { + if (page.selected == null) + return false; + page.settext(page.selected, wtext.value); + return false; }; // Cover child elements with span elements to prevent @@ -115,8 +158,11 @@ if (ui.isIE()) { /** * Init a page editor. Generic implementation for all other browsers. */ - page.initpage = function(elem) { + page.edit = function(elem, wname, wtext) { + + // Track element dragging and selection page.dragging = null; + page.selected = null; /** * Handle a mouse down event. @@ -129,8 +175,20 @@ if (ui.isIE()) { // Find a draggable element page.dragging = page.draggable(e.target, elem); - if (page.dragging == null) + page.selected = page.dragging; + if (page.dragging == null) { + + // Reset current selection + wname.value = ''; + wtext.value = ''; return false; + } + + // Clone element dragged from palette + if (page.dragging.id.substring(0, 8) == 'palette:') { + page.dragging = page.clone(page.dragging); + page.selected = page.dragging; + } // Bring it to the top page.bringtotop(page.dragging); @@ -139,6 +197,10 @@ if (ui.isIE()) { var pos = typeof e.touches != "undefined" ? e.touches[0] : e; page.dragX = pos.screenX; page.dragY = pos.screenY; + + // Update the widget name and text fields + wname.value = page.selected.id; + wtext.value = page.text(page.selected); return false; }; @@ -152,9 +214,22 @@ if (ui.isIE()) { if (page.dragging == null) return false; - // Discard element if dragged out of page area - if (ui.csspos(page.dragging.style.left) < 350 && page.dragging.id.substring(0, 8) != 'palette:') - page.dragging.parentNode.removeChild(page.dragging); + // Discard element dragged out of page area + if (ui.csspos(page.dragging.style.left) < 350 && page.dragging.id.substring(0, 8) != 'palette:') { + if (ui.csspos(page.dragging.style.left) >= 330) { + + // Unless it's close enough to page area, then move it there + page.dragging.style.left = 350; + page.dragging.cover.style.left = 350; + } else { + page.dragging.parentNode.removeChild(page.dragging); + + // Reset current selection + page.selected = null; + wname.value = ''; + wtext.value = ''; + } + } // Forget dragged element page.dragging = null; @@ -188,11 +263,6 @@ if (ui.isIE()) { else newY = 0; - // Clone element dragged from palette - if (page.dragging.id.substring(0, 8) == 'palette:') { - page.dragging = page.clone(page.dragging); - } - // Move the dragged element page.dragging.style.left = newX; page.dragging.style.top = newY; @@ -206,6 +276,23 @@ if (ui.isIE()) { window.ontouchmove = window.onmousemove; window.top.ontouchmove = window.onmousemove; + /** + * Handle field on change events. + */ + wname.onchange = wname.onblue = function() { + if (page.selected == null) + return false; + page.selected.id = wname.value; + return false; + }; + + wtext.onchange = wtext.onblur = function() { + if (page.selected == null) + return false; + page.settext(page.selected, wtext.value); + return false; + }; + // Cover child elements with span elements to prevent // any input events to reach them map(page.cover, nodeList(elem.childNodes)); @@ -215,6 +302,51 @@ if (ui.isIE()) { } /** + * Return the text of a widget. + */ +page.text = function(e) { + if (e.className == 'h1' || e.className == 'h2' || e.className == 'text') + return e.childNodes[0].innerHTML; + if (e.className == 'button' || e.className == 'entry' || e.className == 'password' || e.className == 'checkbox') + return e.childNodes[0].value; + if (e.className == 'list') + return e.childNodes[0].childNodes[0].value; + if (e.className == 'link') + return e.childNodes[0].childNodes[0].innerHTML; + return ''; +}; + +/** + * Set the text of a widget. + */ +page.settext = function(e, t) { + if (e.className == 'h1' || e.className == 'h2' || e.className == 'text') { + e.childNodes[0].innerHTML = t; + return t; + } + if (e.className == 'button' || e.className == 'entry' || e.className == 'password') { + e.childNodes[0].value = t; + return t; + } + if (e.className == 'checkbox') { + e.childNodes[0].value = t; + map(function(n) { if (n.nodeName == "SPAN") n.innerHTML = t; return n; }, nodeList(e.childNodes)); + return t; + } + if (e.className == 'list') { + e.childNodes[0].childNodes[0].value = t; + e.childNodes[0].childNodes[0].innerHTML = t; + return t; + } + if (e.className == 'link') { + e.childNodes[0].childNodes[0].href = t; + e.childNodes[0].childNodes[0].innerHTML = t; + return t; + } + return ''; +}; + +/** * Find a draggable element in a hierarchy of elements. */ page.draggable = function(n, e) { @@ -269,7 +401,8 @@ page.clone = function(e) { // Skip the palette: prefix ne.id = e.id.substr(8); - // Copy the HTML content + // Copy the class and HTML content + ne.className = e.className; ne.innerHTML = e.innerHTML; return ne; } |