From 6afef449a6560d469102ab0298d4cc925d76aa0f Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Sun, 30 Jan 2011 22:30:10 +0000 Subject: Add composite save function, improve UI a bit and some script cleanup and documentation. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1065409 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/modules/edit/Makefile.am | 4 +- .../trunk/modules/edit/apps/relay/app.composite | 10 +- .../trunk/modules/edit/apps/store/app.composite | 10 +- .../trunk/modules/edit/apps/store2/app.composite | 10 +- .../trunk/modules/edit/apps/store3/app.composite | 10 +- .../trunk/modules/edit/apps/travel/app.composite | 20 +- sca-cpp/trunk/modules/edit/htdocs/app/app.html | 85 +++++ sca-cpp/trunk/modules/edit/htdocs/app/index.html | 66 ++++ .../trunk/modules/edit/htdocs/dash/dashboard.html | 3 +- sca-cpp/trunk/modules/edit/htdocs/dash/index.html | 3 +- sca-cpp/trunk/modules/edit/htdocs/graph/graph.html | 39 +- sca-cpp/trunk/modules/edit/htdocs/graph/graph.js | 400 ++++++++++++++++++--- sca-cpp/trunk/modules/edit/htdocs/graph/index.html | 12 +- sca-cpp/trunk/modules/edit/htdocs/index.html | 7 +- sca-cpp/trunk/modules/edit/htdocs/menu.html | 2 +- sca-cpp/trunk/modules/edit/htdocs/page/index.html | 10 +- sca-cpp/trunk/modules/edit/htdocs/page/page.html | 22 +- sca-cpp/trunk/modules/edit/htdocs/page/page.js | 165 ++++++--- .../edit/palettes/control/palette.composite | 10 +- .../edit/palettes/operators/palette.composite | 24 +- .../edit/palettes/sensors/palette.composite | 2 +- .../modules/edit/palettes/social/palette.composite | 10 +- .../edit/palettes/variables/palette.composite | 12 +- 23 files changed, 727 insertions(+), 209 deletions(-) create mode 100644 sca-cpp/trunk/modules/edit/htdocs/app/app.html create mode 100644 sca-cpp/trunk/modules/edit/htdocs/app/index.html (limited to 'sca-cpp/trunk/modules/edit') diff --git a/sca-cpp/trunk/modules/edit/Makefile.am b/sca-cpp/trunk/modules/edit/Makefile.am index 5b456ea4ca..2007507817 100644 --- a/sca-cpp/trunk/modules/edit/Makefile.am +++ b/sca-cpp/trunk/modules/edit/Makefile.am @@ -17,6 +17,6 @@ moddir = $(prefix)/modules/edit -nobase_dist_mod_DATA = htdocs/*.html htdocs/dash/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html -EXTRA_DIST = htdocs/*.html htdocs/dash/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html +nobase_dist_mod_DATA = htdocs/*.html htdocs/dash/*.html htdocs/app/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html +EXTRA_DIST = htdocs/*.html htdocs/dash/*.html htdocs/app/*.html htdocs/graph/*.html htdocs/graph/*.js htdocs/page/*.html htdocs/page/*.js htdocs/login/*.html htdocs/logout/*.html diff --git a/sca-cpp/trunk/modules/edit/apps/relay/app.composite b/sca-cpp/trunk/modules/edit/apps/relay/app.composite index 1e5015315c..2f630872de 100644 --- a/sca-cpp/trunk/modules/edit/apps/relay/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/relay/app.composite @@ -28,7 +28,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -48,7 +48,7 @@ - + @@ -58,7 +58,7 @@ - + @@ -68,7 +68,7 @@ - + diff --git a/sca-cpp/trunk/modules/edit/apps/store/app.composite b/sca-cpp/trunk/modules/edit/apps/store/app.composite index ec3fa32fa4..6f4bb9f43c 100644 --- a/sca-cpp/trunk/modules/edit/apps/store/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/store/app.composite @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + USD @@ -44,7 +44,7 @@ - + @@ -52,14 +52,14 @@ - + - + diff --git a/sca-cpp/trunk/modules/edit/apps/store2/app.composite b/sca-cpp/trunk/modules/edit/apps/store2/app.composite index afec3cb1d3..4a549b37c1 100644 --- a/sca-cpp/trunk/modules/edit/apps/store2/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/store2/app.composite @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + USD @@ -44,7 +44,7 @@ - + @@ -52,14 +52,14 @@ - + - + diff --git a/sca-cpp/trunk/modules/edit/apps/store3/app.composite b/sca-cpp/trunk/modules/edit/apps/store3/app.composite index 7cba2c19e1..9ec440435e 100644 --- a/sca-cpp/trunk/modules/edit/apps/store3/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/store3/app.composite @@ -25,7 +25,7 @@ - + @@ -35,7 +35,7 @@ - + USD @@ -44,7 +44,7 @@ - + @@ -52,14 +52,14 @@ - + - + diff --git a/sca-cpp/trunk/modules/edit/apps/travel/app.composite b/sca-cpp/trunk/modules/edit/apps/travel/app.composite index 833944a855..b4cef31135 100644 --- a/sca-cpp/trunk/modules/edit/apps/travel/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/travel/app.composite @@ -24,7 +24,7 @@ - + @@ -80,7 +80,7 @@ - + @@ -92,7 +92,7 @@ - + - + @@ -170,7 +170,7 @@ - + @@ -191,7 +191,7 @@ - + @@ -220,19 +220,19 @@ - + - + - + - + diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/app.html b/sca-cpp/trunk/modules/edit/htdocs/app/app.html new file mode 100644 index 0000000000..a2cf0e1f60 --- /dev/null +++ b/sca-cpp/trunk/modules/edit/htdocs/app/app.html @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + +
App Listing Information
+
+
+ +
+
+ + + +
App Title:
+
+
+ + + + diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/index.html b/sca-cpp/trunk/modules/edit/htdocs/app/index.html new file mode 100644 index 0000000000..ee07b5d4b7 --- /dev/null +++ b/sca-cpp/trunk/modules/edit/htdocs/app/index.html @@ -0,0 +1,66 @@ + + + +App Editor + + + + + + + + + + +
+

+
+ +
+ + + + + diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html index 71f9c61c41..29de0e396a 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html +++ b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html @@ -85,7 +85,8 @@ function getapps(sync) { title = car(entry); apps += ''; - apps += '' + '' + name + ''; + //apps += '' + '' + name + ''; + apps += '' + name + ''; apps += '' + title + ''; apps += ''; } diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html index 3b3dcc0cd5..60aafcd12e 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html @@ -34,9 +34,10 @@
diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html index 5eb8c6cc1e..b078901a29 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html @@ -31,7 +31,7 @@ - +
PaletteApp
PaletteComposition
diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js index c391afaf23..dc5b48e76a 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js @@ -21,12 +21,12 @@ * SVG and VML composite rendering functions. */ -var graph = new Object(); +var graph = {}; /** * Basic colors */ -graph.colors = new Object(); +graph.colors = {}; graph.colors.black = '#000000'; graph.colors.blue = '#0000ff'; graph.colors.cyan = '#00ffff'; @@ -40,6 +40,13 @@ graph.colors.red = '#ff0000'; graph.colors.white = '#ffffff'; graph.colors.yellow = '#ffff00'; +graph.colors.orange1 = '#ffbb00'; +graph.colors.green1 = '#96d333'; +graph.colors.blue1 = '#00c3c9'; +graph.colors.red1 = '#d03f41'; +graph.colors.yellow1 = '#fcee21'; +graph.colors.magenta1 = '#c0688a'; + /** * Base path class. */ @@ -92,21 +99,31 @@ if (ui.isIE()) { document.write(''); /** - * Make a graph. + * Make a VML graph. */ - graph.mkgraph = function() { + graph.mkgraph = function(pos) { + + // Create div element to host the graph var div = document.createElement('div'); div.id = 'vmldiv'; + div.style.position = 'absolute'; + div.style.left = pos.xpos(); + div.style.top = pos.ypos(); document.body.appendChild(div); + // Create a VML group var vmlg = document.createElement('v:group'); vmlg.style.width = 5000; vmlg.style.height = 5000; vmlg.coordsize = '5000,5000'; div.appendChild(vmlg); + // Keep track of the current dragged element graph.dragging = null; + /** + * Find the first draggable element in a hierarchy of elements. + */ function draggable(n) { if (n == vmlg) return null; @@ -115,53 +132,99 @@ if (ui.isIE()) { return draggable(n.parentNode); } - function bringtotop(n) { - if (n == vmlg) - return null; - n.parentNode.appendChild(n); - return bringtotop(n.parentNode); - } - + /** + * Handle a mousedown event. + */ vmlg.onmousedown = function() { window.event.returnValue = false; + + // Find draggable element graph.dragging = draggable(window.event.srcElement); if (graph.dragging == null) return false; - bringtotop(graph.dragging); + + // Bring it to the top + graph.bringtotop(graph.dragging, vmlg); + + // Remember mouse position graph.dragX = window.event.clientX; graph.dragY = window.event.clientY; vmlg.setCapture(); return false; }; + /** + * Handle a mouseup event. + */ vmlg.onmouseup = function() { if (graph.dragging == null) return false; + + if (graph.dragging.parentNode == vmlg && graph.dragging.id.substring(0, 8) != 'palette:') { + if (ui.csspos(graph.dragging.style.left) >= 350) { + + // Add dragged component to the edited composite + if (!isNil(graph.dragging.comp) && isNil(graph.dragging.compos)) { + var compos = scdl.composite(vmlg.compos); + setlist(compos, graph.addcomp(graph.dragging.comp, compos)); + graph.dragging.compos = vmlg.compos; + } + } else { + + // Discard top level element dragged out of composite area + vmlg.removeChild(graph.dragging); + if (!isNil(graph.dragging.comp) && !isNil(graph.dragging.compos)) { + var compos = scdl.composite(vmlg.compos); + setlist(compos, graph.removecomp(graph.dragging.comp, compos)); + graph.dragging.compos = vmlg.compos; + } + } + } + + // Forget current dragged element graph.dragging = null; vmlg.releaseCapture(); return false; }; + /** + * Handle a mousemove event. + */ vmlg.onmousemove = function() { if (graph.dragging == null) return false; - var origX = graph.dragging.coordorigin.X; - var origY = graph.dragging.coordorigin.Y; - var newX = origX - (window.event.clientX - graph.dragX); - var newY = origY - (window.event.clientY - graph.dragY); - graph.dragX = window.event.clientX; - graph.dragY = window.event.clientY; - if (graph.dragging.id.substring(0, 8) == 'palette:') { - // Clone an element dragged from the palette - var clone = graph.compshape(graph.dragging.comp, mklist(), graph.mkpath().move(ui.posn(graph.dragging.style.left), ui.posn(graph.dragging.style.top))); - graph.dragging.parentNode.appendChild(clone); - graph.dragging = clone; - } - graph.dragging.setAttribute('coordorigin', newX + ' ' + newY); + // Calculate new position of dragged element + var origX = ui.csspos(graph.dragging.style.left); + var origY = ui.csspos(graph.dragging.style.top); + var newX = origX + (window.event.clientX - graph.dragX); + var newY = origY + (window.event.clientY - graph.dragY); + if (newX >= 0) + graph.dragX = window.event.clientX; + else + newX = 0; + if (newY >= 0) + graph.dragY = window.event.clientY; + else + newY = 0; + + // Clone an element dragged from the palette + if (graph.dragging.id.substring(0, 8) == 'palette:') + graph.dragging = graph.clonepalette(graph.dragging); + + // Move the dragged element + graph.dragging.style.left = newX; + graph.dragging.style.top = newY; + + // Update dragged component position + if (!isNil(graph.dragging.comp)) + setlist(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.mkpath().move(newX, newY))); + return false; }; + // Create hidden spans to help compute the width of + // component and reference titles graph.comptitlewidthdiv = document.createElement('span'); graph.comptitlewidthdiv.style.visibility = 'hidden' graph.comptitlewidthdiv.style.fontWeight = 'bold' @@ -268,10 +331,14 @@ if (ui.isIE()) { * Return a shape representing a component. */ graph.compshape = function(comp, cassoc, pos) { + + // Make the component title element var title = graph.comptitle(comp); + // Compute the component shape path var d = graph.comppath(comp, cassoc).str(); + // Create the main component shape var shape = document.createElement('v:shape'); shape.style.width = 5000; shape.style.height = 5000; @@ -280,6 +347,7 @@ if (ui.isIE()) { shape.fillcolor = graph.color(comp); shape.stroked = 'false'; + // Create an overlay contour shape var contour = document.createElement('v:shape'); contour.style.width = 5000; contour.style.height = 5000; @@ -294,6 +362,7 @@ if (ui.isIE()) { stroke.opacity = '20%'; contour.appendChild(stroke); + // Create a group and add the component and contour shapes to it var g = document.createElement('v:group'); g.id = scdl.name(comp); g.style.width = 5000; @@ -325,17 +394,23 @@ if (ui.isIE()) { * Return a shape representing a button. */ graph.mkbutton = function(t, pos) { + + // Make the title element var title = graph.mktitle(t, true, pos); + + // Compute the path of the button shape var d = graph.buttonpath().str(); + // Create the main button shape var shape = document.createElement('v:shape'); shape.style.width = 5000; shape.style.height = 5000; shape.coordsize = '5000,5000'; shape.path = d; - shape.fillcolor = graph.colors.blue; + shape.fillcolor = graph.colors.blue1; shape.stroked = 'false'; + // Create an overlay contour shape var contour = document.createElement('v:shape'); contour.style.width = 5000; contour.style.height = 5000; @@ -350,6 +425,7 @@ if (ui.isIE()) { stroke.opacity = '20%'; contour.appendChild(stroke); + // Create a group and add the button and contour shapes to it var g = document.createElement('v:group'); g.style.width = 5000; g.style.height = 5000; @@ -370,9 +446,11 @@ if (ui.isIE()) { graph.svgns='http://www.w3.org/2000/svg'; /** - * Make a graph. + * Make an SVG graph. */ graph.mkgraph = function(pos) { + + // Create a div element to host the graph var div = document.createElement('div'); div.id = 'svgdiv'; div.style.position = 'absolute'; @@ -381,13 +459,18 @@ if (ui.isIE()) { // -webkit-user-select: none; document.body.appendChild(div); + // Create SVG element var svg = document.createElementNS(graph.svgns, 'svg'); svg.style.height = 5000; svg.style.width = 5000; div.appendChild(svg); + // Keep track of current dragged element graph.dragging = null; + /** + * Find the first draggable element in a hierarchy of elements. + */ function draggable(n) { if (n == svg) return null; @@ -396,37 +479,70 @@ if (ui.isIE()) { return draggable(n.parentNode); } - function bringtotop(n) { - if (n == svg) - return null; - n.parentNode.appendChild(n); - return bringtotop(n.parentNode); - } - + /** + * Handle a mouse down event. + */ svg.onmousedown = function(e) { if (e.preventDefault) e.preventDefault(); else e.returnValue = false; + + // Find draggable element graph.dragging = draggable(e.target); if (graph.dragging == null) return false; - bringtotop(graph.dragging); + + // Bring it to the top + graph.bringtotop(graph.dragging, svg); + + // Remember the mouse position var pos = typeof e.touches != "undefined" ? e.touches[0] : e; graph.dragX = pos.screenX; graph.dragY = pos.screenY; return false; }; + // Support touch devices svg.ontouchstart = svg.onmousedown; + /** + * Handle a mouse up event. + */ window.onmouseup = function(e) { if (graph.dragging == null) return false; + + if (graph.dragging.parentNode == svg && graph.dragging.id.substring(0, 8) != 'palette:') { + var pmatrix = graph.dragging.parentNode.getCTM(); + var matrix = graph.dragging.getCTM(); + var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e); + if (curX >= 350) { + + // Add dragged component to the edited composite + if (!isNil(graph.dragging.comp) && isNil(graph.dragging.compos)) { + var compos = scdl.composite(svg.compos); + setlist(compos, graph.addcomp(graph.dragging.comp, compos)); + graph.dragging.compos = svg.compos; + } + } else { + + // Discard top level element dragged out of composite area + svg.removeChild(graph.dragging); + if (!isNil(graph.dragging.comp) && !isNil(graph.dragging.compos)) { + var compos = scdl.composite(svg.compos); + setlist(compos, graph.removecomp(graph.dragging.comp, compos)); + graph.dragging.compos = svg.compos; + } + } + } + + // Forget current dragged element graph.dragging = null; return false; }; + // Support touch devices window.top.onmouseup = window.onmouseup; window.ontouchend = window.onmouseup; window.gestureend = window.onmouseup; @@ -435,6 +551,9 @@ if (ui.isIE()) { window.ontouchcancel = window.onmouseup; window.top.ontouchcancel = window.onmouseup; + /** + * Handle a mouse move event. + */ window.onmousemove = function(e) { if (graph.dragging == null) return false; @@ -442,6 +561,8 @@ if (ui.isIE()) { e.preventDefault(); else e.returnValue = false; + + // Calculate new position of dragged element var pmatrix = graph.dragging.parentNode.getCTM(); var matrix = graph.dragging.getCTM(); var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e); @@ -458,20 +579,27 @@ if (ui.isIE()) { else newY = 0; - if (graph.dragging.id.substring(0, 8) == 'palette:') { - // Clone an element dragged from the palette - var clone = graph.compshape(graph.dragging.comp, mklist(), graph.mkpath()); - graph.dragging.parentNode.appendChild(clone); - graph.dragging = clone; - } + // Clone an element dragged from the palette + if (graph.dragging.id.substring(0, 8) == 'palette:') + graph.dragging = graph.clonepalette(graph.dragging); + + // Move the dragged element graph.dragging.setAttribute('transform', 'translate(' + newX + ',' + newY + ')'); + + // Update dragged component position + if (!isNil(graph.dragging.comp)) + setlist(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.mkpath().move(newX, newY))); + return false; }; + // Support touch devices window.top.onmousemove = window.onmousemove; window.ontouchmove = window.onmousemove; window.top.ontouchmove = window.onmousemove; + // Create a hidden SVG element to help compute the width + // of component and reference titles graph.titlewidthsvg = document.createElementNS(graph.svgns, 'svg'); graph.titlewidthsvg.style.visibility = 'hidden'; graph.titlewidthsvg.style.height = 0; @@ -571,14 +699,19 @@ if (ui.isIE()) { * Return a shape representing a component. */ graph.compshape = function(comp, cassoc, pos) { + + // Make the component title var title = graph.comptitle(comp); + // Compute the path of the component shape var d = graph.comppath(comp, cassoc).str(); + // Create the main component shape var shape = document.createElementNS(graph.svgns, 'path'); shape.setAttribute('d', d); shape.setAttribute('fill', graph.color(comp)); + // Create an overlay contour shape var contour = document.createElementNS(graph.svgns, 'path'); contour.setAttribute('d', d); contour.setAttribute('fill', 'none'); @@ -587,6 +720,7 @@ if (ui.isIE()) { contour.setAttribute('stroke-opacity', '0.20'); contour.setAttribute('transform', 'translate(1,1)'); + // Create a group and add the component and contour shapes to it. var g = document.createElementNS(graph.svgns, 'g'); g.id = scdl.name(comp); g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')'); @@ -613,13 +747,19 @@ if (ui.isIE()) { * Return a shape representing a button. */ graph.mkbutton = function(t, pos) { + + // Make the button title var title = graph.mktitle(t, true); + + // Compute the path of the button shape var d = graph.buttonpath().str(); + // Create the main button shape var shape = document.createElementNS(graph.svgns, 'path'); shape.setAttribute('d', d); - shape.setAttribute('fill', graph.colors.blue); + shape.setAttribute('fill', graph.colors.blue1); + // Create an overlay contour shape var contour = document.createElementNS(graph.svgns, 'path'); contour.setAttribute('d', d); contour.setAttribute('fill', 'none'); @@ -628,6 +768,7 @@ if (ui.isIE()) { contour.setAttribute('stroke-opacity', '0.20'); contour.setAttribute('transform', 'translate(1,1)'); + // Create a group and add the button and contour shapes to it var g = document.createElementNS(graph.svgns, 'g'); g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')'); g.appendChild(shape); @@ -637,6 +778,16 @@ if (ui.isIE()) { }; } +/** + * Bring an element and its parents to the top. + */ +graph.bringtotop = function(n, g) { + if (n == g) + return null; + n.parentNode.appendChild(n); + return graph.bringtotop(n.parentNode, g); +} + /** * Return the title of a SCDL element. */ @@ -646,7 +797,17 @@ graph.title = function(e) { }; /** - * Return the services and references of a component. + * Return the color of a component. + */ +graph.color = function(comp) { + return memo(comp, 'color', function() { + var c = scdl.color(comp); + return c == null? graph.colors.blue1 : graph.colors[c]; + }); +}; + +/** + * Return the services on the top side of a component. */ graph.tsvcs = function(comp) { return memo(comp, 'tsvcs', function() { @@ -658,6 +819,9 @@ graph.tsvcs = function(comp) { }); }; +/** + * Return the services on the left side of a component. + */ graph.lsvcs = function(comp) { return memo(comp, 'lsvcs', function() { var svcs = scdl.services(comp); @@ -676,28 +840,24 @@ graph.lsvcs = function(comp) { }); }; +/** + * Return the references on the bottom side of a component. + */ graph.brefs = function(comp) { return memo(comp, 'brefs', function() { return filter(function(r) { return scdl.align(r) == 'bottom'; }, scdl.references(comp)); }); }; +/** + * Return the references on the right side of a component. + */ graph.rrefs = function(comp) { return memo(comp, 'rrefs', function() { return filter(function(r) { var a = scdl.align(r); return a == null || a == 'right'; }, scdl.references(comp)); }); }; -/** - * Return the color of a component. - */ -graph.color = function(comp) { - return memo(comp, 'color', function() { - var c = scdl.color(comp); - return c == null? graph.colors.blue : graph.colors[c]; - }); -}; - /** * Return the height of a reference on the right side of a component. */ @@ -861,33 +1021,43 @@ graph.tsvcpath = function(svc, cassoc, path) { * Return a path representing a component. */ graph.comppath = function(comp, cassoc) { - var height = graph.compheight(comp, cassoc); + + // Calculate the width and height of the component shape var width = graph.compwidth(comp, cassoc); + var height = graph.compheight(comp, cassoc); + /** + * Apply a path rendering function to a list of services or references. + */ function renderpath(x, f, cassoc, path) { if (isNil(x)) return path; return renderpath(cdr(x), f, cassoc, f(car(x), cassoc, path)); } + // Render the services on the top side of the component var tsvcs = graph.tsvcs(comp); var path = graph.mkpath().move(10,0); path = renderpath(tsvcs, graph.tsvcpath, cassoc, path); + // Render the references on the right side of the component var rrefs = graph.rrefs(comp); path = path.line(width - 10,path.ypos()).rcurve(10,0,0,10); path = renderpath(rrefs, graph.rrefpath, cassoc, path); + // Render the references on the bottom side of the component var brefs = reverse(graph.brefs(comp)); var boffset = 10 + graph.brefswidth(brefs, cassoc); path = path.line(path.xpos(),height - 10).rcurve(0,10,-10,0).line(boffset, path.ypos()); path = renderpath(brefs, graph.brefpath, cassoc, path); + // Render the services on the top side of the component var lsvcs = graph.lsvcs(comp); var loffset = 10 + (length(lsvcs) * 60); path = path.line(10,path.ypos()).rcurve(-10,0,0,-10).line(path.xpos(), loffset); path = renderpath(lsvcs, graph.lsvcpath, cassoc, path); + // Close the component shape path path = path.line(0,10).rcurve(0,-10,10,0); return path.end(); }; @@ -915,15 +1085,31 @@ graph.composite = function(compos, pos) { var cassoc = scdl.nameToElementAssoc(comps); var proms = scdl.promotions(compos); + /** + * Render a component. + */ function rendercomp(comp, cassoc, pos) { + + /** + * Render the references on the right side of a component. + */ function renderrrefs(refs, cassoc, pos) { + + /** + * Render a reference on the right side of a component. + */ function renderrref(ref, cassoc, pos) { var target = assoc(scdl.target(ref), cassoc); if (isNil(target)) return mklist(); + + // Render the component target of the reference return rendercomp(cadr(target), cassoc, pos); } + /** + * Move the rendering cursor down below a reference. + */ function rendermove(ref, cassoc, pos) { return pos.clone().rmove(0, graph.rrefheight(ref, cassoc)); } @@ -933,14 +1119,26 @@ graph.composite = function(compos, pos) { return append(renderrref(car(refs), cassoc, pos), renderrrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos))); } + /** + * Render the references on the bottom side of a component. + */ function renderbrefs(refs, cassoc, pos) { + + /** + * Render a reference on the bottom side of a component. + */ function renderbref(ref, cassoc, pos) { var target = assoc(scdl.target(ref), cassoc); if (isNil(target)) return mklist(); + + // Render the component target of the reference return rendercomp(cadr(target), cassoc, pos); } + /** + * Move the rendering cursor to the right of a reference. + */ function rendermove(ref, cassoc, pos) { return pos.clone().rmove(graph.brefwidth(ref, cassoc), 0); } @@ -950,8 +1148,11 @@ graph.composite = function(compos, pos) { return append(renderbref(car(refs), cassoc, pos), renderbrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos))); } + // Compute the component shape var gcomp = graph.compshape(comp, cassoc, pos); + // Add the shapes of the components wired to its references + // as children elements var rrefs = graph.rrefs(comp); var rpos = graph.mkpath().rmove(graph.compwidth(comp, cassoc), 0); appendNodes(renderrrefs(rrefs, cassoc, rpos), gcomp); @@ -963,7 +1164,14 @@ graph.composite = function(compos, pos) { return mklist(gcomp); } + /** + * Render a list of promoted service components. + */ function renderproms(svcs, cassoc, pos) { + + /** + * Return the component promoted by a service. + */ function promcomp(svc, cassoc) { var c = assoc(scdl.promote(svc), cassoc); if (isNil(c)) @@ -971,12 +1179,18 @@ graph.composite = function(compos, pos) { return cadr(c); } + /** + * Return the position of a component. + */ function comppos(comp, pos) { var x = scdl.x(comp); var y = scdl.y(comp); - return graph.mkpath().move(x != null? x : pos.xpos(), y != null? y : pos.ypos()); + return graph.mkpath().move(x != null? Number(x) + 350 : pos.xpos(), y != null? Number(y) : pos.ypos()); } + /** + * Move the rendering cursor down below a component. + */ function rendermove(comp, cassoc, pos) { return pos.clone().rmove(0, graph.compclosureheight(comp, cassoc) + 40); } @@ -984,6 +1198,8 @@ graph.composite = function(compos, pos) { if (isNil(svcs)) return mklist(); + // Render the first promoted component in the list + // then recurse to render the rest of the list var comp = promcomp(car(svcs), cassoc); if (isNil(comp)) return renderproms(cdr(svcs), cassoc, rendermove(car(svcs), cassoc, pos)); @@ -992,13 +1208,85 @@ graph.composite = function(compos, pos) { return append(rendercomp(comp, cassoc, cpos), renderproms(cdr(svcs), cassoc, rendermove(comp, cassoc, cpos))); } + // Render the promoted service components var rproms = renderproms(proms, cassoc, pos.clone().rmove(20,20)); - if (name == 'palette') + if (name == 'palette') { + + // Prefix ids of palette component elements with 'palette:' return map(function(r) { r.id = 'palette:' + r.id; return r; }, rproms); + } else { + + // Link app component elements to the containing composite + return map(function(r) { + r.compos = compos; + return r; + }, rproms); + } return rproms; }; +/** + * Clone a palette element and the component associated with it. + */ +graph.clones = 0; +graph.clonepalette = function(e) { + + // Clone the component and give it a unique name + var comp = append(mklist(element, "'component", mklist(attribute, "'name", scdl.name(e.comp) + (++graph.clones))), + filter(function(c) { return !(isAttribute(c) && attributeName(c) == "'name")}, elementChildren(e.comp))); + + // Make the component shape element + var clone = graph.compshape(comp, mklist(), graph.mkpath()); + e.parentNode.appendChild(clone); + return clone; +}; + +/** + * Move a component to the given position. + */ +graph.movecomp = function(comp, pos) { + + // Add or set the x and y attributes of the component + return append(mklist(element, "'component", mklist(attribute, "'t:x", '' + (pos.xpos() - 350)), mklist(attribute, "'t:y", '' + pos.ypos())), + filter(function(e) { return !(isAttribute(e) && (attributeName(e) == "'t:x" || attributeName(e) == "'t:y")); }, elementChildren(comp))); +}; + +/** + * Add a component to a composite. + */ +graph.addcomp = function(comp, compos) { + var name = scdl.name(comp); + var prom = mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name)); + return append(mklist(element, "'composite"), append(elementChildren(compos), mklist(prom, graph.dragging.comp))); +} + +/** + * Remove a component from a composite. + */ +graph.removecomp = function(comp, compos) { + var name = scdl.name(comp); + return append(mklist(element, "'composite"), + filter(function(c) { return !(isElement(c) && scdl.name(c) == name); }, elementChildren(compos))); +} + +/** + * Display a list of graphical nodes. + */ +graph.display = function(nodes, g) { + appendNodes(nodes, g); + return nodes; +}; + +/** + * Display and enable editing of a composite and the graphical + * nodes that represent it. + */ +graph.edit = function(compos, nodes, g) { + g.compos = compos; + return graph.display(nodes, g); +}; + diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html index aebc0ece68..e1f0bacdeb 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html @@ -18,7 +18,7 @@ --> -App Editor +App Composition Editor @@ -37,14 +37,12 @@ diff --git a/sca-cpp/trunk/modules/edit/htdocs/index.html b/sca-cpp/trunk/modules/edit/htdocs/index.html index 4dde5b543d..d0736ba295 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/index.html @@ -37,10 +37,13 @@

Try the App Dashboard to manage your collection of apps.

App Editor

-

Try the App Editor to edit an app.

+

Try the App Editor to edit an app.

+ +

Composition Editor

+

Try the Composition Editor to compose an app.

Page Editor

-

Try the Page Editor to edit an app page.

+

Try the Page Editor to draw an app page.

diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/index.html b/sca-cpp/trunk/modules/edit/htdocs/page/index.html index 92f286fdc6..5f9d93efed 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html @@ -37,14 +37,12 @@ diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.html b/sca-cpp/trunk/modules/edit/htdocs/page/page.html index e2cd50088e..202fb7aacc 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.html @@ -57,11 +57,9 @@ var editWidget = sca.component("EditWidget"); var pages = sca.reference(editWidget, "pages"); /** - * Return the current app name. + * The current app name. */ -function appname() { - return ui.queryParams()['app']; -} +var appname = ui.queryParams()['app']; /** * Return the page in an ATOM entry. @@ -79,6 +77,7 @@ function getpage(name, edit) { if (isNil(name)) return; pages.get(name, function(doc) { + // Convert the page to XHTML var xhtml = writeStrings(writeXML(atompage(doc), false)); @@ -88,7 +87,7 @@ function getpage(name, edit) { // Append page nodes to editor map(function(e) { - e.style.left = ui.posn(e.style.left) + 350; + e.style.left = ui.csspos(e.style.left) + 350; edit.appendChild(e); return page.cover(e); }, nodeList(buffer.childNodes[0].childNodes)); @@ -99,6 +98,7 @@ function getpage(name, edit) { * Save the current edited page. */ $('saveButton').onclick = function(e) { + // Copy page DOM to hidden buffer var edit = $('page'); var buffer = $('buffer'); @@ -114,8 +114,8 @@ $('saveButton').onclick = function(e) { div.removeChild(e); return e; } - var x = ui.posn(e.style.left) - 350; - if (x < 0 || ui.posn(e.style.top) < 0) { + var x = ui.csspos(e.style.left) - 350; + if (x < 0 || ui.csspos(e.style.top) < 0) { div.removeChild(e); return e; } @@ -128,11 +128,11 @@ $('saveButton').onclick = function(e) { var xhtml = writeStrings(writeXML(lxhtml, false)); // Update the page ATOM entry - var name = appname(); - var entry = '' + name + '' + name + '' + + var entry = '' + + '' + appname + '' + appname + '' + xhtml + ''; - pages.put(name, entry, function(e) {}); + pages.put(appname, entry, function(e) {}); }; // Initialize the page editor @@ -140,7 +140,7 @@ var edit = $('page'); page.initpage(edit); // Get and display the current app page -getpage(appname(), edit); +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 25f6399075..4628ec1235 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.js +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js @@ -20,56 +20,66 @@ /** * Page editing functions. */ -var page = new Object(); +var page = {}; if (ui.isIE()) { /** - * Init a page editor. + * Init a page editor. IE-specific implementation. */ page.initpage = function(elem) { - page.dragging = null; - function draggable(n) { - if (n == elem) - return null; - if (n.id != '') - return n; - if (n.covered) - return n.covered; - return draggable(n.parentNode); - } - - function bringtotop(n) { - n.parentNode.appendChild(n); - n.cover.parentNode.appendChild(n.cover); - } + // Keep track of the current dragged element + page.dragging = null; + /** + * Handle a mouse down event. + */ elem.onmousedown = function() { window.event.returnValue = false; - page.dragging = draggable(window.event.srcElement); + + // Find a draggable element + page.dragging = page.draggable(window.event.srcElement, elem); if (page.dragging == null) return false; - bringtotop(page.dragging); + + // Bring it to the top + page.bringtotop(page.dragging); + + // Save the mouse position page.dragX = window.event.clientX; page.dragY = window.event.clientY; elem.setCapture(); return false; }; + /** + * Handle a mouse up event. + */ elem.onmouseup = function() { if (page.dragging == null) 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); + + // Forget current dragged element page.dragging = null; elem.releaseCapture(); return false; }; + /** + * Handle a mouse move event. + */ elem.onmousemove = function() { if (page.dragging == null) return false; - var curX = ui.posn(page.dragging.style.left); - var curY = ui.posn(page.dragging.style.top); + + // Compute dragged element position + var curX = ui.csspos(page.dragging.style.left); + var curY = ui.csspos(page.dragging.style.top); var newX = curX + (window.event.clientX - page.dragX); var newY = curY + (window.event.clientY - page.dragY); if (newX >= 0) @@ -81,10 +91,11 @@ if (ui.isIE()) { else newY = 0; - if (page.dragging.id.substring(0, 8) == 'palette:') { - // Clone the dragged element + // 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; @@ -92,7 +103,8 @@ if (ui.isIE()) { }; - // Cover child elements with span elements + // Cover child elements with span elements to prevent + // any input events to reach them map(page.cover, nodeList(elem.childNodes)); return elem; @@ -101,59 +113,69 @@ if (ui.isIE()) { } else { /** - * Init a page editor. + * Init a page editor. Generic implementation for all other browsers. */ page.initpage = function(elem) { page.dragging = null; - function draggable(n) { - if (n == elem) - return null; - if (n.id != '') - return n; - if (n.covered) - return n.covered; - return draggable(n.parentNode); - } - - function bringtotop(n) { - n.parentNode.appendChild(n); - n.cover.parentNode.appendChild(n.cover); - } - + /** + * Handle a mouse down event. + */ elem.onmousedown = function(e) { if (e.preventDefault) e.preventDefault(); else e.returnValue = false; - page.dragging = draggable(e.target); + + // Find a draggable element + page.dragging = page.draggable(e.target, elem); if (page.dragging == null) return false; - bringtotop(page.dragging); + + // Bring it to the top + page.bringtotop(page.dragging); + + // Remember mouse position var pos = typeof e.touches != "undefined" ? e.touches[0] : e; page.dragX = pos.screenX; page.dragY = pos.screenY; return false; }; + // Support touch devices elem.ontouchstart = elem.onmousedown; + /** + * Handle a mouse up event. + */ window.onmouseup = function(e) { 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); + + // Forget dragged element page.dragging = null; return false; }; + // Support touch devices window.top.onmouseup = window.onmouseup; window.ontouchend = window.onmouseup; window.top.ontouchend = window.onmouseup; + /** + * Handle a mouse move event. + */ window.onmousemove = function(e) { if (page.dragging == null) return false; - var curX = ui.posn(page.dragging.style.left); - var curY = ui.posn(page.dragging.style.top); + + // Compute position of dragged element + var curX = ui.csspos(page.dragging.style.left); + var curY = ui.csspos(page.dragging.style.top); var pos = typeof e.touches != "undefined" ? e.touches[0] : e; var newX = curX + (pos.screenX - page.dragX); var newY = curY + (pos.screenY - page.dragY); @@ -166,10 +188,12 @@ if (ui.isIE()) { else newY = 0; + // Clone element dragged from palette if (page.dragging.id.substring(0, 8) == 'palette:') { - // Clone the dragged element page.dragging = page.clone(page.dragging); } + + // Move the dragged element page.dragging.style.left = newX; page.dragging.style.top = newY; page.dragging.cover.style.left = newX; @@ -177,11 +201,13 @@ if (ui.isIE()) { return false; }; + // Support touch devices window.top.onmousemove = window.onmousemove; window.ontouchmove = window.onmousemove; window.top.ontouchmove = window.onmousemove; - // Cover child elements with span elements + // Cover child elements with span elements to prevent + // any input events to reach them map(page.cover, nodeList(elem.childNodes)); return elem; @@ -189,15 +215,37 @@ if (ui.isIE()) { } /** - * Cover a page element with a element to prevent mouse events to reach it. + * Find a draggable element in a hierarchy of elements. + */ +page.draggable = function(n, e) { + if (n == e) + return null; + if (n.id != '') + return n; + if (n.covered) + return n.covered; + return page.draggable(n.parentNode, e); +} + +/** + * Bring an element and its parent to the top. + */ +page.bringtotop = function(n) { + n.parentNode.appendChild(n); + n.cover.parentNode.appendChild(n.cover); +} + +/** + * Cover a page element with a element to prevent + * any input events to reach it. */ page.cover = function(e) { if (e.id == '' || isNil(e.style)) return e; var cover = document.createElement('span'); cover.style.position = 'absolute'; - cover.style.left = ui.posn(e.style.left) - 5; - cover.style.top = ui.posn(e.style.top) - 5; + cover.style.left = ui.csspos(e.style.left) - 5; + cover.style.top = ui.csspos(e.style.top) - 5; cover.style.width = e.clientWidth + 10; cover.style.height = e.clientHeight + 10; cover.style.visibility = 'visible'; @@ -208,20 +256,31 @@ page.cover = function(e) { } /** - * Clone a page element. + * Clone a palette element. */ page.clone = function(e) { + + /** + * Clone an element's HTML. + */ function mkclone(e) { var ne = document.createElement('span'); + + // Skip the palette: prefix ne.id = e.id.substr(8); + + // Copy the HTML content ne.innerHTML = e.innerHTML; return ne; } + /** + * Clone an element's position. + */ function posclone(ne, e) { ne.style.position = 'absolute'; - ne.style.left = ui.posn(e.style.left); - ne.style.top = ui.posn(e.style.top); + ne.style.left = ui.csspos(e.style.left); + ne.style.top = ui.csspos(e.style.top); e.parentNode.appendChild(ne); page.cover(ne); return ne; diff --git a/sca-cpp/trunk/modules/edit/palettes/control/palette.composite b/sca-cpp/trunk/modules/edit/palettes/control/palette.composite index 56c50a4e48..acb1c15755 100644 --- a/sca-cpp/trunk/modules/edit/palettes/control/palette.composite +++ b/sca-cpp/trunk/modules/edit/palettes/control/palette.composite @@ -28,7 +28,7 @@ - + when page requested @@ -36,7 +36,7 @@ - + every n seconds @@ -44,14 +44,14 @@ - + - + if else @@ -60,7 +60,7 @@ - + for each diff --git a/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite b/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite index 35f8dfdf9c..54fd47768a 100644 --- a/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite +++ b/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite @@ -35,37 +35,37 @@ - + - + - + - + - + - + = @@ -75,7 +75,7 @@ - + gt @@ -85,7 +85,7 @@ - + lt @@ -95,7 +95,7 @@ - + * @@ -105,7 +105,7 @@ - + / @@ -115,7 +115,7 @@ - + + @@ -125,7 +125,7 @@ - + - diff --git a/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite b/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite index 20ef8225ce..87381f24f4 100644 --- a/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite +++ b/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite @@ -24,7 +24,7 @@ - + diff --git a/sca-cpp/trunk/modules/edit/palettes/social/palette.composite b/sca-cpp/trunk/modules/edit/palettes/social/palette.composite index 264e2ed137..739b878025 100644 --- a/sca-cpp/trunk/modules/edit/palettes/social/palette.composite +++ b/sca-cpp/trunk/modules/edit/palettes/social/palette.composite @@ -28,7 +28,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -48,7 +48,7 @@ - + @@ -58,7 +58,7 @@ - + @@ -68,7 +68,7 @@ - + diff --git a/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite b/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite index 42fc43525b..1d10027f95 100644 --- a/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite +++ b/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite @@ -29,17 +29,17 @@ - + - + - + set variable @@ -47,7 +47,7 @@ - + make a list @@ -55,14 +55,14 @@ - + first of a list - + rest of a list -- cgit v1.2.3