From f7c193259ef1c8c955d261f78929783f460a6c49 Mon Sep 17 00:00:00 2001
From: Jake Read <jake.read@cba.mit.edu>
Date: Wed, 11 Dec 2019 13:08:28 -0500
Subject: [PATCH] defs stay inbound

---
 core/scope.js  |  2 +-
 view/blocks.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/core/scope.js b/core/scope.js
index 1e3d028..c3f76a8 100644
--- a/core/scope.js
+++ b/core/scope.js
@@ -107,7 +107,7 @@ export default function Scope(wrapper, tlv) {
         }
         block.handle.position.x += evt.movementX * (1 / cs)
         block.handle.position.y += evt.movementY * (1 / cs)
-        blocks.repositionBlock(block)
+        blocks.repositionDef(block.handle)
       })
     } else if ($(evt.target).is('.output')) {
       evt.preventDefault()
diff --git a/view/blocks.js b/view/blocks.js
index e113cdf..5dc046c 100644
--- a/view/blocks.js
+++ b/view/blocks.js
@@ -40,6 +40,7 @@ let getBlockStackHeight = (blocks) => {
   return y
 }
 
+// stack: just state,
 let getBlockStackWidth = (blocks) => {
   let x = 0
   for (let bl of blocks) {
@@ -50,6 +51,27 @@ let getBlockStackWidth = (blocks) => {
   return (x += 5)
 }
 
+let getBlockStackRightWidth = (blocks) => {
+  let x = getBlockStackWidth(blocks)
+  let y = 0
+  for(let bl of blocks) {
+    if($(bl).is('.output')) {
+      if(y < bl.clientWidth) y = bl.clientWidth
+    }
+  }
+  return (x + y + 5)
+}
+
+let getBlockStackLeftWidth = (blocks) => {
+  let x = 0
+  for(let bl of blocks){
+    if($(bl).is('.input')){
+      if(x < bl.clientWidth) x = bl.clientWidth
+    }
+  }
+  return (x += 5)
+}
+
 // oboy,
 let makeLink = (ldef, titleblock) => {
   // ok, we have a new link,
@@ -80,8 +102,9 @@ let makeLink = (ldef, titleblock) => {
           size.y += deltas.y
           dt.writeContainerSize(view.plane, size)
           repositionDef(ldef)
-          if(ldef.downstream){
-            repositionDef(ldef.downstream)
+          // reposition all defs in the downstream: we might be squishing them about:
+          for(let dsdef of ldef.downstream.context.defs){
+            repositionDef(dsdef)
           }
         }
         // and,
@@ -469,6 +492,38 @@ let repositionBlock = (block) => {
 }
 
 let repositionDef = (def) => {
+  // context bounds ...
+  if(!def.context.plane) {
+    // not completely unlikely, invisible views refreshing, perhaps... but those
+    // should come thru ah reposition check-switch, not here direct, so
+    console.warn('reposition for invisible def, wyd?')
+    return
+  }
+  // hmmm ... ok, for our siblings' children, we are subject to not-overrun them,
+  for(let df of def.context.defs){
+    if(def.contains){
+      if(def.contains.plane){
+        // this one's tricky: we have potentially many-sub-planes, let's just
+        // stick to not-excaping-our-own-bounds for now,
+      }
+    }
+  }
+  // ok, for our parents:
+  // ah ... titles drag blocks, not defs ... maybe they should drag defs.
+  if(def.context.within){
+    let bw = def.context.plane.clientWidth
+    let bh = def.context.plane.clientHeight
+    // clip to bounds, plus some margin...
+    let wr = getBlockStackRightWidth(def.blocks)
+    let wl = getBlockStackLeftWidth(def.blocks)
+    console.log(wl)
+    let h = getBlockStackHeight(def.blocks)
+    // cover bottom left:
+    if(def.position.x + wr > bw) def.position.x = bw - wr
+    if(def.position.y + h > bh) def.position.y = bh - h
+    if(def.position.x - wl < 0) def.position.x = wl
+    if(def.position.y < 0) def.position.y = 0
+  }
   // arrange,
   if (def.blocks) {
     for (let bl of def.blocks) {
-- 
GitLab