File : dialogs/baseDialog/BaseDialogMover.js

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