slickgrid added to third-party
[myslice.git] / third-party / slickgrid-2.1 / plugins / slick.cellselectionmodel.js
1 (function ($) {
2   // register namespace
3   $.extend(true, window, {
4     "Slick": {
5       "CellSelectionModel": CellSelectionModel
6     }
7   });
8
9
10   function CellSelectionModel(options) {
11     var _grid;
12     var _canvas;
13     var _ranges = [];
14     var _self = this;
15     var _selector = new Slick.CellRangeSelector({
16       "selectionCss": {
17         "border": "2px solid black"
18       }
19     });
20     var _options;
21     var _defaults = {
22       selectActiveCell: true
23     };
24
25
26     function init(grid) {
27       _options = $.extend(true, {}, _defaults, options);
28       _grid = grid;
29       _canvas = _grid.getCanvasNode();
30       _grid.onActiveCellChanged.subscribe(handleActiveCellChange);
31       _grid.onKeyDown.subscribe(handleKeyDown);
32       grid.registerPlugin(_selector);
33       _selector.onCellRangeSelected.subscribe(handleCellRangeSelected);
34       _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);
35     }
36
37     function destroy() {
38       _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);
39       _grid.onKeyDown.unsubscribe(handleKeyDown);
40       _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);
41       _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);
42       _grid.unregisterPlugin(_selector);
43     }
44
45     function removeInvalidRanges(ranges) {
46       var result = [];
47
48       for (var i = 0; i < ranges.length; i++) {
49         var r = ranges[i];
50         if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)) {
51           result.push(r);
52         }
53       }
54
55       return result;
56     }
57
58     function setSelectedRanges(ranges) {
59       _ranges = removeInvalidRanges(ranges);
60       _self.onSelectedRangesChanged.notify(_ranges);
61     }
62
63     function getSelectedRanges() {
64       return _ranges;
65     }
66
67     function handleBeforeCellRangeSelected(e, args) {
68       if (_grid.getEditorLock().isActive()) {
69         e.stopPropagation();
70         return false;
71       }
72     }
73
74     function handleCellRangeSelected(e, args) {
75       setSelectedRanges([args.range]);
76     }
77
78     function handleActiveCellChange(e, args) {
79       if (_options.selectActiveCell && args.row != null && args.cell != null) {
80         setSelectedRanges([new Slick.Range(args.row, args.cell)]);
81       }
82     }
83     
84     function handleKeyDown(e) {
85       /***
86        * Кey codes
87        * 37 left
88        * 38 up
89        * 39 right
90        * 40 down                     
91        */                                         
92       var ranges, last;
93       var active = _grid.getActiveCell(); 
94
95       if ( active && e.shiftKey && !e.ctrlKey && !e.altKey && 
96           (e.which == 37 || e.which == 39 || e.which == 38 || e.which == 40) ) {
97       
98         ranges = getSelectedRanges();
99         if (!ranges.length)
100          ranges.push(new Slick.Range(active.row, active.cell));
101          
102         // keyboard can work with last range only          
103         last = ranges.pop();
104         
105         // can't handle selection out of active cell
106         if (!last.contains(active.row, active.cell))
107           last = new Slick.Range(active.row, active.cell);
108         
109         var dRow = last.toRow - last.fromRow,
110             dCell = last.toCell - last.fromCell,
111             // walking direction
112             dirRow = active.row == last.fromRow ? 1 : -1,
113             dirCell = active.cell == last.fromCell ? 1 : -1;
114                  
115         if (e.which == 37) {
116           dCell -= dirCell; 
117         } else if (e.which == 39) {
118           dCell += dirCell ; 
119         } else if (e.which == 38) {
120           dRow -= dirRow; 
121         } else if (e.which == 40) {
122           dRow += dirRow; 
123         }
124         
125         // define new selection range 
126         var new_last = new Slick.Range(active.row, active.cell, active.row + dirRow*dRow, active.cell + dirCell*dCell);
127         if (removeInvalidRanges([new_last]).length) {
128           ranges.push(new_last);
129           var viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;
130           var viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;
131          _grid.scrollRowIntoView(viewRow);
132          _grid.scrollCellIntoView(viewRow, viewCell);
133         }
134         else 
135           ranges.push(last);
136
137         setSelectedRanges(ranges);  
138        
139         e.preventDefault();
140         e.stopPropagation();        
141       }           
142     }
143
144     $.extend(this, {
145       "getSelectedRanges": getSelectedRanges,
146       "setSelectedRanges": setSelectedRanges,
147
148       "init": init,
149       "destroy": destroy,
150
151       "onSelectedRangesChanged": new Slick.Event()
152     });
153   }
154 })(jQuery);