diff options
28 files changed, 1186 insertions, 217 deletions
diff --git a/sca-cpp/trunk/modules/edit/apps.py b/sca-cpp/trunk/modules/edit/apps.py index 920bb635e6..61cdfe07ef 100644 --- a/sca-cpp/trunk/modules/edit/apps.py +++ b/sca-cpp/trunk/modules/edit/apps.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -# Workspace collection implementation +# Apps collection implementation import uuid import sys from util import * @@ -24,24 +24,24 @@ from util import * def appid(id): return ("'" + car(id), "'app.composite") -# Post a new app to the domains db +# Post a new app to the apps db def post(collection, app, cache): id = appid((str(uuid.uuid1()),)) cache.put((id,), app) return id -# Put an app into the domains db +# Put an app into the apps db def put(id, app, cache): cache.put(appid(id), app) return True -# Get an app from the domains db +# Get an app from the apps db def get(id, cache): if isNil(id): return ("Apps", "apps") return (car(id), car(id), cache.get(appid(id))) -# Delete an app from the domains db +# Delete an app from the apps db def delete(id, cache): cache.delete(appid(id)) return True diff --git a/sca-cpp/trunk/modules/edit/domains/relay/app.composite b/sca-cpp/trunk/modules/edit/apps/relay/app.composite index 1e5015315c..1e5015315c 100644 --- a/sca-cpp/trunk/modules/edit/domains/relay/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/relay/app.composite diff --git a/sca-cpp/trunk/modules/edit/domains/store/app.composite b/sca-cpp/trunk/modules/edit/apps/store/app.composite index ec3fa32fa4..ec3fa32fa4 100644 --- a/sca-cpp/trunk/modules/edit/domains/store/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/store/app.composite diff --git a/sca-cpp/trunk/modules/edit/domains/store2/app.composite b/sca-cpp/trunk/modules/edit/apps/store2/app.composite index afec3cb1d3..afec3cb1d3 100644 --- a/sca-cpp/trunk/modules/edit/domains/store2/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/store2/app.composite diff --git a/sca-cpp/trunk/modules/edit/domains/store3/app.composite b/sca-cpp/trunk/modules/edit/apps/store3/app.composite index 7cba2c19e1..7cba2c19e1 100644 --- a/sca-cpp/trunk/modules/edit/domains/store3/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/store3/app.composite diff --git a/sca-cpp/trunk/modules/edit/domains/travel/app.composite b/sca-cpp/trunk/modules/edit/apps/travel/app.composite index 833944a855..833944a855 100644 --- a/sca-cpp/trunk/modules/edit/domains/travel/app.composite +++ b/sca-cpp/trunk/modules/edit/apps/travel/app.composite diff --git a/sca-cpp/trunk/modules/edit/dashboard.py b/sca-cpp/trunk/modules/edit/dashboard.py index 990476a84e..825bf8b405 100644 --- a/sca-cpp/trunk/modules/edit/dashboard.py +++ b/sca-cpp/trunk/modules/edit/dashboard.py @@ -15,68 +15,68 @@ # specific language governing permissions and limitations # under the License. -# Workspace collection implementation +# Dashboards collection implementation import uuid import sys from util import * -# Convert a particular user email to a workspace id -def workspaceid(user): +# Convert a particular user email to a dashboard id +def dashboardid(user): return ("'" + user.id(),) -# Get a workspace from the cache -def getworkspace(id, cache): - workspace = cache.get(id) - if isNil(workspace): +# Get a dashboard from the cache +def getdashboard(id, cache): + dashboard = cache.get(id) + if isNil(dashboard): return () - return workspace + return dashboard -# Post a new app to the user's workspace +# Post a new app to the user's dashboard def post(collection, app, user, cache): id = (str(uuid.uuid1()),) - workspace = cons((car(app), car(id), caddr(app)), getworkspace(workspaceid(user), cache)) - cache.put(workspaceid(user), workspace) + dashboard = cons((car(app), car(id), caddr(app)), getdashboard(dashboardid(user), cache)) + cache.put(dashboardid(user), dashboard) return id -# Put an app into the user's workspace +# Put an app into the user's dashboard def put(id, app, user, cache): - def putapp(app, workspace): - if isNil(workspace): + def putapp(app, dashboard): + if isNil(dashboard): return (app,) - if cadr(app) == cadr(car(workspace)): - return cons(app, cdr(workspace)) - return cons(car(workspace), putapp(app, cdr(workspace))) + if cadr(app) == cadr(car(dashboard)): + return cons(app, cdr(dashboard)) + return cons(car(dashboard), putapp(app, cdr(dashboard))) - workspace = putapp(app, getworkspace(workspaceid(user), cache)) - cache.put(workspaceid(user), workspace) + dashboard = putapp(app, getdashboard(dashboardid(user), cache)) + cache.put(dashboardid(user), dashboard) return True -# Get apps from the user's workspace +# Get apps from the user's dashboard def get(id, user, cache): - def findapp(id, workspace): - if isNil(workspace): + def findapp(id, dashboard): + if isNil(dashboard): return None - if car(id) == cadr(car(workspace)): - return car(workspace) - return findapp(id, cdr(workspace)) + if car(id) == cadr(car(dashboard)): + return car(dashboard) + return findapp(id, cdr(dashboard)) if isNil(id): - return ("Your Apps", user.id()) + getworkspace(workspaceid(user), cache) - return findapp(id, getworkspace(workspaceid(user), cache)) + return ("Your Apps", user.id()) + getdashboard(dashboardid(user), cache) + return findapp(id, getdashboard(dashboardid(user), cache)) -# Delete apps from the user's workspace +# Delete apps from the user's dashboard def delete(id, user, cache): if isNil(id): - return cache.delete(workspaceid(user)) + return cache.delete(dashboardid(user)) - def deleteapp(id, workspace): - if isNil(workspace): + def deleteapp(id, dashboard): + if isNil(dashboard): return () - if car(id) == cadr(car(workspace)): - return cdr(workspace) - return cons(car(workspace), deleteapp(id, cdr(workspace))) + if car(id) == cadr(car(dashboard)): + return cdr(dashboard) + return cons(car(dashboard), deleteapp(id, cdr(dashboard))) - workspace = deleteapp(id, getworkspace(workspaceid(user), cache)) - cache.put(workspaceid(user), workspace) + dashboard = deleteapp(id, getdashboard(dashboardid(user), cache)) + cache.put(dashboardid(user), dashboard) return True diff --git a/sca-cpp/trunk/modules/edit/workspaces/joe@localhost b/sca-cpp/trunk/modules/edit/dashboards/joe@localhost index b9419e75d0..b9419e75d0 100644 --- a/sca-cpp/trunk/modules/edit/workspaces/joe@localhost +++ b/sca-cpp/trunk/modules/edit/dashboards/joe@localhost diff --git a/sca-cpp/trunk/modules/edit/edit.composite b/sca-cpp/trunk/modules/edit/edit.composite index c73ac82037..49a5c84a56 100644 --- a/sca-cpp/trunk/modules/edit/edit.composite +++ b/sca-cpp/trunk/modules/edit/edit.composite @@ -39,6 +39,7 @@ <component name="EditWidget"> <t:implementation.widget location="/index.html"/> <reference name="dashboard" target="Dashboard"/> + <reference name="palettes" target="Palettes"/> <reference name="apps" target="Apps"/> </component> @@ -48,7 +49,7 @@ <t:binding.http uri="dashboard"/> </service> <reference name="user" target="User"/> - <reference name="cache" target="WorkspaceCache"/> + <reference name="cache" target="DashboardCache"/> </component> <component name="Apps"> @@ -56,46 +57,74 @@ <service name="Apps"> <t:binding.http uri="apps"/> </service> - <reference name="cache" target="DomainCache"/> + <reference name="cache" target="AppCache"/> </component> - <component name="WorkspaceCache"> + <component name="Palettes"> + <t:implementation.python script="palettes.py"/> + <service name="Palettes"> + <t:binding.http uri="palettes"/> + </service> + <reference name="cache" target="PaletteCache"/> + </component> + + <component name="DashboardCache"> <implementation.cpp path="../../components/cache" library="libdatacache"/> - <service name="WorkspaceCache"> - <t:binding.http uri="workspacecache"/> + <service name="DashboardCache"> + <t:binding.http uri="dashboardcache"/> </service> <reference name="l1reader" target="Memcache"/> <reference name="l1writer" target="Memcache"/> - <reference name="l2reader" target="WorkspaceDB"/> - <reference name="l2writer" target="WorkspaceDB"/> + <reference name="l2reader" target="DashboardDB"/> + <reference name="l2writer" target="DashboardDB"/> </component> - <component name="WorkspaceDB"> + <component name="DashboardDB"> <implementation.cpp path="../../components/filedb" library="libfiledb"/> - <property name="dbname">workspaces</property> + <property name="dbname">dashboards</property> <property name="format">scheme</property> - <service name="WorkspaceDB"> - <t:binding.http uri="workspaces"/> + <service name="DashboardDB"> + <t:binding.http uri="dashboarddb"/> + </service> + </component> + + <component name="AppCache"> + <implementation.cpp path="../../components/cache" library="libdatacache"/> + <service name="AppCache"> + <t:binding.http uri="appcache"/> + </service> + <reference name="l1reader" target="Memcache"/> + <reference name="l1writer" target="Memcache"/> + <reference name="l2reader" target="AppDB"/> + <reference name="l2writer" target="AppDB"/> + </component> + + <component name="AppDB"> + <implementation.cpp path="../../components/filedb" library="libfiledb"/> + <property name="dbname">apps</property> + <property name="format">xml</property> + <service name="AppDB"> + <t:binding.http uri="appdb"/> </service> </component> - <component name="DomainCache"> + <component name="PaletteCache"> <implementation.cpp path="../../components/cache" library="libdatacache"/> - <service name="DomainCache"> - <t:binding.http uri="domaincache"/> + <service name="PaletteCache"> + <t:binding.http uri="palettecache"/> </service> <reference name="l1reader" target="Memcache"/> <reference name="l1writer" target="Memcache"/> - <reference name="l2reader" target="DomainDB"/> - <reference name="l2writer" target="DomainDB"/> + <reference name="l2reader" target="PaletteDB"/> + <reference name="l2writer" target="PaletteDB"/> </component> - <component name="DomainDB"> + <component name="PaletteDB"> <implementation.cpp path="../../components/filedb" library="libfiledb"/> - <property name="dbname">domains</property> + <property name="dbname">palettes</property> <property name="format">xml</property> - <service name="DomainDB"> - <t:binding.http uri="domains"/> + <service name="PaletteDB"> + <t:binding.http uri="palettedb"/> </service> </component> diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html index b69c760c99..60d869abde 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html +++ b/sca-cpp/trunk/modules/edit/htdocs/dash/dashboard.html @@ -82,7 +82,7 @@ function getapps(sync) { title = car(entry); apps += '<tr>'; - apps += '<td><input name="apps" type="checkbox" value="' + name + '">' + '<a href=\"' + '/edit/?app=' + name + '\">' + name + '</a></td>'; + apps += '<td><input name="apps" type="checkbox" value="' + name + '">' + '<a href=\"' + '/graph/?app=' + name + '\">' + name + '</a></td>'; apps += '<td class="tdw">' + title + '</td>'; apps += '</tr>'; } diff --git a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html index 0abb384d75..d1da06d71c 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/dash/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/dash/index.html @@ -30,14 +30,11 @@ <h1>Welcome to your App Dashboard!</h1> <div id="dashboard"></div> -<iframe id="menuFrame" src="/menu.html"></iframe> -<iframe id="dashboardFrame" src="dashboard.html"></iframe> - <script type="text/javascript"> -ui.bindwidget('menuFrame', 'menu'); +ui.loadwidget('menu', '/menu.html'); // Display the dashboard widget -ui.bindwidget('dashboardFrame', 'dashboard'); +ui.loadwidget('dashboard', 'dashboard.html'); </script> </body> </html> diff --git a/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html new file mode 100644 index 0000000000..618d638e7d --- /dev/null +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.html @@ -0,0 +1,112 @@ +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<html> +<head> +<link rel="stylesheet" type="text/css" href="/ui.css"> +<script type="text/javascript" src="/util.js"></script> +<script type="text/javascript" src="/elemutil.js"></script> +<script type="text/javascript" src="/xmlutil.js"></script> +<script type="text/javascript" src="/atomutil.js"></script> +<script type="text/javascript" src="/scdl.js"></script> +<script type="text/javascript" src="/ui.js"></script> +<script type="text/javascript" src="/component.js"></script> +<script type="text/javascript" src="graph.js"></script> +</head> +<body> + +<script type="text/javascript"> +var editWidget = sca.component("EditWidget"); +var dashboard = sca.reference(editWidget, "dashboard"); +var palettes = sca.reference(editWidget, "palettes"); +var apps = sca.reference(editWidget, "apps"); + +/** + * Return the current app name. + */ +function appname() { + return ui.queryParams()['app']; +} + +/** + * Return the composite in an ATOM entry. + */ +function atomcomposite(doc) { + var entry = atom.readATOMEntryDocument(doc); + var item = caddr(entry); + return cddr(item); +} + +/** + * Load and display an app. + */ +function getapp(name, g) { + if (isNil(name)) + return; + apps.get(name, function(doc) { + graph.append(graph.composite(atomcomposite(doc), graph.mkpath().move(300,0)), g); + }); +} + +/** + * Load and display a palette content. + */ + +function getpalette(name, g, bg, palette, gpalettes) { + if (isNil(name)) + return; + palettes.get(name, function(doc) { + gpalettes[name] = graph.composite(atomcomposite(doc), graph.mkpath().move(150,0)); + graph.append(gpalettes[name], name == spalette? g : bg); + }); +} + +/** + * Install a palette button and content. + */ +function installpalette(name, pos, g, bg, palette, gpalettes) { + var b = graph.mkbutton(name, pos); + graph.append(mklist(b), g); + b.onclick = function() { + // Display the selected palette + spalette = name; + for (var pn in gpalettes) + graph.append(gpalettes[pn], pn == spalette? g : bg); + } + getpalette(name, g, bg, palette, gpalettes); +} + +// Create editor graph area +var g = graph.mkgraph(); +var bg = graph.mkgroup(graph.mkpath()); + +// 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); + +// Display the current app +getapp(appname(), g); + +</script> +</body> +</html> diff --git a/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js index 5f122ac498..88a2efd50b 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/edit/graph.js +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/graph.js @@ -18,32 +18,12 @@ */ /** - * SVG and VML component rendering functions. + * SVG and VML composite rendering functions. */ var graph = new Object(); /** - * Detect browser VML support. - */ -graph.supportsVML = function() { - if (typeof graph.supportsVML.supported != 'undefined') - return graph.supportsVML.supported; - graph.supportsVML.supported = navigator.appName == 'Microsoft Internet Explorer'; - return graph.supportsVML.supported; -}; - -/** - * Detect browser SVG support. - */ -graph.supportsSVG = function() { - if (typeof graph.supportsSVG.supported != 'undefined') - return graph.supportsSVG.supported; - graph.supportsSVG.supported = navigator.appName != 'Microsoft Internet Explorer'; - return graph.supportsSVG.supported; -}; - -/** * Basic colors */ graph.colors = new Object(); @@ -51,7 +31,7 @@ graph.colors.black = '#000000'; graph.colors.blue = '#0000ff'; graph.colors.cyan = '#00ffff'; graph.colors.gray = '#808080' -graph.colors.green = '#008000'; +graph.colors.green = '#00ff00'; graph.colors.magenta = '#ff00ff'; graph.colors.orange = '#ffa500'; graph.colors.pink = '#ffc0cb'; @@ -106,7 +86,7 @@ graph.BasePath = function() { /** * VML rendering. */ -if (graph.supportsVML()) { +if (ui.isIE()) { graph.vmlns='urn:schemas-microsoft-com:vml'; document.write('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />'); @@ -120,9 +100,9 @@ if (graph.supportsVML()) { document.body.appendChild(div); var vmlg = document.createElement('v:group'); - vmlg.style.width = 2000; - vmlg.style.height = 2000; - vmlg.coordsize = '2000,2000'; + vmlg.style.width = 5000; + vmlg.style.height = 5000; + vmlg.coordsize = '5000,5000'; div.appendChild(vmlg); graph.dragging = null; @@ -130,17 +110,24 @@ if (graph.supportsVML()) { function draggable(n) { if (n == vmlg) return null; - if (n.nodeName == 'group') + if (n.nodeName == 'group' && n.id != '') return n; return draggable(n.parentNode); } + function bringtotop(n) { + if (n == vmlg) + return null; + n.parentNode.appendChild(n); + return bringtotop(n.parentNode); + } + vmlg.onmousedown = function() { window.event.returnValue = false; graph.dragging = draggable(window.event.srcElement); if (graph.dragging == null) return false; - graph.dragging.parentNode.appendChild(graph.dragging); + bringtotop(graph.dragging); graph.dragX = window.event.clientX; graph.dragY = window.event.clientY; vmlg.setCapture(); @@ -164,6 +151,13 @@ if (graph.supportsVML()) { 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); return false; }; @@ -217,27 +211,36 @@ if (graph.supportsVML()) { }; /** - * Return an element representing the title of a component. + * Return an element representing a title. */ - graph.comptitle = function(comp) { - var t = scdl.name(comp); - var tsvcs = graph.tsvcs(comp); - var lsvcs = graph.lsvcs(comp); + graph.mktitle = function(t, bold, pos) { var title = document.createElement('v:textbox'); - title.style.left = '' + (isNil(lsvcs)? 5 : 25); - title.style.top = '' + (isNil(tsvcs)? 5 : 25); + title.style.left = pos.xpos(); + title.style.top = pos.ypos(); title.style.position = 'absolute'; - title.style.fontWeight = 'bold'; + if (bold) + title.style.fontWeight = 'bold'; var tnode = document.createTextNode(t); title.appendChild(tnode); return title; + return title; + }; + + /** + * Return an element representing the title of a component. + */ + graph.comptitle = function(comp) { + var tsvcs = graph.tsvcs(comp); + var lsvcs = graph.lsvcs(comp); + var pos = graph.mkpath().move(isNil(lsvcs)? 5 : 25, isNil(tsvcs)? 5 : 25); + return graph.mktitle(graph.title(comp), true, pos); }; /** * Return the width of the title of a component. */ graph.comptitlewidth = function(comp) { - var t = scdl.name(comp); + var t = graph.title(comp); graph.comptitlewidthdiv.innerHTML = t; var twidth = graph.comptitlewidthdiv.offsetWidth; graph.comptitlewidthdiv.innerHTML = ''; @@ -248,21 +251,14 @@ if (graph.supportsVML()) { * Return an element representing the title of a reference. */ graph.reftitle = function(ref) { - var t = scdl.name(ref); - var title = document.createElement('v:textbox'); - title.style.left = '' + 25; - title.style.top = '' + 25; - title.style.position = 'absolute'; - var tnode = document.createTextNode(t); - title.appendChild(tnode); - return title; + return graph.mktitle(graph.title(ref), false, graph.mkpath().move(25,25)); }; /** * Return the width of the title of a reference. */ graph.reftitlewidth = function(ref) { - var t = scdl.name(ref); + var t = graph.title(ref); graph.reftitlewidthdiv.innerHTML = t; var twidth = graph.reftitlewidthdiv.offsetWidth; graph.reftitlewidthdiv.innerHTML = ''; @@ -278,17 +274,17 @@ if (graph.supportsVML()) { var d = graph.comppath(comp, cassoc).str(); var shape = document.createElement('v:shape'); - shape.style.width = 2000; - shape.style.height = 2000; - shape.coordsize = '2000,2000'; + shape.style.width = 5000; + shape.style.height = 5000; + shape.coordsize = '5000,5000'; shape.path = d; shape.fillcolor = graph.color(comp); shape.stroked = 'false'; var contour = document.createElement('v:shape'); - contour.style.width = 2000; - contour.style.height = 2000; - contour.coordsize = '2000,2000'; + contour.style.width = 5000; + contour.style.height = 5000; + contour.coordsize = '5000,5000'; contour.setAttribute('path', d); contour.filled = 'false'; contour.strokecolor = graph.colors.gray; @@ -301,23 +297,77 @@ if (graph.supportsVML()) { var g = document.createElement('v:group'); g.id = scdl.name(comp); - g.style.width = 2000; - g.style.height = 2000; - g.coordsize = '2000,2000'; + g.style.width = 5000; + g.style.height = 5000; + g.coordsize = '5000,5000'; g.style.left = pos.xpos(); g.style.top = pos.ypos(); g.appendChild(shape); shape.appendChild(title); g.appendChild(contour) + + // Store the component in the shape + g.comp = comp; + return g; }; -} -/** - * SVG rendering. - */ -if (graph.supportsSVG()) { + /** + * Return a graphical group. + */ + graph.mkgroup = function(pos) { + var g = document.createElement('v:group'); + g.style.left = pos.xpos(); + g.style.top = pos.ypos(); + return g; + }; + /** + * Return a shape representing a button. + */ + graph.mkbutton = function(t, pos) { + var title = graph.mktitle(t, true, pos); + var d = graph.buttonpath().str(); + + 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.stroked = 'false'; + + var contour = document.createElement('v:shape'); + contour.style.width = 5000; + contour.style.height = 5000; + contour.coordsize = '5000,5000'; + contour.setAttribute('path', d); + contour.filled = 'false'; + contour.strokecolor = graph.colors.gray; + contour.strokeweight = '2'; + contour.style.left = 1; + contour.style.top = 1; + var stroke = document.createElement('v:stroke'); + stroke.opacity = '20%'; + contour.appendChild(stroke); + + var g = document.createElement('v:group'); + g.style.width = 5000; + g.style.height = 5000; + g.coordsize = '5000,5000'; + g.style.left = pos.xpos(); + g.style.top = pos.ypos(); + g.appendChild(shape); + shape.appendChild(title); + g.appendChild(contour) + return g; + }; + +} else { + + /** + * SVG rendering. + */ graph.svgns='http://www.w3.org/2000/svg'; /** @@ -329,8 +379,8 @@ if (graph.supportsSVG()) { document.body.appendChild(div); var svg = document.createElementNS(graph.svgns, 'svg'); - svg.style.height = '100%'; - svg.style.width = '100%'; + svg.style.height = 5000; + svg.style.width = 5000; div.appendChild(svg); graph.dragging = null; @@ -338,20 +388,27 @@ if (graph.supportsSVG()) { function draggable(n) { if (n == svg) return null; - if (n.nodeName == 'g') + if (n.nodeName == 'g' && n.id != '') return n; return draggable(n.parentNode); } + function bringtotop(n) { + if (n == svg) + return null; + n.parentNode.appendChild(n); + return bringtotop(n.parentNode); + } + svg.onmousedown = function(e) { if (e.preventDefault) e.preventDefault(); else - e.returnValue= false; + e.returnValue = false; graph.dragging = draggable(e.target); if (graph.dragging == null) return false; - graph.dragging.parentNode.appendChild(graph.dragging); + bringtotop(graph.dragging); var pos = typeof e.touches != "undefined" ? e.touches[0] : e; graph.dragX = pos.clientX; graph.dragY = pos.clientY; @@ -381,6 +438,13 @@ if (graph.supportsSVG()) { var newY = curY + (pos.clientY - graph.dragY); graph.dragX = pos.clientX; graph.dragY = pos.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()); + graph.dragging.parentNode.appendChild(clone); + graph.dragging = clone; + } graph.dragging.setAttribute('transform', 'translate(' + newX + ',' + newY + ')'); return false; }; @@ -389,8 +453,8 @@ if (graph.supportsSVG()) { graph.titlewidthsvg = document.createElementNS(graph.svgns, 'svg'); graph.titlewidthsvg.style.visibility = 'hidden'; - graph.titlewidthsvg.style.height = '0px'; - graph.titlewidthsvg.style.width = '0px'; + graph.titlewidthsvg.style.height = 0; + graph.titlewidthsvg.style.width = 0; div.appendChild(graph.titlewidthsvg); return svg; @@ -433,20 +497,27 @@ if (graph.supportsSVG()) { }; /** - * Return an element representing the title of a component. + * Return an element representing a title. */ - graph.comptitle = function(comp) { - var t = scdl.name(comp); + graph.mktitle = function(t, bold) { var title = document.createElementNS(graph.svgns, 'text'); title.setAttribute('text-anchor', 'start'); title.setAttribute('x', 5); title.setAttribute('y', 15); - title.style.fontWeight = 'bold'; + if (bold) + title.style.fontWeight = 'bold'; title.appendChild(document.createTextNode(t)); return title; }; /** + * Return an element representing the title of a component. + */ + graph.comptitle = function(comp) { + return graph.mktitle(graph.title(comp), true); + }; + + /** * Return the width of the title of a component. */ graph.comptitlewidth = function(comp) { @@ -461,12 +532,7 @@ if (graph.supportsSVG()) { * Return an element representing the title of a reference. */ graph.reftitle = function(ref) { - var t = scdl.name(ref); - var title = document.createElementNS(graph.svgns, 'text'); - title.setAttribute('text-anchor', 'start'); - title.setAttribute('x', 5); - title.setAttribute('y', 15); - return title; + return graph.mktitle(graph.title(ref), false); }; /** @@ -506,11 +572,59 @@ if (graph.supportsSVG()) { g.appendChild(shape); g.appendChild(contour); g.appendChild(title); + + // Store the component in the shape. + g.comp = comp; + + return g; + }; + + /** + * Return a graphical group. + */ + graph.mkgroup = function(pos) { + var g = document.createElementNS(graph.svgns, 'g'); + g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')'); + return g; + }; + + /** + * Return a shape representing a button. + */ + graph.mkbutton = function(t, pos) { + var title = graph.mktitle(t, true); + var d = graph.buttonpath().str(); + + var shape = document.createElementNS(graph.svgns, 'path'); + shape.setAttribute('d', d); + shape.setAttribute('fill', graph.colors.blue); + + var contour = document.createElementNS(graph.svgns, 'path'); + contour.setAttribute('d', d); + contour.setAttribute('fill', 'none'); + contour.setAttribute('stroke', graph.colors.gray); + contour.setAttribute('stroke-width', '4'); + contour.setAttribute('stroke-opacity', '0.20'); + contour.setAttribute('transform', 'translate(1,1)'); + + var g = document.createElementNS(graph.svgns, 'g'); + g.setAttribute('transform', 'translate(' + pos.xpos() + ',' + pos.ypos() + ')'); + g.appendChild(shape); + g.appendChild(contour); + g.appendChild(title); return g; }; } /** + * Return the title of a SCDL element. + */ +graph.title = function(e) { + var d = scdl.documentation(e); + return d != null? d : scdl.name(e); +}; + +/** * Return the services and references of a component. */ graph.tsvcs = function(comp) { @@ -707,8 +821,8 @@ graph.tsvcpath = function(svc, cassoc, path) { }; /** -* Return a path representing a component. -*/ + * Return a path representing a component. + */ graph.comppath = function(comp, cassoc) { var height = graph.compheight(comp, cassoc); var width = graph.compwidth(comp, cassoc); @@ -742,22 +856,39 @@ graph.comppath = function(comp, cassoc) { }; /** + * Return a path representing a button. + */ +graph.buttonpath = function(t) { + var height = 60; + var width = 120; + var path = graph.mkpath().move(10,0); + path = path.line(width - 10,path.ypos()).rcurve(10,0,0,10); + path = path.line(path.xpos(),height - 10).rcurve(0,10,-10,0).line(10, path.ypos()); + path = path.line(10,path.ypos()).rcurve(-10,0,0,-10).line(path.xpos(), 10); + path = path.line(0,10).rcurve(0,-10,10,0); + return path.end(); +}; + +/** + * Append a list of graphical elements to a parent. + */ +graph.append = function(nodes, p) { + if (isNil(nodes)) + return p; + p.appendChild(car(nodes)); + return graph.append(cdr(nodes), p); +}; + +/** * Render a composite. */ -graph.composite = function(compos) { - var name = scdl.name(compos); +graph.composite = function(compos, pos) { + var name = scdl.name(scdl.composite(compos)); var comps = scdl.components(compos); var cassoc = scdl.nameToElementAssoc(comps); var proms = scdl.promotions(compos); function rendercomp(comp, cassoc, pos) { - function appendg(nodes, parent) { - if (isNil(nodes)) - return parent; - parent.appendChild(car(nodes)); - return appendg(cdr(nodes), parent); - } - function renderrrefs(refs, cassoc, pos) { function renderrref(ref, cassoc, pos) { var target = assoc(scdl.target(ref), cassoc); @@ -796,36 +927,51 @@ graph.composite = function(compos) { var rrefs = graph.rrefs(comp); var rpos = graph.mkpath().rmove(graph.compwidth(comp, cassoc), 0); - appendg(renderrrefs(rrefs, cassoc, rpos), gcomp); + graph.append(renderrrefs(rrefs, cassoc, rpos), gcomp); var brefs = graph.brefs(comp); var bpos = graph.mkpath().rmove(0 , graph.compheight(comp, cassoc)); - appendg(renderbrefs(brefs, cassoc, bpos), gcomp); + graph.append(renderbrefs(brefs, cassoc, bpos), gcomp); return mklist(gcomp); } function renderproms(svcs, cassoc, pos) { - function renderprom(svc, cassoc, pos) { - var comp = assoc(scdl.promote(svc), cassoc); - if (isNil(comp)) + function promcomp(svc, cassoc) { + var c = assoc(scdl.promote(svc), cassoc); + if (isNil(c)) return mklist(); - return rendercomp(cadr(comp), cassoc, pos); + return cadr(c); } - function rendermove(svc, cassoc, pos) { - var comp = assoc(scdl.promote(svc), cassoc); - if (isNil(comp)) - return pos; - return pos.clone().rmove(0, graph.compclosureheight(cadr(comp), cassoc) + 20); + 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()); + } + + function rendermove(comp, cassoc, pos) { + return pos.clone().rmove(0, graph.compclosureheight(comp, cassoc) + 20); } if (isNil(svcs)) return mklist(); - return append(renderprom(car(svcs), cassoc, pos), renderproms(cdr(svcs), cassoc, rendermove(car(svcs), cassoc, pos))); + + var comp = promcomp(car(svcs), cassoc); + if (isNil(comp)) + 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))); } - var rcomps = renderproms(proms, cassoc, graph.mkpath().rmove(20,20)); - return rcomps; + var rproms = renderproms(proms, cassoc, pos.clone().rmove(20,20)); + + if (name == 'palette') + return map(function(r) { + r.id = 'palette:' + r.id; + return r; + }, rproms); + return rproms; }; diff --git a/sca-cpp/trunk/modules/edit/htdocs/edit/index.html b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html index 34479a37a5..105e240389 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/edit/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/graph/index.html @@ -27,13 +27,12 @@ <body> <div id="menu"></div> -<h1><span id="titleDiv"></span></h1> -<div id="editDiv"></div> +<h1><span id="title"></span></h1> -<iframe id="menuFrame" src="/menu.html"></iframe> +<div id="graph"></div> <script type="text/javascript"> -ui.bindwidget('menuFrame', 'menu'); +ui.loadwidget('menu', '/menu.html'); /** * Return the current app name. @@ -48,9 +47,9 @@ function appname() { function editapp(name) { if (isNil(name)) return; - $('titleDiv').innerHTML = 'Editing: ' + name; - $('editDiv').innerHTML = - '<iframe id="editFrame" style="visibility: visible; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="edit.html?' + + $('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 + '"></iframe>'; } diff --git a/sca-cpp/trunk/modules/edit/htdocs/index.html b/sca-cpp/trunk/modules/edit/htdocs/index.html index 52ed6259c7..d9791a8b78 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/index.html @@ -34,12 +34,13 @@ <p>Try the <a href="dash">App Dashboard</a> to manage your collection of apps.</p> <h2>App Editor</h2> -<p>Try the <a href="edit/?app=store">App Editor</a> to edit an app.</p> +<p>Try the <a href="graph/?app=store">App Editor</a> to edit an app.</p> -<iframe id="menuFrame" src="menu.html"></iframe> +<h2>Page Editor</h2> +<p>Try the <a href="page/?app=store">Page Editor</a> to edit an app page.</p> <script type="text/javascript"> -ui.bindwidget('menuFrame', 'menu'); +ui.loadwidget('menu', '/menu.html'); </script> </body> </html> diff --git a/sca-cpp/trunk/modules/edit/htdocs/menu.html b/sca-cpp/trunk/modules/edit/htdocs/menu.html index a4addf1f96..7bf2ef931e 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/menu.html +++ b/sca-cpp/trunk/modules/edit/htdocs/menu.html @@ -29,7 +29,7 @@ ui.installwidget(); var mdiv = $('menu'); -mdiv.innerHTML = ui.menubar(mklist(ui.menu('Home', '/'), ui.menu('Dashboard', '/dash'), ui.menu('Editor', '/edit?app=store')), mklist(ui.menu('Sign out', '/logout'))); +mdiv.innerHTML = ui.menubar(mklist(ui.menu('Home', '/'), ui.menu('Dashboard', '/dash')), mklist(ui.menu('Sign out', '/logout'))); </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 new file mode 100644 index 0000000000..e34aca0bea --- /dev/null +++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html @@ -0,0 +1,41 @@ +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<html> +<head> +<title>App Page Editor</title> +<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0"/> +<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> + +<h1>Editing: HTML Page</h1> +<div id="page"></div> + +<script type="text/javascript"> +ui.loadwidget('menu', '/menu.html'); + +// Display the page widget +ui.loadwidget('page', 'page.html'); +</script> +</body> +</html> + diff --git a/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html b/sca-cpp/trunk/modules/edit/htdocs/page/page.html index d5618834ba..75405ce163 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/edit/edit.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.html @@ -26,43 +26,24 @@ <script type="text/javascript" src="/scdl.js"></script> <script type="text/javascript" src="/ui.js"></script> <script type="text/javascript" src="/component.js"></script> -<script type="text/javascript" src="/edit/graph.js"></script> +<script type="text/javascript" src="page.js"></script> </head> <body> -<script type="text/javascript"> -var editWidget = sca.component("EditWidget"); -var dashboard = sca.reference(editWidget, "dashboard"); -var apps = sca.reference(editWidget, "apps"); +<div id="page" style="position: absolute; width: 5000px; height: 5000px;"> -/** - * Return the current app name. - */ -function appname() { - return ui.queryParams()['app']; -} +<input id="palette:button" type="button" value="sample button" style="position: absolute; left:20px; top: 20px;"/> +<input id="palette:entry" type="text" value="sample value" style="position: absolute; left:20px; top: 60px;"/> +<span id="palette:text" style="position: absolute; left:20px; top: 100px;">sample text</span> -/** - * Get an app and display it. - */ -function getapp(name) { - if (isNil(name)) - return; - apps.get(name, function(doc) { - var entry = atom.readATOMEntryDocument(doc); - var item = caddr(entry); - var composite = cddr(item); - var comps = scdl.components(composite); +</div> - var g = graph.mkgraph(); - var shapes = graph.composite(composite); - for (var s in shapes) - g.appendChild(shapes[s]); - }); -} +<script type="text/javascript"> +// Install the widget +ui.installwidget(); -// Display the current app -getapp(appname()); +// Enable drag&drop on sample UI elements +page.initpage($('page')); </script> </body> diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.js b/sca-cpp/trunk/modules/edit/htdocs/page/page.js new file mode 100644 index 0000000000..e4554195c1 --- /dev/null +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Page editing functions. + */ +var page = new Object(); + +if (ui.isIE()) { + + /** + * Init a page. + */ + page.initpage = function(elem) { + page.dragging = null; + + function draggable(n) { + if (n == elem) + return null; + if (n.id != '') + return n; + return draggable(n.parentNode); + } + + function bringtotop(n) { + if (n == elem) + return null; + n.parentNode.appendChild(n); + return bringtotop(n.parentNode); + } + + elem.onmousedown = function() { + window.event.returnValue = false; + page.dragging = draggable(window.event.srcElement); + if (page.dragging == null) + return false; + bringtotop(page.dragging); + page.dragX = window.event.clientX; + page.dragY = window.event.clientY; + elem.setCapture(); + return false; + }; + + elem.onmouseup = function() { + if (page.dragging == null) + return false; + page.dragging = null; + elem.releaseCapture(); + return false; + }; + + elem.onmousemove = function() { + if (page.dragging == null) + return false; + var origX = page.dragging.coordorigin.X; + var origY = page.dragging.coordorigin.Y; + var newX = origX - (window.event.clientX - page.dragX); + var newY = origY - (window.event.clientY - page.dragY); + page.dragX = window.event.clientX; + page.dragY = window.event.clientY; + + if (page.dragging.id.substring(0, 8) == 'palette:') { + // Clone the dragged element + page.dragging = page.clone(page.dragging); + } + page.dragging.style.left = newX; + page.dragging.style.top = newY; + return false; + }; + + return elem; + }; + +} else { + + /** + * Init a page. + */ + page.initpage = function(elem) { + page.dragging = null; + + function draggable(n) { + if (n == elem) + return null; + if (n.id != '') + return n; + return draggable(n.parentNode); + } + + function bringtotop(n) { + if (n == elem) + return null; + n.parentNode.appendChild(n); + return bringtotop(n.parentNode); + } + + elem.onmousedown = function(e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue = false; + page.dragging = draggable(e.target); + if (page.dragging == null) + return false; + bringtotop(page.dragging); + var pos = typeof e.touches != "undefined" ? e.touches[0] : e; + page.dragX = pos.clientX; + page.dragY = pos.clientY; + return false; + }; + + elem.ontouchstart = elem.onmousedown; + + elem.onmouseup = function(e) { + if (page.dragging == null) + return false; + page.dragging = null; + return false; + }; + + elem.ontouchend = elem.onmouseup; + + elem.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); + var pos = typeof e.touches != "undefined" ? e.touches[0] : e; + var newX = curX + (pos.clientX - page.dragX); + var newY = curY + (pos.clientY - page.dragY); + page.dragX = pos.clientX; + page.dragY = pos.clientY; + + if (page.dragging.id.substring(0, 8) == 'palette:') { + // Clone the dragged element + page.dragging = page.clone(page.dragging); + } + page.dragging.style.left = newX; + page.dragging.style.top = newY; + return false; + }; + + elem.ontouchmove = elem.onmousemove; + + return elem; + }; +} + +/** + * Clone an HTML element. + */ +page.elemcount = 0; + +page.clone = function(e) { + function mkclone(e) { + if (e.nodeName == 'INPUT' && e.type == 'button') { + var ne = document.createElement('input'); + ne.type = 'button'; + ne.id = 'button' + (++page.elemcount); + ne.value = ne.id; + return ne; + } + if (e.nodeName == 'INPUT' && e.type == 'text') { + var ne = document.createElement('input'); + ne.type = 'text'; + ne.id = 'entry' + (++page.elemcount); + ne.value = ne.id; + return ne; + } + if (e.nodeName == 'SPAN') { + var ne = document.createElement('span'); + ne.id = 'text' + (++page.elemcount); + ne.innerHTML = ne.id; + return ne; + } + } + + function posclone(ne, e) { + ne.style.position = 'absolute'; + ne.style.left = ui.posn(e.style.left); + ne.style.top = ui.posn(e.style.top); + e.parentNode.appendChild(ne); + return ne; + } + + return posclone(mkclone(e), e); +}; + diff --git a/sca-cpp/trunk/modules/edit/palettes.py b/sca-cpp/trunk/modules/edit/palettes.py new file mode 100644 index 0000000000..9d07973cef --- /dev/null +++ b/sca-cpp/trunk/modules/edit/palettes.py @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Palettes collection implementation +import uuid +import sys +from util import * + +# Convert an id to a palette id +def paletteid(id): + return ("'" + car(id), "'palette.composite") + +# Get a palette from the palettes db +def get(id, cache): + if isNil(id): + return ("Palettes", "palettes") + return (car(id), car(id), cache.get(paletteid(id))) + diff --git a/sca-cpp/trunk/modules/edit/palettes/control/palette.composite b/sca-cpp/trunk/modules/edit/palettes/control/palette.composite new file mode 100644 index 0000000000..21aa631217 --- /dev/null +++ b/sca-cpp/trunk/modules/edit/palettes/control/palette.composite @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://control" + name="palette"> + + <service name="if" promote="if"/> + <service name="ifelse" promote="ifelse"/> + <service name="foreach" promote="foreach"/> + + <component name="if" t:color="yellow"> + <t:implementation.python script="if_.py"/> + <service name="if" t:align="top"/> + <reference name="condition"/> + <reference name="do" t:align="bottom"/> + </component> + + <component name="ifelse" t:color="yellow"> + <documentation>if else</documentation> + <t:implementation.python script="ifelse.py"/> + <service name="ifelse" t:align="top"/> + <reference name="condition"/> + <reference name="do" t:align="bottom"/> + <reference name="else" t:align="bottom"/> + </component> + + <component name="foreach" t:color="yellow"> + <documentation>for each</documentation> + <t:implementation.python script="ifelse.py"/> + <service name="foreach" t:align="top"/> + <reference name="list"/> + <reference name="do" t:align="bottom"/> + </component> + +</composite> diff --git a/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite b/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite new file mode 100644 index 0000000000..35f8dfdf9c --- /dev/null +++ b/sca-cpp/trunk/modules/edit/palettes/operators/palette.composite @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://operators" + name="palette"> + + <service name="true" promote="true"/> + <service name="false" promote="false"/> + <service name="and" promote="and"/> + <service name="or" promote="or"/> + <service name="not" promote="not"/> + <service name="equals" promote="equals"/> + <service name="greater" promote="greater"/> + <service name="lesser" promote="lesser"/> + <service name="multiply" promote="multiply"/> + <service name="divide" promote="divide"/> + <service name="add" promote="add"/> + <service name="subtract" promote="subtract"/> + + <component name="true" t:color="green"> + <t:implementation.python script="true_.py"/> + <service name="true"/> + </component> + + <component name="false" t:color="green"> + <t:implementation.python script="false_.py"/> + <service name="false"/> + </component> + + <component name="and" t:color="green"> + <t:implementation.python script="and_.py"/> + <service name="and"/> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="or" t:color="green"> + <t:implementation.python script="or_.py"/> + <service name="or"/> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="not" t:color="green"> + <t:implementation.python script="not_.py"/> + <service name="not"/> + <reference name="value"/> + </component> + + <component name="equals" t:color="green"> + <documentation>=</documentation> + <t:implementation.python script="equals.py"/> + <service name="equals"> + <documentation>=</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="greater" t:color="green"> + <documentation>gt</documentation> + <t:implementation.python script="greater.py"/> + <service name="greater"> + <documentation>gt</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="lesser" t:color="green"> + <documentation>lt</documentation> + <t:implementation.python script="lesser.py"/> + <service name="lesser"> + <documentation>lt</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="multiply" t:color="green"> + <documentation>*</documentation> + <t:implementation.python script="multiply.py"/> + <service name="multiply"> + <documentation>*</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="divide" t:color="green"> + <documentation>/</documentation> + <t:implementation.python script="divide.py"/> + <service name="divide"> + <documentation>/</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="add" t:color="green"> + <documentation>+</documentation> + <t:implementation.python script="add.py"/> + <service name="add"> + <documentation>+</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + + <component name="subtract" t:color="green"> + <documentation>-</documentation> + <t:implementation.python script="subtract.py"/> + <service name="subtract"> + <documentation>-</documentation> + </service> + <reference name="value1"/> + <reference name="value2"/> + </component> + +</composite> diff --git a/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite b/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite new file mode 100644 index 0000000000..20ef8225ce --- /dev/null +++ b/sca-cpp/trunk/modules/edit/palettes/sensors/palette.composite @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://sensors" + name="palette"> + + <service name="location" promote="location"/> + + <component name="location" t:color="magenta"> + <t:implementation.python script="location.py"/> + <service name="location"/> + </component> + +</composite> diff --git a/sca-cpp/trunk/modules/edit/palettes/social/palette.composite b/sca-cpp/trunk/modules/edit/palettes/social/palette.composite new file mode 100644 index 0000000000..264e2ed137 --- /dev/null +++ b/sca-cpp/trunk/modules/edit/palettes/social/palette.composite @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://social" + name="palette"> + + <service name="JSONTwit" promote="JSONTwit"/> + <service name="XMLTwit" promote="XMLTwit"/> + <service name="RSSTwit" promote="RSSTwit"/> + <service name="HTML" promote="HTML"/> + <service name="JSONFB" promote="JSONFB"/> + + <component name="JSONTwit" t:color="red"> + <t:implementation.python script="relay.py"/> + <service name="Relay"> + <t:binding.http uri="jsontwit"/> + </service> + <reference name="target"> + <t:binding.http uri="http://api.twitter.com/1/statuses/user_timeline.json?screen_name=jsdelfino"/> + </reference> + </component> + + <component name="XMLTwit" t:color="green"> + <t:implementation.python script="relay.py"/> + <service name="Relay"> + <t:binding.http uri="xmltwit"/> + </service> + <reference name="target"> + <t:binding.http uri="http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=jsdelfino"/> + </reference> + </component> + + <component name="RSSTwit" t:color="blue"> + <t:implementation.python script="relay.py"/> + <service name="Relay"> + <t:binding.http uri="rsstwit"/> + </service> + <reference name="target"> + <t:binding.http uri="http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=jsdelfino"/> + </reference> + </component> + + <component name="HTML" t:color="yellow"> + <t:implementation.python script="relay.py"/> + <service name="Relay"> + <t:binding.http uri="html"/> + </service> + <reference name="target"> + <t:binding.http uri="http://people.apache.org/~jsdelfino/"/> + </reference> + </component> + + <component name="JSONFB" t:color="orange"> + <t:implementation.python script="relay.py"/> + <service name="Relay"> + <t:binding.http uri="jsonfb"/> + </service> + <reference name="target"> + <t:binding.http uri="https://graph.facebook.com/100001053301307"/> + </reference> + </component> + +</composite> diff --git a/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite b/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite new file mode 100644 index 0000000000..42fc43525b --- /dev/null +++ b/sca-cpp/trunk/modules/edit/palettes/variables/palette.composite @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://variables" + name="palette"> + + <service name="number" promote="number"/> + <service name="text" promote="text"/> + <service name="set" promote="set"/> + <service name="list" promote="list"/> + <service name="first" promote="first"/> + <service name="rest" promote="rest"/> + + <component name="number" t:color="orange"> + <t:implementation.python script="number.py"/> + <service name="number"/> + </component> + + <component name="text" t:color="orange"> + <t:implementation.python script="text.py"/> + <service name="text"/> + </component> + + <component name="set" t:color="orange"> + <documentation>set variable</documentation> + <t:implementation.python script="set.py"/> + <service name="set"/> + <reference name="value"/> + <reference name="variable"/> + </component> + + <component name="list" t:color="orange"> + <documentation>make a list</documentation> + <t:implementation.python script="list_.py"/> + <service name="list"/> + <reference name="first"/> + <reference name="rest"/> + </component> + + <component name="first" t:color="orange"> + <documentation>first of a list</documentation> + <t:implementation.python script="first.py"/> + <service name="first"/> + <reference name="value"/> + </component> + + <component name="rest" t:color="orange"> + <documentation>rest of a list</documentation> + <t:implementation.python script="rest.py"/> + <service name="rest"/> + <reference name="value"/> + </component> + +</composite> diff --git a/sca-cpp/trunk/modules/js/htdocs/scdl.js b/sca-cpp/trunk/modules/js/htdocs/scdl.js index d0b229cae6..561a3e446b 100644 --- a/sca-cpp/trunk/modules/js/htdocs/scdl.js +++ b/sca-cpp/trunk/modules/js/htdocs/scdl.js @@ -23,6 +23,16 @@ var scdl = new Object(); /** + * Returns a composite element. + */ +scdl.composite = function(l) { + var cs = namedElementChildren("'composite", l); + if (isNil(cs)) + return cs; + return car(cs); +}; + +/** * Returns a list of components in a composite. */ scdl.components = function(l) { @@ -60,6 +70,23 @@ scdl.name = function(l) { }; /** + * Returns the description of a component, componentType, service or reference. + */ +scdl.documentation = function(l) { + var d = namedElementChildren("'documentation", l); + if (isNil(d)) + return null; + if (!elementHasValue(car(d))) + return null; + var v = elementValue(car(d)); + if (v == 'gt') + return '>' + if (v == 'lt') + return '<'; + return v; +}; + +/** * Returns the color of a component or componentType. */ scdl.color = function(l) { diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.css b/sca-cpp/trunk/modules/js/htdocs/ui.css index d1413018a0..014cc5110d 100644 --- a/sca-cpp/trunk/modules/js/htdocs/ui.css +++ b/sca-cpp/trunk/modules/js/htdocs/ui.css @@ -35,10 +35,14 @@ border-style: solid; border-top-color: #a2bae7; border-bottom-color: #d1d3d4; } td { -padding-left: 2px; padding-top: 2px; padding-right: 8px; vertical-align: text-top; +padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: nowrap; vertical-align: text-top; } -iframe { +.tdw { +padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; vertical-align: text-top; +} + +.widgetframe { visibility: hidden; width: 0px; height: 0px; } @@ -55,10 +59,6 @@ a:visited { color: blue; } -.tdw { -padding-left: 2px; padding-top: 2px; padding-right: 8px; white-space: normal; vertical-align: text-top; -} - .hd1 { font-size: 150%; font-weight: bold; } diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.js b/sca-cpp/trunk/modules/js/htdocs/ui.js index d8266c7af6..60ca01568e 100644 --- a/sca-cpp/trunk/modules/js/htdocs/ui.js +++ b/sca-cpp/trunk/modules/js/htdocs/ui.js @@ -24,6 +24,16 @@ var ui = new Object(); /** + * Return true if the current browser is Internet Explorer. + */ +ui.isIE = function() { + if (typeof ui.isIE.detected != 'undefined') + return ui.isIE.detected; + ui.isIE.detected = navigator.appName == 'Microsoft Internet Explorer'; + return ui.isIE.detected; +}; + +/** * Build a menu bar. */ ui.menu = function(name, href) { @@ -222,7 +232,12 @@ ui.queryParams = function() { */ ui.widgets = new Array(); -ui.bindwidget = function(f, el) { +ui.loadwidget = function(el, doc) { + var f = el + 'Frame'; + var div = document.createElement('div'); + div.id = f + 'Div'; + div.innerHTML = '<iframe id="' + f + '" class="widgetframe" src="' + doc + '"></iframe>'; + document.body.appendChild(div); window.ui.widgets[f] = el; return f; }; @@ -245,3 +260,12 @@ ui.installwidget = function() { return true; }; +/** + * Convert a CSS position to a numeric position. + */ +ui.posn = function(p) { + if (p == '') + return 0; + return Number(p.substr(0, p.length - 2)); +}; + |