diff options
| author | CircleShift <kgunger12@gmail.com> | 2025-08-08 02:01:50 -0400 | 
|---|---|---|
| committer | CircleShift <kgunger12@gmail.com> | 2025-08-08 02:01:50 -0400 | 
| commit | 672fe4c0b3c35e5a0189bb53971796cf93a7dafa (patch) | |
| tree | 9fbeee1c8331d2ad8d3b0a22a836fad09b2eac5d /scripts/gui-common | |
| parent | 04c9c0d1f06ebf4fa2aa234a00838bc198c734e3 (diff) | |
Diffstat (limited to 'scripts/gui-common')
| -rw-r--r-- | scripts/gui-common/widgets.js | 269 | 
1 files changed, 124 insertions, 145 deletions
diff --git a/scripts/gui-common/widgets.js b/scripts/gui-common/widgets.js index 05d6126..3762e92 100644 --- a/scripts/gui-common/widgets.js +++ b/scripts/gui-common/widgets.js @@ -15,8 +15,11 @@ class Widget extends EventTarget{      /** @type {boolean} */      #inactive = false; -    /** @type {Array<string>} */ -    prevent_keys = []; +    /** @type {Object} */ +    prevent_keys = { +        "Enter": 1, +        " ": 1 +    };      /**       * Construct a new widget @@ -112,9 +115,6 @@ class Widget extends EventTarget{      /** @param {TouchEvent} event */      #emitTouchEvent(event)      { -        //if (window.SCROLLING) -        //    return; -          if (event.type == "touchstart")              this.element.classList.add("touch");          else if (event.type == "touchend" || event.type == "touchcancel") @@ -135,15 +135,7 @@ class Widget extends EventTarget{          else              this.dispatchEvent(new KeyboardEvent(event.type, event)); -        if (event.key == " " || event.key == "Enter") { -            if (event.type == "keydown") -                this.element.classList.add("touch"); -            else if (event.type == "keyup") -                this.element.classList.remove("touch"); -            event.preventDefault(); -        } - -        if (this.prevent_keys.indexOf(event.key) != -1) +        if (this.prevent_keys[event.key] == 1)              event.preventDefault();      } @@ -292,6 +284,8 @@ class WidgetButton extends Widget              if (this.#pressing == 0)                  this.set(this.get("true"));              this.#pressing |= button; + +            this.element.classList.add("touch");          }      } @@ -307,7 +301,10 @@ class WidgetButton extends Widget          if ((button & this.#pressing) !== 0) {              this.#pressing -= button;              if (this.#pressing == 0) +            {                  this.set(this.get("false")); +                this.element.classList.remove("touch"); +            }          }      } @@ -319,7 +316,10 @@ class WidgetButton extends Widget          if ((button & this.#pressing) !== 0) {              this.#pressing -= (button & this.#pressing);              if (this.#pressing == 0) +            {                  this.set(this.get("false")); +                this.element.classList.remove("touch"); +            }          }      } @@ -360,45 +360,58 @@ class WidgetToggle extends Widget          super();          this.element.classList.add("button");          this.element.classList.add("toggle"); -        this.element.setAttribute("aria-role", "switch"); +        this.element.setAttribute("role", "switch");          this.element.setAttribute("aria-checked", value === tv ? "true" : "false");          this.addEventListener("mousedown", this.#prime); -        this.addEventListener("mouseup", this.#toggle);          this.addEventListener("mouseleave", this.#leave);          this.addEventListener("mouseenter", this.#enter);          this.addEventListener("change", this.update);          this.addEventListener("touchend", this.#touchend); +        this.addEventListener("keydown", this.#keystart); +        this.addEventListener("keyup", this.#keyend); +        this.addEventListener("focusout", this.#focusend);          this.#bound = this.#toggle.bind(this);          super.set_by_id("false", fv);          super.set_by_id("true", tv);          this.set(value);      } +    do_toggle() { +        if (this.get() === this.get("true")) +        	this.set(this.get("false")); +		else +			this.set(this.get("true")); +    } +      /** @param {MouseEvent} event */      #prime(event)      { -        this.#primed |= (1 << event.button); +        if (event.button != 0) +            return; +        this.#primed |= 1; +        window.addEventListener("mouseup", this.#bound);      }      /** @param {MouseEvent} event */      #toggle(event)      { -        if (this.#gone) +        if (event.button != 0) +            return; + +        if ((this.#primed & 1) != 0) { +            window.removeEventListener("mouseup", this.#bound); +        } + +        if (this.#gone != 0)          {              this.#primed = 0;              this.#gone = 0; -            window.removeEventListener("mouseup", this.#bound); -        } -        if (((1 << event.button) & this.#primed) == 0)              return; +        } -		if (this.get() === this.get("true")) -        	this.set(this.get("false")); -		else -			this.set(this.get("true")); -		 +		this.do_toggle();  		this.update(); -        this.#primed -= (1 << event.button); +        this.#primed -= 1;      }  	update() @@ -412,7 +425,6 @@ class WidgetToggle extends Widget          if (this.#primed == 0)              return;          this.#gone = 1; -        window.addEventListener("mouseup", this.#bound);      }      /** @param {MouseEvent} event */ @@ -421,7 +433,6 @@ class WidgetToggle extends Widget          if (this.#primed == 0)              return;          this.#gone = 0; -        window.removeEventListener("mouseup", this.#bound);      }      /** @param {TouchEvent} event */ @@ -439,15 +450,54 @@ class WidgetToggle extends Widget                  i.clientY > rect.top &&                  i.clientY < rect.bottom              ) { -                if (this.get() === this.get("true")) -                    this.set(this.get("false")); -                else -                    this.set(this.get("true")); +                this.do_toggle();                  return;              }          }      } +    #keystart (event) +    { +        let btn = 0; +        if (event.key == " ") +            btn = 2; +        else if (event.key == "Enter") +            btn = 4; +         +        this.#primed |= btn; + +        if (this.#primed && btn) +            this.element.classList.add("touch"); +    } + +    #keyend (event) +    { +        let btn = 0; +        if (event.key == " ") +            btn = 2; +        else if (event.key == "Enter") +            btn = 4; +         +        if (this.#primed & btn) { +            this.#primed -= btn; + +            this.do_toggle() + +            if (this.#primed == 0) +                this.element.classList.remove("touch"); +        } +    } + +    #focusend(event) +    { +        let btn = 6; +        if ((this.#primed & btn) != 0) { +            this.#primed -= (this.#primed & btn); +            if (this.#primed == 0) +                this.element.classList.remove("touch"); +        } +    } +      /**       * @param {string} id       * @param {*} v @@ -474,7 +524,7 @@ class WidgetCheckbox extends WidgetToggle {      constructor(value = false, tv = true, fv = false)      {          super(value, tv, fv); -        this.element.setAttribute("aria-role", "checkbox"); +        this.element.setAttribute("role", "checkbox");          this.element.classList.remove("toggle");          this.element.classList.add("checkbox");      } @@ -646,8 +696,12 @@ class WidgetSlider extends WidgetDragable      {          super(1);          this.element.classList.add("slider"); +        this.element.setAttribute("role", "slider");          this.element.setAttribute("aria-orientation", "vertical"); -        this.element.setAttribute("aria-role", "slider") +        this.element.setAttribute("aria-valuenow", value); +        if (percent) +            this.element.setAttribute("aria-valuetext", `${Math.trunc((value - min) / (max - min) * 100)}%`); +          let fill = document.createElement("div");          fill.classList.add("fill");          this.element.appendChild(fill); @@ -663,15 +717,26 @@ class WidgetSlider extends WidgetDragable          this.addEventListener("focusout", this.#focusend);          super.set_by_id("max", max); -        this.element.setAttribute("aria-max", max); +        this.element.setAttribute("aria-valuemax", max);          super.set_by_id("min", min); -        this.element.setAttribute("aria-min", min); +        this.element.setAttribute("aria-valuemin", min);          super.set_by_id("step", step);          super.set_by_id("prec", precision);          super.set_by_id("perc", percent);          this.set(value); -        this.prevent_keys = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "PageUp", "PageDown", "End", "Home"]; +        this.prevent_keys = { +            "ArrowUp": 1, +            "ArrowDown": 1, +            "ArrowLeft": 1, +            "ArrowRight": 1, +            "PageUp": 1, +            "PageDown": 1, +            "End": 1, +            "Home": 1, +            "Enter": 1, +            " ": 1 +        };      }      #common_move(x, y) @@ -784,7 +849,7 @@ class WidgetSlider extends WidgetDragable      /** @param {KeyboardEvent} event */      #keystart(event) { -        if (event.key != "Tab") +        if (event.key != "Tab" && event.key != "Shift")              this.element.classList.add("touch");          if (event.key == "Home") { @@ -1423,6 +1488,7 @@ class WidgetScrubber extends WidgetDragable          super(1);          this.element.classList.add("scrubber"); +        this.element.setAttribute("role", "slider")          this.element.setAttribute("aria-orientation", "vertical");          this.#fill = document.createElement("div"); @@ -1435,8 +1501,12 @@ class WidgetScrubber extends WidgetDragable          this.element.style.setProperty("--percent", 0); +        this.element.setAttribute("aria-valuenow", value); +          super.set_by_id("max", max); +        this.element.setAttribute("aria-valuemax", max);          super.set_by_id("min", min); +        this.element.setAttribute("aria-valuemin", min);          super.set_by_id("step", step);          super.set_by_id("zones", zones);          super.set_by_id("speed", speed); @@ -1589,6 +1659,11 @@ class WidgetScrubber extends WidgetDragable          this.#detail.innerText = this.#tmpNum;      } +    #keypress(event) +    { + +    } +      /**       * @param {string} id       * @param {*} v @@ -1611,118 +1686,22 @@ class WidgetScrubber extends WidgetDragable  }  /** - * A toggle widget, similar to a WidgetCheckbox, but meant - * to be used for on/off power states. - * @extends Widget<*> + * A radio widget, similar to a WidgetToggle, but meant + * to be used for single selection states. + * @extends WidgetToggle   */ -class WidgetRadio extends Widget { -    /** @type {number} */ -    #primed = 0; +class WidgetRadio extends WidgetToggle { -    /** @type {number} */ -    #gone = 0; - -    #bound = null; - -    constructor (value = false, tv = true, fv = false) +    constructor(value = false, tv = true, fv = false)      { -        super(); -        this.element.classList.add("button"); +        super(value, tv, fv); +        this.element.setAttribute("role", "radio"); +        this.element.classList.remove("toggle");          this.element.classList.add("radio"); -        this.element.setAttribute("aria-checked", value === tv ? "true" : false); -        this.addEventListener("mousedown", this.#prime); -        this.addEventListener("mouseup", this.#toggle); -        this.addEventListener("mouseleave", this.#leave); -        this.addEventListener("mouseenter", this.#enter); -        this.addEventListener("change", this.update); -        this.addEventListener("touchend", this.#touchend); -        this.#bound = this.#toggle.bind(this); -        super.set_by_id("false", fv); -        super.set_by_id("true", tv); -        this.set(value); -    } - -    /** @param {MouseEvent} event */ -    #prime(event) -    { -        this.#primed |= (1 << event.button); -    } - -    /** @param {MouseEvent} event */ -    #toggle(event) -    { -        if (this.#gone) -        { -            this.#primed = 0; -            this.#gone = 0; -            window.removeEventListener("mouseup", this.#bound); -        } -        if (((1 << event.button) & this.#primed) == 0) -            return; - -		this.set(this.get("true")); -		 -		this.update(); -        this.#primed -= (1 << event.button); -    } - -	update() -	{ -        this.element.setAttribute("aria-checked", this.get() === this.get("true") ? "true" : false); -	} - -    /** @param {MouseEvent} event */ -    #leave(event) -    { -        if (this.#primed == 0) -            return; -        this.#gone = 1; -        window.addEventListener("mouseup", this.#bound);      } -    /** @param {MouseEvent} event */ -    #enter(event) -    { -        if (this.#primed == 0) -            return; -        this.#gone = 0; -        window.removeEventListener("mouseup", this.#bound); -    } - -    /** @param {TouchEvent} event */ -    #touchend(event) -    { -        if (event.changedTouches.length < 1) -            return; - -        let rect = this.element.getBoundingClientRect(); - -        for (let i of event.changedTouches) -        { -            if (i.clientX < rect.right && -                i.clientX > rect.left && -                i.clientY > rect.top && -                i.clientY < rect.bottom -            ) { -                this.set(this.get("true")); -                return; -            } -        } -    } - -    /** -     * @param {string} id -     * @param {*} v -     * @param {boolean} [emit] -     */ -    set_by_id(id, v, emit = false) -    { -        if (id == "false" || id == "true") -        { -            if (this.get() === this.get(id)) -                super.set_by_id("value", v); -        } -        super.set_by_id(id, v, emit); +    do_toggle() { +        this.set(this.get("true"))      }  }  |