svghmi/widget_jump.ysl2
author Edouard Tisserant <edouard.tisserant@gmail.com>
Tue, 22 Mar 2022 14:50:46 +0100
branchwxPython4
changeset 3442 29dbdb09da2e
parent 3242 f037e901a17c
child 3512 fce3d407bb46
permissions -rw-r--r--
Tests: fix project edit test sikuli IDE test.

Background click based on bitmap matching doesn't work.
Grid dots are not good match candidates.
Rendering probably affected by virtual display's bpp or rasterizer approximations.
// widget_jump.ysl2

widget_desc("Jump") {
    longdesc
    ||
    Jump widget brings focus to a different page. Mandatory single argument
    gives name of the page.

    Optional single path is used as new reference when jumping to a relative
    page, it must point to a HMI_NODE.

    "active"+"inactive" labeled elements can be provided and reflect current
    page being shown.

    "disabled" labeled element, if provided, is shown instead of "active" or
    "inactive" widget when pointed HMI_NODE is null.
    ||

    shortdesc > Jump to given page

    arg name="page" accepts="string" > name of page to jump to

    path name="reference" count="optional" accepts="HMI_NODE" > reference for relative jump
}

widget_class("Jump") {
||
        activable = false;
        active = false;
        disabled = false;
        frequency = 2;

        update_activity() {
            if(this.active) {
                 /* show active */ 
                 this.active_elt.style.display = "";
                 /* hide inactive */ 
                 this.inactive_elt.style.display = "none";
            } else {
                 /* show inactive */ 
                 this.inactive_elt.style.display = "";
                 /* hide active */ 
                 this.active_elt.style.display = "none";
            }
        }

        update_disability() {
            if(this.disabled) {
                /* show disabled */ 
                this.disabled_elt.style.display = "";
                /* hide inactive */ 
                this.inactive_elt.style.display = "none";
                /* hide active */ 
                this.active_elt.style.display = "none";
            } else {
                /* hide disabled */ 
                this.disabled_elt.style.display = "none";
                this.update_activity();
            }
        }

        make_on_click() {
            let that = this;
            const name = this.args[0];
            return function(evt){
                /* TODO: in order to allow jumps to page selected through for exemple a dropdown,
                   support path pointing to local variable whom value 
                   would be an HMI_TREE index and then jump to a relative page not hard-coded in advance */

                if(!that.disabled) {
                    const index = that.indexes.length > 0 ? that.indexes[0] + that.offset : undefined;
                    switch_page(name, index);
                }
            }
        }

        notify_page_change(page_name, index) {
            if(this.activable) {
                const ref_index = this.indexes.length > 0 ? this.indexes[0] + this.offset : undefined;
                const ref_name = this.args[0];
                this.active = ((ref_name == undefined || ref_name == page_name) && index == ref_index);
                this.update_state();
            }
        }

        dispatch(value) {
            this.disabled = !Number(value);
            this.update_state();
        }
||
}

widget_defs("Jump") {
    // TODO: ensure both active and inactive are provided
    const "activity" optional_labels("active inactive");
    const "have_activity","string-length($activity)>0";
    value "$activity";

    const "disability" optional_labels("disabled");
    const "have_disability","$have_activity and string-length($disability)>0";
    value "$disability";

    |     init: function() {
    |         this.element.onclick = this.make_on_click();
    if "$have_activity" {
    |         this.activable = true;
    }
    if "not($have_disability)" {
    |         this.unsubscribable = true;
    }
    >         this.update_state = 
    choose {
        when "$have_disability" {
            > this.update_disability
        }
        when "$have_activity" {
            > this.update_activity
        }
        otherwise > null
    }
    > ;\n
    |     },

}

widget_page("Jump"){
    param "page_desc";
    /* check that given path is compatible with page's reference path */
    if "path" {
        /* TODO: suport local variable containing an HMI_TREE index to jump to a relative page */
        /* when no page name provided, check for same page */
        const "target_page_name" choose {
            when "arg" value "arg[1]/@value";
            otherwise value "$page_desc/arg[1]/@value";
        }
        const "target_page_path" choose {
            when "arg" value "$hmi_pages_descs[arg[1]/@value = $target_page_name]/path[1]/@value";
            otherwise value "$page_desc/path[1]/@value";
        }

        if "not(func:same_class_paths($target_page_path, path[1]/@value))"
            error > Jump id="«@id»" to page "«$target_page_name»" with incompatible path "«path[1]/@value» (must be same class as "«$target_page_path»")
    }
}

emit "declarations:jump"
||
var jumps_need_update = false;
var jump_history = [[default_page, undefined]];

function update_jumps() {
    page_desc[current_visible_page].jumps.map(w=>w.notify_page_change(current_visible_page,current_page_index));
    jumps_need_update = false;
};

||