Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new vertical digital clock widget #548

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@
</intent-filter>
</activity>

<activity
android:name=".activities.WidgetVerticalDigitalConfigureActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/MyWidgetConfigTheme">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>

<activity
android:name=".activities.WidgetAnalogueConfigureActivity"
android:exported="true"
Expand Down Expand Up @@ -194,6 +204,21 @@
android:resource="@xml/widget_digital_clock_info" />
</receiver>

<receiver
android:name=".helpers.MyVerticalDigitalTimeWidgetProvider"
android:exported="true"
android:label="@string/vertical_digital_clock">

<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
</intent-filter>

<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_vertical_digital_clock_info" />
</receiver>

<receiver
android:name=".helpers.MyAnalogueTimeWidgetProvider"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package com.simplemobiletools.clock.activities

import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.widget.SeekBar
import com.simplemobiletools.clock.databinding.WidgetConfigVerticalDigitalBinding
import com.simplemobiletools.clock.extensions.config
import com.simplemobiletools.clock.helpers.MyVerticalDigitalTimeWidgetProvider
import com.simplemobiletools.clock.helpers.SIMPLE_PHONE
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

class WidgetVerticalDigitalConfigureActivity : SimpleActivity() {
private var mBgAlpha = 0f
private var mWidgetId = 0
private var mBgColor = 0
private var mTextColor = 0
private var mBgColorWithoutTransparency = 0
private var mFeatureLockedDialog: FeatureLockedDialog? = null
private val binding: WidgetConfigVerticalDigitalBinding by viewBinding(WidgetConfigVerticalDigitalBinding::inflate)

public override fun onCreate(savedInstanceState: Bundle?) {
useDynamicTheme = false
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED)
setContentView(binding.root)
initVariables()

mWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID

if (!config.wasInitialWidgetSetUp && Build.BRAND.equals(SIMPLE_PHONE, true)) {
saveConfig()
config.wasInitialWidgetSetUp = true
return
}

val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID && !isCustomizingColors) {
finish()
}

binding.configDigitalSave.setOnClickListener { saveConfig() }
binding.configDigitalBgColor.setOnClickListener { pickBackgroundColor() }
binding.configDigitalTextColor.setOnClickListener { pickTextColor() }

val primaryColor = getProperPrimaryColor()
binding.configDigitalBgSeekbar.setColors(mTextColor, primaryColor, primaryColor)

if (!isCustomizingColors && !isOrWasThankYouInstalled()) {
mFeatureLockedDialog = FeatureLockedDialog(this) {
if (!isOrWasThankYouInstalled()) {
finish()
}
}
}
}

override fun onResume() {
super.onResume()
if (mFeatureLockedDialog != null && isOrWasThankYouInstalled()) {
mFeatureLockedDialog?.dismissDialog()
}
}

private fun initVariables() {
mBgColor = config.widgetBgColor
mBgAlpha = Color.alpha(mBgColor) / 255.toFloat()
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))

binding.configDigitalBgSeekbar.setOnSeekBarChangeListener(bgSeekbarChangeListener)
binding.configDigitalBgSeekbar.progress = (mBgAlpha * 100).toInt()
updateBackgroundColor()

mTextColor = config.widgetTextColor
if (mTextColor == resources.getColor(com.simplemobiletools.commons.R.color.default_widget_text_color) && config.isUsingSystemTheme) {
mTextColor = resources.getColor(com.simplemobiletools.commons.R.color.you_primary_color, theme)
}

updateTextColor()
}

private fun saveConfig() {
storeWidgetColors()
requestWidgetUpdate()

Intent().apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
setResult(Activity.RESULT_OK, this)
}
finish()
}

private fun storeWidgetColors() {
config.apply {
widgetBgColor = mBgColor
widgetTextColor = mTextColor
}
}

private fun pickBackgroundColor() {
ColorPickerDialog(this, mBgColorWithoutTransparency) { wasPositivePressed, color ->
if (wasPositivePressed) {
mBgColorWithoutTransparency = color
updateBackgroundColor()
}
}
}

private fun pickTextColor() {
ColorPickerDialog(this, mTextColor) { wasPositivePressed, color ->
if (wasPositivePressed) {
mTextColor = color
updateTextColor()
}
}
}

private fun requestWidgetUpdate() {
Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyVerticalDigitalTimeWidgetProvider::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId))
sendBroadcast(this)
}
}

private fun updateTextColor() {
binding.configDigitalTextColor.setFillWithStroke(mTextColor, mTextColor)
binding.configDigitalTimeHour.setTextColor(mTextColor)
binding.configDigitalTimeMinute.setTextColor(mTextColor)
binding.configDigitalDate.setTextColor(mTextColor)
binding.configDigitalSave.setTextColor(getProperPrimaryColor().getContrastColor())
}

private fun updateBackgroundColor() {
mBgColor = mBgColorWithoutTransparency.adjustAlpha(mBgAlpha)
binding.configDigitalBgColor.setFillWithStroke(mBgColor, mBgColor)
binding.configDigitalBackground.applyColorFilter(mBgColor)
binding.configDigitalSave.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
}

private val bgSeekbarChangeListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
mBgAlpha = progress.toFloat() / 100.toFloat()
updateBackgroundColor()
}

override fun onStartTrackingTouch(seekBar: SeekBar) {}

override fun onStopTrackingTouch(seekBar: SeekBar) {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.simplemobiletools.clock.helpers

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.*
import android.os.Bundle
import android.widget.RemoteViews
import com.simplemobiletools.clock.R
import com.simplemobiletools.clock.activities.SplashActivity
import com.simplemobiletools.clock.extensions.config
import com.simplemobiletools.clock.extensions.getClosestEnabledAlarmString
import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.getLaunchIntent
import com.simplemobiletools.commons.extensions.setText
import com.simplemobiletools.commons.extensions.setVisibleIf

class MyVerticalDigitalTimeWidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
performUpdate(context)
}

private fun performUpdate(context: Context) {
val appWidgetManager = AppWidgetManager.getInstance(context) ?: return
context.getClosestEnabledAlarmString { nextAlarm ->
appWidgetManager.getAppWidgetIds(getComponentName(context)).forEach {
RemoteViews(context.packageName, R.layout.widget_vertical_digital).apply {
updateTexts(context, this, nextAlarm)
updateColors(context, this)
setupAppOpenIntent(context, this)
appWidgetManager.updateAppWidget(it, this)
}
}
}
}

private fun updateTexts(context: Context, views: RemoteViews, nextAlarm: String) {
views.apply {
setText(R.id.widget_next_alarm, nextAlarm)
setVisibleIf(R.id.widget_alarm_holder, nextAlarm.isNotEmpty())
}
}

private fun updateColors(context: Context, views: RemoteViews) {
val config = context.config
val widgetTextColor = config.widgetTextColor

views.apply {
applyColorFilter(R.id.widget_background, config.widgetBgColor)
setTextColor(R.id.widget_text_clock_hour, widgetTextColor)
setTextColor(R.id.widget_text_clock_minute, widgetTextColor)
setTextColor(R.id.widget_date, widgetTextColor)
setTextColor(R.id.widget_next_alarm, widgetTextColor)

val bitmap = getMultiplyColoredBitmap(R.drawable.ic_clock_shadowed, widgetTextColor, context)
setImageViewBitmap(R.id.widget_next_alarm_image, bitmap)
}
}

private fun getComponentName(context: Context) = ComponentName(context, this::class.java)

private fun setupAppOpenIntent(context: Context, views: RemoteViews) {
(context.getLaunchIntent() ?: Intent(context, SplashActivity::class.java)).apply {
putExtra(OPEN_TAB, TAB_CLOCK)
val pendingIntent = PendingIntent.getActivity(context, OPEN_APP_INTENT_ID, this, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
views.setOnClickPendingIntent(R.id.widget_date_time_holder, pendingIntent)
}
}

override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle?) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
performUpdate(context)
}

private fun getMultiplyColoredBitmap(resourceId: Int, newColor: Int, context: Context): Bitmap {
val options = BitmapFactory.Options()
options.inMutable = true
val bmp = BitmapFactory.decodeResource(context.resources, resourceId, options)
val paint = Paint()
val filter = PorterDuffColorFilter(newColor, PorterDuff.Mode.MULTIPLY)
paint.colorFilter = filter
val canvas = Canvas(bmp)
canvas.drawBitmap(bmp, 0f, 0f, paint)
return bmp
}
}
Loading