Generate SSD group selection helpers from typed Jerboa

ober

41f7478963fc3b117a6abf74b614e1f688bcf6b0

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 6a0fa57..1877e50 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4874,8 +4874,13 @@
                 collectSsdPdfChoicesFromDownloadFiles
                 mainActivityInstallReviewViewCallbacks
                 mainActivitySelectGroupId
+                mainActivitySelectGroup
                 mainActivitySelectRequestedGroup
                 mainActivitySelectCurrentGroup
+                mainActivitySelectedGroup
+                mainActivitySelectRelativeGroup
+                mainActivityFinalizeGroupLabel
+                mainActivityFocusBoxTypeDropdown
                 mainActivityAddApprovedAreaGroup
                 mainActivityAppendAreaToGroup
                 mainActivitySuppressGroupAsDeleted
@@ -5167,6 +5172,9 @@
           (kotlin-member-call getButton))
         (extern (alertDialogDismissRaw (dialog : AlertDialog)) : Unit
           (kotlin-member-call dismiss))
+        (extern (alertDialogWindowOrNull
+                  (dialog : AlertDialog)) : (Nullable Window)
+          (kotlin-member-get window))
         (extern (autoCompleteDropDownHeightSet
                   (view : AutoCompleteTextView)
                   (height : Int32)) : Unit
@@ -5308,6 +5316,10 @@
                   (boxType : (Nullable BoxType))
                   (fallback : String)) : String
           (kotlin-call resolvedBoxTypeIdOr))
+        (extern (boxTypesDisplayFromActivity
+                  (activity : MainActivity)
+                  (id : String)) : String
+          (kotlin-call boxTypesDisplayAndroid))
         (extern (stringLines (text : String)) : (List String)
           (kotlin-member-call lines))
         (extern (stringSplitTwoChars (text : String)
@@ -5609,10 +5621,6 @@
                   (rect : FloatArray)
                   (detectedIds : (List String))) : Unit
           (kotlin-member-call handleAreaSelected))
-        (extern (mainActivitySelectGroupRaw
-                  (activity : MainActivity)
-                  (groupId : String)) : Unit
-          (kotlin-member-call selectGroup))
         (extern (mainActivityRenderCurrentPageRaw
                   (activity : MainActivity)) : Unit
           (kotlin-member-call renderCurrentPage))
@@ -6530,7 +6538,8 @@
           (reviewViewClearInteractionStateRaw view))
         (def (mainActivityInstallReviewViewCallbacks
                (activity : MainActivity)
-               (view : SsdReviewView)) : Unit
+               (view : SsdReviewView)
+               (groupTapFeedback : Int32)) : Unit
           (begin
             (reviewViewOnStatusSet
               view
@@ -6543,13 +6552,39 @@
             (reviewViewOnGroupTappedSet
               view
               (lambda ((groupId : String))
-                (mainActivitySelectGroupRaw activity groupId)))))
+                (mainActivitySelectGroup
+                  activity
+                  view
+                  (mainActivityCurrentSessionRaw activity)
+                  (nullable-some groupId)
+                  groupTapFeedback)))))
         (def (mainActivitySelectGroupId (activity : MainActivity)
                                         (view : SsdReviewView)
                                         (id : (Nullable String))) : Unit
           (begin
             (mainActivitySelectedGroupIdSet activity id)
             (reviewViewSelectGroupId view id)))
+        (def (mainActivitySelectGroup
+               (activity : MainActivity)
+               (view : SsdReviewView)
+               (session : (Nullable SsdSession))
+               (groupId : (Nullable String))
+               (feedbackConstant : Int32)) : Unit
+          (let ((group
+                  (mainActivitySelectRequestedGroup
+                    activity
+                    view
+                    session
+                    groupId)))
+            (if (ssdGroupMissing group)
+              (begin)
+              (let ((selectedGroup (ssdGroupOrEmpty group)))
+                (begin
+                  (reviewViewCenterOnGroup view selectedGroup)
+                  (reviewViewPerformHaptic view feedbackConstant)
+                  (mainActivitySetStatusRaw
+                    activity
+                    (selectedGroupStatus selectedGroup)))))))
         (def (mainActivitySelectRequestedGroup
                (activity : MainActivity)
                (view : SsdReviewView)
@@ -6580,6 +6615,57 @@
                   view
                   (nullable-some (SsdGroup-id (nullable-get group))))
                 group))))
+        (def (mainActivitySelectedGroup
+               (activity : MainActivity)
+               (view : SsdReviewView)
+               (session : (Nullable SsdSession))
+               (groupId : (Nullable String))) : (Nullable SsdGroup)
+          (mainActivitySelectCurrentGroup activity view session groupId))
+        (def (mainActivitySelectRelativeGroup
+               (activity : MainActivity)
+               (view : SsdReviewView)
+               (session : (Nullable SsdSession))
+               (groupId : (Nullable String))
+               (delta : Int32)
+               (feedbackConstant : Int32)) : Unit
+          (let ((next (ssdCurrentRelativeGroupId session groupId delta)))
+            (if (nullableTextPresent next)
+              (mainActivitySelectGroup
+                activity
+                view
+                session
+                (nullable-some (nullableTextOrEmpty next))
+                feedbackConstant)
+              (begin))))
+        (def (mainActivityFinalizeGroupLabel
+               (activity : MainActivity)
+               (group : SsdGroup)) : Unit
+          (let ((typeDisplay
+                  (boxTypesDisplayFromActivity
+                    activity
+                    (SsdGroup-boxTypeId group))))
+            (let ((resolved
+                    (resolvedLabelForBoxTypeFromActivity
+                      activity
+                      (SsdGroup-label group)
+                      typeDisplay
+                      (SsdGroup-boxTypeId group))))
+              (begin
+                (ssdGroupApplyResolvedLabel group resolved)
+                (begin)))))
+        (def (mainActivityFocusBoxTypeDropdown
+               (dialog : AlertDialog)
+               (boxType : AutoCompleteTextView)
+               (displayHeightPixels : Int32)
+               (softInputMode : Int32)) : Unit
+          (begin
+            (autoCompleteDropDownHeightSet
+              boxType
+              (dropdownHeight displayHeightPixels))
+            (setSoftInputModeIfWindowPresent
+              (alertDialogWindowOrNull dialog)
+              softInputMode)
+            (autoCompleteFocusAndShowDropdown dialog boxType)))
         (def (mainActivityAddApprovedAreaGroup
                (activity : MainActivity)
                (view : SsdReviewView)
@@ -9928,7 +10014,7 @@
        "        })"
        "        root.addView(status)"
 	       "        mainActivitySetReviewView(this, SsdReviewView(this).apply {"
-       "            mainActivityInstallReviewViewCallbacks(this@MainActivity, this)"
+       "            mainActivityInstallReviewViewCallbacks(this@MainActivity, this, HapticFeedbackConstants.CLOCK_TICK)"
 	       "        })"
        "        root.addView(reviewView, LinearLayout.LayoutParams("
        "            LinearLayout.LayoutParams.MATCH_PARENT,"
@@ -9958,8 +10044,8 @@
 	       "                button(\"Add\", ButtonKind.ACCENT) { startAppendMode() },"
 	       "            ))"
 	       "            addView(actionRow("
-	       "                button(\"Prev\", ButtonKind.NAV) { selectRelativeGroup(-1) },"
-	       "                button(\"Next\", ButtonKind.PRIMARY) { selectRelativeGroup(1) },"
+	       "                button(\"Prev\", ButtonKind.NAV) { mainActivitySelectRelativeGroup(this@MainActivity, reviewView, currentSession, selectedGroupId, -1, HapticFeedbackConstants.CLOCK_TICK) },"
+	       "                button(\"Next\", ButtonKind.PRIMARY) { mainActivitySelectRelativeGroup(this@MainActivity, reviewView, currentSession, selectedGroupId, 1, HapticFeedbackConstants.CLOCK_TICK) },"
 	       "                button(\"Edit\") { editSelectedGroup() },"
 	       "            ))"
 	       "            addView(actionRow("
@@ -10031,21 +10117,6 @@
        "        autoCompleteInstallBoxTypeDialogBehavior(this, label, boxType, firingArc, initialBoxType)"
        "    }"
        ""
-       "    private fun finalizeGroupLabel(group: SsdGroup) {"
-       "        val typeDisplay = boxTypesDisplayAndroid(this, group.boxTypeId)"
-       "        val resolved = resolvedLabelForBoxTypeAndroid(this, group.label, typeDisplay, group.boxTypeId)"
-       "        ssdGroupApplyResolvedLabel(group, resolved)"
-       "    }"
-       ""
-       "    private fun focusBoxTypeDropdown(dialog: AlertDialog, boxType: AutoCompleteTextView) {"
-       "        boxType.dropDownHeight = dropdownHeight(resources.displayMetrics.heightPixels)"
-       "        setSoftInputModeIfWindowPresent(dialog.window,"
-       "            android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or"
-       "                android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE"
-       "        )"
-       "        autoCompleteFocusAndShowDropdown(dialog, boxType)"
-       "    }"
-       ""
        "    private fun openPdf() {"
        "        val remembered = getPreferences(MODE_PRIVATE).getString(PREF_SSD_PDF_TREE_URI, null)"
        "        mainActivityOpenPdfAsync(this, remembered)"
@@ -10179,29 +10250,8 @@
 	       "        }"
 	       "    }"
 	       ""
-       "    internal fun selectGroup(groupId: String?) {"
-       "        val group = mainActivitySelectRequestedGroup(this, reviewView, currentSession, groupId)"
-       "        if (ssdGroupMissing(group)) return"
-       "        val selectedGroup = ssdGroupOrEmpty(group)"
-	       "        reviewViewCenterOnGroup(reviewView, selectedGroup)"
-	       "        reviewViewPerformHaptic(reviewView, HapticFeedbackConstants.CLOCK_TICK)"
-       "        setStatus(selectedGroupStatus(selectedGroup))"
-       "    }"
-       ""
-       "    private fun selectedGroup(): SsdGroup? {"
-       "        val group = mainActivitySelectCurrentGroup(this, reviewView, currentSession, selectedGroupId)"
-       "        if (ssdGroupMissing(group)) return null"
-       "        return ssdGroupOrEmpty(group)"
-       "    }"
-       ""
-       "    private fun selectRelativeGroup(delta: Int) {"
-       "        val next = ssdCurrentRelativeGroupId(currentSession, selectedGroupId, delta)"
-       "        if (!nullableTextPresent(next)) return"
-       "        selectGroup(nullableTextOrEmpty(next))"
-       "    }"
-       ""
        "    private fun editSelectedGroup() {"
-       "        val group = selectedGroup()"
+       "        val group = mainActivitySelectedGroup(this, reviewView, currentSession, selectedGroupId)"
        "        if (ssdGroupMissing(group)) return"
        "        showGroupEditDialog(ssdGroupOrEmpty(group))"
        "    }"
@@ -10209,10 +10259,10 @@
        "    private fun approveSelectedGroup() {"
        "        if (sessionMissing(currentSession)) return"
        "        val session = ssdSessionOrEmpty(currentSession)"
-       "        val group = selectedGroup()"
+       "        val group = mainActivitySelectedGroup(this, reviewView, currentSession, selectedGroupId)"
        "        if (ssdGroupMissing(group)) return"
        "        val approvedGroup = ssdGroupOrEmpty(group)"
-       "        finalizeGroupLabel(approvedGroup)"
+       "        mainActivityFinalizeGroupLabel(this, approvedGroup)"
        "        ssdSessionApproveGroup(session, approvedGroup)"
        "        truthStoreAppendGroupApproved(truthStore, session)"
        "        reviewViewPerformHapticAndInvalidate(reviewView, HapticFeedbackConstants.CONFIRM)"
@@ -10327,7 +10377,7 @@
        "            .setPositiveButton(\"Approve\", null)"
        "            .show()"
        "        mainActivityInstallApproveAreaDialogButton(this, dialog, rect, detectedIds, label, boxType, firingArc, count)"
-       "        focusBoxTypeDropdown(dialog, boxType)"
+       "        mainActivityFocusBoxTypeDropdown(dialog, boxType, resources.displayMetrics.heightPixels, android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)"
        "    }"
        ""
        "    private fun showAppendDialog(rect: FloatArray, detectedIds: List<String>) {"
@@ -10460,7 +10510,7 @@
        "            HapticFeedbackConstants.CONFIRM"
        "        )"
        "        boxType.selectAll()"
-       "        focusBoxTypeDropdown(dialog, boxType)"
+       "        mainActivityFocusBoxTypeDropdown(dialog, boxType, resources.displayMetrics.heightPixels, android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)"
        "    }"
        ""
        "    private fun saveTruth() {"
@@ -10476,7 +10526,7 @@
        "    internal fun deleteSelectedGroup() {"
        "        if (sessionMissing(currentSession)) return"
        "        val session = ssdSessionOrEmpty(currentSession)"
-       "        val group = selectedGroup()"
+       "        val group = mainActivitySelectedGroup(this, reviewView, currentSession, selectedGroupId)"
        "        if (ssdGroupMissing(group)) return"
        "        val deletedGroup = ssdGroupOrEmpty(group)"
        "        mainActivitySuppressGroupAsDeleted(this, reviewView, session, deletedGroup)"