blob: 780ad14622f9e95ee79995e298adaa5503f9d9c8 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Paul Lewis9950e182019-12-16 16:06:074
Paul Lewis17e384e2020-01-08 15:46:515import * as Common from '../common/common.js';
Paul Lewis9950e182019-12-16 16:06:076import {elementDragStart} from './UIUtils.js';
7
Blink Reformat4c46d092018-04-07 15:32:378/**
9 * @unrestricted
10 */
Paul Lewis17e384e2020-01-08 15:46:5111export class ResizerWidget extends Common.ObjectWrapper.ObjectWrapper {
Blink Reformat4c46d092018-04-07 15:32:3712 constructor() {
13 super();
14
15 this._isEnabled = true;
Simon Zünd5bbcd5c2020-03-02 09:09:2116 /** @type {!Set<!Element>} */
17 this._elements = new Set();
Blink Reformat4c46d092018-04-07 15:32:3718 this._installDragOnMouseDownBound = this._installDragOnMouseDown.bind(this);
19 this._cursor = 'nwse-resize';
20 }
21
22 /**
23 * @return {boolean}
24 */
25 isEnabled() {
26 return this._isEnabled;
27 }
28
29 /**
30 * @param {boolean} enabled
31 */
32 setEnabled(enabled) {
33 this._isEnabled = enabled;
34 this.updateElementCursors();
35 }
36
37 /**
38 * @return {!Array.<!Element>}
39 */
40 elements() {
Simon Zünd5bbcd5c2020-03-02 09:09:2141 return [...this._elements];
Blink Reformat4c46d092018-04-07 15:32:3742 }
43
44 /**
45 * @param {!Element} element
46 */
47 addElement(element) {
Simon Zünd5bbcd5c2020-03-02 09:09:2148 if (!this._elements.has(element)) {
49 this._elements.add(element);
50 element.addEventListener('mousedown', this._installDragOnMouseDownBound, false);
51 this._updateElementCursor(element);
Tim van der Lippe1d6e57a2019-09-30 11:55:3452 }
Blink Reformat4c46d092018-04-07 15:32:3753 }
54
55 /**
56 * @param {!Element} element
57 */
58 removeElement(element) {
Simon Zünd5bbcd5c2020-03-02 09:09:2159 if (this._elements.has(element)) {
60 this._elements.delete(element);
61 element.removeEventListener('mousedown', this._installDragOnMouseDownBound, false);
62 element.style.removeProperty('cursor');
Tim van der Lippe1d6e57a2019-09-30 11:55:3463 }
Blink Reformat4c46d092018-04-07 15:32:3764 }
65
66 updateElementCursors() {
67 this._elements.forEach(this._updateElementCursor.bind(this));
68 }
69
70 /**
71 * @param {!Element} element
72 */
73 _updateElementCursor(element) {
Tim van der Lippe1d6e57a2019-09-30 11:55:3474 if (this._isEnabled) {
Blink Reformat4c46d092018-04-07 15:32:3775 element.style.setProperty('cursor', this.cursor());
Tim van der Lippe1d6e57a2019-09-30 11:55:3476 } else {
Blink Reformat4c46d092018-04-07 15:32:3777 element.style.removeProperty('cursor');
Tim van der Lippe1d6e57a2019-09-30 11:55:3478 }
Blink Reformat4c46d092018-04-07 15:32:3779 }
80
81 /**
82 * @return {string}
83 */
84 cursor() {
85 return this._cursor;
86 }
87
88 /**
89 * @param {string} cursor
90 */
91 setCursor(cursor) {
92 this._cursor = cursor;
93 this.updateElementCursors();
94 }
95
96 /**
97 * @param {!Event} event
98 */
99 _installDragOnMouseDown(event) {
Simon Zünd5bbcd5c2020-03-02 09:09:21100 const element = /** @type {!Element} */ (event.target);
Blink Reformat4c46d092018-04-07 15:32:37101 // Only handle drags of the nodes specified.
Simon Zünd5bbcd5c2020-03-02 09:09:21102 if (!this._elements.has(element)) {
Blink Reformat4c46d092018-04-07 15:32:37103 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34104 }
Paul Lewis9950e182019-12-16 16:06:07105 elementDragStart(
Simon Zünd5bbcd5c2020-03-02 09:09:21106 element, this._dragStart.bind(this), this._drag.bind(this), this._dragEnd.bind(this), this.cursor(), event);
Blink Reformat4c46d092018-04-07 15:32:37107 }
108
109 /**
110 * @param {!MouseEvent} event
111 * @return {boolean}
112 */
113 _dragStart(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34114 if (!this._isEnabled) {
Blink Reformat4c46d092018-04-07 15:32:37115 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34116 }
Blink Reformat4c46d092018-04-07 15:32:37117 this._startX = event.pageX;
118 this._startY = event.pageY;
119 this.sendDragStart(this._startX, this._startY);
120 return true;
121 }
122
123 /**
124 * @param {number} x
125 * @param {number} y
126 */
127 sendDragStart(x, y) {
Tim van der Lippe0830b3d2019-10-03 13:20:07128 this.dispatchEventToListeners(Events.ResizeStart, {startX: x, currentX: x, startY: y, currentY: y});
Blink Reformat4c46d092018-04-07 15:32:37129 }
130
131 /**
132 * @param {!MouseEvent} event
133 * @return {boolean}
134 */
135 _drag(event) {
136 if (!this._isEnabled) {
137 this._dragEnd(event);
138 return true; // Cancel drag.
139 }
140
141 this.sendDragMove(this._startX, event.pageX, this._startY, event.pageY, event.shiftKey);
142 event.preventDefault();
143 return false; // Continue drag.
144 }
145
146 /**
147 * @param {number} startX
148 * @param {number} currentX
149 * @param {number} startY
150 * @param {number} currentY
151 * @param {boolean} shiftKey
152 */
153 sendDragMove(startX, currentX, startY, currentY, shiftKey) {
154 this.dispatchEventToListeners(
Tim van der Lippe0830b3d2019-10-03 13:20:07155 Events.ResizeUpdate,
Blink Reformat4c46d092018-04-07 15:32:37156 {startX: startX, currentX: currentX, startY: startY, currentY: currentY, shiftKey: shiftKey});
157 }
158
159 /**
160 * @param {!MouseEvent} event
161 */
162 _dragEnd(event) {
Tim van der Lippe0830b3d2019-10-03 13:20:07163 this.dispatchEventToListeners(Events.ResizeEnd);
Blink Reformat4c46d092018-04-07 15:32:37164 delete this._startX;
165 delete this._startY;
166 }
Tim van der Lippe0830b3d2019-10-03 13:20:07167}
Blink Reformat4c46d092018-04-07 15:32:37168
169/** @enum {symbol} */
Tim van der Lippe0830b3d2019-10-03 13:20:07170export const Events = {
Blink Reformat4c46d092018-04-07 15:32:37171 ResizeStart: Symbol('ResizeStart'),
172 ResizeUpdate: Symbol('ResizeUpdate'),
173 ResizeEnd: Symbol('ResizeEnd')
174};
175
176/**
177 * @unrestricted
178 */
Tim van der Lippe0830b3d2019-10-03 13:20:07179export class SimpleResizerWidget extends ResizerWidget {
Blink Reformat4c46d092018-04-07 15:32:37180 constructor() {
181 super();
182 this._isVertical = true;
183 }
184
185 /**
186 * @return {boolean}
187 */
188 isVertical() {
189 return this._isVertical;
190 }
191
192 /**
193 * Vertical widget resizes height (along y-axis).
194 * @param {boolean} vertical
195 */
196 setVertical(vertical) {
197 this._isVertical = vertical;
198 this.updateElementCursors();
199 }
200
201 /**
202 * @override
203 * @return {string}
204 */
205 cursor() {
206 return this._isVertical ? 'ns-resize' : 'ew-resize';
207 }
208
209 /**
210 * @override
211 * @param {number} x
212 * @param {number} y
213 */
214 sendDragStart(x, y) {
215 const position = this._isVertical ? y : x;
Tim van der Lippe0830b3d2019-10-03 13:20:07216 this.dispatchEventToListeners(Events.ResizeStart, {startPosition: position, currentPosition: position});
Blink Reformat4c46d092018-04-07 15:32:37217 }
218
219 /**
220 * @override
221 * @param {number} startX
222 * @param {number} currentX
223 * @param {number} startY
224 * @param {number} currentY
225 * @param {boolean} shiftKey
226 */
227 sendDragMove(startX, currentX, startY, currentY, shiftKey) {
228 if (this._isVertical) {
229 this.dispatchEventToListeners(
Tim van der Lippe0830b3d2019-10-03 13:20:07230 Events.ResizeUpdate, {startPosition: startY, currentPosition: currentY, shiftKey: shiftKey});
Blink Reformat4c46d092018-04-07 15:32:37231 } else {
232 this.dispatchEventToListeners(
Tim van der Lippe0830b3d2019-10-03 13:20:07233 Events.ResizeUpdate, {startPosition: startX, currentPosition: currentX, shiftKey: shiftKey});
Blink Reformat4c46d092018-04-07 15:32:37234 }
235 }
Tim van der Lippe0830b3d2019-10-03 13:20:07236}