author | Edouard Tisserant |
Thu, 27 Aug 2020 14:34:48 +0200 | |
branch | svghmi |
changeset 3044 | 5227415929be |
parent 3042 | ed43facc7137 |
child 3047 | c113904f0e62 |
permissions | -rw-r--r-- |
2908 | 1 |
// widget_keypad.ysl2 |
2 |
||
2943
304e88bae115
SVGHMI: added more meaningful namespaces to emit javascript code from.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2941
diff
changeset
|
3 |
emit "declarations:keypad" { |
2941
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
4 |
| |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
5 |
| var keypads = { |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
6 |
foreach "$keypads_descs"{ |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
7 |
const "keypad_id","@id"; |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
8 |
foreach "arg"{ |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
9 |
const "g", "$geometry[@Id = $keypad_id]"; |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
10 |
| "«@value»":["«$keypad_id»", «$g/@x», «$g/@y»], |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
11 |
} |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
12 |
} |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
13 |
| } |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
14 |
} |
ef13a4007538
SVGHMI: spread JS code from svghmi/scripts.ysl2 in other .ysl2 files, using dedicated preamble and epilogue namespaces
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2920
diff
changeset
|
15 |
|
3010 | 16 |
template "widget[@type='Keypad']", mode="widget_class" |
17 |
|| |
|
18 |
class KeypadWidget extends Widget{ |
|
19 |
moving = undefined; |
|
20 |
enTimer = undefined; |
|
21 |
offset = undefined; |
|
22 |
||
23 |
on_position_click(evt) { |
|
24 |
this.moving = true; |
|
25 |
this.enTimer = true; |
|
26 |
||
27 |
// get click position offset from widget x,y and save it to variable |
|
28 |
var keypad_borders = this.position_elt.getBoundingClientRect(); |
|
29 |
var clickX = undefined; |
|
30 |
var clickY = undefined; |
|
31 |
if (evt.type == "touchstart"){ |
|
32 |
clickX = Math.ceil(evt.touches[0].clientX); |
|
33 |
clickY = Math.ceil(evt.touches[0].clientY); |
|
34 |
} |
|
35 |
else{ |
|
36 |
clickX = evt.pageX; |
|
37 |
clickY = evt.pageY; |
|
38 |
} |
|
39 |
this.offset=[clickX-keypad_borders.left,clickY-keypad_borders.top] |
|
40 |
} |
|
41 |
||
42 |
off_position_click(evt) { |
|
43 |
if(this.moving) |
|
44 |
this.moving = false; |
|
45 |
} |
|
46 |
||
47 |
on_move(evt) { |
|
48 |
if(this.moving && this.enTimer){ |
|
49 |
//get keyboard pos in html |
|
50 |
let [eltid, tmpgrp] = current_modal; |
|
51 |
let [xcoord,ycoord] = this.coordinates; |
|
52 |
let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox; |
|
53 |
||
54 |
//get mouse coordinates |
|
55 |
var clickX = undefined; |
|
56 |
var clickY = undefined; |
|
57 |
if (evt.type == "touchmove"){ |
|
58 |
clickX = Math.ceil(evt.touches[0].clientX); |
|
59 |
clickY = Math.ceil(evt.touches[0].clientY); |
|
60 |
} |
|
61 |
else{ |
|
62 |
clickX = evt.pageX; |
|
63 |
clickY = evt.pageY; |
|
64 |
} |
|
65 |
||
66 |
//translate keyboard position |
|
67 |
let mouseX = ((clickX-this.offset[0])/window.innerWidth)*svgWidth; |
|
68 |
let mouseY = ((clickY-this.offset[1])/window.innerHeight)*svgHeight; |
|
69 |
tmpgrp.setAttribute("transform","translate("+String(xdest-xcoord+mouseX)+","+String(ydest-ycoord+mouseY)+")"); |
|
70 |
||
71 |
//reset timer |
|
72 |
this.enTimer = false; |
|
73 |
setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100); |
|
74 |
} |
|
75 |
||
76 |
} |
|
77 |
||
78 |
on_key_click(symbols) { |
|
79 |
var syms = symbols.split(" "); |
|
80 |
this.shift |= this.caps; |
|
81 |
this.editstr += syms[this.shift?syms.length-1:0]; |
|
82 |
this.shift = false; |
|
83 |
this.update(); |
|
84 |
} |
|
85 |
||
86 |
on_Esc_click() { |
|
87 |
end_modal.call(this); |
|
88 |
} |
|
89 |
||
90 |
on_Enter_click() { |
|
3033
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
91 |
let coercedval = (typeof this.initial) == "number" ? Number(this.editstr) : this.editstr; |
3042
ed43facc7137
SVGHMI: Fix keypad : non-number input was always considered invalid because of missing type checking.
Edouard Tisserant
parents:
3033
diff
changeset
|
92 |
if(typeof coercedval == 'number' && isNaN(coercedval)){ |
ed43facc7137
SVGHMI: Fix keypad : non-number input was always considered invalid because of missing type checking.
Edouard Tisserant
parents:
3033
diff
changeset
|
93 |
// revert to initial so it explicitely shows input was ignored |
3033
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
94 |
this.editstr = String(this.initial); |
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
95 |
this.update(); |
3042
ed43facc7137
SVGHMI: Fix keypad : non-number input was always considered invalid because of missing type checking.
Edouard Tisserant
parents:
3033
diff
changeset
|
96 |
} else { |
3033
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
97 |
let callback_obj = this.result_callback_obj; |
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
98 |
end_modal.call(this); |
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
99 |
callback_obj.edit_callback(coercedval); |
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
100 |
} |
3010 | 101 |
} |
102 |
||
103 |
on_BackSpace_click() { |
|
104 |
this.editstr = this.editstr.slice(0,this.editstr.length-1); |
|
105 |
this.update(); |
|
106 |
} |
|
107 |
||
108 |
on_Sign_click() { |
|
109 |
if(this.editstr[0] == "-") |
|
110 |
this.editstr = this.editstr.slice(1,this.editstr.length); |
|
111 |
else |
|
112 |
this.editstr = "-" + this.editstr; |
|
113 |
this.update(); |
|
114 |
} |
|
115 |
||
116 |
on_NumDot_click() { |
|
117 |
if(this.editstr.indexOf(".") == "-1"){ |
|
118 |
this.editstr += "."; |
|
119 |
this.update(); |
|
120 |
} |
|
121 |
} |
|
122 |
||
123 |
on_Space_click() { |
|
124 |
this.editstr += " "; |
|
125 |
this.update(); |
|
126 |
} |
|
127 |
||
128 |
caps = false; |
|
129 |
_caps = undefined; |
|
130 |
on_CapsLock_click() { |
|
131 |
this.caps = !this.caps; |
|
132 |
this.update(); |
|
133 |
} |
|
134 |
||
135 |
shift = false; |
|
136 |
_shift = undefined; |
|
137 |
on_Shift_click() { |
|
138 |
this.shift = !this.shift; |
|
139 |
this.caps = false; |
|
140 |
this.update(); |
|
141 |
} |
|
142 |
editstr = ""; |
|
143 |
_editstr = undefined; |
|
144 |
result_callback_obj = undefined; |
|
145 |
start_edit(info, valuetype, callback_obj, initial,size) { |
|
146 |
show_modal.call(this,size); |
|
3033
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
147 |
this.editstr = String(initial); |
3010 | 148 |
this.result_callback_obj = callback_obj; |
149 |
this.Info_elt.textContent = info; |
|
150 |
this.shift = false; |
|
151 |
this.caps = false; |
|
3033
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
152 |
this.initial = initial; |
52f6548982d4
SVGHMI: Keypad is now keeping Javascript type constency. In other words, if a number was given as initial value, input value will have to convert to number in order to be valid. In case invalid value is entered, initial value is restored.
Edouard Tisserant
parents:
3010
diff
changeset
|
153 |
|
3010 | 154 |
this.update(); |
155 |
} |
|
156 |
||
157 |
update() { |
|
158 |
if(this.editstr != this._editstr){ |
|
159 |
this._editstr = this.editstr; |
|
160 |
this.Value_elt.textContent = this.editstr; |
|
161 |
} |
|
162 |
if(this.shift != this._shift){ |
|
163 |
this._shift = this.shift; |
|
164 |
(this.shift?widget_active_activable:widget_inactive_activable)(this.Shift_sub); |
|
165 |
} |
|
166 |
if(this.caps != this._caps){ |
|
167 |
this._caps = this.caps; |
|
168 |
(this.caps?widget_active_activable:widget_inactive_activable)(this.CapsLock_sub); |
|
169 |
} |
|
170 |
} |
|
171 |
} |
|
172 |
|| |
|
173 |
||
2908 | 174 |
template "widget[@type='Keypad']", mode="widget_defs" { |
2917
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
175 |
param "hmi_element"; |
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
176 |
labels("Esc Enter BackSpace Keys Info Value"); |
3010 | 177 |
optional_labels("Sign Space NumDot position"); |
2920
3ee337c8c769
SVGHMI: finished shift and capslock support n keypad widget. Added a helper in widgets_common to collect subelements likle active/inactive/disabled...
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2919
diff
changeset
|
178 |
activable_labels("CapsLock Shift"); |
2911
211d6a185e31
SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents:
2908
diff
changeset
|
179 |
| init: function() { |
2917
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
180 |
foreach "$hmi_element/*[@inkscape:label = 'Keys']/*" { |
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
181 |
| id("«@id»").setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_key_click('«func:escape_quotes(@inkscape:label)»')"); |
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
182 |
} |
2920
3ee337c8c769
SVGHMI: finished shift and capslock support n keypad widget. Added a helper in widgets_common to collect subelements likle active/inactive/disabled...
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
2919
diff
changeset
|
183 |
foreach "str:split('Esc Enter BackSpace Sign Space NumDot CapsLock Shift')" { |
2917
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
184 |
| if(this.«.»_elt) |
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
185 |
| this.«.»_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_«.»_click()"); |
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
186 |
} |
3010 | 187 |
| if(this.position_elt){ |
188 |
| this.position_elt.setAttribute("onmousedown", "hmi_widgets['"+this.element_id+"'].on_position_click(evt)"); |
|
189 |
| this.position_elt.setAttribute("ontouchstart", "hmi_widgets['"+this.element_id+"'].on_position_click(evt)"); |
|
190 |
||
191 |
| window.addEventListener("mouseup", hmi_widgets[this.element_id].off_position_click.bind(this)); |
|
192 |
| window.addEventListener("touchend", hmi_widgets[this.element_id].off_position_click.bind(this)); |
|
193 |
| window.addEventListener("touchcancel", hmi_widgets[this.element_id].off_position_click.bind(this)); |
|
194 |
||
195 |
| window.addEventListener("mousemove", hmi_widgets[this.element_id].on_move.bind(this)); |
|
196 |
| window.addEventListener("touchmove", hmi_widgets[this.element_id].on_move.bind(this)); |
|
197 |
| } |
|
2917
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
198 |
| }, |
3010 | 199 |
| |
2917
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
200 |
const "g", "$geometry[@Id = $hmi_element/@id]"; |
c8d923dd707f
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents:
2911
diff
changeset
|
201 |
| coordinates: [«$g/@x», «$g/@y»], |
2908 | 202 |
} |