Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / examples / ux / event / Player.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 Ext.define('Ext.ux.event.Player', {
16     extend: 'Ext.ux.event.Driver',
17
18     speed: 1.0,
19
20     tagPathRegEx: /(\w+)(?:\[(\d+)\])?/,
21
22     constructor: function (config) {
23         var me = this;
24
25         me.callParent(arguments);
26
27         me.eventObject = new Ext.EventObjectImpl();
28         me.timerFn = Ext.Function.bind(me.onTick, me);
29     },
30
31     getElementFromXPath: function (xpath) {
32         var parts = xpath.split('/'),
33             regex = this.tagPathRegEx,
34             i, n, m, count, tag, child,
35             el = (parts[0] == '~') ? document.body
36                     : Ext.fly(parts[0].substring(1)).dom; // remove '#'
37
38         for (i = 1, n = parts.length; el && i < n; ++i) {
39             m = regex.exec(parts[i]);
40             count = m[2] ? parseInt(m[2], 10) : 1;
41             tag = m[1].toUpperCase();
42
43             for (child = el.firstChild; child; child = child.nextSibling) {
44                 if (child.tagName == tag) {
45                     if (count == 1) {
46                         break;
47                     }
48                     --count;
49                 }
50             }
51
52             el = child;
53         }
54
55         return el;
56     },
57
58     onEnd: function () {},
59
60     onStart: function () {
61         this.schedule(0);
62     },
63
64     onStop: function () {
65         var me = this;
66
67         if (me.timer) {
68             clearTimeout(me.timer);
69             me.timer = null;
70         }
71
72         me.onEnd();
73     },
74
75     onTick: function () {
76         var me = this,
77             event,
78             eventIndex = me.nextEvent,
79             events = me.events,
80             timeIndex = me.getTimestamp() * me.speed;
81
82         me.timer = null;
83
84         while (1) {
85             event = events[eventIndex];
86
87             if (event.ts > timeIndex) {
88                 me.schedule(eventIndex);
89                 break;
90             }
91
92             me.playEvent(event);
93
94             if (++eventIndex == events.length) {
95                 me.stop();
96                 break;
97             }
98         }
99     },
100
101     playEvent: function (event) {
102         var me = this,
103             eventObject = me.eventObject,
104             modKeys = event.modKeys || '',
105             target = me.getElementFromXPath(event.target);
106
107         if (target) {
108             Ext.log('play: ' + Ext.encode(event));
109             eventObject.type = event.type;
110             eventObject.xy = event.xy || null;
111             eventObject.button = event.button;
112
113             if ('wheel' in event) {
114                 // see getWheelDelta
115             }
116
117             eventObject.altKey = modKeys.indexOf('A') > 0;
118             eventObject.ctrlKey = modKeys.indexOf('C') > 0;
119             eventObject.metaKey = modKeys.indexOf('M') > 0;
120             eventObject.shiftKey = modKeys.indexOf('S') > 0;
121
122             eventObject.injectEvent(target);
123         } else {
124             Ext.log('Cannot find: ', event.target);
125         }
126     },
127
128     schedule: function (eventIndex) {
129         var me = this;
130         me.nextEvent = eventIndex;
131         me.timer = setTimeout(me.timerFn, 10);
132     }
133 });
134