summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/edit/htdocs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/app/app.html12
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/app/index.html17
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html16
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/dash/index.html11
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/graph/graph.html9
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/graph/graph.js479
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/graph/index.html19
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/index.html11
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/main.html7
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/page/index.html17
-rw-r--r--sca-cpp/trunk/modules/edit/htdocs/page/page.html9
11 files changed, 431 insertions, 176 deletions
diff --git a/sca-cpp/trunk/modules/edit/htdocs/app/app.html b/sca-cpp/trunk/modules/edit/htdocs/app/app.html
index a2cf0e1f60..7a6330102a 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/app/app.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/app/app.html
@@ -29,21 +29,24 @@
</head>
<body>
-<table style="position: absolute; top: 0px; left: 0px;" width="100%">
-<tr><th><span>App Listing Information</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>
+<div 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>
<br>
-<br>
<div>
<form id="appForm">
<table width="100%">
<tr><tr><td><b>App Title:</b></td></tr>
-<tr><td><input type="text" id="appTitle" size="20"/></td></tr>
+<tr><td><input type="text" id="appTitle" size="30"/></td></tr>
</table>
</form>
</div>
+</div>
+
<script type="text/javascript">
// Init service references
@@ -54,6 +57,7 @@ var dashboard = sca.reference(editWidget, "dashboard");
* The current app name.
*/
var appname = ui.queryParams()['app'];
+$('appname').innerHTML = 'App: ' + appname;
/**
* 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 f5f11137ec..f79229d17e 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/app/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/app/index.html
@@ -29,20 +29,18 @@
<body>
<div id="menu"></div>
-<br/>
-<h1><span id="title"></span></h1>
-</br>
-
-<div id="app"></div>
-
<script type="text/javascript">
-/**
- * The current app name.
- */
+
+// Get the app name
var appname = ui.queryParams()['app'];
// Load the menu bar
ui.loadwidget('menu', '/menu.html?app=' + appname);
+</script>
+
+<div id="app"></div>
+
+<script type="text/javascript">
/**
* Display the page editor for an app.
@@ -50,7 +48,6 @@ ui.loadwidget('menu', '/menu.html?app=' + appname);
function editapp(name) {
if (isNil(name))
return;
- $('title').innerHTML = 'Editing: ' + name;
ui.loadiframe('app', 'app.html?app=' + name);
}
diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html
index 0339f3fa76..5b5d758f31 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html
@@ -28,13 +28,12 @@
<script type="text/javascript" src="/component.js"></script>
</head>
<body>
-<div id="dashboard">
-<form id="appsForm">
+<div style="position: absolute; top: 0px; left: 0px; right: 0px;">
+
<div id="apps"></div>
<br/>
<input type="button" id="createAppButton" value="Create App"/>
-</form>
<div id="newApp" style="visibility: hidden;">
<form id="newAppForm">
@@ -48,10 +47,12 @@
<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>
-<tr><td><input type="text" id="appTitle" size="20"/></td></tr>
-</table>
+<tr><td><input type="text" id="appTitle" size="30"/></td></tr>
+<tr><td>
<input id="createAppOKButton" type="button" style="font-weight: bold;" value="Create"/>
<input id="createAppCancelButton" type="button" value="Cancel"/>
+</td></tr>
+</table>
</form>
</div>
@@ -67,8 +68,7 @@ var dashboard = sca.reference(editWidget, "dashboard");
*/
function getapps(sync) {
function display(doc) {
- var apps = '';
- apps += '<table width="100%">';
+ var apps = '<table width="100%">';
apps += '<tr><th>App</th><th>Title</th></tr>';
var entries = cddr(atom.readATOMFeedDocument(doc));
@@ -142,7 +142,7 @@ $('createAppCancelButton').onclick = function() {
*/
/*
$('deleteAppLink').onclick = function() {
- var apps = $('appsForm').apps;
+ var apps = $('apps');
if (isNil(apps))
return false;
if (isNil(apps.length))
diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html
index d84424e96e..d3add792d6 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html
@@ -29,14 +29,15 @@
<body>
<div id="menu"></div>
-<br/>
-<h1>Welcome to your App Dashboard!</h1>
-<br/>
-<div id="dashboard"></div>
-
<script type="text/javascript">
+
// Load the menu bar
ui.loadwidget('menu', '/menu.html');
+</script>
+
+<div id="dashboard"></div>
+
+<script type="text/javascript">
// Load the dashboard
ui.loadiframe('dashboard', 'dashboard.html');
diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html
index b078901a29..1572262627 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html
@@ -30,10 +30,14 @@
</head>
<body>
-<table style="position: absolute; top: 0px; left: 0px;" width="100%">
-<tr><th style="width: 338px;">Palette</th><th style="padding-top: 0px; padding-bottom: 0px;"><span>Composition</span><span style="position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr>
+<div 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>
+</div>
+
<script type="text/javascript">
var editWidget = sca.component("EditWidget");
var palettes = sca.reference(editWidget, "palettes");
@@ -46,6 +50,7 @@ var apps = sca.reference(editWidget, "apps");
* The current app name.
*/
var appname = ui.queryParams()['app'];
+$('appname').innerHTML = 'Composition: ' + appname;
/**
* The current app composite.
diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
index dc5b48e76a..8c0419c8bd 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
+++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js
@@ -143,7 +143,17 @@ if (ui.isIE()) {
if (graph.dragging == null)
return false;
- // Bring it to the top
+ // Clone component from the palette
+ if (graph.dragging.id.substring(0, 8) == 'palette:')
+ graph.dragging = graph.clonepalette(graph.dragging);
+
+ // Cut wire to component
+ if (graph.dragging.parentNode != vmlg) {
+ var compos = scdl.composite(vmlg.compos);
+ setElement(compos, graph.cutwire(graph.dragging, compos, vmlg));
+ }
+
+ // Bring component to the top
graph.bringtotop(graph.dragging, vmlg);
// Remember mouse position
@@ -161,29 +171,44 @@ if (ui.isIE()) {
return false;
if (graph.dragging.parentNode == vmlg && graph.dragging.id.substring(0, 8) != 'palette:') {
- if (ui.csspos(graph.dragging.style.left) >= 350) {
+ var gpos = graph.relpos(graph.dragging);
+ if (pos.xpos() >= 350) {
- // Add dragged component to the edited composite
- if (!isNil(graph.dragging.comp) && isNil(graph.dragging.compos)) {
+ // Add new dragged component to the composite
+ if (isNil(graph.dragging.compos)) {
var compos = scdl.composite(vmlg.compos);
- setlist(compos, graph.addcomp(graph.dragging.comp, compos));
+ setElement(compos, graph.addcomp(graph.dragging.comp, compos));
graph.dragging.compos = vmlg.compos;
}
+
+ // Update component position
+ setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, vmlg)));
+
+ // Wire component to neighboring reference
+ if (!isNil(graph.dragging.svcpos)) {
+ var compos = scdl.composite(vmlg.compos);
+ setElement(compos, graph.wire(graph.dragging, compos, vmlg));
+ }
+
} else {
- // Discard top level element dragged out of composite area
+ // Discard component dragged out of composite
vmlg.removeChild(graph.dragging);
- if (!isNil(graph.dragging.comp) && !isNil(graph.dragging.compos)) {
+ if (!isNil(graph.dragging.compos)) {
var compos = scdl.composite(vmlg.compos);
- setlist(compos, graph.removecomp(graph.dragging.comp, compos));
- graph.dragging.compos = vmlg.compos;
+ setElement(compos, graph.removecomp(graph.dragging.comp, compos));
}
}
}
- // Forget current dragged element
+ // Forget current dragged component
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);
+
return false;
};
@@ -195,10 +220,9 @@ if (ui.isIE()) {
return false;
// 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);
+ var gpos = graph.relpos(graph.dragging);
+ var newX = gpos.xpos() + (window.event.clientX - graph.dragX);
+ var newY = gpos.ypos() + (window.event.clientY - graph.dragY);
if (newX >= 0)
graph.dragX = window.event.clientX;
else
@@ -208,17 +232,8 @@ if (ui.isIE()) {
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)));
+ graph.move(graph.dragging, graph.mkpath().move(newX, newY));
return false;
};
@@ -328,15 +343,16 @@ if (ui.isIE()) {
};
/**
- * Return a shape representing a component.
+ * Return a node representing a component.
*/
- graph.compshape = function(comp, cassoc, pos) {
+ graph.compnode = 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();
+ var path = graph.comppath(comp, cassoc);
+ var d = path.str();
// Create the main component shape
var shape = document.createElement('v:shape');
@@ -352,7 +368,7 @@ if (ui.isIE()) {
contour.style.width = 5000;
contour.style.height = 5000;
contour.coordsize = '5000,5000';
- contour.setAttribute('path', d);
+ contour.path = d;
contour.filled = 'false';
contour.strokecolor = graph.colors.gray;
contour.strokeweight = '2';
@@ -374,8 +390,11 @@ if (ui.isIE()) {
shape.appendChild(title);
g.appendChild(contour)
- // Store the component in the shape
+ // 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;
return g;
};
@@ -391,7 +410,7 @@ if (ui.isIE()) {
};
/**
- * Return a shape representing a button.
+ * Return a node representing a button.
*/
graph.mkbutton = function(t, pos) {
@@ -399,14 +418,14 @@ if (ui.isIE()) {
var title = graph.mktitle(t, true, pos);
// Compute the path of the button shape
- var d = graph.buttonpath().str();
+ var path = 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.path = path;
shape.fillcolor = graph.colors.blue1;
shape.stroked = 'false';
@@ -415,7 +434,7 @@ if (ui.isIE()) {
contour.style.width = 5000;
contour.style.height = 5000;
contour.coordsize = '5000,5000';
- contour.setAttribute('path', d);
+ contour.path = path;
contour.filled = 'false';
contour.strokecolor = graph.colors.gray;
contour.strokeweight = '2';
@@ -438,6 +457,23 @@ if (ui.isIE()) {
return g;
};
+ /**
+ * Return the relative position of a node.
+ */
+ graph.relpos = function(e) {
+ var curX = ui.csspos(e.style.left);
+ var curY = ui.csspos(e.style.top);
+ return graph.mkpath().move(curX, curY);
+ };
+
+ /**
+ * Move a node.
+ */
+ graph.move = function(e, pos) {
+ e.style.left = pos.xpos();
+ e.style.top = pos.ypos();
+ };
+
} else {
/**
@@ -488,15 +524,25 @@ if (ui.isIE()) {
else
e.returnValue = false;
- // Find draggable element
+ // Find draggable component
graph.dragging = draggable(e.target);
if (graph.dragging == null)
return false;
- // Bring it to the top
+ // Clone component from the palette
+ if (graph.dragging.id.substring(0, 8) == 'palette:')
+ graph.dragging = graph.clonepalette(graph.dragging);
+
+ // Cut wire to component
+ if (graph.dragging.parentNode != svg) {
+ var compos = scdl.composite(svg.compos);
+ setElement(compos, graph.cutwire(graph.dragging, compos, svg));
+ }
+
+ // Bring component to the top
graph.bringtotop(graph.dragging, svg);
- // Remember the mouse position
+ // Remember current mouse position
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
graph.dragX = pos.screenX;
graph.dragY = pos.screenY;
@@ -514,31 +560,43 @@ if (ui.isIE()) {
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) {
+ var gpos = graph.relpos(graph.dragging);
+ if (gpos.xpos() >= 350) {
- // Add dragged component to the edited composite
- if (!isNil(graph.dragging.comp) && isNil(graph.dragging.compos)) {
+ // Add new dragged component to the composite
+ if (isNil(graph.dragging.compos)) {
var compos = scdl.composite(svg.compos);
- setlist(compos, graph.addcomp(graph.dragging.comp, compos));
+ setElement(compos, graph.addcomp(graph.dragging.comp, compos));
graph.dragging.compos = svg.compos;
}
+
+ // Update component position
+ setElement(graph.dragging.comp, graph.movecomp(graph.dragging.comp, graph.abspos(graph.dragging, svg)));
+
+ // Wire component to neighboring reference
+ if (!isNil(graph.dragging.svcpos)) {
+ var compos = scdl.composite(svg.compos);
+ setElement(compos, graph.wire(graph.dragging, compos, svg));
+ }
+
} else {
- // Discard top level element dragged out of composite area
+ // Discard component dragged out of composite
svg.removeChild(graph.dragging);
- if (!isNil(graph.dragging.comp) && !isNil(graph.dragging.compos)) {
+ if (!isNil(graph.dragging.compos)) {
var compos = scdl.composite(svg.compos);
- setlist(compos, graph.removecomp(graph.dragging.comp, compos));
- graph.dragging.compos = svg.compos;
+ setElement(compos, graph.removecomp(graph.dragging.comp, compos));
}
}
}
- // Forget current dragged element
+ // 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);
+
return false;
};
@@ -563,13 +621,10 @@ if (ui.isIE()) {
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);
- var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
+ var gpos = graph.relpos(graph.dragging);
var pos = typeof e.touches != "undefined" ? e.touches[0] : e;
- var newX = curX + (pos.screenX - graph.dragX);
- var newY = curY + (pos.screenY - graph.dragY);
+ var newX = gpos.xpos() + (pos.screenX - graph.dragX);
+ var newY = gpos.ypos() + (pos.screenY - graph.dragY);
if (newX >= 0)
graph.dragX = pos.screenX;
else
@@ -579,16 +634,8 @@ if (ui.isIE()) {
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.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)));
+ graph.move(graph.dragging, graph.mkpath().move(newX, newY));
return false;
};
@@ -610,7 +657,7 @@ if (ui.isIE()) {
};
/**
- * Make a shape path.
+ * Make a path.
*/
graph.mkpath = function() {
function Path() {
@@ -696,15 +743,16 @@ if (ui.isIE()) {
};
/**
- * Return a shape representing a component.
+ * Return a node representing a component.
*/
- graph.compshape = function(comp, cassoc, pos) {
+ graph.compnode = 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();
+ var path = graph.comppath(comp, cassoc);
+ var d = path.str();
// Create the main component shape
var shape = document.createElementNS(graph.svgns, 'path');
@@ -728,8 +776,11 @@ if (ui.isIE()) {
g.appendChild(contour);
g.appendChild(title);
- // Store the component in the shape.
+ // Store the component and the positions of its services
+ // and references in the component shape
g.comp = comp;
+ g.refpos = reverse(path.refpos);
+ g.svcpos = reverse(path.svcpos);
return g;
};
@@ -744,7 +795,7 @@ if (ui.isIE()) {
};
/**
- * Return a shape representing a button.
+ * Return a node representing a button.
*/
graph.mkbutton = function(t, pos) {
@@ -752,16 +803,16 @@ if (ui.isIE()) {
var title = graph.mktitle(t, true);
// Compute the path of the button shape
- var d = graph.buttonpath().str();
+ var path = graph.buttonpath().str();
// Create the main button shape
var shape = document.createElementNS(graph.svgns, 'path');
- shape.setAttribute('d', d);
+ shape.setAttribute('d', path);
shape.setAttribute('fill', graph.colors.blue1);
// Create an overlay contour shape
var contour = document.createElementNS(graph.svgns, 'path');
- contour.setAttribute('d', d);
+ contour.setAttribute('d', path);
contour.setAttribute('fill', 'none');
contour.setAttribute('stroke', graph.colors.gray);
contour.setAttribute('stroke-width', '4');
@@ -776,16 +827,45 @@ if (ui.isIE()) {
g.appendChild(title);
return g;
};
-}
+
+ /**
+ * Return the relative position of a node.
+ */
+ graph.relpos = function(e) {
+ var pmatrix = e.parentNode.getCTM();
+ var matrix = e.getCTM();
+ var curX = pmatrix != null? (Number(matrix.e) - Number(pmatrix.e)): Number(matrix.e);
+ var curY = pmatrix != null? (Number(matrix.f) - Number(pmatrix.f)): Number(matrix.f);
+ return graph.mkpath().move(curX, curY);
+ };
+
+ /**
+ * Move a node.
+ */
+ graph.move = function(e, pos) {
+ e.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')');
+ };
+};
+
+/**
+ * Return the absolute position of a component node.
+ */
+graph.abspos = function(e, g) {
+ if (e == g)
+ return graph.mkpath();
+ var gpos = graph.relpos(e);
+ var pgpos = graph.abspos(e.parentNode, g);
+ return graph.mkpath().move(gpos.xpos() + pgpos.xpos(), gpos.ypos() + pgpos.ypos());
+};
/**
- * Bring an element and its parents to the top.
+ * Bring a component node to the top.
*/
graph.bringtotop = function(n, g) {
if (n == g)
return null;
- n.parentNode.appendChild(n);
- return graph.bringtotop(n.parentNode, g);
+ graph.move(n, graph.abspos(n, g));
+ g.appendChild(n);
}
/**
@@ -797,7 +877,7 @@ graph.title = function(e) {
};
/**
- * Return the color of a component.
+ * Return the color of a SCDL component.
*/
graph.color = function(comp) {
return memo(comp, 'color', function() {
@@ -901,7 +981,7 @@ graph.brefsheight = function(refs, cassoc) {
};
/**
- * Return the height of a component.
+ * Return the height of a component node.
*/
graph.compheight = function(comp, cassoc) {
return memo(comp, 'height', function() {
@@ -986,7 +1066,13 @@ graph.compclosurewidth = function(comp, cassoc) {
*/
graph.rrefpath = function(ref, cassoc, path) {
var height = graph.rrefheight(ref, cassoc);
+
+ // Record reference position in the path
+ var xpos = path.xpos();
var ypos = path.ypos();
+ path.refpos = cons(mklist(ref, graph.mkpath().move(xpos, ypos + 30)), path.refpos);
+
+ // Compute the reference path
return path.rline(0,10).rline(0,10).rcurve(0,5,-5,0).rcurve(-5,0,0,-5).rcurve(0,-5,-5,0).rcurve(-5,0,0,5).rline(0,20).rcurve(0,5,5,0).rcurve(5,0,0,-5).rcurve(0,-5,5,0).rcurve(5,0,0,5).line(path.xpos(),ypos + height);
};
@@ -995,7 +1081,13 @@ graph.rrefpath = function(ref, cassoc, path) {
*/
graph.brefpath = function(ref, cassoc, path) {
var width = graph.brefwidth(ref, cassoc);
+
+ // Record reference position in the path
var xpos = path.xpos();
+ var ypos = path.ypos();
+ path.refpos = cons(mklist(ref, graph.mkpath().move(xpos - width + 30, ypos)), path.refpos);
+
+ // Compute the reference path
return path.line(xpos - width + 60,path.ypos()).rline(-10,0).rline(-10,0).rcurve(-5,0,0,-5).rcurve(0,-5,5,0).rcurve(5,0,0,-5).rcurve(0,-5,-5,0).rline(-20,0).rcurve(-5,0,0,5).rcurve(0,5,5,0).rcurve(5,0,0,5).rcurve(0,5,-5,0).line(xpos - width,path.ypos());
};
@@ -1004,7 +1096,13 @@ graph.brefpath = function(ref, cassoc, path) {
*/
graph.lsvcpath = function(svc, cassoc, path) {
var height = 60;
+
+ // Record service position in the path
+ var xpos = path.xpos();
var ypos = path.ypos();
+ path.svcpos = cons(mklist(svc, graph.mkpath().move(xpos, ypos - 30)), path.svcpos);
+
+ // Compute the service path
return path.rline(0,-10).rline(0, -10).rcurve(0,-5,-5,0).rcurve(-5,0,0,5).rcurve(0,5,-5,0).rcurve(-5,0,0,-5).rline(0,-20).rcurve(0,-5,5,0).rcurve(5,0,0,5).rcurve(0,5,5,0).rcurve(5,0,0,-5).line(path.xpos(), ypos - height);
};
@@ -1013,16 +1111,22 @@ graph.lsvcpath = function(svc, cassoc, path) {
*/
graph.tsvcpath = function(svc, cassoc, path) {
var width = 60;
+
+ // Record service position in the path
var xpos = path.xpos();
+ var ypos = path.ypos();
+ path.svcpos = cons(mklist(svc, graph.mkpath().move(xpos + 30, ypos)), path.svcpos);
+
+ // Compute the service path
return path.rline(10,0).rline(10,0).rcurve(5,0,0,-5).rcurve(0,-5,-5,0).rcurve(-5,0,0,-5).rcurve(0,-5,5,0).rline(20,0).rcurve(5,0,0,5).rcurve(0,5,-5,0).rcurve(-5,0,0,5).rcurve(0,5,5,0).line(xpos + width,path.ypos());
};
/**
- * Return a path representing a component.
+ * Return a path representing a component node.
*/
graph.comppath = function(comp, cassoc) {
- // Calculate the width and height of the component shape
+ // Calculate the width and height of the component node
var width = graph.compwidth(comp, cassoc);
var height = graph.compheight(comp, cassoc);
@@ -1035,9 +1139,14 @@ graph.comppath = function(comp, cassoc) {
return renderpath(cdr(x), f, cassoc, f(car(x), cassoc, path));
}
+ var path = graph.mkpath().move(10,0);
+
+ // Store the positions of services and references in the path
+ path.refpos = mklist();
+ path.svcpos = mklist();
+
// 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
@@ -1051,19 +1160,20 @@ graph.comppath = function(comp, 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
+ // Render the services on the left 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
+ // Close the component node path
path = path.line(0,10).rcurve(0,-10,10,0);
+
return path.end();
};
/**
- * Return a path representing a button.
+ * Return a path representing a button node.
*/
graph.buttonpath = function(t) {
var height = 60;
@@ -1077,7 +1187,7 @@ graph.buttonpath = function(t) {
};
/**
- * Render a composite.
+ * Render a SCDL composite into a list of component nodes.
*/
graph.composite = function(compos, pos) {
var name = scdl.name(scdl.composite(compos));
@@ -1093,15 +1203,15 @@ graph.composite = function(compos, pos) {
/**
* Render the references on the right side of a component.
*/
- function renderrrefs(refs, cassoc, pos) {
+ function renderrrefs(refs, cassoc, pos, gcomp) {
/**
* Render a reference on the right side of a component.
*/
- function renderrref(ref, cassoc, pos) {
+ function renderrref(ref, cassoc, pos, gcomp) {
var target = assoc(scdl.target(ref), cassoc);
if (isNil(target))
- return mklist();
+ return null;
// Render the component target of the reference
return rendercomp(cadr(target), cassoc, pos);
@@ -1116,21 +1226,24 @@ graph.composite = function(compos, pos) {
if (isNil(refs))
return mklist();
- return append(renderrref(car(refs), cassoc, pos), renderrrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos)));
+
+ // Return list of (ref, comp rendering) pairs
+ var grefcomp = renderrref(car(refs), cassoc, pos, gcomp);
+ return cons(mklist(car(refs), grefcomp), renderrrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos), gcomp));
}
/**
* Render the references on the bottom side of a component.
*/
- function renderbrefs(refs, cassoc, pos) {
+ function renderbrefs(refs, cassoc, pos, gcomp) {
/**
* Render a reference on the bottom side of a component.
*/
- function renderbref(ref, cassoc, pos) {
+ function renderbref(ref, cassoc, pos, gcomp) {
var target = assoc(scdl.target(ref), cassoc);
if (isNil(target))
- return mklist();
+ return null;
// Render the component target of the reference
return rendercomp(cadr(target), cassoc, pos);
@@ -1145,23 +1258,39 @@ graph.composite = function(compos, pos) {
if (isNil(refs))
return mklist();
- return append(renderbref(car(refs), cassoc, pos), renderbrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos)));
+
+ // Return list of (ref, comp rendering) pairs
+ var grefcomp = renderbref(car(refs), cassoc, pos, gcomp);
+ return cons(mklist(car(refs), grefcomp), renderbrefs(cdr(refs), cassoc, rendermove(car(refs), cassoc, pos), gcomp));
}
// Compute the component shape
- var gcomp = graph.compshape(comp, cassoc, pos);
+ var gcomp = graph.compnode(comp, cassoc, pos);
- // Add the shapes of the components wired to its references
- // as children elements
+ // Render the components wired to the component references
var rrefs = graph.rrefs(comp);
var rpos = graph.mkpath().rmove(graph.compwidth(comp, cassoc), 0);
- appendNodes(renderrrefs(rrefs, cassoc, rpos), gcomp);
+ var grrefs = renderrrefs(rrefs, cassoc, rpos, gcomp);
var brefs = graph.brefs(comp);
var bpos = graph.mkpath().rmove(0 , graph.compheight(comp, cassoc));
- appendNodes(renderbrefs(brefs, cassoc, bpos), gcomp);
+ var gbrefs = renderbrefs(brefs, cassoc, bpos, gcomp);
+
+ // Store list of (ref, pos, component rendering) triplets in the component
+ function refposgcomp(refpos, grefs) {
+ if (isNil(refpos))
+ return mklist();
- return mklist(gcomp);
+ // Append component rendering to component
+ var gref = cadr(car(grefs));
+ if (gref != null)
+ appendNodes(mklist(gref), gcomp);
+ return cons(mklist(car(car(refpos)), cadr(car(refpos)), gref), refposgcomp(cdr(refpos), cdr(grefs)));
+ }
+
+ gcomp.refpos = refposgcomp(gcomp.refpos, append(grrefs, gbrefs));
+
+ return gcomp;
}
/**
@@ -1205,7 +1334,7 @@ graph.composite = function(compos, pos) {
return renderproms(cdr(svcs), cassoc, rendermove(car(svcs), cassoc, pos));
var cpos = comppos(comp, pos);
- return append(rendercomp(comp, cassoc, cpos), renderproms(cdr(svcs), cassoc, rendermove(comp, cassoc, cpos)));
+ return cons(rendercomp(comp, cassoc, cpos), renderproms(cdr(svcs), cassoc, rendermove(comp, cassoc, cpos)));
}
// Render the promoted service components
@@ -1214,69 +1343,171 @@ graph.composite = function(compos, pos) {
if (name == 'palette') {
// Prefix ids of palette component elements with 'palette:'
- return map(function(r) {
- r.id = 'palette:' + r.id;
- return r;
- }, rproms);
+ 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 map(function(r) { r.compos = compos; return r; }, rproms);
}
- return rproms;
};
/**
- * Clone a palette element and the component associated with it.
+ * Clone a palette component node.
*/
graph.clones = 0;
graph.clonepalette = function(e) {
- // Clone the component and give it a unique name
+ // 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))),
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;
+ // Make a component node
+ var gcomp = graph.compnode(comp, mklist(), graph.mkpath());
+ graph.move(gcomp, graph.relpos(e));
+ e.parentNode.appendChild(gcomp);
+
+ return gcomp;
};
/**
- * Move a component to the given position.
+ * Move a SCDL 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.
+ * Add a component to a SCDL 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)));
-}
+ return append(mklist(element, "'composite"), append(elementChildren(compos), mklist(prom, comp)));
+};
/**
- * Remove a component from a composite.
+ * Remove a component from a SCDL 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)));
+};
+
+/**
+ * Cut the wire to a component node and make that node a
+ * top level component node.
+ */
+graph.cutwire = function(node, compos, g) {
+
+ /**
+ * Find the reference wired to a node and cut its wire.
+ */
+ function cutref(refs, node) {
+ if (isNil(refs))
+ return true;
+ var ref = car(refs);
+ if (caddr(ref) == node) {
+ setlist(ref, mklist(car(ref), cadr(ref), null));
+ setElement(car(ref), append(mklist(element, "'reference"), filter(function(e) { return !(isAttribute(e) && attributeName(e) == "'target"); }, elementChildren(car(ref)))));
+ }
+ return cutref(cdr(refs), node);
+ }
+
+ // Cut any reference wire, if found
+ cutref(node.parentNode.refpos, node);
+
+ // Make the component node a top level node.
+ node.compos = g.compos;
+
+ // Update the SCDL composite, add a promote element for
+ // that component
+ var comp = node.comp;
+ var name = scdl.name(comp);
+ var prom = mklist(element, "'service", mklist(attribute, "'name", name), mklist(attribute, "'promote", name));
+ 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.
+ */
+graph.wire = function(n, compos, g) {
+
+ // Compute position of the component's service node
+ var spos = cadr(car(n.svcpos));
+ var aspos = graph.abspos(n, g).rmove(spos.xpos(), spos.ypos());
+
+ /**
+ * Find closest unwired reference node among all the references
+ * of all the components.
+ */
+ function closecomprefs(nodes, spos, cref) {
+
+ /**
+ * Find the closest unwired reference node among all the
+ * references of a node.
+ */
+ function closerefs(npos, refs, spos, cref) {
+ if (isNil(refs))
+ return cref;
+ var fdist = cadddr(cref);
+ var ref = car(refs);
+
+ // Skip wired reference
+ if (!isNil(filter(function(n) { return isAttribute(n) && attributeName(n) == "'target"; }, car(ref))))
+ return closerefs(npos, cdr(refs), spos, cref);
+
+ // Compute distance between service node and reference node
+ var rpos = cadr(ref).clone().rmove(npos.xpos(), npos.ypos());
+ var dx = Math.pow(rpos.xpos() - spos.xpos(), 2);
+ var dy = Math.pow(rpos.ypos() - spos.ypos(), 2);
+
+ // Proximity threshold is 40 x 40 pixels
+ var rdist = (dx < 400 && dy < 400)? Math.sqrt(dx + dy) : 25000000;
+
+ // Go through all the references in the component
+ return closerefs(npos, cdr(refs), spos, fdist < rdist? cref : mklist(car(ref), cadr(ref), caddr(ref), rdist));
+ }
+
+ if (isNil(nodes))
+ return cref;
+
+ // Skip non-component nodes
+ var node = car(nodes);
+ if (isNil(node.comp))
+ return closecomprefs(cdr(nodes), spos, cref);
+
+ // Compute the component absolute position
+ var npos = graph.abspos(node, g);
+
+ // Go through all the components and their references
+ return closecomprefs(append(nodeList(node.childNodes), cdr(nodes)), spos, closerefs(npos, node.refpos, spos, cref));
+ }
+
+ // Find closest reference node
+ var cref = closecomprefs(nodeList(g.childNodes), aspos, mklist(null, graph.mkpath(), null, 25000000));
+ if (car(cref) == null)
+ return compos;
+ if (cadddr(cref) == 25000000)
+ return compos;
+
+ // Wire component to that reference, update the SCDL
+ // reference and composite
+ n.compos = null;
+ setElement(car(cref), append(mklist(element, "'reference", mklist(attribute, "'target", scdl.name(n.comp))), elementChildren(car(cref))));
+ var name = scdl.name(n.comp);
+ return append(mklist(element, "'composite"),
+ filter(function(c) { return !(isElement(c) && elementName(c) == "'service" && scdl.name(c) == name); }, elementChildren(compos)));
}
/**
* Display a list of graphical nodes.
*/
graph.display = function(nodes, g) {
+
+ // Append the nodes to the graphical canvas
appendNodes(nodes, g);
return nodes;
};
@@ -1286,7 +1517,11 @@ graph.display = function(nodes, g) {
* nodes that represent it.
*/
graph.edit = function(compos, nodes, g) {
+
+ // Store the composite in the graphical canvas
g.compos = compos;
+
+ // Display the composite nodes
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 e1f0bacdeb..dbe16d06bf 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/graph/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html
@@ -22,27 +22,25 @@
<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"/>
-<link rel="stylesheet" type="text/css" href="/ui.css">
+<link rel="stylesheet" type="text/css" href="/ui.css"/>
<script type="text/javascript" src="/util.js"></script>
<script type="text/javascript" src="/ui.js"></script>
</head>
<body>
<div id="menu"></div>
-<br/>
-<h1><span id="title"></span></h1>
-</br/>
-
-<div id="graph"></div>
-
<script type="text/javascript">
-/**
- * The current app name.
- */
+
+// Get the app name
var appname = ui.queryParams()['app'];
// Load the menu bar
ui.loadwidget('menu', '/menu.html?app=' + appname);
+</script>
+
+<div id="graph"></div>
+
+<script type="text/javascript">
/**
* Display the editor for an app.
@@ -50,7 +48,6 @@ ui.loadwidget('menu', '/menu.html?app=' + appname);
function editapp(name) {
if (isNil(name))
return;
- $('title').innerHTML = 'Editing: ' + name;
$('graph').innerHTML =
'<iframe id="graphFrame" style="height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="graph.html?' +
'app=' + name +
diff --git a/sca-cpp/trunk/modules/edit/htdocs/index.html b/sca-cpp/trunk/modules/edit/htdocs/index.html
index d47031fa7e..db5764781a 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/index.html
@@ -29,12 +29,21 @@
<body>
<div id="menu"></div>
+<script type="text/javascript">
+
+// Load the menu bar
+ui.loadwidget('menu', '/menu.html');
+</script>
+
<br/>
<h1>App Edit Tools</h1>
+<br/>
+
<div id="main"></div>
<script type="text/javascript">
-ui.loadwidget('menu', '/menu.html');
+
+// Load the main page
ui.loadiframe('main', 'main.html');
</script>
</body>
diff --git a/sca-cpp/trunk/modules/edit/htdocs/main.html b/sca-cpp/trunk/modules/edit/htdocs/main.html
index a9f074c8ae..65909c1a94 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/main.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/main.html
@@ -24,7 +24,10 @@
</head>
<body>
-<p>This module implements simple tools to help you create Tuscany apps.</p>
+<div style="position: absolute; top: 0px; left: 0px; right: 0px;">
+
+<div>This module implements simple tools to help you create Tuscany apps.</div>
+<br/>
<h2>App Dashboard</h2>
<p>Try the <a href="dash" target="_parent">App Dashboard</a> to manage your collection of apps.</p>
@@ -38,5 +41,7 @@
<h2>Page Editor</h2>
<p>Try the <a href="page/?app=store" target="_parent">Page Editor</a> to draw an app page.</p>
+</div>
+
</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 5f9d93efed..f8bfa273c7 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/page/index.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html
@@ -29,20 +29,18 @@
<body>
<div id="menu"></div>
-<br/>
-<h1><span id="title"></span></h1>
-</br>
-
-<div id="page"></div>
-
<script type="text/javascript">
-/**
- * The current app name.
- */
+
+// Get the app name
var appname = ui.queryParams()['app'];
// Load the menu bar
ui.loadwidget('menu', '/menu.html?app=' + appname);
+</script>
+
+<div id="page"></div>
+
+<script type="text/javascript">
/**
* Display the page editor for an app.
@@ -50,7 +48,6 @@ ui.loadwidget('menu', '/menu.html?app=' + appname);
function editapp(name) {
if (isNil(name))
return;
- $('title').innerHTML = 'Editing: ' + name;
$('page').innerHTML =
'<iframe id="pageFrame" style="height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="page.html?' +
'app=' + name +
diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.html b/sca-cpp/trunk/modules/edit/htdocs/page/page.html
index 202fb7aacc..d0a26fdad0 100644
--- a/sca-cpp/trunk/modules/edit/htdocs/page/page.html
+++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.html
@@ -30,8 +30,10 @@
</head>
<body>
-<table style="position: absolute; top: 0px; left: 0px;" width="100%">
-<tr><th style="width: 338px;">Palette</th><th style="padding-top: 0px; padding-bottom: 0px;"><span>Page</span><span style="position: absolute; top: 2px; right: 8px;"><input type="button" id="saveButton" style="font-weight: bold;" Value="Save"/></span></th></tr>
+<div 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>
<div id="page" style="position: absolute; top: 60px; left: 0px; width: 5000px; height: 5000px;">
@@ -52,6 +54,8 @@
<div id="buffer" style="visibility: hidden; width: 0px; height: 0px">
</div>
+</div>
+
<script type="text/javascript">
var editWidget = sca.component("EditWidget");
var pages = sca.reference(editWidget, "pages");
@@ -60,6 +64,7 @@ var pages = sca.reference(editWidget, "pages");
* The current app name.
*/
var appname = ui.queryParams()['app'];
+$('appname').innerHTML = 'Page: ' + appname;
/**
* Return the page in an ATOM entry.