Changed keyboard to show on defined position.
* svghmi.js
added size paramter to edit_value
changed show_modal function to offset keyboard if paramter passed
*widget_input.ysl2
in on_edit_click:
function get position if key_pos element is defined in input widget
*widget_keypad.ysl2
Reworked keypad widget to extand class widget,
added support for changing keyboard position to user defined location
--- a/svghmi/svghmi.js Wed Aug 05 15:04:53 2020 +0200
+++ b/svghmi/svghmi.js Wed Aug 05 15:13:59 2020 +0200
@@ -395,26 +395,31 @@
var xmlns = "http://www.w3.org/2000/svg";
var edit_callback;
-function edit_value(path, valuetype, callback, initial) {
+function edit_value(path, valuetype, callback, initial, size) {
let [keypadid, xcoord, ycoord] = keypads[valuetype];
console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid);
edit_callback = callback;
let widget = hmi_widgets[keypadid];
- widget.start_edit(path, valuetype, callback, initial);
+ widget.start_edit(path, valuetype, callback, initial, size);
};
var current_modal; /* TODO stack ?*/
-function show_modal() {
+function show_modal(size) {
let [element, parent] = detachable_elements[this.element.id];
tmpgrp = document.createElementNS(xmlns,"g");
tmpgrpattr = document.createAttribute("transform");
-
let [xcoord,ycoord] = this.coordinates;
let [xdest,ydest] = page_desc[current_visible_page].bbox;
- tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
+ if (typeof size === 'undefined'){
+ tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
+ }
+ else{
+ tmpgrpattr.value = "translate("+String(xdest-xcoord+size.x)+","+String(ydest-ycoord+size.y)+")";
+ }
+
tmpgrp.setAttributeNode(tmpgrpattr);
tmpgrp.appendChild(element);
--- a/svghmi/widget_input.ysl2 Wed Aug 05 15:04:53 2020 +0200
+++ b/svghmi/widget_input.ysl2 Wed Aug 05 15:13:59 2020 +0200
@@ -2,6 +2,7 @@
template "widget[@type='Input']", mode="widget_defs" {
param "hmi_element";
+ optional_labels("key_pos");
const "value_elt" {
optional_labels("value");
}
@@ -33,7 +34,8 @@
// }
| },
| on_edit_click: function(opstr) {
- | edit_value("«path/@value»", "«path/@type»", this, this.last_val);
+ | var size = (typeof this.key_pos_elt !== 'undefined') ? this.key_pos_elt.getBBox() : undefined
+ | edit_value("«path/@value»", "«path/@type»", this, this.last_val,size);
| },
| edit_callback: function(new_val) {
--- a/svghmi/widget_keypad.ysl2 Wed Aug 05 15:04:53 2020 +0200
+++ b/svghmi/widget_keypad.ysl2 Wed Aug 05 15:13:59 2020 +0200
@@ -13,10 +13,159 @@
| }
}
+template "widget[@type='Keypad']", mode="widget_class"
+ ||
+ class KeypadWidget extends Widget{
+ moving = undefined;
+ enTimer = undefined;
+ offset = undefined;
+
+ on_position_click(evt) {
+ this.moving = true;
+ this.enTimer = 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]
+ }
+
+ off_position_click(evt) {
+ if(this.moving)
+ this.moving = false;
+ }
+
+ on_move(evt) {
+ if(this.moving && this.enTimer){
+ //get keyboard pos in html
+ let [eltid, tmpgrp] = current_modal;
+ let [xcoord,ycoord] = this.coordinates;
+ let [xdest,ydest,svgWidth,svgHeight] = page_desc[current_visible_page].bbox;
+
+ //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;
+ }
+
+ //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)+")");
+
+ //reset timer
+ this.enTimer = false;
+ setTimeout("{hmi_widgets['"+this.element_id+"'].enTimer = true;}", 100);
+ }
+
+ }
+
+ 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() {
+ end_modal.call(this);
+ let callback_obj = this.result_callback_obj;
+ callback_obj.edit_callback(this.editstr);
+ }
+
+ 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 = initial;
+ this.result_callback_obj = callback_obj;
+ this.Info_elt.textContent = info;
+ this.shift = false;
+ this.caps = false;
+ 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");
+ optional_labels("Sign Space NumDot position");
activable_labels("CapsLock Shift");
| init: function() {
foreach "$hmi_element/*[@inkscape:label = 'Keys']/*" {
@@ -26,82 +175,19 @@
| if(this.«.»_elt)
| this.«.»_elt.setAttribute("onclick", "hmi_widgets['«$hmi_element/@id»'].on_«.»_click()");
}
+ | if(this.position_elt){
+ | 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)");
+
+ | window.addEventListener("mouseup", hmi_widgets[this.element_id].off_position_click.bind(this));
+ | window.addEventListener("touchend", hmi_widgets[this.element_id].off_position_click.bind(this));
+ | window.addEventListener("touchcancel", hmi_widgets[this.element_id].off_position_click.bind(this));
+
+ | window.addEventListener("mousemove", hmi_widgets[this.element_id].on_move.bind(this));
+ | window.addEventListener("touchmove", hmi_widgets[this.element_id].on_move.bind(this));
+ | }
| },
- | on_key_click: function(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: function() {
- | end_modal.call(this);
- | },
- | on_Enter_click: function() {
- | end_modal.call(this);
- | callback_obj = this.result_callback_obj;
- | callback_obj.edit_callback(this.editstr);
- | },
- | on_BackSpace_click: function() {
- | this.editstr = this.editstr.slice(0,this.editstr.length-1);
- | this.update();
- | },
- | on_Sign_click: function() {
- | if(this.editstr[0] == "-")
- | this.editstr = this.editstr.slice(1,this.editstr.length);
- | else
- | this.editstr = "-" + this.editstr;
- | this.update();
- | },
- | on_NumDot_click: function() {
- | if(this.editstr.indexOf(".") == "-1"){
- | this.editstr += ".";
- | this.update();
- | }
- | },
- | on_Space_click: function() {
- | this.editstr += " ";
- | this.update();
- | },
- | caps: false,
- | _caps: undefined,
- | on_CapsLock_click: function() {
- | this.caps = !this.caps;
- | this.update();
- | },
- | shift: false,
- | _shift: undefined,
- | on_Shift_click: function() {
- | this.shift = !this.shift;
- | this.caps = false;
- | this.update();
- | },
+ |
const "g", "$geometry[@Id = $hmi_element/@id]";
| coordinates: [«$g/@x», «$g/@y»],
- | editstr: "",
- | _editstr: undefined,
- | result_callback_obj: undefined,
- | start_edit: function(info, valuetype, callback_obj, initial) {
- | show_modal.call(this);
- | this.editstr = initial;
- | this.result_callback_obj = callback_obj;
- | this.Info_elt.textContent = info;
- | this.shift = false;
- | this.caps = false;
- | this.update();
- | },
- | update: function() {
- | 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);
- | }
- | },
}