Skip to content

Commit

Permalink
replace LengthInput with LengthInputViewController
Browse files Browse the repository at this point in the history
  • Loading branch information
westnordost committed Mar 15, 2022
1 parent 0cef8de commit e2a1e6f
Show file tree
Hide file tree
Showing 20 changed files with 546 additions and 713 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,91 +2,51 @@ package de.westnordost.streetcomplete.quests.max_height

import android.os.Bundle
import android.view.View
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.Spinner
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.meta.LengthUnit
import de.westnordost.streetcomplete.data.osm.mapdata.ElementType
import de.westnordost.streetcomplete.osm.Length
import de.westnordost.streetcomplete.osm.LengthInFeetAndInches
import de.westnordost.streetcomplete.osm.LengthInMeters
import de.westnordost.streetcomplete.quests.AbstractQuestFormAnswerFragment
import de.westnordost.streetcomplete.quests.AnswerItem
import de.westnordost.streetcomplete.util.ktx.intOrNull
import de.westnordost.streetcomplete.util.ktx.numberOrNull
import de.westnordost.streetcomplete.view.OnAdapterItemSelectedListener
import de.westnordost.streetcomplete.view.TextChangedWatcher
import de.westnordost.streetcomplete.view.inputfilter.acceptDecimalDigits
import de.westnordost.streetcomplete.view.inputfilter.acceptIntRange
import de.westnordost.streetcomplete.view.controller.LengthInputViewController

class AddMaxHeightForm : AbstractQuestFormAnswerFragment<MaxHeightAnswer>() {

private lateinit var lengthInput: LengthInputViewController

override val contentLayoutResId get() = when (countryInfo.countryCode) {
"AU", "NZ", "US", "CA" -> R.layout.quest_maxheight_mutcd
else -> R.layout.quest_maxheight
}

override val otherAnswers = listOf(
AnswerItem(R.string.quest_maxheight_answer_noSign) { confirmNoSign() }
)

private var meterInput: EditText? = null
private var feetInput: EditText? = null
private var inchInput: EditText? = null
private var heightUnitSelect: Spinner? = null
private var meterInputSign: View? = null
private var feetInputSign: View? = null

private val lengthUnits get() = countryInfo.lengthUnits

override fun isFormComplete() = getHeightFromInput() != null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setMaxHeightSignLayout(R.layout.quest_maxheight, lengthUnits.first())
}

private fun setMaxHeightSignLayout(resourceId: Int, unit: LengthUnit) {
val contentView = setContentView(resourceId)

val splitWayHint = contentView.findViewById<TextView>(R.id.splitWayHint)
val splitWayHint = view.findViewById<TextView>(R.id.splitWayHint)
splitWayHint?.text = getString(R.string.quest_maxheight_split_way_hint, getString(R.string.quest_generic_answer_differs_along_the_way))
splitWayHint?.isGone = osmElement!!.type == ElementType.NODE

meterInput = contentView.findViewById(R.id.meterInput)
feetInput = contentView.findViewById(R.id.feetInput)
inchInput = contentView.findViewById(R.id.inchInput)

val onTextChangedListener = TextChangedWatcher { checkIsFormComplete() }
meterInput?.addTextChangedListener(onTextChangedListener)
feetInput?.addTextChangedListener(onTextChangedListener)
inchInput?.addTextChangedListener(onTextChangedListener)

meterInputSign = contentView.findViewById(R.id.meterInputSign)
feetInputSign = contentView.findViewById(R.id.feetInputSign)

heightUnitSelect = contentView.findViewById(R.id.heightUnitSelect)
heightUnitSelect?.isGone = lengthUnits.size == 1
heightUnitSelect?.adapter = ArrayAdapter(requireContext(), R.layout.spinner_item_centered, lengthUnits)
heightUnitSelect?.setSelection(0)
heightUnitSelect?.onItemSelectedListener = OnAdapterItemSelectedListener {
switchLayout(heightUnitSelect?.selectedItem as LengthUnit)
}

inchInput?.filters = arrayOf(acceptIntRange(0..12))
meterInput?.filters = arrayOf(acceptDecimalDigits(2, 2))
switchLayout(unit)
lengthInput = LengthInputViewController(
unitSelect = view.findViewById(R.id.heightUnitSelect),
metersContainer = view.findViewById(R.id.meterInputSign),
metersInput = view.findViewById(R.id.meterInput),
feetInchesContainer = view.findViewById(R.id.feetInputSign),
feetInput = view.findViewById(R.id.feetInput),
inchesInput = view.findViewById(R.id.inchInput),
R.layout.spinner_item_centered
)
lengthInput.maxFeetDigits = 2
lengthInput.maxMeterDigits = Pair(1, 2)
lengthInput.selectableUnits = countryInfo.lengthUnits
lengthInput.onInputChanged = { checkIsFormComplete() }
}

private fun switchLayout(unit: LengthUnit) {
val isMetric = unit == LengthUnit.METER
val isImperial = unit == LengthUnit.FOOT_AND_INCH

meterInputSign?.isGone = !isMetric
feetInputSign?.isGone = !isImperial

if (isMetric) meterInput?.requestFocus()
if (isImperial) feetInput?.requestFocus()
}
override fun isFormComplete() = lengthInput.length != null

override fun onClickOk() {
if (userSelectedUnrealisticHeight()) {
Expand All @@ -97,30 +57,12 @@ class AddMaxHeightForm : AbstractQuestFormAnswerFragment<MaxHeightAnswer>() {
}

private fun userSelectedUnrealisticHeight(): Boolean {
val height = getHeightFromInput() ?: return false
val m = height.toMeters()
return m > 6 || m < 1.9
val m = lengthInput.length?.toMeters() ?: return false
return m > 6 || m < 1.8
}

private fun applyMaxHeightFormAnswer() {
applyAnswer(MaxHeight(getHeightFromInput()!!))
}

private fun getHeightFromInput(): Length? {
when (heightUnitSelect?.selectedItem as LengthUnit? ?: lengthUnits.first()) {
LengthUnit.METER -> {
return meterInput?.numberOrNull?.let { LengthInMeters(it) }
}
LengthUnit.FOOT_AND_INCH -> {
val feet = feetInput?.intOrNull
val inches = inchInput?.intOrNull

if (feet != null && inches != null) {
return LengthInFeetAndInches(feet, inches)
}
}
}
return null
applyAnswer(MaxHeight(lengthInput.length!!))
}

private fun confirmNoSign() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class AddMaxPhysicalHeight(
override fun isApplicableTo(element: Element): Boolean =
nodeFilter.matches(element) || wayFilter.matches(element)

override fun createForm() = AddHeightForm()
override fun createForm() = AddMaxPhysicalHeightForm()

override fun applyAnswerTo(answer: MaxPhysicalHeightAnswer, tags: Tags, timestampEdited: Long) {
// overwrite maxheight value but retain the info that there is no sign onto another tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ import de.westnordost.streetcomplete.databinding.QuestLengthBinding
import de.westnordost.streetcomplete.quests.AbstractQuestFormAnswerFragment
import de.westnordost.streetcomplete.screens.measure.ArSupportChecker
import de.westnordost.streetcomplete.screens.measure.TakeMeasurementLauncher
import de.westnordost.streetcomplete.view.controller.LengthInputViewController
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject

class AddHeightForm : AbstractQuestFormAnswerFragment<MaxPhysicalHeightAnswer>() {
class AddMaxPhysicalHeightForm : AbstractQuestFormAnswerFragment<MaxPhysicalHeightAnswer>() {

override val contentLayoutResId = R.layout.quest_length
private val binding by contentViewBinding(QuestLengthBinding::bind)
private val takeMeasurement = TakeMeasurementLauncher(this)
private val checkArSupport: ArSupportChecker by inject()
private var isARMeasurement: Boolean = false
private lateinit var lengthInput: LengthInputViewController

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -28,10 +30,14 @@ class AddHeightForm : AbstractQuestFormAnswerFragment<MaxPhysicalHeightAnswer>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.lengthInput.maxFeetDigits = 2
binding.lengthInput.maxMeterDigitsBeforeDecimalPoint = 1
binding.lengthInput.selectableUnits = countryInfo.lengthUnits
binding.lengthInput.onInputChanged = {
lengthInput = binding.lengthInput.let {
LengthInputViewController(it.unitSelect, it.metersContainer, it.metersInput, it.feetInchesContainer, it.feetInput, it.inchesInput, R.layout.spinner_item_centered_large)
}
lengthInput.isCompactMode = true
lengthInput.maxFeetDigits = 2
lengthInput.maxMeterDigits = Pair(1, 2)
lengthInput.selectableUnits = countryInfo.lengthUnits
lengthInput.onInputChanged = {
isARMeasurement = false
checkIsFormComplete()
}
Expand All @@ -40,18 +46,18 @@ class AddHeightForm : AbstractQuestFormAnswerFragment<MaxPhysicalHeightAnswer>()
}

private suspend fun takeMeasurement() {
val lengthUnit = binding.lengthInput.unit ?: return
val lengthUnit = lengthInput.unit ?: return
val length = takeMeasurement(requireContext(), lengthUnit, true) ?: return
binding.lengthInput.length = length
lengthInput.length = length
isARMeasurement = true
}

override fun isFormComplete(): Boolean = lengthInput.length != null

override fun onClickOk() {
applyAnswer(MaxPhysicalHeightAnswer(binding.lengthInput.length!!, isARMeasurement))
applyAnswer(MaxPhysicalHeightAnswer(lengthInput.length!!, isARMeasurement))
}

override fun isFormComplete(): Boolean = binding.lengthInput.length != null

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(AR, isARMeasurement)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import de.westnordost.streetcomplete.osm.ALL_ROADS
import de.westnordost.streetcomplete.quests.AbstractQuestFormAnswerFragment
import de.westnordost.streetcomplete.screens.measure.ArSupportChecker
import de.westnordost.streetcomplete.screens.measure.TakeMeasurementLauncher
import de.westnordost.streetcomplete.view.controller.LengthInputViewController
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject

Expand All @@ -20,6 +21,7 @@ class AddWidthForm : AbstractQuestFormAnswerFragment<WidthAnswer>() {
private val takeMeasurement = TakeMeasurementLauncher(this)
private val checkArSupport: ArSupportChecker by inject()
private var isARMeasurement: Boolean = false
private lateinit var lengthInput: LengthInputViewController

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -34,10 +36,14 @@ class AddWidthForm : AbstractQuestFormAnswerFragment<WidthAnswer>() {
binding.widthExplanationTextView.isGone = explanation == null
binding.widthExplanationTextView.text = explanation

binding.lengthInput.maxFeetDigits = if (isRoad) 3 else 2
binding.lengthInput.maxMeterDigitsBeforeDecimalPoint = if (isRoad) 2 else 1
binding.lengthInput.selectableUnits = countryInfo.lengthUnits
binding.lengthInput.onInputChanged = {
lengthInput = binding.lengthInput.let {
LengthInputViewController(it.unitSelect, it.metersContainer, it.metersInput, it.feetInchesContainer, it.feetInput, it.inchesInput, R.layout.spinner_item_centered_large)
}
lengthInput.isCompactMode = true
lengthInput.maxFeetDigits = if (isRoad) 3 else 2
lengthInput.maxMeterDigits = Pair(if (isRoad) 2 else 1, 2)
lengthInput.selectableUnits = countryInfo.lengthUnits
lengthInput.onInputChanged = {
isARMeasurement = false
checkIsFormComplete()
}
Expand All @@ -46,17 +52,17 @@ class AddWidthForm : AbstractQuestFormAnswerFragment<WidthAnswer>() {
}

private suspend fun takeMeasurement() {
val lengthUnit = binding.lengthInput.unit ?: return
val lengthUnit = lengthInput.unit ?: return
val length = takeMeasurement(requireContext(), lengthUnit, false) ?: return
binding.lengthInput.length = length
lengthInput.length = length
isARMeasurement = true
}

override fun onClickOk() {
applyAnswer(WidthAnswer(binding.lengthInput.length!!, isARMeasurement))
applyAnswer(WidthAnswer(lengthInput.length!!, isARMeasurement))
}

override fun isFormComplete(): Boolean = binding.lengthInput.length != null
override fun isFormComplete(): Boolean = lengthInput.length != null

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Expand Down
Loading

0 comments on commit e2a1e6f

Please sign in to comment.