From d27b023b83d61378e6c2c29a81fed6b22468de71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Woldan=CC=81ska?= Date: Mon, 8 Oct 2018 16:54:35 +0200 Subject: [PATCH 01/28] Version 3.0.0 --- CockpitCore/build.gradle | 2 +- CockpitPlugin/build.gradle | 4 ++-- README.md | 6 +++--- gradle.properties | 2 +- gradle/dependencies.gradle | 2 +- images/{cockpit-2.3.0.gif => cockpit-3.0.gif} | Bin sample/build.gradle | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) rename images/{cockpit-2.3.0.gif => cockpit-3.0.gif} (100%) diff --git a/CockpitCore/build.gradle b/CockpitCore/build.gradle index 8c06ef8..b5a8c31 100644 --- a/CockpitCore/build.gradle +++ b/CockpitCore/build.gradle @@ -16,7 +16,7 @@ plugins { } group 'com.polidea.cockpit' -version '2.2.0' +version '3.0.0' repositories { google() diff --git a/CockpitPlugin/build.gradle b/CockpitPlugin/build.gradle index 83da75a..4058549 100644 --- a/CockpitPlugin/build.gradle +++ b/CockpitPlugin/build.gradle @@ -1,6 +1,6 @@ buildscript { ext.kotlin_version = '1.2.51' - ext.cockpit_core_version = '2.2.0' + ext.cockpit_core_version = '3.0.0' repositories { maven { url "https://plugins.gradle.org/m2/" @@ -21,7 +21,7 @@ plugins { } group = 'com.polidea.cockpit' -version = '2.2.0' +version = '3.0.0' sourceCompatibility = 1.7 diff --git a/README.md b/README.md index ada8827..83e2136 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ It consists of three parts: - Android library containing classes to manage and display those params, - CockpitCore module containing classes common for plugin and the library. - + Each defined value is called `param`. The set of params is called `cockpit`. @@ -198,7 +198,7 @@ Then add CockpitPlugin classpath into your `buildscript#dependencies`: ``` buildscript { dependencies { - classpath "gradle.plugin.com.polidea.cockpit:CockpitPlugin:2.2.0" + classpath "gradle.plugin.com.polidea.cockpit:CockpitPlugin:3.0.0" } } ``` @@ -206,7 +206,7 @@ Last thing is to add Cockpit library dependency: ``` dependencies { - debugImplementation 'com.polidea.cockpit:cockpit:2.2.0' + debugImplementation 'com.polidea.cockpit:cockpit:3.0.0' } ``` diff --git a/gradle.properties b/gradle.properties index 96e2640..9a00b60 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ GROUP=com.polidea.cockpit POM_ARTIFACT_ID=cockpit POM_NAME=Cockpit POM_PACKAGING=aar -VERSION_NAME=2.2.0 +VERSION_NAME=3.0.0 POM_DESCRIPTION=Cockpit is an Android library providing a way to easily define a set of parameters that can be accessed and changed by the developers via built-in compact UI at runtime. diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 85bdfb1..2e11ac4 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -1,3 +1,3 @@ ext { - cockpit_core_version = '2.2.0' + cockpit_core_version = '3.0.0' } \ No newline at end of file diff --git a/images/cockpit-2.3.0.gif b/images/cockpit-3.0.gif similarity index 100% rename from images/cockpit-2.3.0.gif rename to images/cockpit-3.0.gif diff --git a/sample/build.gradle b/sample/build.gradle index d091246..da02480 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -27,7 +27,7 @@ android { minSdkVersion 21 targetSdkVersion 28 versionCode 2 - versionName "2.2.0" + versionName "3.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From 5bd2fa39cf499950fe31ceaf6d29ad63dab5e6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Woldan=CC=81ska?= Date: Thu, 6 Dec 2018 12:15:38 +0100 Subject: [PATCH 02/28] CI test --- CockpitPlugin/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CockpitPlugin/build.gradle b/CockpitPlugin/build.gradle index 4058549..79eb080 100644 --- a/CockpitPlugin/build.gradle +++ b/CockpitPlugin/build.gradle @@ -21,7 +21,7 @@ plugins { } group = 'com.polidea.cockpit' -version = '3.0.0' +version = '3.0.0' sourceCompatibility = 1.7 From f63dd8aa0f3da58f5bbae8440c688a2d96977fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Woldan=CC=81ska?= Date: Mon, 8 Oct 2018 14:57:28 +0200 Subject: [PATCH 03/28] Version 3.0.0 --- CockpitPlugin/build.gradle | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CockpitPlugin/build.gradle b/CockpitPlugin/build.gradle index 79eb080..4058549 100644 --- a/CockpitPlugin/build.gradle +++ b/CockpitPlugin/build.gradle @@ -21,7 +21,7 @@ plugins { } group = 'com.polidea.cockpit' -version = '3.0.0' +version = '3.0.0' sourceCompatibility = 1.7 diff --git a/README.md b/README.md index 83e2136..944b962 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ It consists of three parts: - Android library containing classes to manage and display those params, - CockpitCore module containing classes common for plugin and the library. - + Each defined value is called `param`. The set of params is called `cockpit`. @@ -33,9 +33,9 @@ showDescription: true After you've built your project, `Cockpit.java` file will get generated for you. You can use it like any other code in your project.

- - - + + +

### Documentation From cb8b2585c6d9ac98348f47ecf5e8e55143e58a7e Mon Sep 17 00:00:00 2001 From: Marta Date: Tue, 16 Oct 2018 12:05:42 +0200 Subject: [PATCH 04/28] Added issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..41bc808 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Create a report to help us improve Cockpit + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Library version** +Version of Cockpit the issue occurs in: `X.X.X`. + +**To reproduce** +Steps to reproduce the issue. + +**Expected behavior** +What you expected to happen. + +**Actual behavior** +What actually happened. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Device details** +Provide device details and Android version the issue occurs on. From c4ca85f8fb4419e0169470e6a6e0a375f92d670b Mon Sep 17 00:00:00 2001 From: Marcin Kornacki Date: Thu, 6 Dec 2018 08:44:59 +0100 Subject: [PATCH 05/28] Update dependencies --- CockpitCore/build.gradle | 2 +- build.gradle | 10 +++++----- cockpit/build.gradle | 4 ++-- sample/build.gradle | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CockpitCore/build.gradle b/CockpitCore/build.gradle index b5a8c31..f2f350b 100644 --- a/CockpitCore/build.gradle +++ b/CockpitCore/build.gradle @@ -7,7 +7,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' + classpath 'com.android.tools.build:gradle:3.2.1' } } diff --git a/build.gradle b/build.gradle index 2327356..4f4609a 100644 --- a/build.gradle +++ b/build.gradle @@ -3,14 +3,14 @@ apply plugin: 'kotlin' apply from: 'gradle/dependencies.gradle' buildscript { - ext.kotlin_version = '1.2.51' + ext.kotlin_version = '1.3.10' repositories { google() jcenter() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' + classpath 'com.android.tools.build:gradle:3.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -31,16 +31,16 @@ repositories { jcenter() } dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" } compileKotlin { kotlinOptions { - jvmTarget = "1.7" + jvmTarget = "1.8" } } compileTestKotlin { kotlinOptions { - jvmTarget = "1.7" + jvmTarget = "1.8" } } diff --git a/cockpit/build.gradle b/cockpit/build.gradle index c8a9382..4eb9e35 100644 --- a/cockpit/build.gradle +++ b/cockpit/build.gradle @@ -6,7 +6,7 @@ apply from: rootProject.file('gradle/publishing.gradle') buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.android.tools.build:gradle:3.2.0' + classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath files("../CockpitCore/build/libs/CockpitCore-{$cockpit_core_version}.jar") } @@ -45,7 +45,7 @@ dependencies { api "com.jaredrummler:colorpicker:1.0.2" api 'org.yaml:snakeyaml:1.20' api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - api 'androidx.appcompat:appcompat:1.0.0' + api 'androidx.appcompat:appcompat:1.0.2' api 'com.google.android.material:material:1.0.0' api 'androidx.recyclerview:recyclerview:1.0.0' api 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' diff --git a/sample/build.gradle b/sample/build.gradle index da02480..32dae0a 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -69,13 +69,13 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' implementation 'com.squareup:seismic:1.0.2' testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.0-beta01' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-beta01' + androidTestImplementation 'androidx.test:runner:1.1.1-alpha01' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1-alpha01' debugImplementation project(':cockpit') } From 756aaf2238633f681933d2555e49d1e651900476 Mon Sep 17 00:00:00 2001 From: Marcin Kornacki Date: Thu, 6 Dec 2018 08:37:42 +0100 Subject: [PATCH 06/28] Fix disappearing read only param values after restoring defaults. --- .../cockpit/paramsedition/ParamsEditionModel.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt index f8cbbd9..a9ebdb8 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt @@ -1,9 +1,10 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.core.CockpitParam -import com.polidea.cockpit.manager.CockpitManager +import com.polidea.cockpit.core.type.CockpitReadOnly import com.polidea.cockpit.extensions.getParam import com.polidea.cockpit.extensions.toGroupedParams +import com.polidea.cockpit.manager.CockpitManager internal class ParamsEditionModel : ParamsModel { @@ -49,7 +50,15 @@ internal class ParamsEditionModel : ParamsModel { } fun restoreAll() { - paramsCopy = CockpitManager.getDefaultParamsCopy() + val restoredParams = CockpitManager.getDefaultParamsCopy() + restoredParams.forEachIndexed { index, param -> + if (param.value is CockpitReadOnly) { + //Keeping current value prevents CockpitReadOnly param from being emptied. + param.value = paramsCopy[index].value + } + } + + paramsCopy = restoredParams groupedParamsCopy = paramsCopy.toGroupedParams() } From b969af0bb3b3633ec2a58092a8a3656ca9737cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Woldan=CC=81ska?= Date: Thu, 6 Dec 2018 11:12:22 +0100 Subject: [PATCH 07/28] Version 3.0.1 --- CockpitCore/build.gradle | 2 +- CockpitPlugin/build.gradle | 4 ++-- README.md | 4 ++-- gradle.properties | 2 +- gradle/dependencies.gradle | 2 +- sample/build.gradle | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CockpitCore/build.gradle b/CockpitCore/build.gradle index f2f350b..9d3c60b 100644 --- a/CockpitCore/build.gradle +++ b/CockpitCore/build.gradle @@ -16,7 +16,7 @@ plugins { } group 'com.polidea.cockpit' -version '3.0.0' +version '3.0.1' repositories { google() diff --git a/CockpitPlugin/build.gradle b/CockpitPlugin/build.gradle index 4058549..a6abf1a 100644 --- a/CockpitPlugin/build.gradle +++ b/CockpitPlugin/build.gradle @@ -1,6 +1,6 @@ buildscript { ext.kotlin_version = '1.2.51' - ext.cockpit_core_version = '3.0.0' + ext.cockpit_core_version = '3.0.1' repositories { maven { url "https://plugins.gradle.org/m2/" @@ -21,7 +21,7 @@ plugins { } group = 'com.polidea.cockpit' -version = '3.0.0' +version = '3.0.1' sourceCompatibility = 1.7 diff --git a/README.md b/README.md index 944b962..cb48a40 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Then add CockpitPlugin classpath into your `buildscript#dependencies`: ``` buildscript { dependencies { - classpath "gradle.plugin.com.polidea.cockpit:CockpitPlugin:3.0.0" + classpath "gradle.plugin.com.polidea.cockpit:CockpitPlugin:3.0.1" } } ``` @@ -206,7 +206,7 @@ Last thing is to add Cockpit library dependency: ``` dependencies { - debugImplementation 'com.polidea.cockpit:cockpit:3.0.0' + debugImplementation 'com.polidea.cockpit:cockpit:3.0.1' } ``` diff --git a/gradle.properties b/gradle.properties index 9a00b60..fde3aa3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ GROUP=com.polidea.cockpit POM_ARTIFACT_ID=cockpit POM_NAME=Cockpit POM_PACKAGING=aar -VERSION_NAME=3.0.0 +VERSION_NAME=3.0.1 POM_DESCRIPTION=Cockpit is an Android library providing a way to easily define a set of parameters that can be accessed and changed by the developers via built-in compact UI at runtime. diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 2e11ac4..2d050ca 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -1,3 +1,3 @@ ext { - cockpit_core_version = '3.0.0' + cockpit_core_version = '3.0.1' } \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 32dae0a..89b446c 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -27,7 +27,7 @@ android { minSdkVersion 21 targetSdkVersion 28 versionCode 2 - versionName "3.0.0" + versionName "3.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From 16b4122c22db460d765e06bb4db1b7c3cbc8a55e Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Thu, 31 Jan 2019 18:10:22 +0100 Subject: [PATCH 08/28] Group parsing logic --- .../polidea/cockpit/core/CockpitParamGroup.kt | 21 ++++++++ .../com/polidea/cockpitplugin/util/Util.kt | 6 +++ .../cockpit/extensions/CockpitParamExt.kt | 2 +- .../extensions/CockpitParamGroupExt.kt | 53 +++++++++++++++++++ .../cockpit/paramsedition/ItemPosition.kt | 3 +- .../paramsedition/ParamsEditionModel.kt | 34 ++++++++---- .../cockpit/paramsedition/ParamsModel.kt | 4 ++ .../src/main/res/drawable/chevron_right.xml | 9 ++++ .../main/res/layout/open_group_in_page.xml | 15 ++++++ 9 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt create mode 100644 cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt create mode 100644 cockpit/src/main/res/drawable/chevron_right.xml create mode 100644 cockpit/src/main/res/layout/open_group_in_page.xml diff --git a/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt b/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt new file mode 100644 index 0000000..9a08296 --- /dev/null +++ b/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt @@ -0,0 +1,21 @@ +package com.polidea.cockpit.core + +const val GROUP_DELIMITER = '/' + +data class CockpitParamGroup(val name: String?, val subgroups: List, val params: List>) { + val displayName: String? + get() = name?.split(GROUP_DELIMITER)?.last() + + val displaySize: Int + get() = subgroups.size + params.size + + fun isParent(): Boolean = subgroups.isNotEmpty() + fun isChild(): Boolean = name?.contains(GROUP_DELIMITER) == true +} + +data class MutableCockpitParamGroup(val name: String?, + val subgroups: MutableList = mutableListOf(), + val params: MutableList> = mutableListOf()) { + + fun toReadOnly(): CockpitParamGroup = CockpitParamGroup(name, subgroups.map { it.toReadOnly() }, params) +} \ No newline at end of file diff --git a/CockpitPlugin/src/main/java/com/polidea/cockpitplugin/util/Util.kt b/CockpitPlugin/src/main/java/com/polidea/cockpitplugin/util/Util.kt index d3b2815..ff48aaa 100644 --- a/CockpitPlugin/src/main/java/com/polidea/cockpitplugin/util/Util.kt +++ b/CockpitPlugin/src/main/java/com/polidea/cockpitplugin/util/Util.kt @@ -5,6 +5,12 @@ internal class Util { companion object { // Kotlin version of following deep merge map method: // http://blog.mathieu.photography/post/103163278870/deep-merge-map-in-groovy + // + // Merges `overrides` into `onto`. + // Merging strategy is as follows: + // 1. if value doesn't exist in destination, add it to destination + // 2. if value is a map, merge it using the same algorithm + // 3. if value exists, overwrites it with value from last of the `overrides` fun deepMerge(onto: MutableMap, vararg overrides: Map): MutableMap { if (overrides.isEmpty()) { return onto diff --git a/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamExt.kt b/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamExt.kt index 7af8e12..0404d3b 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamExt.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamExt.kt @@ -29,4 +29,4 @@ internal fun List>.toGroupedParams(): Map.getDisplaySize(): Int { + return this.values.fold(0) { acc, group -> + acc + if (!group.isChild()) 1 + group.displaySize else 0 + } +} + +internal fun Map>>.convertToGroups(): Map { + val extractedSubgroups = LinkedHashMap() + + forEach { + val group = extractedSubgroups.getOrCreateGroupAndParents(it.key) + group.params.addAll(it.value) + extractedSubgroups[it.key] = group + } + + return extractedSubgroups.toReducedNonMutable() +} + +private fun MutableMap.getOrCreateGroupAndParents(name: String?): MutableCockpitParamGroup { + val group = this[name] ?: MutableCockpitParamGroup(name) + if (!this.containsKey(name)) this[name] = group + + if (name?.contains(GROUP_DELIMITER) == true) { + val nextName = name.substring(0, name.lastIndexOf(GROUP_DELIMITER) - 1) + val parent = getOrCreateGroupAndParents(nextName) + parent.subgroups.add(group) + } + + return group +} + +private fun MutableMap.toReducedNonMutable(): Map { + val mapOfNonMutables = LinkedHashMap() + topLevelGroups().forEach { + mapOfNonMutables[it.key] = it.value.toReadOnly() + mapOfNonMutables[it.key]?.subgroups?.forEach { subgroup -> + mapOfNonMutables[subgroup.name] = subgroup + } + } + + assert(this.size == mapOfNonMutables.size) + + return mapOfNonMutables +} + +internal fun Map.topLevelGroups(): Map = filter { it.key?.contains(GROUP_DELIMITER) != true } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt index ef46dee..e7c7afb 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt @@ -3,8 +3,9 @@ package com.polidea.cockpit.paramsedition internal data class ItemPosition(val groupIndex: Int, val paramIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM) { fun isGroupPosition() = paramIndex == PARAM_INDEX_FOR_GROUP_ITEM + fun isSubGroupPosition() = paramIndex < 0 && paramIndex != PARAM_INDEX_FOR_GROUP_ITEM companion object { - private const val PARAM_INDEX_FOR_GROUP_ITEM = -1 + private const val PARAM_INDEX_FOR_GROUP_ITEM = Int.MIN_VALUE } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt index a9ebdb8..a27adbe 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt @@ -1,16 +1,22 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.core.CockpitParam +import com.polidea.cockpit.core.CockpitParamGroup import com.polidea.cockpit.core.type.CockpitReadOnly -import com.polidea.cockpit.extensions.getParam -import com.polidea.cockpit.extensions.toGroupedParams +import com.polidea.cockpit.extensions.* import com.polidea.cockpit.manager.CockpitManager internal class ParamsEditionModel : ParamsModel { - private var paramsCopy: List> = CockpitManager.getParamsCopy() + private lateinit var paramsCopy: List> + private lateinit var groupedParamsCopy: Map + private lateinit var topLevelGroups: Map - private var groupedParamsCopy: Map>> = paramsCopy.toGroupedParams() + override lateinit var groupNames: List + private set + + override val displaySize: Int + get() = groupedParamsCopy.getDisplaySize() override val paramsSize: Int get() = paramsCopy.size @@ -18,14 +24,18 @@ internal class ParamsEditionModel : ParamsModel { override val groupsSize: Int get() = groupedParamsCopy.size + init { + setParams(CockpitManager.getParamsCopy()) + } + override fun getGroupSize(groupIndex: Int) = - groupedParamsCopy[getGroupName(groupIndex)]?.size + groupedParamsCopy[getGroupName(groupIndex)]?.displaySize ?: throw IllegalArgumentException("Couldn't find group for index: $groupIndex") - override fun getGroupName(groupIndex: Int) = groupedParamsCopy.keys.toList()[groupIndex] + override fun getGroupName(groupIndex: Int) = groupNames[groupIndex] override fun getParamAt(itemPosition: ItemPosition): CockpitParam = - groupedParamsCopy[getGroupName(itemPosition.groupIndex)]?.getParam(itemPosition.paramIndex) + groupedParamsCopy[getGroupName(itemPosition.groupIndex)]?.params?.getParam(itemPosition.paramIndex) ?: throw IllegalArgumentException("Cannot find param for ${itemPosition.groupIndex} group index and ${itemPosition.paramIndex} param index") fun setValue(itemPosition: ItemPosition, newValue: T) { @@ -58,12 +68,18 @@ internal class ParamsEditionModel : ParamsModel { } } - paramsCopy = restoredParams - groupedParamsCopy = paramsCopy.toGroupedParams() + setParams(restoredParams) } fun save() { CockpitManager.setParamValues(paramsCopy) CockpitManager.save() } + + private fun setParams(newParams: List>) { + paramsCopy = newParams + groupedParamsCopy = paramsCopy.toGroupedParams().convertToGroups() + topLevelGroups = groupedParamsCopy.topLevelGroups() + groupNames = topLevelGroups.keys.toList() + } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt index afacd1a..8fa2f2f 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt @@ -4,10 +4,14 @@ import com.polidea.cockpit.core.CockpitParam internal interface ParamsModel { + val displaySize: Int + val paramsSize: Int val groupsSize: Int + val groupNames: List + fun getGroupName(groupIndex: Int): String? fun getGroupSize(groupIndex: Int): Int diff --git a/cockpit/src/main/res/drawable/chevron_right.xml b/cockpit/src/main/res/drawable/chevron_right.xml new file mode 100644 index 0000000..2483512 --- /dev/null +++ b/cockpit/src/main/res/drawable/chevron_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/cockpit/src/main/res/layout/open_group_in_page.xml b/cockpit/src/main/res/layout/open_group_in_page.xml new file mode 100644 index 0000000..16b7e65 --- /dev/null +++ b/cockpit/src/main/res/layout/open_group_in_page.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file From a5f78abf253824799802aa9caba9b0660c284136 Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Fri, 22 Mar 2019 17:46:31 +0100 Subject: [PATCH 09/28] Update build dependencies --- CockpitCore/build.gradle | 6 +++--- CockpitPlugin/build.gradle | 4 ++-- build.gradle | 2 +- cockpit/build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CockpitCore/build.gradle b/CockpitCore/build.gradle index 9d3c60b..1f27834 100644 --- a/CockpitCore/build.gradle +++ b/CockpitCore/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.51' + ext.kotlin_version = '1.3.10' repositories { jcenter() maven { url 'https://maven.google.com' } @@ -7,12 +7,12 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.2' } } plugins { - id 'org.jetbrains.kotlin.jvm' version '1.2.51' + id 'org.jetbrains.kotlin.jvm' version '1.3.10' } group 'com.polidea.cockpit' diff --git a/CockpitPlugin/build.gradle b/CockpitPlugin/build.gradle index a6abf1a..dd54156 100644 --- a/CockpitPlugin/build.gradle +++ b/CockpitPlugin/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.51' + ext.kotlin_version = '1.3.10' ext.cockpit_core_version = '3.0.1' repositories { maven { @@ -16,7 +16,7 @@ plugins { id 'groovy' id 'maven' id "com.gradle.plugin-publish" version "0.9.10" - id 'org.jetbrains.kotlin.jvm' version '1.2.51' + id 'org.jetbrains.kotlin.jvm' version '1.3.10' id 'java-gradle-plugin' } diff --git a/build.gradle b/build.gradle index 4f4609a..4dbfa75 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/cockpit/build.gradle b/cockpit/build.gradle index 4eb9e35..c792120 100644 --- a/cockpit/build.gradle +++ b/cockpit/build.gradle @@ -6,7 +6,7 @@ apply from: rootProject.file('gradle/publishing.gradle') buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.2' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath files("../CockpitCore/build/libs/CockpitCore-{$cockpit_core_version}.jar") } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0a03183..3ec05bc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Jun 14 10:06:55 CEST 2018 +#Tue Jan 15 15:26:40 CET 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip From e60c4e61723e428e68bc7772fddf889e546d7c5f Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Thu, 28 Mar 2019 16:46:34 +0100 Subject: [PATCH 10/28] Primitive display of subgroups inside top level groups --- .../cockpit/extensions/CockpitParamGroupExt.kt | 2 +- .../polidea/cockpit/paramsedition/GroupSize.kt | 5 +++++ .../cockpit/paramsedition/ItemPosition.kt | 11 +++++++---- .../paramsedition/ParamsEditionAdapter.kt | 6 ++++++ .../cockpit/paramsedition/ParamsEditionModel.kt | 7 +++++-- .../ParamsEditionPositionMapper.kt | 13 +++++++++---- .../cockpit/paramsedition/ParamsModel.kt | 4 +++- .../viewholder/SubgroupViewHolder.kt | 17 +++++++++++++++++ .../{open_group_in_page.xml => subgroup.xml} | 8 ++++++++ sample/cockpit/cockpit.yml | 5 +++++ 10 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt rename cockpit/src/main/res/layout/{open_group_in_page.xml => subgroup.xml} (73%) diff --git a/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt b/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt index 062ae75..b7165b4 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt @@ -28,7 +28,7 @@ private fun MutableMap.getOrCreateGroupAndPar if (!this.containsKey(name)) this[name] = group if (name?.contains(GROUP_DELIMITER) == true) { - val nextName = name.substring(0, name.lastIndexOf(GROUP_DELIMITER) - 1) + val nextName = name.substring(0, name.lastIndexOf(GROUP_DELIMITER)) val parent = getOrCreateGroupAndParents(nextName) parent.subgroups.add(group) } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt new file mode 100644 index 0000000..452dfe4 --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt @@ -0,0 +1,5 @@ +package com.polidea.cockpit.paramsedition + +data class GroupSize(val subgroupsSize: Int, val paramsSize: Int) { + val size = subgroupsSize + paramsSize +} diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt index e7c7afb..396becc 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt @@ -1,11 +1,14 @@ package com.polidea.cockpit.paramsedition -internal data class ItemPosition(val groupIndex: Int, val paramIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM) { +internal data class ItemPosition(val groupIndex: Int, + val subgroupIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM, + val paramIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM) { - fun isGroupPosition() = paramIndex == PARAM_INDEX_FOR_GROUP_ITEM - fun isSubGroupPosition() = paramIndex < 0 && paramIndex != PARAM_INDEX_FOR_GROUP_ITEM + fun isGroupPosition() = paramIndex == PARAM_INDEX_FOR_GROUP_ITEM && subgroupIndex == PARAM_INDEX_FOR_GROUP_ITEM + fun isSubGroupPosition() = subgroupIndex != PARAM_INDEX_FOR_GROUP_ITEM + && paramIndex == PARAM_INDEX_FOR_GROUP_ITEM companion object { - private const val PARAM_INDEX_FOR_GROUP_ITEM = Int.MIN_VALUE + private const val PARAM_INDEX_FOR_GROUP_ITEM = -1 } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt index 32f140a..13f68c8 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt @@ -26,6 +26,7 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present ParamType.READ_ONLY.ordinal -> ReadOnlyParamViewHolder(inflateViewForHolder(R.layout.cockpit_read_only_param, parent)).configure() ParamType.STEP_INT.ordinal -> StepIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() + SUBGROUP_TYPE_ID -> SubgroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)) else -> GroupViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) } } @@ -52,6 +53,7 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present ParamType.STEP_INT.ordinal -> (holder as StepIntParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) ParamType.STEP_DOUBLE.ordinal -> (holder as StepDoubleParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) GROUP_TYPE_ID -> (holder as GroupViewHolder).display(paramsModel.getGroupName(itemPosition.groupIndex)) + SUBGROUP_TYPE_ID -> (holder as SubgroupViewHolder).display(paramsModel.getSubgroupName(itemPosition.groupIndex, itemPosition.subgroupIndex)) } } @@ -71,6 +73,9 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present if (itemPosition.isGroupPosition()) return GROUP_TYPE_ID + if (itemPosition.isSubGroupPosition()) + return SUBGROUP_TYPE_ID + val param = paramsModel.getParamAt(itemPosition) return ParamType.getParamType(param).ordinal } @@ -98,5 +103,6 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present companion object { private val GROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 1 + private val SUBGROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 2 } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt index a27adbe..b1dec23 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt @@ -1,5 +1,6 @@ package com.polidea.cockpit.paramsedition +import android.util.Log import com.polidea.cockpit.core.CockpitParam import com.polidea.cockpit.core.CockpitParamGroup import com.polidea.cockpit.core.type.CockpitReadOnly @@ -22,18 +23,20 @@ internal class ParamsEditionModel : ParamsModel { get() = paramsCopy.size override val groupsSize: Int - get() = groupedParamsCopy.size + get() = topLevelGroups.size init { setParams(CockpitManager.getParamsCopy()) } override fun getGroupSize(groupIndex: Int) = - groupedParamsCopy[getGroupName(groupIndex)]?.displaySize + groupedParamsCopy[getGroupName(groupIndex)]?.run { GroupSize(subgroups.size, params.size) } ?: throw IllegalArgumentException("Couldn't find group for index: $groupIndex") override fun getGroupName(groupIndex: Int) = groupNames[groupIndex] + override fun getSubgroupName(groupIndex: Int, subgroupIndex: Int): String? = topLevelGroups.values.toList()[groupIndex].subgroups[subgroupIndex].displayName + override fun getParamAt(itemPosition: ItemPosition): CockpitParam = groupedParamsCopy[getGroupName(itemPosition.groupIndex)]?.params?.getParam(itemPosition.paramIndex) ?: throw IllegalArgumentException("Cannot find param for ${itemPosition.groupIndex} group index and ${itemPosition.paramIndex} param index") diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt index 8384a75..7175951 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt @@ -10,10 +10,15 @@ internal class ParamsEditionPositionMapper(private val paramsModel: ParamsModel) tmpPosition++ val groupSize = paramsModel.getGroupSize(groupIndex) - if (adapterPosition >= tmpPosition && adapterPosition < tmpPosition + groupSize) { - return ItemPosition(groupIndex, adapterPosition - tmpPosition) + if (adapterPosition >= tmpPosition && adapterPosition < tmpPosition + groupSize.size) { + if (adapterPosition - tmpPosition < groupSize.subgroupsSize) { + return ItemPosition(groupIndex, subgroupIndex = adapterPosition - tmpPosition) + } else { + return ItemPosition(groupIndex, paramIndex = adapterPosition - tmpPosition - groupSize.subgroupsSize) + } + } - tmpPosition += groupSize + tmpPosition += groupSize.size } throw IllegalArgumentException("No item position for $adapterPosition adapter position") @@ -24,7 +29,7 @@ internal class ParamsEditionPositionMapper(private val paramsModel: ParamsModel) var adapterPosition = itemPosition.groupIndex for (tmpGroupIndex in 0 until itemPosition.groupIndex) - adapterPosition += paramsModel.getGroupSize(tmpGroupIndex) + adapterPosition += paramsModel.getGroupSize(tmpGroupIndex).size if (!itemPosition.isGroupPosition()) adapterPosition += itemPosition.paramIndex + 1 diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt index 8fa2f2f..4e436f9 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt @@ -14,7 +14,9 @@ internal interface ParamsModel { fun getGroupName(groupIndex: Int): String? - fun getGroupSize(groupIndex: Int): Int + fun getSubgroupName(groupIndex: Int, subgroupIndex: Int): String? + + fun getGroupSize(groupIndex: Int): GroupSize fun getParamAt(itemPosition: ItemPosition): CockpitParam } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt new file mode 100644 index 0000000..9e85c2f --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt @@ -0,0 +1,17 @@ +package com.polidea.cockpit.paramsedition.viewholder + +import android.view.View +import android.widget.TextView +import android.widget.Toast +import androidx.recyclerview.widget.RecyclerView +import com.polidea.cockpit.R + +internal class SubgroupViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + + private val name: TextView = view.findViewById(R.id.subgroup_name) + + fun display(groupName: String?) { + name.text = groupName ?: view.context.getString(R.string.default_group_name) + view.setOnClickListener { Toast.makeText(view.context, groupName, Toast.LENGTH_SHORT).show() } + } +} \ No newline at end of file diff --git a/cockpit/src/main/res/layout/open_group_in_page.xml b/cockpit/src/main/res/layout/subgroup.xml similarity index 73% rename from cockpit/src/main/res/layout/open_group_in_page.xml rename to cockpit/src/main/res/layout/subgroup.xml index 16b7e65..eafae34 100644 --- a/cockpit/src/main/res/layout/open_group_in_page.xml +++ b/cockpit/src/main/res/layout/subgroup.xml @@ -4,6 +4,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + Date: Mon, 1 Apr 2019 14:12:11 +0200 Subject: [PATCH 11/28] Review changes --- .../polidea/cockpit/core/CockpitParamGroup.kt | 1 - .../extensions/CockpitParamGroupExt.kt | 6 +++--- .../cockpit/paramsedition/ItemPosition.kt | 4 ++-- .../paramsedition/ParamsEditionAdapter.kt | 18 ++++++++-------- .../ParamsEditionPositionMapper.kt | 10 +++++++-- .../viewholder/GroupViewHolder.kt | 10 +++------ .../viewholder/SectionViewHolder.kt | 21 +++++++++++++++++++ .../viewholder/SubgroupViewHolder.kt | 17 --------------- .../ParamsEditionPositionMapperTest.kt | 14 ++++++------- 9 files changed, 53 insertions(+), 48 deletions(-) create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SectionViewHolder.kt delete mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt diff --git a/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt b/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt index 9a08296..b6170d1 100644 --- a/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt +++ b/CockpitCore/src/main/java/com/polidea/cockpit/core/CockpitParamGroup.kt @@ -9,7 +9,6 @@ data class CockpitParamGroup(val name: String?, val subgroups: List>>.convertToGroups(): Map() forEach { - val group = extractedSubgroups.getOrCreateGroupAndParents(it.key) + val group = extractedSubgroups.getOrCreateGroupHierarchy(it.key) group.params.addAll(it.value) extractedSubgroups[it.key] = group } @@ -23,13 +23,13 @@ internal fun Map>>.convertToGroups(): Map.getOrCreateGroupAndParents(name: String?): MutableCockpitParamGroup { +private fun MutableMap.getOrCreateGroupHierarchy(name: String?): MutableCockpitParamGroup { val group = this[name] ?: MutableCockpitParamGroup(name) if (!this.containsKey(name)) this[name] = group if (name?.contains(GROUP_DELIMITER) == true) { val nextName = name.substring(0, name.lastIndexOf(GROUP_DELIMITER)) - val parent = getOrCreateGroupAndParents(nextName) + val parent = getOrCreateGroupHierarchy(nextName) parent.subgroups.add(group) } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt index 396becc..bb5eea1 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt @@ -4,8 +4,8 @@ internal data class ItemPosition(val groupIndex: Int, val subgroupIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM, val paramIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM) { - fun isGroupPosition() = paramIndex == PARAM_INDEX_FOR_GROUP_ITEM && subgroupIndex == PARAM_INDEX_FOR_GROUP_ITEM - fun isSubGroupPosition() = subgroupIndex != PARAM_INDEX_FOR_GROUP_ITEM + fun isSectionPosition() = paramIndex == PARAM_INDEX_FOR_GROUP_ITEM && subgroupIndex == PARAM_INDEX_FOR_GROUP_ITEM + fun isGroupPosition() = subgroupIndex != PARAM_INDEX_FOR_GROUP_ITEM && paramIndex == PARAM_INDEX_FOR_GROUP_ITEM companion object { diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt index 13f68c8..9a0a80c 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt @@ -26,8 +26,8 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present ParamType.READ_ONLY.ordinal -> ReadOnlyParamViewHolder(inflateViewForHolder(R.layout.cockpit_read_only_param, parent)).configure() ParamType.STEP_INT.ordinal -> StepIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() - SUBGROUP_TYPE_ID -> SubgroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)) - else -> GroupViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) + GROUP_TYPE_ID -> GroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)) + else -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) } } @@ -52,8 +52,8 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present ParamType.READ_ONLY.ordinal -> (holder as ReadOnlyParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) ParamType.STEP_INT.ordinal -> (holder as StepIntParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) ParamType.STEP_DOUBLE.ordinal -> (holder as StepDoubleParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - GROUP_TYPE_ID -> (holder as GroupViewHolder).display(paramsModel.getGroupName(itemPosition.groupIndex)) - SUBGROUP_TYPE_ID -> (holder as SubgroupViewHolder).display(paramsModel.getSubgroupName(itemPosition.groupIndex, itemPosition.subgroupIndex)) + SECTION_TYPE_ID -> (holder as SectionViewHolder).display(paramsModel.getGroupName(itemPosition.groupIndex)) + GROUP_TYPE_ID -> (holder as GroupViewHolder).display(paramsModel.getSubgroupName(itemPosition.groupIndex, itemPosition.subgroupIndex)) } } @@ -70,12 +70,12 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present override fun getItemViewType(position: Int): Int { val itemPosition = positionMapper.toItemPosition(position) + if (itemPosition.isSectionPosition()) + return SECTION_TYPE_ID + if (itemPosition.isGroupPosition()) return GROUP_TYPE_ID - if (itemPosition.isSubGroupPosition()) - return SUBGROUP_TYPE_ID - val param = paramsModel.getParamAt(itemPosition) return ParamType.getParamType(param).ordinal } @@ -102,7 +102,7 @@ internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Present } companion object { - private val GROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 1 - private val SUBGROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 2 + private val SECTION_TYPE_ID: Int = ParamType.values().last().ordinal + 1 + private val GROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 2 } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt index 7175951..44398df 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt @@ -31,8 +31,14 @@ internal class ParamsEditionPositionMapper(private val paramsModel: ParamsModel) for (tmpGroupIndex in 0 until itemPosition.groupIndex) adapterPosition += paramsModel.getGroupSize(tmpGroupIndex).size - if (!itemPosition.isGroupPosition()) - adapterPosition += itemPosition.paramIndex + 1 + if (!itemPosition.isSectionPosition()) { + if (!itemPosition.isGroupPosition()) { + adapterPosition += paramsModel.getGroupSize(itemPosition.groupIndex).subgroupsSize + itemPosition.paramIndex + 1 + } else { + adapterPosition += itemPosition.subgroupIndex + 1 + } + } + return adapterPosition } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt index e9ca605..08983c5 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt @@ -2,20 +2,16 @@ package com.polidea.cockpit.paramsedition.viewholder import android.view.View import android.widget.TextView +import android.widget.Toast import androidx.recyclerview.widget.RecyclerView import com.polidea.cockpit.R internal class GroupViewHolder(val view: View) : RecyclerView.ViewHolder(view) { - private val separator: View = view.findViewById(R.id.cockpit_group_separator) - private val name: TextView = view.findViewById(R.id.cockpit_group_name) + private val name: TextView = view.findViewById(R.id.subgroup_name) fun display(groupName: String?) { - if (adapterPosition == 0) - separator.visibility = View.GONE - else - separator.visibility = View.VISIBLE - name.text = groupName ?: view.context.getString(R.string.default_group_name) + view.setOnClickListener { Toast.makeText(view.context, groupName, Toast.LENGTH_SHORT).show() } } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SectionViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SectionViewHolder.kt new file mode 100644 index 0000000..30674b1 --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SectionViewHolder.kt @@ -0,0 +1,21 @@ +package com.polidea.cockpit.paramsedition.viewholder + +import android.view.View +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.polidea.cockpit.R + +internal class SectionViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + + private val separator: View = view.findViewById(R.id.cockpit_group_separator) + private val name: TextView = view.findViewById(R.id.cockpit_group_name) + + fun display(groupName: String?) { + if (adapterPosition == 0) + separator.visibility = View.GONE + else + separator.visibility = View.VISIBLE + + name.text = groupName ?: view.context.getString(R.string.default_group_name) + } +} \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt deleted file mode 100644 index 9e85c2f..0000000 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/SubgroupViewHolder.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.polidea.cockpit.paramsedition.viewholder - -import android.view.View -import android.widget.TextView -import android.widget.Toast -import androidx.recyclerview.widget.RecyclerView -import com.polidea.cockpit.R - -internal class SubgroupViewHolder(val view: View) : RecyclerView.ViewHolder(view) { - - private val name: TextView = view.findViewById(R.id.subgroup_name) - - fun display(groupName: String?) { - name.text = groupName ?: view.context.getString(R.string.default_group_name) - view.setOnClickListener { Toast.makeText(view.context, groupName, Toast.LENGTH_SHORT).show() } - } -} \ No newline at end of file diff --git a/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt b/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt index 22ff523..0c3c18c 100644 --- a/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt +++ b/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt @@ -40,7 +40,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(0) - assertTrue(itemPosition.isGroupPosition()) + assertTrue(itemPosition.isSectionPosition()) assertEquals(0, itemPosition.groupIndex) CockpitManager.clear() @@ -52,7 +52,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(1) - assertFalse(itemPosition.isGroupPosition()) + assertFalse(itemPosition.isSectionPosition()) assertEquals(0, itemPosition.groupIndex) assertEquals(0, itemPosition.paramIndex) @@ -65,7 +65,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(2) - assertFalse(itemPosition.isGroupPosition()) + assertFalse(itemPosition.isSectionPosition()) assertEquals(0, itemPosition.groupIndex) assertEquals(1, itemPosition.paramIndex) @@ -78,7 +78,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(3) - assertTrue(itemPosition.isGroupPosition()) + assertTrue(itemPosition.isSectionPosition()) assertEquals(1, itemPosition.groupIndex) } @@ -88,7 +88,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(4) - assertFalse(itemPosition.isGroupPosition()) + assertFalse(itemPosition.isSectionPosition()) assertEquals(1, itemPosition.groupIndex) assertEquals(0, itemPosition.paramIndex) @@ -101,7 +101,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(5) - assertTrue(itemPosition.isGroupPosition()) + assertTrue(itemPosition.isSectionPosition()) assertEquals(2, itemPosition.groupIndex) CockpitManager.clear() @@ -113,7 +113,7 @@ class ParamsEditionPositionMapperTest { val mapper = createMapper() val itemPosition = mapper.toItemPosition(6) - assertFalse(itemPosition.isGroupPosition()) + assertFalse(itemPosition.isSectionPosition()) assertEquals(2, itemPosition.groupIndex) assertEquals(0, itemPosition.paramIndex) From 64ac82af82e85bfa18c3dc5427c7bb6fbca2ae8c Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Wed, 3 Apr 2019 13:25:41 +0200 Subject: [PATCH 12/28] Descending navigation + param display refactor --- .../cockpit/paramsedition/CockpitDialog.kt | 18 +- .../paramsedition/CockpitDialogPresenter.kt | 47 ++-- .../cockpit/paramsedition/GroupSize.kt | 5 - .../cockpit/paramsedition/ItemPosition.kt | 14 -- .../paramsedition/ParamsEditionAdapter.kt | 108 --------- .../paramsedition/ParamsEditionContract.kt | 22 +- .../paramsedition/ParamsEditionModel.kt | 66 ++---- .../ParamsEditionPositionMapper.kt | 45 ---- .../cockpit/paramsedition/ParamsModel.kt | 17 +- .../paramsedition/refactor/AdapterModel.kt | 35 +++ .../paramsedition/refactor/ParamAdapter.kt | 148 ++++++++++++ .../viewholder/GroupViewHolder.kt | 6 +- cockpit/src/main/res/layout/subgroup.xml | 21 +- .../ParamsEditionPositionMapperTest.kt | 221 ------------------ 14 files changed, 285 insertions(+), 488 deletions(-) delete mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt delete mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt delete mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt delete mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt delete mode 100644 cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt index 74faac4..0759276 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt @@ -15,11 +15,13 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import com.polidea.cockpit.R import com.polidea.cockpit.extensions.removeDimmedBackground import com.polidea.cockpit.paramsedition.layout.CockpitLayout +import com.polidea.cockpit.paramsedition.refactor.DisplayModel +import com.polidea.cockpit.paramsedition.refactor.ParamAdapter internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), ParamsEditionContract.View { override lateinit var presenter: ParamsEditionContract.Presenter - private lateinit var paramsEditionAdapter: ParamsEditionAdapter + private lateinit var paramsEditionAdapter: ParamAdapter private lateinit var expandCollapse: ImageButton private lateinit var cockpitRoot: CockpitLayout private lateinit var cockpitContent: LinearLayout @@ -34,7 +36,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), ViewGroup.LayoutParams.MATCH_PARENT) } - override fun showColorPicker(itemPosition: ItemPosition, color: Int) { + override fun showColorPicker(paramName: String, color: Int) { val colorPicker = ColorPickerDialog.newBuilder() .setDialogType(ColorPickerDialog.TYPE_CUSTOM) .setAllowPresets(false) @@ -46,7 +48,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), } override fun onColorSelected(dialogId: Int, color: Int) { - presenter.newColorSelected(itemPosition, color) + presenter.newColorSelected(paramName, color) } }) activity?.fragmentManager?.let { @@ -75,7 +77,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), @SuppressLint("ClickableViewAccessibility") private fun setupViews(view: View) { - paramsEditionAdapter = ParamsEditionAdapter(presenter) + paramsEditionAdapter = ParamAdapter(DisplayModel(listOf()), presenter) view.findViewById(R.id.params_list).adapter = paramsEditionAdapter view.findViewById(R.id.restore_defaults).setOnClickListener { presenter.restoreAll() } expandCollapse = view.findViewById(R.id.expand_collapse) @@ -118,14 +120,18 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), presenter.stop() } - override fun reloadParam(itemPosition: ItemPosition) { - paramsEditionAdapter.reloadParam(itemPosition) + override fun reloadParam(paramName: String) { + paramsEditionAdapter.reloadParam(paramName) } override fun reloadAll() { paramsEditionAdapter.reloadAll() } + override fun display(model: DisplayModel) { + paramsEditionAdapter.display(model) + } + override fun expand() { animateExpandCollapseIcon(true) cockpitRoot.expand() diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt index 89b232c..e2de3f6 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt @@ -1,8 +1,12 @@ package com.polidea.cockpit.paramsedition import android.graphics.Color +import com.polidea.cockpit.core.CockpitParamGroup import com.polidea.cockpit.core.type.CockpitColor +import com.polidea.cockpit.paramsedition.refactor.DisplayModel +import com.polidea.cockpit.paramsedition.refactor.toDisplayModel import com.polidea.cockpit.utils.colorToArgbHexString +import java.util.* internal class CockpitDialogPresenter(private val view: ParamsEditionContract.View) : ParamsEditionContract.Presenter { @@ -11,21 +15,21 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi view.presenter = this } - private val model = ParamsEditionModel() + private val model: ParamsModel = ParamsEditionModel() + private val displayStack: Stack = Stack() override fun start() { - view.reloadAll() + displayStack.push(model.topLevelGroups.toDisplayModel()) + view.display(displayStack.peek()) } override fun stop() { model.save() } - override fun getParamsModel() = model - - override fun restore(itemPosition: ItemPosition) { - model.restoreValue(itemPosition) - view.reloadParam(itemPosition) + override fun restore(paramName: String) { + model.restoreValue(paramName) + view.reloadParam(paramName) } override fun restoreAll() { @@ -33,16 +37,21 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi view.reloadAll() } - override fun onParamChange(itemPosition: ItemPosition, newValue: T) { - model.setValue(itemPosition, newValue) + override fun onDisplayGroup(group: CockpitParamGroup) { + displayStack.push(group.toDisplayModel()) + view.display(displayStack.peek()) + } + + override fun onParamChange(paramName: String, newValue: T) { + model.setValue(paramName, newValue) } - override fun onParamValueSelected(itemPosition: ItemPosition, selectedItemIndex: Int) { - model.selectValue(itemPosition, selectedItemIndex) + override fun onParamValueSelected(paramName: String, selectedItemIndex: Int) { + model.selectValue(paramName, selectedItemIndex) } - override fun requestAction(itemPosition: ItemPosition) { - model.requestAction(itemPosition) + override fun requestAction(paramName: String) { + model.requestAction(paramName) } override fun expand() { @@ -61,13 +70,13 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi view.resize(height) } - override fun editColor(itemPosition: ItemPosition) { - val param = model.getParamAt(itemPosition) - view.showColorPicker(itemPosition, Color.parseColor(param.value.value)) + override fun editColor(paramName: String) { + val param = model.getParam(paramName) + view.showColorPicker(paramName, Color.parseColor(param.value.value)) } - override fun newColorSelected(itemPosition: ItemPosition, color: Int) { - onParamChange(itemPosition, CockpitColor(colorToArgbHexString(color))) - view.reloadParam(itemPosition) + override fun newColorSelected(paramName: String, color: Int) { + onParamChange(paramName, CockpitColor(colorToArgbHexString(color))) + view.reloadParam(paramName) } } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt deleted file mode 100644 index 452dfe4..0000000 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/GroupSize.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.polidea.cockpit.paramsedition - -data class GroupSize(val subgroupsSize: Int, val paramsSize: Int) { - val size = subgroupsSize + paramsSize -} diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt deleted file mode 100644 index bb5eea1..0000000 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ItemPosition.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.polidea.cockpit.paramsedition - -internal data class ItemPosition(val groupIndex: Int, - val subgroupIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM, - val paramIndex: Int = PARAM_INDEX_FOR_GROUP_ITEM) { - - fun isSectionPosition() = paramIndex == PARAM_INDEX_FOR_GROUP_ITEM && subgroupIndex == PARAM_INDEX_FOR_GROUP_ITEM - fun isGroupPosition() = subgroupIndex != PARAM_INDEX_FOR_GROUP_ITEM - && paramIndex == PARAM_INDEX_FOR_GROUP_ITEM - - companion object { - private const val PARAM_INDEX_FOR_GROUP_ITEM = -1 - } -} \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt deleted file mode 100644 index 9a0a80c..0000000 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt +++ /dev/null @@ -1,108 +0,0 @@ -package com.polidea.cockpit.paramsedition - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.annotation.LayoutRes -import androidx.recyclerview.widget.RecyclerView -import com.polidea.cockpit.R -import com.polidea.cockpit.paramsedition.viewholder.* - -internal class ParamsEditionAdapter(var presenter: ParamsEditionContract.Presenter) : RecyclerView.Adapter(), ParamsEditionContract.ParamView { - - private val paramsModel = presenter.getParamsModel() - private val positionMapper = ParamsEditionPositionMapper(paramsModel) - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - return when (viewType) { - ParamType.BOOL.ordinal -> BooleanParamViewHolder(inflateViewForHolder(R.layout.cockpit_boolean_param, parent)).configure() - ParamType.INT.ordinal -> IntParamViewHolder(inflateViewForHolder(R.layout.cockpit_number_param, parent)).configure() - ParamType.DOUBLE.ordinal -> DoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_number_param, parent)).configure() - ParamType.STRING.ordinal -> StringParamViewHolder(inflateViewForHolder(R.layout.cockpit_string_param, parent)).configure() - ParamType.LIST.ordinal -> ListParamViewHolder(inflateViewForHolder(R.layout.cockpit_list_param, parent)).configure() - ParamType.ACTION.ordinal -> ActionParamViewHolder(inflateViewForHolder(R.layout.cockpit_action_param, parent)).configure() - ParamType.COLOR.ordinal -> ColorParamViewHolder(inflateViewForHolder(R.layout.cockpit_color_param, parent)).configure() - ParamType.RANGE_INT.ordinal -> RangeIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_range_param, parent)).configure() - ParamType.RANGE_DOUBLE.ordinal -> RangeDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_range_param, parent)).configure() - ParamType.READ_ONLY.ordinal -> ReadOnlyParamViewHolder(inflateViewForHolder(R.layout.cockpit_read_only_param, parent)).configure() - ParamType.STEP_INT.ordinal -> StepIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() - ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() - GROUP_TYPE_ID -> GroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)) - else -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) - } - } - - private fun inflateViewForHolder(@LayoutRes layoutId: Int, parent: ViewGroup) = LayoutInflater.from(parent.context) - .inflate(layoutId, parent, false) - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - val itemPosition = positionMapper.toItemPosition(position) - when (getItemViewType(position)) { - ParamType.BOOL.ordinal -> (holder as BooleanParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.INT.ordinal -> (holder as IntParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.DOUBLE.ordinal -> (holder as DoubleParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.STRING.ordinal -> (holder as StringParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.LIST.ordinal -> (holder as ListParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.ACTION.ordinal -> (holder as ActionParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.COLOR.ordinal -> (holder as ColorParamViewHolder).apply { - displayParam(paramsModel.getParamAt(itemPosition)) - onColorEditionRequestListener = { presenter.editColor(itemPosition) } - } - ParamType.RANGE_INT.ordinal -> (holder as RangeIntParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.RANGE_DOUBLE.ordinal -> (holder as RangeDoubleParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.READ_ONLY.ordinal -> (holder as ReadOnlyParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.STEP_INT.ordinal -> (holder as StepIntParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - ParamType.STEP_DOUBLE.ordinal -> (holder as StepDoubleParamViewHolder).displayParam(paramsModel.getParamAt(itemPosition)) - SECTION_TYPE_ID -> (holder as SectionViewHolder).display(paramsModel.getGroupName(itemPosition.groupIndex)) - GROUP_TYPE_ID -> (holder as GroupViewHolder).display(paramsModel.getSubgroupName(itemPosition.groupIndex, itemPosition.subgroupIndex)) - } - } - - override fun reloadAll() { - notifyDataSetChanged() - } - - override fun reloadParam(itemPosition: ItemPosition) { - notifyItemChanged(positionMapper.toAdapterPosition(itemPosition)) - } - - override fun getItemCount() = paramsModel.paramsSize + paramsModel.groupsSize - - override fun getItemViewType(position: Int): Int { - val itemPosition = positionMapper.toItemPosition(position) - - if (itemPosition.isSectionPosition()) - return SECTION_TYPE_ID - - if (itemPosition.isGroupPosition()) - return GROUP_TYPE_ID - - val param = paramsModel.getParamAt(itemPosition) - return ParamType.getParamType(param).ordinal - } - - private fun ParamBaseValueWithRestoreViewHolder.configure(): ParamBaseValueWithRestoreViewHolder { - (this as ParamBaseValueViewHolder).configure() - restoreClickListener = { presenter.restore(positionMapper.toItemPosition(adapterPosition)) } - return this - } - - private fun ParamBaseValueViewHolder.configure(): ParamBaseValueViewHolder { - valueChangeListener = { presenter.onParamChange(positionMapper.toItemPosition(adapterPosition), it) } - return this - } - - private fun ActionParamViewHolder.configure(): ActionParamViewHolder { - actionButtonClickListener = { presenter.requestAction(positionMapper.toItemPosition(adapterPosition)) } - return this - } - - private fun SelectionParamBaseViewHolder.configure(): SelectionParamBaseViewHolder { - valueSelectedListener = { presenter.onParamValueSelected(positionMapper.toItemPosition(adapterPosition), it) } - return this - } - - companion object { - private val SECTION_TYPE_ID: Int = ParamType.values().last().ordinal + 1 - private val GROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 2 - } -} \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt index d935d01..389a947 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt @@ -2,6 +2,8 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.BasePresenter import com.polidea.cockpit.BaseView +import com.polidea.cockpit.core.CockpitParamGroup +import com.polidea.cockpit.paramsedition.refactor.DisplayModel internal interface ParamsEditionContract { @@ -14,26 +16,28 @@ internal interface ParamsEditionContract { fun dismiss() - fun showColorPicker(itemPosition: ItemPosition, color: Int) + fun showColorPicker(paramName: String, color: Int) } interface ParamView { - fun reloadParam(itemPosition: ItemPosition) + fun reloadParam(paramName: String) fun reloadAll() + + fun display(model: DisplayModel) } interface Presenter : BasePresenter { - fun getParamsModel(): ParamsModel + fun onParamChange(paramName: String, newValue: T) - fun onParamChange(itemPosition: ItemPosition, newValue: T) + fun onParamValueSelected(paramName: String, selectedItemIndex: Int) - fun onParamValueSelected(itemPosition: ItemPosition, selectedItemIndex: Int) + fun onDisplayGroup(group: CockpitParamGroup) - fun requestAction(itemPosition: ItemPosition) + fun requestAction(paramName: String) - fun restore(itemPosition: ItemPosition) + fun restore(paramName: String) fun restoreAll() @@ -45,8 +49,8 @@ internal interface ParamsEditionContract { fun hidden() - fun editColor(itemPosition: ItemPosition) + fun editColor(paramName: String) - fun newColorSelected(itemPosition: ItemPosition, color: Int) + fun newColorSelected(paramName: String, color: Int) } } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt index b1dec23..570d302 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt @@ -1,6 +1,5 @@ package com.polidea.cockpit.paramsedition -import android.util.Log import com.polidea.cockpit.core.CockpitParam import com.polidea.cockpit.core.CockpitParamGroup import com.polidea.cockpit.core.type.CockpitReadOnly @@ -9,80 +8,55 @@ import com.polidea.cockpit.manager.CockpitManager internal class ParamsEditionModel : ParamsModel { - private lateinit var paramsCopy: List> + private lateinit var paramsCopy: Map> private lateinit var groupedParamsCopy: Map - private lateinit var topLevelGroups: Map - - override lateinit var groupNames: List + override lateinit var topLevelGroups: Map private set - override val displaySize: Int - get() = groupedParamsCopy.getDisplaySize() - - override val paramsSize: Int - get() = paramsCopy.size - - override val groupsSize: Int - get() = topLevelGroups.size - init { setParams(CockpitManager.getParamsCopy()) } - override fun getGroupSize(groupIndex: Int) = - groupedParamsCopy[getGroupName(groupIndex)]?.run { GroupSize(subgroups.size, params.size) } - ?: throw IllegalArgumentException("Couldn't find group for index: $groupIndex") - - override fun getGroupName(groupIndex: Int) = groupNames[groupIndex] - - override fun getSubgroupName(groupIndex: Int, subgroupIndex: Int): String? = topLevelGroups.values.toList()[groupIndex].subgroups[subgroupIndex].displayName - - override fun getParamAt(itemPosition: ItemPosition): CockpitParam = - groupedParamsCopy[getGroupName(itemPosition.groupIndex)]?.params?.getParam(itemPosition.paramIndex) - ?: throw IllegalArgumentException("Cannot find param for ${itemPosition.groupIndex} group index and ${itemPosition.paramIndex} param index") + override fun getParam(paramName: String): CockpitParam + = paramsCopy[paramName] as CockpitParam? ?: throw IllegalArgumentException("Cannot find param for name $paramName") - fun setValue(itemPosition: ItemPosition, newValue: T) { - val param = getParamAt(itemPosition) - param.value = newValue - CockpitManager.setParamValue(param.name, newValue) + override fun setValue(paramName: String, newValue: T) { + getParam(paramName).value = newValue + CockpitManager.setParamValue(paramName, newValue) } - fun selectValue(itemPosition: ItemPosition, selectedItemIndex: Int) { - val param = getParamAt(itemPosition) - CockpitManager.selectParamValue(param.name, selectedItemIndex) + override fun selectValue(paramName: String, selectedItemIndex: Int) { + CockpitManager.selectParamValue(paramName, selectedItemIndex) } - fun restoreValue(itemPosition: ItemPosition) { - val param = getParamAt>(itemPosition) - param.value = CockpitManager.getParamDefaultValue(param.name) + override fun restoreValue(paramName: String) { + getParam>(paramName).value = CockpitManager.getParamDefaultValue(paramName) } - fun requestAction(itemPosition: ItemPosition) { - val param = getParamAt>(itemPosition) - CockpitManager.requestAction(param.name) + override fun requestAction(paramName: String) { + CockpitManager.requestAction(paramName) } - fun restoreAll() { + override fun restoreAll() { val restoredParams = CockpitManager.getDefaultParamsCopy() - restoredParams.forEachIndexed { index, param -> + restoredParams.forEach { param -> if (param.value is CockpitReadOnly) { //Keeping current value prevents CockpitReadOnly param from being emptied. - param.value = paramsCopy[index].value + paramsCopy[param.name]?.apply { param.value = value } } } setParams(restoredParams) } - fun save() { - CockpitManager.setParamValues(paramsCopy) + override fun save() { + CockpitManager.setParamValues(paramsCopy.values) CockpitManager.save() } private fun setParams(newParams: List>) { - paramsCopy = newParams - groupedParamsCopy = paramsCopy.toGroupedParams().convertToGroups() + paramsCopy = newParams.map { it.name to it }.toMap() + groupedParamsCopy = paramsCopy.values.toList().toGroupedParams().convertToGroups() topLevelGroups = groupedParamsCopy.topLevelGroups() - groupNames = topLevelGroups.keys.toList() } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt deleted file mode 100644 index 44398df..0000000 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapper.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.polidea.cockpit.paramsedition - -internal class ParamsEditionPositionMapper(private val paramsModel: ParamsModel) { - - fun toItemPosition(adapterPosition: Int): ItemPosition { - var tmpPosition = 0 - for (groupIndex in 0 until paramsModel.groupsSize) { - if (adapterPosition == tmpPosition) - return ItemPosition(groupIndex) - - tmpPosition++ - val groupSize = paramsModel.getGroupSize(groupIndex) - if (adapterPosition >= tmpPosition && adapterPosition < tmpPosition + groupSize.size) { - if (adapterPosition - tmpPosition < groupSize.subgroupsSize) { - return ItemPosition(groupIndex, subgroupIndex = adapterPosition - tmpPosition) - } else { - return ItemPosition(groupIndex, paramIndex = adapterPosition - tmpPosition - groupSize.subgroupsSize) - } - - } - tmpPosition += groupSize.size - } - - throw IllegalArgumentException("No item position for $adapterPosition adapter position") - } - - fun toAdapterPosition(itemPosition: ItemPosition): Int { - - var adapterPosition = itemPosition.groupIndex - - for (tmpGroupIndex in 0 until itemPosition.groupIndex) - adapterPosition += paramsModel.getGroupSize(tmpGroupIndex).size - - if (!itemPosition.isSectionPosition()) { - if (!itemPosition.isGroupPosition()) { - adapterPosition += paramsModel.getGroupSize(itemPosition.groupIndex).subgroupsSize + itemPosition.paramIndex + 1 - } else { - adapterPosition += itemPosition.subgroupIndex + 1 - } - } - - - return adapterPosition - } -} \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt index 4e436f9..77b1e76 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt @@ -1,22 +1,23 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.core.CockpitParam +import com.polidea.cockpit.core.CockpitParamGroup internal interface ParamsModel { - val displaySize: Int + val topLevelGroups: Map - val paramsSize: Int + fun getParam(paramName: String): CockpitParam - val groupsSize: Int + fun setValue(paramName: String, newValue: T) - val groupNames: List + fun selectValue(paramName: String, selectedItemIndex: Int) - fun getGroupName(groupIndex: Int): String? + fun restoreValue(paramName: String) - fun getSubgroupName(groupIndex: Int, subgroupIndex: Int): String? + fun requestAction(paramName: String) - fun getGroupSize(groupIndex: Int): GroupSize + fun restoreAll() - fun getParamAt(itemPosition: ItemPosition): CockpitParam + fun save() } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt new file mode 100644 index 0000000..f675aec --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt @@ -0,0 +1,35 @@ +package com.polidea.cockpit.paramsedition.refactor + +import com.polidea.cockpit.core.CockpitParam +import com.polidea.cockpit.core.CockpitParamGroup + +internal class DisplayModel(val items: List) + +internal sealed class DisplayItem(val displayName: String?) { + class Section(displayName: String?) : DisplayItem(displayName) + class Group(displayName: String?, val group: CockpitParamGroup) : DisplayItem(displayName) + class Param(displayName: String?, val param: CockpitParam) : DisplayItem(displayName) +// class TopNavigation : DisplayItem(null) +// class BackNavigation : DisplayItem(null) +} + +internal fun Map.toDisplayModel(): DisplayModel { + val items = mutableListOf() + forEach { + items.addAll(it.value.toDisplayModel().items) + } + + return DisplayModel(items) +} + +internal fun CockpitParamGroup.toDisplayModel(addTopNavigation: Boolean = false): DisplayModel { + val items = mutableListOf(DisplayItem.Section(displayName)) +// if (addTopNavigation) { +// items.add(DisplayItem.TopNavigation()) +// items.add(DisplayItem.BackNavigation()) +// } + items.addAll(subgroups.map { DisplayItem.Group(it.displayName, it) }) + items.addAll(params.map { DisplayItem.Param(it.description ?: it.name, it) }) + + return DisplayModel(items) +} diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt new file mode 100644 index 0000000..d088ef6 --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt @@ -0,0 +1,148 @@ +package com.polidea.cockpit.paramsedition.refactor + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.annotation.LayoutRes +import androidx.recyclerview.widget.RecyclerView +import com.polidea.cockpit.R +import com.polidea.cockpit.core.CockpitParam +import com.polidea.cockpit.core.type.* +import com.polidea.cockpit.paramsedition.ParamType +import com.polidea.cockpit.paramsedition.ParamsEditionContract +import com.polidea.cockpit.paramsedition.viewholder.* + +internal class ParamAdapter(private var displayModel: DisplayModel, + private val presenter: ParamsEditionContract.Presenter) : RecyclerView.Adapter(), ParamsEditionContract.ParamView { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return when (viewType) { + ParamType.BOOL.ordinal -> BooleanParamViewHolder(inflateViewForHolder(R.layout.cockpit_boolean_param, parent)).configure() + ParamType.INT.ordinal -> IntParamViewHolder(inflateViewForHolder(R.layout.cockpit_number_param, parent)).configure() + ParamType.DOUBLE.ordinal -> DoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_number_param, parent)).configure() + ParamType.STRING.ordinal -> StringParamViewHolder(inflateViewForHolder(R.layout.cockpit_string_param, parent)).configure() + ParamType.LIST.ordinal -> ListParamViewHolder(inflateViewForHolder(R.layout.cockpit_list_param, parent)).configure() + ParamType.ACTION.ordinal -> ActionParamViewHolder(inflateViewForHolder(R.layout.cockpit_action_param, parent)).configure() + ParamType.COLOR.ordinal -> ColorParamViewHolder(inflateViewForHolder(R.layout.cockpit_color_param, parent)).configure() + ParamType.RANGE_INT.ordinal -> RangeIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_range_param, parent)).configure() + ParamType.RANGE_DOUBLE.ordinal -> RangeDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_range_param, parent)).configure() + ParamType.READ_ONLY.ordinal -> ReadOnlyParamViewHolder(inflateViewForHolder(R.layout.cockpit_read_only_param, parent)).configure() + ParamType.STEP_INT.ordinal -> StepIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() + ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() + GROUP_TYPE_ID -> GroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)).configure() + else -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) + } + } + + private fun inflateViewForHolder(@LayoutRes layoutId: Int, parent: ViewGroup) = LayoutInflater.from(parent.context) + .inflate(layoutId, parent, false) + + override fun getItemCount(): Int = displayModel.items.size + + override fun getItemViewType(position: Int): Int { + val displayedItem = displayModel.items[position] + return when (displayedItem) { + is DisplayItem.Param -> ParamType.getParamType(displayedItem.param).ordinal + is DisplayItem.Group -> GROUP_TYPE_ID + is DisplayItem.Section -> SECTION_TYPE_ID + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val displayedItem = displayModel.items[position] + when (displayedItem) { + is DisplayItem.Param -> { + when (ParamType.getParamType(displayedItem.param)) { + ParamType.BOOL -> (holder as BooleanParamViewHolder).displayParam(displayedItem.param as CockpitParam) + ParamType.INT -> (holder as IntParamViewHolder).displayParam(displayedItem.param as CockpitParam) + ParamType.DOUBLE -> (holder as DoubleParamViewHolder).displayParam(displayedItem.param as CockpitParam) + ParamType.STRING -> (holder as StringParamViewHolder).displayParam(displayedItem.param as CockpitParam) + ParamType.LIST -> (holder as ListParamViewHolder).displayParam(displayedItem.param as CockpitParam>) + ParamType.ACTION -> (holder as ActionParamViewHolder).displayParam(displayedItem.param as CockpitParam) + ParamType.COLOR -> (holder as ColorParamViewHolder).apply { + displayParam(displayedItem.param as CockpitParam) + onColorEditionRequestListener = { presenter.editColor(displayedItem.param.name) } + } + ParamType.RANGE_INT -> (holder as RangeIntParamViewHolder).displayParam(displayedItem.param as CockpitParam>) + ParamType.RANGE_DOUBLE -> (holder as RangeDoubleParamViewHolder).displayParam(displayedItem.param as CockpitParam>) + ParamType.READ_ONLY -> (holder as ReadOnlyParamViewHolder).displayParam(displayedItem.param as CockpitParam) + ParamType.STEP_INT -> (holder as StepIntParamViewHolder).displayParam(displayedItem.param as CockpitParam>) + ParamType.STEP_DOUBLE -> (holder as StepDoubleParamViewHolder).displayParam(displayedItem.param as CockpitParam>) + } + ParamType.getParamType(displayedItem.param).ordinal + } + is DisplayItem.Group -> (holder as GroupViewHolder).display(displayedItem.displayName) + is DisplayItem.Section -> (holder as SectionViewHolder).display(displayedItem.displayName) + } + } + + override fun display(model: DisplayModel) { + displayModel = model + notifyDataSetChanged() + } + + override fun reloadParam(paramName: String) { + val index = displayModel.items.indexOfFirst { it is DisplayItem.Param && it.param.name == paramName } + notifyItemChanged(index) + } + + override fun reloadAll() { + notifyDataSetChanged() + } + + private fun ParamBaseValueWithRestoreViewHolder.configure(): ParamBaseValueWithRestoreViewHolder { + (this as ParamBaseValueViewHolder).configure() + restoreClickListener = { + val item = displayModel.items[adapterPosition] + if (item is DisplayItem.Param) { + presenter.restore(item.param.name) + } + } + return this + } + + private fun ParamBaseValueViewHolder.configure(): ParamBaseValueViewHolder { + valueChangeListener = { + val item = displayModel.items[adapterPosition] + if (item is DisplayItem.Param) { + presenter.onParamChange(item.param.name, it) + } + } + return this + } + + private fun ActionParamViewHolder.configure(): ActionParamViewHolder { + actionButtonClickListener = { + val item = displayModel.items[adapterPosition] + if (item is DisplayItem.Param) { + presenter.requestAction(item.param.name) + } + } + return this + } + + private fun SelectionParamBaseViewHolder.configure(): SelectionParamBaseViewHolder { + valueSelectedListener = { + val item = displayModel.items[adapterPosition] + if (item is DisplayItem.Param) { + presenter.onParamValueSelected(item.param.name, it) + } + } + return this + } + + private fun GroupViewHolder.configure(): GroupViewHolder { + onGroupClickedListener = { + val item = displayModel.items[adapterPosition] + if (item is DisplayItem.Group) { + presenter.onDisplayGroup(item.group) + } + } + + return this + } + + companion object { + private val SECTION_TYPE_ID: Int = ParamType.values().last().ordinal + 1 + private val GROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 2 + } +} \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt index 08983c5..229a971 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/GroupViewHolder.kt @@ -8,10 +8,14 @@ import com.polidea.cockpit.R internal class GroupViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + var onGroupClickedListener: () -> Unit = {} private val name: TextView = view.findViewById(R.id.subgroup_name) + init { + view.setOnClickListener { onGroupClickedListener() } + } + fun display(groupName: String?) { name.text = groupName ?: view.context.getString(R.string.default_group_name) - view.setOnClickListener { Toast.makeText(view.context, groupName, Toast.LENGTH_SHORT).show() } } } \ No newline at end of file diff --git a/cockpit/src/main/res/layout/subgroup.xml b/cockpit/src/main/res/layout/subgroup.xml index eafae34..8143a66 100644 --- a/cockpit/src/main/res/layout/subgroup.xml +++ b/cockpit/src/main/res/layout/subgroup.xml @@ -1,21 +1,30 @@ - + + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintTop_toTopOf="parent"/> diff --git a/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt b/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt deleted file mode 100644 index 0c3c18c..0000000 --- a/cockpit/src/test/java/com/polidea/cockpit/paramsedition/ParamsEditionPositionMapperTest.kt +++ /dev/null @@ -1,221 +0,0 @@ -package com.polidea.cockpit.paramsedition - -import android.content.Context -import com.polidea.cockpit.core.CockpitParam -import com.polidea.cockpit.manager.CockpitManager -import com.polidea.cockpit.persistency.CockpitYamlFileManager -import com.polidea.cockpit.utils.FileUtils -import io.mockk.every -import io.mockk.mockk -import io.mockk.spyk -import org.junit.Before -import org.junit.Test -import java.io.File -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -class ParamsEditionPositionMapperTest { - - private val context: Context = mockk(relaxed = true) - private val cockpitYamlFileManager: CockpitYamlFileManager = spyk(CockpitYamlFileManager(DIRECTORY_PATH, context.assets)) - - init { - File(DIRECTORY_PATH).mkdirs() - FileUtils.init(DIRECTORY_PATH, context.assets) - } - - @Before - fun setUp() { - every { context.assets } returns mockk(relaxed = true) - FileUtils.setCockpitYamlFileManager(cockpitYamlFileManager) - - every { cockpitYamlFileManager.readInputParams() } returns getTestCockpitParams() - every { cockpitYamlFileManager.readSavedParams() } returns emptyList() - } - - @Test - fun toItemPositionAGroup() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(0) - assertTrue(itemPosition.isSectionPosition()) - assertEquals(0, itemPosition.groupIndex) - - CockpitManager.clear() - } - - @Test - fun toItemPositionDoubleParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(1) - assertFalse(itemPosition.isSectionPosition()) - assertEquals(0, itemPosition.groupIndex) - assertEquals(0, itemPosition.paramIndex) - - CockpitManager.clear() - } - - @Test - fun toItemPositionBooleanParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(2) - assertFalse(itemPosition.isSectionPosition()) - assertEquals(0, itemPosition.groupIndex) - assertEquals(1, itemPosition.paramIndex) - - CockpitManager.clear() - } - - @Test - fun toItemPositionDefaultGroup() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(3) - assertTrue(itemPosition.isSectionPosition()) - assertEquals(1, itemPosition.groupIndex) - } - - @Test - fun toItemPositionStringParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(4) - assertFalse(itemPosition.isSectionPosition()) - assertEquals(1, itemPosition.groupIndex) - assertEquals(0, itemPosition.paramIndex) - - CockpitManager.clear() - } - - @Test - fun toItemPositionBGroup() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(5) - assertTrue(itemPosition.isSectionPosition()) - assertEquals(2, itemPosition.groupIndex) - - CockpitManager.clear() - } - - @Test - fun toItemPositionIntParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val itemPosition = mapper.toItemPosition(6) - assertFalse(itemPosition.isSectionPosition()) - assertEquals(2, itemPosition.groupIndex) - assertEquals(0, itemPosition.paramIndex) - - CockpitManager.clear() - } - - @Test - fun toAdapterPositionAGroup() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(0)) - assertEquals(0, adapterPosition) - - CockpitManager.clear() - } - - @Test - fun toAdapterPositionDoubleParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(0, 0)) - assertEquals(1, adapterPosition) - - CockpitManager.clear() - } - - @Test - fun toAdapterPositionBooleanParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(0, 1)) - assertEquals(2, adapterPosition) - - CockpitManager.clear() - } - - @Test - fun toAdapterPositionDefaultGroup() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(1)) - assertEquals(3, adapterPosition) - - CockpitManager.clear() - } - - @Test - fun toAdapterPositionStringParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(1, 0)) - assertEquals(4, adapterPosition) - - CockpitManager.clear() - } - - @Test - fun toAdapterPositionBGroup() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(2)) - assertEquals(5, adapterPosition) - - CockpitManager.clear() - } - - - @Test - fun toAdapterPositionIntParam() { - addParamsToCockpit(getTestCockpitParams()) - val mapper = createMapper() - - val adapterPosition = mapper.toAdapterPosition(ItemPosition(2, 0)) - assertEquals(6, adapterPosition) - - CockpitManager.clear() - } - - private fun createMapper() = ParamsEditionPositionMapper(ParamsEditionModel()) - - private fun addParamsToCockpit(params: List>) { - params.forEach { CockpitManager.addParam(it) } - } - - private fun getTestCockpitParams(): List> { - val testParams: MutableList> = mutableListOf() - - testParams.add(CockpitParam("doubleParam", 3.0, null, "a")) - testParams.add(CockpitParam("booleanParam", false, null, "a")) - testParams.add(CockpitParam("stringParam", "testValue")) - testParams.add(CockpitParam("integerParam", 2, null, "b")) - - return testParams - } - - companion object { - private const val DIRECTORY_PATH = "data" - } -} \ No newline at end of file From 419e8c36a5e39b44286d3e02b9306ea7dcc4af83 Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Wed, 3 Apr 2019 19:05:47 +0200 Subject: [PATCH 13/28] Fixed creation of duplicate groups --- .../extensions/CockpitParamGroupExt.kt | 31 +++++++++---------- .../cockpit/paramsedition/CockpitDialog.kt | 5 +-- .../paramsedition/CockpitDialogPresenter.kt | 12 ++++--- sample/cockpit/cockpit.yml | 10 ++++++ 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt b/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt index eb96039..aa52eb0 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/extensions/CockpitParamGroupExt.kt @@ -5,27 +5,23 @@ import com.polidea.cockpit.core.CockpitParamGroup import com.polidea.cockpit.core.GROUP_DELIMITER import com.polidea.cockpit.core.MutableCockpitParamGroup -internal fun Map.getDisplaySize(): Int { - return this.values.fold(0) { acc, group -> - acc + if (!group.isChild()) 1 + group.displaySize else 0 - } -} - internal fun Map>>.convertToGroups(): Map { - val extractedSubgroups = LinkedHashMap() - + val extractedSubgroups = mutableMapOf() forEach { val group = extractedSubgroups.getOrCreateGroupHierarchy(it.key) group.params.addAll(it.value) extractedSubgroups[it.key] = group } - return extractedSubgroups.toReducedNonMutable() } private fun MutableMap.getOrCreateGroupHierarchy(name: String?): MutableCockpitParamGroup { val group = this[name] ?: MutableCockpitParamGroup(name) - if (!this.containsKey(name)) this[name] = group + if (!this.containsKey(name)) { + this[name] = group + } else { + return group + } if (name?.contains(GROUP_DELIMITER) == true) { val nextName = name.substring(0, name.lastIndexOf(GROUP_DELIMITER)) @@ -37,17 +33,20 @@ private fun MutableMap.getOrCreateGroupHierar } private fun MutableMap.toReducedNonMutable(): Map { - val mapOfNonMutables = LinkedHashMap() + val mapOfNonMutables = mutableMapOf() topLevelGroups().forEach { mapOfNonMutables[it.key] = it.value.toReadOnly() - mapOfNonMutables[it.key]?.subgroups?.forEach { subgroup -> - mapOfNonMutables[subgroup.name] = subgroup - } + mapOfNonMutables.storeSubgroupsRefs(mapOfNonMutables[it.key]!!) } - assert(this.size == mapOfNonMutables.size) - return mapOfNonMutables } +private fun MutableMap.storeSubgroupsRefs(subgroup: CockpitParamGroup) { + subgroup.subgroups.forEach { + this[it.name] = it + storeSubgroupsRefs(it) + } +} + internal fun Map.topLevelGroups(): Map = filter { it.key?.contains(GROUP_DELIMITER) != true } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt index 0759276..8e50256 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt @@ -95,7 +95,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), if (ev.action == MotionEvent.ACTION_DOWN) { cockpitRoot.startDrag = true true - } + } else false } @@ -104,7 +104,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), if (motionEvent.action == MotionEvent.ACTION_MOVE) { presenter.requestResize(bottomButton.y.toInt() + motionEvent.y.toInt()) true - } + } else false } @@ -117,6 +117,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), override fun onDestroy() { super.onDestroy() + //TODO remove all callbacks from action type params presenter.stop() } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt index e2de3f6..e971961 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt @@ -19,7 +19,11 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi private val displayStack: Stack = Stack() override fun start() { - displayStack.push(model.topLevelGroups.toDisplayModel()) + displayModel(model.topLevelGroups.toDisplayModel()) + } + + private fun displayModel(displayModel: DisplayModel) { + displayStack.push(displayModel) view.display(displayStack.peek()) } @@ -34,12 +38,12 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi override fun restoreAll() { model.restoreAll() - view.reloadAll() + displayStack.clear() + displayModel(model.topLevelGroups.toDisplayModel()) } override fun onDisplayGroup(group: CockpitParamGroup) { - displayStack.push(group.toDisplayModel()) - view.display(displayStack.peek()) + displayModel(group.toDisplayModel()) } override fun onParamChange(paramName: String, newValue: T) { diff --git a/sample/cockpit/cockpit.yml b/sample/cockpit/cockpit.yml index 2a0ba0f..e1b88ad 100644 --- a/sample/cockpit/cockpit.yml +++ b/sample/cockpit/cockpit.yml @@ -45,6 +45,16 @@ exampleSubGroupParam: value: 500 group: "Footer/subgroup" +nestingTest: + description: "Whatever really" + value: 500 + group: "Footer/subgroup/manamana" + +nestingTest2: + description: "Whatever really" + value: 500 + group: "Footer/subgroup/manamana/123" + appVersion: type: read_only description: "Version" \ No newline at end of file From b2f6b1550eec746734b1943b8999e8b7a538728d Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Thu, 4 Apr 2019 13:30:27 +0200 Subject: [PATCH 14/28] Review changes --- .../paramsedition/{refactor => }/AdapterModel.kt | 10 ++-------- .../polidea/cockpit/paramsedition/CockpitDialog.kt | 6 ++---- .../cockpit/paramsedition/CockpitDialogPresenter.kt | 4 +--- .../ParamAdapter.kt => ParamsEditionAdapter.kt} | 12 ++++++------ .../cockpit/paramsedition/ParamsEditionContract.kt | 1 - 5 files changed, 11 insertions(+), 22 deletions(-) rename cockpit/src/main/java/com/polidea/cockpit/paramsedition/{refactor => }/AdapterModel.kt (72%) rename cockpit/src/main/java/com/polidea/cockpit/paramsedition/{refactor/ParamAdapter.kt => ParamsEditionAdapter.kt} (93%) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt similarity index 72% rename from cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt rename to cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt index f675aec..e6ecb16 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/AdapterModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt @@ -1,4 +1,4 @@ -package com.polidea.cockpit.paramsedition.refactor +package com.polidea.cockpit.paramsedition import com.polidea.cockpit.core.CockpitParam import com.polidea.cockpit.core.CockpitParamGroup @@ -9,8 +9,6 @@ internal sealed class DisplayItem(val displayName: String?) { class Section(displayName: String?) : DisplayItem(displayName) class Group(displayName: String?, val group: CockpitParamGroup) : DisplayItem(displayName) class Param(displayName: String?, val param: CockpitParam) : DisplayItem(displayName) -// class TopNavigation : DisplayItem(null) -// class BackNavigation : DisplayItem(null) } internal fun Map.toDisplayModel(): DisplayModel { @@ -22,12 +20,8 @@ internal fun Map.toDisplayModel(): DisplayModel { return DisplayModel(items) } -internal fun CockpitParamGroup.toDisplayModel(addTopNavigation: Boolean = false): DisplayModel { +internal fun CockpitParamGroup.toDisplayModel(): DisplayModel { val items = mutableListOf(DisplayItem.Section(displayName)) -// if (addTopNavigation) { -// items.add(DisplayItem.TopNavigation()) -// items.add(DisplayItem.BackNavigation()) -// } items.addAll(subgroups.map { DisplayItem.Group(it.displayName, it) }) items.addAll(params.map { DisplayItem.Param(it.description ?: it.name, it) }) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt index 8e50256..f5ea66b 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt @@ -15,13 +15,11 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import com.polidea.cockpit.R import com.polidea.cockpit.extensions.removeDimmedBackground import com.polidea.cockpit.paramsedition.layout.CockpitLayout -import com.polidea.cockpit.paramsedition.refactor.DisplayModel -import com.polidea.cockpit.paramsedition.refactor.ParamAdapter internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), ParamsEditionContract.View { override lateinit var presenter: ParamsEditionContract.Presenter - private lateinit var paramsEditionAdapter: ParamAdapter + private lateinit var paramsEditionAdapter: ParamsEditionAdapter private lateinit var expandCollapse: ImageButton private lateinit var cockpitRoot: CockpitLayout private lateinit var cockpitContent: LinearLayout @@ -77,7 +75,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), @SuppressLint("ClickableViewAccessibility") private fun setupViews(view: View) { - paramsEditionAdapter = ParamAdapter(DisplayModel(listOf()), presenter) + paramsEditionAdapter = ParamsEditionAdapter(DisplayModel(listOf()), presenter) view.findViewById(R.id.params_list).adapter = paramsEditionAdapter view.findViewById(R.id.restore_defaults).setOnClickListener { presenter.restoreAll() } expandCollapse = view.findViewById(R.id.expand_collapse) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt index e971961..f8bf400 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt @@ -3,10 +3,8 @@ package com.polidea.cockpit.paramsedition import android.graphics.Color import com.polidea.cockpit.core.CockpitParamGroup import com.polidea.cockpit.core.type.CockpitColor -import com.polidea.cockpit.paramsedition.refactor.DisplayModel -import com.polidea.cockpit.paramsedition.refactor.toDisplayModel import com.polidea.cockpit.utils.colorToArgbHexString -import java.util.* +import java.util.Stack internal class CockpitDialogPresenter(private val view: ParamsEditionContract.View) : ParamsEditionContract.Presenter { diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt similarity index 93% rename from cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt rename to cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt index d088ef6..f89a41f 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/refactor/ParamAdapter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt @@ -1,4 +1,4 @@ -package com.polidea.cockpit.paramsedition.refactor +package com.polidea.cockpit.paramsedition import android.view.LayoutInflater import android.view.ViewGroup @@ -7,12 +7,11 @@ import androidx.recyclerview.widget.RecyclerView import com.polidea.cockpit.R import com.polidea.cockpit.core.CockpitParam import com.polidea.cockpit.core.type.* -import com.polidea.cockpit.paramsedition.ParamType -import com.polidea.cockpit.paramsedition.ParamsEditionContract import com.polidea.cockpit.paramsedition.viewholder.* +import java.lang.IllegalArgumentException -internal class ParamAdapter(private var displayModel: DisplayModel, - private val presenter: ParamsEditionContract.Presenter) : RecyclerView.Adapter(), ParamsEditionContract.ParamView { +internal class ParamsEditionAdapter(private var displayModel: DisplayModel, + private val presenter: ParamsEditionContract.Presenter) : RecyclerView.Adapter(), ParamsEditionContract.ParamView { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { @@ -29,7 +28,8 @@ internal class ParamAdapter(private var displayModel: DisplayModel, ParamType.STEP_INT.ordinal -> StepIntParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() GROUP_TYPE_ID -> GroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)).configure() - else -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) + SECTION_TYPE_ID -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) + else -> throw IllegalArgumentException("View type $viewType does not match any known case") } } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt index 389a947..811b296 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt @@ -3,7 +3,6 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.BasePresenter import com.polidea.cockpit.BaseView import com.polidea.cockpit.core.CockpitParamGroup -import com.polidea.cockpit.paramsedition.refactor.DisplayModel internal interface ParamsEditionContract { From c574869d4e71fe346bd4217de0551e84ec499aba Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Thu, 4 Apr 2019 18:09:34 +0200 Subject: [PATCH 15/28] Top and back navigation --- .../cockpit/paramsedition/AdapterModel.kt | 18 +++++-- .../cockpit/paramsedition/CockpitDialog.kt | 25 +++++++++ .../paramsedition/CockpitDialogPresenter.kt | 51 +++++++++++++++++-- .../cockpit/paramsedition/NavigationState.kt | 11 ++++ .../paramsedition/ParamsEditionAdapter.kt | 11 ++++ .../paramsedition/ParamsEditionContract.kt | 10 ++++ .../paramsedition/ParamsEditionModel.kt | 3 ++ .../cockpit/paramsedition/ParamsModel.kt | 2 + .../viewholder/PathViewHolder.kt | 12 +++++ .../main/res/drawable/arrow_back_black.xml | 9 ++++ cockpit/src/main/res/drawable/home_black.xml | 9 ++++ .../main/res/layout/dialog_params_edition.xml | 23 ++++++++- cockpit/src/main/res/layout/path_button.xml | 7 +++ 13 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt create mode 100644 cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt create mode 100644 cockpit/src/main/res/drawable/arrow_back_black.xml create mode 100644 cockpit/src/main/res/drawable/home_black.xml create mode 100644 cockpit/src/main/res/layout/path_button.xml diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt index e6ecb16..5f85ba8 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt @@ -3,27 +3,37 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.core.CockpitParam import com.polidea.cockpit.core.CockpitParamGroup -internal class DisplayModel(val items: List) +internal class DisplayModel(val items: List, val breadcrumb: Breadcrumb = Breadcrumb(), val label: String? = null) + +internal class Breadcrumb(val crumbs: List = listOf()) { + constructor(crumb: String, previousCrumb: Breadcrumb) : this(previousCrumb.crumbs.toMutableList().apply { add(crumb) }) +} internal sealed class DisplayItem(val displayName: String?) { class Section(displayName: String?) : DisplayItem(displayName) class Group(displayName: String?, val group: CockpitParamGroup) : DisplayItem(displayName) class Param(displayName: String?, val param: CockpitParam) : DisplayItem(displayName) + class Path(val breadcrumb: Breadcrumb) : DisplayItem(null) } internal fun Map.toDisplayModel(): DisplayModel { val items = mutableListOf() forEach { - items.addAll(it.value.toDisplayModel().items) + items.addAll(it.value.toDisplayModel(Breadcrumb()).items) } return DisplayModel(items) } -internal fun CockpitParamGroup.toDisplayModel(): DisplayModel { +internal fun CockpitParamGroup.toDisplayModel(breadcrumb: Breadcrumb, addPath: Boolean = false): DisplayModel { + val newBreadcrumb = Breadcrumb(name ?: "", breadcrumb) + val items = mutableListOf(DisplayItem.Section(displayName)) + + if (addPath) items.add(DisplayItem.Path(newBreadcrumb)) + items.addAll(subgroups.map { DisplayItem.Group(it.displayName, it) }) items.addAll(params.map { DisplayItem.Param(it.description ?: it.name, it) }) - return DisplayModel(items) + return DisplayModel(items, newBreadcrumb, displayName) } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt index f5ea66b..f13704c 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt @@ -8,6 +8,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageButton import android.widget.LinearLayout +import android.widget.TextView import androidx.appcompat.app.AppCompatDialogFragment import androidx.recyclerview.widget.RecyclerView import com.jaredrummler.android.colorpicker.ColorPickerDialog @@ -21,6 +22,9 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), override lateinit var presenter: ParamsEditionContract.Presenter private lateinit var paramsEditionAdapter: ParamsEditionAdapter private lateinit var expandCollapse: ImageButton + private lateinit var navigateBack: ImageButton + private lateinit var navigateTop: ImageButton + private lateinit var label: TextView private lateinit var cockpitRoot: CockpitLayout private lateinit var cockpitContent: LinearLayout private lateinit var actionBar: LinearLayout @@ -88,6 +92,14 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), } } + navigateBack = view.findViewById(R.id.go_back) + navigateBack.setOnClickListener { presenter.onNavigateBack() } + + navigateTop = view.findViewById(R.id.go_top) + navigateTop.setOnClickListener { presenter.onNavigateToTop() } + + label = view.findViewById(R.id.label) + actionBar = view.findViewById(R.id.action_bar) actionBar.setOnTouchListener { _, ev -> if (ev.action == MotionEvent.ACTION_DOWN) { @@ -128,9 +140,22 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), } override fun display(model: DisplayModel) { + if (model.breadcrumb.crumbs.isNotEmpty()) { + if (model.label != null) label.text = model.label + navigateTop.visibility = View.VISIBLE + navigateBack.visibility = View.VISIBLE + } else { + label.setText(R.string.title) + navigateBack.visibility = View.INVISIBLE + navigateTop.visibility = View.GONE + } paramsEditionAdapter.display(model) } + override fun displayNavigationDialog(options: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + override fun expand() { animateExpandCollapseIcon(true) cockpitRoot.expand() diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt index f8bf400..ef770d1 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt @@ -17,12 +17,27 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi private val displayStack: Stack = Stack() override fun start() { - displayModel(model.topLevelGroups.toDisplayModel()) + restoreDisplayState() } - private fun displayModel(displayModel: DisplayModel) { + private fun restoreDisplayState() { + displayStack.push(model.topLevelGroups.toDisplayModel()) + NavigationState.getHierarchy().forEach { + val nextDisplayModel = model.getGroup(it).toDisplayModel(displayStack.peek().breadcrumb, true) + displayStack.push(nextDisplayModel) + } + displayCurrentModel() + } + + private fun displayNewModel(displayModel: DisplayModel) { displayStack.push(displayModel) - view.display(displayStack.peek()) + displayCurrentModel() + } + + private fun displayCurrentModel() { + val model = displayStack.peek() + view.display(model) + NavigationState.saveHierarchy(model.breadcrumb.crumbs) } override fun stop() { @@ -36,12 +51,38 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi override fun restoreAll() { model.restoreAll() + restoreDisplayState() + } + + override fun onPathClicked() { + view.displayNavigationDialog(listOf()) //TODO + } + + override fun onNavigateBack() { + displayStack.pop() + displayCurrentModel() + } + + override fun onNavigateToTop() { displayStack.clear() - displayModel(model.topLevelGroups.toDisplayModel()) + displayNewModel(model.topLevelGroups.toDisplayModel()) + } + + override fun onNavigateToCrumb(crumb: String) { + val index = NavigationState.getHierarchy().lastIndexOf(crumb) + val toPop = NavigationState.getHierarchy().lastIndex - index + + if (index > 0 && toPop > 0) { + for (i in 0..toPop) { + displayStack.pop() + } + + displayCurrentModel() + } } override fun onDisplayGroup(group: CockpitParamGroup) { - displayModel(group.toDisplayModel()) + displayNewModel(group.toDisplayModel(displayStack.peek().breadcrumb, true)) } override fun onParamChange(paramName: String, newValue: T) { diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt new file mode 100644 index 0000000..87bd87b --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt @@ -0,0 +1,11 @@ +package com.polidea.cockpit.paramsedition + +object NavigationState { + private var navHierarchy: List = listOf() + + fun saveHierarchy(hierarchy: List) { + navHierarchy = hierarchy + } + + fun getHierarchy(): List = navHierarchy +} \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt index f89a41f..6ed599d 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt @@ -29,6 +29,7 @@ internal class ParamsEditionAdapter(private var displayModel: DisplayModel, ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() GROUP_TYPE_ID -> GroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)).configure() SECTION_TYPE_ID -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) + PATH_TYPE_ID -> PathViewHolder(inflateViewForHolder(R.layout.path_button, parent)).configure() //TODO fix layout else -> throw IllegalArgumentException("View type $viewType does not match any known case") } } @@ -44,6 +45,7 @@ internal class ParamsEditionAdapter(private var displayModel: DisplayModel, is DisplayItem.Param -> ParamType.getParamType(displayedItem.param).ordinal is DisplayItem.Group -> GROUP_TYPE_ID is DisplayItem.Section -> SECTION_TYPE_ID + is DisplayItem.Path -> PATH_TYPE_ID } } @@ -141,8 +143,17 @@ internal class ParamsEditionAdapter(private var displayModel: DisplayModel, return this } + private fun PathViewHolder.configure(): PathViewHolder { + onPathClickedListener = { + presenter.onPathClicked() + } + + return this + } + companion object { private val SECTION_TYPE_ID: Int = ParamType.values().last().ordinal + 1 private val GROUP_TYPE_ID: Int = ParamType.values().last().ordinal + 2 + private val PATH_TYPE_ID: Int = ParamType.values().last().ordinal + 3 } } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt index 811b296..cdf3d7a 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt @@ -16,6 +16,8 @@ internal interface ParamsEditionContract { fun dismiss() fun showColorPicker(paramName: String, color: Int) + + fun displayNavigationDialog(options: List) } interface ParamView { @@ -32,6 +34,14 @@ internal interface ParamsEditionContract { fun onParamValueSelected(paramName: String, selectedItemIndex: Int) + fun onPathClicked() + + fun onNavigateBack() + + fun onNavigateToTop() + + fun onNavigateToCrumb(crumb: String) + fun onDisplayGroup(group: CockpitParamGroup) fun requestAction(paramName: String) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt index 570d302..4fdb7f4 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionModel.kt @@ -20,6 +20,9 @@ internal class ParamsEditionModel : ParamsModel { override fun getParam(paramName: String): CockpitParam = paramsCopy[paramName] as CockpitParam? ?: throw IllegalArgumentException("Cannot find param for name $paramName") + override fun getGroup(groupName: String?): CockpitParamGroup + = groupedParamsCopy[groupName] ?: throw java.lang.IllegalArgumentException("Cannot find group for name $groupName") + override fun setValue(paramName: String, newValue: T) { getParam(paramName).value = newValue CockpitManager.setParamValue(paramName, newValue) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt index 77b1e76..8aa0fba 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsModel.kt @@ -9,6 +9,8 @@ internal interface ParamsModel { fun getParam(paramName: String): CockpitParam + fun getGroup(groupName: String?): CockpitParamGroup + fun setValue(paramName: String, newValue: T) fun selectValue(paramName: String, selectedItemIndex: Int) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt new file mode 100644 index 0000000..7de8358 --- /dev/null +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt @@ -0,0 +1,12 @@ +package com.polidea.cockpit.paramsedition.viewholder + +import android.view.View +import androidx.recyclerview.widget.RecyclerView + +internal class PathViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + var onPathClickedListener: () -> Unit = {} + + init { + view.setOnClickListener { onPathClickedListener() } + } +} \ No newline at end of file diff --git a/cockpit/src/main/res/drawable/arrow_back_black.xml b/cockpit/src/main/res/drawable/arrow_back_black.xml new file mode 100644 index 0000000..beafea3 --- /dev/null +++ b/cockpit/src/main/res/drawable/arrow_back_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/cockpit/src/main/res/drawable/home_black.xml b/cockpit/src/main/res/drawable/home_black.xml new file mode 100644 index 0000000..70fb291 --- /dev/null +++ b/cockpit/src/main/res/drawable/home_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/cockpit/src/main/res/layout/dialog_params_edition.xml b/cockpit/src/main/res/layout/dialog_params_edition.xml index a08cb36..3f12abf 100644 --- a/cockpit/src/main/res/layout/dialog_params_edition.xml +++ b/cockpit/src/main/res/layout/dialog_params_edition.xml @@ -27,22 +27,32 @@ android:orientation="horizontal"> + android:src="@drawable/arrow_back_black" /> + + + + + + + \ No newline at end of file From 277960c7f45419f022e677f76f88123b8247f7d7 Mon Sep 17 00:00:00 2001 From: Mikolaj Kojdecki Date: Fri, 5 Apr 2019 16:20:00 +0200 Subject: [PATCH 16/28] Add navigation tree traversal --- .../cockpit/paramsedition/CockpitDialog.kt | 28 +++++++++++++----- .../paramsedition/CockpitDialogPresenter.kt | 29 ++++++++++--------- .../cockpit/paramsedition/NavigationState.kt | 10 ++----- .../paramsedition/ParamsEditionAdapter.kt | 2 +- .../paramsedition/ParamsEditionContract.kt | 4 +-- .../{AdapterModel.kt => ViewModels.kt} | 24 +++++++++------ .../viewholder/PathViewHolder.kt | 6 +++- cockpit/src/main/res/layout/path_button.xml | 13 ++++++++- cockpit/src/main/res/values/strings.xml | 1 + 9 files changed, 75 insertions(+), 42 deletions(-) rename cockpit/src/main/java/com/polidea/cockpit/paramsedition/{AdapterModel.kt => ViewModels.kt} (51%) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt index f13704c..37b49f2 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialog.kt @@ -9,6 +9,7 @@ import android.view.ViewGroup import android.widget.ImageButton import android.widget.LinearLayout import android.widget.TextView +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDialogFragment import androidx.recyclerview.widget.RecyclerView import com.jaredrummler.android.colorpicker.ColorPickerDialog @@ -20,6 +21,7 @@ import com.polidea.cockpit.paramsedition.layout.CockpitLayout internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), ParamsEditionContract.View { override lateinit var presenter: ParamsEditionContract.Presenter + private var alertDialog: AlertDialog? = null private lateinit var paramsEditionAdapter: ParamsEditionAdapter private lateinit var expandCollapse: ImageButton private lateinit var navigateBack: ImageButton @@ -86,8 +88,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), expandCollapse.setOnClickListener { if (expanded) { presenter.collapse() - } - else { + } else { presenter.expand() } } @@ -106,7 +107,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), cockpitRoot.startDrag = true true } else - false + false } bottomButton = view.findViewById(R.id.resize_handle) @@ -115,7 +116,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), presenter.requestResize(bottomButton.y.toInt() + motionEvent.y.toInt()) true } else - false + false } bottomButton.visibility = View.GONE @@ -125,6 +126,14 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), cockpitRoot.setDraggableView(R.id.cockpit_content) } + override fun onPause() { + super.onPause() + alertDialog?.let { + it.dismiss() + alertDialog = null + } + } + override fun onDestroy() { super.onDestroy() //TODO remove all callbacks from action type params @@ -140,7 +149,7 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), } override fun display(model: DisplayModel) { - if (model.breadcrumb.crumbs.isNotEmpty()) { + if (model.breadcrumb.descendants.isNotEmpty()) { if (model.label != null) label.text = model.label navigateTop.visibility = View.VISIBLE navigateBack.visibility = View.VISIBLE @@ -152,8 +161,13 @@ internal class CockpitDialog internal constructor() : AppCompatDialogFragment(), paramsEditionAdapter.display(model) } - override fun displayNavigationDialog(options: List) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + override fun displayNavigationDialog(options: List) { + val items = options.map { it.displayName }.toTypedArray() + alertDialog = AlertDialog.Builder(context!!) + .setTitle("Navigate to:") + .setItems(items) { _, which: Int -> + presenter.onNavigationChosen(options[which]) + }.create().apply { show() } } override fun expand() { diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt index ef770d1..624528b 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/CockpitDialogPresenter.kt @@ -22,8 +22,8 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi private fun restoreDisplayState() { displayStack.push(model.topLevelGroups.toDisplayModel()) - NavigationState.getHierarchy().forEach { - val nextDisplayModel = model.getGroup(it).toDisplayModel(displayStack.peek().breadcrumb, true) + NavigationState.breadcrumb.descendants.forEach { + val nextDisplayModel = model.getGroup(it.groupName).toDisplayModel(displayStack.peek().breadcrumb, true) displayStack.push(nextDisplayModel) } displayCurrentModel() @@ -37,7 +37,7 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi private fun displayCurrentModel() { val model = displayStack.peek() view.display(model) - NavigationState.saveHierarchy(model.breadcrumb.crumbs) + NavigationState.breadcrumb = displayStack.peek().breadcrumb } override fun stop() { @@ -55,7 +55,13 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi } override fun onPathClicked() { - view.displayNavigationDialog(listOf()) //TODO + val breadcrumb = NavigationState.breadcrumb + view.displayNavigationDialog( + listOf( + NavigationOption("Cockpit Home", breadcrumb.groupName), + *breadcrumb.descendants.map { NavigationOption(it.displayName ?: "", it.groupName) }.toTypedArray() + ) + ) } override fun onNavigateBack() { @@ -68,17 +74,14 @@ internal class CockpitDialogPresenter(private val view: ParamsEditionContract.Vi displayNewModel(model.topLevelGroups.toDisplayModel()) } - override fun onNavigateToCrumb(crumb: String) { - val index = NavigationState.getHierarchy().lastIndexOf(crumb) - val toPop = NavigationState.getHierarchy().lastIndex - index + override fun onNavigationChosen(navigationOption: NavigationOption) { + if (navigationOption.groupName == displayStack.peek().breadcrumb.lastGroupName) + return - if (index > 0 && toPop > 0) { - for (i in 0..toPop) { - displayStack.pop() - } - - displayCurrentModel() + while (displayStack.peek().breadcrumb.lastGroupName != navigationOption.groupName) { + displayStack.pop() } + displayCurrentModel() } override fun onDisplayGroup(group: CockpitParamGroup) { diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt index 87bd87b..6a64e14 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/NavigationState.kt @@ -1,11 +1,5 @@ package com.polidea.cockpit.paramsedition -object NavigationState { - private var navHierarchy: List = listOf() - - fun saveHierarchy(hierarchy: List) { - navHierarchy = hierarchy - } - - fun getHierarchy(): List = navHierarchy +internal object NavigationState { + var breadcrumb: Breadcrumb = Breadcrumb() } \ No newline at end of file diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt index 6ed599d..d19d2a8 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionAdapter.kt @@ -29,7 +29,7 @@ internal class ParamsEditionAdapter(private var displayModel: DisplayModel, ParamType.STEP_DOUBLE.ordinal -> StepDoubleParamViewHolder(inflateViewForHolder(R.layout.cockpit_step_param, parent)).configure() GROUP_TYPE_ID -> GroupViewHolder(inflateViewForHolder(R.layout.subgroup, parent)).configure() SECTION_TYPE_ID -> SectionViewHolder(inflateViewForHolder(R.layout.cockpit_group_name, parent)) - PATH_TYPE_ID -> PathViewHolder(inflateViewForHolder(R.layout.path_button, parent)).configure() //TODO fix layout + PATH_TYPE_ID -> PathViewHolder(inflateViewForHolder(R.layout.path_button, parent)).configure() else -> throw IllegalArgumentException("View type $viewType does not match any known case") } } diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt index cdf3d7a..274eca2 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ParamsEditionContract.kt @@ -17,7 +17,7 @@ internal interface ParamsEditionContract { fun showColorPicker(paramName: String, color: Int) - fun displayNavigationDialog(options: List) + fun displayNavigationDialog(options: List) } interface ParamView { @@ -40,7 +40,7 @@ internal interface ParamsEditionContract { fun onNavigateToTop() - fun onNavigateToCrumb(crumb: String) + fun onNavigationChosen(navigationOption: NavigationOption) fun onDisplayGroup(group: CockpitParamGroup) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ViewModels.kt similarity index 51% rename from cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt rename to cockpit/src/main/java/com/polidea/cockpit/paramsedition/ViewModels.kt index 5f85ba8..2497648 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/AdapterModel.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/ViewModels.kt @@ -3,34 +3,40 @@ package com.polidea.cockpit.paramsedition import com.polidea.cockpit.core.CockpitParam import com.polidea.cockpit.core.CockpitParamGroup -internal class DisplayModel(val items: List, val breadcrumb: Breadcrumb = Breadcrumb(), val label: String? = null) +internal class DisplayModel(val items: List, val breadcrumb: Breadcrumb = Breadcrumb(null, null), val label: String? = null) -internal class Breadcrumb(val crumbs: List = listOf()) { - constructor(crumb: String, previousCrumb: Breadcrumb) : this(previousCrumb.crumbs.toMutableList().apply { add(crumb) }) +internal class Breadcrumb(val displayName: String? = null, val groupName: String? = null, val descendants: List = listOf()) { + constructor(toCopy: Breadcrumb, child: Breadcrumb) : this(toCopy.displayName, toCopy.groupName, toCopy.descendants.toMutableList().apply { add(child) }) + + val lastGroupName: String? + get() = if (descendants.isEmpty()) groupName else descendants.last().groupName } +internal class NavigationOption(val displayName: String, val groupName: String?) + internal sealed class DisplayItem(val displayName: String?) { class Section(displayName: String?) : DisplayItem(displayName) class Group(displayName: String?, val group: CockpitParamGroup) : DisplayItem(displayName) class Param(displayName: String?, val param: CockpitParam) : DisplayItem(displayName) - class Path(val breadcrumb: Breadcrumb) : DisplayItem(null) + class Path : DisplayItem(null) } internal fun Map.toDisplayModel(): DisplayModel { val items = mutableListOf() + val crumb = Breadcrumb() forEach { - items.addAll(it.value.toDisplayModel(Breadcrumb()).items) + items.addAll(it.value.toDisplayModel(crumb).items) } return DisplayModel(items) } -internal fun CockpitParamGroup.toDisplayModel(breadcrumb: Breadcrumb, addPath: Boolean = false): DisplayModel { - val newBreadcrumb = Breadcrumb(name ?: "", breadcrumb) - +internal fun CockpitParamGroup.toDisplayModel(parentCrumb: Breadcrumb, addPath: Boolean = false): DisplayModel { + val childCrumb = Breadcrumb(displayName, name) + val newBreadcrumb = Breadcrumb(parentCrumb, childCrumb) val items = mutableListOf(DisplayItem.Section(displayName)) - if (addPath) items.add(DisplayItem.Path(newBreadcrumb)) + if (addPath) items.add(DisplayItem.Path()) items.addAll(subgroups.map { DisplayItem.Group(it.displayName, it) }) items.addAll(params.map { DisplayItem.Param(it.description ?: it.name, it) }) diff --git a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt index 7de8358..1f38479 100644 --- a/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt +++ b/cockpit/src/main/java/com/polidea/cockpit/paramsedition/viewholder/PathViewHolder.kt @@ -2,11 +2,15 @@ package com.polidea.cockpit.paramsedition.viewholder import android.view.View import androidx.recyclerview.widget.RecyclerView +import com.polidea.cockpit.R internal class PathViewHolder(val view: View) : RecyclerView.ViewHolder(view) { var onPathClickedListener: () -> Unit = {} + private val button: View = view.findViewById(R.id.path_button) init { - view.setOnClickListener { onPathClickedListener() } + button.setOnClickListener { + onPathClickedListener() + } } } \ No newline at end of file diff --git a/cockpit/src/main/res/layout/path_button.xml b/cockpit/src/main/res/layout/path_button.xml index c71e80b..3c571e5 100644 --- a/cockpit/src/main/res/layout/path_button.xml +++ b/cockpit/src/main/res/layout/path_button.xml @@ -1,7 +1,18 @@ + android:layout_height="wrap_content"> + +