Generate SSD activity dp helper from typed Jerboa

ober

8b6afc4ec8f8536f0dfe810b716262a49c9a8465

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 090208e..26eef52 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -9773,6 +9773,30 @@
           (NEUTRAL (reviewNeutralColor) (reviewDarkTextColor) (float32 15.0) (int32 48))
           (DANGER (reviewDangerColor) (reviewWhiteColor) (float32 16.0) (int32 50)))))
 
+    (typed-kotlin-file "com/sfb/ssdreview/MainActivityMetrics.kt"
+      (kotlin-imports (android content Context)
+                      (android content res Resources)
+                      (android util DisplayMetrics))
+      (typed-library (com sfb ssdreview)
+        (export mainActivityDp)
+        (type Context)
+        (type Resources)
+        (type DisplayMetrics)
+        (type Int32)
+        (type Float32)
+        (extern (contextResources (context : Context)) : Resources
+          (kotlin-member-get resources))
+        (extern (resourcesDisplayMetrics (resources : Resources)) : DisplayMetrics
+          (kotlin-member-get displayMetrics))
+        (extern (displayMetricsDensity (metrics : DisplayMetrics)) : Float32
+          (kotlin-member-get density))
+        (def (mainActivityDp (context : Context) (value : Int32)) : Int32
+          (float32-round->int32
+            (* (float32 value)
+               (displayMetricsDensity
+                 (resourcesDisplayMetrics
+                   (contextResources context))))))))
+
     (kotlin-file-lines "com/sfb/ssdreview/MainActivity.kt"
       (
        "package com.sfb.ssdreview"
@@ -9929,18 +9953,16 @@
        "        return root"
        "    }"
        ""
-	       "    private fun dp(value: Int): Int = (value * resources.displayMetrics.density + 0.5f).toInt()"
-	       ""
 	       "    private fun button(label: String, kind: ButtonKind = ButtonKind.NEUTRAL, action: () -> Unit): Button ="
 	       "        Button(this).apply {"
 	       "            text = label"
 	       "            textSize = kind.textSp"
-	       "            minHeight = dp(kind.heightDp)"
+	       "            minHeight = mainActivityDp(this@MainActivity, kind.heightDp)"
 	       "            setTextColor(kind.foregroundColor)"
 	       "            setAllCaps(false)"
-	       "            setPadding(dp(10), dp(6), dp(10), dp(6))"
+	       "            setPadding(mainActivityDp(this@MainActivity, 10), mainActivityDp(this@MainActivity, 6), mainActivityDp(this@MainActivity, 10), mainActivityDp(this@MainActivity, 6))"
 	       "            background = GradientDrawable().apply {"
-	       "                cornerRadius = dp(9).toFloat()"
+	       "                cornerRadius = mainActivityDp(this@MainActivity, 9).toFloat()"
 	       "                setColor(kind.backgroundColor)"
 	       "            }"
        "            buttonSetOnClickAction(this, action)"
@@ -9950,8 +9972,8 @@
        "        LinearLayout(this).apply {"
        "            orientation = LinearLayout.HORIZONTAL"
        "            gravity = Gravity.CENTER_VERTICAL"
-       "            mainActivityAddActionRowButtons(this, buttons.asList(), dp(3))"
-	       "        }"
+       "            mainActivityAddActionRowButtons(this, buttons.asList(), mainActivityDp(this@MainActivity, 3))"
+       "        }"
        ""
        "    private fun boxTypeInput(): AutoCompleteTextView ="
        "        AutoCompleteTextView(this).apply {"