diff --git a/src/bin/sol-fbp-runner/Modal.js b/src/bin/sol-fbp-runner/Modal.js new file mode 100644 index 000000000..ac1a09801 --- /dev/null +++ b/src/bin/sol-fbp-runner/Modal.js @@ -0,0 +1,50 @@ +(function(window) { + + 'use strict' + + function Modal(){ + + var instance = this; + + this.el = $("
").addClass("modal").appendTo("#modal-container"); + this.header = $("").addClass("modal-header").appendTo(this.el); + this.title = $("").appendTo(this.header).addClass("modal-title"); + this.content = $("").appendTo(this.el); + + this.el.hide(); + this.shield = $("").attr("id","shield"); + + this.closeButton = $("").attr("src","images/ico_close.png").addClass("close").appendTo(this.header) + .click(function(){ + instance.hide(); + }); + + + } + + Modal.prototype.show = function(data, title) { + + var instance = this; + + this.title.empty().append(title); + this.content.empty().append(data); + + //adding click to the shield div + this.shield.insertBefore(this.el) + .click(function() { + instance.hide(); + }); + + this.el.show(400); + }; + + Modal.prototype.hide = function() { + this.title.empty(); + this.content.empty(); + this.el.hide(); + this.shield.remove(); + }; + + window.Modal = Modal; + +})(window) diff --git a/src/bin/sol-fbp-runner/Port.js b/src/bin/sol-fbp-runner/Port.js new file mode 100644 index 000000000..1c744611e --- /dev/null +++ b/src/bin/sol-fbp-runner/Port.js @@ -0,0 +1,122 @@ +(function(window) { + + 'use strict' + + function Port (params) { + + //data properties + var instance = this; //returns the __proto__ of the object + + this.name = params["name"]; + this.value = params["value"]; + this.type = params["type"] || "in"; + this.data_type = params["data_type"]; + this.widget = params["widget"]; + this.port_index = params["port_index"]; + this.required = params["required"] || true; + this.key = "port_" + this.type + "_" + params["key"]; + this.connections = []; //the pair port which this port is connected + this.emitt = false; + + //DOM properties + this.el = $("") + .attr("id",this.key) + .addClass("port "+this.getPortType()) + .append(this.name); + + //adding the port to the correct container + if(this.type == "in") this.widget.getLeft().append(this.el); + if(this.type == "out") this.widget.getRight().append(this.el); + + //MOUSE AND CUSTOM EVENTS + this.el.click(function (event) { + $(event.target).trigger({ + type:"port-select", + port:instance, + widget:instance.widget, + value:instance.value + }); + + }); + + this.el.mouseover(function (event) { + $(event.target).trigger({ + type:"port-over", + port:instance, + widget:instance.widget, + connections:instance.connections + }); + }); + + this.el.mouseout(function (event) { + $(event.target).trigger({ + type:"port-out", + port:instance, + widget:instance.widget, + connections:instance.connections + }); + }); + } + + Port.prototype.update = function (value) { + + this.value = value; //retrieves only the valu + + var widget = this.widget; + var instance = this.instance; + + if(this.emitt) this.el.trigger( + { + type:"port-update", + widget:widget, + port:instance, + value:value, + }); + } + + Port.prototype.getElement = function() { + return this.el; + } + + Port.prototype.getParentWidget = function() { + return this.widget; + } + + Port.prototype.getPortType = function() { + return (this.type === "in") ? "in" : "out"; + } + + Port.prototype.select = function() { + this.emitt = true; + this.el.addClass("selected"); + } + + Port.prototype.unselect = function() { + this.emitt = false; + this.el.removeClass("selected"); + } + + Port.prototype.connect = function (port) { + + //ERROR TRYING TO CONNECT PORTs! + if(this.connections.indexOf(port.key) == -1) + { + this.connections.push(port.key); + this.widget.autoSelectPort(this); + } + + } + + Port.prototype.hidePort = function() { + this.el.addClass("hidden"); + this.el.addClass("non-selectable"); + this.el.unbind(); + } + + Port.prototype.showPort = function() { + //TODO + } + + window.Port = Port; + +})(window) diff --git a/src/bin/sol-fbp-runner/Widget.js b/src/bin/sol-fbp-runner/Widget.js new file mode 100644 index 000000000..56e553aa0 --- /dev/null +++ b/src/bin/sol-fbp-runner/Widget.js @@ -0,0 +1,222 @@ +(function(window) { + + 'use strict' + + function Widget(payload, key) { + + //caching a secure reference to the instance + var instance = this; + //var selectedPort; + + Widget.prototype.portsCount = 0; + + //unique id for the widget and other unique properties + this.raw = JSON.stringify(payload, null, 4); + this.key = key; + this.widgetName = payload.id; //change to 'name ?' + this.uid = payload.path[payload.path.length-1]; + this.type = payload.type; + this.category = payload.category; + this.description = payload.description; + this.url = payload.url; + this.portsIn = []; + this.portsOut = []; + this.autoSelected = false; + this.hidden = true; + this.selectedPort = null; + this.totalPorts = 0; + + //TODO: we should change the id key to name + this.name = "widget" + payload.id; + + //title and subtitle of the widget + this.title = $("").addClass("widget-title").append(this.widgetName); + this.subtitle = $("").addClass("widget-subtitle").append(this.type); + + //info button + var info = $("").attr("src","images/ico_info.png").addClass("info"); + info.click(function(event) { + window.modal.show(instance.raw, instance.type); + }); + + //creating DOM elements + this.displayValue = $("").addClass("display-value"); + this.el = $("").addClass("widget").attr("id",this.uid).appendTo("#container"); + $("").addClass("widget-header").appendTo(this.el).append(this.title).append(this.subtitle).append(info); + $("").addClass("widget-display").appendTo(this.el).addClass("widget-data").append(this.displayValue); + this.widgetPorts = $("").addClass("widget-ports").appendTo(this.el); + + //putting the ports in the correct container + this.lports = $("").addClass("port-container").appendTo("#"+this.uid + " .widget-ports"); + this.rports = $("").addClass("port-container").appendTo("#"+this.uid + " .widget-ports"); + + //reading all in ports + var port; + payload.ports_in.forEach(function(element, index) { + port = new Port( + { + name:element["name"], + value:undefined, + type:"in", + port_index:element["base_port_idx"], + data_type:element["data_type"], + required:element["required"], + widget:instance, + key:instance.key + "_" + Widget.prototype.portsCount + }); + + instance.portsIn.push(port); + instance.totalPorts++; + port.el.on("port-select", instance.onPortSelect); + Widget.prototype.portsCount ++; + }); + + //reading all out ports + payload.ports_out.forEach(function(element, index) { + port = new Port( + { + name:element["name"], + value:undefined, + type:"out", + port_index:element["base_port_idx"], + data_type:element["data_type"], + required:element["required"], + widget:instance, + key:instance.key + "_" + Widget.prototype.portsCount + }); + instance.portsOut.push(port); + instance.totalPorts++; + port.el.on("port-select", instance.onPortSelect); + Widget.prototype.portsCount ++; + }); + + //Auto Adjusting the size of the Widget Container + var h = Math.max(this.portsIn.length, this.portsOut.length) * 26; + this.widgetPorts.css("height",h); + + } + + Widget.prototype.onPortSelect = function(event) { + event.widget.selectPort(event.port, event.value); + }; + + Widget.prototype.getUID = function() { + return this.uid; + }; + + //UPDATES THE VALUES OF ALL PORTS + Widget.prototype.update = function(type, data) { + + //getting the child ports of the widget + var port = (type === "deliver") ? this.portsIn[data.port_idx] : this.portsOut[data.port_idx]; + + //if the ports have no pair, skip + if(port.connections.length < 0) return; + + //found paired ports, update its value + var packet = data.packet; + var packetType = packet.packet_type; + + if(packetType === "empty"){ + port.update("empty"); + }else if(packetType === "int" || packetType === "float"){ + port.update(packet.payload.value) + }else if(packetType === "byte"){ + port.update(packet.payload); + }else if(packetType === "boolean"){ + port.update(packet.payload.toString()); + } + }; + + Widget.prototype.fadeIn = function(delay) { + var instance = this; + setTimeout(function(){ + instance.el.fadeIn(300); + },delay); + }; + + Widget.prototype.clearPorts = function() { + + this.portsIn.forEach(function(p, i){ + if(p.connections.length === 0){ + p.hidePort(); + } + }) + + this.portsOut.forEach(function(p, i){ + if(p.connections === 0){ + p.hidePort(); + } + }) + }; + + Widget.prototype.autoSelectPort = function(port) { + if(this.selectedPort == null){ + this.selectPort(port,port.value); + } + }; + + Widget.prototype.selectPort = function(port, value) { + + //dealing with repeated port click + if(port === this.selectedPort) { + port.unselect(); + this.unsubscribe(port); + this.selectedPort = null; + return; + } + + //clearing last selected port + if(this.selectedPort != null) { + this.selectedPort.unselect(); + this.unsubscribe(port); + } + + //selecting new port + this.clearDisplay().append(value); + this.selectedPort = port; + this.selectedPort.select(); + this.subscribe(port); + }; + + Widget.prototype.onPortValueChange = function(event) { + event.widget.clearDisplay().append(event.value); + }; + + Widget.prototype.subscribe = function(port) { + port.el.on('port-update', this.onPortValueChange); + }; + + Widget.prototype.unsubscribe = function(port) { + port.el.off('port-update', this.onPortValueChange); + this.clearDisplay(port.widget); + }; + + Widget.prototype.clearDisplay = function() { + var display = $("#" + this.uid + " .display-value").empty(); + return display; + }; + + Widget.prototype.getElement = function() { + return this.el; + }; + + Widget.prototype.getLeft = function() { + return this.lports; + }; + + Widget.prototype.getRight = function() { + return this.rports; + }; + + Widget.prototype.getInByIndex = function(index) { + return this.portsIn[index]; + }; + + Widget.prototype.getOutByIndex = function(index) { + return this.portsOut[index]; + }; + + window.Widget = Widget; + +})(window) diff --git a/src/bin/sol-fbp-runner/css/style.css b/src/bin/sol-fbp-runner/css/style.css new file mode 100644 index 000000000..3d5bce215 --- /dev/null +++ b/src/bin/sol-fbp-runner/css/style.css @@ -0,0 +1,192 @@ +/* + * This file is part of the Soletta Project + * + * Copyright (C) 2015 Intel Corporation. All rights reserved. + * + * Licensed 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. + */ +* { + font-family: Arial, Helvetica, sans-serif; +} +body { + background-color: #4C5155; +} +h1 { + background-color: blue; +} +body { + margin: 0px; + border: 0px; +} +.widget { + width: 180px; + margin: 10px; + overflow: hidden; + float: left; +} +.widget-header { + background-color: #2D3237; + color: white; + width: 100%; + height: 46px; + padding-left: 10px; + padding-top: 10px; +} +.widget-title { + width: 140px; + overflow: hidden; + color: white; + font-size: 1.3em !important; + display: block; +} +.widget-subitle { + width: 140px; + height: 15px; + overflow: hidden; + font-size: 8px !important; + display: block; + background-color: red; +} +.widget-display { + background-Color: white; + width: 100%; + height: 120px; +} +.display-value { + display: block; + word-wrap: break-word; + margin-left: 30px; + margin-right: 30px; + padding-top: 20px; + color: #2D3237; +} +.widget-data { + font-size: 2em; +} +.widget-ports { + width: 100%; + background-color: #777E83; +} +.port { + width: 85px; + /*border-bottom: 1px solid @gray;*/ + color: white; + font-size: .6em; + padding: 8px 0; + cursor: pointer; + overflow: hidden; +} +.port.in { + background-color: #777E83; + float: left; + text-align: left; + border-right: 1px solid white; + padding-left: 8px; +} +.port.out { + background-color: #777E83; + float: right; + text-align: right; + border-left: 1px solid white; + margin-left: -4px; + padding-right: 8px; +} +.port.selected { + background-color: #2D3237; +} +.port.paired-slave { + background-color: #E71C4C; +} +.port.paired-master { + background-color: #39CD89; +} +.port.hidden { + opacity: 0.2; + cursor: default; +} +.port-container { + width: 50%; + min-height: 50px; + float: left; + overflow: hidden; +} +.info { + float: right; + border: 0; + cursor: pointer; + width: 16px; + height: 16px; + margin-right: 18px; + margin-top: -18px; +} +.close { + float: right; + border: 0; + cursor: pointer; + width: 24px; + height: 24px; + -webkit-filter: invert(100%); + filter: invert(100%); +} +.modal { + width: 750px; + height: 500px; + overflow: hidden; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: white; +} +.modal-header { + background-color: #7595C3; + height: 30px; + padding: .5em; + overflow: hidden; +} +.modal-title { + font-size: 2em; + color: white; + margin: 15px; +} +#shield { + position: fixed; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); +} +pre { + position: absolute; + height: 455px; + width: 735px; + left: 15px; + background-color: white; + color: #2D3237; + overflow-y: scroll; + top: 30px; +} +.non-selectable { + -webkit-touch-callout: none; + /* iOS Safari */ + -webkit-user-select: none; + /* Chrome/Safari/Opera */ + -khtml-user-select: none; + /* Konqueror */ + -moz-user-select: none; + /* Firefox */ + -ms-user-select: none; + /* Internet Explorer/Edge */ + user-select: none; + /* Non-prefixed version, currently + not supported by any browser */ +} diff --git a/src/bin/sol-fbp-runner/images/ico_close.png b/src/bin/sol-fbp-runner/images/ico_close.png new file mode 100644 index 000000000..b8cfbb37e Binary files /dev/null and b/src/bin/sol-fbp-runner/images/ico_close.png differ diff --git a/src/bin/sol-fbp-runner/images/ico_info.png b/src/bin/sol-fbp-runner/images/ico_info.png new file mode 100644 index 000000000..7311e9364 Binary files /dev/null and b/src/bin/sol-fbp-runner/images/ico_info.png differ diff --git a/src/bin/sol-fbp-runner/web-inspector.css b/src/bin/sol-fbp-runner/web-inspector.css index 9154bd652..18430e8b6 100644 --- a/src/bin/sol-fbp-runner/web-inspector.css +++ b/src/bin/sol-fbp-runner/web-inspector.css @@ -16,173 +16,37 @@ * limitations under the License. */ -td.fbp-node-ports-in, td.fbp-node-ports-out { - min-width: 300pt; -} - -div.fbp-node-port-names-in, div.fbp-node-port-names-out { - font-family: monospace; - color: #333; -} - -div.fbp-node-port-description-in, div.fbp-node-port-description-out { - font-family: sans-serif; - font-size: smaller; - color: #999; -} - -div.fbp-node-port-data_type-in, div.fbp-node-port-data_type-in, span.fbp-packet { - font-family: monospace; -} - -span.fbp-packet-type-rgb-preview { - margin: 2pt 2pt 2pt 2pt; - padding: 2pt 2pt 2pt 2pt; - display: inline-block; - width: 10pt; - height: 10pt; - border: 1px solid black; -} - -div.fbp-node-port-required-true { - font-weight: bold; -} - -span.fbp-packet-type-int { - color: #0000aa; -} - -span.fbp-packet-type-float { - color: #aa00aa; -} - -span.fbp-packet-type-string { - color: #aa7700; -} - -span.fbp-packet-type-error { - color: #ff0000; -} - -span.fbp-packet-type-boolean { - color: #0077aa; -} - -table#fbp-container-inspector { - width: 100%; -} - -td.fbp-node-ports-in, td.fbp-node-ports-out { - padding-top: 30pt; - vertical-align: top; -} - -td.fbp-node-info h3 { - height: 30pt; - font-size: 1em; -} - -table.fbp-log { - width: 100%; -} - -table.fbp-log thead, table.fbp-log tbody { - display: block; -} - -table.fbp-log tbody { - height: 100pt; - overflow-y: auto; - overflow-x: auto; -} - -table.fbp-log tr td { - font-family: monospace; - font-size: smaller; -} - -td.fbp-log-timestamp { - text-align: right; -} - -td.fbp-node-info { - vertical-align: top; - min-width: 300pt; - border: 1px solid #ccc; - background-color: #d9d9d9; -} - -td.fbp-node-info dl { - font-size: x-small; -} - -td.fbp-node-info dl dt { - color: #666; - float: left; - clear: left; -} - -td.fbp-node-info dl dt:after { - content: ": "; -} - -td.fbp-node-info dl dd { - color: #333; - padding: 0 0 0.5em 0; - -webkit-margin-start: 10pt; -} - -span.fbp-node-option-type-rgb-preview { - margin: 1pt 1pt 1pt 1pt; - padding: 1pt 1pt 1pt 1pt; - display: inline-block; - width: 10pt; - height: 8pt; - border: 1px solid black; -} - -div.fbp-node-port-info-in, div.fbp-node-port-info-out, div.fbp-node-options-info { -} - -div.fbp-node-port-container-in, div.fbp-node-port-container-out { - margin: 1pt 1pt 1pt; - padding: 2pt 2pt 2pt; -} - -div.fbp-node-port-name-in { - margin: 1pt 1pt 1pt; - padding: 2pt 2pt 2pt; - float: right; - clear: right; - background-color: #d9d9d9; - border: 1px solid #ccc; -} - -div.fbp-node-port-value-in { - float: right; -} - -div.fbp-node-port-name-out { - margin: 1pt 1pt 1pt; - padding: 2pt 2pt 2pt; - float: left; - clear: left; - background-color: #d9d9d9; - border: 1px solid #ccc; -} - -div.fbp-node-port-value-out { - float: left; -} - -div.fbp-node-port-data_type-in-float div div div.fbp-node-port-name-in, div.fbp-node-port-data_type-out-float div div div.fbp-node-port-name-out { - background-color: #ff66ff; -} - -div.fbp-node-port-data_type-in-int div div div.fbp-node-port-name-in, div.fbp-node-port-data_type-out-int div div div.fbp-node-port-name-out { - background-color: #6666ff; -} - -div.fbp-node-port-data_type-in-boolean div div div.fbp-node-port-name-in, div.fbp-node-port-data_type-out-boolean div div div.fbp-node-port-name-out { - background-color: #66aaff; -} +.widget{ + background-color: #C0C0C0; + width:350px; + height:360px; + float:left; + margin:10px; + overflow: hidden;; + border-radius: 10px; +} +.widgetHeader{ + background-Color:#A0A0A0; + width: 350px; + height:50px; + padding-left: 10px; + padding-top: 10px +} +.widgetData{ + font-size: 3em; +} + +.port-in{ + width:100px; + height:30px; + background-color: #00FF00; + margin: 1px; + padding: 4px; +} +.port-out{ + width:100px; + height:30px; + background-color: #FF0000; + margin: 1px; + padding: 4px; +} \ No newline at end of file diff --git a/src/bin/sol-fbp-runner/web-inspector.html b/src/bin/sol-fbp-runner/web-inspector.html index a0f83ef8e..af80e96fd 100644 --- a/src/bin/sol-fbp-runner/web-inspector.html +++ b/src/bin/sol-fbp-runner/web-inspector.html @@ -1,57 +1,21 @@ - - - - - - -Input Ports | -Node | -Output Ports | - - - -
---|
Timestamp | -Node | -Port | -Packet | - - - -
---|
Timestamp | -Node | -Port | -Packet | - - - -
---|