1 | /* |
2 | Copyright - 2017 2023 - wwwouaiebe - Contact: https://www.ouaie.be/ |
3 | |
4 | This program is free software; |
5 | you can redistribute it and/or modify it under the terms of the |
6 | GNU General Public License as published by the Free Software Foundation; |
7 | either version 3 of the License, or any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | /* |
19 | Changes: |
20 | - v4.0.0: |
21 | - created from v3.6.0 |
22 | Doc reviewed 202208 |
23 | */ |
24 | |
25 | import ObjId from '../../data/ObjId.js'; |
26 | import theDevice from '../../core/lib/Device.js'; |
27 | import { ZERO, TWO, DIALOG_DRAG_MARGIN, DIALOG_MAX_WIDTH } from '../../main/Constants.js'; |
28 | import theConfig from '../../data/Config.js'; |
29 | |
30 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
31 | /** |
32 | This class store the dialog position and expose methods to move the dialog |
33 | */ |
34 | /* ------------------------------------------------------------------------------------------------------------------------- */ |
35 | |
36 | class BaseDialogMover { |
37 | |
38 | /** |
39 | A unique identifier given to the mover for drag and drop operations |
40 | @type {Number} |
41 | */ |
42 | |
43 | #objId; |
44 | |
45 | /** |
46 | The start drag X screen coordinate of the mouse |
47 | @type {Number} |
48 | */ |
49 | |
50 | #dragStartX; |
51 | |
52 | /** The start drag Y screen coordinate of the mouse |
53 | @type {Number} |
54 | */ |
55 | |
56 | #dragStartY; |
57 | |
58 | /** |
59 | The X screen coordinate of the upper left corner of the dialog |
60 | @type {Number} |
61 | */ |
62 | |
63 | #dialogX; |
64 | |
65 | /** |
66 | The Y screen coordinate of the upper left corner of the dialog |
67 | @type {Number} |
68 | */ |
69 | |
70 | #dialogY; |
71 | |
72 | /** |
73 | Compute the new position of the dialog on the screen |
74 | @param {Number} newDialogX The new X position of the dialog in pixels |
75 | @param {Number} newDialogY The new Y position of the dialog in pixels |
76 | */ |
77 | |
78 | #computePosition ( newDialogX, newDialogY ) { |
79 | const screenAvailable = theDevice.screenAvailable; |
80 | const maxDialogX = |
81 | screenAvailable.width - this.dialogHTMLElement.offsetWidth - DIALOG_DRAG_MARGIN; |
82 | const maxDialogY = |
83 | screenAvailable.height - this.dialogHTMLElement.offsetHeight - DIALOG_DRAG_MARGIN; |
84 | this.#dialogX = Math.max ( Math.min ( newDialogX, maxDialogX ), DIALOG_DRAG_MARGIN ); |
85 | this.#dialogY = Math.max ( Math.min ( newDialogY, maxDialogY ), DIALOG_DRAG_MARGIN ); |
86 | } |
87 | |
88 | /** |
89 | Finish the move dialog. Adapt the style of the dialog |
90 | */ |
91 | |
92 | #endMoveDialog ( ) { |
93 | this.dialogHTMLElement.style.left = String ( this.#dialogX ) + 'px'; |
94 | this.dialogHTMLElement.style.top = String ( this.#dialogY ) + 'px'; |
95 | } |
96 | |
97 | /** |
98 | The container element of the dialog |
99 | @type {HTMLElement} |
100 | */ |
101 | |
102 | dialogHTMLElement = null; |
103 | |
104 | /** |
105 | The top bar element of the dialog |
106 | @type {HTMLElement} |
107 | */ |
108 | |
109 | topBarHTMLElement = null; |
110 | |
111 | /** |
112 | The constructor |
113 | */ |
114 | |
115 | constructor ( ) { |
116 | Object.seal ( this ); |
117 | this.#dialogX = DIALOG_DRAG_MARGIN; |
118 | this.#dialogY = DIALOG_DRAG_MARGIN; |
119 | this.#dragStartX = ZERO; |
120 | this.#dragStartY = ZERO; |
121 | this.#objId = ObjId.nextObjId; |
122 | } |
123 | |
124 | /** |
125 | A flag to detect if the dialog is on top of the screen |
126 | @type {boolean} |
127 | */ |
128 | |
129 | get onTop ( ) { return DIALOG_DRAG_MARGIN + TWO > this.#dialogY; } |
130 | |
131 | /** |
132 | A unique identifier given to the mover for drag and drop operations |
133 | @type {Number} |
134 | */ |
135 | |
136 | get objId ( ) { return this.#objId; } |
137 | |
138 | /** |
139 | Center the dialog o the screen |
140 | */ |
141 | |
142 | centerDialog ( ) { |
143 | const screenAvailable = theDevice.screenAvailable; |
144 | this.dialogHTMLElement.style [ 'max-height' ] = |
145 | String ( screenAvailable.height - ( TWO * DIALOG_DRAG_MARGIN ) ) + 'px'; |
146 | this.dialogHTMLElement.style [ 'max-width' ] = |
147 | String ( Math.min ( screenAvailable.width - ( TWO * DIALOG_DRAG_MARGIN ), DIALOG_MAX_WIDTH ) ) + 'px'; |
148 | this.#dialogX = ( screenAvailable.width - this.dialogHTMLElement.clientWidth ) / TWO; |
149 | if ( theConfig.baseDialog.touchTopScreen && theDevice.isTouch ) { |
150 | this.#dialogY = DIALOG_DRAG_MARGIN; |
151 | } |
152 | else { |
153 | this.#dialogY = ( screenAvailable.height - this.dialogHTMLElement.clientHeight ) / TWO; |
154 | } |
155 | this.#endMoveDialog ( ); |
156 | } |
157 | |
158 | /** |
159 | Move the dialog to a drag event point and set the drag start values to this point |
160 | @param {Event|Touch} dragEventOrTouch The drag event or Touch with the drag start values |
161 | @param {?String} eventType The type of the event that have triggered the call to the method |
162 | */ |
163 | |
164 | moveDialog ( dragEventOrTouch, eventType ) { |
165 | const newDialogX = this.#dialogX + dragEventOrTouch.screenX - this.#dragStartX; |
166 | const newDialogY = this.#dialogY + dragEventOrTouch.screenY - this.#dragStartY; |
167 | this.moveDialogTo ( newDialogX, newDialogY, eventType ); |
168 | this.setDragStartPoint ( dragEventOrTouch ); |
169 | } |
170 | |
171 | /** |
172 | Move the dialog on the screen |
173 | @param {Number} newDialogX The new X position of the dialog in pixels |
174 | @param {Number} newDialogY The new Y position of the dialog in pixels |
175 | */ |
176 | |
177 | moveDialogTo ( newDialogX, newDialogY ) { |
178 | this.#computePosition ( newDialogX, newDialogY ); |
179 | this.#endMoveDialog ( ); |
180 | } |
181 | |
182 | /** |
183 | Move the dialog to it's last position after a hide followed by a show |
184 | */ |
185 | |
186 | moveDialogToLastPosition ( ) { |
187 | this.moveDialogTo ( this.#dialogX, this.#dialogY ); |
188 | } |
189 | |
190 | /** |
191 | Move the dialog to the top left corner of the screen |
192 | */ |
193 | |
194 | moveDialogToTopLeft ( ) { |
195 | this.#dialogX = DIALOG_DRAG_MARGIN; |
196 | this.#dialogY = DIALOG_DRAG_MARGIN; |
197 | this.#endMoveDialog ( ); |
198 | } |
199 | |
200 | /** |
201 | Set the drag start values |
202 | @param {Event|Touch} dragEventOrTouch The drag event or Touch with the drag start values |
203 | */ |
204 | |
205 | setDragStartPoint ( dragEventOrTouch ) { |
206 | this.#dragStartX = dragEventOrTouch.screenX; |
207 | this.#dragStartY = dragEventOrTouch.screenY; |
208 | } |
209 | } |
210 | |
211 | export default BaseDialogMover; |
212 | |
213 | /* --- End of file --------------------------------------------------------------------------------------------------------- */ |
214 |