1 | import {
|
2 | DragAndDropService, DraggingEvent, DragSourceType, DropTarget,
|
3 | VDirection
|
4 | } from "../dragAndDrop/dragAndDropService";
|
5 | import {Autowired, Optional, PostConstruct} from "../context/context";
|
6 | import {ClientSideRowModel} from "../rowModels/clientSide/clientSideRowModel";
|
7 | import {FocusedCellController} from "../focusedCellController";
|
8 | import {IRangeController} from "../interfaces/iRangeController";
|
9 | import {GridPanel} from "./gridPanel";
|
10 | import {GridOptionsWrapper} from "../gridOptionsWrapper";
|
11 | import {EventService} from "../eventService";
|
12 | import {RowDragEvent} from "../events";
|
13 | import {Events} from "../eventKeys";
|
14 | import {IRowModel} from "../interfaces/iRowModel";
|
15 |
|
16 | export class RowDragFeature implements DropTarget {
|
17 |
|
18 | @Autowired('dragAndDropService') private dragAndDropService: DragAndDropService;
|
19 |
|
20 | @Autowired('rowModel') private rowModel: IRowModel;
|
21 | @Autowired('focusedCellController') private focusedCellController: FocusedCellController;
|
22 | @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
|
23 | @Optional('rangeController') private rangeController: IRangeController;
|
24 | @Autowired('eventService') private eventService: EventService;
|
25 |
|
26 | private gridPanel: GridPanel;
|
27 |
|
28 | private clientSideRowModel: ClientSideRowModel;
|
29 |
|
30 | private eContainer: HTMLElement;
|
31 |
|
32 | private needToMoveUp: boolean;
|
33 | private needToMoveDown: boolean;
|
34 |
|
35 | private movingIntervalId: number;
|
36 | private intervalCount: number;
|
37 |
|
38 | private lastDraggingEvent: DraggingEvent;
|
39 |
|
40 | constructor(eContainer: HTMLElement, gridPanel: GridPanel) {
|
41 | this.eContainer = eContainer;
|
42 | this.gridPanel = gridPanel;
|
43 | }
|
44 |
|
45 | @PostConstruct
|
46 | private postConstruct(): void {
|
47 | if (this.gridOptionsWrapper.isRowModelDefault()) {
|
48 | this.clientSideRowModel = <ClientSideRowModel> this.rowModel;
|
49 | }
|
50 | }
|
51 |
|
52 | public getContainer(): HTMLElement {
|
53 | return this.eContainer;
|
54 | }
|
55 |
|
56 | public isInterestedIn(type: DragSourceType): boolean {
|
57 | return type===DragSourceType.RowDrag;
|
58 | }
|
59 |
|
60 | public getIconName(): string {
|
61 | return DragAndDropService.ICON_MOVE;
|
62 | }
|
63 |
|
64 | public onDragEnter(draggingEvent: DraggingEvent): void {
|
65 |
|
66 |
|
67 | this.dispatchEvent(Events.EVENT_ROW_DRAG_ENTER, draggingEvent);
|
68 | this.dragAndDropService.setGhostIcon(DragAndDropService.ICON_MOVE);
|
69 | draggingEvent.dragItem.rowNode.setDragging(true);
|
70 | this.onEnterOrDragging(draggingEvent);
|
71 | }
|
72 |
|
73 | public onDragging(draggingEvent: DraggingEvent): void {
|
74 | this.onEnterOrDragging(draggingEvent);
|
75 | }
|
76 |
|
77 | private onEnterOrDragging(draggingEvent: DraggingEvent): void {
|
78 |
|
79 | this.dispatchEvent(Events.EVENT_ROW_DRAG_MOVE, draggingEvent);
|
80 |
|
81 | this.lastDraggingEvent = draggingEvent;
|
82 | let pixel = this.normaliseForScroll(draggingEvent.y);
|
83 |
|
84 | let managedDrag = this.gridOptionsWrapper.isRowDragManaged();
|
85 | if (managedDrag) {
|
86 | this.doManagedDrag(draggingEvent, pixel);
|
87 | }
|
88 |
|
89 | this.checkCenterForScrolling(pixel);
|
90 | }
|
91 |
|
92 | private doManagedDrag(draggingEvent: DraggingEvent, pixel: number): void {
|
93 | let rowNode = draggingEvent.dragItem.rowNode;
|
94 | let rowWasMoved = this.clientSideRowModel.ensureRowAtPixel(rowNode, pixel);
|
95 |
|
96 | if (rowWasMoved) {
|
97 | this.focusedCellController.clearFocusedCell();
|
98 | if (this.rangeController) {
|
99 | this.rangeController.clearSelection();
|
100 | }
|
101 | }
|
102 | }
|
103 |
|
104 | private normaliseForScroll(pixel: number): number {
|
105 | let gridPanelHasScrolls = !this.gridOptionsWrapper.isGridAutoHeight();
|
106 | if (gridPanelHasScrolls) {
|
107 | let pixelRange = this.gridPanel.getVScrollPosition();
|
108 | return pixel + pixelRange.top;
|
109 | } else {
|
110 | return pixel;
|
111 | }
|
112 | }
|
113 |
|
114 | private checkCenterForScrolling(pixel: number): void {
|
115 |
|
116 |
|
117 | let pixelRange = this.gridPanel.getVScrollPosition();
|
118 |
|
119 |
|
120 |
|
121 | this.needToMoveUp = pixel < (pixelRange.top + 50);
|
122 | this.needToMoveDown = pixel > (pixelRange.bottom - 50);
|
123 |
|
124 |
|
125 |
|
126 |
|
127 | if (this.needToMoveUp || this.needToMoveDown) {
|
128 | this.ensureIntervalStarted();
|
129 | } else {
|
130 | this.ensureIntervalCleared();
|
131 | }
|
132 | }
|
133 |
|
134 | private ensureIntervalStarted(): void {
|
135 | if (!this.movingIntervalId) {
|
136 | this.intervalCount = 0;
|
137 | this.movingIntervalId = setInterval(this.moveInterval.bind(this), 100);
|
138 | }
|
139 | }
|
140 |
|
141 | private ensureIntervalCleared(): void {
|
142 | if (this.moveInterval) {
|
143 | clearInterval(this.movingIntervalId);
|
144 | this.movingIntervalId = null;
|
145 | }
|
146 | }
|
147 |
|
148 | private moveInterval(): void {
|
149 |
|
150 |
|
151 | let pixelsToMove: number;
|
152 | this.intervalCount++;
|
153 | pixelsToMove = 10 + (this.intervalCount * 5);
|
154 | if (pixelsToMove > 100) {
|
155 | pixelsToMove = 100;
|
156 | }
|
157 |
|
158 | let pixelsMoved: number;
|
159 | if (this.needToMoveDown) {
|
160 | pixelsMoved = this.gridPanel.scrollVertically(pixelsToMove);
|
161 | } else if (this.needToMoveUp) {
|
162 | pixelsMoved = this.gridPanel.scrollVertically(-pixelsToMove);
|
163 | }
|
164 |
|
165 | if (pixelsMoved !== 0) {
|
166 | this.onDragging(this.lastDraggingEvent);
|
167 | }
|
168 | }
|
169 |
|
170 |
|
171 |
|
172 |
|
173 | public dispatchEvent(type: string, draggingEvent: DraggingEvent): void {
|
174 |
|
175 | let yNormalised = this.normaliseForScroll(draggingEvent.y);
|
176 |
|
177 | let overIndex = -1;
|
178 | let overNode = null;
|
179 | let mouseIsPastLastRow = yNormalised > this.rowModel.getCurrentPageHeight();
|
180 |
|
181 | if (!mouseIsPastLastRow) {
|
182 | overIndex = this.rowModel.getRowIndexAtPixel(yNormalised);
|
183 | overNode = this.rowModel.getRow(overIndex);
|
184 | }
|
185 |
|
186 | let vDirectionString: string;
|
187 | switch (draggingEvent.vDirection) {
|
188 | case VDirection.Down:
|
189 | vDirectionString = 'down';
|
190 | break;
|
191 | case VDirection.Up:
|
192 | vDirectionString = 'up';
|
193 | break;
|
194 | default:
|
195 | vDirectionString = null;
|
196 | break;
|
197 | }
|
198 |
|
199 | let event: RowDragEvent = {
|
200 | type: type,
|
201 | api: this.gridOptionsWrapper.getApi(),
|
202 | columnApi: this.gridOptionsWrapper.getColumnApi(),
|
203 | event: draggingEvent.event,
|
204 | node: draggingEvent.dragItem.rowNode,
|
205 | overIndex: overIndex,
|
206 | overNode: overNode,
|
207 | y: yNormalised,
|
208 | vDirection: vDirectionString
|
209 | };
|
210 |
|
211 | this.eventService.dispatchEvent(event);
|
212 | }
|
213 |
|
214 | public onDragLeave(draggingEvent: DraggingEvent): void {
|
215 | this.dispatchEvent(Events.EVENT_ROW_DRAG_LEAVE, draggingEvent);
|
216 | this.stopDragging(draggingEvent);
|
217 | }
|
218 |
|
219 | public onDragStop(draggingEvent: DraggingEvent): void {
|
220 | this.dispatchEvent(Events.EVENT_ROW_DRAG_END, draggingEvent);
|
221 | this.stopDragging(draggingEvent);
|
222 | }
|
223 |
|
224 | private stopDragging(draggingEvent: DraggingEvent): void {
|
225 | this.ensureIntervalCleared();
|
226 | draggingEvent.dragItem.rowNode.setDragging(false);
|
227 | }
|
228 | } |
\ | No newline at end of file |