Changed keyboard to show on defined position. svghmi
authorusveticic
Wed, 05 Aug 2020 15:13:59 +0200
branchsvghmi
changeset 3010 893cc309f5e2
parent 3009 7c6960f09881
child 3011 601c6dbc1da7
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
svghmi/svghmi.js
svghmi/widget_input.ysl2
svghmi/widget_keypad.ysl2
--- 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);
-    |         }
-    |     },
 }