]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * Recorder manager.\r | |
3 | * Used as a bookmarklet:\r | |
4 | *\r | |
5 | * javascript:void(window.open("../ux/event/RecorderManager.html","recmgr"))\r | |
6 | */\r | |
7 | Ext.define('Ext.ux.event.RecorderManager', {\r | |
8 | extend: 'Ext.panel.Panel',\r | |
9 | \r | |
10 | alias: 'widget.eventrecordermanager',\r | |
11 | \r | |
12 | uses: [\r | |
13 | 'Ext.ux.event.Recorder',\r | |
14 | 'Ext.ux.event.Player'\r | |
15 | ],\r | |
16 | \r | |
17 | layout: 'fit',\r | |
18 | buttonAlign: 'left',\r | |
19 | \r | |
20 | eventsToIgnore: {\r | |
21 | mousemove: 1,\r | |
22 | mouseover: 1,\r | |
23 | mouseout: 1\r | |
24 | },\r | |
25 | \r | |
26 | bodyBorder: false,\r | |
27 | playSpeed: 1,\r | |
28 | \r | |
29 | initComponent: function () {\r | |
30 | var me = this;\r | |
31 | \r | |
32 | me.recorder = new Ext.ux.event.Recorder({\r | |
33 | attachTo: me.attachTo,\r | |
34 | listeners: {\r | |
35 | add: me.updateEvents,\r | |
36 | coalesce: me.updateEvents,\r | |
37 | buffer: 200,\r | |
38 | scope: me\r | |
39 | }\r | |
40 | });\r | |
41 | me.recorder.eventsToRecord = Ext.apply({}, me.recorder.eventsToRecord);\r | |
42 | \r | |
43 | function speed (text, value) {\r | |
44 | return {\r | |
45 | text: text,\r | |
46 | speed: value,\r | |
47 | group: 'speed',\r | |
48 | checked: value == me.playSpeed,\r | |
49 | handler: me.onPlaySpeed,\r | |
50 | scope: me\r | |
51 | };\r | |
52 | }\r | |
53 | \r | |
54 | me.tbar = [\r | |
55 | {\r | |
56 | text: 'Record',\r | |
57 | xtype: 'splitbutton',\r | |
58 | whenIdle: true,\r | |
59 | handler: me.onRecord,\r | |
60 | scope: me,\r | |
61 | menu: me.makeRecordButtonMenu()\r | |
62 | },\r | |
63 | {\r | |
64 | text: 'Play',\r | |
65 | xtype: 'splitbutton',\r | |
66 | whenIdle: true,\r | |
67 | handler: me.onPlay,\r | |
68 | scope: me,\r | |
69 | menu: [\r | |
70 | speed('Qarter Speed (0.25x)', .25),\r | |
71 | speed('Half Speed (0.5x)', .5 ),\r | |
72 | speed('3/4 Speed (0.75x)', .75),\r | |
73 | '-',\r | |
74 | speed('Recorded Speed (1x)', 1),\r | |
75 | speed('Double Speed (2x)', 2),\r | |
76 | speed('Quad Speed (4x)', 4),\r | |
77 | '-',\r | |
78 | speed('Full Speed', 1000)\r | |
79 | ]\r | |
80 | },\r | |
81 | {\r | |
82 | text: 'Clear',\r | |
83 | whenIdle: true,\r | |
84 | handler: me.onClear,\r | |
85 | scope: me\r | |
86 | },\r | |
87 | '->',\r | |
88 | {\r | |
89 | text: 'Stop',\r | |
90 | whenActive: true,\r | |
91 | disabled: true,\r | |
92 | handler: me.onStop,\r | |
93 | scope: me\r | |
94 | }\r | |
95 | ];\r | |
96 | \r | |
97 | var events = me.attachTo && me.attachTo.testEvents;\r | |
98 | me.items = [\r | |
99 | {\r | |
100 | xtype: 'textarea',\r | |
101 | itemId: 'eventView',\r | |
102 | fieldStyle: 'font-family: monospace',\r | |
103 | selectOnFocus: true,\r | |
104 | emptyText: 'Events go here!',\r | |
105 | value: events ? me.stringifyEvents(events) : '',\r | |
106 | scrollToBottom: function () {\r | |
107 | var inputEl = this.inputEl.dom;\r | |
108 | inputEl.scrollTop = inputEl.scrollHeight;\r | |
109 | }\r | |
110 | }\r | |
111 | ];\r | |
112 | me.fbar = [\r | |
113 | {\r | |
114 | xtype: 'tbtext',\r | |
115 | text: 'Attached To: ' + (me.attachTo && me.attachTo.location.href)\r | |
116 | }\r | |
117 | ];\r | |
118 | \r | |
119 | me.callParent();\r | |
120 | },\r | |
121 | \r | |
122 | makeRecordButtonMenu: function () {\r | |
123 | var ret = [],\r | |
124 | subs = {},\r | |
125 | eventsToRec = this.recorder.eventsToRecord,\r | |
126 | ignoredEvents = this.eventsToIgnore;\r | |
127 | \r | |
128 | Ext.Object.each(eventsToRec, function (name, value) {\r | |
129 | var sub = subs[value.kind];\r | |
130 | if (!sub) {\r | |
131 | subs[value.kind] = sub = [];\r | |
132 | ret.push({\r | |
133 | text: value.kind,\r | |
134 | menu: sub\r | |
135 | });\r | |
136 | }\r | |
137 | \r | |
138 | sub.push({\r | |
139 | text: name,\r | |
140 | checked: true,\r | |
141 | handler: function (menuItem) {\r | |
142 | if (menuItem.checked) {\r | |
143 | eventsToRec[name] = value;\r | |
144 | } else {\r | |
145 | delete eventsToRec[name];\r | |
146 | }\r | |
147 | }\r | |
148 | });\r | |
149 | \r | |
150 | if (ignoredEvents[name]) {\r | |
151 | sub[sub.length - 1].checked = false;\r | |
152 | Ext.Function.defer(function () {\r | |
153 | delete eventsToRec[name];\r | |
154 | }, 1);\r | |
155 | }\r | |
156 | });\r | |
157 | \r | |
158 | function less (lhs, rhs) {\r | |
159 | return (lhs.text < rhs.text) ? -1\r | |
160 | : ((rhs.text < lhs.text) ? 1 : 0);\r | |
161 | }\r | |
162 | \r | |
163 | ret.sort(less);\r | |
164 | Ext.Array.each(ret, function (sub) {\r | |
165 | sub.menu.sort(less);\r | |
166 | });\r | |
167 | \r | |
168 | return ret;\r | |
169 | },\r | |
170 | \r | |
171 | getEventView: function () {\r | |
172 | return this.down('#eventView');\r | |
173 | },\r | |
174 | \r | |
175 | onClear: function () {\r | |
176 | var view = this.getEventView();\r | |
177 | view.setValue('');\r | |
178 | },\r | |
179 | \r | |
180 | onPlay: function () {\r | |
181 | var me = this,\r | |
182 | view = me.getEventView(),\r | |
183 | events = view.getValue();\r | |
184 | \r | |
185 | if (events) {\r | |
186 | events = Ext.decode(events);\r | |
187 | if (events.length) {\r | |
188 | me.player = Ext.create('Ext.ux.event.Player', {\r | |
189 | attachTo: window.opener,\r | |
190 | eventQueue: events,\r | |
191 | speed: me.playSpeed,\r | |
192 | listeners: {\r | |
193 | stop: me.onPlayStop,\r | |
194 | scope: me\r | |
195 | }\r | |
196 | });\r | |
197 | \r | |
198 | me.player.start();\r | |
199 | me.syncBtnUI();\r | |
200 | }\r | |
201 | }\r | |
202 | },\r | |
203 | \r | |
204 | onPlayStop: function () {\r | |
205 | this.player = null;\r | |
206 | this.syncBtnUI();\r | |
207 | },\r | |
208 | \r | |
209 | onPlaySpeed: function (menuitem) {\r | |
210 | this.playSpeed = menuitem.speed;\r | |
211 | },\r | |
212 | \r | |
213 | onRecord: function () {\r | |
214 | this.recorder.start();\r | |
215 | this.syncBtnUI();\r | |
216 | },\r | |
217 | \r | |
218 | onStop: function () {\r | |
219 | var me = this;\r | |
220 | \r | |
221 | if (me.player) {\r | |
222 | me.player.stop();\r | |
223 | me.player = null;\r | |
224 | } else {\r | |
225 | me.recorder.stop();\r | |
226 | }\r | |
227 | me.syncBtnUI();\r | |
228 | me.updateEvents();\r | |
229 | },\r | |
230 | \r | |
231 | syncBtnUI: function () {\r | |
232 | var me = this,\r | |
233 | idle = !me.player && !me.recorder.active;\r | |
234 | \r | |
235 | Ext.each(me.query('[whenIdle]'), function (btn) {\r | |
236 | btn.setDisabled(!idle);\r | |
237 | });\r | |
238 | Ext.each(me.query('[whenActive]'), function (btn) {\r | |
239 | btn.setDisabled(idle);\r | |
240 | });\r | |
241 | \r | |
242 | var view = me.getEventView();\r | |
243 | view.setReadOnly(!idle);\r | |
244 | },\r | |
245 | \r | |
246 | stringifyEvents: function (events) {\r | |
247 | var line,\r | |
248 | lines = [];\r | |
249 | \r | |
250 | Ext.each(events, function (ev) {\r | |
251 | line = [];\r | |
252 | \r | |
253 | Ext.Object.each(ev, function (name, value) {\r | |
254 | if (line.length) {\r | |
255 | line.push(', ');\r | |
256 | } else {\r | |
257 | line.push(' { ');\r | |
258 | }\r | |
259 | line.push(name, ': ');\r | |
260 | line.push(Ext.encode(value));\r | |
261 | });\r | |
262 | \r | |
263 | line.push(' }');\r | |
264 | lines.push(line.join(''));\r | |
265 | });\r | |
266 | \r | |
267 | return '[\n' + lines.join(',\n') + '\n]';\r | |
268 | },\r | |
269 | \r | |
270 | updateEvents: function () {\r | |
271 | var me = this,\r | |
272 | text = me.stringifyEvents(me.recorder.getRecordedEvents()),\r | |
273 | view = me.getEventView();\r | |
274 | \r | |
275 | view.setValue(text);\r | |
276 | view.scrollToBottom();\r | |
277 | }\r | |
278 | });\r |