svghmi/widget_keypad.ysl2
author usveticic
Thu, 01 Oct 2020 14:23:27 +0200
branchsvghmi
changeset 3062 9ec338a99a18
parent 3047 c113904f0e62
child 3102 abb487b56911
permissions -rw-r--r--
Button fix if no active or inactive state,
Widget animate changed to use anitmateTransform and added option to change rotation
Widget circular slider fixed so it is working on got and reprogramed so it similar to normal slider
Widget slider added support for changing size still need some changes to work properly
Added slider to svghmi test project
Changed svg in svhgmi_v2 project
// 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»],
}