adminpanel 2.1.2 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/adminpanel.gemspec +20 -18
  3. data/app/assets/javascripts/adminpanel/jquery.knob.js +652 -0
  4. data/app/assets/javascripts/adminpanel/realm.js +20 -18
  5. data/app/assets/javascripts/adminpanel/spinner.js.coffee +3 -3
  6. data/app/controllers/adminpanel/analytics_controller.rb +99 -53
  7. data/app/controllers/adminpanel/auths_controller.rb +1 -1
  8. data/app/controllers/adminpanel/sessions_controller.rb +26 -26
  9. data/app/controllers/concerns/adminpanel/facebook_actions.rb +2 -2
  10. data/app/helpers/adminpanel/adminpanel_form_builder.rb +257 -298
  11. data/app/helpers/adminpanel/analytics_helper.rb +46 -0
  12. data/app/helpers/adminpanel/application_helper.rb +57 -57
  13. data/app/helpers/adminpanel/breadcrumbs_helper.rb +13 -13
  14. data/app/helpers/adminpanel/sessions_helper.rb +20 -20
  15. data/app/helpers/adminpanel/shared_pages_helper.rb +41 -41
  16. data/app/models/adminpanel/gallery.rb +65 -63
  17. data/app/models/adminpanel/image.rb +5 -5
  18. data/app/models/adminpanel/section.rb +61 -53
  19. data/app/models/adminpanel/user.rb +1 -6
  20. data/app/models/concerns/adminpanel/facebook.rb +1 -1
  21. data/app/uploaders/adminpanel/gallery_uploader.rb +1 -1
  22. data/app/views/adminpanel/analytics/_widget_task_statistics.html.erb +63 -0
  23. data/app/views/adminpanel/analytics/fb.html.erb +98 -0
  24. data/app/views/adminpanel/analytics/index.html.erb +8 -8
  25. data/app/views/adminpanel/galleries/_galleries_table.html.erb +12 -12
  26. data/app/views/adminpanel/galleries/move_better.js.erb +1 -1
  27. data/app/views/adminpanel/galleries/move_worst.js.erb +1 -1
  28. data/app/views/adminpanel/sections/_sections_table.html.erb +7 -7
  29. data/app/views/adminpanel/sections/show.html.erb +25 -25
  30. data/app/views/adminpanel/sessions/new.html.erb +22 -22
  31. data/app/views/layouts/_shim.html.erb +1 -1
  32. data/app/views/layouts/_side_menu.html.erb +35 -35
  33. data/app/views/layouts/admin-login.html.erb +22 -22
  34. data/app/views/layouts/admin.html.erb +35 -35
  35. data/app/views/shared/_breadcrumb.html.erb +4 -4
  36. data/app/views/shared/_error_messages.html.erb +15 -15
  37. data/app/views/shared/_form_fields.html.erb +48 -47
  38. data/app/views/shared/_image_fields.html.erb +1 -1
  39. data/config/initializers/pluralization_es.rb +1 -1
  40. data/config/locales/es.yml +38 -2
  41. data/config/routes.rb +5 -4
  42. data/lib/adminpanel/version.rb +1 -1
  43. data/lib/generators/adminpanel/gallery/templates/gallery_migration.rb +5 -5
  44. data/lib/generators/adminpanel/gallery/templates/uploader.rb +1 -1
  45. data/lib/generators/adminpanel/initialize/initialize_generator.rb +54 -54
  46. data/lib/generators/adminpanel/initialize/templates/category_template.rb +1 -1
  47. data/lib/generators/adminpanel/initialize/templates/create_adminpanel_categories_table.rb +5 -5
  48. data/lib/generators/adminpanel/initialize/templates/create_adminpanel_tables.rb +57 -57
  49. data/lib/generators/adminpanel/initialize/templates/section_uploader.rb +1 -1
  50. data/lib/generators/adminpanel/migration/migration_generator.rb +44 -0
  51. data/lib/generators/adminpanel/migration/migration_generator_helper.rb +19 -0
  52. data/lib/generators/adminpanel/resource/resource_generator.rb +60 -245
  53. data/lib/generators/adminpanel/resource/resource_generator_helper.rb +189 -0
  54. data/lib/generators/adminpanel/resource/templates/{controller.rb → adminpanel_controller_template.rb} +2 -2
  55. data/lib/generators/adminpanel/resource/templates/{resource.rb → adminpanel_resource_template.rb} +0 -0
  56. data/test/dummy/app/models/adminpanel/categorization.rb +2 -2
  57. data/test/dummy/app/models/adminpanel/category.rb +3 -3
  58. data/test/dummy/app/models/adminpanel/department.rb +2 -2
  59. data/test/dummy/app/models/adminpanel/item.rb +3 -3
  60. data/test/dummy/app/models/adminpanel/mug.rb +14 -14
  61. data/test/dummy/app/models/adminpanel/product.rb +19 -19
  62. data/test/dummy/app/models/adminpanel/salesman.rb +15 -15
  63. data/test/dummy/app/uploader/adminpanel/photo_uploader.rb +1 -1
  64. data/test/dummy/app/views/layouts/application.html.erb +9 -9
  65. data/test/dummy/config/boot.rb +1 -1
  66. data/test/features/shared/{belongs_to_category_modal_test.rb → form/belongs_to_category_modal_test.rb} +0 -0
  67. data/test/features/shared/{belongs_to_non_category_modal_test.rb → form/belongs_to_non_category_modal_test.rb} +0 -0
  68. data/test/features/shared/{has_many_through_category_modal_test.rb → form/has_many_through_category_modal_test.rb} +0 -0
  69. data/test/features/shared/{has_many_through_non_category_modal_test.rb → form/has_many_through_non_category_modal_test.rb} +0 -0
  70. data/test/features/shared/{edit_test.rb → resource/edit_test.rb} +0 -0
  71. data/test/features/shared/{index_test.rb → resource/index_test.rb} +0 -0
  72. data/test/features/shared/{new_test.rb → resource/new_test.rb} +0 -0
  73. data/test/features/shared/{show_test.rb → resource/show_test.rb} +0 -0
  74. data/test/features/shared/{action_exclution_test.rb → ui/action_exclution_test.rb} +0 -0
  75. data/test/test_helper.rb +1 -1
  76. metadata +44 -32
  77. data/test/dummy/app/controllers/adminpanel/.gitkeep +0 -0
  78. data/test/dummy/app/models/.gitkeep +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12212a53c9a9f2c010bfd19215a87d260a8fdf5c
4
- data.tar.gz: f2c4698f3c330934d03727b23e71d1d8a30a3f6a
3
+ metadata.gz: 2a62132c9e4fb208f8ba36a33c457128ed0a790e
4
+ data.tar.gz: 9a2b4ffc2fb96a36f51bf8d4925aa4e6ed34d272
5
5
  SHA512:
6
- metadata.gz: c9ff9e24e0b7ce8e63c86f0599dc576a93cd6b1526733bf21b5d50276d5622d37f2148737bf5b5fdaf7e8ea9f8b0a199e373f7c3c45e5e0b1aa4c5d8b8cf76e3
7
- data.tar.gz: d8a24e70bac9aeba5efe00103af7cc9708d31c0c9cfece3253d49a0129f4d4a76c8b8f744a5c9dd9ad0da8e83fb2d610cae2550439637061661bc5526b393e88
6
+ metadata.gz: b0a069de0a2f71e9a7741482eba89df1e66f4c1d0b0ab03a27560c1a74306dcb1ec3bdd213f5b056980a7856ca0ac498916a035f2a905851dedd626cc63ec0fb
7
+ data.tar.gz: 2280cbafd12000d5d8f16f57901140344c3119aa973aad0d2f7759856d16620bdcd6bf64d44d0b5b4a223696212687d52d6e4aa6b67e95812f862cb495e32f9f
data/adminpanel.gemspec CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |spec|
7
7
  spec.name = 'adminpanel'
8
8
  spec.version = Adminpanel::VERSION
9
9
  spec.authors = ['Jose Ramon Camacho', 'Victor Camacho']
10
- spec.email = ['joserracamacho@gmail.com']
11
- spec.description = %q{Gem that makes the administrative panel for a site a breeze!}
12
- spec.summary = %q{Developed with <3 by CoDN}
10
+ spec.email = ['info@codn.mx']
11
+ spec.description = %q{Gem that makes the CMS for a site a breeze!, supports facebook sharing and analytics integration}
12
+ spec.summary = %q{Made with <3 by CoDN}
13
13
  spec.homepage = 'https://github.com/joseramonc/adminpanel'
14
14
  spec.license = 'MIT'
15
15
 
@@ -20,21 +20,23 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.required_ruby_version = '>= 2.0.0'
22
22
 
23
- spec.add_dependency 'rails', '>= 4.0.0', '<= 4.1.1'
24
- spec.add_dependency 'carrierwave', '>= 0.10.0', '<= 1.0.0'
25
- spec.add_dependency 'rmagick', '2.13.2'
26
- spec.add_dependency 'jquery-rails', '>= 3.1.0', '<= 4.0.0'
27
- spec.add_dependency 'turbolinks', '>= 2.2.2', '<= 3.0.0'
28
- spec.add_dependency 'bcrypt', '>= 3.1.7', '<= 4.0.0'
29
- spec.add_dependency 'rails-i18n', '>= 4.0.2', '<= 4.1.0'
30
- spec.add_dependency 'inherited_resources', '>= 1.4.1', '<= 2.0.0'
31
- spec.add_dependency 'cancancan', '>= 1.7', '<= 2.0.0'
32
- spec.add_dependency 'google-api-client', '>= 0.7.1', '<= 1.0.0'
33
- spec.add_dependency 'faker', '>= 1.3.0', '<= 2.0.0'
34
- spec.add_dependency 'sass-rails', '>= 4.0.3', '<= 4.1.0'
35
- spec.add_dependency 'font-awesome-rails', '>= 4.0.3.1', '<= 4.1.0'
36
- spec.add_dependency 'koala', '>= 1.9.0', '<= 2.0.0'
37
- spec.add_dependency 'coffee-script'
23
+ spec.requirements << 'rmagick, v 2.13.2'
24
+
25
+ spec.add_runtime_dependency 'rails', '>= 4.0.0', '<= 4.1.1'
26
+ spec.add_runtime_dependency 'carrierwave', '>= 0.10.0', '<= 1.0.0'
27
+ spec.add_runtime_dependency 'rmagick', '2.13.2'
28
+ spec.add_runtime_dependency 'jquery-rails', '>= 3.1.0', '<= 4.0.0'
29
+ spec.add_runtime_dependency 'turbolinks', '>= 2.2.2', '<= 3.0.0'
30
+ spec.add_runtime_dependency 'bcrypt', '>= 3.1.7', '<= 4.0.0'
31
+ spec.add_runtime_dependency 'rails-i18n', '>= 4.0.2', '<= 4.1.0'
32
+ spec.add_runtime_dependency 'inherited_resources', '>= 1.4.1', '<= 2.0.0'
33
+ spec.add_runtime_dependency 'cancancan', '>= 1.7', '<= 2.0.0'
34
+ spec.add_runtime_dependency 'google-api-client', '>= 0.7.1', '<= 1.0.0'
35
+ spec.add_runtime_dependency 'faker', '>= 1.3.0', '<= 2.0.0'
36
+ spec.add_runtime_dependency 'sass-rails', '>= 4.0.3', '<= 4.1.0'
37
+ spec.add_runtime_dependency 'font-awesome-rails', '>= 4.0.3.1', '<= 4.1.0'
38
+ spec.add_runtime_dependency 'koala', '>= 1.9.0', '<= 2.0.0'
39
+ spec.add_runtime_dependency 'coffee-script', '>= 2.2.0', '<= 3.0.0'
38
40
 
39
41
  spec.add_development_dependency 'sqlite3', '>= 1.3.9', '<= 2.0.0'
40
42
  spec.add_development_dependency 'minitest', '>= 5.3.4', '<= 6.0.0'
@@ -0,0 +1,652 @@
1
+ /*!jQuery Knob*/
2
+ /**
3
+ * Downward compatible, touchable dial
4
+ *
5
+ * Version: 1.2.0 (15/07/2012)
6
+ * Requires: jQuery v1.7+
7
+ *
8
+ * Copyright (c) 2012 Anthony Terrien
9
+ * Under MIT and GPL licenses:
10
+ * http://www.opensource.org/licenses/mit-license.php
11
+ * http://www.gnu.org/licenses/gpl.html
12
+ *
13
+ * Thanks to vor, eskimoblood, spiffistan, FabrizioC
14
+ */
15
+ (function($) {
16
+
17
+ /**
18
+ * Kontrol library
19
+ */
20
+ "use strict";
21
+
22
+ /**
23
+ * Definition of globals and core
24
+ */
25
+ var k = {}, // kontrol
26
+ max = Math.max,
27
+ min = Math.min;
28
+
29
+ k.c = {};
30
+ k.c.d = $(document);
31
+ k.c.t = function (e) {
32
+ return e.originalEvent.touches.length - 1;
33
+ };
34
+
35
+ /**
36
+ * Kontrol Object
37
+ *
38
+ * Definition of an abstract UI control
39
+ *
40
+ * Each concrete component must call this one.
41
+ * <code>
42
+ * k.o.call(this);
43
+ * </code>
44
+ */
45
+ k.o = function () {
46
+ var s = this;
47
+
48
+ this.o = null; // array of options
49
+ this.$ = null; // jQuery wrapped element
50
+ this.i = null; // mixed HTMLInputElement or array of HTMLInputElement
51
+ this.g = null; // 2D graphics context for 'pre-rendering'
52
+ this.v = null; // value ; mixed array or integer
53
+ this.cv = null; // change value ; not commited value
54
+ this.x = 0; // canvas x position
55
+ this.y = 0; // canvas y position
56
+ this.$c = null; // jQuery canvas element
57
+ this.c = null; // rendered canvas context
58
+ this.t = 0; // touches index
59
+ this.isInit = false;
60
+ this.fgColor = null; // main color
61
+ this.pColor = null; // previous color
62
+ this.dH = null; // draw hook
63
+ this.cH = null; // change hook
64
+ this.eH = null; // cancel hook
65
+ this.rH = null; // release hook
66
+
67
+ this.run = function () {
68
+ var cf = function (e, conf) {
69
+ var k;
70
+ for (k in conf) {
71
+ s.o[k] = conf[k];
72
+ }
73
+ s.init();
74
+ s._configure()
75
+ ._draw();
76
+ };
77
+
78
+ if(this.$.data('kontroled')) return;
79
+ this.$.data('kontroled', true);
80
+
81
+ this.extend();
82
+ this.o = $.extend(
83
+ {
84
+ // Config
85
+ min : this.$.data('min') || 0,
86
+ max : this.$.data('max') || 100,
87
+ stopper : true,
88
+ readOnly : this.$.data('readonly'),
89
+
90
+ // UI
91
+ cursor : (this.$.data('cursor') === true && 30)
92
+ || this.$.data('cursor')
93
+ || 0,
94
+ thickness : this.$.data('thickness') || 0.35,
95
+ width : this.$.data('width') || 200,
96
+ height : this.$.data('height') || 200,
97
+ displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'),
98
+ displayPrevious : this.$.data('displayprevious'),
99
+ fgColor : this.$.data('fgcolor') || '#87CEEB',
100
+ inline : false,
101
+
102
+ // Hooks
103
+ draw : null, // function () {}
104
+ change : null, // function (value) {}
105
+ cancel : null, // function () {}
106
+ release : null // function (value) {}
107
+ }, this.o
108
+ );
109
+
110
+ // routing value
111
+ if(this.$.is('fieldset')) {
112
+
113
+ // fieldset = array of integer
114
+ this.v = {};
115
+ this.i = this.$.find('input')
116
+ this.i.each(function(k) {
117
+ var $this = $(this);
118
+ s.i[k] = $this;
119
+ s.v[k] = $this.val();
120
+
121
+ $this.bind(
122
+ 'change'
123
+ , function () {
124
+ var val = {};
125
+ val[k] = $this.val();
126
+ s.val(val);
127
+ }
128
+ );
129
+ });
130
+ this.$.find('legend').remove();
131
+
132
+ } else {
133
+ // input = integer
134
+ this.i = this.$;
135
+ this.v = this.$.val();
136
+ (this.v == '') && (this.v = this.o.min);
137
+
138
+ this.$.bind(
139
+ 'change'
140
+ , function () {
141
+ s.val(s.$.val());
142
+ }
143
+ );
144
+ }
145
+
146
+ (!this.o.displayInput) && this.$.hide();
147
+
148
+ this.$c = $('<canvas width="' +
149
+ this.o.width + 'px" height="' +
150
+ this.o.height + 'px"></canvas>');
151
+ this.c = this.$c[0].getContext("2d");
152
+
153
+ this.$
154
+ .wrap($('<div style="' + (this.o.inline ? 'display:inline;' : '') +
155
+ 'width:' + this.o.width + 'px;height:' +
156
+ this.o.height + 'px;"></div>'))
157
+ .before(this.$c);
158
+
159
+ if (this.v instanceof Object) {
160
+ this.cv = {};
161
+ this.copy(this.v, this.cv);
162
+ } else {
163
+ this.cv = this.v;
164
+ }
165
+
166
+ this.$
167
+ .bind("configure", cf)
168
+ .parent()
169
+ .bind("configure", cf);
170
+
171
+ this._listen()
172
+ ._configure()
173
+ ._xy()
174
+ .init();
175
+
176
+ this.isInit = true;
177
+
178
+ this._draw();
179
+
180
+ return this;
181
+ };
182
+
183
+ this._draw = function () {
184
+
185
+ // canvas pre-rendering
186
+ var d = true,
187
+ c = document.createElement('canvas');
188
+
189
+ c.width = s.o.width;
190
+ c.height = s.o.height;
191
+ s.g = c.getContext('2d');
192
+
193
+ s.clear();
194
+
195
+ s.dH
196
+ && (d = s.dH());
197
+
198
+ (d !== false) && s.draw();
199
+
200
+ s.c.drawImage(c, 0, 0);
201
+ c = null;
202
+ };
203
+
204
+ this._touch = function (e) {
205
+
206
+ var touchMove = function (e) {
207
+
208
+ var v = s.xy2val(
209
+ e.originalEvent.touches[s.t].pageX,
210
+ e.originalEvent.touches[s.t].pageY
211
+ );
212
+
213
+ if (v == s.cv) return;
214
+
215
+ if (
216
+ s.cH
217
+ && (s.cH(v) === false)
218
+ ) return;
219
+
220
+
221
+ s.change(v);
222
+ s._draw();
223
+ };
224
+
225
+ // get touches index
226
+ this.t = k.c.t(e);
227
+
228
+ // First touch
229
+ touchMove(e);
230
+
231
+ // Touch events listeners
232
+ k.c.d
233
+ .bind("touchmove.k", touchMove)
234
+ .bind(
235
+ "touchend.k"
236
+ , function () {
237
+ k.c.d.unbind('touchmove.k touchend.k');
238
+
239
+ if (
240
+ s.rH
241
+ && (s.rH(s.cv) === false)
242
+ ) return;
243
+
244
+ s.val(s.cv);
245
+ }
246
+ );
247
+
248
+ return this;
249
+ };
250
+
251
+ this._mouse = function (e) {
252
+
253
+ var mouseMove = function (e) {
254
+ var v = s.xy2val(e.pageX, e.pageY);
255
+ if (v == s.cv) return;
256
+
257
+ if (
258
+ s.cH
259
+ && (s.cH(v) === false)
260
+ ) return;
261
+
262
+ s.change(v);
263
+ s._draw();
264
+ };
265
+
266
+ // First click
267
+ mouseMove(e);
268
+
269
+ // Mouse events listeners
270
+ k.c.d
271
+ .bind("mousemove.k", mouseMove)
272
+ .bind(
273
+ // Escape key cancel current change
274
+ "keyup.k"
275
+ , function (e) {
276
+ if (e.keyCode === 27) {
277
+ k.c.d.unbind("mouseup.k mousemove.k keyup.k");
278
+
279
+ if (
280
+ s.eH
281
+ && (s.eH() === false)
282
+ ) return;
283
+
284
+ s.cancel();
285
+ }
286
+ }
287
+ )
288
+ .bind(
289
+ "mouseup.k"
290
+ , function (e) {
291
+ k.c.d.unbind('mousemove.k mouseup.k keyup.k');
292
+
293
+ if (
294
+ s.rH
295
+ && (s.rH(s.cv) === false)
296
+ ) return;
297
+
298
+ s.val(s.cv);
299
+ }
300
+ );
301
+
302
+ return this;
303
+ };
304
+
305
+ this._xy = function () {
306
+ var o = this.$c.offset();
307
+ this.x = o.left;
308
+ this.y = o.top;
309
+ return this;
310
+ };
311
+
312
+ this._listen = function () {
313
+
314
+ if (!this.o.readOnly) {
315
+ this.$c
316
+ .bind(
317
+ "mousedown"
318
+ , function (e) {
319
+ e.preventDefault();
320
+ s._xy()._mouse(e);
321
+ }
322
+ )
323
+ .bind(
324
+ "touchstart"
325
+ , function (e) {
326
+ e.preventDefault();
327
+ s._xy()._touch(e);
328
+ }
329
+ );
330
+ this.listen();
331
+ } else {
332
+ this.$.attr('readonly', 'readonly');
333
+ }
334
+
335
+ return this;
336
+ };
337
+
338
+ this._configure = function () {
339
+
340
+ // Hooks
341
+ if (this.o.draw) this.dH = this.o.draw;
342
+ if (this.o.change) this.cH = this.o.change;
343
+ if (this.o.cancel) this.eH = this.o.cancel;
344
+ if (this.o.release) this.rH = this.o.release;
345
+
346
+ if (this.o.displayPrevious) {
347
+ this.pColor = this.h2rgba(this.o.fgColor, "0.4");
348
+ this.fgColor = this.h2rgba(this.o.fgColor, "0.6");
349
+ } else {
350
+ this.fgColor = this.o.fgColor;
351
+ }
352
+
353
+ return this;
354
+ };
355
+
356
+ this._clear = function () {
357
+ this.$c[0].width = this.$c[0].width;
358
+ };
359
+
360
+ // Abstract methods
361
+ this.listen = function () {}; // on start, one time
362
+ this.extend = function () {}; // each time configure triggered
363
+ this.init = function () {}; // each time configure triggered
364
+ this.change = function (v) {}; // on change
365
+ this.val = function (v) {}; // on release
366
+ this.xy2val = function (x, y) {}; //
367
+ this.draw = function () {}; // on change / on release
368
+ this.clear = function () { this._clear(); };
369
+
370
+ // Utils
371
+ this.h2rgba = function (h, a) {
372
+ var rgb;
373
+ h = h.substring(1,7)
374
+ rgb = [parseInt(h.substring(0,2),16)
375
+ ,parseInt(h.substring(2,4),16)
376
+ ,parseInt(h.substring(4,6),16)];
377
+ return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")";
378
+ };
379
+
380
+ this.copy = function (f, t) {
381
+ for (var i in f) { t[i] = f[i]; }
382
+ };
383
+ };
384
+
385
+
386
+ /**
387
+ * k.Dial
388
+ */
389
+ k.Dial = function () {
390
+ k.o.call(this);
391
+
392
+ this.startAngle = null;
393
+ this.xy = null;
394
+ this.radius = null;
395
+ this.lineWidth = null;
396
+ this.cursorExt = null;
397
+ this.w2 = null;
398
+ this.PI2 = 2*Math.PI;
399
+
400
+ this.extend = function () {
401
+ this.o = $.extend(
402
+ {
403
+ bgColor : this.$.data('bgcolor') || '#EEEEEE',
404
+ angleOffset : this.$.data('angleoffset') || 0,
405
+ angleArc : this.$.data('anglearc') || 360,
406
+ inline : true
407
+ }, this.o
408
+ );
409
+ };
410
+
411
+ this.val = function (v) {
412
+ if (null != v) {
413
+ this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;
414
+ this.v = this.cv;
415
+ this.$.val(this.v);
416
+ this._draw();
417
+ } else {
418
+ return this.v;
419
+ }
420
+ };
421
+
422
+ this.xy2val = function (x, y) {
423
+ var a, ret;
424
+
425
+ a = Math.atan2(
426
+ x - (this.x + this.w2)
427
+ , - (y - this.y - this.w2)
428
+ ) - this.angleOffset;
429
+
430
+ if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {
431
+ // if isset angleArc option, set to min if .5 under min
432
+ a = 0;
433
+ } else if (a < 0) {
434
+ a += this.PI2;
435
+ }
436
+
437
+ ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc))
438
+ + this.o.min;
439
+
440
+ this.o.stopper
441
+ && (ret = max(min(ret, this.o.max), this.o.min));
442
+
443
+ return ret;
444
+ };
445
+
446
+ this.listen = function () {
447
+ // bind MouseWheel
448
+ var s = this,
449
+ mw = function (e) {
450
+ e.preventDefault();
451
+
452
+ var ori = e.originalEvent
453
+ ,deltaX = ori.detail || ori.wheelDeltaX
454
+ ,deltaY = ori.detail || ori.wheelDeltaY
455
+ ,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? 1 : deltaX<0 || deltaY<0 ? -1 : 0);
456
+
457
+ if (
458
+ s.cH
459
+ && (s.cH(v) === false)
460
+ ) return;
461
+
462
+ s.val(v);
463
+ }
464
+ , kval, to, m = 1, kv = {37:-1, 38:1, 39:1, 40:-1};
465
+
466
+ this.$
467
+ .bind(
468
+ "keydown"
469
+ ,function (e) {
470
+ var kc = e.keyCode;
471
+
472
+ // numpad support
473
+ if(kc >= 96 && kc <= 105) {
474
+ kc = e.keyCode = kc - 48;
475
+ }
476
+
477
+ kval = parseInt(String.fromCharCode(kc));
478
+
479
+ if (isNaN(kval)) {
480
+
481
+ (kc !== 13) // enter
482
+ && (kc !== 8) // bs
483
+ && (kc !== 9) // tab
484
+ && (kc !== 189) // -
485
+ && e.preventDefault();
486
+
487
+ // arrows
488
+ if ($.inArray(kc,[37,38,39,40]) > -1) {
489
+ e.preventDefault();
490
+
491
+ var v = parseInt(s.$.val()) + kv[kc] * m;
492
+
493
+ s.o.stopper
494
+ && (v = max(min(v, s.o.max), s.o.min));
495
+
496
+ s.change(v);
497
+ s._draw();
498
+
499
+ // long time keydown speed-up
500
+ to = window.setTimeout(
501
+ function () { m*=2; }
502
+ ,30
503
+ );
504
+ }
505
+ }
506
+ }
507
+ )
508
+ .bind(
509
+ "keyup"
510
+ ,function (e) {
511
+ if (isNaN(kval)) {
512
+ if (to) {
513
+ window.clearTimeout(to);
514
+ to = null;
515
+ m = 1;
516
+ s.val(s.$.val());
517
+ }
518
+ } else {
519
+ // kval postcond
520
+ (s.$.val() > s.o.max && s.$.val(s.o.max))
521
+ || (s.$.val() < s.o.min && s.$.val(s.o.min));
522
+ }
523
+
524
+ }
525
+ );
526
+
527
+ this.$c.bind("mousewheel DOMMouseScroll", mw);
528
+ this.$.bind("mousewheel DOMMouseScroll", mw)
529
+ };
530
+
531
+ this.init = function () {
532
+
533
+ if (
534
+ this.v < this.o.min
535
+ || this.v > this.o.max
536
+ ) this.v = this.o.min;
537
+
538
+ this.$.val(this.v);
539
+ this.w2 = this.o.width / 2;
540
+ this.cursorExt = this.o.cursor / 100;
541
+ this.xy = this.w2;
542
+ this.lineWidth = this.xy * this.o.thickness;
543
+ this.radius = this.xy - this.lineWidth / 2;
544
+
545
+ this.o.angleOffset
546
+ && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);
547
+
548
+ this.o.angleArc
549
+ && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);
550
+
551
+ // deg to rad
552
+ this.angleOffset = this.o.angleOffset * Math.PI / 180;
553
+ this.angleArc = this.o.angleArc * Math.PI / 180;
554
+
555
+ // compute start and end angles
556
+ this.startAngle = 1.5 * Math.PI + this.angleOffset;
557
+ this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;
558
+
559
+ var s = max(
560
+ String(Math.abs(this.o.max)).length
561
+ , String(Math.abs(this.o.min)).length
562
+ , 2
563
+ ) + 2;
564
+
565
+ this.o.displayInput
566
+ && this.i.css({
567
+ 'width' : ((this.o.width / 2 + 4) >> 0) + 'px'
568
+ ,'height' : ((this.o.width / 3) >> 0) + 'px'
569
+ ,'position' : 'absolute'
570
+ ,'vertical-align' : 'middle'
571
+ ,'margin-top' : ((this.o.width / 3) >> 0) + 'px'
572
+ ,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px'
573
+ ,'border' : 0
574
+ ,'background' : 'none'
575
+ ,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial'
576
+ ,'text-align' : 'center'
577
+ ,'color' : this.o.fgColor
578
+ ,'padding' : '0px'
579
+ ,'-webkit-appearance': 'none'
580
+ })
581
+ || this.i.css({
582
+ 'width' : '0px'
583
+ ,'visibility' : 'hidden'
584
+ });
585
+ };
586
+
587
+ this.change = function (v) {
588
+ this.cv = v;
589
+ this.$.val(v);
590
+ };
591
+
592
+ this.angle = function (v) {
593
+ return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);
594
+ };
595
+
596
+ this.draw = function () {
597
+
598
+ var c = this.g, // context
599
+ a = this.angle(this.cv) // Angle
600
+ , sat = this.startAngle // Start angle
601
+ , eat = sat + a // End angle
602
+ , sa, ea // Previous angles
603
+ , r = 1;
604
+
605
+ c.lineWidth = this.lineWidth;
606
+
607
+ this.o.cursor
608
+ && (sat = eat - this.cursorExt)
609
+ && (eat = eat + this.cursorExt);
610
+
611
+ c.beginPath();
612
+ c.strokeStyle = this.o.bgColor;
613
+ c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true);
614
+ c.stroke();
615
+
616
+ if (this.o.displayPrevious) {
617
+ ea = this.startAngle + this.angle(this.v);
618
+ sa = this.startAngle;
619
+ this.o.cursor
620
+ && (sa = ea - this.cursorExt)
621
+ && (ea = ea + this.cursorExt);
622
+
623
+ c.beginPath();
624
+ c.strokeStyle = this.pColor;
625
+ c.arc(this.xy, this.xy, this.radius, sa, ea, false);
626
+ c.stroke();
627
+ r = (this.cv == this.v);
628
+ }
629
+
630
+ c.beginPath();
631
+ c.strokeStyle = r ? this.o.fgColor : this.fgColor ;
632
+ c.arc(this.xy, this.xy, this.radius, sat, eat, false);
633
+ c.stroke();
634
+ };
635
+
636
+ this.cancel = function () {
637
+ this.val(this.v);
638
+ };
639
+ };
640
+
641
+ $.fn.dial = $.fn.knob = function (o) {
642
+ return this.each(
643
+ function () {
644
+ var d = new k.Dial();
645
+ d.o = o;
646
+ d.$ = $(this);
647
+ d.run();
648
+ }
649
+ ).parent();
650
+ };
651
+
652
+ })(jQuery);