Generate SSD buttons from typed Jerboa

ober

48ca6e5355ef6e9dad7c1e7d9f7fe26713409f82

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 3e8de41..ecdae15 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -4771,6 +4771,7 @@
                       (android graphics Bitmap)
                       (android content Intent)
                       (android database Cursor)
+                      (android graphics drawable GradientDrawable)
                       (android net Uri)
                       (android os ParcelFileDescriptor)
                       (android text Editable)
@@ -4958,7 +4959,7 @@
                 autoCompleteUpdateFiringArcVisibility
                 autoCompleteInstallFiringArcVisibilityWatcher
                 autoCompleteInstallBoxTypeDialogBehavior
-                buttonSetOnClickAction
+                buttonSetOnClickAction mainActivityButton
                 mainActivityActionRow
                 mainActivityAddActionRowButtons
                 permissionResultGranted downloadAccessBeforeRuntimePermissions
@@ -5016,6 +5017,7 @@
         (type AdapterView)
         (type AutoCompleteTextView)
         (type Button)
+        (type ButtonKind)
         (type CharSequence)
         (type ContentResolver)
         (type Context)
@@ -5033,6 +5035,7 @@
         (type ParcelFileDescriptor)
         (type View)
         (type Window)
+        (type GradientDrawable)
         (type DocumentFile)
         (type NativeDetection)
         (type OcrWord)
@@ -5257,6 +5260,64 @@
                   (button : Button)
                   (listener : (-> View Unit))) : Unit
           (kotlin-member-call setOnClickListener))
+        (extern (buttonForActivity
+                  (activity : MainActivity)) : Button
+          (kotlin-call Button))
+        (extern (buttonKindNeutral) : ButtonKind
+          (kotlin-value ButtonKind NEUTRAL))
+        (extern (buttonKindBackgroundColor
+                  (kind : ButtonKind)) : Int32
+          (kotlin-member-get backgroundColor))
+        (extern (buttonKindForegroundColor
+                  (kind : ButtonKind)) : Int32
+          (kotlin-member-get foregroundColor))
+        (extern (buttonKindTextSp
+                  (kind : ButtonKind)) : Float32
+          (kotlin-member-get textSp))
+        (extern (buttonKindHeightDp
+                  (kind : ButtonKind)) : Int32
+          (kotlin-member-get heightDp))
+        (extern (buttonTextSetRaw
+                  (button : Button)
+                  (text : String)) : Unit
+          (kotlin-member-set text))
+        (extern (buttonTextSizeSetRaw
+                  (button : Button)
+                  (size : Float32)) : Unit
+          (kotlin-member-set textSize))
+        (extern (buttonMinHeightSetRaw
+                  (button : Button)
+                  (height : Int32)) : Unit
+          (kotlin-member-set minHeight))
+        (extern (buttonSetTextColorRaw
+                  (button : Button)
+                  (color : Int32)) : Unit
+          (kotlin-member-call setTextColor))
+        (extern (buttonSetAllCapsRaw
+                  (button : Button)
+                  (enabled : Bool)) : Unit
+          (kotlin-member-call setAllCaps))
+        (extern (buttonSetPaddingRaw
+                  (button : Button)
+                  (left : Int32)
+                  (top : Int32)
+                  (right : Int32)
+                  (bottom : Int32)) : Unit
+          (kotlin-member-call setPadding))
+        (extern (gradientDrawable) : GradientDrawable
+          (kotlin-call GradientDrawable))
+        (extern (gradientDrawableCornerRadiusSetRaw
+                  (drawable : GradientDrawable)
+                  (radius : Float32)) : Unit
+          (kotlin-member-set cornerRadius))
+        (extern (gradientDrawableSetColorRaw
+                  (drawable : GradientDrawable)
+                  (color : Int32)) : Unit
+          (kotlin-member-call setColor))
+        (extern (buttonBackgroundSetRaw
+                  (button : Button)
+                  (drawable : GradientDrawable)) : Unit
+          (kotlin-member-set background))
         (extern (linearLayoutForActivity
                   (activity : MainActivity)) : LinearLayout
           (kotlin-call LinearLayout))
@@ -7577,6 +7638,41 @@
             button
             (lambda ((unused : View))
               (invoke action))))
+        (def (mainActivityButton
+               (activity : MainActivity)
+               (label : String)
+               (kind : ButtonKind
+                 (default (buttonKindNeutral)))
+               (action : (-> Unit))) : Button
+          (let ((button (buttonForActivity activity))
+                (background (gradientDrawable))
+                (horizontalPadding (mainActivityDpRaw activity (int32 10)))
+                (verticalPadding (mainActivityDpRaw activity (int32 6))))
+            (begin
+              (buttonTextSetRaw button label)
+              (buttonTextSizeSetRaw button (buttonKindTextSp kind))
+              (buttonMinHeightSetRaw
+                button
+                (mainActivityDpRaw activity (buttonKindHeightDp kind)))
+              (buttonSetTextColorRaw
+                button
+                (buttonKindForegroundColor kind))
+              (buttonSetAllCapsRaw button #f)
+              (buttonSetPaddingRaw
+                button
+                horizontalPadding
+                verticalPadding
+                horizontalPadding
+                verticalPadding)
+              (gradientDrawableCornerRadiusSetRaw
+                background
+                (float32 (mainActivityDpRaw activity (int32 9))))
+              (gradientDrawableSetColorRaw
+                background
+                (buttonKindBackgroundColor kind))
+              (buttonBackgroundSetRaw button background)
+              (buttonSetOnClickAction button action)
+              button)))
         (def (mainActivityActionRow
                (activity : MainActivity)
                (orientation : Int32)
@@ -10355,7 +10451,6 @@
 	       "import android.graphics.Bitmap"
 	       "import android.graphics.Color"
 	       "import android.graphics.Matrix"
-	       "import android.graphics.drawable.GradientDrawable"
 	       "import android.graphics.pdf.PdfRenderer"
        "import android.net.Uri"
        "import android.os.Build"
@@ -10453,39 +10548,39 @@
        "        val controls = LinearLayout(this).apply {"
        "            orientation = LinearLayout.VERTICAL"
        "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-	       "                button(\"Open SSDs\", ButtonKind.PRIMARY) { openPdf() },"
-	       "                button(\"Detect\", ButtonKind.ACCENT) { detectCurrent(forceDetect = true) },"
-	       "                button(\"Set SSD Area\", ButtonKind.MODE) { mainActivityStartSsdAreaMode(this@MainActivity, reviewView, currentSession, selectedGroupId, HapticFeedbackConstants.CLOCK_TICK) },"
+	       "                mainActivityButton(this@MainActivity, \"Open SSDs\", ButtonKind.PRIMARY) { openPdf() },"
+	       "                mainActivityButton(this@MainActivity, \"Detect\", ButtonKind.ACCENT) { detectCurrent(forceDetect = true) },"
+	       "                mainActivityButton(this@MainActivity, \"Set SSD Area\", ButtonKind.MODE) { mainActivityStartSsdAreaMode(this@MainActivity, reviewView, currentSession, selectedGroupId, HapticFeedbackConstants.CLOCK_TICK) },"
 	       "            ))"
 	       "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-	       "                button(\"Open Any\") { openAnyPdf() },"
-	       "                button(\"Rotate\") { mainActivityRotatePage(this@MainActivity, reviewView, loadGeneration, currentSession) },"
-	       "                button(\"Fit\") { reviewViewFitImage(reviewView) },"
+	       "                mainActivityButton(this@MainActivity, \"Open Any\") { openAnyPdf() },"
+	       "                mainActivityButton(this@MainActivity, \"Rotate\") { mainActivityRotatePage(this@MainActivity, reviewView, loadGeneration, currentSession) },"
+	       "                mainActivityButton(this@MainActivity, \"Fit\") { reviewViewFitImage(reviewView) },"
 	       "            ))"
 	       "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-	       "                button(\"Prev Page\") { mainActivityChangePage(this@MainActivity, pdfUri, pageCount, pageIndex, -1) },"
-	       "                button(\"Page #\") { showPageDialog() },"
-	       "                button(\"Next Page\") { mainActivityChangePage(this@MainActivity, pdfUri, pageCount, pageIndex, 1) },"
+	       "                mainActivityButton(this@MainActivity, \"Prev Page\") { mainActivityChangePage(this@MainActivity, pdfUri, pageCount, pageIndex, -1) },"
+	       "                mainActivityButton(this@MainActivity, \"Page #\") { showPageDialog() },"
+	       "                mainActivityButton(this@MainActivity, \"Next Page\") { mainActivityChangePage(this@MainActivity, pdfUri, pageCount, pageIndex, 1) },"
 	       "            ))"
 	       "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-	       "                button(\"Pan\", ButtonKind.NEUTRAL) { mainActivityApplySelectMode(this@MainActivity, reviewView, ssdAreaMode, appendMode, false) },"
-	       "                button(\"Select Area\", ButtonKind.PRIMARY) { mainActivityApplySelectMode(this@MainActivity, reviewView, ssdAreaMode, appendMode, true) },"
-	       "                button(\"Add\", ButtonKind.ACCENT) { mainActivityStartAppendMode(this@MainActivity, reviewView, currentSession, selectedGroupId) },"
+	       "                mainActivityButton(this@MainActivity, \"Pan\", ButtonKind.NEUTRAL) { mainActivityApplySelectMode(this@MainActivity, reviewView, ssdAreaMode, appendMode, false) },"
+	       "                mainActivityButton(this@MainActivity, \"Select Area\", ButtonKind.PRIMARY) { mainActivityApplySelectMode(this@MainActivity, reviewView, ssdAreaMode, appendMode, true) },"
+	       "                mainActivityButton(this@MainActivity, \"Add\", ButtonKind.ACCENT) { mainActivityStartAppendMode(this@MainActivity, reviewView, currentSession, selectedGroupId) },"
 	       "            ))"
 	       "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-	       "                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() },"
+	       "                mainActivityButton(this@MainActivity, \"Prev\", ButtonKind.NAV) { mainActivitySelectRelativeGroup(this@MainActivity, reviewView, currentSession, selectedGroupId, -1, HapticFeedbackConstants.CLOCK_TICK) },"
+	       "                mainActivityButton(this@MainActivity, \"Next\", ButtonKind.PRIMARY) { mainActivitySelectRelativeGroup(this@MainActivity, reviewView, currentSession, selectedGroupId, 1, HapticFeedbackConstants.CLOCK_TICK) },"
+	       "                mainActivityButton(this@MainActivity, \"Edit\") { editSelectedGroup() },"
 	       "            ))"
 	       "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-	       "                button(\"Approve\", ButtonKind.ACCENT) { mainActivityApproveSelectedGroup(this@MainActivity, reviewView, truthStore, currentSession, selectedGroupId, HapticFeedbackConstants.CONFIRM) },"
-	       "                button(\"Delete\", ButtonKind.DANGER) { mainActivityDeleteSelectedGroup(this@MainActivity, reviewView, truthStore, currentSession, selectedGroupId, HapticFeedbackConstants.REJECT) },"
-	       "                button(\"Save\") { mainActivitySaveTruth(this@MainActivity, reviewView, truthStore, currentSession) },"
+	       "                mainActivityButton(this@MainActivity, \"Approve\", ButtonKind.ACCENT) { mainActivityApproveSelectedGroup(this@MainActivity, reviewView, truthStore, currentSession, selectedGroupId, HapticFeedbackConstants.CONFIRM) },"
+	       "                mainActivityButton(this@MainActivity, \"Delete\", ButtonKind.DANGER) { mainActivityDeleteSelectedGroup(this@MainActivity, reviewView, truthStore, currentSession, selectedGroupId, HapticFeedbackConstants.REJECT) },"
+	       "                mainActivityButton(this@MainActivity, \"Save\") { mainActivitySaveTruth(this@MainActivity, reviewView, truthStore, currentSession) },"
 	       "            ))"
        "            addView(mainActivityActionRow(this@MainActivity, LinearLayout.HORIZONTAL, Gravity.CENTER_VERTICAL,"
-       "                button(\"Pull Truth\") { mainActivityPullTruthDumpAsync(this@MainActivity, truthStore) },"
-       "                button(\"Push Truth\") { mainActivityPushTruthDumpAsync(this@MainActivity, truthStore) },"
-       "                button(\"Sync Folder\") { syncTruthFolder() },"
+       "                mainActivityButton(this@MainActivity, \"Pull Truth\") { mainActivityPullTruthDumpAsync(this@MainActivity, truthStore) },"
+       "                mainActivityButton(this@MainActivity, \"Push Truth\") { mainActivityPushTruthDumpAsync(this@MainActivity, truthStore) },"
+       "                mainActivityButton(this@MainActivity, \"Sync Folder\") { syncTruthFolder() },"
 	       "            ))"
 	       "        }"
        "        root.addView(ScrollView(this).apply {"
@@ -10498,21 +10593,6 @@
        "        return root"
        "    }"
        ""
-	       "    private fun button(label: String, kind: ButtonKind = ButtonKind.NEUTRAL, action: () -> Unit): Button ="
-	       "        Button(this).apply {"
-	       "            text = label"
-	       "            textSize = kind.textSp"
-	       "            minHeight = mainActivityDp(this@MainActivity, kind.heightDp)"
-	       "            setTextColor(kind.foregroundColor)"
-	       "            setAllCaps(false)"
-	       "            setPadding(mainActivityDp(this@MainActivity, 10), mainActivityDp(this@MainActivity, 6), mainActivityDp(this@MainActivity, 10), mainActivityDp(this@MainActivity, 6))"
-	       "            background = GradientDrawable().apply {"
-	       "                cornerRadius = mainActivityDp(this@MainActivity, 9).toFloat()"
-	       "                setColor(kind.backgroundColor)"
-	       "            }"
-       "            buttonSetOnClickAction(this, action)"
-	       "        }"
-       ""
        "    private fun boxTypeInput(): AutoCompleteTextView ="
        "        AutoCompleteTextView(this).apply {"
        "            inputType = InputType.TYPE_CLASS_TEXT"