robeaux 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/Gruntfile.js +43 -0
  3. data/Makefile +11 -2
  4. data/README.markdown +2 -0
  5. data/css/main.css +1 -0
  6. data/css/style.css +113 -24
  7. data/css/themes/blackboard.css +1 -0
  8. data/css/themes/dark.css +1 -0
  9. data/css/themes/gray.css +1 -0
  10. data/css/themes/whiteboard.css +1 -0
  11. data/images/bullet-connections-2.png +0 -0
  12. data/images/bullet-connections.png +0 -0
  13. data/images/bullet-devices-2.png +0 -0
  14. data/images/bullet-devices.png +0 -0
  15. data/images/devices-image-2.png +0 -0
  16. data/images/devices-image.png +0 -0
  17. data/images/logo-robeaux.png +0 -0
  18. data/images/robots-icon_03.png +0 -0
  19. data/index.html +15 -8
  20. data/js/controllers/widget_editor_ctrl.js +44 -0
  21. data/js/controllers/widgets_ctrl.js +40 -0
  22. data/js/directives/widget.js +50 -0
  23. data/js/router.js +5 -0
  24. data/js/services/themes.js +9 -5
  25. data/js/services/widgets.js +86 -0
  26. data/js/vendor/angular-route.min.js +1 -2
  27. data/js/vendor/angular.min.js +208 -206
  28. data/js/widgets/attitude.html +32 -0
  29. data/js/widgets/attitude.js +27 -0
  30. data/js/widgets/mindwave.html +51 -0
  31. data/js/widgets/mindwave.js +23 -0
  32. data/less/app.less +21 -0
  33. data/less/objects/buttons.less +32 -0
  34. data/less/objects/connections.less +28 -0
  35. data/less/objects/device.less +30 -0
  36. data/less/objects/forms.less +29 -0
  37. data/less/objects/list.less +27 -0
  38. data/less/objects/nav.less +33 -0
  39. data/less/objects/robot.less +43 -0
  40. data/less/objects/themes.less +18 -0
  41. data/less/objects/widgets.less +85 -0
  42. data/less/support/buttons.less +39 -0
  43. data/less/support/container.less +9 -0
  44. data/less/support/forms.less +18 -0
  45. data/less/support/mixins.less +3 -0
  46. data/less/themes/blackboard.less +158 -0
  47. data/less/themes/dark.less +148 -0
  48. data/less/themes/default.less +52 -0
  49. data/less/themes/gray.less +121 -0
  50. data/less/themes/whiteboard.less +152 -0
  51. data/less/vendor/elements.less +156 -0
  52. data/less/vendor/normalize.less +425 -0
  53. data/less/vendor/semantic-grid.less +67 -0
  54. data/less/views/devices.less +47 -0
  55. data/less/views/robots.less +132 -0
  56. data/less/views/themes.less +31 -0
  57. data/less/views/widgets.less +50 -0
  58. data/package.json +6 -3
  59. data/partials/device.html +66 -57
  60. data/partials/index.html +12 -6
  61. data/partials/robot.html +104 -51
  62. data/partials/themes.html +32 -29
  63. data/partials/widget_editor.html +68 -0
  64. data/robeaux.gemspec +1 -1
  65. data/test/controllers/device_commands_ctrl.js +129 -0
  66. data/test/controllers/device_events_ctrl.js +82 -0
  67. data/test/controllers/index_ctrl.js +48 -0
  68. data/test/controllers/nav_ctrl.js +40 -0
  69. data/test/controllers/robot_commands_ctrl.js +127 -0
  70. data/test/controllers/robot_ctrl.js +62 -0
  71. data/test/controllers/themes_ctrl.js +96 -0
  72. data/test/controllers/widget_editor_ctrl.js +111 -0
  73. data/test/controllers/widgets_ctrl.js +74 -0
  74. data/test/functions/functions.js +30 -0
  75. data/test/karma.conf.js +3 -7
  76. data/test/karma_test_all.conf.js +23 -0
  77. data/test/karma_test_controllers.conf.js +19 -0
  78. data/test/karma_test_functions.conf.js +14 -0
  79. data/test/karma_test_services.conf.js +17 -0
  80. data/test/services/themes.js +122 -0
  81. data/test/services/widgets.js +104 -0
  82. data/test/support/themes.json +9 -0
  83. data/test/support/widgets.json +18 -0
  84. data/test/vendor/angular-mocks.js +13 -13
  85. data/test/vendor/jquery.js +8 -8
  86. metadata +69 -3
  87. 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,18 @@
1
+ .themes {
2
+ .new-theme {
3
+ .clearfix();
4
+
5
+ input {
6
+ padding: 8px 12px;
7
+ }
8
+ }
9
+
10
+ .footer {
11
+ display: block;
12
+ text-align: right;
13
+ }
14
+
15
+ .selector {
16
+ margin-top: 20px;
17
+ }
18
+ }
@@ -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,9 @@
1
+ .container() {
2
+ .container-block();
3
+ }
4
+
5
+ .container-block() {
6
+ margin-left: auto;
7
+ margin-right: auto;
8
+ display: block;
9
+ }
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ @import 'buttons';
2
+ @import 'container';
3
+ @import 'forms';