summaryrefslogtreecommitdiff
path: root/android-app/app/src/main/kotlin/com/example/androidapp
diff options
context:
space:
mode:
Diffstat (limited to 'android-app/app/src/main/kotlin/com/example/androidapp')
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt23
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt58
2 files changed, 81 insertions, 0 deletions
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt b/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt
new file mode 100644
index 0000000..507736e
--- /dev/null
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt
@@ -0,0 +1,23 @@
+package com.example.androidapp.safety
+
+/**
+ * Holds UI-facing state for the anchor watch setup screen and provides
+ * the suggested watch-circle radius derived from depth and rode out.
+ */
+class AnchorWatchState {
+
+ /**
+ * Returns the recommended watch-circle radius (metres) for the given depth
+ * and amount of rode deployed.
+ *
+ * Uses the Pythagorean formula via [ScopeCalculator.watchCircleRadius] when
+ * the geometry is valid (rode > depth + freeboard). Falls back to [rodeOutM]
+ * itself as the maximum possible swing radius when the rode is too short to
+ * form a catenary angle.
+ */
+ fun calculateRecommendedWatchCircleRadius(depthM: Double, rodeOutM: Double): Double {
+ val vertical = depthM + 2.0 // 2 m default freeboard
+ return if (rodeOutM > vertical) ScopeCalculator.watchCircleRadius(rodeOutM, depthM)
+ else rodeOutM
+ }
+}
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt b/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt
new file mode 100644
index 0000000..bc82795
--- /dev/null
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt
@@ -0,0 +1,58 @@
+package com.example.androidapp.ui.anchorwatch
+
+import android.os.Bundle
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.androidapp.R
+import com.example.androidapp.databinding.FragmentAnchorWatchBinding
+import com.example.androidapp.safety.AnchorWatchState
+
+class AnchorWatchHandler : Fragment() {
+
+ private var _binding: FragmentAnchorWatchBinding? = null
+ private val binding get() = _binding!!
+
+ private val anchorWatchState = AnchorWatchState()
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = FragmentAnchorWatchBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val watcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
+ override fun afterTextChanged(s: Editable?) = updateSuggestedRadius()
+ }
+ binding.etDepth.addTextChangedListener(watcher)
+ binding.etRodeOut.addTextChangedListener(watcher)
+ }
+
+ private fun updateSuggestedRadius() {
+ val depth = binding.etDepth.text.toString().toDoubleOrNull()
+ val rode = binding.etRodeOut.text.toString().toDoubleOrNull()
+
+ if (depth != null && rode != null && depth >= 0.0 && rode > 0.0) {
+ val radius = anchorWatchState.calculateRecommendedWatchCircleRadius(depth, rode)
+ binding.tvSuggestedRadius.text =
+ getString(R.string.anchor_suggested_radius_fmt, radius)
+ } else {
+ binding.tvSuggestedRadius.text = getString(R.string.anchor_suggested_radius_empty)
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}