From bbd9c4a1c911a74c81a4853f402245f2568341c8 Mon Sep 17 00:00:00 2001
From: Guillem <guillembartrina@gmail.com>
Date: Mon, 17 Aug 2020 14:50:59 +0200
Subject: [PATCH] add visual markings for dirty abstractions all the way up

---
 pd/nw/pdgui.js    | 18 ++++++++++++++++++
 pd/src/g_canvas.c | 15 +++++++++++++++
 pd/src/g_canvas.h |  1 +
 pd/src/g_editor.c |  6 ++++++
 pd/src/g_text.c   |  8 ++++++++
 5 files changed, 48 insertions(+)

diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index d172ee900..ef461b1cb 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -2659,6 +2659,24 @@ function gui_gobj_deselect(cid, tag) {
     });
 }
 
+function gui_gobj_setdirty(cid, tag, state) {
+    var color;
+    switch (state) {
+        case 1:
+            color = "crimson";
+            break;
+        case 2:
+            color = "coral";
+            break;
+        default:
+            color = "none";
+            break;
+    }
+    gui(cid).get_elem(tag + "text", function(e) {
+        e.setAttribute("stroke", color);
+    });
+}
+
 function gui_canvas_emphasize(cid) {
     gui(cid).get_elem("patchsvg", function(e) {
         // raise the window
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index b7b6d5ad1..95b8b5a70 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -481,6 +481,8 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
     }
     else x->gl_isab = 0;
 
+    x->gl_subdirties = 0;
+
     if (yloc < GLIST_DEFCANVASYLOC)
         yloc = GLIST_DEFCANVASYLOC;
     if (xloc < 0)
@@ -794,6 +796,19 @@ void canvas_dirty(t_canvas *x, t_floatarg n)
         x2->gl_dirty = n;
         if (x2->gl_havewindow)
             canvas_reflecttitle(x2);
+        if (x2->gl_owner)
+        {
+            gobj_isdirty(x2->gl_owner, x2,
+                (x2->gl_dirty ? 1 : (x2->gl_subdirties ? 2 : 0)));
+            x2 = x2->gl_owner;
+            while(x2->gl_owner)
+            {
+                x2->gl_subdirties += (n ? 1 : -1);
+                if(!x2->gl_dirty)
+                    gobj_isdirty(x2->gl_owner, x2, (x2->gl_subdirties ? 2 : 0));
+                x2 = x2->gl_owner;
+            }
+        }
     }
 }
 
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index dc4ce7f22..73078aa5a 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -225,6 +225,7 @@ struct _glist
     unsigned int gl_havewindow:1;   /* true if we own a window */
     unsigned int gl_mapped:1;       /* true if, moreover, it's "mapped" */
     unsigned int gl_dirty:1;        /* (root canvas only:) patch has changed */
+    int gl_subdirties;
     unsigned int gl_loading:1;      /* am now loading from file */
     unsigned int gl_willvis:1;      /* make me visible after loading */ 
     unsigned int gl_edit:1;         /* edit mode */
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index ff61bbd60..e526e1fb6 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -5914,6 +5914,12 @@ static void gobj_emphasize(t_glist *g, t_gobj *x)
     gui_vmess("gui_gobj_emphasize", "xs", g, rtext_gettag(y));
 }
 
+void gobj_isdirty(t_glist *g, t_gobj *x, int on)
+{
+    t_rtext *y = glist_findrtext(g, (t_text *)x);
+    gui_vmess("gui_gobj_setdirty", "xsi", g, rtext_gettag(y), on);
+}
+
 static int glist_dofinderror(t_glist *gl, void *error_object)
 {
     t_gobj *g;
diff --git a/pd/src/g_text.c b/pd/src/g_text.c
index 2a1ef4879..b8c25cafd 100644
--- a/pd/src/g_text.c
+++ b/pd/src/g_text.c
@@ -2121,6 +2121,14 @@ static void text_vis(t_gobj *z, t_glist *glist, int vis)
                 text_drawborder(x, glist, rtext_gettag(y),
                     rtext_width(y), rtext_height(y), 1);
                 rtext_draw(y);
+
+                if(pd_class(&x->te_pd) == canvas_class)
+                {
+                    if (((t_canvas *)x)->gl_dirty)
+                        gobj_isdirty(glist, x, 1);
+                    else if (((t_canvas *)x)->gl_subdirties)
+                        gobj_isdirty(glist, x, 2);
+                }
             }
         }
         else
-- 
GitLab