Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of github.com:doug/depthjs

  • Loading branch information...
commit acc6e0682bada82acb723ce01acb2fb38123c12e 2 parents b8ed719 + a22423f
@azinman azinman authored
Showing with 37,044 additions and 4,149 deletions.
  1. +1 −1  README.md
  2. +25 −0 chrome-extension-mac/background.html
  3. +184 −0 chrome-extension-mac/background/backend.js
  4. +1 −7 {safari-extension/DepthJS.safariextension → chrome-extension-mac}/background/message_routing.js
  5. +80 −0 chrome-extension-mac/background/root.js
  6. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/background/tabs.js
  7. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/background/test.js
  8. +269 −0 chrome-extension-mac/chrome.js
  9. +107 −0 chrome-extension-mac/content_script/depthose.js
  10. +174 −0 chrome-extension-mac/content_script/event_handlers.js
  11. +26 −0 chrome-extension-mac/content_script/event_link.js
  12. +35 −0 chrome-extension-mac/content_script/init.js
  13. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/content_script/panner.js
  14. +67 −0 chrome-extension-mac/content_script/root.js
  15. +183 −0 chrome-extension-mac/content_script/selector_box.js
  16. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/css/selectorBox.css
  17. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/images/logo_128x128.png
  18. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/images/logo_16x16.png
  19. 0  {chrome-extension → chrome-extension-mac}/logo_128x128.png
  20. +44 −0 chrome-extension-mac/manifest.json
  21. +1 −0  chrome-extension-mac/plugin
  22. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/third_party/jquery-1.4.4.min.js
  23. 0  {chrome-extension → chrome-extension-mac/third_party}/jquery.idle-timer.js
  24. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/third_party/underscore-min.js
  25. 0  {safari-extension/DepthJS.safariextension → chrome-extension-mac}/third_party/vfx/zflow/zflow.css
  26. +358 −0 chrome-extension-mac/third_party/vfx/zflow/zflow.js
  27. 0  chrome-extension/README.mk
  28. +0 −546 chrome-extension/background.html
  29. +0 −633 chrome-extension/content_script.js
  30. BIN  chrome-extension/logo.psd
  31. +0 −33 chrome-extension/manifest.json
  32. +0 −112 chrome-extension/popup.html
  33. +0 −1,918 chrome-extension/socket.io.js
  34. +0 −357 chrome-extension/vfx/zflow/zflow.js
  35. +80 −23 extension-common/background/backend.js
  36. +1 −7 extension-common/background/message_routing.js
  37. +12 −7 extension-common/background/root.js
  38. +16 −4 extension-common/background_template.html
  39. +12 −2 extension-common/content_script/event_handlers.js
  40. +2 −2 extension-common/content_script/event_link.js
  41. +35 −0 extension-common/content_script/init.js
  42. +53 −7 extension-common/content_script/selector_box.js
  43. +341 −340 extension-common/third_party/vfx/zflow/zflow.js
  44. +60 −0 npapi_plugin/Info.plist
  45. +252 −0 npapi_plugin/bg_fg_blobs.cpp
  46. 0  {cv → npapi_plugin}/bg_fg_blobs.h
  47. +19 −0 npapi_plugin/build-mac.sh
  48. +291 −0 npapi_plugin/depthjs.cc
  49. +48 −0 npapi_plugin/depthjs.h
  50. +64 −0 npapi_plugin/depthjs.mm
  51. +60 −0 npapi_plugin/depthjs.plugin/Contents/Info.plist
  52. BIN  npapi_plugin/depthjs.plugin/Contents/MacOS/depthjs
  53. +215 −0 npapi_plugin/libfreenect.hpp
  54. BIN  npapi_plugin/mac_native_libs/libfreenect.a
  55. BIN  npapi_plugin/mac_native_libs/libfreenect_sync.a
  56. BIN  npapi_plugin/mac_native_libs/libusb-1.0.a
  57. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_calib3d.a
  58. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_calib3d_pch_dephelp.a
  59. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_contrib.a
  60. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_contrib_pch_dephelp.a
  61. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_core.a
  62. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_core_pch_dephelp.a
  63. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_features2d.a
  64. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_features2d_pch_dephelp.a
  65. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_flann.a
  66. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_flann_pch_dephelp.a
  67. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_gpu.a
  68. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_gpu_pch_dephelp.a
  69. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_haartraining_engine.a
  70. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_highgui.a
  71. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_highgui_pch_dephelp.a
  72. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_imgproc.a
  73. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_imgproc_pch_dephelp.a
  74. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_legacy.a
  75. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_legacy_pch_dephelp.a
  76. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_ml.a
  77. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_ml_pch_dephelp.a
  78. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_objdetect.a
  79. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_objdetect_pch_dephelp.a
  80. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_video.a
  81. BIN  npapi_plugin/mac_native_libs/opencv/libopencv_video_pch_dephelp.a
  82. +129 −0 npapi_plugin/np_entry.cc
  83. +713 −0 npapi_plugin/npapi.h
  84. +288 −0 npapi_plugin/npfunctions.h
  85. +144 −0 npapi_plugin/npp_entry.cc
  86. +425 −0 npapi_plugin/npruntime.h
  87. +113 −0 npapi_plugin/nptypes.h
  88. +575 −0 npapi_plugin/ocv_freenect.cpp
  89. +32 −0 npapi_plugin/ocv_freenect.h
  90. +191 −0 npapi_plugin/plugin.cc
  91. +87 −0 npapi_plugin/plugin.h
  92. 0  { → old}/backend/backend.py
  93. 0  { → old}/backend/static/console.html
  94. 0  { → old}/backend/static/favicon.ico
  95. 0  { → old}/backend/templates/index.html
  96. 0  { → old}/backend/test.py
  97. 0  { → old}/backend/tornado/__init__.py
  98. 0  { → old}/backend/tornado/auth.py
  99. 0  { → old}/backend/tornado/autoreload.py
  100. 0  { → old}/backend/tornado/database.py
  101. 0  { → old}/backend/tornado/epoll.c
  102. 0  { → old}/backend/tornado/escape.py
  103. 0  { → old}/backend/tornado/httpclient.py
  104. 0  { → old}/backend/tornado/httpserver.py
  105. 0  { → old}/backend/tornado/httputil.py
  106. 0  { → old}/backend/tornado/ioloop.py
  107. 0  { → old}/backend/tornado/iostream.py
  108. 0  { → old}/backend/tornado/locale.py
  109. 0  { → old}/backend/tornado/options.py
  110. 0  { → old}/backend/tornado/s3server.py
  111. 0  { → old}/backend/tornado/simple_httpclient.py
  112. 0  { → old}/backend/tornado/stack_context.py
  113. 0  { → old}/backend/tornado/template.py
  114. 0  { → old}/backend/tornado/test/README
  115. 0  { → old}/backend/tornado/test/__init__.py
  116. 0  { → old}/backend/tornado/test/escape_test.py
  117. 0  { → old}/backend/tornado/test/httpserver_test.py
  118. 0  { → old}/backend/tornado/test/ioloop_test.py
  119. 0  { → old}/backend/tornado/test/iostream_test.py
  120. 0  { → old}/backend/tornado/test/runtests.py
  121. 0  { → old}/backend/tornado/test/simple_httpclient_test.py
  122. 0  { → old}/backend/tornado/test/stack_context_test.py
  123. 0  { → old}/backend/tornado/test/test.crt
  124. 0  { → old}/backend/tornado/test/test.key
  125. 0  { → old}/backend/tornado/test/testing_test.py
  126. 0  { → old}/backend/tornado/test/web_test.py
  127. 0  { → old}/backend/tornado/testing.py
  128. 0  { → old}/backend/tornado/web.py
  129. 0  { → old}/backend/tornado/websocket.py
  130. 0  { → old}/backend/tornado/win32_support.py
  131. 0  { → old}/backend/tornado/wsgi.py
  132. 0  { → old}/cv/DepthJS/DepthJS.xcodeproj/project.pbxproj
  133. 0  { → old}/cv/Makefile
  134. 0  { → old}/cv/bg_fg_blobs.cpp
  135. +19 −0 old/cv/bg_fg_blobs.h
  136. 0  { → old}/cv/depthvid.mp4
  137. 0  { → old}/cv/ocv_freenect.cpp
  138. 0  { → old}/cv/ocv_freenect.h
  139. 0  { → old}/cv/zhelpers.hpp
  140. 0  { → old}/plugin/DepthJS.cpp
  141. 0  { → old}/plugin/DepthJS.h
  142. 0  { → old}/plugin/DepthJSAPI.cpp
  143. 0  { → old}/plugin/DepthJSAPI.h
  144. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/Info.plist
  145. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/Settings.plist
  146. +17 −6 {safari-extension → safari-extension-mac}/DepthJS.safariextension/background.html
  147. +184 −0 safari-extension-mac/DepthJS.safariextension/background/backend.js
  148. +52 −0 safari-extension-mac/DepthJS.safariextension/background/message_routing.js
  149. +9 −4 {safari-extension → safari-extension-mac}/DepthJS.safariextension/background/root.js
  150. +18 −0 safari-extension-mac/DepthJS.safariextension/background/tabs.js
  151. +84 −0 safari-extension-mac/DepthJS.safariextension/background/test.js
  152. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/content_script/depthose.js
  153. +3 −1 {safari-extension → safari-extension-mac}/DepthJS.safariextension/content_script/event_handlers.js
  154. +1 −1  {safari-extension → safari-extension-mac}/DepthJS.safariextension/content_script/event_link.js
  155. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/content_script/init.js
  156. +66 −0 safari-extension-mac/DepthJS.safariextension/content_script/panner.js
  157. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/content_script/root.js
  158. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/content_script/selector_box.js
  159. 0  {chrome-extension → safari-extension-mac/DepthJS.safariextension/css}/selectorBox.css
  160. BIN  safari-extension-mac/DepthJS.safariextension/images/logo_128x128.png
  161. BIN  safari-extension-mac/DepthJS.safariextension/images/logo_16x16.png
  162. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/old_background.html
  163. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/old_content_script.js
  164. +27 −11 {safari-extension → safari-extension-mac}/DepthJS.safariextension/safari.js
  165. 0  {chrome-extension → safari-extension-mac/DepthJS.safariextension/third_party}/jquery-1.4.4.min.js
  166. 0  {chrome-extension → safari-extension-mac/DepthJS.safariextension/third_party}/underscore-min.js
  167. 0  {chrome-extension → safari-extension-mac/DepthJS.safariextension/third_party}/vfx/zflow/zflow.css
  168. 0  {safari-extension → safari-extension-mac}/DepthJS.safariextension/third_party/vfx/zflow/zflow.js
  169. +0 −127 safari-extension/DepthJS.safariextension/background/backend.js
  170. BIN  webkit-plugin-mac/English.lproj/InfoPlist.strings
  171. +44 −0 webkit-plugin-mac/Info.plist
  172. +252 −0 webkit-plugin-mac/bg_fg_blobs.cpp
  173. +18 −0 webkit-plugin-mac/bg_fg_blobs.h
  174. +42 −0 webkit-plugin-mac/build/Debug/webkit-plugin-mac.webplugin/Contents/Info.plist
  175. BIN  webkit-plugin-mac/build/Debug/webkit-plugin-mac.webplugin/Contents/Resources/English.lproj/InfoPlist.strings
  176. +60 −0 webkit-plugin-mac/build/Debug/webkit-plugin-mac.webplugin/Contents/Resources/Info.plist
  177. +3 −0  ...ld/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/Objects-normal/i386/webkit-plugin-mac.LinkFileList
  178. +1,088 −0 webkit-plugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/build-state.dat
  179. +1,090 −0 webkit-plugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/build-state~.dat
  180. BIN  ...n-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac-all-target-headers.hmap
  181. BIN  ...ugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac-generated-files.hmap
  182. BIN  ...n-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac-own-target-headers.hmap
  183. BIN  ...ugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac-project-headers.hmap
  184. +13 −0 webkit-plugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac.dep
  185. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac.hmap
  186. +13 −0 webkit-plugin-mac/build/webkit-plugin-mac.build/Debug/webkit-plugin-mac.build/webkit-plugin-mac~.dep
  187. +145 −0 webkit-plugin-mac/build/webkit-plugin-mac.build/Release/webkit-plugin-mac.build/build-state.dat
  188. +11 −0 webkit-plugin-mac/build/webkit-plugin-mac.build/Release/webkit-plugin-mac.build/webkit-plugin-mac.dep
  189. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/categories.pbxbtree
  190. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/cdecls.pbxbtree
  191. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/decls.pbxbtree
  192. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/files.pbxbtree
  193. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/imports.pbxbtree
  194. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/pbxindex.header
  195. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/protocols.pbxbtree
  196. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/refs.pbxbtree
  197. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/strings.pbxstrings/control
  198. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/strings.pbxstrings/strings
  199. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/subclasses.pbxbtree
  200. BIN  webkit-plugin-mac/build/webkit-plugin-mac.build/webkit-plugin-mac.pbxindex/symbols0.pbxsymbols
  201. +433 −0 webkit-plugin-mac/include/libfreenect/libfreenect.h
  202. +108 −0 webkit-plugin-mac/include/libfreenect/libfreenect_sync.h
  203. +1,322 −0 webkit-plugin-mac/include/libusb-1.0/libusb.h
  204. +83 −0 webkit-plugin-mac/include/opencv/cv.h
  205. +52 −0 webkit-plugin-mac/include/opencv/cv.hpp
  206. +65 −0 webkit-plugin-mac/include/opencv/cvaux.h
  207. +51 −0 webkit-plugin-mac/include/opencv/cvaux.hpp
  208. +46 −0 webkit-plugin-mac/include/opencv/cvwimage.h
  209. +53 −0 webkit-plugin-mac/include/opencv/cxcore.h
  210. +52 −0 webkit-plugin-mac/include/opencv/cxcore.hpp
  211. +49 −0 webkit-plugin-mac/include/opencv/cxeigen.hpp
  212. +6 −0 webkit-plugin-mac/include/opencv/cxmisc.h
  213. +50 −0 webkit-plugin-mac/include/opencv/highgui.h
  214. +48 −0 webkit-plugin-mac/include/opencv/ml.h
  215. +761 −0 webkit-plugin-mac/include/opencv2/calib3d/calib3d.hpp
  216. +566 −0 webkit-plugin-mac/include/opencv2/contrib/contrib.hpp
  217. +4,050 −0 webkit-plugin-mac/include/opencv2/core/core.hpp
  218. +1,885 −0 webkit-plugin-mac/include/opencv2/core/core_c.h
  219. +186 −0 webkit-plugin-mac/include/opencv2/core/eigen.hpp
  220. +684 −0 webkit-plugin-mac/include/opencv2/core/internal.hpp
  221. +2,470 −0 webkit-plugin-mac/include/opencv2/core/mat.hpp
  222. +3,553 −0 webkit-plugin-mac/include/opencv2/core/operations.hpp
  223. +1,866 −0 webkit-plugin-mac/include/opencv2/core/types_c.h
  224. +58 −0 webkit-plugin-mac/include/opencv2/core/version.hpp
  225. +621 −0 webkit-plugin-mac/include/opencv2/core/wimage.hpp
  226. +2,747 −0 webkit-plugin-mac/include/opencv2/features2d/features2d.hpp
  227. +76 −0 webkit-plugin-mac/include/opencv2/flann/all_indices.h
  228. +187 −0 webkit-plugin-mac/include/opencv2/flann/allocator.h
  229. +614 −0 webkit-plugin-mac/include/opencv2/flann/autotuned_index.h
  230. +163 −0 webkit-plugin-mac/include/opencv2/flann/composite_index.h
  231. +361 −0 webkit-plugin-mac/include/opencv2/flann/dist.h
  232. +196 −0 webkit-plugin-mac/include/opencv2/flann/flann.hpp
  233. +261 −0 webkit-plugin-mac/include/opencv2/flann/flann_base.hpp
  234. +150 −0 webkit-plugin-mac/include/opencv2/flann/general.h
  235. +95 −0 webkit-plugin-mac/include/opencv2/flann/ground_truth.h
  236. +163 −0 webkit-plugin-mac/include/opencv2/flann/hdf5.h
  237. +209 −0 webkit-plugin-mac/include/opencv2/flann/heap.h
  238. +292 −0 webkit-plugin-mac/include/opencv2/flann/index_testing.h
  239. +622 −0 webkit-plugin-mac/include/opencv2/flann/kdtree_index.h
  240. +1,117 −0 webkit-plugin-mac/include/opencv2/flann/kmeans_index.h
  241. +120 −0 webkit-plugin-mac/include/opencv2/flann/linear_index.h
  242. +92 −0 webkit-plugin-mac/include/opencv2/flann/logger.h
  243. +118 −0 webkit-plugin-mac/include/opencv2/flann/matrix.h
  244. +108 −0 webkit-plugin-mac/include/opencv2/flann/nn_index.h
  245. +94 −0 webkit-plugin-mac/include/opencv2/flann/object_factory.h
  246. +134 −0 webkit-plugin-mac/include/opencv2/flann/random.h
  247. +320 −0 webkit-plugin-mac/include/opencv2/flann/result_set.h
  248. +94 −0 webkit-plugin-mac/include/opencv2/flann/sampling.h
  249. +115 −0 webkit-plugin-mac/include/opencv2/flann/saving.h
  250. +186 −0 webkit-plugin-mac/include/opencv2/flann/simplex_downhill.h
  251. +90 −0 webkit-plugin-mac/include/opencv2/flann/timer.h
  252. +130 −0 webkit-plugin-mac/include/opencv2/gpu/devmem2d.hpp
Sorry, we could not display the entire diff because too many files (304) changed.
View
2  README.md
@@ -39,4 +39,4 @@ In addition to the obvious improvements to our gesture recognition, we need to m
We like that the backend is very modular, so that anything (not just DepthJS) can connect via 0MQ or WebSockets to the C++ Kinect+OpenCV backend.
-However, this is not a user friendly setup. We want to eventually integrate the entire driver+backend into an NSAPI-based native code extension such that we can distribute the extension "batteries-included" as a one-click install. Eventually it should be hosted on the various web browser (Safari, Firefox, and Chome) extension galleries.
+However, this is not a user friendly setup. We want to eventually integrate the entire driver+backend into an NPAPI-based native code extension such that we can distribute the extension "batteries-included" as a one-click install. Eventually it should be hosted on the various web browser (Safari, Firefox, and Chome) extension galleries.
View
25 chrome-extension-mac/background.html
@@ -0,0 +1,25 @@
+<html><head>
+<script src="third_party/jquery-1.4.4.min.js"></script>
+<script src="third_party/underscore-min.js"></script>
+<script src="background/root.js"></script>
+<script src="background/backend.js"></script>
+<script src="background/tabs.js"></script>
+<script src="background/test.js"></script>
+<script src="background/message_routing.js"></script>
+<script src="chrome.js"></script>
+</head>
+
+<body>
+<embed id="pluginObj" type="application/x-depthjs">
+
+<script>
+var pluginObj = document.getElementById('pluginObj');
+setTimeout(function() {
+ console.log('Starting DepthJS...');
+ if (!DepthJS.init(pluginObj)) {
+ console.log("Could not init DepthJS");
+ }
+}, 1000);
+</script>
+</body>
+</html>
View
184 chrome-extension-mac/background/backend.js
@@ -0,0 +1,184 @@
+var WS_CONNECTING = 0;
+var WS_OPEN = 1;
+var WS_CLOSING = 2;
+var WS_CLOSED = 3;
+
+// WEB SOCKETS BASED BACKEND -----------------------------------------------------------------------
+
+DepthJS.wsBackend = {};
+
+DepthJS.wsBackend.eventWs = null;
+DepthJS.wsBackend.imageWs = null;
+DepthJS.wsBackend.depthWs = null;
+DepthJS.wsBackend.host = "localhost";
+DepthJS.wsBackend.port = 8000;
+DepthJS.wsBackend.connect = function() {
+ DepthJS.backend.connecting = true;
+ DepthJS.browser.sendMessageToPopup("connecting");
+ var connected = 0;
+ function check() {
+ connected++;
+ if (connected == 3) {
+ if (DepthJS.verbose) console.log("All 3 connected");
+ DepthJS.browser.sendMessageToPopup("connected");
+ DepthJS.backend.connecting = false;
+ DepthJS.backend.connected = true;
+ }
+ }
+
+ // If we do not connect within a timeout period,
+ // effectively cancel it and let the popup know.
+ setTimeout(function() {
+ if (connected != 3) {
+ DepthJS.wsBackend.disconnect();
+ }
+ }, 3000);
+
+ return _.all(_.map(["event", "image", "depth"], function(stream) {
+ var path = "ws://" + DepthJS.wsBackend.host + ":" + DepthJS.wsBackend.port + "/" + stream;
+ if (DepthJS.verbose) console.log("Connecting to " + stream + " stream on " + path);
+
+ // Clear out any old sockets
+ var oldSocket = DepthJS.wsBackend[stream+"Ws"];
+ if (oldSocket != null) {
+ oldSocket.onmessage = null;
+ oldSocket.onclose = null;
+ oldSocket.onopen = null;
+
+ if (oldSocket.readyState == WS_OPEN ||
+ oldSocket.readyState == WS_CONNECTING) {
+ oldSocket.close();
+ }
+ }
+
+ var socket = new WebSocket(path);
+ DepthJS.wsBackend[stream+"Ws"] = socket;
+
+ socket.onmessage = function(data){
+ DepthJS.wsBackend.onMessage(stream, data);
+ };
+
+ socket.onclose = function() {
+ DepthJS.wsBackend.onDisconnect(stream);
+ };
+
+ socket.onopen = function() {
+ DepthJS.wsBackend.onConnect(stream);
+ check();
+ };
+
+ return true;
+ }));
+};
+
+DepthJS.wsBackend.onMessage = function (stream, data) {
+ if (stream == "event") {
+ if (data === undefined || data.data == null) {
+ return;
+ }
+ var msg = JSON.parse(data.data);
+ if (!$.isPlainObject(msg)) {
+ if (DepthJS.verbose) console.log('Unknown message: ' + data);
+ return;
+ }
+ DepthJS.logSortaVerbose(msg.type, msg);
+ var handler = DepthJS.eventHandlers["on"+msg.type];
+ if (handler != null) {
+ handler(msg.data);
+ }
+
+ msg.jsonRep = data.data;
+ // Don't send to all--send to only the current tab.
+ DepthJS.browser.sendMessageToActiveTab(msg);
+ } else if (stream == "image") {
+ /*DepthJS.eventHandlers.onImageMsg(data);*/
+ } else if (stream == "depth") {
+ /*DepthJS.eventHandlers.onDepthMsg(data);*/
+ }
+};
+
+DepthJS.wsBackend.disconnect = function() {
+ DepthJS.backend.connected = false;
+ if (DepthJS.verbose) console.log("Disconnecting");
+ DepthJS.browser.sendMessageToPopup("disconnected");
+ return _.map(["event", "image", "depth"], function(stream) {
+ var oldSocket = DepthJS.wsBackend[stream+"Ws"];
+ if (oldSocket != null) {
+ oldSocket.onmessage = null;
+ oldSocket.onclose = null;
+ oldSocket.onopen = null;
+
+ if (oldSocket.readyState == WS_OPEN ||
+ oldSocket.readyState == WS_CONNECTING) {
+ oldSocket.close();
+ }
+ }
+ DepthJS.wsBackend[stream+"Ws"] = null;
+ });
+};
+
+DepthJS.wsBackend.onDisconnect = function (stream) {
+ if (DepthJS.verbose) console.log("Disconnected on " + stream + " stream");
+ // If one is closed, close them all.
+ DepthJS.wsBackend.disconnect();
+};
+
+DepthJS.wsBackend.onConnect = function (stream) {
+ if (DepthJS.verbose) console.log("Connect on " + stream + " stream");
+};
+
+
+// NPAPI PLUGIN BASED BACKEND ----------------------------------------------------------------------
+
+DepthJS.npBackend = {};
+DepthJS.npBackend.connect = function() {
+ if (DepthJS.backend.connecting || DepthJS.backend.connected) {
+ console.log("Already connectted... disconnecting and reconnecting");
+ DepthJS.npBackend.disconnect();
+ }
+ DepthJS.browser.sendMessageToPopup("connecting");
+
+ DepthJS.backend.connected = false;
+ var success = DepthJS.pluginObj.InitDepthJS();
+ DepthJS.backend.connecting = false;
+ if (success) {
+ console.log("Successfully acquired Kinect event monitor from plugin!");
+ DepthJS.backend.connected = true;
+ } else {
+ console.log("ERROR: Could not acquire Kinect event monitor from plugin");
+ DepthJS.backend.connected = false;
+ }
+ return success;
+};
+
+DepthJS.npBackend.receiveEvent = function (msg) {
+ if (msg == null || msg.type == null) {
+ return;
+ }
+ DepthJS.logSortaVerbose(msg.type, msg);
+ var handler = DepthJS.eventHandlers["on"+msg.type];
+ if (handler != null) {
+ handler(msg.data);
+ }
+
+ msg.jsonRep = JSON.stringify(msg);
+ // Don't send to all--send to only the current tab.
+ DepthJS.browser.sendMessageToActiveTab(msg);
+};
+
+DepthJS.npBackend.disconnect = function() {
+ DepthJS.backend.connected = false;
+ DepthJS.backend.connecting = false;
+ if (DepthJS.verbose) console.log("Disconnecting");
+ DepthJS.browser.sendMessageToPopup("disconnected");
+ DepthJS.pluginObj.ShutdownDepthJS();
+};
+
+// Native library chooses; default websocket
+
+DepthJS.backend = {
+ connect: DepthJS.wsBackend.connect,
+ disconnect: DepthJS.wsBackend.disconnect,
+ connecting: false,
+ connected: false
+}
View
8 ...hJS.safariextension/background/message_routing.js → chrome-extension-mac/background/message_routing.js
@@ -30,13 +30,7 @@ DepthJS.background.handleMessage = function(action, data, reply) {
selectTab: function() {
var tabId = data.tabId;
- var tab = _.select(DepthJS.tabs.activeWindowTabCache, function(t) { return t.tabId == tabId; });
- if (tab.length == 0) {
- console.log("Couldn't find tabId " + tabId);
- return;
- }
- tab = tab[0];
- tab.activate();
+ DepthJS.tabs.selectTab(tabId);
},
depthoseMode: function() {
View
80 chrome-extension-mac/background/root.js
@@ -0,0 +1,80 @@
+/*
+DepthJS
+Copyright (C) 2010 Aaron Zinman, Doug Fritz, Roy Shilkrot, and Greg Elliott
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+console.log('background.html Starting DepthJS');
+var DepthJS = {
+ __VERSION__: '0.3',
+ verbose: true,
+ backend: {},
+ eventHandlers: {},
+ cv: {},
+ tools: {},
+ portsByTabId: {},
+ tabs: {},
+ test: {},
+ toolbar: {},
+ browser: {},
+ background: {},
+ registerMode: "selectorBox",
+ pluginObj: null
+};
+
+DepthJS.init = function (pluginObj) {
+ console.log("Initing DepthJS background");
+ DepthJS.pluginObj = pluginObj;
+ DepthJS.initBrowserBackground();
+ DepthJS.browser.addBackgroundListener(DepthJS.background.handleMessage);
+ if (DepthJS.verbose) console.log("Connecting to Backend");
+ if (!DepthJS.backend.connect()) {
+ if (DepthJS.verbose) console.log("Couldn't connect... aborting");
+ return false;
+ }
+ console.log("Init complete");
+ return true;
+};
+
+
+(function() {
+var lastMessages = [];
+DepthJS.logSortaVerbose = function(type, fullMessage) {
+ lastMessages.push({type: type, data:fullMessage});
+};
+
+function print() {
+ setTimeout(print, 1000);
+ if (lastMessages.length == 0) return;
+ var counts = {};
+ var lastByType = {};
+ _.each(lastMessages, function(msg) {
+ if (counts[msg.type] == null) counts[msg.type] = 0;
+ counts[msg.type] = counts[msg.type] + 1;
+ lastByType[msg.type] = msg.data;
+ });
+
+ var alphabeticalKeys = _.keys(counts).sort();
+ console.log("------" + (new Date() + ""));
+ _.each(alphabeticalKeys, function(type) {
+ console.log([" " + counts[type] + " " + type + "; last = ", lastByType[type]]);
+ });
+
+ lastMessages = [];
+}
+setTimeout(print, 1000);
+
+})();
View
0  ...ension/DepthJS.safariextension/background/tabs.js → chrome-extension-mac/background/tabs.js
File renamed without changes
View
0  ...ension/DepthJS.safariextension/background/test.js → chrome-extension-mac/background/test.js
File renamed without changes
View
269 chrome-extension-mac/chrome.js
@@ -0,0 +1,269 @@
+if (DepthJS) {
+console.log("DepthJS Loading Chrome shit");
+
+DepthJS.initBrowserBackground = function() {
+ console.log("DepthJS: Initing Chrome background");
+ // Choose the NPAPI-based backend
+ DepthJS.backend.connect = DepthJS.npBackend.connect;
+ DepthJS.backend.disconnect = DepthJS.npBackend.disconnect;
+
+ console.log("DepthJS: Initing port listener");
+ chrome.extension.onConnect.addListener(function(port) {
+ var name = port.name;
+ if (DepthJS.verbose) console.assert(name == "event" || name == "image" || name == "depth");
+ if (DepthJS.verbose) console.log(name + " port connected");
+ //var listeners = DepthJS[name + "Listeners"];
+ //listeners.push(port);
+
+ var tabId = port.sender.tab.id;
+ var tabPorts = DepthJS.portsByTabId[tabId];
+ if (tabPorts == null) {
+ tabPorts = {}; DepthJS.portsByTabId[tabId] = tabPorts;
+ }
+ tabPorts[name] = port;
+
+ port.onDisconnect.addListener(function (e) {
+ if (DepthJS.verbose) console.log(name + " port disconnected on tab " + tabId);
+ //DepthJS[name + "Listeners"] = _.reject(
+ //listeners, function(el) { el === port; });
+ var _tabPorts = DepthJS.portsByTabId[tabId];
+ if (_tabPorts) {
+ delete _tabPorts[name];
+ if (_.isEmpty(_tabPorts)) {
+ if (DepthJS.verbose) console.log("for all ports on this tab");
+ delete DepthJS.portsByTabId[tabId];
+ }
+ }
+ });
+ });
+};
+
+if (DepthJS.tabs) {
+DepthJS.tabs.selectTab = function(tabId) {
+ console.log("Selecting tabId " + tabId);
+ chrome.tabs.update(tabId, {selected: true});
+};
+
+DepthJS.tabs.populateActiveWindowCache = function(callback) {
+ chrome.windows.getCurrent(function(windowObj) {
+ DepthJS.tabs.activeWindowTabCache = _.filter(_.map(windowObj.tabs, function(tab) {
+ return DepthJS.tabs.thumbnailCache[tab.id];
+ }), function(obj) { return obj != null; });
+
+ callback(DepthJS.tabs.activeWindowTabCache);
+ });
+};
+
+DepthJS.tabs.thumbnailCache = {};
+DepthJS.tabs.tabCache = {};
+DepthJS.tabs.windowCache = {};
+
+DepthJS.tabs.init = function() {
+ DepthJS.tabs.populateCaches();
+
+ // Subscribe to event handlers
+ chrome.tabs.onCreated.addListener(function(tab) {
+ // console.log('new tab created: ' + obj_repr(tab, 'Tab'));
+ // But not yet loaded--wait for onUpdated
+ DepthJS.tabs.tabCache[tab.id] = tab;
+ });
+
+ chrome.tabs.onRemoved.addListener(DepthJS.tabs.onClosedTab);
+
+ chrome.tabs.onUpdated.addListener(DepthJS.tabs.onTabUpdated);
+
+ chrome.windows.onRemoved.addListener(function(windowId) {
+ // console.log('window removed: id=' + windowId);
+ });
+};
+
+DepthJS.tabs.populateCaches = function() {
+ var obj_repr = DepthJS.tools.obj_repr;
+ // Go through all existing tabs/windows and add to cache
+ chrome.windows.getAll({populate: true}, function(windows) {
+ for (var i = 0; i < windows.length; ++i) {
+ var window = windows[i];
+ if (DepthJS.verbose) console.log('Adding existing window '+ obj_repr(window, 'Window'));
+ for (var j = 0; j < window.tabs.length; ++j) {
+ var tab = window.tabs[j];
+ if (DepthJS.verbose) console.log('Adding existing tab ' + obj_repr(tab, 'Tab'));
+ DepthJS.tabs.tabCache[tab.id] = tab;
+
+ if (tab.status == 'complete') {
+ // We should add this already loaded tab
+ if (tab.selected) { // since we are only doing a screenshot on new
+ DepthJS.tabs.onNewVisibleTab(tab.url, tab.title, window.id, tab.id);
+ }
+ }
+ }
+ delete window.tabs; // Unnecessary... it'll be too stale to do anything with.
+ DepthJS.tabs.windowCache[window.id] = window;
+ }
+ });
+};
+
+DepthJS.tabs.onTabUpdated = function(tabId, changeInfo, tab) {
+ var cachedTab = DepthJS.tabs.tabCache[tabId];
+ if (!cachedTab) {
+ DepthJS.logSortaVerbose('Could not find tabId ' + tabId + ' in cache: ' + cachedTab);
+ return;
+ }
+
+ if (changeInfo.status == 'complete' && cachedTab.status == 'loading') {
+ if (tab.selected) DepthJS.tabs.onNewVisibleTab(tab.url, tab.title, tab.id);
+ } else if (tab.url != cachedTab.url) {
+ DepthJS.tabs.onClosedTab(cachedTab.id);
+ if (tab.status == 'complete') {
+ // Never the case?
+ if (tab.selected) DepthJS.tabs.onNewVisibleTab(tab.url, tab.title, tab.id);
+ }
+ }
+ // Save state
+ delete DepthJS.tabs.tabCache[tabId]; // help GC
+ DepthJS.tabs.tabCache[tabId] = tab;
+};
+
+DepthJS.tabs.onNewVisibleTab = function(url, title, windowId, tabId) {
+ // Take screenshot
+ var capture = function(windowId) {
+ chrome.tabs.captureVisibleTab(windowId, null, function(dataUrl) {
+ if (DepthJS.verbose) console.log("captured thumbnail for tabId " + tabId);
+ DepthJS.tabs.thumbnailCache[tabId] = {
+ dataUrl: dataUrl,
+ title: title};
+ });
+ }
+ if (tabId != null) {
+ capture(windowId);
+ } else {
+ tabId = windowId; // variable num args in function call, jquery style.
+ chrome.tabs.get(tabId, function(tab) { capture(tab.windowId); });
+ }
+};
+
+DepthJS.tabs.onClosedTab = function(tabId) {
+ if (DepthJS.portsByTabId[tabId] != null) {
+ if (DepthJS.verbose) console.log("Had ports by closed tab laying around, deleting");
+ delete DepthJS.portsByTabId[tabId];
+ }
+ // Close page
+ var cachedTab = DepthJS.tabs.tabCache[tabId];
+ if (!cachedTab) {
+ if (DepthJS.verbose) console.log('Could not find tabId ' + tabId + ' in cache: ' + cachedTab);
+ return;
+ }
+
+ delete DepthJS.tabs.tabCache[tabId];
+ if (DepthJS.tabs.thumbnailCache[tabId] != null) {
+ delete DepthJS.tabs.thumbnailCache[tabId];
+ }
+};
+
+DepthJS.tabs.onReaccessedTab = function(url, tabId) {
+};
+} // end if DepthJS.tabs
+
+
+
+
+if(!DepthJS.tools) DepthJS.tools = {};
+DepthJS.tools.obj_repr = function (obj, className) {
+ var buf = [];
+ if (className === undefined) {
+ buf.push('[Object ');
+ } else {
+ buf.push('[' + className + ' ');
+ }
+ for (var key in obj) {
+ buf.push(key + '=' + obj[key]);
+ buf.push(', ');
+ }
+ buf.pop();
+ buf.push(']');
+ return buf.join('');
+};
+
+
+/**
+ * Typically used for background.html. When a message is passed in, it passes to the
+ * callback two parameters: action & data.
+ */
+DepthJS.browser.addBackgroundListener = function(callback) {
+ chrome.extension.onRequest.addListener(function(req, sender, sendResponse) {
+ callback(req.action, req.data, sendResponse);
+ });
+
+ /*
+ safari.application.addEventListener("message", function(e) {
+ var action = e.name;
+ var data = e.message;
+ var reply = function(messageType, data) {
+ e.target.page.dispatchMessage(messageType, data);
+ };
+ callback(action, data, reply);
+ });
+ */
+};
+
+/**
+ * Typically used for content scripts. When a message is passed in, it passes to the
+ * callback the data attached to the messageType.
+ */
+(function() {
+var cache = {};
+DepthJS.browser.addContentScriptListener = function(messageType, callback) {
+ if (cache[messageType] && cache[messageType][0] == callback) {
+ console.log("Ignoring existing port subscription on " + messageType);
+ return;
+ }
+ var port = chrome.extension.connect({name: messageType});
+ port.onMessage.addListener(callback);
+ cache[messageType] = [callback, port];
+ /*
+ safari.self.addEventListener("message", function(e) {
+ if (e.name == messageType) callback(e.message);
+ }, false);
+ */
+};
+
+DepthJS.browser.readdContentScriptListeners = function() {
+ console.log("DepthJS: Unimplemented for chrome: readdContentScriptListeners");
+ /*
+ _.each(stuff, function(callback, messageType) {
+ console.log("Reading event listener for " + messageType);
+ safari.self.addEventListener("message", function(e) {
+ if (e.name == messageType) callback(e.message);
+ }, false);
+ });
+ */
+};
+})();
+
+DepthJS.browser.sendMessageToPopup = function(msg) {
+ chrome.extension.sendRequest({action: msg});
+};
+
+DepthJS.browser.sendMessageToActiveTab = function(message) {
+ chrome.tabs.getSelected(null, function(tab) {
+ var tabId = tab.id;
+ var tabPorts = DepthJS.portsByTabId[tabId];
+ if (tabPorts == null) {
+ DepthJS.logSortaVerbose("Could not find ports for tabId " + tabId);
+ return;
+ }
+ var eventPort = tabPorts.event;
+ if (eventPort == null) {
+ DepthJS.logSortaVerbose("Could not find event port for tabId " + tabId);
+ return;
+ }
+
+ DepthJS.logSortaVerbose("sending_" + message.type, message);
+ eventPort.postMessage(message);
+ });
+};
+
+DepthJS.browser.sendMessageToBackground = function(messageType, data) {
+ chrome.extension.sendRequest({action: messageType, data: data});
+};
+
+} // if (DepthJS)
View
107 chrome-extension-mac/content_script/depthose.js
@@ -0,0 +1,107 @@
+if (window.top === window) {
+// DEPTHOSE ---------------------------------------------------------------------------------------
+console.log("DepthJS: Loading Depthose");
+DepthJS.depthose.$div = null;
+DepthJS.depthose.thumbnailCache = null;
+
+DepthJS.depthose.init = function() {
+ console.log("Initting Depthose");
+ DepthJS.browser.addContentScriptListener("thumbnails", function(data) {
+ DepthJS.depthose.recieveThumbnails(data.tabs);
+ });
+ DepthJS.depthose.zflowInit();
+};
+
+DepthJS.depthose.start = function() {
+ if (DepthJS.verbose) console.log("DepthJS: Requesting thumbnails");
+ DepthJS.browser.sendMessageToBackground("getThumbnails");
+};
+
+DepthJS.depthose.recieveThumbnails = function(thumbnails) {
+ if (DepthJS.verbose) console.log(["DepthJS: Got back thumbnails", thumbnails]);
+ DepthJS.depthose.thumbnailCache = thumbnails;
+ if (DepthJS.depthose.thumbnailCache != null) DepthJS.depthose.show();
+};
+
+DepthJS.depthose.show = function() {
+ if (DepthJS.depthose.thumbnailCache == null) {
+ DepthJS.depthose.start();
+ return;
+ }
+ var thumbnailCache = DepthJS.depthose.thumbnailCache;
+
+ DepthJS.selectorBox.hide();
+ if (DepthJS.verbose) console.log(["DepthJS: Starting depthose with", DepthJS.depthose.thumbnailCache]);
+ $("#DepthJS_depthose").remove();
+ DepthJS.depthose.$div = $("<div id='DepthJS_depthose'></div>");
+ var $div = DepthJS.depthose.$div;
+ $div.css({"position": "fixed",
+ "width": "100%",
+ "height": "100%",
+ "background-color": "#333",
+ "z-index": "10000",
+ "top": "0",
+ "left": "0"})
+ .addClass("zflow")
+ .appendTo("body");
+
+ $div.append("<div class='centering'><div id='DepthJS_tray' class='tray'></div></div>");
+
+ _.each(thumbnailCache, function(tabObj, tabId) {
+ tabObj.selectCallback = function() {
+ if (DepthJS.verbose) console.log("selecting tab id " + tabId);
+ DepthJS.eventHandlers.onUnregister();
+ DepthJS.browser.sendMessageToBackground("selectTab", tabObj);
+ };
+ });
+
+ if (!_.isEmpty(thumbnailCache)) {
+ if (DepthJS.verbose) console.log("starting zflow");
+ DepthJS.depthose.zflow(_.values(thumbnailCache), "#DepthJS_tray");
+ var e = document.createEvent("Event");
+ e.initEvent("depthstart");
+ e.pageX = $(window).width()/2;
+ e.pageY = $(window).height()/2;
+ document.getElementById("DepthJS_tray").dispatchEvent(e);
+ } else {
+ if (DepthJS.verbose) console.log("Not showing Depthose--no windows to show");
+ }
+};
+
+DepthJS.depthose.hide = function() {
+ if (DepthJS.depthose.$div == null) return;
+ if (DepthJS.verbose) console.log("DepthJS: Exiting Depthose");
+ var e = document.createEvent("Event");
+ e.initEvent("depthend");
+ document.getElementById("DepthJS_tray").dispatchEvent(e);
+ DepthJS.depthose.$div.remove();
+ DepthJS.depthose.$div = null;
+ DepthJS.depthose.thumbnailCache = null;
+};
+
+DepthJS.depthose.move = function(x, y) {
+ if (DepthJS.depthose.thumbnailCache == null) {
+ if (DepthJS.verbose) console.log("DepthJS: Haven't loaded Depthose yet, ignoring move event");
+ return;
+ }
+
+ if (DepthJS.verbose == STUPID_VERBOSE) console.log("DepthJS: Move depthose");
+ var e = document.createEvent("Event");
+ e.initEvent("depthmove");
+ e.pageX = x * $(window).width() / 100;
+ e.pageY = y * $(window).height() / 100;
+ document.getElementById("DepthJS_tray").dispatchEvent(e);
+};
+
+DepthJS.depthose.select = function() {
+ if (DepthJS.depthose.thumbnailCache == null) {
+ if (DepthJS.verbose) console.log("DepthJS: Haven't loaded Depthose yet, ignoring move event");
+ return;
+ }
+
+ if (DepthJS.verbose) console.log("DepthJS: Selecting in Depthose");
+ var e = document.createEvent("Event");
+ e.initEvent("depthselect");
+ document.getElementById("DepthJS_tray").dispatchEvent(e);
+};
+}
View
174 chrome-extension-mac/content_script/event_handlers.js
@@ -0,0 +1,174 @@
+// EVENT HANDLERS ----------------------------------------------------------------------------------
+
+/**
+ * DepthJS here maps gestures to interactions with this web page.
+ *
+ * Users interact with the system in two different "modes".
+ *
+ * 1) Lazy gestures
+ * 2) Virtual pointer
+ *
+ * LAZY GESTURES:
+ * By default, the user can lazily make swiping motions with their whole hand:
+ * up, down, left and right.
+ *
+ * The user does not leave her hand still in the air, but instead rests it hand out of frame.
+ *
+ * The swipes provide basic level navigation--moving forward and backward in history and
+ * moving the web page up and down.
+ *
+ * VIRTUAL POINTER:
+ * Once the hand is registered, the user manipulates a cursor along a parallel 2D plane to the monitor.
+ *
+ * The cursor can be moved, "pushed", and "pulled". Moving the cursor moves a visible selection box
+ * around the web page. Pushing and pulling activate (click) any links below the selection box.
+ **/
+
+if (window.top === window) {
+console.log("DepthJS: Loading event handlers");
+
+DepthJS.state = null;
+DepthJS.lastRegisterTime = null;
+
+DepthJS.eventHandlers.onSwipeLeft = function() {
+ // history.back();
+};
+
+DepthJS.eventHandlers.onSwipeRight = function() {
+ // We interpret as "forward".
+ // history.forward();
+};
+
+DepthJS.eventHandlers.onSwipeDown = function() {
+ // We interpret as "scroll down 75% of window".
+ // var scrollAmount = Math.floor($(window).height() * 0.75);
+ // $("html, body").animate({
+ // scrollTop: ($(document).scrollTop() + scrollAmount)
+ // });
+};
+
+DepthJS.eventHandlers.onSwipeUp = function() {
+ // We interpret as "scroll up 75% of window".
+ // var scrollAmount = Math.floor($(window).height() * 0.75);
+ // $("html, body").animate({
+ // scrollTop: ($(document).scrollTop() - scrollAmount)
+ // });
+};
+
+DepthJS.eventHandlers.onHandPointer = function(){
+ if (DepthJS.verbose) console.log("DepthJS. Hand Pointer");
+ DepthJS.eventHandlers.onUnregister();
+ DepthJS.state = "selectorBox";
+};
+
+DepthJS.eventHandlers.onHandOpen = function(){
+ if (DepthJS.verbose) console.log("DepthJS. Hand Open");
+ DepthJS.eventHandlers.onUnregister();
+ DepthJS.state = "panner";
+ DepthJS.panner.show();
+};
+
+DepthJS.eventHandlers.onDepthoseMode = function() {
+ DepthJS.registerMode = "depthose";
+};
+
+DepthJS.eventHandlers.onPannerMode = function() {
+ DepthJS.registerMode = "panner";
+};
+
+DepthJS.eventHandlers.onSelectorBoxMode = function() {
+ DepthJS.registerMode = "selectorBox";
+};
+
+// POINTER -----------------------------------------------------------------------------------------
+DepthJS.eventHandlers.onRegister = function(data) {
+ if (DepthJS.verbose) console.log("DepthJS: User registered their hand");
+ $(window).trigger("touchstart");
+ if (data.mode == "twohands") {
+ console.log("Ignoring in two hands for now");
+ return;
+ }
+ if (data.mode == "theforce") {
+ DepthJS.registerMode = "selectorBox";
+ } else if (data.mode == "twohands") {
+ DepthJS.registerMode = "depthose";
+ } else if (data.mode == "openhand") {
+ DepthJS.registerMode = "panner";
+ } else {
+ console.log(["DID NOT UNDERSTAND MODE: ", data.mode]);
+ }
+ DepthJS.lastRegisterTime = new Date();
+ DepthJS.state = DepthJS.registerMode;
+ DepthJS[DepthJS.registerMode].show();
+};
+
+DepthJS.eventHandlers.onUnregister = function() {
+ if (DepthJS.verbose) console.log("DepthJS. User removed their hand");
+ DepthJS.state = null;
+ DepthJS.panner.hide();
+ DepthJS.selectorBox.hide();
+ DepthJS.selectorBoxPopup.hide();
+ DepthJS.depthose.hide();
+};
+
+DepthJS.eventHandlers.onHandClick = function() {
+ if (DepthJS.lastRegisterTime == null) return;
+ if (new Date() - DepthJS.lastRegisterTime < 1500) return;
+
+ if (DepthJS.state == "selectorBoxPopup") {
+ DepthJS.selectorBoxPopup.openHighlightedLink();
+ } else if (DepthJS.state == "selectorBox") {
+ DepthJS.selectorBox.activate();
+ } else if (DepthJS.state == "depthose") {
+ DepthJS.depthose.select();
+ }
+
+ // They are now "unregistered"
+ // setTimeout(DepthJS.eventHandlers.onUnregister, 200);
+};
+
+// Right now users can either push or pull
+DepthJS.eventHandlers.onPull = function() {
+ DepthJS.state = "depthose";
+ DepthJS.depthose.start();
+};
+
+(function() {
+var accumulatedX = null;
+var accumulatedY = null;
+var accumulatedZ = null;
+var smoothing = 0.95;
+DepthJS.eventHandlers.onMove = function(data) {
+ if (data.x == null || data.y == null || data.z == null) {
+ if (DepthJS.verbose) console.log(["Could not understand data", data]);
+ return;
+ }
+
+ data.x = 100-data.x;
+
+ if (accumulatedX == null) {
+ accumulatedX = data.x;
+ accumulatedY = data.y;
+ accumulatedZ = data.z;
+ } else {
+ accumulatedX = accumulatedX * smoothing + data.x * (1-smoothing);
+ accumulatedY = accumulatedY * smoothing + data.y * (1-smoothing);
+ accumulatedZ = accumulatedZ * smoothing + data.z * (1-smoothing);
+ }
+
+ if (DepthJS.state == "panner"){
+ DepthJS.panner.move(accumulatedX, accumulatedY, accumulatedZ);
+ } else if (DepthJS.state == "depthose") {
+ DepthJS.depthose.move(accumulatedX, accumulatedY, accumulatedZ);
+ } else if (DepthJS.state == "selectorBox") {
+ //DepthJS.selectorBox.move(accumulatedX * $(window).width() / 100,
+ // accumulatedY * $(window).height() / 100);
+ DepthJS.selectorBox.move(accumulatedX, accumulatedY);
+ } else if (DepthJS.state == "selectorBoxPopup") {
+ DepthJS.selectorBoxPopup.move(accumulatedX, accumulatedY, accumulatedZ);
+ } else {
+ if (DepthJS.verbose) console.log("Ignoring move in state " + DepthJS.state);
+ }
+};
+})();
+}
View
26 chrome-extension-mac/content_script/event_link.js
@@ -0,0 +1,26 @@
+// EVENT LINK --------------------------------------------------------------------------------------
+if (window.top === window) {
+console.log("DepthJS: Loading Event Link");
+
+DepthJS.eventLink.initPort = function() {
+ if (DepthJS.verbose) console.log("DepthJS: Event link init");
+ DepthJS.eventLink.domPort = $("<div id='DepthJS_eventPort' style='display:none'></div>");
+ $(function() {
+ DepthJS.eventLink.domPort.appendTo("body");
+ });
+ DepthJS.browser.addContentScriptListener("event", DepthJS.eventLink.onEvent);
+};
+
+DepthJS.eventLink.onEvent = function (msg) {
+ DepthJS.logSortaVerbose(msg.type, "DepthJS: event " + msg.type);
+ var handler = DepthJS.eventHandlers["on"+msg.type];
+ if (handler != null) {
+ handler(msg.data);
+ }
+ // jQuery's trigger doesn't seem to work here for some reason
+ var event = document.createEvent("Event");
+ event.initEvent(msg.type, false, false);
+ DepthJS.eventLink.domPort.text(msg.jsonRep);
+ DepthJS.eventLink.domPort.get(0).dispatchEvent(event);
+};
+}
View
35 chrome-extension-mac/content_script/init.js
@@ -0,0 +1,35 @@
+// Do the initialization
+$(function() {
+ if (window.top === window) {
+ // The parent frame is the top-level frame, not an iframe.
+ console.log(["Initing DepthJS", DepthJS]);
+ DepthJS.selectorBox.init();
+ DepthJS.eventLink.initPort();
+ DepthJS.depthose.init();
+
+ // Let us know its running
+ console.log("Finished initing, sticking in logo");
+ $("<img src='https://github.com/doug/depthjs/raw/master/chrome-extension/logo_128x128.png'>").css({
+ position: "fixed",
+ width: "32px",
+ height: "32px",
+ bottom: "20px",
+ left: "20px"
+ }).appendTo("body");
+ console.log($("img"));
+
+
+ var lastTime = null;
+ function reloadChecker() {
+ setTimeout(reloadChecker, 1000);
+ if (lastTime == null) {
+ lastTime = new Date();
+ } else if ((new Date()) - lastTime > 1300) {
+ console.log("I think I reloaded, redoing init.");
+ DepthJS.browser.readdContentScriptListeners();
+ }
+ lastTime = new Date();
+ }
+ setTimeout(reloadChecker, 1000);
+ }
+});
View
0  .../DepthJS.safariextension/content_script/panner.js → chrome-extension-mac/content_script/panner.js
File renamed without changes
View
67 chrome-extension-mac/content_script/root.js
@@ -0,0 +1,67 @@
+/*
+DepthJS
+Copyright (C) 2010 Aaron Zinman, Doug Fritz, Roy Shilkrot, Greg Elliott
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+if (window.top === window) {
+console.log("DepthJS: Loading Root");
+
+var NOT_VERBOSE = 0;
+var VERBOSE = 1;
+var STUPID_VERBOSE = 2;
+
+var DepthJS = {
+ verbose: VERBOSE,
+ registerMode: "selectorBox",
+ eventHandlers: {},
+ eventLink: {},
+ selectorBox: {},
+ selectorBoxPopup: {},
+ panner: {},
+ depthose: {},
+ browser: {},
+ MAX_HANDPLANE_WIDTH: 100,
+ MAX_HANDPLANE_HEIGHT: 100
+};
+
+(function() {
+var lastMessages = [];
+DepthJS.logSortaVerbose = function(type, fullMessage) {
+ lastMessages.push({type: type, data:fullMessage});
+};
+
+function print() {
+ setTimeout(print, 1000);
+ if (lastMessages.length == 0) return;
+ var counts = {};
+ var lastByType = {};
+ _.each(lastMessages, function(msg) {
+ if (counts[msg.type] == null) counts[msg.type] = 0;
+ counts[msg.type] = counts[msg.type] + 1;
+ lastByType[msg.type] = msg.data;
+ });
+
+ var alphabeticalKeys = _.keys(counts).sort();
+ console.log("------" + (new Date() + ""));
+ _.each(alphabeticalKeys, function(type) {
+ console.log([" " + counts[type] + " " + type + "; last = ", lastByType[type]]);
+ });
+
+ lastMessages = [];
+}
+setTimeout(print, 1000);
+
+})();
+}
View
183 chrome-extension-mac/content_script/selector_box.js
@@ -0,0 +1,183 @@
+if (window.top === window) {
+// SELECTOR BOX ------------------------------------------------------------------------------------
+console.log("DepthJS: Loading SelectorBox");
+
+DepthJS.selectorBox.firstMove = null;
+
+DepthJS.selectorBox.init = function() {
+ console.log("Initing selector box");
+ var $box = $("<div id='DepthJS_selectorBox'></div>");
+ $box.appendTo("body").hide();
+ DepthJS.selectorBox.$box = $box;
+};
+
+DepthJS.selectorBox.show = function() {
+ DepthJS.selectorBox.$box.show();
+ DepthJS.selectorBox.firstMove = null;
+};
+
+DepthJS.selectorBox.hide = function() {
+ DepthJS.selectorBox.$box.hide();
+ DepthJS.selectorBox.firstMove = null;
+};
+
+DepthJS.selectorBox.move = function(x, y) {
+ x = (x - 50) / 50.0;
+ y = (y - 50) / 50.0;
+
+ // Expode out for a smaller range in Kinect-hand space
+ x *= 5;
+ y *= 5;
+ x = Math.min(1, Math.max(-1, x));
+ y = Math.min(1, Math.max(-1, y));
+
+ var hwidth = $(window).width() * 0.5;
+ var hheight = $(window).height() * 0.5;
+ x = hwidth*x + hwidth;
+ y = hheight*y + hheight;
+
+ // Constrain to window
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ var $box = DepthJS.selectorBox.$box;
+ x = Math.min(x, $(window).width() - $box.width());
+ y = Math.min(y, $(window).height() - $box.height());
+ //console.log("move selector box to " + x + ", " + y);
+ if (x != $box.css("left") || y != $box.css("top")) {
+ $box.css({left: x, top: y});
+ }
+};
+
+DepthJS.selectorBox.activate = function() {
+ if (DepthJS.verbose) console.log("DepthJS: Activating underneath selectorBox");
+ // Lame code for now...
+
+ var $intersectingLinks = $("a").filter(function() {
+ var $a = $(this);
+ var ax = $a.offset().left + $(window).scrollLeft();
+ var aw = $a.width();
+ var ay = $a.offset().top + $(window).scrollTop();
+ var ah = $a.height();
+
+ var $box = DepthJS.selectorBox.$box;
+ var bx = $box.position().left;
+ var by = $box.position().top;
+ var bw = $box.width();
+ var bh = $box.height();
+
+ if (by > ay + ah || // box-top is lower than link-bottom
+ by + bh < ay || // box-bottom is higher than link-top
+ bx > ax + aw || // box-left is right of link right
+ bx + bw < aw) { // box-right is left of link left
+ return false;
+ }
+ return true;
+ });
+
+ if (DepthJS.verbose) console.log("Got " + $intersectingLinks.length + " links");
+ if (DepthJS.verbose) console.log($intersectingLinks);
+ if ($intersectingLinks.length > 0) {
+ DepthJS.selectorBoxPopup.$links = $intersectingLinks;
+ DepthJS.selectorBoxPopup.activate();
+ }
+};
+
+
+// SELECTOR BOX POPUP ------------------------------------------------------------------------------
+DepthJS.selectorBoxPopup.activate = function(){
+ if (DepthJS.verbose) console.log("Activating selectorbox popup");
+ var $links = DepthJS.selectorBoxPopup.$links;
+
+ if ($links.length == 1){
+ DepthJS.selectorBox.$box.fadeOut(200);
+
+ var evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ $links[0].dispatchEvent(evt);
+ return;
+ }
+
+
+ DepthJS.state = "selectorBoxPopup";
+ var $box = DepthJS.selectorBox.$box;
+ var top = $box.position().top;
+ var left = $box.position().left;
+ var position = "top:" + top + "px; left:" + left + "px";
+ $("body").append("<div id='DepthJS_selectorBoxPopup' style='" + position + "'></div>");
+
+ var popupContent = "";
+ var popupItemIndex = 0;
+
+ for(var i = 0; i < $links.length; i++){
+ var linkText = $($links[i]).text();
+
+ if (linkText.length <= 0) continue;
+
+ if (linkText.indexOf("<img") > 0) {
+ popupContent += "<div id='DepthJS_popupItem" + popupItemIndex +
+ "' class='DepthJS_selectorBoxPopupItem'>" +
+ linkText.substring(0,70) + "</div>";
+ } else {
+ popupContent += "<div id='DepthJS_popupItem" + popupItemIndex +
+ "' class='DepthJS_selectorBoxPopupItem'>" +
+ $($links[i]).html() + "</div>";
+ }
+ popupItemIndex += 1;
+ }
+ DepthJS.selectorBox.$box.hide();
+ var $popup = $("#DepthJS_selectorBoxPopup");
+ $popup.html(popupContent);
+ if (top + $popup.height() > $(window).height()) {
+ $popup.css("top", $(window).height() - $popup.height() - 40);
+ }
+ if (left + $popup.width() > $(window).width()) {
+ $popup.css("left", $(window).width() - $popup.width() - 40);
+ }
+};
+
+DepthJS.selectorBoxPopup.move = function(x, y) {
+ if (DepthJS.verbose) console.log("move selector box popup (" + x + ", " + y + ")");
+ y = (y - 50) / 50.0; // -1 to 1
+ // Expode out for a smaller range in Kinect-hand space
+ y *= 4.0;
+ console.log("pre clamp" + y);
+ y = Math.min(1.0, Math.max(-1.0, y)); // clamp to -1 to 1
+ y = (y + 1.0) / 2.0; // shift to 0 to 1
+ console.log(y);
+
+ var $links = DepthJS.selectorBoxPopup.$links;
+ var popupHeight = $("#DepthJS_selectorBoxPopup").height();
+ var closestLinkIndex = Math.round(y * $links.length-1);
+ if (DepthJS.verbose) console.log("Closest link is " + closestLinkIndex);
+
+ var $lastHighlightedLink = DepthJS.selectorBoxPopup.$lastHighlightedLink;
+ if ($lastHighlightedLink != null){
+ $lastHighlightedLink.removeClass("DepthJS_selectorBoxPopupItemHighlight");
+ }
+ var $closestLink = $("#DepthJS_popupItem" + closestLinkIndex);
+ $closestLink.addClass("DepthJS_selectorBoxPopupItemHighlight");
+
+ DepthJS.selectorBoxPopup.lastHighlightedLinkIndex = closestLinkIndex;
+ DepthJS.selectorBoxPopup.$lastHighlightedLink = $closestLink;
+};
+
+DepthJS.selectorBoxPopup.openHighlightedLink = function(){
+ var $links = DepthJS.selectorBoxPopup.$links;
+ var lastHighlightedLinkIndex = DepthJS.selectorBoxPopup.lastHighlightedLinkIndex;
+
+ if (lastHighlightedLinkIndex < 0 || lastHighlightedLinkIndex > $links.length) return;
+ var $linkToOpen = $links.eq(lastHighlightedLinkIndex);
+
+ DepthJS.selectorBoxPopup.hide();
+
+ var evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ $linkToOpen[0].dispatchEvent(evt);
+};
+
+DepthJS.selectorBoxPopup.hide = function(){
+ $("#DepthJS_selectorBoxPopup").fadeOut(300, function(){
+ $("#DepthJS_selectorBoxPopup").remove();
+ });
+};
+}
View
0  ...nsion/DepthJS.safariextension/css/selectorBox.css → chrome-extension-mac/css/selectorBox.css
File renamed without changes
View
0  ...n/DepthJS.safariextension/images/logo_128x128.png → chrome-extension-mac/images/logo_128x128.png
File renamed without changes
View
0  ...ion/DepthJS.safariextension/images/logo_16x16.png → chrome-extension-mac/images/logo_16x16.png
File renamed without changes
View
0  chrome-extension/logo_128x128.png → chrome-extension-mac/logo_128x128.png
File renamed without changes
View
44 chrome-extension-mac/manifest.json
@@ -0,0 +1,44 @@
+{
+ "version": "1.0.0",
+
+ "name": "DepthJS",
+
+ "description": "Connecting depth-aware cameras to Javascript",
+
+ "background_page": "background.html",
+
+ "icons": {
+ "16": "images/logo_16x16.png",
+ "128": "images/logo_128x128.png"
+ },
+
+ "permissions": ["tabs", "http://*/*", "https://*/*","notifications"],
+
+ "plugins": [{
+ "path": "plugin/depthjs.plugin"
+ }],
+
+ "browser_action": {
+ "default_icon": "images/logo_128x128.png",
+ "popup": "popup.html",
+ "default_title": "DepthJS"
+ },
+
+ "content_scripts": [
+ { "matches": ["http://*/*"],
+ "css": ["third_party/vfx/zflow/zflow.css",
+ "css/selectorBox.css"],
+ "js": ["third_party/jquery-1.4.4.min.js",
+ "third_party/underscore-min.js",
+ "content_script/root.js",
+ "content_script/depthose.js",
+ "third_party/vfx/zflow/zflow.js",
+ "content_script/panner.js",
+ "content_script/selector_box.js",
+ "content_script/event_handlers.js",
+ "content_script/event_link.js",
+ "chrome.js",
+ "content_script/init.js"],
+ "run_at": "document_end" }
+ ]
+}
View
1  chrome-extension-mac/plugin
View
0  ...S.safariextension/third_party/jquery-1.4.4.min.js → chrome-extension-mac/third_party/jquery-1.4.4.min.js
File renamed without changes
View
0  chrome-extension/jquery.idle-timer.js → ...me-extension-mac/third_party/jquery.idle-timer.js
File renamed without changes
View
0  ...hJS.safariextension/third_party/underscore-min.js → chrome-extension-mac/third_party/underscore-min.js
File renamed without changes
View
0  ...S.safariextension/third_party/vfx/zflow/zflow.css → chrome-extension-mac/third_party/vfx/zflow/zflow.css
File renamed without changes
View
358 chrome-extension-mac/third_party/vfx/zflow/zflow.js
@@ -0,0 +1,358 @@
+/*
+ Copyright (C) 2008, 2009 Charles Ying. All Rights Reserved.
+
+ This distribution is released under the BSD license.
+
+ http://css-vfx.googlecode.com/
+
+ See the README for documentation and license.
+*/
+if (window.top === window) {
+console.log("DepthJS: loading zflow");
+DepthJS.depthose.zflowInit = function () { // Module pattern
+ var global = this;
+
+ /*
+ Utilities (avoid jQuery dependencies)
+ */
+
+ function utils_extend(obj, dict)
+ {
+ for (var key in dict)
+ {
+ obj[key] = dict[key];
+ }
+ }
+
+ function utils_setsize(elem, w, h)
+ {
+ elem.style.width = w.toString() + "px";
+ elem.style.height = h.toString() + "px";
+ }
+
+ function utils_setxy(elem, x, y)
+ {
+ elem.style.left = Math.round(x).toString() + "px";
+ elem.style.top = Math.round(y).toString() + "px";
+ }
+
+ /*
+ TrayController is a horizontal touch event controller that tracks cumulative offsets and passes events to a delegate.
+ */
+
+ TrayController = function ()
+ {
+ return this;
+ }
+
+ TrayController.prototype.init = function (elem)
+ {
+ this.currentX = 0;
+ this.elem = elem;
+ }
+
+ TrayController.prototype.depthstart = function (e)
+ {
+ console.log(["depthstart", e]);
+ this.startX = e.pageX - this.currentX;
+ this.touchMoved = false;
+
+ window.addEventListener("depthmove", this, true);
+ window.addEventListener("depthselect", this, true);
+ window.addEventListener("depthend", this, true);
+
+ this.elem.style.webkitTransitionDuration = "0s";
+ }
+
+ TrayController.prototype.depthmove = function (e)
+ {
+ // console.log(["depthmove", e]);
+ this.touchMoved = true;
+ this.lastX = this.currentX;
+ this.lastMoveTime = new Date();
+ this.currentX = e.pageX - this.startX;
+ this.delegate.update(this.currentX);
+ }
+
+ TrayController.prototype.depthselect = function (e)
+ {
+ console.log(["depthselect", e]);
+ this.delegate.clicked(this.currentX);
+ }
+
+ TrayController.prototype.depthend = function (e)
+ {
+ console.log(["depthend", e]);
+ window.removeEventListener("depthmove", this, true);
+ window.removeEventListener("depthend", this, true);
+
+ this.elem.style.webkitTransitionDuration = "0.4s";
+
+ if (this.touchMoved)
+ {
+ /* Approximate some inertia -- the transition function takes care of the decay over 0.4s for us, but we need to amplify the last movement */
+ var delta = this.currentX - this.lastX;
+ var dt = (new Date()) - this.lastMoveTime + 1;
+ /* dx * 400 / dt */
+
+ this.currentX = this.currentX + delta * 200 / dt;
+ this.delegate.updateTouchEnd(this);
+ }
+ }
+
+ TrayController.prototype.handleEvent = function (event)
+ {
+ this[event.type](event);
+ event.preventDefault();
+ }
+
+ /*
+ These variables define how the zflow presentation is made.
+ */
+
+ const CSIZE = $(window).width() / 3;
+ const CGAP = CSIZE / 6 + 100;
+ // const CGAP = CSIZE / 2;
+
+ const FLOW_ANGLE = .3;
+ const FLOW_THRESHOLD = CGAP / 2;
+ const FLOW_ZFOCUS = CSIZE;
+ const FLOW_XGAP = CSIZE / 3;
+
+ const T_NEG_ANGLE = "rotateY(" + (- FLOW_ANGLE) + "deg)";
+ const T_ANGLE = "rotateY(" + FLOW_ANGLE + "deg)";
+ const T_ZFOCUS = "translate3d(0, 0, " + FLOW_ZFOCUS + "px)";
+
+ // const T_NEG_ANGLE = "scale(" + FLOW_ANGLE + ")";
+ // const T_ANGLE = "scale(" + FLOW_ANGLE + ")";
+ // const T_ZFOCUS = ""
+
+ FlowDelegate = function ()
+ {
+ this.cells = new Array();
+ this.transforms = new Array();
+ }
+
+ FlowDelegate.prototype.init = function (elem, imageObjs)
+ {
+ this.elem = elem;
+ this.imageObjs = imageObjs;
+ }
+
+ FlowDelegate.prototype.updateTouchEnd = function (controller)
+ {
+ this.lastFocus = undefined;
+
+ // Snap to nearest position
+ var i = this.getFocusedCell(controller.currentX);
+
+ controller.currentX = - i * CGAP;
+ this.update(controller.currentX);
+ }
+
+ FlowDelegate.prototype.clicked = function (currentX)
+ {
+ var i = - Math.round(currentX / CGAP);
+ console.log(i);
+ console.log(this.imageObjs);
+
+ if (i < 0 || i >= this.imageObjs.length) {
+ console.log("Invalid obj to select");
+ return;
+ }
+
+ this.imageObjs[i].selectCallback();
+ return; // skip rest as not needed for Depthose.
+
+ var cell = this.cells[i];
+
+ var transform = this.transformForCell(cell, i, currentX);
+
+ if ((this.lastFocus == undefined) || this.lastFocus != i)
+ {
+ //transform += " translate3d(0, 0, 150px) rotateY(180deg)";
+ this.lastFocus = i;
+ }
+ else
+ {
+ this.lastFocus = undefined;
+ }
+
+ this.setTransformForCell(cell, i, transform);
+ }
+
+ FlowDelegate.prototype.getFocusedCell = function (currentX)
+ {
+ // Snap to nearest position
+ var i = - Math.round(currentX / CGAP);
+
+ // Clamp to cells array boundary
+ return Math.min(Math.max(i, 0), this.cells.length - 1);
+ }
+
+ FlowDelegate.prototype.transformForCell = function (cell, i, offset)
+ {
+ /*
+ This function needs to be fast, so we avoid function calls, divides, Math.round,
+ and precalculate any invariants we can.
+ */
+ var x = (i * CGAP);
+ var ix = x + offset;
+
+ if ((ix < FLOW_THRESHOLD) && (ix >= -FLOW_THRESHOLD))
+ {
+ // yangle = 0, zpos = FLOW_ZFOCUS
+ return T_ZFOCUS + " translate3d(" + x + "px, 0, 0)";
+ }
+ else if (ix > 0)
+ {
+ // yangle = -FLOW_ANGLE, x + FLOW_XGAP
+ return "translate3d(" + (x + FLOW_XGAP) + "px, 0, 0) " + T_NEG_ANGLE;
+ }
+ else
+ {
+ // yangle = FLOW_ANGLE, x - FLOW_XGAP
+ return "translate3d(" + (x - FLOW_XGAP) + "px, 0, 0) " + T_ANGLE;
+ }
+ }
+
+ FlowDelegate.prototype.setTransformForCell = function (cell, i, transform)
+ {
+ if (this.transforms[i] != transform)
+ {
+ cell.style.webkitTransform = transform;
+ this.transforms[i] = transform;
+ }
+ }
+
+ FlowDelegate.prototype.update = function (currentX)
+ {
+ this.elem.style.webkitTransform = "translate3d(" + (currentX) + "px, 0, 0)";
+
+ /*
+ It would be nice if we only updated dirty cells... for now, we use a cache
+ */
+ for (var i in this.cells)
+ {
+ var cell = this.cells[i];
+ this.setTransformForCell(cell, i, this.transformForCell(cell, i, currentX));
+ i += 1;
+ }
+ }
+
+ DepthJS.depthose.zflow = function (imageObjs, selector)
+ {
+ var controller = new TrayController();
+ var delegate = new FlowDelegate();
+ var tray = document.querySelector(selector);
+
+ controller.init(tray);
+ delegate.init(tray, imageObjs);
+
+ controller.delegate = delegate;
+
+ var imagesLeft = imageObjs.length;
+
+ var cellCSS = {
+ top: Math.round(-CSIZE * 0.65) + "px",
+ left: Math.round(-CSIZE / 2) + "px",
+ width: CSIZE + "px",
+ height: Math.round(CSIZE * 1.5) + "px",
+ opacity: 0,
+ }
+
+ imageObjs.forEach(function (obj, i)
+ {
+ var cell = document.createElement("div");
+ var image = document.createElement("img");
+ var canvas = document.createElement("canvas");
+
+ cell.className = "cell";
+ cell.appendChild(image);
+ cell.appendChild(canvas);
+
+ image.src = obj.dataUrl;
+
+ image.addEventListener("load", function ()
+ {
+ imagesLeft -= 1;
+
+ var iwidth = image.width;
+ var iheight = image.height;
+
+ var ratio = Math.min(CSIZE / iheight, CSIZE / iwidth);
+
+ iwidth *= ratio;
+ iheight *= ratio;
+
+ utils_setsize(image, iwidth, iheight);
+
+ utils_extend(cell.style, cellCSS);
+
+ utils_setxy(image, (CSIZE - iwidth) / 2, CSIZE - iheight);
+ utils_setxy(canvas, (CSIZE - iwidth) / 2, CSIZE);
+
+ reflect(image, iwidth, iheight, canvas);
+
+ delegate.setTransformForCell(cell, delegate.cells.length, delegate.transformForCell(cell, delegate.cells.length, controller.currentX));
+ delegate.cells.push(cell);
+
+ // Start at 0 opacity
+ tray.appendChild(cell);
+
+ // Set to 1 to fade element in.
+ cell.style.opacity = 1.0;
+
+ if (imagesLeft == 0)
+ {
+ window.setTimeout( function() { window.scrollTo(0, 0); }, 100 );
+ }
+ });
+ });
+
+ tray.addEventListener('depthstart', controller, false);
+
+ /* Limited keyboard support for now */
+ window.addEventListener('keydown', function (e)
+ {
+ if (e.keyCode == 37)
+ {
+ /* Left Arrow */
+ controller.currentX += CGAP;
+ delegate.updateTouchEnd(controller);
+ }
+ else if (e.keyCode == 39)
+ {
+ /* Right Arrow */
+ controller.currentX -= CGAP;
+ delegate.updateTouchEnd(controller);
+ }
+ });
+ }
+
+ function reflect(image, iwidth, iheight, canvas)
+ {
+ canvas.width = iwidth;
+ canvas.height = iheight / 2;
+
+ var ctx = canvas.getContext("2d");
+
+ ctx.save();
+
+ ctx.translate(0, iheight - 1);
+ ctx.scale(1, -1);
+ ctx.drawImage(image, 0, 0, iwidth, iheight);
+
+ ctx.restore();
+
+ ctx.globalCompositeOperation = "destination-out";
+
+ var gradient = ctx.createLinearGradient(0, 0, 0, iheight / 2);
+ gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
+ gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
+
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, 0, iwidth, iheight / 2);
+ }
+};
+}
View
0  chrome-extension/README.mk
No changes.
View
546 chrome-extension/background.html
@@ -1,546 +0,0 @@
-<html><head>
-<script src="jquery-1.4.4.min.js"></script>
-<script src="underscore-min.js"></script>
-<script src="jquery.idle-timer.js"></script>
-<script>
-/*
-DepthJS
-Copyright (C) 2010 Aaron Zinman, Doug Fritz, Roy Shilkrot, and Greg Elliott
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-console.log('background.html Starting DepthJS');
-var DepthJS = {
- __VERSION__: '0.1',
- verbose: true,
- backend: {},
- eventHandlers: {},
- cv: {},
- tools: {},
- portsByTabId: {},
- imageListeners: [],
- eventListeners: [],
- depthListeners: [],
- tabs: {},
- test: {}
-};
-
-console.log('Making loader');
-
-var WS_CONNECTING = 0;
-var WS_OPEN = 1;
-var WS_CLOSING = 2;
-var WS_CLOSED = 3;
-
-DepthJS.init = function () {
- if (DepthJS.verbose) console.log("Connecting WebSocket");
- if (!DepthJS.backend.connect()) {
- if (DepthJS.verbose) console.log("Couldn't connect... aborting");
- return;
- }
- DepthJS.tabs.init();
-}
-
-DepthJS.tabs.thumbnailCache = {};
-DepthJS.tabs.tabCache = {};
-DepthJS.tabs.windowCache = {};
-
-DepthJS.tabs.init = function() {
- DepthJS.tabs.populateCaches();
-
- // Subscribe to event handlers
- chrome.tabs.onCreated.addListener(function(tab) {
- // console.log('new tab created: ' + obj_repr(tab, 'Tab'));
- // But not yet loaded--wait for onUpdated
- DepthJS.tabs.tabCache[tab.id] = tab;
- });
-
- chrome.tabs.onRemoved.addListener(DepthJS.tabs.onClosedTab);
-
- chrome.tabs.onUpdated.addListener(DepthJS.tabs.onTabUpdated);
-
- chrome.windows.onRemoved.addListener(function(windowId) {
- // console.log('window removed: id=' + windowId);
- });
-};
-
-DepthJS.tabs.populateCaches = function() {
- var obj_repr = DepthJS.tools.obj_repr;
- // Go through all existing tabs/windows and add to cache
- chrome.windows.getAll({populate: true}, function(windows) {
- for (var i = 0; i < windows.length; ++i) {
- var window = windows[i];
- if (DepthJS.verbose) console.log('Adding existing window '+ obj_repr(window, 'Window'));
- for (var j = 0; j < window.tabs.length; ++j) {
- var tab = window.tabs[j];
- if (DepthJS.verbose) console.log('Adding existing tab ' + obj_repr(tab, 'Tab'));
- DepthJS.tabs.tabCache[tab.id] = tab;
-
- if (tab.status == 'complete') {
- // We should add this already loaded tab
- if (tab.selected) { // since we are only doing a screenshot on new
- DepthJS.tabs.onNewVisibleTab(tab.url, tab.title, window.id, tab.id);
- }
- }
- }
- delete window.tabs; // Unnecessary... it'll be too stale to do anything with.
- DepthJS.tabs.windowCache[window.id] = window;
- }
- });
-};
-
-DepthJS.tabs.onTabUpdated = function(tabId, changeInfo, tab) {
- var cachedTab = DepthJS.tabs.tabCache[tabId];
- if (!cachedTab) {
- if (DepthJS.verbose) console.log('Could not find tabId ' + tabId + ' in cache: ' + cachedTab);
- return;
- }
-
- if (changeInfo.status == 'complete' && cachedTab.status == 'loading') {
- if (tab.selected) DepthJS.tabs.onNewVisibleTab(tab.url, tab.title, tab.id);
- } else if (tab.url != cachedTab.url) {
- DepthJS.tabs.onClosedTab(cachedTab.id);
- if (tab.status == 'complete') {
- // Never the case?
- if (tab.selected) DepthJS.tabs.onNewVisibleTab(tab.url, tab.title, tab.id);
- }
- }
- // Save state
- delete DepthJS.tabs.tabCache[tabId]; // help GC
- DepthJS.tabs.tabCache[tabId] = tab;
-};
-
-DepthJS.tabs.onNewVisibleTab = function(url, title, windowId, tabId) {
- // Take screenshot
- var capture = function(windowId) {
- chrome.tabs.captureVisibleTab(windowId, null, function(dataUrl) {
- if (DepthJS.verbose) console.log("captured thumbnail for tabId " + tabId);
- DepthJS.tabs.thumbnailCache[tabId] = {
- dataUrl: dataUrl,
- title: title};
- });
- }
- if (tabId != null) {
- capture(windowId);
- } else {
- tabId = windowId; // variable num args in function call, jquery style.
- chrome.tabs.get(tabId, function(tab) { capture(tab.windowId); });
- }
-};
-
-DepthJS.tabs.onClosedTab = function(tabId) {
- if (DepthJS.portsByTabId[tabId] != null) {
- if (DepthJS.verbose) console.log("Had ports by closed tab laying around, deleting");
- delete DepthJS.portsByTabId[tabId];
- }
- // Close page
- var cachedTab = DepthJS.tabs.tabCache[tabId];
- if (!cachedTab) {
- if (DepthJS.verbose) console.log('Could not find tabId ' + tabId + ' in cache: ' + cachedTab);
- return;
- }
-
- delete DepthJS.tabs.tabCache[tabId];
- if (DepthJS.tabs.thumbnailCache[tabId] != null) {
- delete DepthJS.tabs.thumbnailCache[tabId];
- }
-};
-
-DepthJS.tabs.onReaccessedTab = function(url, tabId) {
-};
-
-
-DepthJS.tools.obj_repr = function (obj, className) {
- var buf = [];
- if (className === undefined) {
- buf.push('[Object ');
- } else {
- buf.push('[' + className + ' ');
- }
- for (var key in obj) {
- buf.push(key + '=' + obj[key]);
- buf.push(', ');
- }
- buf.pop();
- buf.push(']');
- return buf.join('');
-};
-
-DepthJS.backend.eventWs = null;
-DepthJS.backend.imageWs = null;
-DepthJS.backend.depthWs = null;
-DepthJS.backend.host = "localhost";
-DepthJS.backend.port = 8000;
-DepthJS.backend.connecting = false;
-DepthJS.backend.connected = false;
-
-DepthJS.backend.connect = function() {
- DepthJS.backend.connecting = true;
- chrome.extension.sendRequest({action: "connecting"});
- var connected = 0;
- function check() {
- connected++;
- if (connected == 3) {
- if (DepthJS.verbose) console.log("All 3 connected");
- chrome.extension.sendRequest({action: "connected"});
- DepthJS.backend.connecting = false;
- DepthJS.backend.connected = true;
- }
- }
-
- // If we do not connect within a timeout period,
- // effectively cancel it and let the popup know.
- setTimeout(function() {
- if (connected != 3) {
- DepthJS.backend.disconnect();
- }
- }, 3000);
-
- return _.all(_.map(["event", "image", "depth"], function(stream) {
- var path = "ws://" + DepthJS.backend.host + ":" + DepthJS.backend.port + "/" + stream;
- if (DepthJS.verbose) console.log("Connecting to " + stream + " stream on " + path);
-
- // Clear out any old sockets
- var oldSocket = DepthJS.backend[stream+"Ws"];
- if (oldSocket != null) {
- oldSocket.onmessage = null;
- oldSocket.onclose = null;
- oldSocket.onopen = null;
-
- if (oldSocket.readyState == WS_OPEN ||
- oldSocket.readyState == WS_CONNECTING) {
- oldSocket.close();
- }
- }
-
- var socket = new WebSocket(path);
- DepthJS.backend[stream+"Ws"] = socket;
-
- socket.onmessage = function(data){
- DepthJS.backend.onMessage(stream, data);
- };
-
- socket.onclose = function() {
- DepthJS.backend.onDisconnect(stream);
- };
-
- socket.onopen = function() {
- DepthJS.backend.onConnect(stream);
- check();
- };
-
- return true;
- }));
-};
-
-DepthJS.backend.onMessage = function (stream, data) {
- if (stream == "event") {
- if (data === undefined || data.data == null) {
- return;
- }
- if (DepthJS.verbose) console.log(data.data);
- var msg = JSON.parse(data.data);
- if (!$.isPlainObject(msg)) {
- if (DepthJS.verbose) console.log('Unknown message: ' + data);
- return;
- }
- var handler = DepthJS.eventHandlers["on"+msg.type];
- if (handler != null) {
- handler(msg.data);
- }
-
- msg.jsonRep = data.data;
- // Don't send to all--send to only the current tab.
- // _.each(DepthJS.eventListeners, function(port) {
- // port.postMessage(msg);
- // });
- chrome.tabs.getSelected(null, function (tab) {
- var tabId = tab.id;
- var tabPorts = DepthJS.portsByTabId[tabId];
- if (tabPorts == null) {
- if (DepthJS.verbose) console.log("Could not find ports for tabId " + tabId);
- return;
- }
- var eventPort = tabPorts.event;
- if (eventPort == null) {
- if (DepthJS.verbose) console.log("Could not find event port for tabId " + tabId);
- return;
- }
-
- eventPort.postMessage(msg);
- });
- } else if (stream == "image") {
- DepthJS.eventHandlers.onImageMsg(data);
- } else if (stream == "depth") {
- DepthJS.eventHandlers.onDepthMsg(data);
- }
-};
-
-DepthJS.backend.disconnect = function() {
- DepthJS.backend.connected = false;
- if (DepthJS.verbose) console.log("Disconnecting");
- chrome.extension.sendRequest({action: "disconnected"});
- return _.map(["event", "image", "depth"], function(stream) {
- var oldSocket = DepthJS.backend[stream+"Ws"];
- if (oldSocket != null) {
- oldSocket.onmessage = null;
- oldSocket.onclose = null;
- oldSocket.onopen = null;
-
- if (oldSocket.readyState == WS_OPEN ||
- oldSocket.readyState == WS_CONNECTING) {
- oldSocket.close();
- }
- }
- DepthJS.backend[stream+"Ws"] = null;
- });
-}
-
-DepthJS.backend.onDisconnect = function (stream) {
- if (DepthJS.verbose) console.log("Disconnected on " + stream + " stream");
- // If one is closed, close them all.
- DepthJS.backend.disconnect();
-};
-
-DepthJS.backend.onConnect = function (stream) {
- if (DepthJS.verbose) console.log("Connect on " + stream + " stream");
-};
-
-
-(function() {
- // WebSockets have frames of a limited size (<32k seems to work best)
- // Buffer the data until we have a complete frame
- function makeImageBuffer(listeners, bytes) {
- var w = 160;
- var h = 120;
- var dataArray = [];
- var dataLength = 0;
- var frameSize = w*h*bytes;
- return function(frameEvent) {
- if (DepthJS.verbose) console.log(frameEvent.data.length);
- var frameData = atob(frameEvent.data);
- if (DepthJS.verbose) console.log(frameData.length);
- _.each(listeners, function(port) {
- if (DepthJS.verbose) console.log("sending image or depth data");
- port.postMessage({data: frameData});
- });
- return;
- if (dataLength + frameData.length < frameSize) {
- dataArray.push(frameData);
- dataLength += frameData.length;
- if (DepthJS.verbose) console.log("got " + frameData.length + " bytes, need " + (frameSize - dataLength) + "more");
- } else {
- var rem = (dataLength + frameData.length) - frameSize;
- var dataTail = frameData.substring(0,frameData.length - rem);
- var remData = frameData.substring(frameData.length - rem + 1);
- dataArray.push(dataTail);
- var data = dataArray.join("");
- _.each(listeners, function(port) {
- if (DepthJS.verbose) console.log("sending image or depth data");
- port.postMessage({data: data});
- });
- dataArray = [];
- dataLength = 0;
- if (remData.length > 0) {
- dataArray.push(remData);
- dataLength += remData.length;
- }
- }
- };
- }
- DepthJS.eventHandlers.onDepthMsg = makeImageBuffer(DepthJS.depthListeners, 1);
- DepthJS.eventHandlers.onImageMsg = makeImageBuffer(DepthJS.imageListeners, 3);
-})();
-
-console.log('Defined DepthJS... launching init');
-DepthJS.init();
-
-console.log("Setting up message passing listener");
-var urls = [];
-chrome.extension.onConnect.addListener(function(port) {
- var name = port.name;
- if (DepthJS.verbose) console.assert(name == "event" || name == "image" || name == "depth");
- if (DepthJS.verbose) console.log(name + " port connected");
- var listeners = DepthJS[name + "Listeners"];
- listeners.push(port);
-
- var tabId = port.sender.tab.id;
- var tabPorts = DepthJS.portsByTabId[tabId];
- if (tabPorts == null) {
- tabPorts = {}; DepthJS.portsByTabId[tabId] = tabPorts;
- }
- tabPorts[name] = port;
-
- port.onDisconnect.addListener(function (e) {
- if (DepthJS.verbose) console.log(name + " port disconnected on tab " + tabId);
- DepthJS[name + "Listeners"] = _.reject(
- listeners, function(el) { el === port; });
- var _tabPorts = DepthJS.portsByTabId[tabId];
- if (_tabPorts) {
- delete _tabPorts[name];
- if (_.isEmpty(_tabPorts)) {
- if (DepthJS.verbose) console.log("for all ports on this tab");
- delete DepthJS.portsByTabId[tabId];
- }
- }
- });
-});
-
-function split(str, size) {
- var splits = [];
- var lastEnd = 0;
- while (true) {
- if (lastEnd + size > str.length) {
- if (lastEnd != str.length) splits.push(str.slice(lastEnd));
- break;
- } else {
- splits.push(str.slice(lastEnd, lastEnd+size));
- lastEnd += size;
- }
- }
- return splits;
-};
-
-DepthJS.registerMode = "selectorBox";
-
-chrome.extension.onRequest.addListener(function(req, sender, sendResponse) {
- if (req.action == "connect") {
- DepthJS.backend.connect();
- } else if (req.action == "disconnect") {
- DepthJS.backend.disconnect();
- } else if (req.action == "getConnectState") {
- if (DepthJS.backend.connecting) {
- sendResponse({state: "connecting", mode: DepthJS.registerMode});
- } else {
- sendResponse({state: DepthJS.backend.connected ? "connected" : "disconnected",
- mode: DepthJS.registerMode});
- }
- } else if (req.action == "depthoseTest") {
- if (DepthJS.verbose) console.log("depthosetest");
- DepthJS.test.depthoseTest();
- } else if (req.action == "pannerTest") {
- DepthJS.test.pannerTest();
- } else if (req.action == "selectorBoxTest") {
- DepthJS.test.selectorBoxTest();
- } else if (req.action == "getThumbnailCache") {
- if (DepthJS.verbose) console.log(["sending thumbnail cache", DepthJS.tabs.thumbnailCache]);
- sendResponse({thumbnailCache: DepthJS.tabs.thumbnailCache});
- } else if (req.action == "selectTab") {
- chrome.tabs.update(req.tabId, {selected: true});
- } else if (req.action == "depthoseMode") {
- console.log("going to depthose mode");
- DepthJS.registerMode = "depthose";
- DepthJS.test.sendTestEvent({type: "DepthoseMode", data:{}});
- } else if (req.action == "pannerMode") {