perfect-gui 4.4.1 → 4.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- function w(y) {
1
+ function w(m) {
2
2
  return (
3
3
  /* css */
4
4
  `
@@ -10,7 +10,7 @@ function w(y) {
10
10
  --color-accent: #1681ca;
11
11
  --color-accent-hover: #218fda;
12
12
 
13
- position: ${y};
13
+ position: ${m};
14
14
  top: 0;
15
15
  left: 0;
16
16
  transform: translate3d(0,0,0);
@@ -413,20 +413,20 @@ function w(y) {
413
413
  `
414
414
  );
415
415
  }
416
- class f {
416
+ class b {
417
417
  constructor(e = {}) {
418
418
  if (e.container ? (this.container = typeof e.container == "string" ? document.querySelector(e.container) : e.container, this.position_type = "absolute") : (this.container = document.body, this.position_type = "fixed"), this.propReferences = [], this.folders = [], e.isFolder) {
419
419
  this._folderConstructor(e.folderOptions);
420
420
  return;
421
421
  }
422
- this.name = e != null && typeof e.name == "string" ? e.name : "", this.backgroundColor = e.color || null, this.container == document.body ? this.maxHeight = window.innerHeight : this.maxHeight = Math.min(this.container.clientHeight, window.innerHeight), e.maxHeight && (this.initMaxHeight = e.maxHeight, this.maxHeight = Math.min(this.initMaxHeight, this.maxHeight)), this.screenCorner = this._parseScreenCorner(e.position), this instanceof f && (typeof f[f.instanceCounter] != "number" ? f[f.instanceCounter] = 0 : f[f.instanceCounter]++), this.instanceId = f[f.instanceCounter], this.wrapperWidth = e.width || 290, this.stylesheet = document.createElement("style"), this.stylesheet.setAttribute("type", "text/css"), this.stylesheet.setAttribute("id", "lm-gui-stylesheet"), document.head.append(this.stylesheet), this.instanceId == 0 && this._addStyles(`${w(this.position_type)}`), this._styleInstance(), this._addWrapper(), this.wrapper.setAttribute("data-corner-x", this.screenCorner.x), this.wrapper.setAttribute("data-corner-y", this.screenCorner.y), e.autoRepositioning != !1 && window.addEventListener("resize", this._handleResize.bind(this)), this._handleResize(), this.hasBeenDragged = !1, e.draggable == !0 && this._makeDraggable(), this.closed = !1, e.closed && this.toggleClose();
422
+ this.name = e != null && typeof e.name == "string" ? e.name : "", this.backgroundColor = e.color || null, this.container == document.body ? this.maxHeight = window.innerHeight : this.maxHeight = Math.min(this.container.clientHeight, window.innerHeight), e.maxHeight && (this.initMaxHeight = e.maxHeight, this.maxHeight = Math.min(this.initMaxHeight, this.maxHeight)), this.screenCorner = this._parseScreenCorner(e.position), this instanceof b && (typeof b[b.instanceCounter] != "number" ? b[b.instanceCounter] = 0 : b[b.instanceCounter]++), this.instanceId = b[b.instanceCounter], this.wrapperWidth = e.width || 290, this.stylesheet = document.createElement("style"), this.stylesheet.setAttribute("type", "text/css"), this.stylesheet.setAttribute("id", "lm-gui-stylesheet"), document.head.append(this.stylesheet), this.instanceId == 0 && this._addStyles(`${w(this.position_type)}`), this._styleInstance(), this._addWrapper(), this.wrapper.setAttribute("data-corner-x", this.screenCorner.x), this.wrapper.setAttribute("data-corner-y", this.screenCorner.y), e.autoRepositioning != !1 && window.addEventListener("resize", this._handleResize.bind(this)), this._handleResize(), this.hasBeenDragged = !1, e.draggable == !0 && this._makeDraggable(), this.closed = !1, e.closed && this.toggleClose();
423
423
  }
424
424
  _styleInstance() {
425
425
  let e = this._getScrollbarWidth(this.container);
426
426
  if (this.screenCorner.x == "left" ? this.xOffset = 0 : this.xOffset = this.container.clientWidth - this.wrapperWidth - e, this.instanceId > 0) {
427
427
  let t = this.container.querySelectorAll(".p-gui");
428
- for (let i = 0; i < t.length; i++)
429
- this.screenCorner.y == t[i].dataset.cornerY && (this.screenCorner.x == "left" && t[i].dataset.cornerX == "left" ? this.xOffset += t[i].offsetWidth : this.screenCorner.x == "right" && t[i].dataset.cornerX == "right" && (this.xOffset -= t[i].offsetWidth));
428
+ for (let o = 0; o < t.length; o++)
429
+ this.screenCorner.y == t[o].dataset.cornerY && (this.screenCorner.x == "left" && t[o].dataset.cornerX == "left" ? this.xOffset += t[o].offsetWidth : this.screenCorner.x == "right" && t[o].dataset.cornerX == "right" && (this.xOffset -= t[o].offsetWidth));
430
430
  }
431
431
  this.yOffset = 0, this.position = {
432
432
  prevX: this.xOffset,
@@ -457,8 +457,8 @@ class f {
457
457
  let e = this._getScrollbarWidth(this.container);
458
458
  if (this.xOffset = this.screenCorner.x == "left" ? 0 : this.container.clientWidth - this.wrapperWidth - e, this.instanceId > 0) {
459
459
  let t = this.container.querySelectorAll(`.p-gui:not(#${this.wrapper.id}):not([data-dragged])`);
460
- for (let i = 0; i < t.length && !(parseInt(t[i].id.replace("p-gui-", "")) > this.instanceId); i++)
461
- this.screenCorner.y == t[i].dataset.cornerY && (this.screenCorner.x == "left" && t[i].dataset.cornerX == "left" ? this.xOffset += t[i].offsetWidth : this.screenCorner.x == "right" && t[i].dataset.cornerX == "right" && (this.xOffset -= t[i].offsetWidth));
460
+ for (let o = 0; o < t.length && !(parseInt(t[o].id.replace("p-gui-", "")) > this.instanceId); o++)
461
+ this.screenCorner.y == t[o].dataset.cornerY && (this.screenCorner.x == "left" && t[o].dataset.cornerX == "left" ? this.xOffset += t[o].offsetWidth : this.screenCorner.x == "right" && t[o].dataset.cornerX == "right" && (this.xOffset -= t[o].offsetWidth));
462
462
  }
463
463
  this.position = { prevX: this.xOffset, prevY: this.yOffset, x: this.xOffset, y: this.yOffset }, this.wrapper.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0)`;
464
464
  }
@@ -466,8 +466,8 @@ class f {
466
466
  e.el = e.el || "div";
467
467
  var t = document.createElement(e.el);
468
468
  if (e.id && (t.id = e.id), e.class && (t.className = e.class), e.inline && (t.style = e.inline), e.href && (t.href = e.href), e.onclick && (t.onclick = e.onclick), e.onchange && (t.onchange = e.onchange), e.textContent && (t.textContent = e.textContent), e.innerHTML && (t.innerHTML = e.innerHTML), e.type && (t.type = e.type), e.value && (t.value = e.value), e.customAttributes)
469
- for (var i in e.customAttributes)
470
- t.setAttribute(i, e.customAttributes[i]);
469
+ for (var o in e.customAttributes)
470
+ t.setAttribute(o, e.customAttributes[o]);
471
471
  return e.parent = e.parent ? e.parent : this.wrapper, e.parent.append(t), t;
472
472
  }
473
473
  _addStyles(e) {
@@ -490,159 +490,181 @@ class f {
490
490
  });
491
491
  }
492
492
  button(e, t) {
493
- let i = "";
494
- typeof e != "string" ? typeof e == "object" && (e != null && e.hasOwnProperty("name")) ? i = e.name == "" ? " " : e.name : i = " " : i = e == "" ? " " : e, this.imageContainer = null, typeof t != "function" && (t = () => {
493
+ let o = "";
494
+ typeof e != "string" ? typeof e == "object" && (e != null && e.hasOwnProperty("name")) ? o = e.name == "" ? " " : e.name : o = " " : o = e == "" ? " " : e, this.imageContainer = null, typeof t != "function" && (t = () => {
495
495
  });
496
- const r = this._createElement({
496
+ const a = this._createElement({
497
497
  class: "p-gui__button",
498
- textContent: i,
498
+ textContent: o,
499
499
  onclick: t
500
500
  });
501
- typeof e.color == "string" && (r.style.setProperty("--color-accent", e.color), r.style.setProperty("--color-accent-hover", e.hoverColor || e.color));
501
+ typeof e.color == "string" && (a.style.setProperty("--color-accent", e.color), a.style.setProperty("--color-accent-hover", e.hoverColor || e.color));
502
502
  }
503
503
  image(e = {}, t) {
504
504
  if (typeof e != "object")
505
505
  throw Error(`[GUI] image() first parameter must be an object. Received: ${typeof e}.`);
506
- let i;
506
+ let o;
507
507
  if (typeof e.path == "string")
508
- i = e.path;
508
+ o = e.path;
509
509
  else
510
510
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
511
- let r = i.replace(/^.*[\\\/]/, ""), s;
512
- e.name == null ? s = r : s = typeof e.name == "string" && e.name || " ";
513
- const o = e.selected === !0, n = e.selectionBorder !== !1;
514
- let a = "";
515
- e.width && (typeof e.width == "number" && (e.width += "px"), a += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), a += `height: ${e.height}; `), this.imageContainer || (this.imageContainer = this._createElement({
511
+ let a = o.replace(/^.*[\\\/]/, ""), n;
512
+ e.name == null ? n = a : n = typeof e.name == "string" && e.name || " ";
513
+ const r = e.selected === !0, i = e.selectionBorder !== !1;
514
+ let s = "";
515
+ e.width && (typeof e.width == "number" && (e.width += "px"), s += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), s += `height: ${e.height}; `), this.imageContainer || (this.imageContainer = this._createElement({
516
516
  class: "p-gui__image-container"
517
517
  }));
518
518
  var l = this._createElement({
519
519
  class: "p-gui__image",
520
- inline: "background-image: url(" + i + "); " + a,
520
+ inline: "background-image: url(" + o + "); " + s,
521
521
  parent: this.imageContainer
522
522
  });
523
- o && n && l.classList.add("p-gui__image--selected"), this._createElement({
523
+ return r && i && l.classList.add("p-gui__image--selected"), this._createElement({
524
524
  parent: l,
525
525
  class: "p-gui__image-text",
526
- textContent: s
527
- }), typeof t == "function" && (l.onclick = () => {
528
- let u = this.imageContainer.querySelectorAll(".p-gui__image--selected");
529
- for (let p = 0; p < u.length; p++)
530
- u[p].classList.remove("p-gui__image--selected");
531
- n && l.classList.add("p-gui__image--selected"), t({ path: i, text: s });
532
- });
526
+ textContent: n
527
+ }), l.onclick = () => {
528
+ let c = l.parentElement.querySelectorAll(".p-gui__image--selected");
529
+ for (let d = 0; d < c.length; d++)
530
+ c[d].classList.remove("p-gui__image--selected");
531
+ i && l.classList.add("p-gui__image--selected"), typeof t == "function" && t({ path: o, text: n });
532
+ }, l.path = o, l;
533
533
  }
534
534
  slider(e = {}, t) {
535
535
  if (typeof e != "object")
536
536
  throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof e}.`);
537
- let i = typeof e.name == "string" && e.name || " ", r = !1, s = null, o = e.obj || e.object, n = e.prop || e.property, a = typeof e.value == "number" ? e.value : null, l = e.min ?? 0, u = e.max ?? 1, p = e.step || (u - l) / 100;
538
- if (a !== null)
539
- (n != null || o != null) && console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');
540
- else if (n != null && o != null) {
541
- if (typeof n != "string")
542
- throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof n}.`);
543
- if (typeof o != "object")
544
- throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof o}.`);
545
- i == " " && (i = n), s = this.propReferences.push(o[n]) - 1, r = !0;
537
+ let o = typeof e.name == "string" && e.name || " ", a = !1, n = null, r = e.obj || e.object, i = e.prop || e.property, s = typeof e.value == "number" ? e.value : null, l = e.min ?? 0, c = e.max ?? 1, d = e.step || (c - l) / 100;
538
+ if (s !== null)
539
+ (i != null || r != null) && console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');
540
+ else if (i != null && r != null) {
541
+ if (typeof i != "string")
542
+ throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);
543
+ if (typeof r != "object")
544
+ throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);
545
+ o == " " && (o = i), n = this.propReferences.push(r[i]) - 1, a = !0;
546
546
  } else
547
- (n != null && o == null || n == null && o == null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), a = (u - l) / 2;
547
+ (i != null && r == null || i == null && r == null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), s = (c - l) / 2;
548
548
  this.imageContainer = null;
549
- var c = this._createElement({
549
+ var p = this._createElement({
550
550
  class: "p-gui__slider",
551
- textContent: i
552
- }), g = this._createElement({
553
- parent: c,
551
+ textContent: o
552
+ }), u = this._createElement({
553
+ parent: p,
554
554
  el: "input",
555
555
  class: "p-gui__slider-ctrl",
556
556
  customAttributes: {
557
557
  type: "range",
558
558
  min: l,
559
- max: u,
560
- step: p,
561
- value: r ? o[n] : a
559
+ max: c,
560
+ step: d,
561
+ value: a ? r[i] : s
562
562
  }
563
- }), b = this._createElement({
564
- parent: c,
563
+ }), g = this._createElement({
564
+ parent: p,
565
565
  class: "p-gui__slider-value",
566
- textContent: String(r ? o[n] : a)
566
+ textContent: String(a ? r[i] : s)
567
567
  });
568
- g.addEventListener("input", () => {
569
- b.textContent = g.value, r ? o[n] = g.value : typeof t == "function" && t(parseFloat(g.value));
570
- }), r && Object.defineProperty(o, n, {
568
+ u.addEventListener("input", () => {
569
+ g.textContent = u.value, a ? r[i] = u.value : typeof t == "function" && t(parseFloat(u.value));
570
+ }), a && Object.defineProperty(r, i, {
571
571
  set: (_) => {
572
- this.propReferences[s] = _, g.value = _, b.textContent = String(_), typeof t == "function" && t(parseFloat(g.value));
572
+ this.propReferences[n] = _, u.value = _, g.textContent = String(_), typeof t == "function" && t(parseFloat(u.value));
573
573
  },
574
- get: () => this.propReferences[s]
574
+ get: () => this.propReferences[n]
575
575
  });
576
576
  }
577
577
  toggle(e = {}, t) {
578
578
  if (typeof e != "object")
579
579
  throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);
580
- let i = typeof e.name == "string" && e.name || " ", r = !1, s = null, o = e.obj || e.object, n = e.prop || e.property, a = typeof e.value == "boolean" ? e.value : null;
581
- if (a !== null)
582
- (n != null || o != null) && console.warn('[GUI] toggle() "obj" and "property" parameters are ignored when a "value" parameter is used.');
583
- else if (n != null && o != null) {
584
- if (typeof n != "string")
585
- throw Error(`[GUI] toggle() "prop" (or "property") parameter must be an string. Received: ${typeof n}.`);
586
- if (typeof o != "object")
587
- throw Error(`[GUI] toggle() "obj" (or "object") parameter must be an object. Received: ${typeof o}.`);
588
- i == " " && (i = n), s = this.propReferences.push(o[n]) - 1, r = !0;
580
+ let o = typeof e.name == "string" && e.name || " ", a = !1, n = null, r = e.obj || e.object, i = e.prop || e.property, s = typeof e.value == "boolean" ? e.value : null;
581
+ if (s !== null)
582
+ (i != null || r != null) && console.warn('[GUI] toggle() "obj" and "property" parameters are ignored when a "value" parameter is used.');
583
+ else if (i != null && r != null) {
584
+ if (typeof i != "string")
585
+ throw Error(`[GUI] toggle() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);
586
+ if (typeof r != "object")
587
+ throw Error(`[GUI] toggle() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);
588
+ o == " " && (o = i), n = this.propReferences.push(r[i]) - 1, a = !0;
589
589
  } else
590
- (n != null && o == null || n == null && o == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
590
+ (i != null && r == null || i == null && r == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
591
591
  this.imageContainer = null;
592
592
  const l = this._createElement({
593
593
  class: "p-gui__switch",
594
- onclick: (c) => {
595
- const g = c.target.childNodes[1];
596
- let b = !0;
597
- g.classList.contains("p-gui__switch-checkbox--active") && (b = !1), g.classList.toggle("p-gui__switch-checkbox--active"), r ? o[n] = b : typeof t == "function" && t(b);
594
+ onclick: (p) => {
595
+ const u = p.target.childNodes[1];
596
+ let g = !0;
597
+ u.classList.contains("p-gui__switch-checkbox--active") && (g = !1), u.classList.toggle("p-gui__switch-checkbox--active"), a ? r[i] = g : typeof t == "function" && t(g);
598
598
  },
599
- textContent: i
599
+ textContent: o
600
600
  });
601
- let u = (() => r ? o[n] ? " p-gui__switch-checkbox--active" : "" : a ? " p-gui__switch-checkbox--active" : "")();
602
- const p = this._createElement({
601
+ let c = (() => a ? r[i] ? " p-gui__switch-checkbox--active" : "" : s ? " p-gui__switch-checkbox--active" : "")();
602
+ const d = this._createElement({
603
603
  parent: l,
604
- class: "p-gui__switch-checkbox" + u
604
+ class: "p-gui__switch-checkbox" + c
605
605
  });
606
- r && Object.defineProperty(o, n, {
607
- set: (c) => {
608
- this.propReferences[s] = c, c ? p.classList.add("p-gui__switch-checkbox--active") : p.classList.remove("p-gui__switch-checkbox--active"), typeof t == "function" && t(c);
606
+ a && Object.defineProperty(r, i, {
607
+ set: (p) => {
608
+ this.propReferences[n] = p, p ? d.classList.add("p-gui__switch-checkbox--active") : d.classList.remove("p-gui__switch-checkbox--active"), typeof t == "function" && t(p);
609
609
  },
610
- get: () => this.propReferences[s]
610
+ get: () => this.propReferences[n]
611
611
  });
612
612
  }
613
613
  list(e = {}, t) {
614
614
  if (typeof e != "object")
615
615
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);
616
- let i = typeof e.name == "string" ? e.name : " ", r = Array.isArray(e.values) ? e.values : null, s = (() => {
617
- if (!r)
618
- return null;
619
- if (typeof e.value == "string")
620
- return r.indexOf(e.value);
621
- if (typeof e.value == "number")
622
- return e.value;
623
- })();
624
- t = typeof t == "function" ? t : null, this.imageContainer = null;
625
- let o = this._createElement({
616
+ let o = typeof e.name == "string" ? e.name : " ", a = !1, n = null, r = e.obj || e.object, i = e.prop || e.property, s = Array.isArray(e.values) ? e.values : null, l;
617
+ if (t = typeof t == "function" ? t : null, e.value !== void 0 || e.value === void 0 && r === void 0 && i === void 0)
618
+ (i != null || r != null) && console.warn('[GUI] list() "obj" and "property" parameters are ignored when a "value" parameter is used.'), l = (() => {
619
+ if (!s)
620
+ return null;
621
+ if (typeof e.value == "string")
622
+ return s.indexOf(e.value);
623
+ if (typeof e.value == "number")
624
+ return e.value;
625
+ })();
626
+ else if (i != null && r != null) {
627
+ if (typeof i != "string")
628
+ throw Error(`[GUI] list() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);
629
+ if (typeof r != "object")
630
+ throw Error(`[GUI] list() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);
631
+ l = (() => {
632
+ if (!s)
633
+ return null;
634
+ if (typeof r[i] == "string")
635
+ return s.indexOf(r[i]);
636
+ if (typeof r[i] == "number")
637
+ return r[i];
638
+ })(), n = this.propReferences.push(r[i]) - 1, a = !0;
639
+ } else
640
+ (i != null && r == null || i == null && r == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
641
+ this.imageContainer = null;
642
+ let c = this._createElement({
626
643
  class: "p-gui__list",
627
- textContent: i
628
- }), n = this._createElement({
629
- parent: o,
644
+ textContent: o
645
+ }), d = this._createElement({
646
+ parent: c,
630
647
  el: "select",
631
648
  class: "p-gui__list-dropdown",
632
- onchange: (a) => {
633
- t && t(a.target.value);
649
+ onchange: (p) => {
650
+ a ? r[i] = p.target.value : t && t(p.target.value);
634
651
  }
635
652
  });
636
- r && r.forEach((a, l) => {
637
- let u = this._createElement({
638
- parent: n,
653
+ s && s.forEach((p, u) => {
654
+ let g = this._createElement({
655
+ parent: d,
639
656
  el: "option",
640
657
  customAttributes: {
641
- value: a
658
+ value: p
642
659
  },
643
- textContent: a
660
+ textContent: p
644
661
  });
645
- s == l && u.setAttribute("selected", "");
662
+ l == u && g.setAttribute("selected", "");
663
+ }), a && Object.defineProperty(r, i, {
664
+ set: (p) => {
665
+ typeof p == "string" && (l = s.indexOf(p)), typeof p == "number" && (l = p), this.propReferences[n] = l, d.querySelector("[selected]").removeAttribute("selected"), d.querySelectorAll("option")[l].setAttribute("selected", ""), typeof t == "function" && t(l);
666
+ },
667
+ get: () => this.propReferences[n]
646
668
  });
647
669
  }
648
670
  options(e, t) {
@@ -653,109 +675,124 @@ class f {
653
675
  vector2(e = {}, t) {
654
676
  if (typeof e != "object")
655
677
  throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
656
- let i = typeof e.name == "string" && e.name || " ";
657
- const r = e.x.min ?? 0, s = e.x.max ?? 1, o = e.y.min ?? 0, n = e.y.max ?? 1, a = e.x.obj || e.x.object, l = e.x.prop || e.x.property, u = this.propReferences.push(a[l]) - 1, p = e.y.obj || e.y.object, c = e.y.prop || e.y.property, g = this.propReferences.push(p[c]) - 1;
678
+ let o = typeof e.name == "string" && e.name || " ";
679
+ const a = e.x.min ?? 0, n = e.x.max ?? 1, r = e.y.min ?? 0, i = e.y.max ?? 1, s = e.x.obj || e.x.object, l = e.x.prop || e.x.property, c = this.propReferences.push(s[l]) - 1, d = e.y.obj || e.y.object, p = e.y.prop || e.y.property, u = this.propReferences.push(d[p]) - 1;
658
680
  t = typeof t == "function" ? t : null, this.imageContainer = null;
659
- const b = this._createElement({
681
+ const g = this._createElement({
660
682
  class: "p-gui__vector2",
661
- textContent: i
683
+ textContent: o
662
684
  }), _ = this._createElement({
663
- parent: b,
685
+ parent: g,
664
686
  class: "p-gui__vector-value",
665
- textContent: a[l] + ", " + p[c]
666
- }), d = this._createElement({
667
- parent: b,
687
+ textContent: s[l] + ", " + d[p]
688
+ }), h = this._createElement({
689
+ parent: g,
668
690
  el: "div",
669
691
  class: "p-gui__vector2-area",
670
- onclick: (h) => {
671
- a[l] = parseFloat(this._mapLinear(h.offsetX, 0, d.clientWidth, r, s).toFixed(2)), p[c] = parseFloat(this._mapLinear(h.offsetY, 0, d.clientHeight, n, o).toFixed(2)), t && t(a[l], a[c]);
692
+ onclick: (f) => {
693
+ s[l] = parseFloat(this._mapLinear(f.offsetX, 0, h.clientWidth, a, n).toFixed(2)), d[p] = parseFloat(this._mapLinear(f.offsetY, 0, h.clientHeight, i, r).toFixed(2)), t && t(s[l], s[p]);
672
694
  }
673
695
  });
674
- let m = !1;
675
- d.addEventListener("pointerdown", (h) => {
676
- m = !0;
677
- }), d.addEventListener("pointerup", () => {
678
- m = !1;
679
- }), d.addEventListener("pointermove", (h) => {
680
- m && (a[l] = parseFloat(this._mapLinear(h.offsetX, 0, d.clientWidth, r, s).toFixed(2)), p[c] = parseFloat(this._mapLinear(h.offsetY, 0, d.clientHeight, n, o).toFixed(2)), t && t(a[l], a[c]));
696
+ let y = !1;
697
+ h.addEventListener("pointerdown", (f) => {
698
+ y = !0;
699
+ }), h.addEventListener("pointerup", () => {
700
+ y = !1;
701
+ }), h.addEventListener("pointermove", (f) => {
702
+ y && (s[l] = parseFloat(this._mapLinear(f.offsetX, 0, h.clientWidth, a, n).toFixed(2)), d[p] = parseFloat(this._mapLinear(f.offsetY, 0, h.clientHeight, i, r).toFixed(2)), t && t(s[l], s[p]));
681
703
  }), this._createElement({
682
- parent: d,
704
+ parent: h,
683
705
  class: "p-gui__vector2-line p-gui__vector2-line-x"
684
706
  }), this._createElement({
685
- parent: d,
707
+ parent: h,
686
708
  class: "p-gui__vector2-line p-gui__vector2-line-y"
687
709
  });
688
710
  const x = this._createElement({
689
- parent: d,
711
+ parent: h,
690
712
  class: "p-gui__vector2-dot"
691
713
  });
692
- x.style.left = this._mapLinear(a[l], r, s, 0, d.clientWidth) + "px", x.style.top = this._mapLinear(p[c], o, n, d.clientHeight, 0) + "px", Object.defineProperty(a, l, {
693
- set: (h) => {
694
- this.propReferences[u] = h, x.style.left = this._mapLinear(h, r, s, 0, d.clientWidth) + "px", _.textContent = String(h) + ", " + p[c];
714
+ x.style.left = this._mapLinear(s[l], a, n, 0, h.clientWidth) + "px", x.style.top = this._mapLinear(d[p], r, i, h.clientHeight, 0) + "px", Object.defineProperty(s, l, {
715
+ set: (f) => {
716
+ this.propReferences[c] = f, x.style.left = this._mapLinear(f, a, n, 0, h.clientWidth) + "px", _.textContent = String(f) + ", " + d[p];
695
717
  },
696
- get: () => this.propReferences[u]
697
- }), Object.defineProperty(p, c, {
698
- set: (h) => {
699
- this.propReferences[g] = h, x.style.top = this._mapLinear(h, o, n, d.clientHeight, 0) + "px", _.textContent = a[l] + ", " + String(h);
718
+ get: () => this.propReferences[c]
719
+ }), Object.defineProperty(d, p, {
720
+ set: (f) => {
721
+ this.propReferences[u] = f, x.style.top = this._mapLinear(f, r, i, h.clientHeight, 0) + "px", _.textContent = s[l] + ", " + String(f);
700
722
  },
701
- get: () => this.propReferences[g]
723
+ get: () => this.propReferences[u]
702
724
  });
703
725
  }
704
726
  color(e = {}, t) {
705
727
  if (typeof e != "object")
706
728
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);
707
- let i = typeof e.name == "string" && e.name || " ", r;
708
- typeof e.value == "string" && (e.value.length != 7 || e.value[0] != "#" ? console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`) : r = e.value), r || (r = "#000000");
709
- const s = this._createElement({
729
+ let o = typeof e.name == "string" && e.name || " ", a = !1, n = null, r = e.obj || e.object, i = e.prop || e.property, s;
730
+ if (typeof e.value == "string" && (e.value.length != 7 || e.value[0] != "#" ? console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`) : s = e.value), s || (s = "#000000"), e.value !== void 0)
731
+ (i != null || r != null) && console.warn('[GUI] color() "obj" and "property" parameters are ignored when a "value" parameter is used.');
732
+ else if (i != null && r != null) {
733
+ if (typeof i != "string")
734
+ throw Error(`[GUI] color() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);
735
+ if (typeof r != "object")
736
+ throw Error(`[GUI] color() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);
737
+ o == " " && (o = i), n = this.propReferences.push(r[i]) - 1, a = !0;
738
+ } else
739
+ (i != null && r == null || i == null && r == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
740
+ this.imageContainer = null;
741
+ const l = this._createElement({
710
742
  el: "div",
711
743
  class: "p-gui__color",
712
- textContent: i
713
- }), o = this._createElement({
714
- parent: s,
744
+ textContent: o
745
+ }), c = this._createElement({
746
+ parent: l,
715
747
  el: "input",
716
748
  class: "p-gui__color-picker",
717
749
  type: "color",
718
- value: r
750
+ value: s
719
751
  });
720
- typeof t == "function" && o.addEventListener("input", () => {
721
- t(o.value);
752
+ typeof t == "function" && c.addEventListener("input", () => {
753
+ a ? r[i] = c.value : typeof t == "function" && t(c.value);
754
+ }), a && Object.defineProperty(r, i, {
755
+ set: (d) => {
756
+ this.propReferences[n] = d, c.value = d, typeof t == "function" && t(d);
757
+ },
758
+ get: () => this.propReferences[n]
722
759
  });
723
760
  }
724
761
  folder(e = {}) {
725
- let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.name || "", r = e.color || null, s = e.maxHeight || null;
762
+ let t = typeof e.closed == "boolean" ? e.closed : !1, o = e.name || "", a = e.color || null, n = e.maxHeight || null;
726
763
  this.imageContainer = null;
727
- let o = "p-gui__folder";
728
- this.folders.length == 0 && (o += " p-gui__folder--first"), t && (o += " p-gui__folder--closed");
729
- let n = r ? `background-color: ${r};` : "";
730
- n += s ? `max-height: ${s}px;` : "";
731
- let a = this._createElement({
732
- class: o,
733
- inline: n
764
+ let r = "p-gui__folder";
765
+ this.folders.length == 0 && (r += " p-gui__folder--first"), t && (r += " p-gui__folder--closed");
766
+ let i = a ? `background-color: ${a};` : "";
767
+ i += n ? `max-height: ${n}px;` : "";
768
+ let s = this._createElement({
769
+ class: r,
770
+ inline: i
734
771
  });
735
772
  this._createElement({
736
- innerHTML: `<span class="p-gui__folder-arrow"></span>${i}`,
773
+ innerHTML: `<span class="p-gui__folder-arrow"></span>${o}`,
737
774
  class: "p-gui__folder-header",
738
775
  onclick: function() {
739
776
  this.parentNode.classList.toggle("p-gui__folder--closed");
740
777
  },
741
- parent: a
778
+ parent: s
742
779
  });
743
- let l = new f({ isFolder: !0, folderOptions: {
744
- wrapper: a
780
+ let l = new b({ isFolder: !0, folderOptions: {
781
+ wrapper: s
745
782
  } });
746
783
  return this.folders.push(l), l;
747
784
  }
748
785
  _makeDraggable() {
749
786
  var e = this;
750
- this.header.addEventListener("pointerdown", t), this.header.addEventListener("pointerup", r);
751
- function t(s) {
752
- s.preventDefault(), e.position.initX = e.position.x, e.position.initY = e.position.y, e.position.prevX = s.clientX, e.position.prevY = s.clientY, document.addEventListener("pointermove", i);
787
+ this.header.addEventListener("pointerdown", t), this.header.addEventListener("pointerup", a);
788
+ function t(n) {
789
+ n.preventDefault(), e.position.initX = e.position.x, e.position.initY = e.position.y, e.position.prevX = n.clientX, e.position.prevY = n.clientY, document.addEventListener("pointermove", o);
753
790
  }
754
- function i(s) {
755
- s.preventDefault(), e.hasBeenDragged || (e.hasBeenDragged = !0, e.wrapper.setAttribute("data-dragged", "true")), e.position.x = e.position.initX + s.clientX - e.position.prevX, e.position.y = e.position.initY + s.clientY - e.position.prevY, e.wrapper.style.transform = "translate3d(" + e.position.x + "px," + e.position.y + "px,0)";
791
+ function o(n) {
792
+ n.preventDefault(), e.hasBeenDragged || (e.hasBeenDragged = !0, e.wrapper.setAttribute("data-dragged", "true")), e.position.x = e.position.initX + n.clientX - e.position.prevX, e.position.y = e.position.initY + n.clientY - e.position.prevY, e.wrapper.style.transform = "translate3d(" + e.position.x + "px," + e.position.y + "px,0)";
756
793
  }
757
- function r(s) {
758
- document.removeEventListener("pointermove", i);
794
+ function a(n) {
795
+ document.removeEventListener("pointermove", o);
759
796
  }
760
797
  }
761
798
  toggleClose() {
@@ -764,10 +801,10 @@ class f {
764
801
  kill() {
765
802
  this.wrapper.remove();
766
803
  }
767
- _mapLinear(e, t, i, r, s) {
768
- return r + (e - t) * (s - r) / (i - t);
804
+ _mapLinear(e, t, o, a, n) {
805
+ return a + (e - t) * (n - a) / (o - t);
769
806
  }
770
807
  }
771
808
  export {
772
- f as default
809
+ b as default
773
810
  };
@@ -1,4 +1,4 @@
1
- (function(x,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(x=typeof globalThis<"u"?globalThis:x||self,x["Perfect GUI"]=c())})(this,function(){"use strict";function x(w){return`
1
+ (function(x,u){typeof exports=="object"&&typeof module<"u"?module.exports=u():typeof define=="function"&&define.amd?define(u):(x=typeof globalThis<"u"?globalThis:x||self,x["Perfect GUI"]=u())})(this,function(){"use strict";function x(w){return`
2
2
  .p-gui {
3
3
  --main-border-radius: 5px;
4
4
  --color-bg: #121212;
@@ -407,10 +407,10 @@
407
407
  .p-gui__folder--closed .p-gui__folder-arrow {
408
408
  transform: rotate(0deg);
409
409
  }
410
- `}class c{constructor(e={}){if(e.container?(this.container=typeof e.container=="string"?document.querySelector(e.container):e.container,this.position_type="absolute"):(this.container=document.body,this.position_type="fixed"),this.propReferences=[],this.folders=[],e.isFolder){this._folderConstructor(e.folderOptions);return}this.name=e!=null&&typeof e.name=="string"?e.name:"",this.backgroundColor=e.color||null,this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),e.maxHeight&&(this.initMaxHeight=e.maxHeight,this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.screenCorner=this._parseScreenCorner(e.position),this instanceof c&&(typeof c[c.instanceCounter]!="number"?c[c.instanceCounter]=0:c[c.instanceCounter]++),this.instanceId=c[c.instanceCounter],this.wrapperWidth=e.width||290,this.stylesheet=document.createElement("style"),this.stylesheet.setAttribute("type","text/css"),this.stylesheet.setAttribute("id","lm-gui-stylesheet"),document.head.append(this.stylesheet),this.instanceId==0&&this._addStyles(`${x(this.position_type)}`),this._styleInstance(),this._addWrapper(),this.wrapper.setAttribute("data-corner-x",this.screenCorner.x),this.wrapper.setAttribute("data-corner-y",this.screenCorner.y),e.autoRepositioning!=!1&&window.addEventListener("resize",this._handleResize.bind(this)),this._handleResize(),this.hasBeenDragged=!1,e.draggable==!0&&this._makeDraggable(),this.closed=!1,e.closed&&this.toggleClose()}_styleInstance(){let e=this._getScrollbarWidth(this.container);if(this.screenCorner.x=="left"?this.xOffset=0:this.xOffset=this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(".p-gui");for(let i=0;i<t.length;i++)this.screenCorner.y==t[i].dataset.cornerY&&(this.screenCorner.x=="left"&&t[i].dataset.cornerX=="left"?this.xOffset+=t[i].offsetWidth:this.screenCorner.x=="right"&&t[i].dataset.cornerX=="right"&&(this.xOffset-=t[i].offsetWidth))}this.yOffset=0,this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this._addStyles(`#p-gui-${this.instanceId} {
410
+ `}class u{constructor(e={}){if(e.container?(this.container=typeof e.container=="string"?document.querySelector(e.container):e.container,this.position_type="absolute"):(this.container=document.body,this.position_type="fixed"),this.propReferences=[],this.folders=[],e.isFolder){this._folderConstructor(e.folderOptions);return}this.name=e!=null&&typeof e.name=="string"?e.name:"",this.backgroundColor=e.color||null,this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),e.maxHeight&&(this.initMaxHeight=e.maxHeight,this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.screenCorner=this._parseScreenCorner(e.position),this instanceof u&&(typeof u[u.instanceCounter]!="number"?u[u.instanceCounter]=0:u[u.instanceCounter]++),this.instanceId=u[u.instanceCounter],this.wrapperWidth=e.width||290,this.stylesheet=document.createElement("style"),this.stylesheet.setAttribute("type","text/css"),this.stylesheet.setAttribute("id","lm-gui-stylesheet"),document.head.append(this.stylesheet),this.instanceId==0&&this._addStyles(`${x(this.position_type)}`),this._styleInstance(),this._addWrapper(),this.wrapper.setAttribute("data-corner-x",this.screenCorner.x),this.wrapper.setAttribute("data-corner-y",this.screenCorner.y),e.autoRepositioning!=!1&&window.addEventListener("resize",this._handleResize.bind(this)),this._handleResize(),this.hasBeenDragged=!1,e.draggable==!0&&this._makeDraggable(),this.closed=!1,e.closed&&this.toggleClose()}_styleInstance(){let e=this._getScrollbarWidth(this.container);if(this.screenCorner.x=="left"?this.xOffset=0:this.xOffset=this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(".p-gui");for(let o=0;o<t.length;o++)this.screenCorner.y==t[o].dataset.cornerY&&(this.screenCorner.x=="left"&&t[o].dataset.cornerX=="left"?this.xOffset+=t[o].offsetWidth:this.screenCorner.x=="right"&&t[o].dataset.cornerX=="right"&&(this.xOffset-=t[o].offsetWidth))}this.yOffset=0,this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this._addStyles(`#p-gui-${this.instanceId} {
411
411
  width: ${this.wrapperWidth}px;
412
412
  max-height: ${this.maxHeight}px;
413
413
  transform: translate3d(${this.xOffset}px,${this.yOffset}px,0);
414
414
  ${this.screenCorner.y=="top"?"":"top: auto; bottom: 0;"}
415
415
  ${this.backgroundColor?"background: "+this.backgroundColor+";":""}
416
- }`)}_folderConstructor(e){this.wrapper=e.wrapper}_parseScreenCorner(e){let t={x:"right",y:"top"};return e==null||(typeof e!="string"&&console.error("[perfect-gui] Position must be a string."),e.includes("left")&&(t.x="left"),e.includes("bottom")&&(t.y="bottom")),t}_getScrollbarWidth(e){return e===document.body?window.innerWidth-document.documentElement.clientWidth:e.offsetWidth-e.clientWidth}_handleResize(){if(this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),this.initMaxHeight&&(this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.wrapper.style.maxHeight=this.maxHeight+"px",this.hasBeenDragged)return;let e=this._getScrollbarWidth(this.container);if(this.xOffset=this.screenCorner.x=="left"?0:this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(`.p-gui:not(#${this.wrapper.id}):not([data-dragged])`);for(let i=0;i<t.length&&!(parseInt(t[i].id.replace("p-gui-",""))>this.instanceId);i++)this.screenCorner.y==t[i].dataset.cornerY&&(this.screenCorner.x=="left"&&t[i].dataset.cornerX=="left"?this.xOffset+=t[i].offsetWidth:this.screenCorner.x=="right"&&t[i].dataset.cornerX=="right"&&(this.xOffset-=t[i].offsetWidth))}this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this.wrapper.style.transform=`translate3d(${this.position.x}px, ${this.position.y}px, 0)`}_createElement(e){e.el=e.el||"div";var t=document.createElement(e.el);if(e.id&&(t.id=e.id),e.class&&(t.className=e.class),e.inline&&(t.style=e.inline),e.href&&(t.href=e.href),e.onclick&&(t.onclick=e.onclick),e.onchange&&(t.onchange=e.onchange),e.textContent&&(t.textContent=e.textContent),e.innerHTML&&(t.innerHTML=e.innerHTML),e.type&&(t.type=e.type),e.value&&(t.value=e.value),e.customAttributes)for(var i in e.customAttributes)t.setAttribute(i,e.customAttributes[i]);return e.parent=e.parent?e.parent:this.wrapper,e.parent.append(t),t}_addStyles(e){this.stylesheet.innerHTML+=e}_addWrapper(){this.wrapper=this._createElement({parent:this.container,id:"p-gui-"+this.instanceId,class:"p-gui"}),this.header=this._createElement({parent:this.wrapper,class:"p-gui__header",textContent:this.name,inline:`${this.backgroundColor?"border-color: "+this.backgroundColor+";":""}`}),this._createElement({parent:this.header,class:"p-gui__header-close",onclick:this.toggleClose.bind(this)})}button(e,t){let i="";typeof e!="string"?typeof e=="object"&&(e!=null&&e.hasOwnProperty("name"))?i=e.name==""?" ":e.name:i=" ":i=e==""?" ":e,this.imageContainer=null,typeof t!="function"&&(t=()=>{});const r=this._createElement({class:"p-gui__button",textContent:i,onclick:t});typeof e.color=="string"&&(r.style.setProperty("--color-accent",e.color),r.style.setProperty("--color-accent-hover",e.hoverColor||e.color))}image(e={},t){if(typeof e!="object")throw Error(`[GUI] image() first parameter must be an object. Received: ${typeof e}.`);let i;if(typeof e.path=="string")i=e.path;else throw typeof e.path==null?Error("[GUI] image() path must be provided."):Error("[GUI] image() path must be a string.");let r=i.replace(/^.*[\\\/]/,""),s;e.name==null?s=r:s=typeof e.name=="string"&&e.name||" ";const o=e.selected===!0,n=e.selectionBorder!==!1;let a="";e.width&&(typeof e.width=="number"&&(e.width+="px"),a+=`flex: 0 0 calc(${e.width} - 5px); `),e.height&&(typeof e.height=="number"&&(e.height+="px"),a+=`height: ${e.height}; `),this.imageContainer||(this.imageContainer=this._createElement({class:"p-gui__image-container"}));var l=this._createElement({class:"p-gui__image",inline:"background-image: url("+i+"); "+a,parent:this.imageContainer});o&&n&&l.classList.add("p-gui__image--selected"),this._createElement({parent:l,class:"p-gui__image-text",textContent:s}),typeof t=="function"&&(l.onclick=()=>{let g=this.imageContainer.querySelectorAll(".p-gui__image--selected");for(let d=0;d<g.length;d++)g[d].classList.remove("p-gui__image--selected");n&&l.classList.add("p-gui__image--selected"),t({path:i,text:s})})}slider(e={},t){if(typeof e!="object")throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",r=!1,s=null,o=e.obj||e.object,n=e.prop||e.property,a=typeof e.value=="number"?e.value:null,l=e.min??0,g=e.max??1,d=e.step||(g-l)/100;if(a!==null)(n!=null||o!=null)&&console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(n!=null&&o!=null){if(typeof n!="string")throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof n}.`);if(typeof o!="object")throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof o}.`);i==" "&&(i=n),s=this.propReferences.push(o[n])-1,r=!0}else(n!=null&&o==null||n==null&&o==null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),a=(g-l)/2;this.imageContainer=null;var p=this._createElement({class:"p-gui__slider",textContent:i}),f=this._createElement({parent:p,el:"input",class:"p-gui__slider-ctrl",customAttributes:{type:"range",min:l,max:g,step:d,value:r?o[n]:a}}),b=this._createElement({parent:p,class:"p-gui__slider-value",textContent:String(r?o[n]:a)});f.addEventListener("input",()=>{b.textContent=f.value,r?o[n]=f.value:typeof t=="function"&&t(parseFloat(f.value))}),r&&Object.defineProperty(o,n,{set:_=>{this.propReferences[s]=_,f.value=_,b.textContent=String(_),typeof t=="function"&&t(parseFloat(f.value))},get:()=>this.propReferences[s]})}toggle(e={},t){if(typeof e!="object")throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",r=!1,s=null,o=e.obj||e.object,n=e.prop||e.property,a=typeof e.value=="boolean"?e.value:null;if(a!==null)(n!=null||o!=null)&&console.warn('[GUI] toggle() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(n!=null&&o!=null){if(typeof n!="string")throw Error(`[GUI] toggle() "prop" (or "property") parameter must be an string. Received: ${typeof n}.`);if(typeof o!="object")throw Error(`[GUI] toggle() "obj" (or "object") parameter must be an object. Received: ${typeof o}.`);i==" "&&(i=n),s=this.propReferences.push(o[n])-1,r=!0}else(n!=null&&o==null||n==null&&o==null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');this.imageContainer=null;const l=this._createElement({class:"p-gui__switch",onclick:p=>{const f=p.target.childNodes[1];let b=!0;f.classList.contains("p-gui__switch-checkbox--active")&&(b=!1),f.classList.toggle("p-gui__switch-checkbox--active"),r?o[n]=b:typeof t=="function"&&t(b)},textContent:i});let g=(()=>r?o[n]?" p-gui__switch-checkbox--active":"":a?" p-gui__switch-checkbox--active":"")();const d=this._createElement({parent:l,class:"p-gui__switch-checkbox"+g});r&&Object.defineProperty(o,n,{set:p=>{this.propReferences[s]=p,p?d.classList.add("p-gui__switch-checkbox--active"):d.classList.remove("p-gui__switch-checkbox--active"),typeof t=="function"&&t(p)},get:()=>this.propReferences[s]})}list(e={},t){if(typeof e!="object")throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"?e.name:" ",r=Array.isArray(e.values)?e.values:null,s=(()=>{if(!r)return null;if(typeof e.value=="string")return r.indexOf(e.value);if(typeof e.value=="number")return e.value})();t=typeof t=="function"?t:null,this.imageContainer=null;let o=this._createElement({class:"p-gui__list",textContent:i}),n=this._createElement({parent:o,el:"select",class:"p-gui__list-dropdown",onchange:a=>{t&&t(a.target.value)}});r&&r.forEach((a,l)=>{let g=this._createElement({parent:n,el:"option",customAttributes:{value:a},textContent:a});s==l&&g.setAttribute("selected","")})}options(e,t){if(typeof e!="object")throw Error(`[GUI] options() first parameter must be an object. Received: ${typeof e}.`);this.list(e,t)}vector2(e={},t){if(typeof e!="object")throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ";const r=e.x.min??0,s=e.x.max??1,o=e.y.min??0,n=e.y.max??1,a=e.x.obj||e.x.object,l=e.x.prop||e.x.property,g=this.propReferences.push(a[l])-1,d=e.y.obj||e.y.object,p=e.y.prop||e.y.property,f=this.propReferences.push(d[p])-1;t=typeof t=="function"?t:null,this.imageContainer=null;const b=this._createElement({class:"p-gui__vector2",textContent:i}),_=this._createElement({parent:b,class:"p-gui__vector-value",textContent:a[l]+", "+d[p]}),h=this._createElement({parent:b,el:"div",class:"p-gui__vector2-area",onclick:u=>{a[l]=parseFloat(this._mapLinear(u.offsetX,0,h.clientWidth,r,s).toFixed(2)),d[p]=parseFloat(this._mapLinear(u.offsetY,0,h.clientHeight,n,o).toFixed(2)),t&&t(a[l],a[p])}});let y=!1;h.addEventListener("pointerdown",u=>{y=!0}),h.addEventListener("pointerup",()=>{y=!1}),h.addEventListener("pointermove",u=>{y&&(a[l]=parseFloat(this._mapLinear(u.offsetX,0,h.clientWidth,r,s).toFixed(2)),d[p]=parseFloat(this._mapLinear(u.offsetY,0,h.clientHeight,n,o).toFixed(2)),t&&t(a[l],a[p]))}),this._createElement({parent:h,class:"p-gui__vector2-line p-gui__vector2-line-x"}),this._createElement({parent:h,class:"p-gui__vector2-line p-gui__vector2-line-y"});const m=this._createElement({parent:h,class:"p-gui__vector2-dot"});m.style.left=this._mapLinear(a[l],r,s,0,h.clientWidth)+"px",m.style.top=this._mapLinear(d[p],o,n,h.clientHeight,0)+"px",Object.defineProperty(a,l,{set:u=>{this.propReferences[g]=u,m.style.left=this._mapLinear(u,r,s,0,h.clientWidth)+"px",_.textContent=String(u)+", "+d[p]},get:()=>this.propReferences[g]}),Object.defineProperty(d,p,{set:u=>{this.propReferences[f]=u,m.style.top=this._mapLinear(u,o,n,h.clientHeight,0)+"px",_.textContent=a[l]+", "+String(u)},get:()=>this.propReferences[f]})}color(e={},t){if(typeof e!="object")throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",r;typeof e.value=="string"&&(e.value.length!=7||e.value[0]!="#"?console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`):r=e.value),r||(r="#000000");const s=this._createElement({el:"div",class:"p-gui__color",textContent:i}),o=this._createElement({parent:s,el:"input",class:"p-gui__color-picker",type:"color",value:r});typeof t=="function"&&o.addEventListener("input",()=>{t(o.value)})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.name||"",r=e.color||null,s=e.maxHeight||null;this.imageContainer=null;let o="p-gui__folder";this.folders.length==0&&(o+=" p-gui__folder--first"),t&&(o+=" p-gui__folder--closed");let n=r?`background-color: ${r};`:"";n+=s?`max-height: ${s}px;`:"";let a=this._createElement({class:o,inline:n});this._createElement({innerHTML:`<span class="p-gui__folder-arrow"></span>${i}`,class:"p-gui__folder-header",onclick:function(){this.parentNode.classList.toggle("p-gui__folder--closed")},parent:a});let l=new c({isFolder:!0,folderOptions:{wrapper:a}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",r);function t(s){s.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=s.clientX,e.position.prevY=s.clientY,document.addEventListener("pointermove",i)}function i(s){s.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+s.clientX-e.position.prevX,e.position.y=e.position.initY+s.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function r(s){document.removeEventListener("pointermove",i)}}toggleClose(){this.closed=!this.closed,this.wrapper.classList.toggle("p-gui--collapsed")}kill(){this.wrapper.remove()}_mapLinear(e,t,i,r,s){return r+(e-t)*(s-r)/(i-t)}}return c});
416
+ }`)}_folderConstructor(e){this.wrapper=e.wrapper}_parseScreenCorner(e){let t={x:"right",y:"top"};return e==null||(typeof e!="string"&&console.error("[perfect-gui] Position must be a string."),e.includes("left")&&(t.x="left"),e.includes("bottom")&&(t.y="bottom")),t}_getScrollbarWidth(e){return e===document.body?window.innerWidth-document.documentElement.clientWidth:e.offsetWidth-e.clientWidth}_handleResize(){if(this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),this.initMaxHeight&&(this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.wrapper.style.maxHeight=this.maxHeight+"px",this.hasBeenDragged)return;let e=this._getScrollbarWidth(this.container);if(this.xOffset=this.screenCorner.x=="left"?0:this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(`.p-gui:not(#${this.wrapper.id}):not([data-dragged])`);for(let o=0;o<t.length&&!(parseInt(t[o].id.replace("p-gui-",""))>this.instanceId);o++)this.screenCorner.y==t[o].dataset.cornerY&&(this.screenCorner.x=="left"&&t[o].dataset.cornerX=="left"?this.xOffset+=t[o].offsetWidth:this.screenCorner.x=="right"&&t[o].dataset.cornerX=="right"&&(this.xOffset-=t[o].offsetWidth))}this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this.wrapper.style.transform=`translate3d(${this.position.x}px, ${this.position.y}px, 0)`}_createElement(e){e.el=e.el||"div";var t=document.createElement(e.el);if(e.id&&(t.id=e.id),e.class&&(t.className=e.class),e.inline&&(t.style=e.inline),e.href&&(t.href=e.href),e.onclick&&(t.onclick=e.onclick),e.onchange&&(t.onchange=e.onchange),e.textContent&&(t.textContent=e.textContent),e.innerHTML&&(t.innerHTML=e.innerHTML),e.type&&(t.type=e.type),e.value&&(t.value=e.value),e.customAttributes)for(var o in e.customAttributes)t.setAttribute(o,e.customAttributes[o]);return e.parent=e.parent?e.parent:this.wrapper,e.parent.append(t),t}_addStyles(e){this.stylesheet.innerHTML+=e}_addWrapper(){this.wrapper=this._createElement({parent:this.container,id:"p-gui-"+this.instanceId,class:"p-gui"}),this.header=this._createElement({parent:this.wrapper,class:"p-gui__header",textContent:this.name,inline:`${this.backgroundColor?"border-color: "+this.backgroundColor+";":""}`}),this._createElement({parent:this.header,class:"p-gui__header-close",onclick:this.toggleClose.bind(this)})}button(e,t){let o="";typeof e!="string"?typeof e=="object"&&(e!=null&&e.hasOwnProperty("name"))?o=e.name==""?" ":e.name:o=" ":o=e==""?" ":e,this.imageContainer=null,typeof t!="function"&&(t=()=>{});const a=this._createElement({class:"p-gui__button",textContent:o,onclick:t});typeof e.color=="string"&&(a.style.setProperty("--color-accent",e.color),a.style.setProperty("--color-accent-hover",e.hoverColor||e.color))}image(e={},t){if(typeof e!="object")throw Error(`[GUI] image() first parameter must be an object. Received: ${typeof e}.`);let o;if(typeof e.path=="string")o=e.path;else throw typeof e.path==null?Error("[GUI] image() path must be provided."):Error("[GUI] image() path must be a string.");let a=o.replace(/^.*[\\\/]/,""),n;e.name==null?n=a:n=typeof e.name=="string"&&e.name||" ";const r=e.selected===!0,i=e.selectionBorder!==!1;let s="";e.width&&(typeof e.width=="number"&&(e.width+="px"),s+=`flex: 0 0 calc(${e.width} - 5px); `),e.height&&(typeof e.height=="number"&&(e.height+="px"),s+=`height: ${e.height}; `),this.imageContainer||(this.imageContainer=this._createElement({class:"p-gui__image-container"}));var l=this._createElement({class:"p-gui__image",inline:"background-image: url("+o+"); "+s,parent:this.imageContainer});return r&&i&&l.classList.add("p-gui__image--selected"),this._createElement({parent:l,class:"p-gui__image-text",textContent:n}),l.onclick=()=>{let c=l.parentElement.querySelectorAll(".p-gui__image--selected");for(let d=0;d<c.length;d++)c[d].classList.remove("p-gui__image--selected");i&&l.classList.add("p-gui__image--selected"),typeof t=="function"&&t({path:o,text:n})},l.path=o,l}slider(e={},t){if(typeof e!="object")throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof e}.`);let o=typeof e.name=="string"&&e.name||" ",a=!1,n=null,r=e.obj||e.object,i=e.prop||e.property,s=typeof e.value=="number"?e.value:null,l=e.min??0,c=e.max??1,d=e.step||(c-l)/100;if(s!==null)(i!=null||r!=null)&&console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(i!=null&&r!=null){if(typeof i!="string")throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);if(typeof r!="object")throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);o==" "&&(o=i),n=this.propReferences.push(r[i])-1,a=!0}else(i!=null&&r==null||i==null&&r==null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),s=(c-l)/2;this.imageContainer=null;var p=this._createElement({class:"p-gui__slider",textContent:o}),f=this._createElement({parent:p,el:"input",class:"p-gui__slider-ctrl",customAttributes:{type:"range",min:l,max:c,step:d,value:a?r[i]:s}}),b=this._createElement({parent:p,class:"p-gui__slider-value",textContent:String(a?r[i]:s)});f.addEventListener("input",()=>{b.textContent=f.value,a?r[i]=f.value:typeof t=="function"&&t(parseFloat(f.value))}),a&&Object.defineProperty(r,i,{set:_=>{this.propReferences[n]=_,f.value=_,b.textContent=String(_),typeof t=="function"&&t(parseFloat(f.value))},get:()=>this.propReferences[n]})}toggle(e={},t){if(typeof e!="object")throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);let o=typeof e.name=="string"&&e.name||" ",a=!1,n=null,r=e.obj||e.object,i=e.prop||e.property,s=typeof e.value=="boolean"?e.value:null;if(s!==null)(i!=null||r!=null)&&console.warn('[GUI] toggle() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(i!=null&&r!=null){if(typeof i!="string")throw Error(`[GUI] toggle() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);if(typeof r!="object")throw Error(`[GUI] toggle() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);o==" "&&(o=i),n=this.propReferences.push(r[i])-1,a=!0}else(i!=null&&r==null||i==null&&r==null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');this.imageContainer=null;const l=this._createElement({class:"p-gui__switch",onclick:p=>{const f=p.target.childNodes[1];let b=!0;f.classList.contains("p-gui__switch-checkbox--active")&&(b=!1),f.classList.toggle("p-gui__switch-checkbox--active"),a?r[i]=b:typeof t=="function"&&t(b)},textContent:o});let c=(()=>a?r[i]?" p-gui__switch-checkbox--active":"":s?" p-gui__switch-checkbox--active":"")();const d=this._createElement({parent:l,class:"p-gui__switch-checkbox"+c});a&&Object.defineProperty(r,i,{set:p=>{this.propReferences[n]=p,p?d.classList.add("p-gui__switch-checkbox--active"):d.classList.remove("p-gui__switch-checkbox--active"),typeof t=="function"&&t(p)},get:()=>this.propReferences[n]})}list(e={},t){if(typeof e!="object")throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);let o=typeof e.name=="string"?e.name:" ",a=!1,n=null,r=e.obj||e.object,i=e.prop||e.property,s=Array.isArray(e.values)?e.values:null,l;if(t=typeof t=="function"?t:null,e.value!==void 0||e.value===void 0&&r===void 0&&i===void 0)(i!=null||r!=null)&&console.warn('[GUI] list() "obj" and "property" parameters are ignored when a "value" parameter is used.'),l=(()=>{if(!s)return null;if(typeof e.value=="string")return s.indexOf(e.value);if(typeof e.value=="number")return e.value})();else if(i!=null&&r!=null){if(typeof i!="string")throw Error(`[GUI] list() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);if(typeof r!="object")throw Error(`[GUI] list() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);l=(()=>{if(!s)return null;if(typeof r[i]=="string")return s.indexOf(r[i]);if(typeof r[i]=="number")return r[i]})(),n=this.propReferences.push(r[i])-1,a=!0}else(i!=null&&r==null||i==null&&r==null)&&console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');this.imageContainer=null;let c=this._createElement({class:"p-gui__list",textContent:o}),d=this._createElement({parent:c,el:"select",class:"p-gui__list-dropdown",onchange:p=>{a?r[i]=p.target.value:t&&t(p.target.value)}});s&&s.forEach((p,f)=>{let b=this._createElement({parent:d,el:"option",customAttributes:{value:p},textContent:p});l==f&&b.setAttribute("selected","")}),a&&Object.defineProperty(r,i,{set:p=>{typeof p=="string"&&(l=s.indexOf(p)),typeof p=="number"&&(l=p),this.propReferences[n]=l,d.querySelector("[selected]").removeAttribute("selected"),d.querySelectorAll("option")[l].setAttribute("selected",""),typeof t=="function"&&t(l)},get:()=>this.propReferences[n]})}options(e,t){if(typeof e!="object")throw Error(`[GUI] options() first parameter must be an object. Received: ${typeof e}.`);this.list(e,t)}vector2(e={},t){if(typeof e!="object")throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);let o=typeof e.name=="string"&&e.name||" ";const a=e.x.min??0,n=e.x.max??1,r=e.y.min??0,i=e.y.max??1,s=e.x.obj||e.x.object,l=e.x.prop||e.x.property,c=this.propReferences.push(s[l])-1,d=e.y.obj||e.y.object,p=e.y.prop||e.y.property,f=this.propReferences.push(d[p])-1;t=typeof t=="function"?t:null,this.imageContainer=null;const b=this._createElement({class:"p-gui__vector2",textContent:o}),_=this._createElement({parent:b,class:"p-gui__vector-value",textContent:s[l]+", "+d[p]}),h=this._createElement({parent:b,el:"div",class:"p-gui__vector2-area",onclick:g=>{s[l]=parseFloat(this._mapLinear(g.offsetX,0,h.clientWidth,a,n).toFixed(2)),d[p]=parseFloat(this._mapLinear(g.offsetY,0,h.clientHeight,i,r).toFixed(2)),t&&t(s[l],s[p])}});let m=!1;h.addEventListener("pointerdown",g=>{m=!0}),h.addEventListener("pointerup",()=>{m=!1}),h.addEventListener("pointermove",g=>{m&&(s[l]=parseFloat(this._mapLinear(g.offsetX,0,h.clientWidth,a,n).toFixed(2)),d[p]=parseFloat(this._mapLinear(g.offsetY,0,h.clientHeight,i,r).toFixed(2)),t&&t(s[l],s[p]))}),this._createElement({parent:h,class:"p-gui__vector2-line p-gui__vector2-line-x"}),this._createElement({parent:h,class:"p-gui__vector2-line p-gui__vector2-line-y"});const y=this._createElement({parent:h,class:"p-gui__vector2-dot"});y.style.left=this._mapLinear(s[l],a,n,0,h.clientWidth)+"px",y.style.top=this._mapLinear(d[p],r,i,h.clientHeight,0)+"px",Object.defineProperty(s,l,{set:g=>{this.propReferences[c]=g,y.style.left=this._mapLinear(g,a,n,0,h.clientWidth)+"px",_.textContent=String(g)+", "+d[p]},get:()=>this.propReferences[c]}),Object.defineProperty(d,p,{set:g=>{this.propReferences[f]=g,y.style.top=this._mapLinear(g,r,i,h.clientHeight,0)+"px",_.textContent=s[l]+", "+String(g)},get:()=>this.propReferences[f]})}color(e={},t){if(typeof e!="object")throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);let o=typeof e.name=="string"&&e.name||" ",a=!1,n=null,r=e.obj||e.object,i=e.prop||e.property,s;if(typeof e.value=="string"&&(e.value.length!=7||e.value[0]!="#"?console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`):s=e.value),s||(s="#000000"),e.value!==void 0)(i!=null||r!=null)&&console.warn('[GUI] color() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(i!=null&&r!=null){if(typeof i!="string")throw Error(`[GUI] color() "prop" (or "property") parameter must be an string. Received: ${typeof i}.`);if(typeof r!="object")throw Error(`[GUI] color() "obj" (or "object") parameter must be an object. Received: ${typeof r}.`);o==" "&&(o=i),n=this.propReferences.push(r[i])-1,a=!0}else(i!=null&&r==null||i==null&&r==null)&&console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');this.imageContainer=null;const l=this._createElement({el:"div",class:"p-gui__color",textContent:o}),c=this._createElement({parent:l,el:"input",class:"p-gui__color-picker",type:"color",value:s});typeof t=="function"&&c.addEventListener("input",()=>{a?r[i]=c.value:typeof t=="function"&&t(c.value)}),a&&Object.defineProperty(r,i,{set:d=>{this.propReferences[n]=d,c.value=d,typeof t=="function"&&t(d)},get:()=>this.propReferences[n]})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,o=e.name||"",a=e.color||null,n=e.maxHeight||null;this.imageContainer=null;let r="p-gui__folder";this.folders.length==0&&(r+=" p-gui__folder--first"),t&&(r+=" p-gui__folder--closed");let i=a?`background-color: ${a};`:"";i+=n?`max-height: ${n}px;`:"";let s=this._createElement({class:r,inline:i});this._createElement({innerHTML:`<span class="p-gui__folder-arrow"></span>${o}`,class:"p-gui__folder-header",onclick:function(){this.parentNode.classList.toggle("p-gui__folder--closed")},parent:s});let l=new u({isFolder:!0,folderOptions:{wrapper:s}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",a);function t(n){n.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=n.clientX,e.position.prevY=n.clientY,document.addEventListener("pointermove",o)}function o(n){n.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+n.clientX-e.position.prevX,e.position.y=e.position.initY+n.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function a(n){document.removeEventListener("pointermove",o)}}toggleClose(){this.closed=!this.closed,this.wrapper.classList.toggle("p-gui--collapsed")}kill(){this.wrapper.remove()}_mapLinear(e,t,o,a,n){return a+(e-t)*(n-a)/(o-t)}}return u});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfect-gui",
3
- "version": "4.4.1",
3
+ "version": "4.6.3",
4
4
  "description": "Nice and simple GUI for JavaScript",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -330,20 +330,21 @@ export default class GUI {
330
330
  textContent: name
331
331
  });
332
332
 
333
-
334
333
 
335
- if (typeof callback == 'function') {
336
- image.onclick = () => {
337
- let selected = this.imageContainer.querySelectorAll('.p-gui__image--selected');
338
- for (let i = 0; i < selected.length; i++) {
339
- selected[i].classList.remove('p-gui__image--selected');
340
- }
341
- if (selectionBorder) {
342
- image.classList.add('p-gui__image--selected');
343
- }
334
+ image.onclick = () => {
335
+ let selected_items = image.parentElement.querySelectorAll('.p-gui__image--selected');
336
+ for (let i = 0; i < selected_items.length; i++) {
337
+ selected_items[i].classList.remove('p-gui__image--selected');
338
+ }
339
+ if (selectionBorder) {
340
+ image.classList.add('p-gui__image--selected');
341
+ }
342
+ if (typeof callback == 'function') {
344
343
  callback({ path, text: name });
345
- };
346
- }
344
+ }
345
+ };
346
+
347
+ return image;
347
348
  }
348
349
 
349
350
  slider (params = {}, callback) {
@@ -558,20 +559,64 @@ export default class GUI {
558
559
  }
559
560
 
560
561
  let name = typeof params.name == 'string' ? params.name : ' ';
562
+ let isObject = false;
563
+ let propReferenceIndex = null;
564
+ let obj = params.obj || params.object;
565
+ let prop = params.prop || params.property;
561
566
  let values = Array.isArray(params.values) ? params.values : null;
562
- let value = (() => {
563
- if (!values) {
564
- return null;
567
+ let value;
568
+
569
+ callback = typeof callback == 'function' ? callback : null;
570
+
571
+ // callback mode
572
+ if ( params.value !== undefined ||
573
+ (params.value === undefined && obj === undefined && prop === undefined)) {
574
+ if (prop != undefined || obj != undefined) {
575
+ console.warn(`[GUI] list() "obj" and "property" parameters are ignored when a "value" parameter is used.`);
565
576
  }
566
- if (typeof params.value == 'string') {
567
- return values.indexOf(params.value);
577
+
578
+ value = (() => {
579
+ if (!values) {
580
+ return null;
581
+ }
582
+ if (typeof params.value == 'string') {
583
+ return values.indexOf(params.value);
584
+ }
585
+ if (typeof params.value == 'number') {
586
+ return params.value;
587
+ }
588
+ })();
589
+ }
590
+
591
+ // object-binding
592
+ else if (prop != undefined && obj != undefined) {
593
+ if (typeof prop != 'string') {
594
+ throw Error(`[GUI] list() "prop" (or "property") parameter must be an string. Received: ${typeof prop}.`);
568
595
  }
569
- if (typeof params.value == 'number') {
570
- return params.value;
596
+ if (typeof obj != 'object') {
597
+ throw Error(`[GUI] list() "obj" (or "object") parameter must be an object. Received: ${typeof obj}.`);
571
598
  }
572
- })();
573
599
 
574
- callback = typeof callback == 'function' ? callback : null;
600
+ value = (() => {
601
+ if (!values) {
602
+ return null;
603
+ }
604
+ if (typeof obj[prop] == 'string') {
605
+ return values.indexOf(obj[prop]);
606
+ }
607
+ if (typeof obj[prop] == 'number') {
608
+ return obj[prop];
609
+ }
610
+ })();
611
+
612
+ propReferenceIndex = this.propReferences.push(obj[prop]) - 1;
613
+ isObject = true;
614
+ }
615
+ else {
616
+ if ((prop != undefined && obj == undefined) || (prop == undefined && obj == undefined)) {
617
+ console.warn(`[GUI] list() "obj" and "prop" parameters must be used together.`);
618
+ }
619
+ }
575
620
 
576
621
  this.imageContainer = null;
577
622
 
@@ -585,7 +630,11 @@ export default class GUI {
585
630
  el: 'select',
586
631
  class: 'p-gui__list-dropdown',
587
632
  onchange: (ev) => {
588
- if (callback) {
633
+ if ( isObject ) {
634
+ obj[prop] = ev.target.value;
635
+ }
636
+
637
+ else if (callback) {
589
638
  callback(ev.target.value);
590
639
  }
591
640
  }
@@ -608,6 +657,31 @@ export default class GUI {
608
657
  }
609
658
  });
610
659
  }
660
+
661
+ if ( isObject ) {
662
+ Object.defineProperty( obj, prop, {
663
+ set: val => {
664
+ if (typeof val == 'string') {
665
+ value = values.indexOf(val);
666
+ }
667
+ if (typeof val == 'number') {
668
+ value = val;
669
+ }
670
+
671
+ this.propReferences[propReferenceIndex] = value;
672
+
673
+ select.querySelector('[selected]').removeAttribute('selected')
674
+ select.querySelectorAll('option')[value].setAttribute('selected', '');
675
+
676
+ if (typeof callback == 'function') {
677
+ callback(value);
678
+ }
679
+ },
680
+ get: () => {
681
+ return this.propReferences[propReferenceIndex];
682
+ }
683
+ });
684
+ }
611
685
  }
612
686
 
613
687
  options(params, callback) {
@@ -730,7 +804,13 @@ export default class GUI {
730
804
  }
731
805
 
732
806
  let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
807
+
808
+ let isObject = false;
809
+ let propReferenceIndex = null;
810
+ let obj = params.obj || params.object;
811
+ let prop = params.prop || params.property;
733
812
  let value;
813
+
734
814
  if (typeof params.value == 'string') {
735
815
  if (params.value.length != 7 || params.value[0] != '#') {
736
816
  console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${params.value}".`)
@@ -741,6 +821,37 @@ export default class GUI {
741
821
  }
742
822
  if (!value) value = '#000000';
743
823
 
824
+ // callback mode
825
+ if ( params.value !== undefined ) {
826
+ if (prop != undefined || obj != undefined) {
827
+ console.warn(`[GUI] color() "obj" and "property" parameters are ignored when a "value" parameter is used.`);
828
+ }
829
+ }
830
+
831
+ // object-binding
832
+ else if (prop != undefined && obj != undefined) {
833
+ if (typeof prop != 'string') {
834
+ throw Error(`[GUI] color() "prop" (or "property") parameter must be an string. Received: ${typeof prop}.`);
835
+ }
836
+ if (typeof obj != 'object') {
837
+ throw Error(`[GUI] color() "obj" (or "object") parameter must be an object. Received: ${typeof obj}.`);
838
+ }
839
+
840
+ if (name == ' ') {
841
+ name = prop;
842
+ }
843
+
844
+ propReferenceIndex = this.propReferences.push(obj[prop]) - 1;
845
+ isObject = true;
846
+ }
847
+ else {
848
+ if ((prop != undefined && obj == undefined) || (prop == undefined && obj == undefined)) {
849
+ console.warn(`[GUI] color() "obj" and "prop" parameters must be used together.`);
850
+ }
851
+ }
852
+
853
+ this.imageContainer = null;
854
+
744
855
  const container = this._createElement({
745
856
  el: 'div',
746
857
  class: 'p-gui__color',
@@ -757,7 +868,30 @@ export default class GUI {
757
868
 
758
869
  if (typeof callback == 'function') {
759
870
  colorpicker.addEventListener('input', () => {
760
- callback(colorpicker.value);
871
+ if ( isObject ) {
872
+ obj[prop] = colorpicker.value;
873
+ }
874
+
875
+ else if (typeof callback == 'function') {
876
+ callback(colorpicker.value);
877
+ }
878
+ });
879
+ }
880
+
881
+ if ( isObject ) {
882
+ Object.defineProperty( obj, prop, {
883
+ set: val => {
884
+ this.propReferences[propReferenceIndex] = val;
885
+
886
+ colorpicker.value = val;
887
+
888
+ if (typeof callback == 'function') {
889
+ callback(val);
890
+ }
891
+ },
892
+ get: () => {
893
+ return this.propReferences[propReferenceIndex];
894
+ }
761
895
  });
762
896
  }
763
897
  }