diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt index 2df72d8a63..406e02730b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt @@ -30,6 +30,9 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.queue.commands.* +import info.nightscout.androidaps.setupwizard.SWEventListener +import info.nightscout.androidaps.setupwizard.SWScreen +import info.nightscout.androidaps.setupwizard.elements.* import info.nightscout.androidaps.utils.wizard.BolusWizard import info.nightscout.androidaps.utils.wizard.QuickWizardEntry import javax.inject.Singleton @@ -155,6 +158,20 @@ interface AppComponent : AndroidInjector { fun injectAuthRequest(authRequest: AuthRequest) + fun injectSWBreak(swBreak: SWBreak) + fun injectSWButton(swButton: SWButton) + fun injectSWEditNumberWithUnits(swEditNumberWithUnits: SWEditNumberWithUnits) + fun injectSWEditString(swEditString: SWEditString) + fun injectSWEditUrl(swEditUrl: SWEditUrl) + fun injectSWFragment(swFragment: SWFragment) + fun injectSSWHtmlLink(swHtmlLink: SWHtmlLink) + fun injectSWInfotext(swInfotext: SWInfotext) + fun injectSWItem(swItem: SWItem) + fun injectSWPlugin(swPlugin: SWPlugin) + fun injectSWRadioButton(swRadioButton: SWRadioButton) + fun injectSWScreen(swScreen: SWScreen) + fun injectSWEventListener(swEventListener: SWEventListener) + fun injectProfile(profile: Profile) fun injectGlucoseStatus(glucoseStatus: GlucoseStatus) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt index ddb268b6db..33d767c82c 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt @@ -41,6 +41,10 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.queue.commands.* +import info.nightscout.androidaps.setupwizard.SWDefinition +import info.nightscout.androidaps.setupwizard.SWEventListener +import info.nightscout.androidaps.setupwizard.SWScreen +import info.nightscout.androidaps.setupwizard.elements.* import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelperImplementation import info.nightscout.androidaps.utils.sharedPreferences.SP @@ -209,6 +213,20 @@ open class AppModule { @ContributesAndroidInjector fun authRequestInjector(): AuthRequest + @ContributesAndroidInjector fun swBreakInjector(): SWBreak + @ContributesAndroidInjector fun swButtonInjector(): SWButton + @ContributesAndroidInjector fun swEditNumberWithUnitsInjector(): SWEditNumberWithUnits + @ContributesAndroidInjector fun swEditStringInjector(): SWEditString + @ContributesAndroidInjector fun swEditUrlInjector(): SWEditUrl + @ContributesAndroidInjector fun swFragmentInjector(): SWFragment + @ContributesAndroidInjector fun swHtmlLinkInjector(): SWHtmlLink + @ContributesAndroidInjector fun swInfotextInjector(): SWInfotext + @ContributesAndroidInjector fun swItemInjector(): SWItem + @ContributesAndroidInjector fun swPluginInjector(): SWPlugin + @ContributesAndroidInjector fun swRadioButtonInjector(): SWRadioButton + @ContributesAndroidInjector fun swScreenInjector(): SWScreen + @ContributesAndroidInjector fun swEventListenerInjector(): SWEventListener + @ContributesAndroidInjector fun profileInjector(): Profile @ContributesAndroidInjector fun glucoseStatusInjector(): GlucoseStatus diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java index 865e8c04d1..6081849d59 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java @@ -81,7 +81,8 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr .pluginName(R.string.openapssmb) .shortName(R.string.smb_shortname) .preferencesId(R.xml.pref_openapssmb) - .description(R.string.description_smb), + .description(R.string.description_smb) + .setDefault(), aapsLogger, resourceHelper, injector ); this.constraintChecker = constraintChecker; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt index 5bf99f1b9a..30014d38e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt @@ -88,7 +88,14 @@ class PluginStore @Inject constructor( var pluginsInCategory: ArrayList? // PluginType.APS - activeAPS = determineActivePlugin(APSInterface::class.java, PluginType.APS) + pluginsInCategory = getSpecificPluginsList(PluginType.APS) + activeAPS = getTheOneEnabledInArray(pluginsInCategory, PluginType.APS) as APSInterface? + if (activeAPS == null) { + activeAPS = getDefaultPlugin(PluginType.APS) as APSInterface + (activeAPS as PluginBase).setPluginEnabled(PluginType.APS, true) + aapsLogger.debug(LTag.CONFIGBUILDER, "Defaulting APSInterface") + } + setFragmentVisiblities((activeAPS as PluginBase).name, pluginsInCategory, PluginType.APS) // PluginType.INSULIN pluginsInCategory = getSpecificPluginsList(PluginType.INSULIN) @@ -121,7 +128,14 @@ class PluginStore @Inject constructor( setFragmentVisiblities((activeSensitivity as PluginBase).name, pluginsInCategory, PluginType.PROFILE) // PluginType.BGSOURCE - activeBgSource = this.determineActivePlugin(BgSourceInterface::class.java, PluginType.BGSOURCE) + pluginsInCategory = getSpecificPluginsList(PluginType.BGSOURCE) + activeBgSource = getTheOneEnabledInArray(pluginsInCategory, PluginType.BGSOURCE) as BgSourceInterface? + if (activeBgSource == null) { + activeBgSource = getDefaultPlugin(PluginType.BGSOURCE) as BgSourceInterface + (activeBgSource as PluginBase).setPluginEnabled(PluginType.BGSOURCE, true) + aapsLogger.debug(LTag.CONFIGBUILDER, "Defaulting BgInterface") + } + setFragmentVisiblities((activeBgSource as PluginBase).name, pluginsInCategory, PluginType.PUMP) // PluginType.PUMP pluginsInCategory = getSpecificPluginsList(PluginType.PUMP) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt index 7e6a936108..a30f0315e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.setupwizard import android.Manifest import android.content.Intent import androidx.appcompat.app.AppCompatActivity +import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Config import info.nightscout.androidaps.Constants import info.nightscout.androidaps.MainApp @@ -43,6 +44,7 @@ import javax.inject.Singleton @Singleton class SWDefinition @Inject constructor( + injector: HasAndroidInjector, private val rxBus: RxBusWrapper, private val mainApp: MainApp, resourceHelper: ResourceHelper, @@ -70,151 +72,151 @@ class SWDefinition @Inject constructor( return this } - private val screenSetupWizard = SWScreen(R.string.nav_setupwizard) - .add(SWInfotext() + private val screenSetupWizard = SWScreen(injector, R.string.nav_setupwizard) + .add(SWInfotext(injector) .label(R.string.welcometosetupwizard)) - private val screenLanguage = SWScreen(R.string.language) + private val screenLanguage = SWScreen(injector, R.string.language) .skippable(false) - .add(SWRadioButton() + .add(SWRadioButton(injector) .option(R.array.languagesArray, R.array.languagesValues) .preferenceId(R.string.key_language).label(R.string.language) .comment(R.string.setupwizard_language_prompt)) - .validator { + .validator(SWValidator { update(mainApp) sp.contains(R.string.key_language) - } - private val screenEula = SWScreen(R.string.end_user_license_agreement) + }) + private val screenEula = SWScreen(injector, R.string.end_user_license_agreement) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.end_user_license_agreement_text)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.end_user_license_agreement_i_understand) - .visibility { !sp.getBoolean(R.string.key_i_understand, false) } - .action { + .visibility(SWValidator { !sp.getBoolean(R.string.key_i_understand, false) }) + .action(Runnable { sp.putBoolean(R.string.key_i_understand, true) rxBus.send(EventSWUpdate(false)) - }) - .visibility { !sp.getBoolean(R.string.key_i_understand, false) } - .validator { sp.getBoolean(R.string.key_i_understand, false) } - private val screenUnits = SWScreen(R.string.units) + })) + .visibility(SWValidator { !sp.getBoolean(R.string.key_i_understand, false) }) + .validator(SWValidator { sp.getBoolean(R.string.key_i_understand, false) }) + private val screenUnits = SWScreen(injector, R.string.units) .skippable(false) - .add(SWRadioButton() + .add(SWRadioButton(injector) .option(R.array.unitsArray, R.array.unitsValues) .preferenceId(R.string.key_units).label(R.string.units) .comment(R.string.setupwizard_units_prompt)) - .validator { sp.contains(R.string.key_units) } - private val displaySettings = SWScreen(R.string.wear_display_settings) + .validator(SWValidator { sp.contains(R.string.key_units) }) + private val displaySettings = SWScreen(injector, R.string.wear_display_settings) .skippable(false) - .add(SWEditNumberWithUnits(Constants.LOWMARK * Constants.MGDL_TO_MMOLL, 3.0, 8.0) + .add(SWEditNumberWithUnits(injector, Constants.LOWMARK * Constants.MGDL_TO_MMOLL, 3.0, 8.0) .preferenceId(R.string.key_low_mark) .updateDelay(5) .label(R.string.low_mark) .comment(R.string.low_mark_comment)) - .add(SWBreak()) - .add(SWEditNumberWithUnits(Constants.HIGHMARK * Constants.MGDL_TO_MMOLL, 5.0, 20.0) + .add(SWBreak(injector)) + .add(SWEditNumberWithUnits(injector, Constants.HIGHMARK * Constants.MGDL_TO_MMOLL, 5.0, 20.0) .preferenceId(R.string.key_high_mark) .updateDelay(5) .label(R.string.high_mark) .comment(R.string.high_mark_comment)) - private val screenPermissionBattery = SWScreen(R.string.permission) + private val screenPermissionBattery = SWScreen(injector, R.string.permission) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(resourceHelper.gs(R.string.needwhitelisting, resourceHelper.gs(R.string.app_name)))) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.askforpermission) - .visibility { AndroidPermission.permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) } - .action { AndroidPermission.askForPermission(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, AndroidPermission.CASE_BATTERY) }) - .visibility { AndroidPermission.permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) } - .validator { !AndroidPermission.permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) } - private val screenPermissionBt = SWScreen(R.string.permission) + .visibility(SWValidator { AndroidPermission.permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) }) + .action(Runnable { AndroidPermission.askForPermission(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, AndroidPermission.CASE_BATTERY) })) + .visibility(SWValidator { AndroidPermission.permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) }) + .validator(SWValidator { !AndroidPermission.permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) }) + private val screenPermissionBt = SWScreen(injector, R.string.permission) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(resourceHelper.gs(R.string.needlocationpermission))) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.askforpermission) - .visibility { AndroidPermission.permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION) } - .action { AndroidPermission.askForPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION, AndroidPermission.CASE_LOCATION) }) - .visibility { AndroidPermission.permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION) } - .validator { !AndroidPermission.permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION) } - private val screenPermissionStore = SWScreen(R.string.permission) + .visibility(SWValidator { AndroidPermission.permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION) }) + .action(Runnable { AndroidPermission.askForPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION, AndroidPermission.CASE_LOCATION) })) + .visibility(SWValidator { AndroidPermission.permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION) }) + .validator(SWValidator { !AndroidPermission.permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION) }) + private val screenPermissionStore = SWScreen(injector, R.string.permission) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(resourceHelper.gs(R.string.needstoragepermission))) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.askforpermission) - .visibility { AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) } - .action { AndroidPermission.askForPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, AndroidPermission.CASE_STORAGE) }) - .visibility { AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) } - .validator { !AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) } - private val screenImport = SWScreen(R.string.nav_import) - .add(SWInfotext() + .visibility(SWValidator { AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) }) + .action(Runnable { AndroidPermission.askForPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, AndroidPermission.CASE_STORAGE) })) + .visibility(SWValidator { AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) }) + .validator(SWValidator { !AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) }) + private val screenImport = SWScreen(injector, R.string.nav_import) + .add(SWInfotext(injector) .label(R.string.storedsettingsfound)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.nav_import) - .action { ImportExportPrefs.importSharedPreferences(activity) }) - .visibility { ImportExportPrefs.file.exists() && !AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) } - private val screenNsClient = SWScreen(R.string.nsclientinternal_title) + .action(Runnable { ImportExportPrefs.importSharedPreferences(activity) })) + .visibility(SWValidator { ImportExportPrefs.file.exists() && !AndroidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) }) + private val screenNsClient = SWScreen(injector, R.string.nsclientinternal_title) .skippable(true) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.nsclientinfotext)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.enable_nsclient) - .action { + .action(Runnable { nsClientPlugin.setPluginEnabled(PluginType.GENERAL, true) nsClientPlugin.setFragmentVisible(PluginType.GENERAL, true) configBuilderPlugin.processOnEnabledCategoryChanged(nsClientPlugin, PluginType.GENERAL) configBuilderPlugin.storeSettings("SetupWizard") rxBus.send(EventConfigBuilderChange()) rxBus.send(EventSWUpdate(true)) - } - .visibility { !nsClientPlugin.isEnabled(PluginType.GENERAL) }) - .add(SWEditUrl() + }) + .visibility(SWValidator { !nsClientPlugin.isEnabled(PluginType.GENERAL) })) + .add(SWEditUrl(injector) .preferenceId(R.string.key_nsclientinternal_url) .updateDelay(5) .label(R.string.nsclientinternal_url_title) .comment(R.string.nsclientinternal_url_dialogmessage)) - .add(SWEditString() - .validator { text: String -> text.length >= 12 } + .add(SWEditString(injector) + .validator(SWTextValidator { text: String -> text.length >= 12 }) .preferenceId(R.string.key_nsclientinternal_api_secret) .updateDelay(5) .label(R.string.nsclientinternal_secret_dialogtitle) .comment(R.string.nsclientinternal_secret_dialogmessage)) - .add(SWBreak()) - .add(SWEventListener(resourceHelper, rxBus, EventNSClientStatus::class.java) + .add(SWBreak(injector)) + .add(SWEventListener(injector, EventNSClientStatus::class.java) .label(R.string.status) .initialStatus(nsClientPlugin.status) ) - .add(SWBreak()) - .validator { nsClientPlugin.nsClientService != null && NSClientService.isConnected && NSClientService.hasWriteAuth } - .visibility { !(nsClientPlugin.nsClientService != null && NSClientService.isConnected && NSClientService.hasWriteAuth) } - private val screenAge = SWScreen(R.string.patientage) + .add(SWBreak(injector)) + .validator(SWValidator { nsClientPlugin.nsClientService != null && NSClientService.isConnected && NSClientService.hasWriteAuth }) + .visibility(SWValidator { !(nsClientPlugin.nsClientService != null && NSClientService.isConnected && NSClientService.hasWriteAuth) }) + private val screenAge = SWScreen(injector, R.string.patientage) .skippable(false) - .add(SWBreak()) - .add(SWRadioButton() + .add(SWBreak(injector)) + .add(SWRadioButton(injector) .option(R.array.ageArray, R.array.ageValues) .preferenceId(R.string.key_age) .label(R.string.patientage) .comment(R.string.patientage_summary)) - .validator { sp.contains(R.string.key_age) } - private val screenInsulin = SWScreen(R.string.configbuilder_insulin) + .validator(SWValidator { sp.contains(R.string.key_age) }) + private val screenInsulin = SWScreen(injector, R.string.configbuilder_insulin) .skippable(false) - .add(SWPlugin() + .add(SWPlugin(injector) .option(PluginType.INSULIN, R.string.configbuilder_insulin_description) .makeVisible(false) .label(R.string.configbuilder_insulin)) - .add(SWBreak()) - .add(SWInfotext() + .add(SWBreak(injector)) + .add(SWInfotext(injector) .label(R.string.diawarning)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.insulinsourcesetup) - .action { + .action(Runnable { val plugin = activePlugin.activeInsulin as PluginBase? if (plugin != null) { PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", Runnable { @@ -223,17 +225,17 @@ class SWDefinition @Inject constructor( activity?.startActivity(i) }, null) } - } - .visibility { (activePlugin.activeInsulin as PluginBase).preferencesId > 0 }) - private val screenBgSource = SWScreen(R.string.configbuilder_bgsource) + }) + .visibility(SWValidator { (activePlugin.activeInsulin as PluginBase).preferencesId > 0 })) + private val screenBgSource = SWScreen(injector, R.string.configbuilder_bgsource) .skippable(false) - .add(SWPlugin() + .add(SWPlugin(injector) .option(PluginType.BGSOURCE, R.string.configbuilder_bgsource_description) .label(R.string.configbuilder_bgsource)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.bgsourcesetup) - .action { + .action(Runnable { val plugin = activePlugin.activeBgSource as PluginBase? if (plugin != null) { PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", Runnable { @@ -242,75 +244,75 @@ class SWDefinition @Inject constructor( activity!!.startActivity(i) }, null) } - } - .visibility { (activePlugin.activeBgSource as PluginBase).preferencesId > 0 }) - private val screenProfile = SWScreen(R.string.configbuilder_profile) + }) + .visibility(SWValidator { (activePlugin.activeBgSource as PluginBase).preferencesId > 0 })) + private val screenProfile = SWScreen(injector, R.string.configbuilder_profile) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.setupwizard_profile_description)) - .add(SWBreak()) - .add(SWPlugin() + .add(SWBreak(injector)) + .add(SWPlugin(injector) .option(PluginType.PROFILE, R.string.configbuilder_profile_description) .label(R.string.configbuilder_profile)) - private val screenNsProfile = SWScreen(R.string.nsprofile) + private val screenNsProfile = SWScreen(injector, R.string.nsprofile) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.adjustprofileinns)) - .add(SWFragment(this) + .add(SWFragment(injector, this) .add(NSProfileFragment())) - .validator { nsProfilePlugin.profile != null && nsProfilePlugin.profile!!.getDefaultProfile() != null && nsProfilePlugin.profile!!.getDefaultProfile()!!.isValid("StartupWizard") } - .visibility { nsProfilePlugin.isEnabled(PluginType.PROFILE) } - private val screenLocalProfile = SWScreen(R.string.localprofile) + .validator(SWValidator { nsProfilePlugin.profile != null && nsProfilePlugin.profile!!.getDefaultProfile() != null && nsProfilePlugin.profile!!.getDefaultProfile()!!.isValid("StartupWizard") }) + .visibility(SWValidator { nsProfilePlugin.isEnabled(PluginType.PROFILE) }) + private val screenLocalProfile = SWScreen(injector, R.string.localprofile) .skippable(false) - .add(SWFragment(this) + .add(SWFragment(injector, this) .add(LocalProfileFragment())) - .validator { localProfilePlugin.profile?.getDefaultProfile()?.isValid("StartupWizard") == true } - .visibility { localProfilePlugin.isEnabled(PluginType.PROFILE) } - private val screenProfileSwitch = SWScreen(R.string.careportal_profileswitch) + .validator(SWValidator { localProfilePlugin.profile?.getDefaultProfile()?.isValid("StartupWizard") == true }) + .visibility(SWValidator { localProfilePlugin.isEnabled(PluginType.PROFILE) }) + private val screenProfileSwitch = SWScreen(injector, R.string.careportal_profileswitch) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.profileswitch_ismissing)) - .add(SWButton() + .add(SWButton(injector) .text(R.string.doprofileswitch) - .action { ProfileSwitchDialog().show(activity!!.supportFragmentManager, "SetupWizard") }) - .validator { profileFunction.getProfile() != null } - .visibility { profileFunction.getProfile() == null } - private val screenPump = SWScreen(R.string.configbuilder_pump) + .action(Runnable { ProfileSwitchDialog().show(activity!!.supportFragmentManager, "SetupWizard") })) + .validator(SWValidator { profileFunction.getProfile() != null }) + .visibility(SWValidator { profileFunction.getProfile() == null }) + private val screenPump = SWScreen(injector, R.string.configbuilder_pump) .skippable(false) - .add(SWPlugin() + .add(SWPlugin(injector) .option(PluginType.PUMP, R.string.configbuilder_pump_description) .label(R.string.configbuilder_pump)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.pumpsetup) - .action { + .action(Runnable { val plugin = activePlugin.activePump as PluginBase PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", Runnable { val i = Intent(activity, PreferencesActivity::class.java) i.putExtra("id", plugin.preferencesId) activity!!.startActivity(i) }, null) - } - .visibility { (activePlugin.activePump as PluginBase).preferencesId > 0 }) - .add(SWButton() + }) + .visibility(SWValidator { (activePlugin.activePump as PluginBase).preferencesId > 0 })) + .add(SWButton(injector) .text(R.string.readstatus) - .action { commandQueue.readStatus("Clicked connect to pump", null) }) - .add(SWEventListener(resourceHelper, rxBus, EventPumpStatusChanged::class.java)) - .validator { activePlugin.activePump.isInitialized } - private val screenAps = SWScreen(R.string.configbuilder_aps) + .action(Runnable { commandQueue.readStatus("Clicked connect to pump", null) })) + .add(SWEventListener(injector, EventPumpStatusChanged::class.java)) + .validator(SWValidator { activePlugin.activePump.isInitialized }) + private val screenAps = SWScreen(injector, R.string.configbuilder_aps) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.setupwizard_aps_description)) - .add(SWBreak()) - .add(SWHtmlLink() + .add(SWBreak(injector)) + .add(SWHtmlLink(injector) .label("https://openaps.readthedocs.io/en/latest/")) - .add(SWBreak()) - .add(SWPlugin() + .add(SWBreak(injector)) + .add(SWPlugin(injector) .option(PluginType.APS, R.string.configbuilder_aps_description) .label(R.string.configbuilder_aps)) - .add(SWButton() + .add(SWButton(injector) .text(R.string.apssetup) - .action { + .action(Runnable { val plugin = activePlugin.activeAPS as PluginBase? if (plugin != null) { PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", Runnable { @@ -319,48 +321,48 @@ class SWDefinition @Inject constructor( activity!!.startActivity(i) }, null) } - } - .visibility { (activePlugin.activeAPS as PluginBase).preferencesId > 0 }) - .visibility { Config.APS } - private val screenApsMode = SWScreen(R.string.apsmode_title) + }) + .visibility(SWValidator { (activePlugin.activeAPS as PluginBase).preferencesId > 0 })) + .visibility(SWValidator { Config.APS }) + private val screenApsMode = SWScreen(injector, R.string.apsmode_title) .skippable(false) - .add(SWRadioButton() + .add(SWRadioButton(injector) .option(R.array.aps_modeArray, R.array.aps_modeValues) .preferenceId(R.string.key_aps_mode).label(R.string.apsmode_title) .comment(R.string.setupwizard_preferred_aps_mode)) - .validator { sp.contains(R.string.key_aps_mode) } - private val screenLoop = SWScreen(R.string.configbuilder_loop) + .validator(SWValidator { sp.contains(R.string.key_aps_mode) }) + private val screenLoop = SWScreen(injector, R.string.configbuilder_loop) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.setupwizard_loop_description)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.enableloop) - .action { + .action(Runnable { loopPlugin.setPluginEnabled(PluginType.LOOP, true) loopPlugin.setFragmentVisible(PluginType.LOOP, true) configBuilderPlugin.processOnEnabledCategoryChanged(loopPlugin, PluginType.LOOP) configBuilderPlugin.storeSettings("SetupWizard") rxBus.send(EventConfigBuilderChange()) rxBus.send(EventSWUpdate(true)) - } - .visibility { !loopPlugin.isEnabled(PluginType.LOOP) }) - .validator { loopPlugin.isEnabled(PluginType.LOOP) } - .visibility { !loopPlugin.isEnabled(PluginType.LOOP) && Config.APS } - private val screenSensitivity = SWScreen(R.string.configbuilder_sensitivity) + }) + .visibility(SWValidator { !loopPlugin.isEnabled(PluginType.LOOP) })) + .validator(SWValidator { loopPlugin.isEnabled(PluginType.LOOP) }) + .visibility(SWValidator { !loopPlugin.isEnabled(PluginType.LOOP) && Config.APS }) + private val screenSensitivity = SWScreen(injector, R.string.configbuilder_sensitivity) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.setupwizard_sensitivity_description)) - .add(SWHtmlLink() + .add(SWHtmlLink(injector) .label(R.string.setupwizard_sensitivity_url)) - .add(SWBreak()) - .add(SWPlugin() + .add(SWBreak(injector)) + .add(SWPlugin(injector) .option(PluginType.SENSITIVITY, R.string.configbuilder_sensitivity_description) .label(R.string.configbuilder_sensitivity)) - .add(SWBreak()) - .add(SWButton() + .add(SWBreak(injector)) + .add(SWButton(injector) .text(R.string.sensitivitysetup) - .action { + .action(Runnable { val plugin = activePlugin.activeSensitivity as PluginBase? if (plugin != null) { PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", Runnable { @@ -369,17 +371,17 @@ class SWDefinition @Inject constructor( activity!!.startActivity(i) }, null) } - } - .visibility { (activePlugin.activeSensitivity as PluginBase).preferencesId > 0 }) - private val getScreenObjectives = SWScreen(R.string.objectives) + }) + .visibility(SWValidator { (activePlugin.activeSensitivity as PluginBase).preferencesId > 0 })) + private val getScreenObjectives = SWScreen(injector, R.string.objectives) .skippable(false) - .add(SWInfotext() + .add(SWInfotext(injector) .label(R.string.startobjective)) - .add(SWBreak()) - .add(SWFragment(this) + .add(SWBreak(injector)) + .add(SWFragment(injector, this) .add(ObjectivesFragment())) - .validator { objectivesPlugin.objectives[ObjectivesPlugin.FIRST_OBJECTIVE].isStarted } - .visibility { !objectivesPlugin.objectives[ObjectivesPlugin.FIRST_OBJECTIVE].isStarted && Config.APS } + .validator(SWValidator { objectivesPlugin.objectives[ObjectivesPlugin.FIRST_OBJECTIVE].isStarted }) + .visibility(SWValidator { !objectivesPlugin.objectives[ObjectivesPlugin.FIRST_OBJECTIVE].isStarted && Config.APS }) private fun swDefinitionFull() { // List all the screens here add(screenSetupWizard) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt index 22bc131995..9757cbca32 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt @@ -1,25 +1,24 @@ package info.nightscout.androidaps.setupwizard +import android.annotation.SuppressLint import android.view.View import android.widget.LinearLayout import android.widget.TextView +import dagger.android.HasAndroidInjector import info.nightscout.androidaps.events.EventStatus -import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.setupwizard.elements.SWItem -import info.nightscout.androidaps.utils.resources.ResourceHelper import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable class SWEventListener constructor( - private val resourceHelper: ResourceHelper, - rxBus: RxBusWrapper, + injector:HasAndroidInjector, clazz: Class -) : SWItem(Type.LISTENER) { +) : SWItem(injector, Type.LISTENER) { private val disposable = CompositeDisposable() private var textLabel = 0 private var status = "" - var textView: TextView? = null + private var textView: TextView? = null // TODO: Adrian how to clear disposable in this case? init { @@ -28,13 +27,14 @@ class SWEventListener constructor( .observeOn(AndroidSchedulers.mainThread()) .subscribe { event: Any -> status = (event as EventStatus).getStatus(resourceHelper) + @SuppressLint("SetTextI18n") textView?.text = (if (textLabel != 0) resourceHelper.gs(textLabel) else "") + " " + status } ) } - override fun label(newLabel: Int): SWEventListener { - textLabel = newLabel + override fun label(label: Int): SWEventListener { + textLabel = label return this } @@ -43,6 +43,7 @@ class SWEventListener constructor( return this } + @SuppressLint("SetTextI18n") override fun generateDialog(layout: LinearLayout) { val context = layout.context textView = TextView(context) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWScreen.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWScreen.java deleted file mode 100644 index 5c7b10315f..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWScreen.java +++ /dev/null @@ -1,49 +0,0 @@ -package info.nightscout.androidaps.setupwizard; - -import java.util.ArrayList; -import java.util.List; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.setupwizard.elements.SWItem; - -public class SWScreen { - - int header; - List items = new ArrayList<>(); - SWValidator validator; - SWValidator visibility; - boolean skippable = false; - - public SWScreen(int header) { - this.header = header; - } - - public String getHeader() { - return MainApp.gs(header); - } - - public SWScreen skippable(boolean skippable) { - this.skippable = skippable; - return this; - } - - public SWScreen add(SWItem newItem) { - items.add(newItem); - return this; - } - - public SWScreen validator(SWValidator validator) { - this.validator = validator; - return this; - } - - public SWScreen visibility(SWValidator visibility) { - this.visibility = visibility; - return this; - } - - public void processVisibility() { - for (SWItem i : items) - i.processVisibility(); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWScreen.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWScreen.kt new file mode 100644 index 0000000000..377aedaed4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWScreen.kt @@ -0,0 +1,49 @@ +package info.nightscout.androidaps.setupwizard + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.setupwizard.elements.SWItem +import info.nightscout.androidaps.utils.resources.ResourceHelper +import java.util.* +import javax.inject.Inject + +class SWScreen(val injector: HasAndroidInjector, private var header: Int) { + + @Inject lateinit var resourceHelper: ResourceHelper + + var items: MutableList = ArrayList() + var validator: SWValidator? = null + var visibility: SWValidator? = null + var skippable = false + + init { + injector.androidInjector().inject(this) + } + + fun getHeader(): String { + return resourceHelper.gs(header) + } + + fun skippable(skippable: Boolean): SWScreen { + this.skippable = skippable + return this + } + + fun add(newItem: SWItem): SWScreen { + items.add(newItem) + return this + } + + fun validator(validator: SWValidator): SWScreen { + this.validator = validator + return this + } + + fun visibility(visibility: SWValidator): SWScreen { + this.visibility = visibility + return this + } + + fun processVisibility() { + for (i in items) i.processVisibility() + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java index 2662f7a980..9ad3a1ecf2 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java @@ -16,6 +16,7 @@ import java.util.List; import javax.inject.Inject; +import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.R; import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; @@ -38,6 +39,7 @@ import io.reactivex.disposables.CompositeDisposable; public class SetupWizardActivity extends NoSplashAppCompatActivity { + @Inject HasAndroidInjector injector; @Inject LocalProfilePlugin localProfilePlugin; @Inject SWDefinition swDefinition; @Inject RxBusWrapper rxBus; @@ -119,9 +121,9 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { private void generateLayout() { SWScreen currentScreen = screens.get(currentWizardPage); - LinearLayout layout = SWItem.generateLayout(this.findViewById(R.id.sw_content_fields)); - for (int i = 0; i < currentScreen.items.size(); i++) { - SWItem currentItem = currentScreen.items.get(i); + LinearLayout layout = new SWItem(injector, SWItem.Type.NONE).generateLayout(this.findViewById(R.id.sw_content_fields)); + for (int i = 0; i < currentScreen.getItems().size(); i++) { + SWItem currentItem = currentScreen.getItems().get(i); currentItem.generateDialog(layout); } scrollView.smoothScrollTo(0, 0); @@ -130,7 +132,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { private void updateButtons() { runOnUiThread(() -> { SWScreen currentScreen = screens.get(currentWizardPage); - if (currentScreen.validator == null || currentScreen.validator.isValid() || currentScreen.skippable) { + if (currentScreen.getValidator() == null || currentScreen.getValidator().isValid() || currentScreen.getSkippable()) { if (currentWizardPage == nextPage()) { findViewById(R.id.finish_button).setVisibility(View.VISIBLE); findViewById(R.id.next_button).setVisibility(View.GONE); @@ -188,7 +190,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { private int nextPage() { int page = currentWizardPage + 1; while (page < screens.size()) { - if (screens.get(page).visibility == null || screens.get(page).visibility.isValid()) + if (screens.get(page).getVisibility() == null || screens.get(page).getVisibility().isValid()) return page; page++; } @@ -198,7 +200,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { private int previousPage() { int page = currentWizardPage - 1; while (page >= 0) { - if (screens.get(page).visibility == null || screens.get(page).visibility.isValid()) + if (screens.get(page).getVisibility() == null || screens.get(page).getVisibility().isValid()) return page; page--; } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java deleted file mode 100644 index 424a0b4d8e..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java +++ /dev/null @@ -1,48 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.setupwizard.SWValidator; - - -public class SWBreak extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWBreak.class); - - private TextView l; - private SWValidator visibilityValidator; - - public SWBreak() { - super(Type.TEXT); - } - - public SWBreak visibility(SWValidator visibilityValidator) { - this.visibilityValidator = visibilityValidator; - return this; - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - l = new TextView(context); - l.setId(View.generateViewId()); - l.setText("\n"); - layout.addView(l); - - } - - @Override - public void processVisibility() { - if (visibilityValidator != null && !visibilityValidator.isValid()) - l.setVisibility(View.GONE); - else - l.setVisibility(View.VISIBLE); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.kt new file mode 100644 index 0000000000..775d5b72d0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.kt @@ -0,0 +1,31 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.setupwizard.SWValidator + +class SWBreak(injector: HasAndroidInjector) : SWItem(injector, Type.TEXT) { + private var l: TextView? = null + private var visibilityValidator: SWValidator? = null + + fun visibility(visibilityValidator: SWValidator): SWBreak { + this.visibilityValidator = visibilityValidator + return this + } + + override fun generateDialog(layout: LinearLayout) { + layout.context + l = TextView(layout.context) + l?.id = View.generateViewId() + l?.text = "\n" + layout.addView(l) + } + + override fun processVisibility() { + if (visibilityValidator != null && !visibilityValidator!!.isValid) + l?.visibility = View.GONE + else l?.visibility = View.VISIBLE + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java deleted file mode 100644 index ed5c3c8914..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java +++ /dev/null @@ -1,64 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.view.View; -import android.widget.Button; -import android.widget.LinearLayout; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.setupwizard.SWValidator; - -public class SWButton extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWButton.class); - - private Runnable buttonRunnable; - private int buttonText; - private SWValidator buttonValidator; - - private Button button; - - public SWButton() { - super(Type.BUTTON); - } - - public SWButton text(int buttonText) { - this.buttonText = buttonText; - return this; - } - - public SWButton action(Runnable buttonRunnable) { - this.buttonRunnable = buttonRunnable; - return this; - } - - public SWButton visibility(SWValidator buttonValidator) { - this.buttonValidator = buttonValidator; - return this; - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - button = new Button(context); - button.setText(buttonText); - button.setOnClickListener((v) -> { - if (buttonRunnable != null) - buttonRunnable.run(); - }); - processVisibility(); - layout.addView(button); - super.generateDialog(layout); - } - - @Override - public void processVisibility() { - if (buttonValidator != null && !buttonValidator.isValid()) - button.setVisibility(View.GONE); - else - button.setVisibility(View.VISIBLE); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.kt new file mode 100644 index 0000000000..cb8bb567b4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.kt @@ -0,0 +1,45 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.view.View +import android.widget.Button +import android.widget.LinearLayout +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.setupwizard.SWValidator + +class SWButton(injector: HasAndroidInjector) : SWItem(injector, Type.BUTTON) { + private var buttonRunnable: Runnable? = null + private var buttonText = 0 + private var buttonValidator: SWValidator? = null + private var button: Button? = null + + fun text(buttonText: Int): SWButton { + this.buttonText = buttonText + return this + } + + fun action(buttonRunnable: Runnable): SWButton { + this.buttonRunnable = buttonRunnable + return this + } + + fun visibility(buttonValidator: SWValidator): SWButton { + this.buttonValidator = buttonValidator + return this + } + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + button = Button(context) + button?.setText(buttonText) + button?.setOnClickListener { buttonRunnable?.run() } + processVisibility() + layout.addView(button) + super.generateDialog(layout) + } + + override fun processVisibility() { + if (buttonValidator != null && !buttonValidator!!.isValid) + button!!.visibility = View.GONE + else button!!.visibility = View.VISIBLE + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java deleted file mode 100644 index 82f006f9ab..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java +++ /dev/null @@ -1,78 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.view.View; -import android.widget.CompoundButton; -import android.widget.LinearLayout; -import android.widget.CheckBox; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.plugins.configBuilder.PluginStore; -import info.nightscout.androidaps.utils.SP; - -/** - * Created by Rumen Georgiev on 5/9/2018. - */ - -public class SWCheckbox extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWCheckbox.class); - - int labelsArray; - int valuesArray; - String label = ""; - int preferenceID; - private CheckBox checkBox; - - public SWCheckbox() { - super(Type.CHECKBOX); - } - - public SWCheckbox option(String label, int preferenceID) { - this.label = label; - this.preferenceID = preferenceID; - return this; - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - // Get if there is already value in SP - Boolean previousValue; - previousValue = SP.getBoolean(preferenceId, false); - checkBox = new CheckBox(context); - checkBox.setText(label); - checkBox.setChecked(previousValue); - checkBox.setVisibility(View.VISIBLE); - checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - ArrayList pluginsInCategory; - pluginsInCategory = PluginStore.Companion.getInstance().getSpecificPluginsList(PluginType.PUMP); - PluginBase found = null; - for (PluginBase p : pluginsInCategory) { - if (p.isEnabled(PluginType.PUMP) && found == null) { - found = p; - } else if (p.isEnabled(PluginType.PUMP)) { - // set others disabled - p.setPluginEnabled(PluginType.PUMP, false); - } - } - log.debug("Enabled pump plugin:"+found.getClass()); - save(checkBox.isChecked()); - } - }); - layout.addView(checkBox); - super.generateDialog(layout); - } - public void save(boolean value){ - SP.putBoolean(preferenceID, value); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.java deleted file mode 100644 index 1d3f651904..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.java +++ /dev/null @@ -1,98 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.graphics.Typeface; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; - -import java.text.DecimalFormat; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.setupwizard.SWNumberValidator; -import info.nightscout.androidaps.utils.NumberPicker; -import info.nightscout.androidaps.utils.SP; -import info.nightscout.androidaps.utils.SafeParse; - - -public class SWEditNumberWithUnits extends SWItem { - - private SWNumberValidator validator = new SWNumberValidator() { - @Override - public boolean isValid(double value) { - return value >= min && value <= max; - } - }; - private int updateDelay = 0; - private double init, min, max; - - public SWEditNumberWithUnits(double defaultMMOL, double minMMOL, double maxMMOL) { - super(Type.UNITNUMBER); - init = defaultMMOL; - min = minMMOL; - max = maxMMOL; - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - TextWatcher watcher = new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (validator != null && validator.isValid(SafeParse.stringToDouble(s.toString()))) - save(s.toString(), updateDelay); - } - - @Override - public void afterTextChanged(Editable s) { - } - }; - - TextView l = new TextView(context); - l.setId(View.generateViewId()); - l.setText(label); - l.setTypeface(l.getTypeface(), Typeface.BOLD); - layout.addView(l); - - double initValue = SP.getDouble(preferenceId, init); - initValue = Profile.toCurrentUnits(ConfigBuilderPlugin.getPlugin().getProfileFunction().getUnits(), initValue); - - NumberPicker numberPicker = new NumberPicker(context); - if (ConfigBuilderPlugin.getPlugin().getProfileFunction().getUnits().equals(Constants.MMOL)) - numberPicker.setParams(initValue, min, max, 0.1d, new DecimalFormat("0.0"), false, null, watcher); - else - numberPicker.setParams(initValue, min * 18, max * 18, 1d, new DecimalFormat("0"), false, null, watcher); - -// LinearLayout.LayoutParams ll = (LinearLayout.LayoutParams) numberPicker.getLayoutParams(); -// ll.gravity = Gravity.CENTER; -// numberPicker.setLayoutParams(ll); - layout.addView(numberPicker); - - TextView c = new TextView(context); - c.setId(View.generateViewId()); - c.setText(comment); - c.setTypeface(c.getTypeface(), Typeface.ITALIC); - layout.addView(c); - - super.generateDialog(layout); - } - - public SWEditNumberWithUnits preferenceId(int preferenceId) { - this.preferenceId = preferenceId; - return this; - } - - public SWEditNumberWithUnits updateDelay(int updateDelay) { - this.updateDelay = updateDelay; - return this; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.kt new file mode 100644 index 0000000000..80ed784fff --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.kt @@ -0,0 +1,67 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.graphics.Typeface +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction +import info.nightscout.androidaps.setupwizard.SWNumberValidator +import info.nightscout.androidaps.utils.NumberPicker +import info.nightscout.androidaps.utils.SafeParse +import java.text.DecimalFormat +import javax.inject.Inject + +class SWEditNumberWithUnits(injector: HasAndroidInjector, private val init: Double, private val min: Double, private val max: Double) : SWItem(injector, Type.UNITNUMBER) { + + @Inject lateinit var profileFunction: ProfileFunction + + private val validator: SWNumberValidator? = SWNumberValidator { value -> value >= min && value <= max } + private var updateDelay = 0 + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + val watcher: TextWatcher = object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + if (validator != null && validator.isValid(SafeParse.stringToDouble(s.toString()))) + save(s.toString(), updateDelay.toLong()) + } + + override fun afterTextChanged(s: Editable) {} + } + + val l = TextView(context) + l.id = View.generateViewId() + label?.let { l.setText(it) } + l.setTypeface(l.typeface, Typeface.BOLD) + layout.addView(l) + var initValue = sp.getDouble(preferenceId, init) + initValue = Profile.toCurrentUnits(profileFunction.getUnits(), initValue) + val numberPicker = NumberPicker(context) + if (profileFunction.getUnits() == Constants.MMOL) numberPicker.setParams(initValue, min, max, 0.1, DecimalFormat("0.0"), false, null, watcher) else numberPicker.setParams(initValue, min * 18, max * 18, 1.0, DecimalFormat("0"), false, null, watcher) + + layout.addView(numberPicker) + val c = TextView(context) + c.id = View.generateViewId() + comment?.let { c.setText(it) } + c.setTypeface(c.typeface, Typeface.ITALIC) + layout.addView(c) + super.generateDialog(layout) + } + + fun preferenceId(preferenceId: Int): SWEditNumberWithUnits { + this.preferenceId = preferenceId + return this + } + + fun updateDelay(updateDelay: Int): SWEditNumberWithUnits { + this.updateDelay = updateDelay + return this + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java deleted file mode 100644 index 1dbfbfe99e..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java +++ /dev/null @@ -1,86 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.graphics.Typeface; -import android.text.Editable; -import android.text.InputType; -import android.text.TextWatcher; -import android.view.View; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.setupwizard.SWTextValidator; -import info.nightscout.androidaps.utils.SP; - - -public class SWEditString extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWEditString.class); - - private SWTextValidator validator = null; - private int updateDelay = 0; - - public SWEditString() { - super(Type.STRING); - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - TextView l = new TextView(context); - l.setId(View.generateViewId()); - l.setText(label); - l.setTypeface(l.getTypeface(), Typeface.BOLD); - layout.addView(l); - - TextView c = new TextView(context); - c.setId(View.generateViewId()); - c.setText(comment); - c.setTypeface(c.getTypeface(), Typeface.ITALIC); - layout.addView(c); - - EditText editText = new EditText(context); - editText.setId(View.generateViewId()); - editText.setInputType(InputType.TYPE_CLASS_TEXT); - editText.setMaxLines(1); - editText.setText(SP.getString(preferenceId, "")); - layout.addView(editText); - super.generateDialog(layout); - - editText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (validator != null && validator.isValid(s.toString())) - save(s.toString(), updateDelay); - } - - @Override - public void afterTextChanged(Editable s) { - } - }); - } - - public SWEditString preferenceId(int preferenceId) { - this.preferenceId = preferenceId; - return this; - } - - public SWEditString validator(SWTextValidator validator) { - this.validator = validator; - return this; - } - - public SWEditString updateDelay(int updateDelay) { - this.updateDelay = updateDelay; - return this; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.kt new file mode 100644 index 0000000000..ccd48a9e1f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.kt @@ -0,0 +1,62 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.graphics.Typeface +import android.text.Editable +import android.text.InputType +import android.text.TextWatcher +import android.view.View +import android.widget.EditText +import android.widget.LinearLayout +import android.widget.TextView +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.setupwizard.SWTextValidator + +class SWEditString(injector: HasAndroidInjector) : SWItem(injector, Type.STRING) { + + private var validator: SWTextValidator? = null + private var updateDelay = 0L + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + val l = TextView(context) + l.id = View.generateViewId() + label?.let { l.setText(it) } + l.setTypeface(l.typeface, Typeface.BOLD) + layout.addView(l) + val c = TextView(context) + c.id = View.generateViewId() + comment?.let { c.setText(it) } + c.setTypeface(c.typeface, Typeface.ITALIC) + layout.addView(c) + val editText = EditText(context) + editText.id = View.generateViewId() + editText.inputType = InputType.TYPE_CLASS_TEXT + editText.maxLines = 1 + editText.setText(sp.getString(preferenceId, "")) + layout.addView(editText) + super.generateDialog(layout) + editText.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + if (validator != null && validator!!.isValid(s.toString())) save(s.toString(), updateDelay) + } + + override fun afterTextChanged(s: Editable) {} + }) + } + + fun preferenceId(preferenceId: Int): SWEditString { + this.preferenceId = preferenceId + return this + } + + fun validator(validator: SWTextValidator): SWEditString { + this.validator = validator + return this + } + + fun updateDelay(updateDelay: Long): SWEditString { + this.updateDelay = updateDelay + return this + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java deleted file mode 100644 index 937b8c8311..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java +++ /dev/null @@ -1,86 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.graphics.Typeface; -import android.text.Editable; -import android.text.InputType; -import android.text.TextWatcher; -import android.util.Patterns; -import android.view.View; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.setupwizard.events.EventSWLabel; -import info.nightscout.androidaps.utils.SP; - -public class SWEditUrl extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWEditUrl.class); - - private int updateDelay = 0; - - public SWEditUrl() { - super(Type.URL); - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - TextView l = new TextView(context); - l.setId(View.generateViewId()); - l.setText(label); - l.setTypeface(l.getTypeface(), Typeface.BOLD); - layout.addView(l); - - TextView c = new TextView(context); - c.setId(View.generateViewId()); - c.setText(comment); - c.setTypeface(c.getTypeface(), Typeface.ITALIC); - layout.addView(c); - - EditText editText = new EditText(context); - editText.setId(View.generateViewId()); - editText.setInputType(InputType.TYPE_CLASS_TEXT); - editText.setMaxLines(1); - editText.setText(SP.getString(preferenceId, "")); - layout.addView(editText); - super.generateDialog(layout); - - editText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (Patterns.WEB_URL.matcher(s).matches()) - save(s.toString(), updateDelay); - else - RxBus.Companion.getINSTANCE().send(new EventSWLabel(MainApp.gs(R.string.error_url_not_valid))); - } - - @Override - public void afterTextChanged(Editable s) { - } - }); - } - - public SWEditUrl preferenceId(int preferenceId) { - this.preferenceId = preferenceId; - return this; - } - - public SWEditUrl updateDelay(int updateDelay) { - this.updateDelay = updateDelay; - return this; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.kt new file mode 100644 index 0000000000..cc9f38ff43 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.kt @@ -0,0 +1,57 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.graphics.Typeface +import android.text.Editable +import android.text.InputType +import android.text.TextWatcher +import android.util.Patterns +import android.view.View +import android.widget.EditText +import android.widget.LinearLayout +import android.widget.TextView +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.R +import info.nightscout.androidaps.setupwizard.events.EventSWLabel + +class SWEditUrl(injector: HasAndroidInjector) : SWItem(injector, Type.URL) { + private var updateDelay = 0L + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + val l = TextView(context) + l.id = View.generateViewId() + label?.let { l.setText(it) } + l.setTypeface(l.typeface, Typeface.BOLD) + layout.addView(l) + val c = TextView(context) + c.id = View.generateViewId() + comment?.let { c.setText(it) } + c.setTypeface(c.typeface, Typeface.ITALIC) + layout.addView(c) + val editText = EditText(context) + editText.id = View.generateViewId() + editText.inputType = InputType.TYPE_CLASS_TEXT + editText.maxLines = 1 + editText.setText(sp.getString(preferenceId, "")) + layout.addView(editText) + super.generateDialog(layout) + editText.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + if (Patterns.WEB_URL.matcher(s).matches()) save(s.toString(), updateDelay.toLong()) else rxBus.send(EventSWLabel(resourceHelper.gs(R.string.error_url_not_valid))) + } + + override fun afterTextChanged(s: Editable) {} + }) + } + + fun preferenceId(preferenceId: Int): SWEditUrl { + this.preferenceId = preferenceId + return this + } + + fun updateDelay(updateDelay: Long): SWEditUrl { + this.updateDelay = updateDelay + return this + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.kt index ab8d20a6dd..72ac956251 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.kt @@ -2,9 +2,10 @@ package info.nightscout.androidaps.setupwizard.elements import android.widget.LinearLayout import androidx.fragment.app.Fragment +import dagger.android.HasAndroidInjector import info.nightscout.androidaps.setupwizard.SWDefinition -class SWFragment(private var definition: SWDefinition) : SWItem(Type.FRAGMENT) { +class SWFragment(injecto:HasAndroidInjector, private var definition: SWDefinition) : SWItem(injecto, Type.FRAGMENT) { lateinit var fragment: Fragment fun add(fragment: Fragment): SWFragment { diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java deleted file mode 100644 index f2eb1bd1ce..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java +++ /dev/null @@ -1,64 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.text.util.Linkify; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.setupwizard.SWValidator; - - -public class SWHtmlLink extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWHtmlLink.class); - private String textLabel = null; - - private TextView l; - private SWValidator visibilityValidator; - - public SWHtmlLink() { - super(Type.HTMLLINK); - } - - public SWHtmlLink label(int label) { - this.label = label; - return this; - } - - public SWHtmlLink label(String newLabel){ - this.textLabel = newLabel; - return this; - } - - public SWHtmlLink visibility(SWValidator visibilityValidator) { - this.visibilityValidator = visibilityValidator; - return this; - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - l = new TextView(context); - l.setId(View.generateViewId()); - l.setAutoLinkMask(Linkify.ALL); - if(textLabel != null) - l.setText(textLabel); - else - l.setText(label); - layout.addView(l); - - } - - @Override - public void processVisibility() { - if (visibilityValidator != null && !visibilityValidator.isValid()) - l.setVisibility(View.GONE); - else - l.setVisibility(View.VISIBLE); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.kt new file mode 100644 index 0000000000..fe5b34241e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.kt @@ -0,0 +1,44 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.text.util.Linkify +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import androidx.annotation.StringRes +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.setupwizard.SWValidator + +class SWHtmlLink(injector: HasAndroidInjector) : SWItem(injector, Type.HTMLLINK) { + + private var textLabel: String? = null + private var l: TextView? = null + private var visibilityValidator: SWValidator? = null + + override fun label(@StringRes label: Int): SWHtmlLink { + this.label = label + return this + } + + fun label(newLabel: String): SWHtmlLink { + textLabel = newLabel + return this + } + + fun visibility(visibilityValidator: SWValidator): SWHtmlLink { + this.visibilityValidator = visibilityValidator + return this + } + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + l = TextView(context) + l?.id = View.generateViewId() + l?.autoLinkMask = Linkify.ALL + if (textLabel != null) l?.text = textLabel else l?.setText(label!!) + layout.addView(l) + } + + override fun processVisibility() { + if (visibilityValidator != null && !visibilityValidator!!.isValid) l?.visibility = View.GONE else l?.visibility = View.VISIBLE + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java deleted file mode 100644 index a328d639ec..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java +++ /dev/null @@ -1,62 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.setupwizard.SWValidator; - - -public class SWInfotext extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWInfotext.class); - private String textLabel = null; - - private TextView l; - private SWValidator visibilityValidator; - - public SWInfotext() { - super(Type.TEXT); - } - - public SWInfotext label(int label) { - this.label = label; - return this; - } - - public SWInfotext label(String newLabel){ - this.textLabel = newLabel; - return this; - } - - public SWInfotext visibility(SWValidator visibilityValidator) { - this.visibilityValidator = visibilityValidator; - return this; - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - l = new TextView(context); - l.setId(View.generateViewId()); - if(textLabel != null) - l.setText(textLabel); - else - l.setText(label); - layout.addView(l); - - } - - @Override - public void processVisibility() { - if (visibilityValidator != null && !visibilityValidator.isValid()) - l.setVisibility(View.GONE); - else - l.setVisibility(View.VISIBLE); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.kt new file mode 100644 index 0000000000..ca9b3b829f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.kt @@ -0,0 +1,40 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.setupwizard.SWValidator + +class SWInfotext(injector: HasAndroidInjector) : SWItem(injector, Type.TEXT) { + private var textLabel: String? = null + private var l: TextView? = null + private var visibilityValidator: SWValidator? = null + + override fun label(label: Int): SWInfotext { + this.label = label + return this + } + + fun label(newLabel: String): SWInfotext { + textLabel = newLabel + return this + } + + fun visibility(visibilityValidator: SWValidator): SWInfotext { + this.visibilityValidator = visibilityValidator + return this + } + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + l = TextView(context) + l?.id = View.generateViewId() + if (textLabel != null) l?.text = textLabel else l?.setText(label!!) + layout.addView(l) + } + + override fun processVisibility() { + if (visibilityValidator != null && !visibilityValidator!!.isValid) l?.visibility = View.GONE else l?.visibility = View.VISIBLE + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java deleted file mode 100644 index 994acc4e0b..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java +++ /dev/null @@ -1,117 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.view.View; -import android.widget.LinearLayout; - -import androidx.annotation.StringRes; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.setupwizard.events.EventSWUpdate; -import info.nightscout.androidaps.utils.SP; - -public class SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWItem.class); - - private static final ScheduledExecutorService eventWorker = Executors.newSingleThreadScheduledExecutor(); - private static ScheduledFuture scheduledEventPost = null; - - public enum Type { - NONE, - TEXT, - HTMLLINK, - BREAK, - LISTENER, - URL, - STRING, - NUMBER, - DECIMALNUMBER, - CHECKBOX, - RADIOBUTTON, - PLUGIN, - BUTTON, - FRAGMENT, - UNITNUMBER - } - - Type type; - Integer label; - Integer comment; - int preferenceId; - - - public SWItem(Type type) { - this.type = type; - } - - String getLabel() { - return MainApp.gs(label); - } - - String getComment() { - if (comment != null) - return MainApp.gs(comment); - else - return ""; - } - - Type getType() { - return type; - } - - public SWItem label(@StringRes int label) { - this.label = label; - return this; - } - - public SWItem comment(@StringRes int comment) { - this.comment = comment; - return this; - } - - public void save(String value, int updateDelay) { - SP.putString(preferenceId, value); - scheduleChange(updateDelay); - } - - public static LinearLayout generateLayout(View view) { - LinearLayout layout = (LinearLayout) view; - layout.removeAllViews(); - return layout; - } - - public void generateDialog(LinearLayout layout) { - } - - public void processVisibility() { - } - - private void scheduleChange(int updateDelay) { - class PostRunnable implements Runnable { - public void run() { - if (L.isEnabled(L.CORE)) - log.debug("Firing EventPreferenceChange"); - RxBus.Companion.getINSTANCE().send(new EventPreferenceChange(MainApp.resources(), preferenceId)); - RxBus.Companion.getINSTANCE().send(new EventSWUpdate(false)); - scheduledEventPost = null; - } - } - // cancel waiting task to prevent sending multiple posts - if (scheduledEventPost != null) - scheduledEventPost.cancel(false); - Runnable task = new PostRunnable(); - final int sec = updateDelay; - scheduledEventPost = eventWorker.schedule(task, sec, TimeUnit.SECONDS); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.kt new file mode 100644 index 0000000000..374c981a8f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.kt @@ -0,0 +1,86 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.view.View +import android.widget.LinearLayout +import androidx.annotation.StringRes +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.events.EventPreferenceChange +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.bus.RxBusWrapper +import info.nightscout.androidaps.setupwizard.events.EventSWUpdate +import info.nightscout.androidaps.utils.resources.ResourceHelper +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledFuture +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +open class SWItem(val injector: HasAndroidInjector, var type: Type) { + + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var rxBus: RxBusWrapper + @Inject lateinit var resourceHelper: ResourceHelper + @Inject lateinit var sp: info.nightscout.androidaps.utils.sharedPreferences.SP + + private val eventWorker = Executors.newSingleThreadScheduledExecutor() + private var scheduledEventPost: ScheduledFuture<*>? = null + + init { + injector.androidInjector().inject(this) + } + + enum class Type { + NONE, TEXT, HTMLLINK, BREAK, LISTENER, URL, STRING, NUMBER, DECIMALNUMBER, CHECKBOX, RADIOBUTTON, PLUGIN, BUTTON, FRAGMENT, UNITNUMBER + } + + var label: Int? = null + var comment: Int? = null + var preferenceId = 0 + + fun getLabel(): String { + return label?.let { resourceHelper.gs(it) } ?: "" + } + + fun getComment(): String { + return comment?.let { resourceHelper.gs(it) } ?: "" + } + + open fun label(@StringRes label: Int): SWItem { + this.label = label + return this + } + + fun comment(@StringRes comment: Int): SWItem { + this.comment = comment + return this + } + + fun save(value: String, updateDelay: Long) { + sp.putString(preferenceId, value) + scheduleChange(updateDelay) + } + + fun generateLayout(view: View): LinearLayout { + val layout = view as LinearLayout + layout.removeAllViews() + return layout + } + + open fun generateDialog(layout: LinearLayout) {} + open fun processVisibility() {} + + private fun scheduleChange(updateDelay: Long) { + class PostRunnable : Runnable { + override fun run() { + aapsLogger.debug(LTag.CORE, "Firing EventPreferenceChange") + rxBus.send(EventPreferenceChange(resourceHelper, preferenceId)) + rxBus.send(EventSWUpdate(false)) + scheduledEventPost = null + } + } + // cancel waiting task to prevent sending multiple posts + scheduledEventPost?.cancel(false) + val task: Runnable = PostRunnable() + scheduledEventPost = eventWorker.schedule(task, updateDelay, TimeUnit.SECONDS) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java deleted file mode 100644 index 5a86397a8b..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java +++ /dev/null @@ -1,97 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.RadioGroup; -import android.widget.TextView; - -import org.slf4j.Logger; - -import java.util.ArrayList; - -import info.nightscout.androidaps.events.EventConfigBuilderChange; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.configBuilder.PluginStore; -import info.nightscout.androidaps.setupwizard.events.EventSWUpdate; - -public class SWPlugin extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWPlugin.class); - - private PluginType pType; - private RadioGroup radioGroup; - private int pluginDescription; - - private boolean makeVisible = true; - - public SWPlugin() { - super(Type.PLUGIN); - } - - public SWPlugin option(PluginType pType, int pluginDescription) { - this.pType = pType; - this.pluginDescription = pluginDescription; - return this; - } - - public SWPlugin makeVisible(boolean makeVisible) { - this.makeVisible = makeVisible; - return this; - } - - @Override - public void generateDialog(LinearLayout layout) { - - Context context = layout.getContext(); - radioGroup = new RadioGroup(context); - radioGroup.clearCheck(); - - ArrayList pluginsInCategory = PluginStore.Companion.getInstance().getSpecificPluginsList(pType); - - radioGroup.setOrientation(LinearLayout.VERTICAL); - radioGroup.setVisibility(View.VISIBLE); - - TextView pdesc = new TextView(context); - pdesc.setText(pluginDescription); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - params.setMargins(0, 0, 0, 40); - pdesc.setLayoutParams(params); - layout.addView(pdesc); - - for (int i = 0; i < pluginsInCategory.size(); i++) { - RadioButton rdbtn = new RadioButton(context); - PluginBase p = pluginsInCategory.get(i); - rdbtn.setId(View.generateViewId()); - rdbtn.setText(p.getName()); - if (p.isEnabled(pType)) - rdbtn.setChecked(true); - rdbtn.setTag(p); - radioGroup.addView(rdbtn); - params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - params.setMargins(80, 0, 0, 0); - TextView desc = new TextView(context); - desc.setText(p.getDescription()); - desc.setLayoutParams(params); - radioGroup.addView(desc); - } - - radioGroup.setOnCheckedChangeListener((group, checkedId) -> { - RadioButton rb = group.findViewById(checkedId); - PluginBase plugin = (PluginBase) rb.getTag(); - plugin.setPluginEnabled(pType, rb.isChecked()); - plugin.setFragmentVisible(pType, rb.isChecked() && makeVisible); - ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(plugin, pType); - ConfigBuilderPlugin.getPlugin().storeSettings("SetupWizard"); - RxBus.Companion.getINSTANCE().send(new EventConfigBuilderChange()); - RxBus.Companion.getINSTANCE().send(new EventSWUpdate(false)); - }); - layout.addView(radioGroup); - super.generateDialog(layout); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.kt new file mode 100644 index 0000000000..5d8c1f0f93 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.kt @@ -0,0 +1,80 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.TextView +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.events.EventConfigBuilderChange +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.configBuilder.PluginStore +import info.nightscout.androidaps.setupwizard.events.EventSWUpdate +import javax.inject.Inject + +class SWPlugin(injector: HasAndroidInjector) : SWItem(injector, Type.PLUGIN) { + + @Inject lateinit var pluginStore: PluginStore + @Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin + + private var pType: PluginType? = null + private var radioGroup: RadioGroup? = null + private var pluginDescription = 0 + private var makeVisible = true + + fun option(pType: PluginType, pluginDescription: Int): SWPlugin { + this.pType = pType + this.pluginDescription = pluginDescription + return this + } + + fun makeVisible(makeVisible: Boolean): SWPlugin { + this.makeVisible = makeVisible + return this + } + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + radioGroup = RadioGroup(context) + radioGroup?.clearCheck() + val pluginsInCategory = pluginStore.getSpecificPluginsList(pType!!) + radioGroup?.orientation = LinearLayout.VERTICAL + radioGroup?.visibility = View.VISIBLE + val pdesc = TextView(context) + pdesc.setText(pluginDescription) + var params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + params.setMargins(0, 0, 0, 40) + pdesc.layoutParams = params + layout.addView(pdesc) + for (i in pluginsInCategory.indices) { + val rdbtn = RadioButton(context) + val p = pluginsInCategory[i] + rdbtn.id = View.generateViewId() + rdbtn.text = p.name + if (p.isEnabled(pType!!)) rdbtn.isChecked = true + rdbtn.tag = p + radioGroup?.addView(rdbtn) + params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + params.setMargins(80, 0, 0, 0) + val desc = TextView(context) + desc.text = p.description + desc.layoutParams = params + radioGroup?.addView(desc) + } + radioGroup?.setOnCheckedChangeListener { group: RadioGroup, checkedId: Int -> + val rb = group.findViewById(checkedId) + val plugin = rb.tag as PluginBase + plugin.setPluginEnabled(pType!!, rb.isChecked) + plugin.setFragmentVisible(pType!!, rb.isChecked && makeVisible) + configBuilderPlugin.processOnEnabledCategoryChanged(plugin, pType) + configBuilderPlugin.storeSettings("SetupWizard") + rxBus.send(EventConfigBuilderChange()) + rxBus.send(EventSWUpdate(false)) + } + layout.addView(radioGroup) + super.generateDialog(layout) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java deleted file mode 100644 index 091a6d8e99..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java +++ /dev/null @@ -1,85 +0,0 @@ -package info.nightscout.androidaps.setupwizard.elements; - -import android.content.Context; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.RadioGroup; -import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; -import info.nightscout.androidaps.utils.SP; - -public class SWRadioButton extends SWItem { - private static Logger log = StacktraceLoggerWrapper.getLogger(SWRadioButton.class); - - int labelsArray; - int valuesArray; - private RadioGroup radioGroup; - - public SWRadioButton() { - super(Type.RADIOBUTTON); - } - - public SWRadioButton option(int labels, int values) { - this.labelsArray = labels; - this.valuesArray = values; - return this; - } - - public String[] labels() { - return MainApp.resources().getStringArray(labelsArray); - } - - public String[] values() { - return MainApp.resources().getStringArray(valuesArray); - } - - @Override - public void generateDialog(LinearLayout layout) { - Context context = layout.getContext(); - - TextView pdesc = new TextView(context); - pdesc.setText(getComment()); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - params.setMargins(0, 0, 0, 40); - pdesc.setLayoutParams(params); - layout.addView(pdesc); - - // Get if there is already value in SP - String previousValue = SP.getString(preferenceId, "none"); - radioGroup = new RadioGroup(context); - radioGroup.clearCheck(); - radioGroup.setOrientation(LinearLayout.VERTICAL); - radioGroup.setVisibility(View.VISIBLE); - - for (int i = 0; i < labels().length; i++) { - RadioButton rdbtn = new RadioButton(context); - rdbtn.setId(View.generateViewId()); - rdbtn.setText(labels()[i]); - if (previousValue.equals(values()[i])) - rdbtn.setChecked(true); - rdbtn.setTag(i); - radioGroup.addView(rdbtn); - } - - radioGroup.setOnCheckedChangeListener((group, checkedId) -> { - int i = (int) group.findViewById(checkedId).getTag(); - save(values()[i], 0); - }); - layout.addView(radioGroup); - - super.generateDialog(layout); - } - - public SWRadioButton preferenceId(int preferenceId) { - this.preferenceId = preferenceId; - return this; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.kt new file mode 100644 index 0000000000..7201c47342 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.kt @@ -0,0 +1,65 @@ +package info.nightscout.androidaps.setupwizard.elements + +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.TextView +import dagger.android.HasAndroidInjector + +class SWRadioButton(injector: HasAndroidInjector) : SWItem(injector, Type.RADIOBUTTON) { + private var labelsArray = 0 + private var valuesArray = 0 + private var radioGroup: RadioGroup? = null + + fun option(labels: Int, values: Int): SWRadioButton { + labelsArray = labels + valuesArray = values + return this + } + + private fun labels(): Array { + return resourceHelper.gsa(labelsArray) + } + + fun values(): Array { + return resourceHelper.gsa(valuesArray) + } + + override fun generateDialog(layout: LinearLayout) { + val context = layout.context + val pdesc = TextView(context) + pdesc.text = getComment() + val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + params.setMargins(0, 0, 0, 40) + pdesc.layoutParams = params + layout.addView(pdesc) + + // Get if there is already value in SP + val previousValue = sp.getString(preferenceId, "none") + radioGroup = RadioGroup(context) + radioGroup?.clearCheck() + radioGroup?.orientation = LinearLayout.VERTICAL + radioGroup?.visibility = View.VISIBLE + for (i in labels().indices) { + val rdbtn = RadioButton(context) + rdbtn.id = View.generateViewId() + rdbtn.text = labels()[i] + if (previousValue == values()[i]) rdbtn.isChecked = true + rdbtn.tag = i + radioGroup!!.addView(rdbtn) + } + radioGroup!!.setOnCheckedChangeListener { group: RadioGroup, checkedId: Int -> + val i = group.findViewById(checkedId).tag as Int + save(values()[i], 0) + } + layout.addView(radioGroup) + super.generateDialog(layout) + } + + fun preferenceId(preferenceId: Int): SWRadioButton { + this.preferenceId = preferenceId + return this + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/events/EventSWLabel.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/events/EventSWLabel.java deleted file mode 100644 index f0f4ff7628..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/events/EventSWLabel.java +++ /dev/null @@ -1,11 +0,0 @@ -package info.nightscout.androidaps.setupwizard.events; - -import info.nightscout.androidaps.events.Event; - -public class EventSWLabel extends Event { - public String label; - - public EventSWLabel(String label) { - this.label = label; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/events/EventSWLabel.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/events/EventSWLabel.kt new file mode 100644 index 0000000000..636c94c2bf --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/events/EventSWLabel.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.setupwizard.events + +import info.nightscout.androidaps.events.Event + +class EventSWLabel(var label: String) : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelper.kt b/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelper.kt index b69529cfc6..4383d9d39d 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelper.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelper.kt @@ -2,11 +2,7 @@ package info.nightscout.androidaps.utils.resources import android.content.res.AssetFileDescriptor import android.graphics.Bitmap -import androidx.annotation.BoolRes -import androidx.annotation.ColorRes -import androidx.annotation.PluralsRes -import androidx.annotation.RawRes -import androidx.annotation.StringRes +import androidx.annotation.* interface ResourceHelper { fun gs(@StringRes id: Int): String @@ -15,6 +11,7 @@ interface ResourceHelper { fun gc(@ColorRes id: Int): Int fun gb(@BoolRes id :Int) : Boolean fun gcs(@ColorRes id: Int): String + fun gsa(@ArrayRes id:Int): Array fun openRawResourceFd(@RawRes id : Int) : AssetFileDescriptor? fun getIcon() : Int diff --git a/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelperImplementation.kt b/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelperImplementation.kt index 6763ec1e0e..4ccaa94025 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelperImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/resources/ResourceHelperImplementation.kt @@ -5,6 +5,7 @@ import android.content.Context import android.content.res.AssetFileDescriptor import android.graphics.Bitmap import android.graphics.BitmapFactory +import androidx.annotation.ArrayRes import androidx.annotation.BoolRes import androidx.annotation.ColorRes import androidx.annotation.PluralsRes @@ -28,12 +29,15 @@ class ResourceHelperImplementation @Inject constructor(private val context: Cont override fun gc(@ColorRes id: Int): Int = ContextCompat.getColor(context, id) - override fun gb(@BoolRes id :Int) : Boolean = context.resources.getBoolean(id) + override fun gb(@BoolRes id: Int): Boolean = context.resources.getBoolean(id) @SuppressLint("ResourceType") override fun gcs(@ColorRes id: Int): String = gs(id).replace("#ff", "#") + override fun gsa(@ArrayRes id: Int): Array = + context.resources.getStringArray(id) + override fun openRawResourceFd(id: Int): AssetFileDescriptor = context.resources.openRawResourceFd(id)