robeaux 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gruntfile.js +43 -0
- data/Makefile +11 -2
- data/README.markdown +2 -0
- data/css/main.css +1 -0
- data/css/style.css +113 -24
- data/css/themes/blackboard.css +1 -0
- data/css/themes/dark.css +1 -0
- data/css/themes/gray.css +1 -0
- data/css/themes/whiteboard.css +1 -0
- data/images/bullet-connections-2.png +0 -0
- data/images/bullet-connections.png +0 -0
- data/images/bullet-devices-2.png +0 -0
- data/images/bullet-devices.png +0 -0
- data/images/devices-image-2.png +0 -0
- data/images/devices-image.png +0 -0
- data/images/logo-robeaux.png +0 -0
- data/images/robots-icon_03.png +0 -0
- data/index.html +15 -8
- data/js/controllers/widget_editor_ctrl.js +44 -0
- data/js/controllers/widgets_ctrl.js +40 -0
- data/js/directives/widget.js +50 -0
- data/js/router.js +5 -0
- data/js/services/themes.js +9 -5
- data/js/services/widgets.js +86 -0
- data/js/vendor/angular-route.min.js +1 -2
- data/js/vendor/angular.min.js +208 -206
- data/js/widgets/attitude.html +32 -0
- data/js/widgets/attitude.js +27 -0
- data/js/widgets/mindwave.html +51 -0
- data/js/widgets/mindwave.js +23 -0
- data/less/app.less +21 -0
- data/less/objects/buttons.less +32 -0
- data/less/objects/connections.less +28 -0
- data/less/objects/device.less +30 -0
- data/less/objects/forms.less +29 -0
- data/less/objects/list.less +27 -0
- data/less/objects/nav.less +33 -0
- data/less/objects/robot.less +43 -0
- data/less/objects/themes.less +18 -0
- data/less/objects/widgets.less +85 -0
- data/less/support/buttons.less +39 -0
- data/less/support/container.less +9 -0
- data/less/support/forms.less +18 -0
- data/less/support/mixins.less +3 -0
- data/less/themes/blackboard.less +158 -0
- data/less/themes/dark.less +148 -0
- data/less/themes/default.less +52 -0
- data/less/themes/gray.less +121 -0
- data/less/themes/whiteboard.less +152 -0
- data/less/vendor/elements.less +156 -0
- data/less/vendor/normalize.less +425 -0
- data/less/vendor/semantic-grid.less +67 -0
- data/less/views/devices.less +47 -0
- data/less/views/robots.less +132 -0
- data/less/views/themes.less +31 -0
- data/less/views/widgets.less +50 -0
- data/package.json +6 -3
- data/partials/device.html +66 -57
- data/partials/index.html +12 -6
- data/partials/robot.html +104 -51
- data/partials/themes.html +32 -29
- data/partials/widget_editor.html +68 -0
- data/robeaux.gemspec +1 -1
- data/test/controllers/device_commands_ctrl.js +129 -0
- data/test/controllers/device_events_ctrl.js +82 -0
- data/test/controllers/index_ctrl.js +48 -0
- data/test/controllers/nav_ctrl.js +40 -0
- data/test/controllers/robot_commands_ctrl.js +127 -0
- data/test/controllers/robot_ctrl.js +62 -0
- data/test/controllers/themes_ctrl.js +96 -0
- data/test/controllers/widget_editor_ctrl.js +111 -0
- data/test/controllers/widgets_ctrl.js +74 -0
- data/test/functions/functions.js +30 -0
- data/test/karma.conf.js +3 -7
- data/test/karma_test_all.conf.js +23 -0
- data/test/karma_test_controllers.conf.js +19 -0
- data/test/karma_test_functions.conf.js +14 -0
- data/test/karma_test_services.conf.js +17 -0
- data/test/services/themes.js +122 -0
- data/test/services/widgets.js +104 -0
- data/test/support/themes.json +9 -0
- data/test/support/widgets.json +18 -0
- data/test/vendor/angular-mocks.js +13 -13
- data/test/vendor/jquery.js +8 -8
- metadata +69 -3
- data/test/main.js +0 -248
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="attitude" ng-style="styles()">
|
2
|
+
<div class="sky"></div>
|
3
|
+
<div class="earth"></div>
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<style>
|
7
|
+
widget[data-name="attitude"] {
|
8
|
+
overflow: hidden;
|
9
|
+
}
|
10
|
+
|
11
|
+
widget[data-name="attitude"] .attitude {
|
12
|
+
width: 200%;
|
13
|
+
height: 200%;
|
14
|
+
margin-left: -50%;
|
15
|
+
margin-top: -50%;
|
16
|
+
}
|
17
|
+
|
18
|
+
widget[data-name="attitude"] .attitude div {
|
19
|
+
width: 100%;
|
20
|
+
height: 54%;
|
21
|
+
padding: 0;
|
22
|
+
margin: 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
widget[data-name="attitude"] .attitude .sky {
|
26
|
+
background: #02A2F9;
|
27
|
+
}
|
28
|
+
|
29
|
+
widget[data-name="attitude"] .attitude .earth {
|
30
|
+
background: #A07857;
|
31
|
+
}
|
32
|
+
</style>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
$scope.styles = function() {
|
2
|
+
var styles = {};
|
3
|
+
|
4
|
+
var prefixes = [
|
5
|
+
"-webkit-",
|
6
|
+
"-moz-",
|
7
|
+
"-ms-",
|
8
|
+
"-o-",
|
9
|
+
""
|
10
|
+
];
|
11
|
+
|
12
|
+
prefixes.forEach(function(prefix) {
|
13
|
+
styles[prefix + "transform"] = "rotate(" + $scope.attitude / 4 + "turn)";
|
14
|
+
});
|
15
|
+
|
16
|
+
return styles;
|
17
|
+
};
|
18
|
+
|
19
|
+
var url = "/api/robots/" + $attrs.robot + "/devices/" + $attrs.device + "/events/" + $attrs.event;
|
20
|
+
|
21
|
+
var es = new EventSource(url);
|
22
|
+
|
23
|
+
es.addEventListener('message', function(message) {
|
24
|
+
$scope.$apply(function() {
|
25
|
+
$scope.attitude = JSON.parse(message.data);
|
26
|
+
});
|
27
|
+
}, false);
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<div class="column {{ name }}"
|
2
|
+
ng-style="{ 'height': value + '%', 'left': (22 * $index) + 'px' }"
|
3
|
+
ng-repeat="(name, value) in eeg">
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<style>
|
7
|
+
widget[data-name="mindwave"] {
|
8
|
+
position: relative;
|
9
|
+
}
|
10
|
+
|
11
|
+
widget[data-name="mindwave"] .column {
|
12
|
+
display: inline-bLock;
|
13
|
+
background: red;
|
14
|
+
width: 20px;
|
15
|
+
margin: 2px;
|
16
|
+
position: absolute;
|
17
|
+
bottom: 10px;
|
18
|
+
}
|
19
|
+
|
20
|
+
widget[data-name='mindwave'] .Delta {
|
21
|
+
background: #52A6FF;
|
22
|
+
}
|
23
|
+
|
24
|
+
widget[data-name='mindwave'] .Theta {
|
25
|
+
background: #BF3629;
|
26
|
+
}
|
27
|
+
|
28
|
+
widget[data-name='mindwave'] .LoAlpha {
|
29
|
+
background: #61BF40;
|
30
|
+
}
|
31
|
+
|
32
|
+
widget[data-name='mindwave'] .HiAlpha {
|
33
|
+
background: #417F2B;
|
34
|
+
}
|
35
|
+
|
36
|
+
widget[data-name='mindwave'] .LoBeta {
|
37
|
+
background: #895ABF;
|
38
|
+
}
|
39
|
+
|
40
|
+
widget[data-name='mindwave'] .HiBeta {
|
41
|
+
background: #5C3C7F;
|
42
|
+
}
|
43
|
+
|
44
|
+
widget[data-name='mindwave'] .LoGamma {
|
45
|
+
background: #536FBF;
|
46
|
+
}
|
47
|
+
|
48
|
+
widget[data-name='mindwave'] .MidGamma {
|
49
|
+
background: #374A7F;
|
50
|
+
}
|
51
|
+
</style>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
var scaleEEG = function(original) {
|
2
|
+
var eeg = {};
|
3
|
+
|
4
|
+
for (var key in original) {
|
5
|
+
var num = original[key];
|
6
|
+
num = (num / 20000000) * 100;
|
7
|
+
eeg[key] = num;
|
8
|
+
}
|
9
|
+
|
10
|
+
return eeg;
|
11
|
+
};
|
12
|
+
|
13
|
+
var url = "/api/robots/" + $attrs.robot + "/devices/" + $attrs.device + "/events/" + $attrs.event;
|
14
|
+
|
15
|
+
var es = new EventSource(url);
|
16
|
+
|
17
|
+
es.addEventListener('message', function(message) {
|
18
|
+
var eeg = JSON.parse(message.data);
|
19
|
+
|
20
|
+
$scope.$apply(function() {
|
21
|
+
$scope.eeg = scaleEEG(eeg);
|
22
|
+
});
|
23
|
+
}, false);
|
data/less/app.less
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
@import 'vendor/elements';
|
2
|
+
@import 'vendor/semantic-grid';
|
3
|
+
@import 'themes/default';
|
4
|
+
@import 'support/mixins';
|
5
|
+
|
6
|
+
/* Objects */
|
7
|
+
@import 'objects/buttons';
|
8
|
+
@import 'objects/connections';
|
9
|
+
@import 'objects/device';
|
10
|
+
@import 'objects/forms';
|
11
|
+
@import 'objects/list';
|
12
|
+
@import 'objects/nav';
|
13
|
+
@import 'objects/robot';
|
14
|
+
@import 'objects/themes';
|
15
|
+
@import 'objects/widgets';
|
16
|
+
|
17
|
+
/* Views */
|
18
|
+
@import 'views/devices';
|
19
|
+
@import 'views/robots';
|
20
|
+
@import 'views/themes';
|
21
|
+
@import 'views/widgets';
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.btn {
|
2
|
+
.button-size(10px; 15px; 15px; 20px; 5px);
|
3
|
+
display: inline-block;
|
4
|
+
border: 0;
|
5
|
+
&:hover {
|
6
|
+
cursor: pointer;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
.btn-big {
|
11
|
+
.button-size(15px; 30px; 15px; 15px; 5px);
|
12
|
+
}
|
13
|
+
|
14
|
+
.btn-robot {
|
15
|
+
.button-variant(@btn-robot-color; @btn-robot-background; @btn-robot-color);
|
16
|
+
text-transform: uppercase;
|
17
|
+
}
|
18
|
+
|
19
|
+
.btn-run, .btn-reset {
|
20
|
+
.button-variant(@btn-run-color; @btn-run-background; @btn-run-color);
|
21
|
+
text-transform: uppercase;
|
22
|
+
}
|
23
|
+
|
24
|
+
.btn-device, .btn-save {
|
25
|
+
.button-variant(@btn-device-color; @btn-device-background; @btn-device-color);
|
26
|
+
text-transform: uppercase;
|
27
|
+
}
|
28
|
+
|
29
|
+
.btn-connect {
|
30
|
+
.button-variant(@btn-connect-color; @btn-connect-background; @btn-connect-color);
|
31
|
+
text-transform: uppercase;
|
32
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
.connections {
|
2
|
+
.robot-devices {
|
3
|
+
.name {
|
4
|
+
display: inline-block;
|
5
|
+
margin-left: 20px;
|
6
|
+
font-weight: bold;
|
7
|
+
}
|
8
|
+
|
9
|
+
.details {
|
10
|
+
display: inline-block;
|
11
|
+
margin-left: 20px;
|
12
|
+
color: @color04;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
.robot-connections {
|
17
|
+
.name {
|
18
|
+
display: inline-block;
|
19
|
+
margin-left: 20px;
|
20
|
+
color: @color04;
|
21
|
+
}
|
22
|
+
|
23
|
+
.details {
|
24
|
+
display: inline-block;
|
25
|
+
margin-left: 20px;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
.device-detail {
|
2
|
+
h2 {
|
3
|
+
text-align: center;
|
4
|
+
}
|
5
|
+
|
6
|
+
table {
|
7
|
+
margin-top: 15px;
|
8
|
+
|
9
|
+
th {
|
10
|
+
border-bottom: 1px solid #ccc;
|
11
|
+
line-height: 34px;
|
12
|
+
}
|
13
|
+
|
14
|
+
td {
|
15
|
+
font-family: @code-font-family;
|
16
|
+
padding: 3px;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
.listeners {
|
21
|
+
margin-top: 0;
|
22
|
+
}
|
23
|
+
|
24
|
+
.remove {
|
25
|
+
color: #f00;
|
26
|
+
&:hover {
|
27
|
+
cursor: pointer;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
input[type="text"], select, textarea {
|
2
|
+
display: inline-block;
|
3
|
+
line-height: @line-height-base;
|
4
|
+
font-size: @body-font-size;
|
5
|
+
color: @body-text-color;
|
6
|
+
.form-control();
|
7
|
+
.form-control-focus(@input-border-color-focus);
|
8
|
+
box-sizing: border-box;
|
9
|
+
}
|
10
|
+
|
11
|
+
button {
|
12
|
+
outline: none;
|
13
|
+
}
|
14
|
+
|
15
|
+
button::-moz-focus-inner,
|
16
|
+
input[type="reset"]::-moz-focus-inner,
|
17
|
+
input[type="button"]::-moz-focus-inner,
|
18
|
+
input[type="submit"]::-moz-focus-inner,
|
19
|
+
input[type="file"] > input[type="button"]::-moz-focus-inner {
|
20
|
+
outline: none;
|
21
|
+
}
|
22
|
+
|
23
|
+
button:focus::-moz-focus-inner,
|
24
|
+
input[type="reset"]:focus::-moz-focus-inner,
|
25
|
+
input[type="button"]:focus::-moz-focus-inner,
|
26
|
+
input[type="submit"]:focus::-moz-focus-inner,
|
27
|
+
input[type="file"] > input[type="button"]:focus::-moz-focus-inner {
|
28
|
+
outline: none;
|
29
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
.list {
|
2
|
+
margin-top: 20px;
|
3
|
+
|
4
|
+
.close {
|
5
|
+
float: right;
|
6
|
+
color: #ccc;
|
7
|
+
&:hover {
|
8
|
+
color: #f00;
|
9
|
+
cursor: pointer;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
.theme, .widget {
|
14
|
+
display: block;
|
15
|
+
clear: both;
|
16
|
+
padding: 5px;
|
17
|
+
border-bottom: 1px dotted #ccc;
|
18
|
+
|
19
|
+
&:hover {
|
20
|
+
cursor: pointer;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
.selected {
|
25
|
+
background: #eee;
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
nav {
|
3
|
+
background: @nav-background-color;
|
4
|
+
height: 70px;
|
5
|
+
margin-bottom: 20px;
|
6
|
+
|
7
|
+
.logo {
|
8
|
+
display: inline-block;
|
9
|
+
margin: 15px 15px 0 15px;
|
10
|
+
}
|
11
|
+
|
12
|
+
.links {
|
13
|
+
float: right;
|
14
|
+
margin-top: 15px;
|
15
|
+
a {
|
16
|
+
color: @nav-link-color;
|
17
|
+
text-decoration: none;
|
18
|
+
display: inline-block;
|
19
|
+
.button-size(10px; 15px; 15px; 20px; 2px);
|
20
|
+
&:hover {
|
21
|
+
color: @nav-link-color-hover;
|
22
|
+
text-decoration: none;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
.active {
|
27
|
+
background: @nav-link-background-hover;
|
28
|
+
&:hover {
|
29
|
+
color: @nav-link-color;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
.robot {
|
2
|
+
.container();
|
3
|
+
|
4
|
+
.details {
|
5
|
+
float: right;
|
6
|
+
line-height: 43px;
|
7
|
+
span {
|
8
|
+
color: @connection-digits-color;
|
9
|
+
margin-left: 50px;
|
10
|
+
}
|
11
|
+
|
12
|
+
strong {
|
13
|
+
color: @body-text-color;
|
14
|
+
margin-right: 20px;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
.name {
|
19
|
+
margin-left: 20px;
|
20
|
+
}
|
21
|
+
|
22
|
+
.commands {
|
23
|
+
.clearfix();
|
24
|
+
|
25
|
+
button {
|
26
|
+
display: block;
|
27
|
+
font-weight: bold;
|
28
|
+
margin-top: 15px;
|
29
|
+
}
|
30
|
+
|
31
|
+
table {
|
32
|
+
th {
|
33
|
+
border-bottom: 1px solid #ccc;
|
34
|
+
line-height: 34px;
|
35
|
+
}
|
36
|
+
|
37
|
+
td {
|
38
|
+
font-family: @code-font-family;
|
39
|
+
padding: 3px;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
.widgets {
|
2
|
+
.new-widget, .new-attr {
|
3
|
+
input {
|
4
|
+
padding: 8px 12px;
|
5
|
+
}
|
6
|
+
}
|
7
|
+
|
8
|
+
.new-attr {
|
9
|
+
padding-top: 15px;
|
10
|
+
}
|
11
|
+
|
12
|
+
.attrs {
|
13
|
+
padding-bottom: 20px;
|
14
|
+
}
|
15
|
+
|
16
|
+
.footer {
|
17
|
+
text-align: right;
|
18
|
+
|
19
|
+
.btn-reset {
|
20
|
+
margin-right: 10px;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
.new-widget-instance {
|
25
|
+
position: fixed;
|
26
|
+
top: 0;
|
27
|
+
left: 0;
|
28
|
+
background-color: rgba(0,0,0,0.5);
|
29
|
+
z-index: 99;
|
30
|
+
overflow: hidden;
|
31
|
+
}
|
32
|
+
|
33
|
+
.panel {
|
34
|
+
background: @modal-bg-color;
|
35
|
+
padding: 6px;
|
36
|
+
.rounded(4px);
|
37
|
+
position: relative;
|
38
|
+
.drop-shadow(0, 0, 5px, 0.3);
|
39
|
+
overflow: hidden;
|
40
|
+
|
41
|
+
.panel-header, .panel-body, .panel-footer {
|
42
|
+
.clearfix();
|
43
|
+
}
|
44
|
+
|
45
|
+
.panel-header {
|
46
|
+
border-bottom: 1px solid #eaeaea;
|
47
|
+
}
|
48
|
+
|
49
|
+
.panel-footer {
|
50
|
+
border-top: 1px solid #eaeaea;
|
51
|
+
padding-top: 6px;
|
52
|
+
margin-top: 12px;
|
53
|
+
text-align: right;
|
54
|
+
}
|
55
|
+
|
56
|
+
.close {
|
57
|
+
position: absolute;
|
58
|
+
top: 4px;
|
59
|
+
right: 10px;
|
60
|
+
color: #ccc;
|
61
|
+
&:hover {
|
62
|
+
cursor: pointer;
|
63
|
+
color: #f00;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
h2 {
|
68
|
+
margin: 0 0 15px 0;
|
69
|
+
text-align: center;
|
70
|
+
}
|
71
|
+
|
72
|
+
h3, label {
|
73
|
+
font-size: 14px;
|
74
|
+
}
|
75
|
+
|
76
|
+
select {
|
77
|
+
display: block;
|
78
|
+
}
|
79
|
+
|
80
|
+
.attr-element {
|
81
|
+
.clearfix();
|
82
|
+
margin-bottom: 10px;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
.button-variant(@color; @background; @border) {
|
2
|
+
color: @color;
|
3
|
+
background-color: @background;
|
4
|
+
border-color: @border;
|
5
|
+
|
6
|
+
&:hover,
|
7
|
+
&:focus,
|
8
|
+
&:active,
|
9
|
+
&.active {
|
10
|
+
color: @color;
|
11
|
+
background-color: darken(@background, 10%);
|
12
|
+
border-color: darken(@border, 12%);
|
13
|
+
}
|
14
|
+
|
15
|
+
&:active,
|
16
|
+
&.active {
|
17
|
+
background-image: none;
|
18
|
+
}
|
19
|
+
|
20
|
+
&.disabled,
|
21
|
+
&[disabled],
|
22
|
+
fieldset[disabled] & {
|
23
|
+
&,
|
24
|
+
&:hover,
|
25
|
+
&:focus,
|
26
|
+
&:active,
|
27
|
+
&.active {
|
28
|
+
background-color: @background;
|
29
|
+
border-color: @border;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
|
35
|
+
padding: @padding-vertical @padding-horizontal;
|
36
|
+
font-size: @font-size;
|
37
|
+
line-height: @line-height;
|
38
|
+
border-radius: @border-radius;
|
39
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
.form-control() {
|
2
|
+
padding: 6px 12px;
|
3
|
+
background-color: #fff;
|
4
|
+
background-image: none;
|
5
|
+
border: 1px solid #ccc;
|
6
|
+
.rounded(4px);
|
7
|
+
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
|
8
|
+
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
9
|
+
}
|
10
|
+
|
11
|
+
.form-control-focus(@color) {
|
12
|
+
@color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
|
13
|
+
&:focus {
|
14
|
+
border-color: @color;
|
15
|
+
outline: 0;
|
16
|
+
.box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
|
17
|
+
}
|
18
|
+
}
|