diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt b/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt index d1a424d..f6953ab 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/helper/PreferenceHelper.kt @@ -34,6 +34,14 @@ class PreferenceHelper @Inject constructor(@ApplicationContext context: Context) get() = prefs.getBoolean(Constants.SHOW_DAILY_WORD, false) set(value) = prefs.edit().putBoolean(Constants.SHOW_DAILY_WORD, value).apply() + var showWeatherWidget: Boolean + get() = prefs.getBoolean(Constants.SHOW_WEATHER_WIDGET, false) + set(value) = prefs.edit().putBoolean(Constants.SHOW_WEATHER_WIDGET, value).apply() + + var showBatteryWidget: Boolean + get() = prefs.getBoolean(Constants.SHOW_BATTERY_WIDGET, false) + set(value) = prefs.edit().putBoolean(Constants.SHOW_BATTERY_WIDGET, value).apply() + var dateColor: Int get() = prefs.getInt(Constants.DATE_COLOR, 0xFFFFFFFF.toInt()) set(value) = prefs.edit().putInt(Constants.DATE_COLOR, value).apply() @@ -114,6 +122,14 @@ class PreferenceHelper @Inject constructor(@ApplicationContext context: Context) get() = prefs.getFloat(Constants.DAILY_WORD_TEXT_SIZE, 18f) set(value) = prefs.edit().putFloat(Constants.DAILY_WORD_TEXT_SIZE, value).apply() + var weatherOrderNumber: Int + get() = prefs.getInt(Constants.WIDGET_WEATHER, 1) + set(value) = prefs.edit().putInt(Constants.WIDGET_WEATHER, value).apply() + + var batteryOrderNumber: Int + get() = prefs.getInt(Constants.WIDGET_BATTERY, 2) + set(value) = prefs.edit().putInt(Constants.WIDGET_BATTERY, value).apply() + var settingsLock: Boolean get() = prefs.getBoolean(Constants.TOGGLE_SETTING_LOCK, false) set(value) = prefs.edit().putBoolean(Constants.TOGGLE_SETTING_LOCK, value).apply() diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/numberpicker/NumberPickerAdapter.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/numberpicker/NumberPickerAdapter.kt new file mode 100644 index 0000000..6b9a1eb --- /dev/null +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/numberpicker/NumberPickerAdapter.kt @@ -0,0 +1,36 @@ +package com.github.droidworksstudio.launcher.ui.numberpicker + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.github.droidworksstudio.launcher.R + +class NumberPickerAdapter( + private val numbers: List, + private val onNumberSelected: (Int) -> Unit +) : RecyclerView.Adapter() { + + inner class NumberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val numberText: TextView = itemView.findViewById(R.id.number_text) + + init { + itemView.setOnClickListener { + onNumberSelected(numbers[adapterPosition]) + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NumberViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item_number, parent, false) + return NumberViewHolder(view) + } + + override fun onBindViewHolder(holder: NumberViewHolder, position: Int) { + holder.numberText.text = numbers[position].toString() + } + + override fun getItemCount(): Int = numbers.size +} diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/WidgetFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/WidgetFragment.kt index f9acfc9..4f1df25 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/WidgetFragment.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/WidgetFragment.kt @@ -12,6 +12,8 @@ import android.graphics.drawable.GradientDrawable import android.os.BatteryManager import android.os.Build import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.util.Log import android.view.LayoutInflater import android.view.View @@ -22,6 +24,7 @@ import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController +import androidx.navigation.NavOptions import androidx.navigation.fragment.findNavController import com.github.droidworksstudio.common.capitalizeEachWord import com.github.droidworksstudio.common.hasInternetPermission @@ -34,12 +37,17 @@ import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener import com.github.droidworksstudio.launcher.listener.ScrollEventListener import com.github.droidworksstudio.launcher.utils.Constants import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale import javax.inject.Inject +import kotlin.math.absoluteValue + @AndroidEntryPoint class WidgetFragment : Fragment(), @@ -74,6 +82,7 @@ class WidgetFragment : Fragment(), super.onViewCreated(view, savedInstanceState) initializeInjectedDependencies() + orderWidgetsBySettings() setupWeatherWidget() setupBatteryWidget() observeSwipeTouchListener() @@ -83,10 +92,36 @@ class WidgetFragment : Fragment(), private fun initializeInjectedDependencies() { context = requireContext() binding.nestScrollView.hideKeyboard() -// + binding.nestScrollView.scrollEventListener = this } + private fun orderWidgetsBySettings() { + val linearLayout = binding.linearLayoutContainer + + // Find RelativeLayouts by their IDs + val weatherRoot = binding.weatherRoot + val batteryRoot = binding.batteryRoot + + // Order the list of layouts + val orderList = listOf( + Pair(weatherRoot, preferenceHelper.weatherOrderNumber), + Pair(batteryRoot, preferenceHelper.batteryOrderNumber) + ) + + // Sort the list based on the second value of the pairs (the order number) + val sortedOrderList = orderList.sortedBy { it.second } + + // Remove all views from the LinearLayout + linearLayout.removeAllViews() + + // Add the RelativeLayouts back in the sorted order + for ((relativeLayout, _) in sortedOrderList) { + linearLayout.addView(relativeLayout) + } + + } + private fun setupWeatherWidget() { val sharedPreferences = context.getSharedPreferences(Constants.WEATHER_PREFS, Context.MODE_PRIVATE) @@ -94,41 +129,58 @@ class WidgetFragment : Fragment(), val longitude = sharedPreferences.getFloat(Constants.LONGITUDE, 0f) val timestamp = convertTimestampToReadableDate(sharedPreferences.getLong("cachedDataTimestamp", 0)) + // Pre-fetch preferences + val showWeatherWidget = preferenceHelper.showWeatherWidget + val temperatureScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.widget_c) else getString( + R.string.widget_f + ) + val speedScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.widget_weather_mps) else getString(R.string.widget_weather_mph) + val widgetTextColor = preferenceHelper.widgetTextColor + val widgetBackgroundColor = preferenceHelper.widgetBackgroundColor + lifecycleScope.launch { + if (!showWeatherWidget || !context.hasInternetPermission()) return@launch + try { - if (!context.hasInternetPermission()) return@launch - binding.weatherRoot.visibility = View.VISIBLE - val weatherResponse = appHelper.fetchWeatherData(context, latitude, longitude) + val weatherDeferred = async { appHelper.fetchWeatherData(context, latitude, longitude) } + + // Prepare UI elements concurrently + withContext(Dispatchers.Main) { + binding.apply { + weatherCity.setTextColor(widgetTextColor) + weatherTemperature.setTextColor(widgetTextColor) + weatherDescription.setTextColor(widgetTextColor) + weatherWind.setTextColor(widgetTextColor) + weatherHumidity.setTextColor(widgetTextColor) + weatherRefresh.setTextColor(widgetTextColor) + weatherLastRun.setTextColor(widgetTextColor) + weatherRefresh.typeface = ResourcesCompat.getFont(requireActivity(), R.font.weather) + } + } + + val weatherResponse = weatherDeferred.await() Log.d("weatherResponse", "$weatherResponse") - val temperatureScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.widget_c) else getString( - R.string.widget_f - ) - val speedScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.widget_weather_mps) else getString(R.string.widget_weather_mph) - binding.weatherCity.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherTemperature.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherDescription.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherWind.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherHumidity.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherRefresh.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherLastRun.setTextColor(preferenceHelper.widgetTextColor) - binding.weatherRefresh.typeface = ResourcesCompat.getFont(requireActivity(), R.font.weather) + withContext(Dispatchers.Main) { + binding.apply { + weatherCity.text = getString(R.string.widget_weather_location, weatherResponse.name, weatherResponse.sys.country) + weatherTemperature.text = getString(R.string.widget_weather_temp, weatherResponse.main.temp, temperatureScale) + weatherDescription.text = getString(R.string.widget_weather_description, weatherResponse.weather[0].description).capitalizeEachWord() + weatherWind.text = getString(R.string.widget_weather_wind, weatherResponse.wind.speed, speedScale) + weatherHumidity.text = getString(R.string.widget_weather_humidity, weatherResponse.main.humidity) + weatherLastRun.text = timestamp + weatherRefresh.text = getString(R.string.widget_weather_refresh, getString(R.string.refresh_icon)) - binding.weatherCity.text = getString(R.string.widget_weather_location, weatherResponse.name, weatherResponse.sys.country) - binding.weatherTemperature.text = getString(R.string.widget_weather_temp, weatherResponse.main.temp, temperatureScale) - binding.weatherDescription.text = getString(R.string.widget_weather_description, weatherResponse.weather[0].description).capitalizeEachWord() - binding.weatherWind.text = getString(R.string.widget_weather_wind, weatherResponse.wind.speed, speedScale) - binding.weatherHumidity.text = getString(R.string.widget_weather_humidity, weatherResponse.main.humidity) - binding.weatherLastRun.text = timestamp - binding.weatherRefresh.text = getString(R.string.widget_weather_refresh, getString(R.string.refresh_icon)) + val weatherIconBitmap = createWeatherIcon(context, setWeatherIcon(context, weatherResponse.weather[0].id)) + weatherIcon.setImageBitmap(weatherIconBitmap) // Ensure this matches your ImageView ID + weatherIcon.setColorFilter(widgetTextColor) - val weatherIcon = createWeatherIcon(context, setWeatherIcon(context, weatherResponse.weather[0].id)) - binding.weatherIcon.setImageBitmap(weatherIcon) - binding.weatherIcon.setColorFilter(preferenceHelper.widgetTextColor) - - val weatherWidgetDrawable = binding.weatherRoot.background - if (weatherWidgetDrawable is GradientDrawable) { - weatherWidgetDrawable.setColor(preferenceHelper.widgetBackgroundColor) + val weatherWidgetDrawable = weatherRoot.background + if (weatherWidgetDrawable is GradientDrawable) { + weatherWidgetDrawable.setColor(widgetBackgroundColor) + } + weatherRoot.visibility = View.VISIBLE + } } } catch (e: Exception) { Log.e("Weather", "Failed to fetch weather data: ${e.message}") @@ -136,6 +188,7 @@ class WidgetFragment : Fragment(), } } + private fun createWeatherIcon(context: Context, text: String): Bitmap { val bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) @@ -183,37 +236,45 @@ class WidgetFragment : Fragment(), } private fun setupBatteryWidget() { - try { - binding.batteryLevel.setTextColor(preferenceHelper.widgetTextColor) - binding.batteryCount.setTextColor(preferenceHelper.widgetTextColor) - binding.chargingStatus.setTextColor(preferenceHelper.widgetTextColor) - binding.batteryHealth.setTextColor(preferenceHelper.widgetTextColor) - binding.batteryVoltage.setTextColor(preferenceHelper.widgetTextColor) - binding.batteryTemperature.setTextColor(preferenceHelper.widgetTextColor) + lifecycleScope.launch { + if (!preferenceHelper.showBatteryWidget) return@launch + try { + binding.batteryLevel.setTextColor(preferenceHelper.widgetTextColor) + binding.batteryCount.setTextColor(preferenceHelper.widgetTextColor) + binding.chargingStatus.setTextColor(preferenceHelper.widgetTextColor) + binding.batteryHealth.setTextColor(preferenceHelper.widgetTextColor) + binding.batteryCurrent.setTextColor(preferenceHelper.widgetTextColor) + binding.batteryVoltage.setTextColor(preferenceHelper.widgetTextColor) + binding.batteryTemperature.setTextColor(preferenceHelper.widgetTextColor) - val weatherBatteryDrawable = binding.batteryRoot.background - if (weatherBatteryDrawable is GradientDrawable) { - weatherBatteryDrawable.setColor(preferenceHelper.widgetBackgroundColor) + val weatherBatteryDrawable = binding.batteryRoot.background + if (weatherBatteryDrawable is GradientDrawable) { + weatherBatteryDrawable.setColor(preferenceHelper.widgetBackgroundColor) + } + binding.batteryRoot.visibility = View.VISIBLE + } catch (e: Exception) { + Log.e("Battery", "Failed to fetch battery data: ${e.message}") } - } catch (e: Exception) { - Log.e("Battery", "Failed to fetch battery data: ${e.message}") } - binding.batteryRoot.visibility = View.VISIBLE } private val batteryReceiver = object : BroadcastReceiver() { @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) override fun onReceive(context: Context?, intent: Intent?) { + val batteryManager = requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager if (intent?.action == Intent.ACTION_BATTERY_CHANGED) { val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1) val isCharging = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) val health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN) val count = intent.getIntExtra(BatteryManager.EXTRA_CYCLE_COUNT, 0) + val current = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW) val voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0) val temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) + val temperatureCelsius = temperature / 10.0 val voltageScale = getString(R.string.widget_mv) + val currentScale = getString(R.string.widget_ma) val temperatureScale = getString(R.string.widget_c) val batteryPct = (level / scale.toFloat() * 100).toInt() @@ -236,7 +297,8 @@ class WidgetFragment : Fragment(), binding.chargingStatus.text = getString(R.string.widgets_battery_status, chargingStatusText) binding.batteryHealth.text = getString(R.string.widgets_battery_health, healthStatus) binding.batteryVoltage.text = getString(R.string.widgets_battery_voltage, voltage, voltageScale) - binding.batteryTemperature.text = getString(R.string.widgets_battery_temperature, temperature, temperatureScale) + binding.batteryCurrent.text = getString(R.string.widgets_battery_current, current, currentScale) + binding.batteryTemperature.text = getString(R.string.widgets_battery_temperature, temperatureCelsius, temperatureScale) } } } @@ -250,6 +312,20 @@ class WidgetFragment : Fragment(), private fun getSwipeGestureListener(context: Context): View.OnTouchListener { return object : OnSwipeTouchListener(context) { + override fun onLongClick() { + super.onLongClick() + val actionTypeNavOptions: NavOptions = + appHelper.getActionType(Constants.Swipe.DoubleTap) + Handler(Looper.getMainLooper()).post { + findNavController().navigate( + R.id.action_WidgetsFragment_to_WidgetsSettingsFragment, + null, + actionTypeNavOptions + ) + } + return + } + override fun onSwipeLeft() { super.onSwipeLeft() findNavController().popBackStack() diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/settings/SettingsFragment.kt b/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/settings/SettingsFragment.kt new file mode 100644 index 0000000..fa6f074 --- /dev/null +++ b/app/src/main/java/com/github/droidworksstudio/launcher/ui/widgets/settings/SettingsFragment.kt @@ -0,0 +1,187 @@ +package com.github.droidworksstudio.launcher.ui.widgets.settings + +import android.annotation.SuppressLint +import android.content.Context +import android.content.DialogInterface +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.navigation.NavController +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.github.droidworksstudio.launcher.R +import com.github.droidworksstudio.launcher.databinding.FragmentSettingsWidgetsBinding +import com.github.droidworksstudio.launcher.helper.AppHelper +import com.github.droidworksstudio.launcher.helper.PreferenceHelper +import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener +import com.github.droidworksstudio.launcher.listener.ScrollEventListener +import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.ColorBottomSheetDialogFragment +import com.github.droidworksstudio.launcher.ui.numberpicker.NumberPickerAdapter +import com.github.droidworksstudio.launcher.utils.Constants +import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject + +@AndroidEntryPoint +class SettingsFragment : Fragment(), + ScrollEventListener { + + private var _binding: FragmentSettingsWidgetsBinding? = null + private val binding get() = _binding!! + + private val preferenceViewModel: PreferenceViewModel by viewModels() + + @Inject + lateinit var preferenceHelper: PreferenceHelper + + @Inject + lateinit var appHelper: AppHelper + + private lateinit var navController: NavController + + private lateinit var context: Context + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + // Inflate the layout for this fragment + _binding = FragmentSettingsWidgetsBinding.inflate(inflater, container, false) + _binding = binding + + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + navController = findNavController() + // Set according to the system theme mode + appHelper.dayNightMod(requireContext(), binding.nestScrollView) + super.onViewCreated(view, savedInstanceState) + + context = requireContext() + + initializeInjectedDependencies() + observeClickListener() + observeSwipeTouchListener() + } + + private fun initializeInjectedDependencies() { + binding.nestScrollView.scrollEventListener = this + + // Set initial values and listeners for switches + binding.weatherSwitchCompat.isChecked = preferenceHelper.showWeatherWidget + binding.batterySwitchCompat.isChecked = preferenceHelper.showBatteryWidget + + binding.weatherOrderControl.text = preferenceHelper.weatherOrderNumber.toString() + binding.batteryOrderControl.text = preferenceHelper.batteryOrderNumber.toString() + } + + private fun observeClickListener() { + setupSwitchListeners() + + binding.weatherOrderControl.setOnClickListener { + showOrderChangeDialog(binding.weatherOrderControl) + } + + binding.batteryOrderControl.setOnClickListener { + showOrderChangeDialog(binding.batteryOrderControl) + } + + binding.selectBatteryWidgetColor.setOnClickListener { + val bottomSheetFragment = ColorBottomSheetDialogFragment() + bottomSheetFragment.show(parentFragmentManager, "BottomSheetDialog") + } + + binding.selectBatteryWidgetColor.setOnClickListener { + val bottomSheetFragment = ColorBottomSheetDialogFragment() + bottomSheetFragment.show(parentFragmentManager, "BottomSheetDialog") + } + } + + private fun setupSwitchListeners() { + binding.weatherSwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowWeatherWidget(isChecked) + } + + binding.batterySwitchCompat.setOnCheckedChangeListener { _, isChecked -> + preferenceViewModel.setShowBatteryWidget(isChecked) + } + } + + @SuppressLint("ClickableViewAccessibility") + private fun observeSwipeTouchListener() { + binding.touchArea.setOnTouchListener(getSwipeGestureListener(context)) + } + + private fun getSwipeGestureListener(context: Context): View.OnTouchListener { + return object : OnSwipeTouchListener(context) { + override fun onSwipeLeft() { + super.onSwipeLeft() + findNavController().popBackStack() + } + + override fun onSwipeRight() { + super.onSwipeRight() + findNavController().popBackStack() + } + + } + } + + @SuppressLint("InflateParams") + private fun showOrderChangeDialog(view: View) { + val numberPickerDialog = MaterialAlertDialogBuilder(context).create() + + val numberPickerView = layoutInflater.inflate(R.layout.item_number_picker, null) + val recyclerView = numberPickerView.findViewById(R.id.recycler_view) + recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + + val numbers = (1..Constants.WIDGETS_COUNT).toList() // Replace with your desired range + + when (view) { + binding.weatherOrderControl -> { + val adapter = NumberPickerAdapter(numbers) { selectedNumber -> + // Save the order number to SharedPreferences or ViewModel + preferenceViewModel.setWeatherOrderNumber(selectedNumber) + binding.weatherOrderControl.text = preferenceHelper.weatherOrderNumber.toString() + numberPickerDialog.dismiss() + } + + recyclerView.adapter = adapter + } + + binding.batteryOrderControl -> { + val adapter = NumberPickerAdapter(numbers) { selectedNumber -> + // Save the order number to SharedPreferences or ViewModel + preferenceViewModel.setBatteryOrderNumber(selectedNumber) + binding.batteryOrderControl.text = preferenceHelper.batteryOrderNumber.toString() + numberPickerDialog.dismiss() + } + + recyclerView.adapter = adapter + } + + else -> { + Log.d("showOrderChangeDialog", "else") + } + + } + + numberPickerDialog.apply { + setTitle("Change Order") + setView(numberPickerView) + setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel") { dialog, _ -> + dialog.dismiss() + } + } + + numberPickerDialog.show() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt b/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt index 8a3ef17..8fecec3 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/utils/Constants.kt @@ -8,6 +8,9 @@ object Constants { const val PACKAGE_NAME_DEBUG = "$PACKAGE_NAME.debug" const val WIDGETS_PREFS = "EasyLauncherWidgets.pref" + const val WIDGETS_COUNT = 2 + const val WIDGET_WEATHER = "WIDGET_WEATHER" + const val WIDGET_BATTERY = "WIDGET_BATTERY" const val WEATHER_PREFS = "EasyWeather.pref" const val LATITUDE = "LATITUDE" @@ -21,6 +24,9 @@ object Constants { const val SHOW_BATTERY = "SHOW_BATTERY" const val SHOW_STATUS_BAR = "SHOW_STATUS_BAR" + const val SHOW_WEATHER_WIDGET = "SHOW_WEATHER_WIDGET" + const val SHOW_BATTERY_WIDGET = "SHOW_BATTERY_WIDGET" + const val DATE_COLOR = "DATE_COLOR" const val TIME_COLOR = "TIME_COLOR" const val BATTERY_COLOR = "BATTERY_COLOR" diff --git a/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt b/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt index 6a4ec57..ee698ad 100644 --- a/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt +++ b/app/src/main/java/com/github/droidworksstudio/launcher/viewmodel/PreferenceViewModel.kt @@ -18,6 +18,8 @@ class PreferenceViewModel @Inject constructor( val showDateLiveData: MutableLiveData = MutableLiveData() val showDailyWordLiveData: MutableLiveData = MutableLiveData() val showBatteryLiveData: MutableLiveData = MutableLiveData() + private val showWeatherWidgetLiveData: MutableLiveData = MutableLiveData() + private val showBatteryWidgetLiveData: MutableLiveData = MutableLiveData() private val showAppIconLiveData: MutableLiveData = MutableLiveData() private val homeAppAlignmentLiveData: MutableLiveData = MutableLiveData() private val homeDateAlignmentLiveData: MutableLiveData = MutableLiveData() @@ -39,6 +41,9 @@ class PreferenceViewModel @Inject constructor( private val lockSettingsLiveData: MutableLiveData = MutableLiveData() private val appPaddingSizeLiveData: MutableLiveData = MutableLiveData() + private val weatherOrderNumberLiveData: MutableLiveData = MutableLiveData() + private val batteryOrderNumberLiveData: MutableLiveData = MutableLiveData() + private val searchEngineLiveData: MutableLiveData = MutableLiveData() private val doubleTapActionLiveData: MutableLiveData = MutableLiveData() private val swipeUpActionLiveData: MutableLiveData = MutableLiveData() @@ -86,11 +91,31 @@ class PreferenceViewModel @Inject constructor( dailyWordColorLiveData.postValue(preferenceHelper.dailyWordColor) } + fun setShowWeatherWidget(showWeather: Boolean) { + preferenceHelper.showWeatherWidget = showWeather + showWeatherWidgetLiveData.postValue(preferenceHelper.showWeatherWidget) + } + + fun setShowBatteryWidget(showBattery: Boolean) { + preferenceHelper.showBatteryWidget = showBattery + showBatteryWidgetLiveData.postValue(preferenceHelper.showBatteryWidget) + } + fun setAppColor(appColor: Int) { preferenceHelper.appColor = appColor appColorLiveData.postValue(preferenceHelper.appColor) } + fun setWeatherOrderNumber(orderNumber: Int) { + preferenceHelper.weatherOrderNumber = orderNumber + weatherOrderNumberLiveData.postValue(preferenceHelper.weatherOrderNumber) + } + + fun setBatteryOrderNumber(orderNumber: Int) { + preferenceHelper.batteryOrderNumber = orderNumber + batteryOrderNumberLiveData.postValue(preferenceHelper.batteryOrderNumber) + } + fun setDateColor(dateColor: Int) { preferenceHelper.dateColor = dateColor dateColorLiveData.postValue(preferenceHelper.dateColor) diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index ad68cad..54c27ff 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -21,7 +21,8 @@ android:fadingEdgeLength="48dp" android:overScrollMode="never" android:requiresFadingEdge="vertical" - android:scrollbars="none"> + android:scrollbars="none" + tools:ignore="TooManyViews"> + + + @@ -479,7 +483,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="20dp" - android:layout_marginBottom="20dp" + android:layout_marginVertical="10dp" android:orientation="horizontal" tools:ignore="MissingConstraints"> @@ -502,7 +506,7 @@ android:layout_width="match_parent" android:layout_height="28dp" android:layout_marginHorizontal="20dp" - android:layout_marginBottom="20dp" + android:layout_marginVertical="10dp" tools:ignore="MissingConstraints,TextSizeCheck"> + + + + + + + + + tools:ignore="MissingConstraints"> + + + + diff --git a/app/src/main/res/layout/fragment_settings_widgets.xml b/app/src/main/res/layout/fragment_settings_widgets.xml new file mode 100644 index 0000000..66bf173 --- /dev/null +++ b/app/src/main/res/layout/fragment_settings_widgets.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_widgets.xml b/app/src/main/res/layout/fragment_widgets.xml index b4c2aff..2982402 100644 --- a/app/src/main/res/layout/fragment_widgets.xml +++ b/app/src/main/res/layout/fragment_widgets.xml @@ -32,6 +32,7 @@ tools:ignore="SpeakableTextPresentCheck"> + + + diff --git a/app/src/main/res/layout/item_number_picker.xml b/app/src/main/res/layout/item_number_picker.xml new file mode 100644 index 0000000..333579a --- /dev/null +++ b/app/src/main/res/layout/item_number_picker.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index abb0ed1..96ac6db 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -41,7 +41,18 @@ android:id="@+id/WidgetsFragment" android:name="com.github.droidworksstudio.launcher.ui.widgets.WidgetFragment" android:label="@string/widgets_fragment_label" - tools:layout="@layout/fragment_widgets" /> + tools:layout="@layout/fragment_widgets"> + + + + + %s%% - mV + mV + mA °C °F diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b32b7df..e224cc5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,6 +29,7 @@ Launcher Settings %1$s Version: %2$s + Widgets Settings Display Behavior @@ -84,7 +85,6 @@ Swipe Left Swipe Right - Search Engine Share @@ -598,10 +598,14 @@ Battery Level : %d %% Battery Charge Count : %1$d + Battery Current : %1$d %2$s Charging Status : %1$s Battery Health : %1$s Battery Voltage : %1$d %2$s - Battery Temperature : %1$d %2$s - + Battery Temperature : %1.2f %2$s + Weather Widget + Battery Widget + Display + Select Order \ No newline at end of file