Move SSD review hit testing to typed Kotlin

ober

572497325ba060a5b6ec3c1a821b7ff7d7fd1906

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 8075c89..2870f64 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -1236,7 +1236,8 @@
     (typed-kotlin-file "com/sfb/ssdreview/SsdReviewGeometry.kt"
       (kotlin-imports (android graphics Bitmap))
       (typed-library (com sfb ssdreview)
-        (export hitGroupId selectionMatchingCells cellIdsForSelection
+        (export hitGroupId hitGroupIdForSession
+                selectionMatchingCells cellIdsForSelection
                 clampInitialScale clampScale clampGroupFitScale
                 clampViewportOffset clampImageCoordinate
                 focusGroupScale groupCenterPoint
@@ -1266,6 +1267,7 @@
         (type Float32)
         (type FloatArray)
         (type Bitmap)
+        (type SsdSession)
         (extern (reviewBitmapWidth (bitmap : Bitmap)) : Int32
           (kotlin-member-get width))
         (extern (reviewBitmapHeight (bitmap : Bitmap)) : Int32
@@ -1527,7 +1529,14 @@
             (let ((group (list-ref groups i)))
               (if (pointInPaddedGroup? group x y pad)
                   (nullable-some (SsdGroup-id group))
-                  found))))))
+                  found))))
+        (def (hitGroupIdForSession (session : (Nullable SsdSession))
+                                   (x : Float32)
+                                   (y : Float32)
+                                   (pad : Float32)) : (Nullable String)
+          (if (nullable-null? session)
+            (nullable-none String)
+            (hitGroupId (SsdSession-groups (nullable-get session)) x y pad)))))
 
     (typed-kotlin-file "com/sfb/ssdreview/TruthStoreCounters.kt"
       (typed-library (com sfb ssdreview)
@@ -8399,7 +8408,7 @@
        "                    finishSelection()"
        "                } else if (touchTapReady(selectMode, moved, motionActionIsUp(event.actionMasked, MotionEvent.ACTION_UP))) {"
        "                    val point = viewToImage(event.x, event.y)"
-       "                    val tappedGroup = hitGroup(point[0], point[1])"
+       "                    val tappedGroup = hitGroupIdForSession(session, point[0], point[1], hitGroupPad(scale))"
        "                    if (nullableTextPresent(tappedGroup)) {"
        "                        val tappedGroupId = nullableTextOrEmpty(tappedGroup)"
        "                        selectedGroupId = tappedGroupId"
@@ -8691,13 +8700,6 @@
        "        return point"
        "    }"
        ""
-       "    private fun hitGroup(x: Float, y: Float): String? {"
-       "        if (sessionMissing(session)) return null"
-       "        val sess = ssdSessionOrEmpty(session)"
-       "        val pad = hitGroupPad(scale)"
-       "        return hitGroupId(sess.groups, x, y, pad)"
-       "    }"
-       ""
        "}"
        ))
     (kotlin-file-lines "com/sfb/ssdreview/TruthStore.kt"