dashing 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/bin/dashing +34 -11
- data/javascripts/batman.jquery.js +4 -2
- data/javascripts/batman.js +2322 -1009
- data/lib/dashing.rb +3 -2
- data/templates/project/.gitignore +1 -0
- data/templates/project/Gemfile +1 -1
- data/templates/project/assets/javascripts/gridster/jquery.gridster.js +530 -157
- data/templates/project/dashboards/layout.erb +1 -1
- data/templates/project/widgets/number/number.html +1 -1
- data/templates/project/widgets/number/number.scss +2 -2
- data/templates/widget/%name%/%name%.scss.tt +1 -1
- metadata +26 -46
data/lib/dashing.rb
CHANGED
@@ -32,6 +32,7 @@ end
|
|
32
32
|
|
33
33
|
get '/events', provides: 'text/event-stream' do
|
34
34
|
protected!
|
35
|
+
response.headers['X-Accel-Buffering'] = 'no' # Disable buffering for nginx
|
35
36
|
stream :keep_open do |out|
|
36
37
|
settings.connections << out
|
37
38
|
out << latest_events
|
@@ -91,8 +92,8 @@ def send_event(id, body)
|
|
91
92
|
body[:id] = id
|
92
93
|
body[:updatedAt] ||= Time.now.to_i
|
93
94
|
event = format_event(body.to_json)
|
94
|
-
settings.history[id] = event
|
95
|
-
settings.connections.each { |out| out << event }
|
95
|
+
Sinatra::Application.settings.history[id] = event
|
96
|
+
Sinatra::Application.settings.connections.each { |out| out << event }
|
96
97
|
end
|
97
98
|
|
98
99
|
def format_event(body)
|
@@ -0,0 +1 @@
|
|
1
|
+
*DS_STORE
|
data/templates/project/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/*! gridster.js - v0.1.0 -
|
1
|
+
/*! gridster.js - v0.1.0 - 2013-02-15
|
2
2
|
* http://gridster.net/
|
3
|
-
* Copyright (c)
|
3
|
+
* Copyright (c) 2013 ducksboard; Licensed MIT */
|
4
4
|
|
5
5
|
;(function($, window, document, undefined){
|
6
6
|
/**
|
@@ -285,12 +285,8 @@
|
|
285
285
|
|
286
286
|
fn.get_closest_colliders = function(player_data_coords){
|
287
287
|
var colliders = this.find_collisions(player_data_coords);
|
288
|
-
var min_area = 100;
|
289
|
-
colliders.sort(function(a, b){
|
290
|
-
if (a.area <= min_area) {
|
291
|
-
return 1;
|
292
|
-
}
|
293
288
|
|
289
|
+
colliders.sort(function(a, b) {
|
294
290
|
/* if colliders are being overlapped by the "C" (center) region,
|
295
291
|
* we have to set a lower index in the array to which they are placed
|
296
292
|
* above in the grid. */
|
@@ -302,7 +298,7 @@
|
|
302
298
|
}
|
303
299
|
}
|
304
300
|
|
305
|
-
if (a.area < b.area){
|
301
|
+
if (a.area < b.area) {
|
306
302
|
return 1;
|
307
303
|
}
|
308
304
|
|
@@ -369,8 +365,10 @@
|
|
369
365
|
distance: 1,
|
370
366
|
limit: true,
|
371
367
|
offset_left: 0,
|
372
|
-
autoscroll: true
|
373
|
-
|
368
|
+
autoscroll: true,
|
369
|
+
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'],
|
370
|
+
handle: null
|
371
|
+
// drag: function(e){},
|
374
372
|
// start : function(e, ui){},
|
375
373
|
// stop : function(e){}
|
376
374
|
};
|
@@ -424,12 +422,30 @@
|
|
424
422
|
fn.init = function() {
|
425
423
|
this.calculate_positions();
|
426
424
|
this.$container.css('position', 'relative');
|
427
|
-
this.
|
425
|
+
this.disabled = false;
|
426
|
+
this.events();
|
428
427
|
|
429
|
-
|
430
|
-
|
428
|
+
this.on_window_resize = throttle($.proxy(this.calculate_positions, this), 200);
|
429
|
+
$(window).bind('resize', this.on_window_resize);
|
431
430
|
};
|
432
431
|
|
432
|
+
fn.events = function() {
|
433
|
+
this.proxied_on_select_start = $.proxy(this.on_select_start, this);
|
434
|
+
this.$container.on('selectstart', this.proxied_on_select_start);
|
435
|
+
|
436
|
+
this.proxied_drag_handler = $.proxy(this.drag_handler, this);
|
437
|
+
this.$container.on(pointer_events.start, this.options.items, this.proxied_drag_handler);
|
438
|
+
|
439
|
+
this.proxied_pointer_events_end = $.proxy(function(e) {
|
440
|
+
this.is_dragging = false;
|
441
|
+
if (this.disabled) { return; }
|
442
|
+
this.$body.off(pointer_events.move);
|
443
|
+
if (this.drag_start) {
|
444
|
+
this.on_dragstop(e);
|
445
|
+
}
|
446
|
+
}, this);
|
447
|
+
this.$body.on(pointer_events.end, this.proxied_pointer_events_end);
|
448
|
+
};
|
433
449
|
|
434
450
|
fn.get_actual_pos = function($el) {
|
435
451
|
var pos = $el.position();
|
@@ -441,7 +457,7 @@
|
|
441
457
|
if (isTouch) {
|
442
458
|
var oe = e.originalEvent;
|
443
459
|
e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0];
|
444
|
-
}
|
460
|
+
}
|
445
461
|
|
446
462
|
return {
|
447
463
|
left: e.clientX,
|
@@ -500,7 +516,7 @@
|
|
500
516
|
$window.scrollTop(nextScrollTop);
|
501
517
|
this.scrollOffset = this.scrollOffset + 30;
|
502
518
|
}
|
503
|
-
}
|
519
|
+
}
|
504
520
|
|
505
521
|
if (abs_mouse_top <= mouse_up_zone) {
|
506
522
|
nextScrollTop = scrollTop - 30;
|
@@ -508,26 +524,24 @@
|
|
508
524
|
$window.scrollTop(nextScrollTop);
|
509
525
|
this.scrollOffset = this.scrollOffset - 30;
|
510
526
|
}
|
511
|
-
}
|
512
|
-
}
|
527
|
+
}
|
528
|
+
};
|
513
529
|
|
514
530
|
|
515
531
|
fn.calculate_positions = function(e) {
|
516
532
|
this.window_height = $window.height();
|
517
|
-
}
|
533
|
+
};
|
518
534
|
|
519
535
|
|
520
536
|
fn.drag_handler = function(e) {
|
521
537
|
var node = e.target.nodeName;
|
522
|
-
|
523
|
-
if (e.which !== 1 && !isTouch) {
|
538
|
+
if (this.disabled || e.which !== 1 && !isTouch) {
|
524
539
|
return;
|
525
540
|
}
|
526
541
|
|
527
|
-
if (
|
528
|
-
node === 'BUTTON') {
|
542
|
+
if (this.ignore_drag(e)) {
|
529
543
|
return;
|
530
|
-
}
|
544
|
+
}
|
531
545
|
|
532
546
|
var self = this;
|
533
547
|
var first = true;
|
@@ -537,7 +551,7 @@
|
|
537
551
|
this.mouse_init_pos = this.get_mouse_pos(e);
|
538
552
|
this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top;
|
539
553
|
|
540
|
-
this
|
554
|
+
this.on_pointer_events_move = function(mme){
|
541
555
|
var mouse_actual_pos = self.get_mouse_pos(mme);
|
542
556
|
var diff_x = Math.abs(
|
543
557
|
mouse_actual_pos.left - self.mouse_init_pos.left);
|
@@ -545,7 +559,7 @@
|
|
545
559
|
mouse_actual_pos.top - self.mouse_init_pos.top);
|
546
560
|
if (!(diff_x > self.options.distance ||
|
547
561
|
diff_y > self.options.distance)
|
548
|
-
|
562
|
+
) {
|
549
563
|
return false;
|
550
564
|
}
|
551
565
|
|
@@ -555,12 +569,14 @@
|
|
555
569
|
return false;
|
556
570
|
}
|
557
571
|
|
558
|
-
if (self.is_dragging
|
572
|
+
if (self.is_dragging === true) {
|
559
573
|
self.on_dragmove.call(self, mme);
|
560
574
|
}
|
561
575
|
|
562
576
|
return false;
|
563
|
-
}
|
577
|
+
};
|
578
|
+
|
579
|
+
this.$body.on(pointer_events.move, this.on_pointer_events_move);
|
564
580
|
|
565
581
|
return false;
|
566
582
|
};
|
@@ -646,38 +662,43 @@
|
|
646
662
|
};
|
647
663
|
|
648
664
|
fn.on_select_start = function(e) {
|
649
|
-
return
|
650
|
-
}
|
665
|
+
if (this.disabled) { return; }
|
651
666
|
|
667
|
+
if (this.ignore_drag(e)) {
|
668
|
+
return;
|
669
|
+
}
|
652
670
|
|
653
|
-
|
654
|
-
this.$container.on('selectstart', this.on_select_start);
|
655
|
-
|
656
|
-
this.$container.on(pointer_events.start, this.options.items, $.proxy(
|
657
|
-
this.drag_handler, this));
|
658
|
-
|
659
|
-
this.$body.on(pointer_events.end, $.proxy(function(e) {
|
660
|
-
this.is_dragging = false;
|
661
|
-
this.$body.off(pointer_events.move);
|
662
|
-
if (this.drag_start) {
|
663
|
-
this.on_dragstop(e);
|
664
|
-
}
|
665
|
-
}, this));
|
671
|
+
return false;
|
666
672
|
};
|
667
673
|
|
674
|
+
fn.enable = function() {
|
675
|
+
this.disabled = false;
|
676
|
+
};
|
668
677
|
|
669
|
-
fn.disable = function(){
|
670
|
-
this
|
671
|
-
this.$body.off(pointer_events.end);
|
672
|
-
this.$container.off('selectstart', this.on_select_start);
|
678
|
+
fn.disable = function() {
|
679
|
+
this.disabled = true;
|
673
680
|
};
|
674
681
|
|
675
682
|
|
676
683
|
fn.destroy = function(){
|
677
684
|
this.disable();
|
685
|
+
|
686
|
+
this.$container.off('selectstart', this.proxied_on_select_start);
|
687
|
+
this.$container.off(pointer_events.start, this.proxied_drag_handler);
|
688
|
+
this.$body.off(pointer_events.end, this.proxied_pointer_events_end);
|
689
|
+
this.$body.off(pointer_events.move, this.on_pointer_events_move);
|
690
|
+
$(window).unbind('resize', this.on_window_resize);
|
691
|
+
|
678
692
|
$.removeData(this.$container, 'drag');
|
679
693
|
};
|
680
694
|
|
695
|
+
fn.ignore_drag = function(event) {
|
696
|
+
if (this.options.handle) {
|
697
|
+
return !$(event.target).is(this.options.handle);
|
698
|
+
}
|
699
|
+
|
700
|
+
return $.inArray(event.target.nodeName, this.options.ignore_dragging) >= 0;
|
701
|
+
};
|
681
702
|
|
682
703
|
//jQuery adapter
|
683
704
|
$.fn.drag = function ( options ) {
|
@@ -694,7 +715,8 @@
|
|
694
715
|
;(function($, window, document, undefined) {
|
695
716
|
|
696
717
|
var defaults = {
|
697
|
-
|
718
|
+
namespace: '',
|
719
|
+
widget_selector: 'li',
|
698
720
|
widget_margins: [10, 10],
|
699
721
|
widget_base_dimensions: [400, 225],
|
700
722
|
extra_rows: 0,
|
@@ -702,13 +724,14 @@
|
|
702
724
|
min_cols: 1,
|
703
725
|
min_rows: 15,
|
704
726
|
max_size_x: 6,
|
705
|
-
max_size_y: 6,
|
706
727
|
autogenerate_stylesheet: true,
|
707
728
|
avoid_overlapped_widgets: true,
|
708
729
|
serialize_params: function($w, wgd) {
|
709
730
|
return {
|
710
731
|
col: wgd.col,
|
711
|
-
row: wgd.row
|
732
|
+
row: wgd.row,
|
733
|
+
size_x: wgd.size_x,
|
734
|
+
size_y: wgd.size_y
|
712
735
|
};
|
713
736
|
},
|
714
737
|
collision: {},
|
@@ -742,8 +765,6 @@
|
|
742
765
|
* @param {Number} [options.min_rows] The minimum required rows.
|
743
766
|
* @param {Number} [options.max_size_x] The maximum number of columns
|
744
767
|
* that a widget can span.
|
745
|
-
* @param {Number} [options.max_size_y] The maximum number of rows
|
746
|
-
* that a widget can span.
|
747
768
|
* @param {Boolean} [options.autogenerate_stylesheet] If true, all the
|
748
769
|
* CSS required to position all widgets in their respective columns
|
749
770
|
* and rows will be generated automatically and injected to the
|
@@ -770,7 +791,7 @@
|
|
770
791
|
this.options = $.extend(true, defaults, options);
|
771
792
|
this.$el = $(el);
|
772
793
|
this.$wrapper = this.$el.parent();
|
773
|
-
this.$widgets =
|
794
|
+
this.$widgets = this.$el.children(this.options.widget_selector).addClass('gs_w');
|
774
795
|
this.widgets = [];
|
775
796
|
this.$changed = $([]);
|
776
797
|
this.wrapper_width = this.$wrapper.width();
|
@@ -786,14 +807,15 @@
|
|
786
807
|
var fn = Gridster.prototype;
|
787
808
|
|
788
809
|
fn.init = function() {
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
810
|
+
this.generate_grid_and_stylesheet();
|
811
|
+
this.get_widgets_from_DOM();
|
812
|
+
this.set_dom_grid_height();
|
813
|
+
this.$wrapper.addClass('ready');
|
814
|
+
this.draggable();
|
815
|
+
|
816
|
+
this.on_window_resize = throttle($.proxy(this.recalculate_faux_grid, this), 200);
|
794
817
|
|
795
|
-
|
796
|
-
'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200));
|
818
|
+
$(window).bind('resize', this.on_window_resize);
|
797
819
|
};
|
798
820
|
|
799
821
|
|
@@ -826,32 +848,251 @@
|
|
826
848
|
* Add a new widget to the grid.
|
827
849
|
*
|
828
850
|
* @method add_widget
|
829
|
-
* @param {String} html The string representing the HTML of the widget
|
830
|
-
*
|
831
|
-
* @param {Number}
|
851
|
+
* @param {String|HTMLElement} html The string representing the HTML of the widget
|
852
|
+
* or the HTMLElement.
|
853
|
+
* @param {Number} [size_x] The nº of rows the widget occupies horizontally.
|
854
|
+
* @param {Number} [size_y] The nº of columns the widget occupies vertically.
|
855
|
+
* @param {Number} [col] The column the widget should start in.
|
856
|
+
* @param {Number} [row] The row the widget should start in.
|
832
857
|
* @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing.
|
833
858
|
* the widget that was just created.
|
834
859
|
*/
|
835
|
-
fn.add_widget = function(html, size_x, size_y) {
|
836
|
-
var
|
860
|
+
fn.add_widget = function(html, size_x, size_y, col, row) {
|
861
|
+
var pos;
|
862
|
+
size_x || (size_x = 1);
|
863
|
+
size_y || (size_y = 1);
|
864
|
+
|
865
|
+
if (!col & !row) {
|
866
|
+
pos = this.next_position(size_x, size_y);
|
867
|
+
}else{
|
868
|
+
pos = {
|
869
|
+
col: col,
|
870
|
+
row: row
|
871
|
+
};
|
872
|
+
|
873
|
+
this.empty_cells(col, row, size_x, size_y);
|
874
|
+
}
|
837
875
|
|
838
876
|
var $w = $(html).attr({
|
839
|
-
'data-col':
|
840
|
-
'data-row':
|
841
|
-
'data-sizex' :
|
842
|
-
'data-sizey' :
|
877
|
+
'data-col': pos.col,
|
878
|
+
'data-row': pos.row,
|
879
|
+
'data-sizex' : size_x,
|
880
|
+
'data-sizey' : size_y
|
843
881
|
}).addClass('gs_w').appendTo(this.$el).hide();
|
844
882
|
|
845
883
|
this.$widgets = this.$widgets.add($w);
|
846
884
|
|
847
885
|
this.register_widget($w);
|
848
886
|
|
887
|
+
this.add_faux_rows(pos.size_y);
|
888
|
+
//this.add_faux_cols(pos.size_x);
|
889
|
+
|
849
890
|
this.set_dom_grid_height();
|
850
891
|
|
851
892
|
return $w.fadeIn();
|
852
893
|
};
|
853
894
|
|
854
895
|
|
896
|
+
|
897
|
+
/**
|
898
|
+
* Change the size of a widget.
|
899
|
+
*
|
900
|
+
* @method resize_widget
|
901
|
+
* @param {HTMLElement} $widget The jQuery wrapped HTMLElement
|
902
|
+
* representing the widget.
|
903
|
+
* @param {Number} size_x The number of columns that will occupy the widget.
|
904
|
+
* @param {Number} size_y The number of rows that will occupy the widget.
|
905
|
+
* @return {HTMLElement} Returns $widget.
|
906
|
+
*/
|
907
|
+
fn.resize_widget = function($widget, size_x, size_y) {
|
908
|
+
var wgd = $widget.coords().grid;
|
909
|
+
size_x || (size_x = wgd.size_x);
|
910
|
+
size_y || (size_y = wgd.size_y);
|
911
|
+
|
912
|
+
if (size_x > this.cols) {
|
913
|
+
size_x = this.cols;
|
914
|
+
}
|
915
|
+
|
916
|
+
var old_cells_occupied = this.get_cells_occupied(wgd);
|
917
|
+
var old_size_x = wgd.size_x;
|
918
|
+
var old_size_y = wgd.size_y;
|
919
|
+
var old_col = wgd.col;
|
920
|
+
var new_col = old_col;
|
921
|
+
var wider = size_x > old_size_x;
|
922
|
+
var taller = size_y > old_size_y;
|
923
|
+
|
924
|
+
if (old_col + size_x - 1 > this.cols) {
|
925
|
+
var diff = old_col + (size_x - 1) - this.cols;
|
926
|
+
var c = old_col - diff;
|
927
|
+
new_col = Math.max(1, c);
|
928
|
+
}
|
929
|
+
|
930
|
+
var new_grid_data = {
|
931
|
+
col: new_col,
|
932
|
+
row: wgd.row,
|
933
|
+
size_x: size_x,
|
934
|
+
size_y: size_y
|
935
|
+
};
|
936
|
+
|
937
|
+
var new_cells_occupied = this.get_cells_occupied(new_grid_data);
|
938
|
+
|
939
|
+
var empty_cols = [];
|
940
|
+
$.each(old_cells_occupied.cols, function(i, col) {
|
941
|
+
if ($.inArray(col, new_cells_occupied.cols) === -1) {
|
942
|
+
empty_cols.push(col);
|
943
|
+
}
|
944
|
+
});
|
945
|
+
|
946
|
+
var occupied_cols = [];
|
947
|
+
$.each(new_cells_occupied.cols, function(i, col) {
|
948
|
+
if ($.inArray(col, old_cells_occupied.cols) === -1) {
|
949
|
+
occupied_cols.push(col);
|
950
|
+
}
|
951
|
+
});
|
952
|
+
|
953
|
+
var empty_rows = [];
|
954
|
+
$.each(old_cells_occupied.rows, function(i, row) {
|
955
|
+
if ($.inArray(row, new_cells_occupied.rows) === -1) {
|
956
|
+
empty_rows.push(row);
|
957
|
+
}
|
958
|
+
});
|
959
|
+
|
960
|
+
var occupied_rows = [];
|
961
|
+
$.each(new_cells_occupied.rows, function(i, row) {
|
962
|
+
if ($.inArray(row, old_cells_occupied.rows) === -1) {
|
963
|
+
occupied_rows.push(row);
|
964
|
+
}
|
965
|
+
});
|
966
|
+
|
967
|
+
this.remove_from_gridmap(wgd);
|
968
|
+
|
969
|
+
if (occupied_cols.length) {
|
970
|
+
var cols_to_empty = [
|
971
|
+
new_col, wgd.row, size_x, Math.min(old_size_y, size_y), $widget
|
972
|
+
];
|
973
|
+
this.empty_cells.apply(this, cols_to_empty);
|
974
|
+
}
|
975
|
+
|
976
|
+
if (occupied_rows.length) {
|
977
|
+
var rows_to_empty = [new_col, wgd.row, size_x, size_y, $widget];
|
978
|
+
this.empty_cells.apply(this, rows_to_empty);
|
979
|
+
}
|
980
|
+
|
981
|
+
wgd.col = new_col;
|
982
|
+
wgd.size_x = size_x;
|
983
|
+
wgd.size_y = size_y;
|
984
|
+
this.add_to_gridmap(new_grid_data, $widget);
|
985
|
+
|
986
|
+
//update coords instance attributes
|
987
|
+
$widget.data('coords').update({
|
988
|
+
width: (size_x * this.options.widget_base_dimensions[0] +
|
989
|
+
((size_x - 1) * this.options.widget_margins[0]) * 2),
|
990
|
+
height: (size_y * this.options.widget_base_dimensions[1] +
|
991
|
+
((size_y - 1) * this.options.widget_margins[1]) * 2)
|
992
|
+
});
|
993
|
+
|
994
|
+
if (size_y > old_size_y) {
|
995
|
+
this.add_faux_rows(size_y - old_size_y);
|
996
|
+
}
|
997
|
+
|
998
|
+
if (size_x > old_size_x) {
|
999
|
+
this.add_faux_cols(size_x - old_size_x);
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
$widget.attr({
|
1003
|
+
'data-col': new_col,
|
1004
|
+
'data-sizex': size_x,
|
1005
|
+
'data-sizey': size_y
|
1006
|
+
});
|
1007
|
+
|
1008
|
+
if (empty_cols.length) {
|
1009
|
+
var cols_to_remove_holes = [
|
1010
|
+
empty_cols[0], wgd.row,
|
1011
|
+
empty_cols.length,
|
1012
|
+
Math.min(old_size_y, size_y),
|
1013
|
+
$widget
|
1014
|
+
];
|
1015
|
+
|
1016
|
+
this.remove_empty_cells.apply(this, cols_to_remove_holes);
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
if (empty_rows.length) {
|
1020
|
+
var rows_to_remove_holes = [
|
1021
|
+
new_col, wgd.row, size_x, size_y, $widget
|
1022
|
+
];
|
1023
|
+
this.remove_empty_cells.apply(this, rows_to_remove_holes);
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
return $widget;
|
1027
|
+
};
|
1028
|
+
|
1029
|
+
/**
|
1030
|
+
* Move down widgets in cells represented by the arguments col, row, size_x,
|
1031
|
+
* size_y
|
1032
|
+
*
|
1033
|
+
* @method empty_cells
|
1034
|
+
* @param {Number} col The column where the group of cells begin.
|
1035
|
+
* @param {Number} row The row where the group of cells begin.
|
1036
|
+
* @param {Number} size_x The number of columns that the group of cells
|
1037
|
+
* occupy.
|
1038
|
+
* @param {Number} size_y The number of rows that the group of cells
|
1039
|
+
* occupy.
|
1040
|
+
* @param {HTMLElement} $exclude Exclude widgets from being moved.
|
1041
|
+
* @return {Class} Returns the instance of the Gridster Class.
|
1042
|
+
*/
|
1043
|
+
fn.empty_cells = function(col, row, size_x, size_y, $exclude) {
|
1044
|
+
var $nexts = this.widgets_below({
|
1045
|
+
col: col,
|
1046
|
+
row: row - size_y,
|
1047
|
+
size_x: size_x,
|
1048
|
+
size_y: size_y
|
1049
|
+
});
|
1050
|
+
|
1051
|
+
$nexts.not($exclude).each($.proxy(function(i, w) {
|
1052
|
+
var wgd = $(w).coords().grid;
|
1053
|
+
if (!(wgd.row <= (row + size_y - 1))) { return; }
|
1054
|
+
var diff = (row + size_y) - wgd.row;
|
1055
|
+
this.move_widget_down($(w), diff);
|
1056
|
+
}, this));
|
1057
|
+
|
1058
|
+
this.set_dom_grid_height();
|
1059
|
+
|
1060
|
+
return this;
|
1061
|
+
};
|
1062
|
+
|
1063
|
+
|
1064
|
+
/**
|
1065
|
+
* Move up widgets below cells represented by the arguments col, row, size_x,
|
1066
|
+
* size_y.
|
1067
|
+
*
|
1068
|
+
* @method remove_empty_cells
|
1069
|
+
* @param {Number} col The column where the group of cells begin.
|
1070
|
+
* @param {Number} row The row where the group of cells begin.
|
1071
|
+
* @param {Number} size_x The number of columns that the group of cells
|
1072
|
+
* occupy.
|
1073
|
+
* @param {Number} size_y The number of rows that the group of cells
|
1074
|
+
* occupy.
|
1075
|
+
* @param {HTMLElement} exclude Exclude widgets from being moved.
|
1076
|
+
* @return {Class} Returns the instance of the Gridster Class.
|
1077
|
+
*/
|
1078
|
+
fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) {
|
1079
|
+
var $nexts = this.widgets_below({
|
1080
|
+
col: col,
|
1081
|
+
row: row,
|
1082
|
+
size_x: size_x,
|
1083
|
+
size_y: size_y
|
1084
|
+
});
|
1085
|
+
|
1086
|
+
$nexts.not(exclude).each($.proxy(function(i, widget) {
|
1087
|
+
this.move_widget_up( $(widget), size_y );
|
1088
|
+
}, this));
|
1089
|
+
|
1090
|
+
this.set_dom_grid_height();
|
1091
|
+
|
1092
|
+
return this;
|
1093
|
+
};
|
1094
|
+
|
1095
|
+
|
855
1096
|
/**
|
856
1097
|
* Get the most left column below to add a new widget.
|
857
1098
|
*
|
@@ -867,9 +1108,10 @@
|
|
867
1108
|
var ga = this.gridmap;
|
868
1109
|
var cols_l = ga.length;
|
869
1110
|
var valid_pos = [];
|
1111
|
+
var rows_l;
|
870
1112
|
|
871
1113
|
for (var c = 1; c < cols_l; c++) {
|
872
|
-
|
1114
|
+
rows_l = ga[c].length;
|
873
1115
|
for (var r = 1; r <= rows_l; r++) {
|
874
1116
|
var can_move_to = this.can_move_to({
|
875
1117
|
size_x: size_x,
|
@@ -899,12 +1141,21 @@
|
|
899
1141
|
*
|
900
1142
|
* @method remove_widget
|
901
1143
|
* @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove.
|
1144
|
+
* @param {Boolean|Function} silent If true, widgets below the removed one
|
1145
|
+
* will not move up. If a Function is passed it will be used as callback.
|
1146
|
+
* @param {Function} callback Function executed when the widget is removed.
|
902
1147
|
* @return {Class} Returns the instance of the Gridster Class.
|
903
1148
|
*/
|
904
|
-
fn.remove_widget = function(el, callback) {
|
1149
|
+
fn.remove_widget = function(el, silent, callback) {
|
905
1150
|
var $el = el instanceof jQuery ? el : $(el);
|
906
1151
|
var wgd = $el.coords().grid;
|
907
1152
|
|
1153
|
+
// if silent is a function assume it's a callback
|
1154
|
+
if ($.isFunction(silent)) {
|
1155
|
+
callback = silent;
|
1156
|
+
silent = false;
|
1157
|
+
}
|
1158
|
+
|
908
1159
|
this.cells_occupied_by_placeholder = {};
|
909
1160
|
this.$widgets = this.$widgets.not($el);
|
910
1161
|
|
@@ -915,9 +1166,11 @@
|
|
915
1166
|
$el.fadeOut($.proxy(function() {
|
916
1167
|
$el.remove();
|
917
1168
|
|
918
|
-
|
919
|
-
|
920
|
-
|
1169
|
+
if (!silent) {
|
1170
|
+
$nexts.each($.proxy(function(i, widget) {
|
1171
|
+
this.move_widget_up( $(widget), wgd.size_y );
|
1172
|
+
}, this));
|
1173
|
+
}
|
921
1174
|
|
922
1175
|
this.set_dom_grid_height();
|
923
1176
|
|
@@ -928,6 +1181,22 @@
|
|
928
1181
|
};
|
929
1182
|
|
930
1183
|
|
1184
|
+
/**
|
1185
|
+
* Remove all widgets from the grid.
|
1186
|
+
*
|
1187
|
+
* @method remove_all_widgets
|
1188
|
+
* @param {Function} callback Function executed for each widget removed.
|
1189
|
+
* @return {Class} Returns the instance of the Gridster Class.
|
1190
|
+
*/
|
1191
|
+
fn.remove_all_widgets = function(callback) {
|
1192
|
+
this.$widgets.each($.proxy(function(i, el){
|
1193
|
+
this.remove_widget(el, true, callback);
|
1194
|
+
}, this));
|
1195
|
+
|
1196
|
+
return this;
|
1197
|
+
};
|
1198
|
+
|
1199
|
+
|
931
1200
|
/**
|
932
1201
|
* Returns a serialized array of the widgets in the grid.
|
933
1202
|
*
|
@@ -1001,7 +1270,7 @@
|
|
1001
1270
|
$el.data('coords').grid = wgd;
|
1002
1271
|
|
1003
1272
|
this.add_to_gridmap(wgd, $el);
|
1004
|
-
|
1273
|
+
|
1005
1274
|
return this;
|
1006
1275
|
};
|
1007
1276
|
|
@@ -1073,7 +1342,6 @@
|
|
1073
1342
|
var self = this;
|
1074
1343
|
var draggable_options = $.extend(true, {}, this.options.draggable, {
|
1075
1344
|
offset_left: this.options.widget_margins[0],
|
1076
|
-
items: '.gs_w',
|
1077
1345
|
start: function(event, ui) {
|
1078
1346
|
self.$widgets.filter('.player-revert')
|
1079
1347
|
.removeClass('player-revert');
|
@@ -1105,8 +1373,8 @@
|
|
1105
1373
|
* This function is executed when the player begins to be dragged.
|
1106
1374
|
*
|
1107
1375
|
* @method on_start_drag
|
1108
|
-
* @param {Event} The original browser event
|
1109
|
-
* @param {Object} A prepared ui object.
|
1376
|
+
* @param {Event} event The original browser event
|
1377
|
+
* @param {Object} ui A prepared ui object.
|
1110
1378
|
*/
|
1111
1379
|
fn.on_start_drag = function(event, ui) {
|
1112
1380
|
|
@@ -1156,14 +1424,14 @@
|
|
1156
1424
|
* This function is executed when the player is being dragged.
|
1157
1425
|
*
|
1158
1426
|
* @method on_drag
|
1159
|
-
* @param {Event} The original browser event
|
1160
|
-
* @param {Object} A prepared ui object.
|
1427
|
+
* @param {Event} event The original browser event
|
1428
|
+
* @param {Object} ui A prepared ui object.
|
1161
1429
|
*/
|
1162
1430
|
fn.on_drag = function(event, ui) {
|
1163
1431
|
//break if dragstop has been fired
|
1164
1432
|
if (this.$player === null) {
|
1165
1433
|
return false;
|
1166
|
-
}
|
1434
|
+
}
|
1167
1435
|
|
1168
1436
|
var abs_offset = {
|
1169
1437
|
left: ui.position.left + this.baseX,
|
@@ -1199,8 +1467,8 @@
|
|
1199
1467
|
* This function is executed when the player stops being dragged.
|
1200
1468
|
*
|
1201
1469
|
* @method on_stop_drag
|
1202
|
-
* @param {Event} The original browser event
|
1203
|
-
* @param {Object} A prepared ui object.
|
1470
|
+
* @param {Event} event The original browser event
|
1471
|
+
* @param {Object} ui A prepared ui object.
|
1204
1472
|
*/
|
1205
1473
|
fn.on_stop_drag = function(event, ui) {
|
1206
1474
|
this.$helper.add(this.$player).add(this.$wrapper)
|
@@ -1244,7 +1512,13 @@
|
|
1244
1512
|
}
|
1245
1513
|
|
1246
1514
|
this.$preview_holder.remove();
|
1515
|
+
|
1247
1516
|
this.$player = null;
|
1517
|
+
this.$helper = null;
|
1518
|
+
this.placeholder_grid_data = {};
|
1519
|
+
this.player_grid_data = {};
|
1520
|
+
this.cells_occupied_by_placeholder = {};
|
1521
|
+
this.cells_occupied_by_player = {};
|
1248
1522
|
|
1249
1523
|
this.set_dom_grid_height();
|
1250
1524
|
};
|
@@ -1263,7 +1537,7 @@
|
|
1263
1537
|
*/
|
1264
1538
|
fn.on_overlapped_column_change = function(start_callback, stop_callback) {
|
1265
1539
|
if (!this.colliders_data.length) {
|
1266
|
-
return;
|
1540
|
+
return this;
|
1267
1541
|
}
|
1268
1542
|
var cols = this.get_targeted_columns(
|
1269
1543
|
this.colliders_data[0].el.data.col);
|
@@ -1296,14 +1570,14 @@
|
|
1296
1570
|
*
|
1297
1571
|
* @param {Function} start_callback Function executed when a new row begins
|
1298
1572
|
* to be overlapped. The row is passed as first argument.
|
1299
|
-
* @param {Function}
|
1573
|
+
* @param {Function} end_callback Function executed when a row stops being
|
1300
1574
|
* overlapped. The row is passed as first argument.
|
1301
1575
|
* @method on_overlapped_row_change
|
1302
1576
|
* @return {Class} Returns the instance of the Gridster Class.
|
1303
1577
|
*/
|
1304
1578
|
fn.on_overlapped_row_change = function(start_callback, end_callback) {
|
1305
1579
|
if (!this.colliders_data.length) {
|
1306
|
-
return;
|
1580
|
+
return this;
|
1307
1581
|
}
|
1308
1582
|
var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row);
|
1309
1583
|
var last_n_rows = this.last_rows.length;
|
@@ -1329,18 +1603,18 @@
|
|
1329
1603
|
/**
|
1330
1604
|
* Sets the current position of the player
|
1331
1605
|
*
|
1332
|
-
* @param {
|
1333
|
-
*
|
1334
|
-
* @param {
|
1335
|
-
* overlapped. The row is passed as first argument.
|
1606
|
+
* @param {Number} col
|
1607
|
+
* @param {Number} row
|
1608
|
+
* @param {Boolean} no_player
|
1336
1609
|
* @method set_player
|
1337
|
-
* @return {
|
1610
|
+
* @return {object}
|
1338
1611
|
*/
|
1339
|
-
fn.set_player = function(col, row) {
|
1340
|
-
this.empty_cells_player_occupies();
|
1341
|
-
|
1612
|
+
fn.set_player = function(col, row, no_player) {
|
1342
1613
|
var self = this;
|
1343
|
-
|
1614
|
+
if (!no_player) {
|
1615
|
+
this.empty_cells_player_occupies();
|
1616
|
+
}
|
1617
|
+
var cell = !no_player ? self.colliders_data[0].el.data : {col: col};
|
1344
1618
|
var to_col = cell.col;
|
1345
1619
|
var to_row = row || cell.row;
|
1346
1620
|
|
@@ -1384,9 +1658,9 @@
|
|
1384
1658
|
* a upper row and which not.
|
1385
1659
|
*
|
1386
1660
|
* @method widgets_contraints
|
1387
|
-
* @param {
|
1661
|
+
* @param {jQuery} $widgets A jQuery wrapped collection of
|
1388
1662
|
* HTMLElements.
|
1389
|
-
* @return {
|
1663
|
+
* @return {object} Returns a literal Object with two keys: `can_go_up` &
|
1390
1664
|
* `can_not_go_up`. Each contains a set of HTMLElements.
|
1391
1665
|
*/
|
1392
1666
|
fn.widgets_constraints = function($widgets) {
|
@@ -1425,6 +1699,11 @@
|
|
1425
1699
|
*/
|
1426
1700
|
fn.sort_by_row_asc = function(widgets) {
|
1427
1701
|
widgets = widgets.sort(function(a, b) {
|
1702
|
+
if (!a.row) {
|
1703
|
+
a = $(a).coords().grid;
|
1704
|
+
b = $(b).coords().grid;
|
1705
|
+
}
|
1706
|
+
|
1428
1707
|
if (a.row > b.row) {
|
1429
1708
|
return 1;
|
1430
1709
|
}
|
@@ -1445,7 +1724,7 @@
|
|
1445
1724
|
*/
|
1446
1725
|
fn.sort_by_row_and_col_asc = function(widgets) {
|
1447
1726
|
widgets = widgets.sort(function(a, b) {
|
1448
|
-
if (a.row > b.row || a.row
|
1727
|
+
if (a.row > b.row || a.row === b.row && a.col > b.col) {
|
1449
1728
|
return 1;
|
1450
1729
|
}
|
1451
1730
|
return -1;
|
@@ -1499,7 +1778,7 @@
|
|
1499
1778
|
* each widget) in descending way.
|
1500
1779
|
*
|
1501
1780
|
* @method manage_movements
|
1502
|
-
* @param {
|
1781
|
+
* @param {jQuery} $widgets A jQuery collection of HTMLElements
|
1503
1782
|
* representing the widgets you want to move.
|
1504
1783
|
* @param {Number} to_col The column to which we want to move the widgets.
|
1505
1784
|
* @param {Number} to_row The row to which we want to move the widgets.
|
@@ -1680,13 +1959,14 @@
|
|
1680
1959
|
|
1681
1960
|
|
1682
1961
|
/**
|
1683
|
-
* Get widgets overlapping with the player
|
1962
|
+
* Get widgets overlapping with the player or with the object passed
|
1963
|
+
* representing the grid cells.
|
1684
1964
|
*
|
1685
1965
|
* @method get_widgets_under_player
|
1686
1966
|
* @return {HTMLElement} Returns a jQuery collection of HTMLElements
|
1687
1967
|
*/
|
1688
|
-
fn.get_widgets_under_player = function() {
|
1689
|
-
|
1968
|
+
fn.get_widgets_under_player = function(cells) {
|
1969
|
+
cells || (cells = this.cells_occupied_by_player || {cols: [], rows: []});
|
1690
1970
|
var $widgets = $([]);
|
1691
1971
|
|
1692
1972
|
$.each(cells.cols, $.proxy(function(i, col) {
|
@@ -1720,7 +2000,7 @@
|
|
1720
2000
|
size_x: phgd.size_x
|
1721
2001
|
});
|
1722
2002
|
|
1723
|
-
//Prevents widgets go out of the grid
|
2003
|
+
// Prevents widgets go out of the grid
|
1724
2004
|
var right_col = (col + phgd.size_x - 1);
|
1725
2005
|
if (right_col > this.cols) {
|
1726
2006
|
col = col - (right_col - col);
|
@@ -1747,6 +2027,16 @@
|
|
1747
2027
|
}, this));
|
1748
2028
|
}
|
1749
2029
|
|
2030
|
+
|
2031
|
+
var $widgets_under_ph = this.get_widgets_under_player(this.cells_occupied_by_placeholder);
|
2032
|
+
if ($widgets_under_ph.length) {
|
2033
|
+
$widgets_under_ph.each($.proxy(function(i, widget) {
|
2034
|
+
var $w = $(widget);
|
2035
|
+
this.move_widget_down(
|
2036
|
+
$w, row + phgd.size_y - $w.data('coords').grid.row);
|
2037
|
+
}, this));
|
2038
|
+
}
|
2039
|
+
|
1750
2040
|
};
|
1751
2041
|
|
1752
2042
|
|
@@ -1814,33 +2104,26 @@
|
|
1814
2104
|
var upper_rows = [];
|
1815
2105
|
var min_row = 10000;
|
1816
2106
|
|
1817
|
-
|
1818
|
-
(widget_grid_data.col + widget_grid_data.size_y - 1) >
|
1819
|
-
(this.player_grid_data.col + this.player_grid_data.size_y - 1)
|
1820
|
-
) {
|
1821
|
-
return false;
|
1822
|
-
};
|
1823
|
-
|
1824
|
-
/* generate an array with columns as index and array with upper rows
|
2107
|
+
/* generate an array with columns as index and array with topmost rows
|
1825
2108
|
* empty as value */
|
1826
2109
|
this.for_each_column_occupied(widget_grid_data, function(tcol) {
|
1827
2110
|
var grid_col = this.gridmap[tcol];
|
1828
2111
|
upper_rows[tcol] = [];
|
1829
2112
|
|
1830
2113
|
var r = p_bottom_row + 1;
|
1831
|
-
|
2114
|
+
// iterate over each row
|
1832
2115
|
while (--r > 0) {
|
1833
2116
|
if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) {
|
1834
2117
|
if (!grid_col[r].is(widget_grid_data.el)) {
|
1835
2118
|
break;
|
1836
|
-
}
|
2119
|
+
}
|
1837
2120
|
}
|
1838
2121
|
|
1839
2122
|
if (!this.is_player(tcol, r) &&
|
1840
2123
|
!this.is_placeholder_in(tcol, r) &&
|
1841
2124
|
!this.is_player_in(tcol, r)) {
|
1842
2125
|
upper_rows[tcol].push(r);
|
1843
|
-
}
|
2126
|
+
}
|
1844
2127
|
|
1845
2128
|
if (r < min_row) {
|
1846
2129
|
min_row = r;
|
@@ -1942,7 +2225,7 @@
|
|
1942
2225
|
* Get widgets overlapping with the player.
|
1943
2226
|
*
|
1944
2227
|
* @method get_widgets_overlapped
|
1945
|
-
* @return {
|
2228
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
1946
2229
|
*/
|
1947
2230
|
fn.get_widgets_overlapped = function() {
|
1948
2231
|
var $w;
|
@@ -1956,7 +2239,6 @@
|
|
1956
2239
|
// if there is a widget in the player position
|
1957
2240
|
if (!this.gridmap[col]) { return true; } //next iteration
|
1958
2241
|
var $w = this.gridmap[col][row];
|
1959
|
-
|
1960
2242
|
if (this.is_occupied(col, row) && !this.is_player($w) &&
|
1961
2243
|
$.inArray($w, used) === -1
|
1962
2244
|
) {
|
@@ -1976,7 +2258,7 @@
|
|
1976
2258
|
*
|
1977
2259
|
* @method on_start_overlapping_column
|
1978
2260
|
* @param {Number} col The collided column.
|
1979
|
-
* @return {
|
2261
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
1980
2262
|
*/
|
1981
2263
|
fn.on_start_overlapping_column = function(col) {
|
1982
2264
|
this.set_player(col, false);
|
@@ -1987,8 +2269,8 @@
|
|
1987
2269
|
* A callback executed when the player begins to collide with a row.
|
1988
2270
|
*
|
1989
2271
|
* @method on_start_overlapping_row
|
1990
|
-
* @param {Number}
|
1991
|
-
* @return {
|
2272
|
+
* @param {Number} row The collided row.
|
2273
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
1992
2274
|
*/
|
1993
2275
|
fn.on_start_overlapping_row = function(row) {
|
1994
2276
|
this.set_player(false, row);
|
@@ -2000,7 +2282,7 @@
|
|
2000
2282
|
*
|
2001
2283
|
* @method on_stop_overlapping_column
|
2002
2284
|
* @param {Number} col The collided row.
|
2003
|
-
* @return {
|
2285
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
2004
2286
|
*/
|
2005
2287
|
fn.on_stop_overlapping_column = function(col) {
|
2006
2288
|
this.set_player(col, false);
|
@@ -2018,7 +2300,7 @@
|
|
2018
2300
|
*
|
2019
2301
|
* @method on_stop_overlapping_row
|
2020
2302
|
* @param {Number} row The collided row.
|
2021
|
-
* @return {
|
2303
|
+
* @return {jQuery} Returns a jQuery collection of HTMLElements.
|
2022
2304
|
*/
|
2023
2305
|
fn.on_stop_overlapping_row = function(row) {
|
2024
2306
|
this.set_player(false, row);
|
@@ -2128,9 +2410,9 @@
|
|
2128
2410
|
* Move down the specified widget and all below it.
|
2129
2411
|
*
|
2130
2412
|
* @method move_widget_down
|
2131
|
-
* @param {
|
2413
|
+
* @param {jQuery} $widget The jQuery object representing the widget
|
2132
2414
|
* you want to move.
|
2133
|
-
* @param {Number} The number of cells that the widget has to move.
|
2415
|
+
* @param {Number} y_units The number of cells that the widget has to move.
|
2134
2416
|
* @return {Class} Returns the instance of the Gridster Class.
|
2135
2417
|
*/
|
2136
2418
|
fn.move_widget_down = function($widget, y_units) {
|
@@ -2266,7 +2548,7 @@
|
|
2266
2548
|
*
|
2267
2549
|
* @method widgets_below
|
2268
2550
|
* @param {HTMLElement} $el The jQuery wrapped HTMLElement.
|
2269
|
-
* @return {
|
2551
|
+
* @return {jQuery} A jQuery collection of HTMLElements.
|
2270
2552
|
*/
|
2271
2553
|
fn.widgets_below = function($el) {
|
2272
2554
|
var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid;
|
@@ -2276,14 +2558,12 @@
|
|
2276
2558
|
var $nexts = $([]);
|
2277
2559
|
|
2278
2560
|
this.for_each_column_occupied(el_grid_data, function(col) {
|
2279
|
-
self.for_each_widget_below(col, next_row,
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
}
|
2286
|
-
});
|
2561
|
+
self.for_each_widget_below(col, next_row, function(tcol, trow) {
|
2562
|
+
if (!self.is_player(this) && $.inArray(this, $nexts) === -1) {
|
2563
|
+
$nexts = $nexts.add(this);
|
2564
|
+
return true; // break
|
2565
|
+
}
|
2566
|
+
});
|
2287
2567
|
});
|
2288
2568
|
|
2289
2569
|
return this.sort_by_row_asc($nexts);
|
@@ -2331,6 +2611,7 @@
|
|
2331
2611
|
|
2332
2612
|
this.for_each_column_occupied(el_grid_data, function(col) {
|
2333
2613
|
var $w = this.is_widget(col, prev_row);
|
2614
|
+
|
2334
2615
|
if (this.is_occupied(col, prev_row) ||
|
2335
2616
|
this.is_player(col, prev_row) ||
|
2336
2617
|
this.is_placeholder_in(col, prev_row) ||
|
@@ -2356,9 +2637,10 @@
|
|
2356
2637
|
* the widget.
|
2357
2638
|
* @param {Object} col The col to check.
|
2358
2639
|
* @param {Object} row The row to check.
|
2640
|
+
* @param {Number} [max_row] The max row allowed.
|
2359
2641
|
* @return {Boolean} Returns true if all cells are empty, else return false.
|
2360
2642
|
*/
|
2361
|
-
fn.can_move_to = function(widget_grid_data, col, row) {
|
2643
|
+
fn.can_move_to = function(widget_grid_data, col, row, max_row) {
|
2362
2644
|
var ga = this.gridmap;
|
2363
2645
|
var $w = widget_grid_data.el;
|
2364
2646
|
var future_wd = {
|
@@ -2373,7 +2655,11 @@
|
|
2373
2655
|
var right_col = col + widget_grid_data.size_x - 1;
|
2374
2656
|
if (right_col > this.cols) {
|
2375
2657
|
return false;
|
2376
|
-
}
|
2658
|
+
}
|
2659
|
+
|
2660
|
+
if (max_row && max_row < row + widget_grid_data.size_y - 1) {
|
2661
|
+
return false;
|
2662
|
+
}
|
2377
2663
|
|
2378
2664
|
this.for_each_cell_occupied(future_wd, function(tcol, trow) {
|
2379
2665
|
var $tw = this.is_widget(tcol, trow);
|
@@ -2646,7 +2932,7 @@
|
|
2646
2932
|
}
|
2647
2933
|
|
2648
2934
|
return $widgets;
|
2649
|
-
}
|
2935
|
+
};
|
2650
2936
|
|
2651
2937
|
|
2652
2938
|
/**
|
@@ -2672,16 +2958,16 @@
|
|
2672
2958
|
*/
|
2673
2959
|
fn.generate_stylesheet = function(opts) {
|
2674
2960
|
var styles = '';
|
2675
|
-
var extra_cells = 10;
|
2676
|
-
var max_size_y = this.options.max_size_y;
|
2677
2961
|
var max_size_x = this.options.max_size_x;
|
2962
|
+
var max_rows = 0;
|
2963
|
+
var max_cols = 0;
|
2678
2964
|
var i;
|
2679
2965
|
var rules;
|
2680
2966
|
|
2681
2967
|
opts || (opts = {});
|
2682
2968
|
opts.cols || (opts.cols = this.cols);
|
2683
2969
|
opts.rows || (opts.rows = this.rows);
|
2684
|
-
opts.namespace || (opts.namespace =
|
2970
|
+
opts.namespace || (opts.namespace = this.options.namespace);
|
2685
2971
|
opts.widget_base_dimensions ||
|
2686
2972
|
(opts.widget_base_dimensions = this.options.widget_base_dimensions);
|
2687
2973
|
opts.widget_margins ||
|
@@ -2691,8 +2977,8 @@
|
|
2691
2977
|
opts.min_widget_height = (opts.widget_margins[1] * 2) +
|
2692
2978
|
opts.widget_base_dimensions[1];
|
2693
2979
|
|
2694
|
-
var serialized_opts = $.param(opts);
|
2695
2980
|
// don't duplicate stylesheets for the same configuration
|
2981
|
+
var serialized_opts = $.param(opts);
|
2696
2982
|
if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) {
|
2697
2983
|
return false;
|
2698
2984
|
}
|
@@ -2700,7 +2986,7 @@
|
|
2700
2986
|
Gridster.generated_stylesheets.push(serialized_opts);
|
2701
2987
|
|
2702
2988
|
/* generate CSS styles for cols */
|
2703
|
-
for (i = opts.cols
|
2989
|
+
for (i = opts.cols; i >= 0; i--) {
|
2704
2990
|
styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' +
|
2705
2991
|
((i * opts.widget_base_dimensions[0]) +
|
2706
2992
|
(i * opts.widget_margins[0]) +
|
@@ -2708,14 +2994,14 @@
|
|
2708
2994
|
}
|
2709
2995
|
|
2710
2996
|
/* generate CSS styles for rows */
|
2711
|
-
for (i = opts.rows
|
2997
|
+
for (i = opts.rows; i >= 0; i--) {
|
2712
2998
|
styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' +
|
2713
2999
|
((i * opts.widget_base_dimensions[1]) +
|
2714
3000
|
(i * opts.widget_margins[1]) +
|
2715
3001
|
((i + 1) * opts.widget_margins[1]) ) + 'px;} ');
|
2716
3002
|
}
|
2717
3003
|
|
2718
|
-
for (var y = 1; y <=
|
3004
|
+
for (var y = 1; y <= opts.rows; y++) {
|
2719
3005
|
styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' +
|
2720
3006
|
(y * opts.widget_base_dimensions[1] +
|
2721
3007
|
(y - 1) * (opts.widget_margins[1] * 2)) + 'px;}');
|
@@ -2771,7 +3057,23 @@
|
|
2771
3057
|
for (col = cols; col > 0; col--) {
|
2772
3058
|
this.gridmap[col] = [];
|
2773
3059
|
for (row = rows; row > 0; row--) {
|
2774
|
-
|
3060
|
+
this.add_faux_cell(row, col);
|
3061
|
+
}
|
3062
|
+
}
|
3063
|
+
return this;
|
3064
|
+
};
|
3065
|
+
|
3066
|
+
|
3067
|
+
/**
|
3068
|
+
* Add cell to the faux grid.
|
3069
|
+
*
|
3070
|
+
* @method add_faux_cell
|
3071
|
+
* @param {Number} row The row for the new faux cell.
|
3072
|
+
* @param {Number} col The col for the new faux cell.
|
3073
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3074
|
+
*/
|
3075
|
+
fn.add_faux_cell = function(row, col) {
|
3076
|
+
var coords = $({
|
2775
3077
|
left: this.baseX + ((col - 1) * this.min_widget_width),
|
2776
3078
|
top: this.baseY + (row -1) * this.min_widget_height,
|
2777
3079
|
width: this.min_widget_width,
|
@@ -2782,10 +3084,66 @@
|
|
2782
3084
|
original_row: row
|
2783
3085
|
}).coords();
|
2784
3086
|
|
2785
|
-
|
2786
|
-
|
3087
|
+
if (!$.isArray(this.gridmap[col])) {
|
3088
|
+
this.gridmap[col] = [];
|
3089
|
+
}
|
3090
|
+
|
3091
|
+
this.gridmap[col][row] = false;
|
3092
|
+
this.faux_grid.push(coords);
|
3093
|
+
|
3094
|
+
return this;
|
3095
|
+
};
|
3096
|
+
|
3097
|
+
|
3098
|
+
/**
|
3099
|
+
* Add rows to the faux grid.
|
3100
|
+
*
|
3101
|
+
* @method add_faux_rows
|
3102
|
+
* @param {Number} rows The number of rows you want to add to the faux grid.
|
3103
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3104
|
+
*/
|
3105
|
+
fn.add_faux_rows = function(rows) {
|
3106
|
+
var actual_rows = this.rows;
|
3107
|
+
var max_rows = actual_rows + (rows || 1);
|
3108
|
+
|
3109
|
+
for (var r = max_rows; r > actual_rows; r--) {
|
3110
|
+
for (var c = this.cols; c >= 1; c--) {
|
3111
|
+
this.add_faux_cell(r, c);
|
2787
3112
|
}
|
2788
3113
|
}
|
3114
|
+
|
3115
|
+
this.rows = max_rows;
|
3116
|
+
|
3117
|
+
if (this.options.autogenerate_stylesheet) {
|
3118
|
+
this.generate_stylesheet();
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
return this;
|
3122
|
+
};
|
3123
|
+
|
3124
|
+
/**
|
3125
|
+
* Add cols to the faux grid.
|
3126
|
+
*
|
3127
|
+
* @method add_faux_cols
|
3128
|
+
* @param {Number} cols The number of cols you want to add to the faux grid.
|
3129
|
+
* @return {Object} Returns the instance of the Gridster class.
|
3130
|
+
*/
|
3131
|
+
fn.add_faux_cols = function(cols) {
|
3132
|
+
var actual_cols = this.cols;
|
3133
|
+
var max_cols = actual_cols + (cols || 1);
|
3134
|
+
|
3135
|
+
for (var c = actual_cols; c < max_cols; c++) {
|
3136
|
+
for (var r = this.rows; r >= 1; r--) {
|
3137
|
+
this.add_faux_cell(r, c);
|
3138
|
+
}
|
3139
|
+
}
|
3140
|
+
|
3141
|
+
this.cols = max_cols;
|
3142
|
+
|
3143
|
+
if (this.options.autogenerate_stylesheet) {
|
3144
|
+
this.generate_stylesheet();
|
3145
|
+
}
|
3146
|
+
|
2789
3147
|
return this;
|
2790
3148
|
};
|
2791
3149
|
|
@@ -2841,8 +3199,6 @@
|
|
2841
3199
|
|
2842
3200
|
var cols = Math.floor(aw / this.min_widget_width) +
|
2843
3201
|
this.options.extra_cols;
|
2844
|
-
var rows = Math.floor(ah / this.min_widget_height) +
|
2845
|
-
this.options.extra_rows;
|
2846
3202
|
|
2847
3203
|
var actual_cols = this.$widgets.map(function() {
|
2848
3204
|
return $(this).attr('data-col');
|
@@ -2851,18 +3207,16 @@
|
|
2851
3207
|
//needed to pass tests with phantomjs
|
2852
3208
|
actual_cols.length || (actual_cols = [0]);
|
2853
3209
|
|
2854
|
-
var actual_rows = this.$widgets.map(function() {
|
2855
|
-
return $(this).attr('data-row');
|
2856
|
-
});
|
2857
|
-
actual_rows = Array.prototype.slice.call(actual_rows, 0);
|
2858
|
-
//needed to pass tests with phantomjs
|
2859
|
-
actual_rows.length || (actual_rows = [0]);
|
2860
|
-
|
2861
3210
|
var min_cols = Math.max.apply(Math, actual_cols);
|
2862
|
-
|
3211
|
+
|
3212
|
+
// get all rows that could be occupied by the current widgets
|
3213
|
+
var max_rows = this.options.extra_rows;
|
3214
|
+
this.$widgets.each(function(i, w) {
|
3215
|
+
max_rows += (+$(w).attr('data-sizey'));
|
3216
|
+
});
|
2863
3217
|
|
2864
3218
|
this.cols = Math.max(min_cols, cols, this.options.min_cols);
|
2865
|
-
this.rows = Math.max(
|
3219
|
+
this.rows = Math.max(max_rows, this.options.min_rows);
|
2866
3220
|
|
2867
3221
|
this.baseX = ($(window).width() - aw) / 2;
|
2868
3222
|
this.baseY = this.$wrapper.offset().top;
|
@@ -2871,11 +3225,29 @@
|
|
2871
3225
|
this.generate_stylesheet();
|
2872
3226
|
}
|
2873
3227
|
|
2874
|
-
/* more faux rows that needed are created so that there are cells
|
2875
|
-
* where drag beyond the limits */
|
2876
3228
|
return this.generate_faux_grid(this.rows, this.cols);
|
2877
3229
|
};
|
2878
3230
|
|
3231
|
+
/**
|
3232
|
+
* Destroy this gridster by removing any sign of its presence, making it easy to avoid memory leaks
|
3233
|
+
*
|
3234
|
+
* @method destroy
|
3235
|
+
* @return {undefined}
|
3236
|
+
*/
|
3237
|
+
fn.destroy = function(){
|
3238
|
+
// remove bound callback on window resize
|
3239
|
+
$(window).unbind('resize', this.on_window_resize);
|
3240
|
+
|
3241
|
+
if(this.drag_api){
|
3242
|
+
this.drag_api.destroy();
|
3243
|
+
}
|
3244
|
+
|
3245
|
+
// lastly, remove gridster element
|
3246
|
+
// this will additionally cause any data associated to this element to be removed, including this
|
3247
|
+
// very gridster instance
|
3248
|
+
this.$el.remove();
|
3249
|
+
};
|
3250
|
+
|
2879
3251
|
|
2880
3252
|
//jQuery adapter
|
2881
3253
|
$.fn.gridster = function(options) {
|
@@ -2886,5 +3258,6 @@
|
|
2886
3258
|
});
|
2887
3259
|
};
|
2888
3260
|
|
3261
|
+
$.Gridster = fn;
|
2889
3262
|
|
2890
3263
|
}(jQuery, window, document));
|