From 09e15ddf169950825e02dbb031d6f8a83b651a85 Mon Sep 17 00:00:00 2001
From: TheFGFSEagle <thefgfseagle@gmail.com>
Date: Wed, 21 Dec 2022 10:14:19 +0100
Subject: [PATCH] Added canvas checkbox subclass whose check state is always
 the bool value of a node and vice versa

---
 Nasal/canvas/gui.nas                         |  2 ++
 Nasal/canvas/gui/widgets/PropertyWidgets.nas | 33 ++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 Nasal/canvas/gui/widgets/PropertyWidgets.nas

diff --git a/Nasal/canvas/gui.nas b/Nasal/canvas/gui.nas
index 9d6c1bb1b..9ba19a7ed 100644
--- a/Nasal/canvas/gui.nas
+++ b/Nasal/canvas/gui.nas
@@ -37,6 +37,7 @@ loadWidget("Button");
 loadWidget("CheckBox");
 loadWidget("Label");
 loadWidget("LineEdit");
+loadWidget("PropertyWidgets");
 loadWidget("ScrollArea");
 loadWidget("Rule");
 loadWidget("Slider");
@@ -308,6 +309,7 @@ var Window = {
   {
     me._ghost.show();
     me.raise();
+    me._canvas.update();
   },
   # Hide / show the window based on whether it's currently visible
   toggle: func()
diff --git a/Nasal/canvas/gui/widgets/PropertyWidgets.nas b/Nasal/canvas/gui/widgets/PropertyWidgets.nas
new file mode 100644
index 000000000..9e9c911da
--- /dev/null
+++ b/Nasal/canvas/gui/widgets/PropertyWidgets.nas
@@ -0,0 +1,33 @@
+# PropertyWidgets.nas - subclassed canvas widgets that are synced with a property node
+
+# SPDX-FileCopyrightText: (C) 2022 Frederic Croix <thefgfseagle@gmail.com>
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+gui.widgets.PropertyCheckBox = {
+	new: func(node, parent, style, cfg) {
+		if (!isa(node, props.Node)) {
+			node = props.globals.getNode(node, 1);
+		}
+		
+		var m = gui.widgets.CheckBox.new(parent, style, cfg);
+		m._checkable = 1;
+		m._node = node;
+
+		append(m.parents, gui.widgets.PropertyCheckBox);
+		
+		m.setChecked(m._node.getBoolValue());
+		m.listen("toggled", func(e) {
+			m._node.setBoolValue(int(e.detail.checked));
+		});
+		m._listener = setlistener(m._node, func(n) {
+			m.setChecked(n.getBoolValue());
+		}, 1, 0);
+		
+		return m;
+	},
+	
+	del: func {
+		removelistener(me._listener);
+	},
+};
+