wip: migrate settings to compose

This commit is contained in:
FunkyMuse 2023-06-26 19:22:56 +02:00
parent a92627c475
commit 73c87aca56
24 changed files with 918 additions and 256 deletions

View File

@ -1,73 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 33
defaultConfig {
applicationId "com.simplemobiletools.calculator"
minSdkVersion 23
targetSdkVersion 33
versionCode 60
versionName "5.11.3"
setProperty("archivesBaseName", "calculator")
}
signingConfigs {
if (keystorePropertiesFile.exists()) {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (keystorePropertiesFile.exists()) {
signingConfig signingConfigs.release
}
}
}
flavorDimensions "variants"
productFlavors {
core {}
fdroid {}
prepaid {}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
}
dependencies {
implementation 'com.github.SimpleMobileTools:Simple-Commons:4c83ec8740'
implementation 'me.grantland:autofittextview:0.2.1'
implementation 'net.objecthunter:exp4j:0.4.8'
kapt 'androidx.room:room-compiler:2.5.1'
implementation 'androidx.room:room-runtime:2.5.1'
annotationProcessor 'androidx.room:room-compiler:2.5.1'
}

110
app/build.gradle.kts Normal file
View File

@ -0,0 +1,110 @@
import java.io.FileInputStream
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.konan.properties.Properties
plugins {
alias(libs.plugins.android)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.ksp)
}
val keystorePropertiesFile: File = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
compileSdk = project.libs.versions.app.build.compileSDKVersion.get().toInt()
defaultConfig {
minSdk = project.libs.versions.app.build.minimumSDK.get().toInt()
targetSdk = project.libs.versions.app.build.targetSDK.get().toInt()
versionName = project.libs.versions.app.version.versionName.get()
versionCode = project.libs.versions.app.version.versionCode.get().toInt()
setProperty("archivesBaseName", "calculator")
}
signingConfigs {
if (keystorePropertiesFile.exists()) {
register("release") {
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
}
}
}
buildTypes {
debug {
applicationIdSuffix = ".debug"
}
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
if (keystorePropertiesFile.exists()) {
signingConfig = signingConfigs.getByName("release")
}
}
}
buildFeatures {
viewBinding = true
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
}
flavorDimensions.add("variants")
productFlavors {
register("core")
register("fdroid")
register("prepaid")
}
compileOptions {
val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get().toString())
sourceCompatibility = currentJavaVersionFromLibs
targetCompatibility = currentJavaVersionFromLibs
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = project.libs.versions.app.build.kotlinJVMTarget.get()
kotlinOptions.freeCompilerArgs = listOf(
"-opt-in=kotlin.RequiresOptIn",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-Xcontext-receivers"
)
}
sourceSets {
getByName("main").java.srcDirs("src/main/kotlin")
}
lint {
checkReleaseBuilds = false
abortOnError = false
}
}
dependencies {
implementation(libs.simple.tools.commons)
implementation(libs.auto.fit.text.view)
implementation(libs.exp4j)
implementation(libs.bundles.compose)
implementation(libs.bundles.accompanist)
implementation(libs.bundles.compose.preview)
implementation(libs.bundles.room)
ksp(libs.androidx.room.compiler)
}

View File

@ -9,6 +9,7 @@ import androidx.core.content.res.ResourcesCompat
import com.simplemobiletools.calculator.BuildConfig
import com.simplemobiletools.calculator.R
import com.simplemobiletools.calculator.databases.CalculatorDatabase
import com.simplemobiletools.calculator.databinding.ActivityMainBinding
import com.simplemobiletools.calculator.dialogs.HistoryDialog
import com.simplemobiletools.calculator.extensions.config
import com.simplemobiletools.calculator.extensions.updateViewColors
@ -20,7 +21,6 @@ import com.simplemobiletools.commons.helpers.LOWER_ALPHA_INT
import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA_INT
import com.simplemobiletools.commons.models.FAQItem
import com.simplemobiletools.commons.models.Release
import kotlinx.android.synthetic.main.activity_main.*
import me.grantland.widget.AutofitHelper
class MainActivity : SimpleActivity(), Calculator {
@ -32,48 +32,50 @@ class MainActivity : SimpleActivity(), Calculator {
private var saveCalculatorState: String = ""
private lateinit var calc: CalculatorImpl
private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setContentView(binding.root)
appLaunched(BuildConfig.APPLICATION_ID)
setupOptionsMenu()
refreshMenuItems()
updateMaterialActivityViews(main_coordinator, null, useTransparentNavigation = false, useTopSearchMenu = false)
setupMaterialScrollListener(main_nested_scrollview, main_toolbar)
updateMaterialActivityViews(binding.mainCoordinator, null, useTransparentNavigation = false, useTopSearchMenu = false)
setupMaterialScrollListener(binding.mainNestedScrollview, binding.mainToolbar)
if (savedInstanceState != null) {
saveCalculatorState = savedInstanceState.getCharSequence(CALCULATOR_STATE) as String
}
calc = CalculatorImpl(this, applicationContext, decimalSeparator, groupingSeparator, saveCalculatorState)
btn_plus.setOnClickOperation(PLUS)
btn_minus.setOnClickOperation(MINUS)
btn_multiply.setOnClickOperation(MULTIPLY)
btn_divide.setOnClickOperation(DIVIDE)
btn_percent.setOnClickOperation(PERCENT)
btn_power.setOnClickOperation(POWER)
btn_root.setOnClickOperation(ROOT)
btn_minus.setOnLongClickListener { calc.turnToNegative() }
btn_clear.setVibratingOnClickListener { calc.handleClear() }
btn_clear.setOnLongClickListener {
binding.btnPlus?.setOnClickOperation(PLUS)
binding.btnMinus?.setOnClickOperation(MINUS)
binding.btnMultiply?.setOnClickOperation(MULTIPLY)
binding.btnDivide?.setOnClickOperation(DIVIDE)
binding.btnPercent?.setOnClickOperation(PERCENT)
binding.btnPower?.setOnClickOperation(POWER)
binding.btnRoot?.setOnClickOperation(ROOT)
binding.btnMinus?.setOnLongClickListener { calc.turnToNegative() }
binding.btnClear?.setVibratingOnClickListener { calc.handleClear() }
binding.btnClear?.setOnLongClickListener {
calc.handleReset()
true
}
getButtonIds().forEach {
it.setVibratingOnClickListener { view ->
it?.setVibratingOnClickListener { view ->
calc.numpadClicked(view.id)
}
}
btn_equals.setVibratingOnClickListener { calc.handleEquals() }
formula.setOnLongClickListener { copyToClipboard(false) }
result.setOnLongClickListener { copyToClipboard(true) }
AutofitHelper.create(result)
AutofitHelper.create(formula)
binding.btnEquals?.setVibratingOnClickListener { calc.handleEquals() }
binding.formula?.setOnLongClickListener { copyToClipboard(false) }
binding.result?.setOnLongClickListener { copyToClipboard(true) }
AutofitHelper.create(binding.result)
AutofitHelper.create(binding.formula)
storeStateVariables()
updateViewColors(calculator_holder, getProperTextColor())
binding.calculatorHolder?.let { updateViewColors(it, getProperTextColor()) }
setupDecimalSeparator()
checkWhatsNewDialog()
checkAppOnSDCard()
@ -81,9 +83,9 @@ class MainActivity : SimpleActivity(), Calculator {
override fun onResume() {
super.onResume()
setupToolbar(main_toolbar)
setupToolbar(binding.mainToolbar)
if (storedTextColor != config.textColor) {
updateViewColors(calculator_holder, getProperTextColor())
binding.calculatorHolder?.let { updateViewColors(it, getProperTextColor()) }
}
if (config.preventPhoneFromSleeping) {
@ -97,14 +99,16 @@ class MainActivity : SimpleActivity(), Calculator {
vibrateOnButtonPress = config.vibrateOnButtonPress
arrayOf(btn_percent, btn_power, btn_root, btn_clear, btn_reset, btn_divide, btn_multiply, btn_plus, btn_minus, btn_equals, btn_decimal).forEach {
it.background = ResourcesCompat.getDrawable(resources, R.drawable.pill_background, theme)
it.background?.alpha = MEDIUM_ALPHA_INT
binding.apply {
arrayOf(btnPercent, btnPower, btnRoot, btnClear, btnReset, btnDivide, btnMultiply, btnPlus, btnMinus, btnEquals, btnDecimal).forEach {
it?.background = ResourcesCompat.getDrawable(resources, com.simplemobiletools.commons.R.drawable.pill_background, theme)
it?.background?.alpha = MEDIUM_ALPHA_INT
}
arrayOf(btn_0, btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9).forEach {
it.background = ResourcesCompat.getDrawable(resources, R.drawable.pill_background, theme)
it.background?.alpha = LOWER_ALPHA_INT
arrayOf(btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9).forEach {
it?.background = ResourcesCompat.getDrawable(resources, com.simplemobiletools.commons.R.drawable.pill_background, theme)
it?.background?.alpha = LOWER_ALPHA_INT
}
}
}
@ -129,7 +133,7 @@ class MainActivity : SimpleActivity(), Calculator {
}
private fun setupOptionsMenu() {
main_toolbar.setOnMenuItemClickListener { menuItem ->
binding.mainToolbar.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.history -> showHistory()
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
@ -142,8 +146,8 @@ class MainActivity : SimpleActivity(), Calculator {
}
private fun refreshMenuItems() {
main_toolbar.menu.apply {
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations)
binding.mainToolbar.menu.apply {
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(com.simplemobiletools.commons.R.bool.hide_google_relations)
}
}
@ -163,7 +167,7 @@ class MainActivity : SimpleActivity(), Calculator {
private fun showHistory() {
HistoryHelper(this).getHistory {
if (it.isEmpty()) {
toast(R.string.history_empty)
toast(com.simplemobiletools.calculator.R.string.history_empty)
} else {
HistoryDialog(this, it, calc)
}
@ -180,27 +184,29 @@ class MainActivity : SimpleActivity(), Calculator {
val faqItems = arrayListOf(
FAQItem(R.string.faq_1_title, R.string.faq_1_text),
FAQItem(R.string.faq_1_title_commons, R.string.faq_1_text_commons),
FAQItem(R.string.faq_4_title_commons, R.string.faq_4_text_commons)
FAQItem(com.simplemobiletools.commons.R.string.faq_1_title_commons, com.simplemobiletools.commons.R.string.faq_1_text_commons),
FAQItem(com.simplemobiletools.commons.R.string.faq_4_title_commons, com.simplemobiletools.commons.R.string.faq_4_text_commons)
)
if (!resources.getBoolean(R.bool.hide_google_relations)) {
faqItems.add(FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons))
faqItems.add(FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons))
if (!resources.getBoolean(com.simplemobiletools.commons.R.bool.hide_google_relations)) {
faqItems.add(FAQItem(com.simplemobiletools.commons.R.string.faq_2_title_commons, com.simplemobiletools.commons.R.string.faq_2_text_commons))
faqItems.add(FAQItem(com.simplemobiletools.commons.R.string.faq_6_title_commons, com.simplemobiletools.commons.R.string.faq_6_text_commons))
}
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true)
}
private fun getButtonIds() = arrayOf(btn_decimal, btn_0, btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9)
private fun copyToClipboard(copyResult: Boolean): Boolean {
var value = formula.value
if (copyResult) {
value = result.value
private fun getButtonIds() = binding.run {
arrayOf(btnDecimal, btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9)
}
return if (value.isEmpty()) {
private fun copyToClipboard(copyResult: Boolean): Boolean {
var value = binding.formula?.value
if (copyResult) {
value = binding.result?.value
}
return if (value.isNullOrEmpty()) {
false
} else {
copyToClipboard(value)
@ -209,19 +215,19 @@ class MainActivity : SimpleActivity(), Calculator {
}
override fun showNewResult(value: String, context: Context) {
result.text = value
binding.result?.text = value
}
private fun checkWhatsNewDialog() {
arrayListOf<Release>().apply {
add(Release(18, R.string.release_18))
add(Release(28, R.string.release_28))
add(Release(18, com.simplemobiletools.calculator.R.string.release_18))
add(Release(28, com.simplemobiletools.calculator.R.string.release_28))
checkWhatsNew(this, BuildConfig.VERSION_CODE)
}
}
override fun showNewFormula(value: String, context: Context) {
formula.text = value
binding.formula?.text = value
}
private fun setupDecimalSeparator() {
@ -234,7 +240,7 @@ class MainActivity : SimpleActivity(), Calculator {
groupingSeparator = COMMA
}
calc.updateSeparators(decimalSeparator, groupingSeparator)
btn_decimal.text = decimalSeparator
binding.btnDecimal?.text = decimalSeparator
}
private fun View.setVibratingOnClickListener(callback: (view: View) -> Unit) {

View File

@ -1,33 +1,82 @@
package com.simplemobiletools.calculator.activities
import android.app.ActivityManager
import android.content.Intent
import android.os.Build
import android.os.Bundle
import com.simplemobiletools.calculator.R
import android.view.View
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import com.simplemobiletools.calculator.compose.screens.SettingsScreen
import com.simplemobiletools.calculator.compose.theme.AppThemeSurface
import com.simplemobiletools.calculator.compose.theme.Theme
import com.simplemobiletools.calculator.databinding.ActivitySettingsBinding
import com.simplemobiletools.calculator.extensions.calculatorDB
import com.simplemobiletools.calculator.extensions.config
import com.simplemobiletools.calculator.extensions.updateWidgets
import com.simplemobiletools.calculator.extensions.viewBinding
import com.simplemobiletools.commons.activities.CustomizationActivity
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
import com.simplemobiletools.commons.helpers.NavigationIcon
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isTiramisuPlus
import kotlinx.android.synthetic.main.activity_settings.*
import java.util.*
import com.simplemobiletools.commons.helpers.*
import java.util.Locale
import kotlin.system.exitProcess
class SettingsActivity : SimpleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
class SettingsActivity : AppCompatActivity() {
updateMaterialActivityViews(settings_coordinator, settings_holder, useTransparentNavigation = true, useTopSearchMenu = false)
setupMaterialScrollListener(settings_nested_scrollview, settings_toolbar)
private val binding by viewBinding(ActivitySettingsBinding::inflate)
private val preferences by lazy { config }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppThemeSurface {
SettingsScreen(
customizeColors = ::handleCustomizeColorsClick, goBack = ::finish,
backgroundColor = getProperBackgroundColor()
)
}
}
val backgroundColor = getProperBackgroundColor()
updateStatusbarColor(backgroundColor)
updateActionbarColor(backgroundColor)
//updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
//setupMaterialScrollListener(binding.settingsNestedScrollview, binding.settingsToolbar)
}
fun updateStatusbarColor(color: Int) {
window.statusBarColor = color
if (color.getContrastColor() == DARK_GREY) {
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
} else {
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
}
}
fun updateActionbarColor(color: Int = getProperStatusBarColor()) {
updateStatusbarColor(color)
setTaskDescription(ActivityManager.TaskDescription(null, null, color))
}
fun updateNavigationBarColor(color: Int) {
window.navigationBarColor = color
updateNavigationBarButtons(color)
}
fun updateNavigationBarButtons(color: Int) {
if (isOreoPlus()) {
if (color.getContrastColor() == DARK_GREY) {
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.addBit(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
} else {
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility.removeBit(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
}
}
}
override fun onResume() {
super.onResume()
setupToolbar(settings_toolbar, NavigationIcon.Arrow)
/*setupToolbar(binding.settingsToolbar, NavigationIcon.Arrow)
setupPurchaseThankYou()
setupCustomizeColors()
@ -37,66 +86,76 @@ class SettingsActivity : SimpleActivity() {
setupPreventPhoneFromSleeping()
setupUseCommaAsDecimalMark()
setupCustomizeWidgetColors()
updateTextColors(settings_nested_scrollview)
updateTextColors(binding.settingsNestedScrollview)
arrayOf(settings_color_customization_section_label, settings_general_settings_label).forEach {
arrayOf(binding.settingsColorCustomizationSectionLabel, binding.settingsGeneralSettingsLabel).forEach {
it.setTextColor(getProperPrimaryColor())
}
}*/
}
private fun setupPurchaseThankYou() {
settings_purchase_thank_you_holder.beGoneIf(isOrWasThankYouInstalled())
settings_purchase_thank_you_holder.setOnClickListener {
binding.settingsPurchaseThankYouHolder.beGoneIf(isOrWasThankYouInstalled())
binding.settingsPurchaseThankYouHolder.setOnClickListener {
launchPurchaseThankYouIntent()
}
}
private fun setupCustomizeColors() {
settings_color_customization_label.text = getCustomizeColorsString()
settings_color_customization_holder.setOnClickListener {
binding.settingsWidgetColorCustomizationLabel.text = getCustomizeColorsString()
binding.settingsWidgetColorCustomizationHolder.setOnClickListener {
handleCustomizeColorsClick()
}
}
private fun handleCustomizeColorsClick() {
Intent(applicationContext, CustomizationActivity::class.java).apply {
/*putExtra(APP_ICON_IDS, getAppIconIDs())
putExtra(APP_LAUNCHER_NAME, getAppLauncherName())*/
startActivity(this)
}
}
private fun setupUseEnglish() {
settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus())
settings_use_english.isChecked = config.useEnglish
settings_use_english_holder.setOnClickListener {
settings_use_english.toggle()
config.useEnglish = settings_use_english.isChecked
binding.settingsUseEnglishHolder.beVisibleIf((preferences.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus())
binding.settingsUseEnglish.isChecked = preferences.useEnglish
binding.settingsUseEnglishHolder.setOnClickListener {
binding.settingsUseEnglish.toggle()
preferences.useEnglish = binding.settingsUseEnglish.isChecked
exitProcess(0)
}
}
private fun setupLanguage() {
settings_language.text = Locale.getDefault().displayLanguage
settings_language_holder.beVisibleIf(isTiramisuPlus())
settings_language_holder.setOnClickListener {
launchChangeAppLanguageIntent()
binding.settingsLanguage.text = Locale.getDefault().displayLanguage
binding.settingsLanguageHolder.beVisibleIf(isTiramisuPlus())
binding.settingsLanguageHolder.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// launchChangeAppLanguageIntent()
}
}
}
private fun setupVibrate() {
settings_vibrate.isChecked = config.vibrateOnButtonPress
settings_vibrate_holder.setOnClickListener {
settings_vibrate.toggle()
config.vibrateOnButtonPress = settings_vibrate.isChecked
binding.settingsVibrate.isChecked = preferences.vibrateOnButtonPress
binding.settingsVibrateHolder.setOnClickListener {
binding.settingsVibrate.toggle()
preferences.vibrateOnButtonPress = binding.settingsVibrate.isChecked
}
}
private fun setupPreventPhoneFromSleeping() {
settings_prevent_phone_from_sleeping.isChecked = config.preventPhoneFromSleeping
settings_prevent_phone_from_sleeping_holder.setOnClickListener {
settings_prevent_phone_from_sleeping.toggle()
config.preventPhoneFromSleeping = settings_prevent_phone_from_sleeping.isChecked
binding.settingsPreventPhoneFromSleeping.isChecked = preferences.preventPhoneFromSleeping
binding.settingsPreventPhoneFromSleepingHolder.setOnClickListener {
binding.settingsPreventPhoneFromSleeping.toggle()
preferences.preventPhoneFromSleeping = binding.settingsPreventPhoneFromSleeping.isChecked
}
}
private fun setupUseCommaAsDecimalMark() {
settings_use_comma_as_decimal_mark.isChecked = config.useCommaAsDecimalMark
settings_use_comma_as_decimal_mark_holder.setOnClickListener {
settings_use_comma_as_decimal_mark.toggle()
config.useCommaAsDecimalMark = settings_use_comma_as_decimal_mark.isChecked
binding.settingsUseCommaAsDecimalMark.isChecked = preferences.useCommaAsDecimalMark
binding.settingsUseCommaAsDecimalMark.setOnClickListener {
binding.settingsUseCommaAsDecimalMark.toggle()
preferences.useCommaAsDecimalMark = binding.settingsUseCommaAsDecimalMark.isChecked
updateWidgets()
ensureBackgroundThread {
applicationContext.calculatorDB.deleteHistory()
@ -105,7 +164,7 @@ class SettingsActivity : SimpleActivity() {
}
private fun setupCustomizeWidgetColors() {
settings_widget_color_customization_holder.setOnClickListener {
binding.settingsWidgetColorCustomizationHolder.setOnClickListener {
Intent(this, WidgetConfigureActivity::class.java).apply {
putExtra(IS_CUSTOMIZING_COLORS, true)
startActivity(this)

View File

@ -10,14 +10,14 @@ import android.widget.RemoteViews
import android.widget.SeekBar
import android.widget.TextView
import com.simplemobiletools.calculator.R
import com.simplemobiletools.calculator.databinding.WidgetConfigBinding
import com.simplemobiletools.calculator.extensions.config
import com.simplemobiletools.calculator.extensions.viewBinding
import com.simplemobiletools.calculator.helpers.MyWidgetProvider
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.dialogs.FeatureLockedDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.widget_config.*
class WidgetConfigureActivity : SimpleActivity() {
private var mBgAlpha = 0f
@ -27,11 +27,13 @@ class WidgetConfigureActivity : SimpleActivity() {
private var mBgColorWithoutTransparency = 0
private var mFeatureLockedDialog: FeatureLockedDialog? = null
private val binding by viewBinding(WidgetConfigBinding::inflate)
public override fun onCreate(savedInstanceState: Bundle?) {
useDynamicTheme = false
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED)
setContentView(R.layout.widget_config)
setContentView(binding.root)
initVariables()
val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false
@ -41,12 +43,12 @@ class WidgetConfigureActivity : SimpleActivity() {
finish()
}
config_save.setOnClickListener { saveConfig() }
config_bg_color.setOnClickListener { pickBackgroundColor() }
config_text_color.setOnClickListener { pickTextColor() }
binding.configSave.setOnClickListener { saveConfig() }
binding.configBgColor.setOnClickListener { pickBackgroundColor() }
binding.configTextColor.setOnClickListener { pickTextColor() }
val primaryColor = getProperPrimaryColor()
config_bg_seekbar.setColors(mTextColor, primaryColor, primaryColor)
binding.configBgSeekbar.setColors(mTextColor, primaryColor, primaryColor)
if (!isCustomizingColors && !isOrWasThankYouInstalled()) {
mFeatureLockedDialog = FeatureLockedDialog(this) {
@ -70,27 +72,27 @@ class WidgetConfigureActivity : SimpleActivity() {
mBgColor = config.widgetBgColor
mBgAlpha = Color.alpha(mBgColor) / 255.toFloat()
btn_reset.beVisible()
binding.configCalc.btnReset.beVisible()
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))
config_bg_seekbar.setOnSeekBarChangeListener(seekbarChangeListener)
config_bg_seekbar.progress = (mBgAlpha * 100).toInt()
binding.configBgSeekbar.setOnSeekBarChangeListener(seekbarChangeListener)
binding.configBgSeekbar.progress = (mBgAlpha * 100).toInt()
updateBackgroundColor()
mTextColor = config.widgetTextColor
if (mTextColor == resources.getColor(R.color.default_widget_text_color) && config.isUsingSystemTheme) {
mTextColor = resources.getColor(R.color.you_primary_color, theme)
if (mTextColor == resources.getColor(com.simplemobiletools.commons.R.color.default_widget_text_color, theme) && config.isUsingSystemTheme) {
mTextColor = resources.getColor(com.simplemobiletools.commons.R.color.you_primary_color, theme)
}
updateTextColor()
formula.text = "15,937*5"
result.text = "79,685"
binding.configCalc.formula.text = "15,937*5"
binding.configCalc.result.text = "79,685"
}
private fun saveConfig() {
val appWidgetManager = AppWidgetManager.getInstance(this) ?: return
val views = RemoteViews(packageName, R.layout.widget).apply {
applyColorFilter(R.id.widget_background, mBgColor)
applyColorFilter(binding.widgetBackground.id, mBgColor)
}
appWidgetManager.updateAppWidget(mWidgetId, views)
@ -121,13 +123,13 @@ class WidgetConfigureActivity : SimpleActivity() {
private fun updateBackgroundColor() {
mBgColor = mBgColorWithoutTransparency.adjustAlpha(mBgAlpha)
widget_background.applyColorFilter(mBgColor)
config_bg_color.setFillWithStroke(mBgColor, mBgColor)
config_save.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
binding.widgetBackground.applyColorFilter(mBgColor)
binding.configBgColor.setFillWithStroke(mBgColor, mBgColor)
binding.configSave.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
}
private fun updateTextColor() {
config_text_color.setFillWithStroke(mTextColor, mTextColor)
binding.configTextColor.setFillWithStroke(mTextColor, mTextColor)
val viewIds = intArrayOf(
R.id.btn_0, R.id.btn_1, R.id.btn_2, R.id.btn_3, R.id.btn_4, R.id.btn_5, R.id.btn_6, R.id.btn_7, R.id.btn_8,
@ -135,9 +137,10 @@ class WidgetConfigureActivity : SimpleActivity() {
R.id.btn_minus, R.id.btn_plus, R.id.btn_decimal, R.id.btn_equals
)
result.setTextColor(mTextColor)
formula.setTextColor(mTextColor)
config_save.setTextColor(getProperPrimaryColor().getContrastColor())
binding.configCalc.result.setTextColor(mTextColor)
binding.configCalc.formula.setTextColor(mTextColor)
binding.configSave.setTextColor(getProperPrimaryColor().getContrastColor())
viewIds.forEach {
(findViewById<TextView>(it)).setTextColor(mTextColor)

View File

@ -3,23 +3,21 @@ package com.simplemobiletools.calculator.adapters
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.calculator.R
import com.simplemobiletools.calculator.activities.SimpleActivity
import com.simplemobiletools.calculator.databinding.HistoryViewBinding
import com.simplemobiletools.calculator.helpers.CalculatorImpl
import com.simplemobiletools.calculator.models.History
import com.simplemobiletools.commons.extensions.copyToClipboard
import com.simplemobiletools.commons.extensions.getProperTextColor
import kotlinx.android.synthetic.main.history_view.view.*
class HistoryAdapter(val activity: SimpleActivity, val items: List<History>, val calc: CalculatorImpl, val itemClick: () -> Unit) :
RecyclerView.Adapter<HistoryAdapter.ViewHolder>() {
private var textColor = activity.getProperTextColor()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = activity.layoutInflater.inflate(R.layout.history_view, parent, false)
return ViewHolder(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(HistoryViewBinding.inflate(activity.layoutInflater, parent, false))
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
@ -28,13 +26,13 @@ class HistoryAdapter(val activity: SimpleActivity, val items: List<History>, val
override fun getItemCount() = items.size
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
inner class ViewHolder(private val binding: HistoryViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindView(item: History): View {
itemView.apply {
item_formula.text = item.formula
item_result.text = item.result
item_formula.setTextColor(textColor)
item_result.setTextColor(textColor)
binding.itemFormula.text = item.formula
binding.itemResult.text = item.result
binding.itemFormula.setTextColor(textColor)
binding.itemResult.setTextColor(textColor)
setOnClickListener {
calc.addNumberToFormula(item.result)

View File

@ -0,0 +1,8 @@
package com.simplemobiletools.calculator.compose.extensions
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
class BooleanPreviewParameterProvider : PreviewParameterProvider<Boolean> {
override val values: Sequence<Boolean>
get() = sequenceOf(false, true)
}

View File

@ -0,0 +1,28 @@
package com.simplemobiletools.calculator.compose.extensions
import android.content.res.Configuration
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
const val LIGHT = "Light"
const val DARK = "Dark"
@MyDevicesDarkOnly
@MyDevicesLightOnly
annotation class MyDevices
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_4_XL, name = "6.3 inches dark", group = DARK)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_2, name = "5.0 inches dark", group = DARK)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_2_XL, name = "6.0 inches dark", group = DARK)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_4_XL, name = "5.5 inches dark", group = DARK)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_4, name = "5.7 inches dark", group = DARK)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.TABLET, name = "Tablet", group = DARK)
annotation class MyDevicesDarkOnly
@Preview(showBackground = true, device = Devices.PIXEL_4_XL, name = "6.3 inches light", group = LIGHT)
@Preview(showBackground = true, device = Devices.PIXEL_2, name = "5.0 inches light", group = LIGHT)
@Preview(showBackground = true, device = Devices.PIXEL_2_XL, name = "6.0 inches light", group = LIGHT)
@Preview(showBackground = true, device = Devices.PIXEL_XL, name = "5.5 inches light", group = LIGHT)
@Preview(showBackground = true, device = Devices.PIXEL_4, name = "5.7 inches light", group = LIGHT)
@Preview(showBackground = true, device = Devices.TABLET, name = "Tablet", group = DARK)
annotation class MyDevicesLightOnly

View File

@ -0,0 +1,88 @@
package com.simplemobiletools.calculator.compose.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.graphics.toColor
import com.simplemobiletools.calculator.compose.extensions.MyDevices
import com.simplemobiletools.calculator.compose.settings.SettingsCheckBoxComponent
import com.simplemobiletools.calculator.compose.settings.SettingsGroup
import com.simplemobiletools.calculator.compose.settings.SettingsPreferenceComponent
import com.simplemobiletools.calculator.compose.settings.SettingsTitleTextComponent
import com.simplemobiletools.calculator.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.R
@Composable
fun SettingsScreen(
goBack: () -> Unit,
customizeColors: () -> Unit,
backgroundColor: Int
) {
Scaffold(
modifier = Modifier
.fillMaxSize()
.background(Color(backgroundColor)),
topBar = {
TopAppBar(
title = {
Text(
text = stringResource(id = R.string.settings),
modifier = Modifier
.padding(start = 16.dp)
.fillMaxWidth()
)
},
navigationIcon = {
Icon(
imageVector = Icons.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back),
modifier = Modifier
.clickable { goBack() }
.padding(start = 8.dp)
)
}
)
}
) { paddingValues ->
Column(
Modifier
.padding(paddingValues)
.verticalScroll(rememberScrollState())
) {
SettingsGroup(title = {
SettingsTitleTextComponent(text = stringResource(id = R.string.color_customization))
}) {
SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.customize_colors), doOnPreferenceClick = customizeColors)
SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.customize_widget_colors))
Spacer(modifier = Modifier.padding(bottom = 16.dp))
}
Divider()
SettingsGroup(title = {
SettingsTitleTextComponent(text = stringResource(id = R.string.general_settings))
}) {
SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.purchase_simple_thank_you))
SettingsCheckBoxComponent(title = stringResource(id = R.string.use_english_language))
SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.language), preferenceSummary = "English")
SettingsCheckBoxComponent(title = stringResource(id = R.string.vibrate_on_button_press))
SettingsCheckBoxComponent(title = stringResource(id = R.string.prevent_phone_from_sleeping))
SettingsCheckBoxComponent(title = stringResource(id = com.simplemobiletools.calculator.R.string.use_comma_as_decimal_mark))
}
}
}
}
@MyDevices
@Composable
private fun SettingsScreenPreview() {
AppThemeSurface { SettingsScreen(goBack = {}, customizeColors = {}, backgroundColor = MaterialTheme.colorScheme.background.toArgb()) }
}

View File

@ -0,0 +1,75 @@
package com.simplemobiletools.calculator.compose.settings
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.simplemobiletools.calculator.compose.extensions.MyDevices
import com.simplemobiletools.calculator.compose.theme.AppThemeSurface
import com.simplemobiletools.calculator.compose.theme.preferenceSummaryColor
import com.simplemobiletools.calculator.compose.theme.preferenceTitleColor
@Composable
fun SettingsCheckBoxComponent(
modifier: Modifier = Modifier,
title: String,
summary: String? = null,
initialValue: Boolean = false,
isPreferenceEnabled: Boolean = true,
onChange: ((Boolean) -> Unit)? = null,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.fillMaxWidth()
.padding(vertical = 14.dp, horizontal = 16.dp),
) {
Column(
modifier = Modifier.weight(1f),
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(end = 16.dp),
text = title,
fontSize = 16.sp,
color = preferenceTitleColor(isEnabled = isPreferenceEnabled),
)
AnimatedVisibility(visible = !summary.isNullOrBlank()) {
Text(
text = summary.toString(),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp)
.padding(end = 16.dp),
fontSize = 14.sp,
color = preferenceSummaryColor(isEnabled = isPreferenceEnabled),
)
}
}
Checkbox(
checked = initialValue,
onCheckedChange = { onChange?.invoke(it) },
enabled = isPreferenceEnabled,
)
}
}
@MyDevices
@Composable
private fun SettingsCheckBoxComponentPreview() {
AppThemeSurface {
SettingsCheckBoxComponent(
title = "Some title",
summary = "Some summary",
)
}
}

View File

@ -0,0 +1,64 @@
package com.simplemobiletools.calculator.compose.settings
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.simplemobiletools.calculator.compose.extensions.MyDevices
@Composable
fun SettingsGroup(
modifier: Modifier = Modifier,
title: @Composable (() -> Unit)? = null,
content: @Composable ColumnScope.() -> Unit,
) {
Surface {
Column(
modifier = modifier.fillMaxWidth(),
) {
if (title != null) {
SettingsGroupTitle(title)
}
content()
}
}
}
@Composable
internal fun SettingsGroupTitle(title: @Composable () -> Unit) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.padding(horizontal = 16.dp),
contentAlignment = Alignment.CenterStart
) {
val primary = MaterialTheme.colorScheme.primary
val titleStyle = MaterialTheme.typography.headlineMedium.copy(color = primary)
ProvideTextStyle(value = titleStyle) { title() }
}
}
@MyDevices
@Composable
private fun SettingsGroupPreview() {
MaterialTheme {
SettingsGroup(
title = { Text(text = "Title") }
) {
Box(
modifier = Modifier
.height(64.dp)
.fillMaxWidth(),
contentAlignment = Alignment.Center,
) {
Text(text = "Settings group")
}
}
}
}

View File

@ -0,0 +1,68 @@
package com.simplemobiletools.calculator.compose.settings
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.simplemobiletools.calculator.compose.extensions.MyDevices
import com.simplemobiletools.calculator.compose.theme.AppThemeSurface
import com.simplemobiletools.calculator.compose.theme.preferenceSummaryColor
import com.simplemobiletools.calculator.compose.theme.preferenceTitleColor
import com.simplemobiletools.commons.R
@Composable
fun SettingsPreferenceComponent(
modifier: Modifier = Modifier,
preferenceTitle: String,
preferenceSummary: String? = null,
isPreferenceEnabled: Boolean = true,
doOnPreferenceLongClick: (() -> Unit)? = null,
doOnPreferenceClick: (() -> Unit)? = null,
) {
Column(
modifier = modifier
.fillMaxWidth()
.combinedClickable(
enabled = isPreferenceEnabled,
onClick = { doOnPreferenceClick?.invoke() },
onLongClick = { doOnPreferenceLongClick?.invoke() },
)
.padding(vertical = 14.dp, horizontal = 16.dp),
) {
Text(
text = preferenceTitle,
modifier = Modifier.fillMaxWidth(),
fontSize = 16.sp,
color = preferenceTitleColor(isEnabled = isPreferenceEnabled),
)
AnimatedVisibility(visible = !preferenceSummary.isNullOrBlank()) {
Text(
text = preferenceSummary.toString(),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
fontSize = 14.sp,
color = preferenceSummaryColor(isEnabled = isPreferenceEnabled),
)
}
}
}
@MyDevices
@Composable
private fun SettingsPreferencePreview() {
AppThemeSurface {
SettingsPreferenceComponent(
preferenceTitle = stringResource(id = R.string.language),
preferenceSummary = stringResource(id = R.string.translation_english),
isPreferenceEnabled = true,
)
}
}

View File

@ -0,0 +1,38 @@
package com.simplemobiletools.calculator.compose.settings
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.simplemobiletools.calculator.compose.extensions.MyDevices
import com.simplemobiletools.calculator.compose.theme.AppThemeSurface
@Composable
fun SettingsTitleTextComponent(
modifier: Modifier = Modifier,
text: String,
) {
Box(modifier = Modifier.padding(top = 24.dp, bottom = 8.dp)) {
Text(
text = text.uppercase(),
modifier = modifier,
fontWeight = FontWeight(300),
color = MaterialTheme.colorScheme.primary,
fontSize = with(LocalDensity.current) {
dimensionResource(id = com.simplemobiletools.commons.R.dimen.normal_text_size).toSp()
},
)
}
}
@MyDevices
@Composable
private fun SettingsTitleTextComponentPreview() = AppThemeSurface {
SettingsTitleTextComponent(text = "Color customization")
}

View File

@ -0,0 +1,103 @@
package com.simplemobiletools.calculator.compose.theme
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.HIGHER_ALPHA
val primaryColor = Color(0xFFF57C00)
val secondaryColor = Color(0xFFD76D00)
val tertiaryColor = primaryColor
private val DarkColorScheme = darkColorScheme(
primary = primaryColor,
secondary = secondaryColor,
tertiary = tertiaryColor,
)
private val LightColorScheme = lightColorScheme(
primary = primaryColor,
secondary = secondaryColor,
tertiary = tertiaryColor,
)
@get:ReadOnlyComposable
val disabledTextColor @Composable get() = if (isSystemInDarkTheme()) Color.DarkGray else Color.LightGray
@get:ReadOnlyComposable
val textSubTitleColor
@Composable get() = if (isSystemInDarkTheme()) {
Color.White.copy(0.5f)
} else {
Color.Black.copy(
0.5f,
)
}
@Composable
fun preferenceSummaryColor(isEnabled: Boolean) =
if (isEnabled) textSubTitleColor else disabledTextColor
@Composable
fun preferenceTitleColor(isEnabled: Boolean) = if (isEnabled) Color.Unspecified else disabledTextColor
@Composable
fun Theme(
useTransparentNavigation: Boolean = true,
properBackgroundColor: Int,
content: @Composable () -> Unit,
statusBarColor: Int,
) {
//todo
val context = LocalContext.current
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
if (context.navigationBarHeight > 0 || context.isUsingGestureNavigation() && useTransparentNavigation) {
systemUiController.isNavigationBarVisible = false
}
systemUiController.setStatusBarColor(
color = Color(statusBarColor)
)
systemUiController.setNavigationBarColor(Color(properBackgroundColor.adjustAlpha(HIGHER_ALPHA)))
}
MaterialTheme(
colorScheme = DarkColorScheme,
content = content,
)
}
@Composable
fun AppThemeSurface(
modifier: Modifier = Modifier,
properBackgroundColor: Int = LocalContext.current.getProperBackgroundColor(),
backgroundColor: Int = MaterialTheme.colorScheme.background.toArgb(),
statusBarColor: Int = LocalContext.current.getProperStatusBarColor(),
content: @Composable () -> Unit,
) {
Theme(properBackgroundColor = properBackgroundColor, content = {
Surface(
modifier = modifier
.fillMaxSize()
.background(Color(backgroundColor))
) {
content()
}
}, statusBarColor = statusBarColor)
}

View File

@ -4,6 +4,7 @@ import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.calculator.R
import com.simplemobiletools.calculator.activities.SimpleActivity
import com.simplemobiletools.calculator.adapters.HistoryAdapter
import com.simplemobiletools.calculator.databinding.DialogHistoryBinding
import com.simplemobiletools.calculator.extensions.calculatorDB
import com.simplemobiletools.calculator.helpers.CalculatorImpl
import com.simplemobiletools.calculator.models.History
@ -11,28 +12,28 @@ import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import kotlinx.android.synthetic.main.dialog_history.view.*
class HistoryDialog(activity: SimpleActivity, items: List<History>, calculator: CalculatorImpl) {
var dialog: AlertDialog? = null
private var dialog: AlertDialog? = null
init {
val view = activity.layoutInflater.inflate(R.layout.dialog_history, null)
val view = DialogHistoryBinding.inflate(activity.layoutInflater, null, false)
activity.getAlertDialogBuilder()
.setPositiveButton(R.string.ok, null)
.setPositiveButton(com.simplemobiletools.commons.R.string.ok, null)
.setNeutralButton(R.string.clear_history) { _, _ ->
ensureBackgroundThread {
activity.applicationContext.calculatorDB.deleteHistory()
activity.toast(R.string.history_cleared)
}
}.apply {
activity.setupDialogStuff(view, this, R.string.history) { alertDialog ->
activity.setupDialogStuff(view.root, this, R.string.history) { alertDialog ->
dialog = alertDialog
}
}
view.history_list.adapter = HistoryAdapter(activity, items, calculator) {
view.historyList.adapter = HistoryAdapter(activity, items, calculator) {
dialog?.dismiss()
}
}

View File

@ -0,0 +1,10 @@
package com.simplemobiletools.calculator.extensions
import android.app.Activity
import android.view.LayoutInflater
import androidx.viewbinding.ViewBinding
inline fun <T : ViewBinding> Activity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) =
lazy(LazyThreadSafetyMode.NONE) {
bindingInflater.invoke(layoutInflater)
}

View File

@ -281,7 +281,7 @@ class CalculatorImpl(
}
if (result.isInfinite() || result.isNaN()) {
context.toast(R.string.unknown_error_occurred)
context.toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
return
}
@ -295,7 +295,7 @@ class CalculatorImpl(
inputDisplayedFormula = result.format()
baseValue = result
} catch (e: Exception) {
context.toast(R.string.unknown_error_occurred)
context.toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
}
}
}

View File

@ -1,29 +0,0 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

5
build.gradle.kts Normal file
View File

@ -0,0 +1,5 @@
plugins {
alias(libs.plugins.android).apply(false)
alias(libs.plugins.kotlinAndroid).apply(false)
alias(libs.plugins.ksp).apply(false)
}

View File

@ -1,20 +1,12 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.enableJetifier=true
org.gradle.jvmargs=-Xmx4g -XX:+UseGCOverheadLimit -XX:GCTimeLimit=10 -Dfile.encoding=UTF-8 -XX:+UseParallelGC
org.gradle.workers.max=8
kotlin.code.style=official
android.useAndroidX=true
android.enableJetifier=true
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.vfs.watch=true
org.gradle.configureondemand=true
org.gradle.unsafe.configuration-cache=true
org.gradle.unsafe.configuration-cache-problems=warn
android.nonTransitiveRClass=true

93
gradle/libs.versions.toml Normal file
View File

@ -0,0 +1,93 @@
[versions]
#jetbrains
kotlin = "1.8.21"
#KSP
ksp = "1.8.21-1.0.11"
#Androidx
androidx-customView = "1.2.0-alpha02"
androidx-customViewPooling = "1.0.0"
#Compose
composeActivity = "1.8.0-alpha06"
compose = "1.6.0-alpha01"
composeCompiler = "1.4.7"
composeMaterial3 = "1.2.0-alpha03"
accompanist = "0.31.4-beta"
#AutoFitTextView
autofittextview = "0.2.1"
#exp4j
exp4j = "0.4.8"
#Room
room = "2.5.2"
#Simple tools
simple-commons = "4c83ec8740"
#Gradle
gradlePlugins-agp = "7.3.1"
#build
app-build-compileSDKVersion = "34"
app-build-targetSDK = "33"
app-build-minimumSDK = "23"
app-build-javaVersion = "VERSION_17"
app-build-kotlinJVMTarget = "17"
#versioning
app-version-appId = "com.simplemobiletools.calculator"
app-version-versionCode = "60"
app-version-versionName = "5.11.3"
[libraries]
#Android X
androidx-customView = { module = "androidx.customview:customview", version.ref = "androidx-customView" }
androidx-customViewPooling = { module = "androidx.customview:customview-poolingcontainer", version.ref = "androidx-customViewPooling" }
#Room
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
#Compose
compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial3" }
compose-material2 = { module = "androidx.compose.material:material", version.ref = "compose" }
compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" }
compose-animation = { module = "androidx.compose.animation:animation", version.ref = "compose" }
compose-activity = { module = "androidx.activity:activity-compose", version.ref = "composeActivity" }
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" }
compose-uiTooling-debug = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
compose-uiTooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
#UI
auto-fit-text-view = { module = "me.grantland:autofittextview", version.ref = "autofittextview" }
#Simple Mobile Tools
simple-tools-commons = { module = "com.github.SimpleMobileTools:Simple-Commons", version.ref = "simple-commons" }
#Exp4j
exp4j = { module = "net.objecthunter:exp4j", version.ref = "exp4j" }
#Accompanist
accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
[bundles]
compose = [
"compose-activity",
"compose-animation",
"compose-compiler",
"compose-foundation",
"compose-material-icons",
"compose-material3",
"compose-runtime",
"compose-ui",
"compose-uiTooling-preview",
]
compose-preview = [
"androidx-customView",
"androidx-customViewPooling",
"compose-uiTooling-debug",
]
room = [
"androidx-room-ktx",
"androidx-room-runtime",
]
accompanist = [
"accompanist-systemuicontroller",
]
[plugins]
android = { id = "com.android.application", version.ref = "gradlePlugins-agp" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip

View File

@ -1 +0,0 @@
include ':app'

16
settings.gradle.kts Normal file
View File

@ -0,0 +1,16 @@
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { setUrl("https://jitpack.io") }
}
}
include(":app")