PageRenderTime 29ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/sencha-touch-1.1.1/examples/kitchensink/src/demos/simulator.js

https://github.com/metaodi/TrailDevilsXPl-2
JavaScript | 362 lines | 316 code | 34 blank | 12 comment | 50 complexity | fce1bfa81490f3ba12ba03a6282ea273 MD5 | raw file
  1. demos.isSimulatorEnabled = false;
  2. demos.isSimulatorDemoing = false;
  3. demos.Simulator = new Ext.Panel({
  4. layout: {
  5. type: 'vbox',
  6. pack: 'center',
  7. align: 'stretch'
  8. },
  9. defaults: {
  10. xtype: 'button',
  11. cls: 'demobtn'
  12. },
  13. items: [
  14. // {
  15. // text: 'Dump',
  16. // handler: function() {
  17. // var events = Ext.getCmp('simulator').getRecorder().getEventSet('main');
  18. // console.log(JSON.stringify(events));
  19. // Ext.Ajax.request({
  20. // url: '../../dump.php',
  21. // method: 'POST',
  22. // params: {data: JSON.stringify(events)}
  23. // });
  24. // }
  25. // },
  26. {
  27. text: "What's This?",
  28. handler: function() {
  29. if (!this.popup) {
  30. var popup = this.popup = new Ext.Panel({
  31. cls: "x-simulator-popup",
  32. floating: true,
  33. modal: true,
  34. centered: true,
  35. width: "90%",
  36. height: "80%",
  37. styleHtmlContent: true,
  38. scroll: 'vertical',
  39. html: "<p>Sencha Touch's <b>EventRecorder</b> and <b>EventSimulator</b> allow you to capture, \n\
  40. store and later playback all the touch events fired on the device's screen.</p>\n\
  41. <p>This opens up the possibility for automated UI and functional testing, or something\n\
  42. cool like live demostration of how your app works without the need of any pre-recorded videos.</p>\n\
  43. <p>Close this dialog and tap on the <b>\"Show Me!\"</b> button to see it in action. A demo series of events \n\
  44. (technically an array of serialized events in JSON format) will be replayed live on the screen.</p>\n\
  45. <p>To try it yourself, follow the steps below:\n\
  46. <ul>\n\
  47. <li>Show the Simulator Toolbar by tapping on the <b>\"Enable Simulator\"</b> button</li>\n\
  48. <li>Tap on the <b>\"Start\"</b> button to start recording events.</li>\n\
  49. <li>Interact with the app in any way you like, then tap on the <b>\"Stop\"</b> button to stop recording.</li>\n\
  50. <li>Tap on the <b>\"Playback\"</b> button and enjoy watching!.</li>\n\
  51. <li>Remember to tap on the <b>\"Erase\"</b> button before tapping on <b>\"Start\"</b> again if you want to start a new session.\n\
  52. Otherwise it will resume recording from where it was left off.</li>\n\
  53. </ul></p>",
  54. dockedItems: [{
  55. dock: 'bottom',
  56. xtype: 'toolbar',
  57. layout: {
  58. type: 'vbox',
  59. pack: 'center',
  60. align: 'stretch'
  61. },
  62. items: [
  63. { xtype: 'button', ui: 'decline', text: 'Close', handler: function() { popup.hide('fade'); } }
  64. ]
  65. }]
  66. });
  67. }
  68. this.popup.show('pop');
  69. }
  70. },
  71. {
  72. ui: 'action',
  73. text: "Show Me!",
  74. handler: function() {
  75. if (Ext.Viewport.orientation != 'portrait') {
  76. Ext.Msg.alert('Sorry...', 'The pre-recorded data were made for portrait orientation only. Rotate your device and try again');
  77. }
  78. else if (Ext.is.Desktop){
  79. Ext.Msg.alert('Sorry...', "There's no pre-recorded data for desktop yet. Tap on \"What's This?\" for instructions.");
  80. }
  81. else {
  82. var simulator = Ext.getCmp('simulator');
  83. simulator.enableSimulator();
  84. demos.Simulator.setLoading(true);
  85. Ext.Ajax.request({
  86. url: 'resources/simulator/' + ((Ext.is.Phone) ? 'phone' : 'tablet') + '.json',
  87. method: 'GET',
  88. success: function(response, opts) {
  89. demos.Simulator.setLoading(false);
  90. simulator.getRecorder().setEventSet('demo', Ext.decode(response.responseText));
  91. simulator.getRecorder().replay('demo');
  92. }
  93. });
  94. }
  95. }
  96. },
  97. {
  98. id: 'simulator',
  99. ui: 'confirm',
  100. text: 'Enable Simulator',
  101. recorderEvents: ['touchstart', 'touchmove', 'touchend', 'mousedown', 'mousemove', 'mouseup', 'click'],
  102. handler: function() {
  103. if (!demos.isSimulatorEnabled) {
  104. this.enableSimulator();
  105. } else {
  106. this.disableSimulator();
  107. }
  108. },
  109. enableSimulator: function() {
  110. if (!demos.isSimulatorEnabled) {
  111. demos.isSimulatorEnabled = true;
  112. this.setText('Disable Simulator');
  113. this.el.addCls('x-button-decline').removeCls('x-button-confirm');
  114. this.showToolbar();
  115. }
  116. },
  117. disableSimulator: function() {
  118. if (demos.isSimulatorEnabled) {
  119. demos.isSimulatorEnabled = false;
  120. this.setText('Enable Simulator');
  121. this.el.removeCls('x-button-decline').addCls('x-button-confirm');
  122. this.hideToolbar();
  123. this.eraseRecorder();
  124. }
  125. },
  126. doRecord: function(e) {
  127. var target = e.target;
  128. if (target.nodeType == 3)
  129. target = target.parentNode;
  130. if (Ext.get(target).hasCls('x-button-label')) {
  131. target = target.parentNode;
  132. }
  133. if (!Ext.get(target).hasCls('recorderButton')) {
  134. this.getRecorder().record('main', e);
  135. }
  136. },
  137. getRecorder: function() {
  138. if (!this.recorder) {
  139. this.recorder = new Ext.util.EventRecorder();
  140. this.recorder.on({
  141. replaystart: this.onReplayStart,
  142. replayend: this.onReplayEnd,
  143. beforecalculatetarget: this.onBeforeCalculateTarget,
  144. aftercalculatetarget: this.onAfterCalculateTarget,
  145. beforefire: this.onBeforeFire,
  146. afterfire: this.onAfterFire,
  147. interrupted: this.onInterrupted,
  148. scope: this
  149. });
  150. }
  151. return this.recorder;
  152. },
  153. startRecorder: function() {
  154. if (demos.isSimulatorDemoing) {
  155. return;
  156. }
  157. var me = this;
  158. if (!this.doRecordWrap) {
  159. this.doRecordWrap = Ext.createDelegate(me.doRecord, me);
  160. }
  161. this.getRecorder().start('main');
  162. this.recorderEvents.forEach(function(name) {
  163. document.addEventListener(name, me.doRecordWrap, true);
  164. });
  165. this.isRecording = true;
  166. },
  167. stopRecorder: function() {
  168. if (demos.isSimulatorDemoing) {
  169. return;
  170. }
  171. var me = this;
  172. if (!this.doRecordWrap) {
  173. this.doRecordWrap = Ext.createDelegate(me.doRecord, me);
  174. }
  175. this.recorderEvents.forEach(function(name) {
  176. document.removeEventListener(name, me.doRecordWrap, true);
  177. });
  178. window.localStorage.setItem('recordedEvents', JSON.stringify(this.getRecorder().getEventSet('main')));
  179. },
  180. eraseRecorder: function() {
  181. this.getThumb().hide();
  182. this.getRecorder().erase('main');
  183. window.localStorage.setItem('recordedEvents', null);
  184. },
  185. replayRecorder: function() {
  186. if (this.isRecording) {
  187. this.stopRecorder();
  188. this.isRecording = false;
  189. }
  190. var events = window.localStorage.getItem('recordedEvents');
  191. if (events) {
  192. this.getRecorder().setEventSet('main', JSON.parse(events));
  193. }
  194. this.getRecorder().replay('main');
  195. },
  196. showToolbar: function() {
  197. sink.Main.ui.addDocked(this.getToolbar());
  198. },
  199. hideToolbar: function() {
  200. sink.Main.ui.removeDocked(this.getToolbar(), false);
  201. },
  202. getToolbar: function() {
  203. if (!this.toolbar) {
  204. this.toolbar = new Ext.Toolbar({
  205. docked: 'bottom',
  206. items: [
  207. {
  208. xtype: 'button',
  209. ui: 'confirm',
  210. cls: 'recorderButton',
  211. text: 'Start',
  212. handler: Ext.createDelegate(this.startRecorder, this)
  213. },
  214. {
  215. xtype: 'button',
  216. text: 'Stop',
  217. ui: 'decline',
  218. cls: 'recorderButton',
  219. handler: Ext.createDelegate(this.stopRecorder, this)
  220. },
  221. {
  222. xtype: 'button',
  223. text: 'Erase',
  224. ui: 'action',
  225. cls: 'recorderButton',
  226. handler: Ext.createDelegate(this.eraseRecorder, this)
  227. },
  228. {
  229. xtype: 'button',
  230. ui: 'forward',
  231. text: 'Playback',
  232. cls: 'recorderButton',
  233. handler: Ext.createDelegate(this.replayRecorder, this)
  234. }
  235. ]
  236. });
  237. }
  238. return this.toolbar;
  239. },
  240. onEventDuringReplay: function(e) {
  241. if (!e.isSimulated) {
  242. e.preventDefault();
  243. e.stopPropagation();
  244. e.stopped = true;
  245. if (e.type == 'touchstart' || e.type == 'mousedown') {
  246. this.getRecorder().stopReplay();
  247. }
  248. return false;
  249. }
  250. },
  251. getThumb: function() {
  252. if (!this.thumb) {
  253. this.thumb = Ext.getBody().createChild({
  254. cls: 'x-simulator-thumb'
  255. });
  256. this.thumb.hide();
  257. }
  258. return this.thumb;
  259. },
  260. onReplayStart: function(name) {
  261. if (name == 'demo') {
  262. demos.isSimulatorDemoing = true;
  263. }
  264. if (!this.onEventDuringReplayWrap) {
  265. this.onEventDuringReplayWrap = Ext.createDelegate(this.onEventDuringReplay, this);
  266. }
  267. Ext.gesture.Manager.detachListeners();
  268. this.recorderEvents.forEach(function(name) {
  269. document.addEventListener(name, this.onEventDuringReplayWrap, true);
  270. }, this);
  271. Ext.gesture.Manager.attachListeners();
  272. this.getThumb().show();
  273. },
  274. onReplayEnd: function(name, isInterrupted) {
  275. var me = this;
  276. if (name == 'demo') {
  277. demos.isSimulatorDemoing = false;
  278. }
  279. this.recorderEvents.forEach(function(name) {
  280. document.removeEventListener(name, this.onEventDuringReplayWrap, true);
  281. }, this);
  282. this.getThumb().hide();
  283. if (isInterrupted) {
  284. if (!confirm("Do you want to stop this playback?")) {
  285. setTimeout(function() {
  286. me.getRecorder().resumeReplay(name);
  287. }, 100);
  288. }
  289. } else {
  290. if (name == 'demo') {
  291. Ext.Msg.alert("End of Demo", "For full description / instructions, tap on the \"What's This?\" button");
  292. }
  293. }
  294. },
  295. onBeforeCalculateTarget: function() {
  296. this.getThumb().dom.style.visibility = 'hidden';
  297. },
  298. onAfterCalculateTarget: function() {
  299. this.getThumb().dom.style.visibility = 'visible';
  300. },
  301. onAfterFire: Ext.emptyFn,
  302. onInterrupted: function() {
  303. this.getThumb().removeCls('pressed');
  304. },
  305. onBeforeFire: function(type, target, event) {
  306. var point = Ext.util.Point.fromEvent(event);
  307. point.translate(-20, -20);
  308. Ext.Element.cssTranslate(this.getThumb(), point);
  309. if (type == 'touchstart' || type == 'mousedown') {
  310. this.getThumb().addCls('pressed');
  311. } else if (type == 'touchend' || type == 'mouseup') {
  312. this.getThumb().removeCls('pressed');
  313. }
  314. }
  315. }]
  316. });
  317. Ext.Element.fromPoint = function(x, y) {
  318. if (!demos.isSimulatorEnabled) {
  319. return Ext.get(document.elementFromPoint(x, y));
  320. } else {
  321. var thumb = Ext.getCmp('simulator').getThumb(),
  322. target;
  323. thumb.dom.style.visibility = 'hidden';
  324. target = Ext.get(document.elementFromPoint(x, y));
  325. thumb.dom.style.visibility = 'visible';
  326. return target;
  327. }
  328. };