feat(templates): add ability to filter values in EnumParameter

This commit is contained in:
Akash Yadav
2023-05-24 20:51:27 +05:30
parent bd89c8e090
commit 2b746526f7
4 changed files with 37 additions and 10 deletions
@@ -20,6 +20,7 @@ package com.itsaky.androidide.templates.base
import com.itsaky.androidide.templates.CheckBoxWidget
import com.itsaky.androidide.templates.FileTemplate
import com.itsaky.androidide.templates.FileTemplateRecipeResult
import com.itsaky.androidide.templates.Language
import com.itsaky.androidide.templates.ModuleTemplate
import com.itsaky.androidide.templates.ModuleTemplateData
import com.itsaky.androidide.templates.ModuleType
@@ -33,6 +34,7 @@ import com.itsaky.androidide.templates.ProjectTemplate
import com.itsaky.androidide.templates.ProjectTemplateData
import com.itsaky.androidide.templates.ProjectVersionData
import com.itsaky.androidide.templates.R
import com.itsaky.androidide.templates.Sdk
import com.itsaky.androidide.templates.SpinnerWidget
import com.itsaky.androidide.templates.TextFieldWidget
import com.itsaky.androidide.templates.base.util.moduleNameToDir
@@ -49,20 +51,25 @@ import java.io.File
typealias AndroidModuleTemplateConfigurator = AndroidModuleTemplateBuilder.() -> Unit
/**
* Setup base files for project templates.
*
* @param block Function to configure the template.
*/
fun baseProject(block: ProjectTemplateBuilder.() -> Unit
fun baseProject(sdkFilter: ((Sdk) -> Boolean)? = null,
languageFilter: ((Language) -> Boolean)? = null,
block: ProjectTemplateBuilder.() -> Unit
): ProjectTemplate {
return ProjectTemplateBuilder().apply {
val projectName = projectNameParameter()
val language = projectLanguageParameter()
val minSdk = minSdkParameter()
val packageName = packageNameParameter()
val useKts = useKtsParameter()
val minSdk = minSdkParameter {
filter = sdkFilter
}
val language = projectLanguageParameter {
filter = languageFilter
}
// When project name is changed, change the package name accordingly
projectName.observe { name ->
@@ -170,8 +177,8 @@ fun baseAndroidModule(isLibrary: Boolean = false,
ModuleTemplateData(name = moduleName.value, appName = appName?.value,
packageName = packageName.value,
projectDir = requireProjectData().moduleNameToDir(moduleName.value),
type = type.value, language = language.value,
minSdk = minSdk.value, useKts = useKts.value)
type = type.value, language = language.value, minSdk = minSdk.value,
useKts = useKts.value)
}
postRecipe = commonPostRecipe()
@@ -253,19 +253,21 @@ class EnumParameter<T : Enum<*>>(@StringRes name: Int,
onStartIconClick: (() -> Unit)?,
onEndIconClick: (() -> Unit)?,
constraints: List<ParameterConstraint>,
val displayName: ((T) -> String)? = null
val displayName: ((T) -> String)? = null,
val filter: ((T) -> Boolean)? = null
) : TextFieldParameter<T>(name, description, default, startIcon, endIcon,
onStartIconClick, onEndIconClick, constraints)
class EnumParameterBuilder<T : Enum<*>> : TextFieldParameterBuilder<T>() {
var displayName: ((T) -> String)? = null
var filter: ((T) -> Boolean)? = null
override fun build(): EnumParameter<T> {
return EnumParameter(name = name!!, description = description,
default = default!!, startIcon = startIcon, endIcon = endIcon,
onStartIconClick = onStartIconClick, onEndIconClick = onEndIconClick,
constraints = constraints, displayName = displayName)
constraints = constraints, displayName = displayName, filter = filter)
}
}
@@ -138,6 +138,12 @@ class TemplateWidgetViewProviderImpl : ITemplateWidgetViewProvider {
val nameToEnum = mutableMapOf<String, Enum<*>>()
val enumToName = mutableMapOf<Enum<*>, String>()
param.default.javaClass.enumConstants?.forEach {
// remove the elements for which the filter fails
if (param.filter?.invoke(it) == false) {
return@forEach
}
val displayName = param.displayName?.invoke(it) ?: it.name
nameToEnum[displayName] = it
enumToName[it] = displayName
@@ -174,6 +180,14 @@ class TemplateWidgetViewProviderImpl : ITemplateWidgetViewProvider {
}
}
if (param.default != nameToEnum[defaultName]) {
// the default value may have been filtered
// reset the value to the first item
val first = checkNotNull(
nameToEnum.values.firstOrNull()) { "No entries available for enum parameter (all entries filtered out?)." }
param.setValue(first)
}
param.observe(observer)
}.root
}
@@ -17,7 +17,9 @@
package com.itsaky.androidide.templates.impl
import com.itsaky.androidide.templates.Language
import com.itsaky.androidide.templates.ProjectTemplate
import com.itsaky.androidide.templates.Sdk
import com.itsaky.androidide.templates.base.AndroidModuleTemplateBuilder
import com.itsaky.androidide.templates.base.ProjectTemplateBuilder
import com.itsaky.androidide.templates.base.baseProject
@@ -43,8 +45,10 @@ internal fun AndroidModuleTemplateBuilder.templateAsset(name: String,
return "templates/${name}/${path}"
}
internal fun baseProjectImpl(block: ProjectTemplateBuilder.() -> Unit
): ProjectTemplate = baseProject {
internal fun baseProjectImpl(sdkFilter: ((Sdk) -> Boolean)? = null,
languageFilter: ((Language) -> Boolean)? = null,
block: ProjectTemplateBuilder.() -> Unit
): ProjectTemplate = baseProject(sdkFilter = sdkFilter, languageFilter = languageFilter) {
block()
// make sure we return a proper result