perfect-gui 4.4.0 → 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 u {
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 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(`${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 u {
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 u {
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,141 +490,181 @@ class u {
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(/^.*[\\\/]/, ""), o;
512
- e.name == null ? o = r : o = typeof e.name == "string" && e.name || " ";
513
- const s = e.selected === !0, a = e.selectionBorder !== !1;
514
- let n = "";
515
- e.width && (typeof e.width == "number" && (e.width += "px"), n += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), n += `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 + "); " + n,
520
+ inline: "background-image: url(" + o + "); " + s,
521
521
  parent: this.imageContainer
522
522
  });
523
- s && a && 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: o
527
- }), typeof t == "function" && (l.onclick = () => {
528
- let g = this.imageContainer.querySelectorAll(".p-gui__image--selected");
529
- for (let d = 0; d < g.length; d++)
530
- g[d].classList.remove("p-gui__image--selected");
531
- a && l.classList.add("p-gui__image--selected"), t({ path: i, text: o });
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, o = null, s = e.obj || e.object, a = e.prop || e.property, n = typeof e.value == "number" ? e.value : null, l = e.min ?? 0, g = e.max ?? 1, d = e.step || (g - l) / 100;
538
- if (n !== null)
539
- (a != null || s != null) && console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');
540
- else if (a != null && s != null) {
541
- if (typeof a != "string")
542
- throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof a}.`);
543
- if (typeof s != "object")
544
- throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof s}.`);
545
- i == " " && (i = a), o = this.propReferences.push(s[a]) - 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
- (a != null && s == null || a == null && s == null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), n = (g - 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 h = this._createElement({
549
+ var p = this._createElement({
550
550
  class: "p-gui__slider",
551
- textContent: i
552
- }), f = this._createElement({
553
- parent: h,
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: g,
559
+ max: c,
560
560
  step: d,
561
- value: r ? s[a] : n
561
+ value: a ? r[i] : s
562
562
  }
563
- }), _ = this._createElement({
564
- parent: h,
563
+ }), g = this._createElement({
564
+ parent: p,
565
565
  class: "p-gui__slider-value",
566
- textContent: String(r ? s[a] : n)
566
+ textContent: String(a ? r[i] : s)
567
567
  });
568
- f.addEventListener("input", () => {
569
- _.textContent = f.value, r && (s[a] = f.value), typeof t == "function" && t(parseFloat(f.value));
570
- }), r && Object.defineProperty(s, a, {
571
- set: (b) => {
572
- this.propReferences[o] = b, f.value = b, _.textContent = String(b);
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
+ set: (_) => {
572
+ this.propReferences[n] = _, u.value = _, g.textContent = String(_), typeof t == "function" && t(parseFloat(u.value));
573
573
  },
574
- get: () => this.propReferences[o]
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 = e.value === !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
+ } else
590
+ (i != null && r == null || i == null && r == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
581
591
  this.imageContainer = null;
582
- let o = this._createElement({
592
+ const l = this._createElement({
583
593
  class: "p-gui__switch",
584
- onclick: (a) => {
585
- let n = a.target.childNodes[1], l = !0;
586
- n.classList.contains("p-gui__switch-checkbox--active") && (l = !1), n.classList.toggle("p-gui__switch-checkbox--active"), typeof t == "function" && t(l);
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);
587
598
  },
588
- textContent: i
589
- }), s = r ? " p-gui__switch-checkbox--active" : "";
590
- this._createElement({
591
- parent: o,
592
- class: "p-gui__switch-checkbox" + s
599
+ textContent: o
600
+ });
601
+ let c = (() => a ? r[i] ? " p-gui__switch-checkbox--active" : "" : s ? " p-gui__switch-checkbox--active" : "")();
602
+ const d = this._createElement({
603
+ parent: l,
604
+ class: "p-gui__switch-checkbox" + c
605
+ });
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
+ },
610
+ get: () => this.propReferences[n]
593
611
  });
594
612
  }
595
613
  list(e = {}, t) {
596
614
  if (typeof e != "object")
597
615
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);
598
- let i = typeof e.name == "string" ? e.name : " ", r = Array.isArray(e.values) ? e.values : null, o = (() => {
599
- if (!r)
600
- return null;
601
- if (typeof e.value == "string")
602
- return r.indexOf(e.value);
603
- if (typeof e.value == "number")
604
- return e.value;
605
- })();
606
- t = typeof t == "function" ? t : null, this.imageContainer = null;
607
- let s = 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({
608
643
  class: "p-gui__list",
609
- textContent: i
610
- }), a = this._createElement({
611
- parent: s,
644
+ textContent: o
645
+ }), d = this._createElement({
646
+ parent: c,
612
647
  el: "select",
613
648
  class: "p-gui__list-dropdown",
614
- onchange: (n) => {
615
- t && t(n.target.value);
649
+ onchange: (p) => {
650
+ a ? r[i] = p.target.value : t && t(p.target.value);
616
651
  }
617
652
  });
618
- r && r.forEach((n, l) => {
653
+ s && s.forEach((p, u) => {
619
654
  let g = this._createElement({
620
- parent: a,
655
+ parent: d,
621
656
  el: "option",
622
657
  customAttributes: {
623
- value: n
658
+ value: p
624
659
  },
625
- textContent: n
660
+ textContent: p
626
661
  });
627
- o == l && g.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]
628
668
  });
629
669
  }
630
670
  options(e, t) {
@@ -635,109 +675,124 @@ class u {
635
675
  vector2(e = {}, t) {
636
676
  if (typeof e != "object")
637
677
  throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
638
- let i = typeof e.name == "string" && e.name || " ";
639
- const r = e.x.min ?? 0, o = e.x.max ?? 1, s = e.y.min ?? 0, a = e.y.max ?? 1, n = e.x.obj || e.x.object, l = e.x.prop || e.x.property, g = this.propReferences.push(n[l]) - 1, d = e.y.obj || e.y.object, h = e.y.prop || e.y.property, f = this.propReferences.push(d[h]) - 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;
640
680
  t = typeof t == "function" ? t : null, this.imageContainer = null;
641
- const _ = this._createElement({
681
+ const g = this._createElement({
642
682
  class: "p-gui__vector2",
643
- textContent: i
644
- }), b = this._createElement({
645
- parent: _,
683
+ textContent: o
684
+ }), _ = this._createElement({
685
+ parent: g,
646
686
  class: "p-gui__vector-value",
647
- textContent: n[l] + ", " + d[h]
648
- }), c = this._createElement({
649
- parent: _,
687
+ textContent: s[l] + ", " + d[p]
688
+ }), h = this._createElement({
689
+ parent: g,
650
690
  el: "div",
651
691
  class: "p-gui__vector2-area",
652
- onclick: (p) => {
653
- n[l] = parseFloat(this._mapLinear(p.offsetX, 0, c.clientWidth, r, o).toFixed(2)), d[h] = parseFloat(this._mapLinear(p.offsetY, 0, c.clientHeight, a, s).toFixed(2)), t && t(n[l], n[h]);
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]);
654
694
  }
655
695
  });
656
- let m = !1;
657
- c.addEventListener("pointerdown", (p) => {
658
- m = !0;
659
- }), c.addEventListener("pointerup", () => {
660
- m = !1;
661
- }), c.addEventListener("pointermove", (p) => {
662
- m && (n[l] = parseFloat(this._mapLinear(p.offsetX, 0, c.clientWidth, r, o).toFixed(2)), d[h] = parseFloat(this._mapLinear(p.offsetY, 0, c.clientHeight, a, s).toFixed(2)), t && t(n[l], n[h]));
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]));
663
703
  }), this._createElement({
664
- parent: c,
704
+ parent: h,
665
705
  class: "p-gui__vector2-line p-gui__vector2-line-x"
666
706
  }), this._createElement({
667
- parent: c,
707
+ parent: h,
668
708
  class: "p-gui__vector2-line p-gui__vector2-line-y"
669
709
  });
670
710
  const x = this._createElement({
671
- parent: c,
711
+ parent: h,
672
712
  class: "p-gui__vector2-dot"
673
713
  });
674
- x.style.left = this._mapLinear(n[l], r, o, 0, c.clientWidth) + "px", x.style.top = this._mapLinear(d[h], s, a, c.clientHeight, 0) + "px", Object.defineProperty(n, l, {
675
- set: (p) => {
676
- this.propReferences[g] = p, x.style.left = this._mapLinear(p, r, o, 0, c.clientWidth) + "px", b.textContent = String(p) + ", " + d[h];
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];
677
717
  },
678
- get: () => this.propReferences[g]
679
- }), Object.defineProperty(d, h, {
680
- set: (p) => {
681
- this.propReferences[f] = p, x.style.top = this._mapLinear(p, s, a, c.clientHeight, 0) + "px", b.textContent = n[l] + ", " + String(p);
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);
682
722
  },
683
- get: () => this.propReferences[f]
723
+ get: () => this.propReferences[u]
684
724
  });
685
725
  }
686
726
  color(e = {}, t) {
687
727
  if (typeof e != "object")
688
728
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);
689
- let i = typeof e.name == "string" && e.name || " ", r;
690
- 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");
691
- const o = 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({
692
742
  el: "div",
693
743
  class: "p-gui__color",
694
- textContent: i
695
- }), s = this._createElement({
696
- parent: o,
744
+ textContent: o
745
+ }), c = this._createElement({
746
+ parent: l,
697
747
  el: "input",
698
748
  class: "p-gui__color-picker",
699
749
  type: "color",
700
- value: r
750
+ value: s
701
751
  });
702
- typeof t == "function" && s.addEventListener("input", () => {
703
- t(s.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]
704
759
  });
705
760
  }
706
761
  folder(e = {}) {
707
- let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.name || "", r = e.color || null, o = e.maxHeight || null;
762
+ let t = typeof e.closed == "boolean" ? e.closed : !1, o = e.name || "", a = e.color || null, n = e.maxHeight || null;
708
763
  this.imageContainer = null;
709
- let s = "p-gui__folder";
710
- this.folders.length == 0 && (s += " p-gui__folder--first"), t && (s += " p-gui__folder--closed");
711
- let a = r ? `background-color: ${r};` : "";
712
- a += o ? `max-height: ${o}px;` : "";
713
- let n = this._createElement({
714
- class: s,
715
- inline: a
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
716
771
  });
717
772
  this._createElement({
718
- innerHTML: `<span class="p-gui__folder-arrow"></span>${i}`,
773
+ innerHTML: `<span class="p-gui__folder-arrow"></span>${o}`,
719
774
  class: "p-gui__folder-header",
720
775
  onclick: function() {
721
776
  this.parentNode.classList.toggle("p-gui__folder--closed");
722
777
  },
723
- parent: n
778
+ parent: s
724
779
  });
725
- let l = new u({ isFolder: !0, folderOptions: {
726
- wrapper: n
780
+ let l = new b({ isFolder: !0, folderOptions: {
781
+ wrapper: s
727
782
  } });
728
783
  return this.folders.push(l), l;
729
784
  }
730
785
  _makeDraggable() {
731
786
  var e = this;
732
- this.header.addEventListener("pointerdown", t), this.header.addEventListener("pointerup", r);
733
- function t(o) {
734
- o.preventDefault(), e.position.initX = e.position.x, e.position.initY = e.position.y, e.position.prevX = o.clientX, e.position.prevY = o.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);
735
790
  }
736
- function i(o) {
737
- o.preventDefault(), e.hasBeenDragged || (e.hasBeenDragged = !0, e.wrapper.setAttribute("data-dragged", "true")), e.position.x = e.position.initX + o.clientX - e.position.prevX, e.position.y = e.position.initY + o.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)";
738
793
  }
739
- function r(o) {
740
- document.removeEventListener("pointermove", i);
794
+ function a(n) {
795
+ document.removeEventListener("pointermove", o);
741
796
  }
742
797
  }
743
798
  toggleClose() {
@@ -746,10 +801,10 @@ class u {
746
801
  kill() {
747
802
  this.wrapper.remove();
748
803
  }
749
- _mapLinear(e, t, i, r, o) {
750
- return r + (e - t) * (o - r) / (i - t);
804
+ _mapLinear(e, t, o, a, n) {
805
+ return a + (e - t) * (n - a) / (o - t);
751
806
  }
752
807
  }
753
808
  export {
754
- u as default
809
+ b as default
755
810
  };
@@ -1,4 +1,4 @@
1
- (function(_,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(_=typeof globalThis<"u"?globalThis:_||self,_["Perfect GUI"]=c())})(this,function(){"use strict";function _(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(`${_(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(/^.*[\\\/]/,""),o;e.name==null?o=r:o=typeof e.name=="string"&&e.name||" ";const s=e.selected===!0,a=e.selectionBorder!==!1;let n="";e.width&&(typeof e.width=="number"&&(e.width+="px"),n+=`flex: 0 0 calc(${e.width} - 5px); `),e.height&&(typeof e.height=="number"&&(e.height+="px"),n+=`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+"); "+n,parent:this.imageContainer});s&&a&&l.classList.add("p-gui__image--selected"),this._createElement({parent:l,class:"p-gui__image-text",textContent:o}),typeof t=="function"&&(l.onclick=()=>{let g=this.imageContainer.querySelectorAll(".p-gui__image--selected");for(let h=0;h<g.length;h++)g[h].classList.remove("p-gui__image--selected");a&&l.classList.add("p-gui__image--selected"),t({path:i,text:o})})}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,o=null,s=e.obj||e.object,a=e.prop||e.property,n=typeof e.value=="number"?e.value:null,l=e.min??0,g=e.max??1,h=e.step||(g-l)/100;if(n!==null)(a!=null||s!=null)&&console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(a!=null&&s!=null){if(typeof a!="string")throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof a}.`);if(typeof s!="object")throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof s}.`);i==" "&&(i=a),o=this.propReferences.push(s[a])-1,r=!0}else(a!=null&&s==null||a==null&&s==null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),n=(g-l)/2;this.imageContainer=null;var u=this._createElement({class:"p-gui__slider",textContent:i}),f=this._createElement({parent:u,el:"input",class:"p-gui__slider-ctrl",customAttributes:{type:"range",min:l,max:g,step:h,value:r?s[a]:n}}),x=this._createElement({parent:u,class:"p-gui__slider-value",textContent:String(r?s[a]:n)});f.addEventListener("input",()=>{x.textContent=f.value,r&&(s[a]=f.value),typeof t=="function"&&t(parseFloat(f.value))}),r&&Object.defineProperty(s,a,{set:b=>{this.propReferences[o]=b,f.value=b,x.textContent=String(b)},get:()=>this.propReferences[o]})}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=e.value===!0;this.imageContainer=null;let o=this._createElement({class:"p-gui__switch",onclick:a=>{let n=a.target.childNodes[1],l=!0;n.classList.contains("p-gui__switch-checkbox--active")&&(l=!1),n.classList.toggle("p-gui__switch-checkbox--active"),typeof t=="function"&&t(l)},textContent:i}),s=r?" p-gui__switch-checkbox--active":"";this._createElement({parent:o,class:"p-gui__switch-checkbox"+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,o=(()=>{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 s=this._createElement({class:"p-gui__list",textContent:i}),a=this._createElement({parent:s,el:"select",class:"p-gui__list-dropdown",onchange:n=>{t&&t(n.target.value)}});r&&r.forEach((n,l)=>{let g=this._createElement({parent:a,el:"option",customAttributes:{value:n},textContent:n});o==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,o=e.x.max??1,s=e.y.min??0,a=e.y.max??1,n=e.x.obj||e.x.object,l=e.x.prop||e.x.property,g=this.propReferences.push(n[l])-1,h=e.y.obj||e.y.object,u=e.y.prop||e.y.property,f=this.propReferences.push(h[u])-1;t=typeof t=="function"?t:null,this.imageContainer=null;const x=this._createElement({class:"p-gui__vector2",textContent:i}),b=this._createElement({parent:x,class:"p-gui__vector-value",textContent:n[l]+", "+h[u]}),p=this._createElement({parent:x,el:"div",class:"p-gui__vector2-area",onclick:d=>{n[l]=parseFloat(this._mapLinear(d.offsetX,0,p.clientWidth,r,o).toFixed(2)),h[u]=parseFloat(this._mapLinear(d.offsetY,0,p.clientHeight,a,s).toFixed(2)),t&&t(n[l],n[u])}});let y=!1;p.addEventListener("pointerdown",d=>{y=!0}),p.addEventListener("pointerup",()=>{y=!1}),p.addEventListener("pointermove",d=>{y&&(n[l]=parseFloat(this._mapLinear(d.offsetX,0,p.clientWidth,r,o).toFixed(2)),h[u]=parseFloat(this._mapLinear(d.offsetY,0,p.clientHeight,a,s).toFixed(2)),t&&t(n[l],n[u]))}),this._createElement({parent:p,class:"p-gui__vector2-line p-gui__vector2-line-x"}),this._createElement({parent:p,class:"p-gui__vector2-line p-gui__vector2-line-y"});const m=this._createElement({parent:p,class:"p-gui__vector2-dot"});m.style.left=this._mapLinear(n[l],r,o,0,p.clientWidth)+"px",m.style.top=this._mapLinear(h[u],s,a,p.clientHeight,0)+"px",Object.defineProperty(n,l,{set:d=>{this.propReferences[g]=d,m.style.left=this._mapLinear(d,r,o,0,p.clientWidth)+"px",b.textContent=String(d)+", "+h[u]},get:()=>this.propReferences[g]}),Object.defineProperty(h,u,{set:d=>{this.propReferences[f]=d,m.style.top=this._mapLinear(d,s,a,p.clientHeight,0)+"px",b.textContent=n[l]+", "+String(d)},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 o=this._createElement({el:"div",class:"p-gui__color",textContent:i}),s=this._createElement({parent:o,el:"input",class:"p-gui__color-picker",type:"color",value:r});typeof t=="function"&&s.addEventListener("input",()=>{t(s.value)})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.name||"",r=e.color||null,o=e.maxHeight||null;this.imageContainer=null;let s="p-gui__folder";this.folders.length==0&&(s+=" p-gui__folder--first"),t&&(s+=" p-gui__folder--closed");let a=r?`background-color: ${r};`:"";a+=o?`max-height: ${o}px;`:"";let n=this._createElement({class:s,inline:a});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:n});let l=new c({isFolder:!0,folderOptions:{wrapper:n}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",r);function t(o){o.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=o.clientX,e.position.prevY=o.clientY,document.addEventListener("pointermove",i)}function i(o){o.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+o.clientX-e.position.prevX,e.position.y=e.position.initY+o.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function r(o){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,o){return r+(e-t)*(o-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.0",
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
  }