summaryrefslogtreecommitdiff
path: root/scripts/gui-common/widgets.js
diff options
context:
space:
mode:
authorCircleShift <kgunger12@gmail.com>2025-12-20 11:23:46 -0500
committerCircleShift <kgunger12@gmail.com>2025-12-20 11:23:46 -0500
commitd036ac50abc68a28270773009c1c005de788296b (patch)
treefcb29e78b0f7882d6eeda519f4e7ec2a353db973 /scripts/gui-common/widgets.js
parent96c8d99ec74acad6f0c99d4d7c006a67ee7d643e (diff)
parent672fe4c0b3c35e5a0189bb53971796cf93a7dafa (diff)
Merge branch 'main' of cshift.net:~/git/osm-facade-web
Diffstat (limited to 'scripts/gui-common/widgets.js')
-rw-r--r--scripts/gui-common/widgets.js269
1 files changed, 124 insertions, 145 deletions
diff --git a/scripts/gui-common/widgets.js b/scripts/gui-common/widgets.js
index f14fb22..86bc5b1 100644
--- a/scripts/gui-common/widgets.js
+++ b/scripts/gui-common/widgets.js
@@ -17,8 +17,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
@@ -118,9 +121,6 @@ class Widget extends EventTarget{
/** @param {TouchEvent} event */
#emitTouchEvent(event)
{
- //if (window.SCROLLING)
- // return;
-
if (WIDGETS_DEBUG) {
console.log(event);
}
@@ -149,15 +149,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();
}
@@ -314,6 +306,8 @@ class WidgetButton extends Widget
if (this.#pressing == 0)
this.set(this.get("true"));
this.#pressing |= button;
+
+ this.element.classList.add("touch");
}
}
@@ -329,7 +323,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");
+ }
}
}
@@ -341,7 +338,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");
+ }
}
}
@@ -382,45 +382,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()
@@ -434,7 +447,6 @@ class WidgetToggle extends Widget
if (this.#primed == 0)
return;
this.#gone = 1;
- window.addEventListener("mouseup", this.#bound);
}
/** @param {MouseEvent} event */
@@ -443,7 +455,6 @@ class WidgetToggle extends Widget
if (this.#primed == 0)
return;
this.#gone = 0;
- window.removeEventListener("mouseup", this.#bound);
}
/** @param {TouchEvent} event */
@@ -461,15 +472,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
@@ -496,7 +546,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");
}
@@ -668,8 +718,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);
@@ -685,15 +739,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)
@@ -806,7 +871,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") {
@@ -1445,6 +1510,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");
@@ -1457,8 +1523,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);
@@ -1611,6 +1681,11 @@ class WidgetScrubber extends WidgetDragable
this.#detail.innerText = this.#tmpNum;
}
+ #keypress(event)
+ {
+
+ }
+
/**
* @param {string} id
* @param {*} v
@@ -1633,118 +1708,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"))
}
}