// widget_keypad.ysl2
emit "declarations:keypad" {
|
| var keypads = {
foreach "$keypads_descs"{
const "keypad_id","@id";
foreach "arg"{
const "g", "$geometry[@Id = $keypad_id]";
| "«@value»":["«$keypad_id»", «$g/@x», «$g/@y»],
}
}
| }
}
template "widget[@type='Keypad']", mode="widget_class"
||
class KeypadWidget extends Widget{
moving = undefined;
click = undefined;
offset = undefined;
on_position_click(evt) {
this.moving = true;
// chatch window events
window.addEventListener("touchmove", this.bound_on_drag, true);
window.addEventListener("mousemove", this.bound_on_drag, true);
window.addEventListener("mouseup", this.bound_on_release, true)
window.addEventListener("touchend", this.bound_on_release, true);
window.addEventListener("touchcancel", this.bound_on_release, true);
// get click position offset from widget x,y and save it to variable
var keypad_borders = this.position_elt.getBoundingClientRect();
var clickX = undefined;
var clickY = undefined;
if (evt.type == "touchstart"){
clickX = Math.ceil(evt.touches[0].clientX);
clickY = Math.ceil(evt.touches[0].clientY);
}
else{
clickX = evt.pageX;
clickY = evt.pageY;
}
this.offset=[clickX-keypad_borders.left,clickY-keypad_borders.top]
}
on_release(evt) {
//relase binds
window.removeEventListener("touchmove", this.bound_on_drag, true);
window.removeEventListener("mousemove", this.bound_on_drag, true);
window.removeEventListener("mouseup", this.bound_on_release, true)
window.removeEventListener("touchend", this.bound_on_release, true);
window.removeEventListener("touchcancel", this.bound_on_release, true);
if(this.moving)
this.moving = false;
}
on_drag(evt) {
if(this.moving)
//get mouse coordinates
var clickX = undefined;
var clickY = undefined;
if (evt.type == "touchmove"){
clickX = Math.ceil(evt.touches[0].clientX);
clickY = Math.ceil(evt.touches[0].clientY);
}
else{
clickX = evt.pageX;
clickY = evt.pageY;
}
this.click = [clickX,clickY]
//requeset redraw
this.request_animate();
}
animate(){
//get keyboard pos in html
let [eltid, tmpgrp] = current_modal;
let [xcoord,ycoord] = this.coordinates;
let [clickX,clickY] = this.click;
let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox;
//translate keyboard position
let mouseX = ((clickX-this.offset[0])/window.innerWidth)*svgWidth;
let mouseY = ((clickY-this.offset[1])/window.innerHeight)*svgHeight;
tmpgrp.setAttribute("transform","translate("+String(xdest-xcoord+mouseX)+","+String(ydest-ycoord+mouseY)+")");
}
on_key_click(symbols) {
var syms = symbols.split(" ");
this.shift |= this.caps;
this.editstr += syms[this.shift?syms.length-1:0];
this.shift = false;
this.update();
}
on_Esc_click() {
end_modal.call(this);
}
on_Enter_click() {
let coercedval = (typeof this.initial) == "number" ? Number(this.editstr) : this.editstr;
if(typeof coercedval == 'number' && isNaN(coercedval)){
// revert to initial so it explicitely shows input was ignored
this.editstr = String(this.initial);
this.update();
} else {
let callback_obj = this.result_callback_obj;
end_modal.call(this);
callback_obj.edit_callback(coercedval);
}
}
on_BackSpace_click() {
this.editstr = this.editstr.slice(0,this.editstr.length-1);
this.update();
}
on_Sign_click() {
if(this.editstr[0] == "-")
this.editstr = this.editstr.slice(1,this.editstr.length);
else
this.editstr = "-" + this.editstr;
this.update();
}
on_NumDot_click() {
if(this.editstr.indexOf(".") == "-1"){
this.editstr += ".";
this.update();
}
}
on_Space_click() {
this.editstr += " ";
this.update();
}
caps = false;
_caps = undefined;
on_CapsLock_click() {
this.caps = !this.caps;
this.update();
}
shift = false;
_shift = undefined;
on_Shift_click() {
this.shift = !this.shift;
this.caps = false;
this.update();
}
editstr = "";
_editstr = undefined;
result_callback_obj = undefined;
start_edit(info, valuetype, callback_obj, initial,size) {
show_modal.call(this,size);
this.editstr = String(initial);
this.result_callback_obj = callback_obj;
this.Info_elt.textContent = info;
this.shift = false;
this.caps = false;
this.initial = initial;
this.update();
}
update() {
if(this.editstr != this._editstr){
this._editstr = this.editstr;
this.Value_elt.textContent = this.editstr;
}
if(this.shift != this._shift){
this._shift = this.shift;
(this.shift?widget_active_activable:widget_inactive_activable)(this.Shift_sub);
}
if(this.caps != this._caps){
this._caps = this.caps;
(this.caps?widget_active_activable:widget_inactive_activable)(this.CapsLock_sub);
}
}
}
||
template "widget[@type='Keypad']", mode="widget_defs" {
param "hmi_element";
labels("Esc Enter BackSpace Keys Info Value");
optional_labels("Sign Space NumDot position");
activable_labels("CapsLock Shift");
| init: function() {
foreach "$hmi_element/*[@inkscape:label = 'Keys']/*" {
| id("«@id»").setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_key_click('«func:escape_quotes(@inkscape:label)»')");
}
foreach "str:split('Esc Enter BackSpace Sign Space NumDot CapsLock Shift')" {
| if(this.«.»_elt)
| this.«.»_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_«.»_click()");
}
| if(this.position_elt){
| this.bound_on_release = this.on_release.bind(this);
| this.bound_on_drag = this.on_drag.bind(this);
|
| this.position_elt.setAttribute("onmousedown", "hmi_widgets['"+this.element_id+"'].on_position_click(evt)");
| this.position_elt.setAttribute("ontouchstart", "hmi_widgets['"+this.element_id+"'].on_position_click(evt)");
| }
| },
|
const "g", "$geometry[@Id = $hmi_element/@id]";
| coordinates: [«$g/@x», «$g/@y»],
}