File : dialogs/profileDialog/ProfileDialog.js

1
/*
2
Copyright - 2020 - wwwouaiebe - Contact: http//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 theTranslator from '../../core/uiLib/Translator.js';
26
import ObjId from '../../data/ObjId.js';
27
import NonModalBaseDialog from '../baseDialog/NonModalBaseDialog.js';
28
import theHTMLElementsFactory from '../../core/uiLib/HTMLElementsFactory.js';
29
import theEventDispatcher from '../../core/lib/EventDispatcher.js';
30
import theUtilities from '../../core/uiLib/Utilities.js';
31
import SvgProfileBuilder from '../../core/lib/SvgProfileBuilder.js';
32
import SvgContextMenuEL from './SvgContextMenuEL.js';
33
import SvgMouseLeaveEL from './SvgMouseLeaveEL.js';
34
import SvgMouseMoveEL from './SvgMouseMoveEL.js';
35
import { ZERO } from '../../main/Constants.js';
36
37
/* ------------------------------------------------------------------------------------------------------------------------- */
38
/**
39
a float window containing a route profile
40
*/
41
/* ------------------------------------------------------------------------------------------------------------------------- */
42
43
class ProfileDialog extends NonModalBaseDialog {
44
45
    /**
46
    The svg profile
47
    @type {SVGElement}
48
    */
49
50
    #svg = null;
51
52
    /**
53
    The svg div
54
    @type {HTMLElement}
55
    */
56
57
    #svgDiv;
58
59
    /**
60
    A div under the svg profile with ascent, descent and distance
61
    @type {HTMLElement}
62
    */
63
64
    #ascentDiv;
65
66
    /**
67
    A div under the svg profile with the route name
68
    @type {HTMLElement}
69
    */
70
71
    #nameDiv;
72
73
    /**
74
    contextmenu event listener
75
    @type {SvgContextMenuEL}
76
    */
77
78
    #svgContextMenuEL = null;
79
80
    /**
81
    mousemove event listener
82
    @type {SvgMouseMoveEL}
83
    */
84
85
    #svgMouseMoveEL = null;
86
87
    /**
88
    mouseleave event listener
89
    @type {SvgMouseLeaveEL}
90
    */
91
92
    #svgMouseLeaveEL = null;
93
94
    /**
95
    An objId for the position marker
96
    @type {Number}
97
    */
98
99
    #markerObjId = ObjId.nextObjId;
100
101
    /**
102
    the displayed route objId
103
    @type {Number}
104
    */
105
106
    #routeObjId;
107
108
    /**
109
    remove all the content of the dialog and remove event listeners
110
    */
111
112
    #clean ( ) {
113
        if ( this.#svg ) {
114
            this.#svg.removeEventListener ( 'contextmenu', this.#svgContextMenuEL, false );
115
            this.#svg.removeEventListener ( 'mousemove', this.#svgMouseMoveEL, false );
116
            this.#svg.removeEventListener ( 'mouseleave', this.#svgMouseLeaveEL, false );
117
            this.#svgDiv.removeChild ( this.#svg );
118
            this.#svg = null;
119
            theEventDispatcher.dispatch ( 'removeobject', { objId : this.#markerObjId } );
120
            this.#nameDiv.textContent = '';
121
            this.#ascentDiv.textContent = '';
122
        }
123
    }
124
125
    /**
126
    Set the content of the dialog : heading, svg profile and ascent text
127
    @param {Route} route The route for witch the profile will be displayed
128
    */
129
130
    setContent ( route ) {
131
        this.#routeObjId = route.objId;
132
        this.#clean ( );
133
        this.#svg = new SvgProfileBuilder ( ).createSvg ( route );
134
        this.#svg.dataset.tanObjId = route.objId;
135
        this.#svg.dataset.tanMarkerObjId = this.#markerObjId;
136
        this.#svg.addEventListener ( 'contextmenu', this.#svgContextMenuEL, false );
137
        this.#svg.addEventListener ( 'mousemove', this.#svgMouseMoveEL, false );
138
        this.#svg.addEventListener ( 'mouseleave', this.#svgMouseLeaveEL, false );
139
        this.#svgDiv.appendChild ( this.#svg );
140
        this.setContentName ( route );
141
    }
142
143
    /**
144
    This method update the profile name. Also called when the user changes the route name with the RoutePropertiesDialog
145
    or when a waypoint is updated with the geocoder
146
    @param {Route} route The route for witch the profile is displayed
147
    */
148
149
    setContentName ( route ) {
150
        this.#nameDiv.textContent = theTranslator.getText (
151
            'ProfileWindow - Route {name}',
152
            {
153
                name : route.computedName
154
            }
155
        );
156
        this.#ascentDiv.textContent = theTranslator.getText (
157
            'ProfileWindow - Ascent: {ascent} m. - Descent: {descent} m. - Distance: {distance}',
158
            {
159
                ascent : route.itinerary.ascent.toFixed ( ZERO ),
160
                descent : route.itinerary.descent.toFixed ( ZERO ),
161
                distance : theUtilities.formatDistance ( route.distance )
162
            }
163
        );
164
    }
165
166
    /**
167
    The constructor
168
    */
169
170
    constructor ( ) {
171
        super ( );
172
        this.#svgContextMenuEL = new SvgContextMenuEL ( );
173
        this.#svgMouseMoveEL = new SvgMouseMoveEL ( );
174
        this.#svgMouseLeaveEL = new SvgMouseLeaveEL ( );
175
        this.#svgDiv = theHTMLElementsFactory.create ( 'div', { className : 'TravelNotes-ProfileDialog-SvgContainer' } );
176
        this.#nameDiv = theHTMLElementsFactory.create ( 'div', { className : 'TravelNotes-ProfileDialog-NameContainer' } );
177
        this.#ascentDiv = theHTMLElementsFactory.create ( 'div', { className : 'TravelNotes-ProfileDialog-AscentContainer' } );
178
    }
179
180
    /**
181
    Create all the controls needed for the dialog.
182
    Overload of the base class createContentHTML
183
    */
184
185
    createContentHTML ( ) {
186
    }
187
188
    /**
189
    Overload of the BaseDialog.onCancel ( ) method.
190
    */
191
192
    onCancel ( ) {
193
        this.#clean ( );
194
        super.onCancel ( );
195
        theEventDispatcher.dispatch (
196
            'profileclosed',
197
            {
198
                objId : this.#routeObjId
199
            }
200
        );
201
    }
202
203
    /**
204
    Show the dialog
205
    */
206
207
    show ( ) {
208
        super.show ( );
209
        this.mover.moveDialogToTopLeft ( );
210
    }
211
212
    /**
213
    An array with the HTMLElements that have to be added in the content of the dialog.
214
    Overload of the base class contentHTMLElements
215
    @type {Array.<HTMLElement>}
216
    */
217
218
    get contentHTMLElements ( ) {
219
        return [
220
            this.#svgDiv,
221
            this.#nameDiv,
222
            this.#ascentDiv
223
        ];
224
    }
225
226
    /**
227
    The title of the DialogControl. Overload of the base class get title
228
    @type {String}
229
    */
230
231
    get title ( ) { return theTranslator.getText ( 'ProfileWindow - Profile' ); }
232
}
233
234
export default ProfileDialog;
235
236
/* --- End of file --------------------------------------------------------------------------------------------------------- */
237