Added color copy/paste, better size and color text selection

This commit is contained in:
Tommaso Berlose 2021-05-07 17:19:23 +02:00
parent 1ac53e09a8
commit 5d07cc8d73
52 changed files with 460 additions and 75 deletions

View File

@ -22,8 +22,8 @@ android {
applicationId "com.tommasoberlose.anotherwidget" applicationId "com.tommasoberlose.anotherwidget"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 30 targetSdkVersion 30
versionCode 135 versionCode 136
versionName "2.3.1" versionName "2.3.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY']) buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])

View File

@ -3,40 +3,30 @@ package com.tommasoberlose.anotherwidget.components
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.GridLayout import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.SeekBar
import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuHorBinding import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuHorBinding
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuListBinding import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuListBinding
import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper.copyToClipboard
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isClipboardColor
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.utils.expand import com.tommasoberlose.anotherwidget.helpers.ColorHelper.pasteFromClipboard
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
import com.tommasoberlose.anotherwidget.utils.isDarkTheme import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import com.tommasoberlose.anotherwidget.utils.reveal
import com.tommasoberlose.anotherwidget.utils.toPixel
import com.warkiz.widget.IndicatorSeekBar import com.warkiz.widget.IndicatorSeekBar
import com.warkiz.widget.OnSeekChangeListener import com.warkiz.widget.OnSeekChangeListener
import com.warkiz.widget.SeekParams import com.warkiz.widget.SeekParams
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter import net.idik.lib.slimadapter.SlimAdapter
import java.lang.Exception
import java.util.prefs.Preferences
class BottomSheetColorPicker( class BottomSheetColorPicker(
context: Context, context: Context,
@ -46,20 +36,45 @@ class BottomSheetColorPicker(
private val onColorSelected: ((selectedValue: Int) -> Unit)? = null, private val onColorSelected: ((selectedValue: Int) -> Unit)? = null,
private val showAlphaSelector: Boolean = false, private val showAlphaSelector: Boolean = false,
private val alpha: Int = 0, private val alpha: Int = 0,
private val onAlphaChangeListener: ((alpha: Int) -> Unit)? = null private val onAlphaChangeListener: ((alpha: Int) -> Unit)? = null,
private val hideCopyPaste: Boolean = false,
) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { ) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private var loadingJobs: ArrayList<Job> = ArrayList() private var loadingJobs: ArrayList<Job> = ArrayList()
private lateinit var adapter: SlimAdapter private lateinit var adapter: SlimAdapter
private var alphaDebouncing: Job? = null
private var binding: BottomSheetMenuHorBinding = BottomSheetMenuHorBinding.inflate(LayoutInflater.from(context)) private var binding: BottomSheetMenuHorBinding = BottomSheetMenuHorBinding.inflate(LayoutInflater.from(context))
private var listBinding: BottomSheetMenuListBinding = BottomSheetMenuListBinding.inflate(LayoutInflater.from(context)) private var listBinding: BottomSheetMenuListBinding = BottomSheetMenuListBinding.inflate(LayoutInflater.from(context))
override fun show() { override fun show() {
window?.setDimAmount(0f)
// Header // Header
binding.header.isVisible = header != null binding.header.isVisible = header != null
binding.headerText.text = header ?: "" binding.headerText.text = header ?: ""
if (hideCopyPaste) {
binding.actionContainer.isVisible = false
} else {
binding.actionContainer.isVisible = true
binding.actionCopy.setOnClickListener {
context.copyToClipboard(getSelected?.invoke(), alpha)
}
binding.actionPaste.setOnClickListener {
context.pasteFromClipboard { color, alpha ->
binding.alphaSelector.setProgress(alpha.toIntValue().toFloat())
adapter.notifyItemChanged(adapter.data.indexOf(getSelected?.invoke()))
onColorSelected?.invoke(Color.parseColor(color))
val idx = colors.toList().indexOf(getSelected?.invoke())
adapter.notifyItemChanged(idx)
(listBinding.root.layoutManager as GridLayoutManager).scrollToPositionWithOffset(idx,0)
}
}
binding.actionPaste.isVisible = context.isClipboardColor()
}
// Alpha // Alpha
binding.alphaSelectorContainer.isVisible = showAlphaSelector binding.alphaSelectorContainer.isVisible = showAlphaSelector
binding.alphaSelector.setProgress(alpha.toFloat()) binding.alphaSelector.setProgress(alpha.toFloat())
@ -67,10 +82,17 @@ class BottomSheetColorPicker(
binding.alphaSelector.onSeekChangeListener = object : OnSeekChangeListener { binding.alphaSelector.onSeekChangeListener = object : OnSeekChangeListener {
override fun onSeeking(seekParams: SeekParams?) { override fun onSeeking(seekParams: SeekParams?) {
seekParams?.let { seekParams?.let {
binding.textAlpha.text = "%s: %s%%".format(context.getString(R.string.alpha), it.progress) binding.textAlpha.text =
"%s: %s%%".format(context.getString(R.string.alpha), it.progress)
alphaDebouncing?.cancel()
alphaDebouncing = GlobalScope.launch(Dispatchers.IO) {
delay(150)
withContext(Dispatchers.Main) {
onAlphaChangeListener?.invoke(it.progress) onAlphaChangeListener?.invoke(it.progress)
} }
} }
}
}
override fun onStartTrackingTouch(seekBar: IndicatorSeekBar?) { override fun onStartTrackingTouch(seekBar: IndicatorSeekBar?) {
} }
override fun onStopTrackingTouch(seekBar: IndicatorSeekBar?) { override fun onStopTrackingTouch(seekBar: IndicatorSeekBar?) {
@ -78,7 +100,6 @@ class BottomSheetColorPicker(
} }
// List // List
adapter = SlimAdapter.create() adapter = SlimAdapter.create()
loadingJobs.add(GlobalScope.launch(Dispatchers.IO) { loadingJobs.add(GlobalScope.launch(Dispatchers.IO) {
@ -120,10 +141,13 @@ class BottomSheetColorPicker(
adapter.updateData(colors.toList()) adapter.updateData(colors.toList())
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
binding.colorLoader.isVisible = false binding.loader.isVisible = false
binding.listContainer.addView(listBinding.root) binding.listContainer.addView(listBinding.root)
this@BottomSheetColorPicker.behavior.state = BottomSheetBehavior.STATE_EXPANDED this@BottomSheetColorPicker.behavior.state = BottomSheetBehavior.STATE_EXPANDED
binding.listContainer.isVisible = true binding.listContainer.isVisible = true
val idx = colors.toList().indexOf(getSelected?.invoke())
(listBinding.root.layoutManager as GridLayoutManager).scrollToPositionWithOffset(idx,0)
} }
}) })

View File

@ -6,6 +6,7 @@ import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R

View File

@ -0,0 +1,108 @@
package com.tommasoberlose.anotherwidget.components
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.card.MaterialCardView
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuHorBinding
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuListBinding
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.copyToClipboard
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isClipboardColor
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.pasteFromClipboard
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import com.warkiz.widget.IndicatorSeekBar
import com.warkiz.widget.OnSeekChangeListener
import com.warkiz.widget.SeekParams
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
class BottomSheetPicker<T>(
context: Context,
private val items: List<MenuItem<T>> = arrayListOf(),
private val getSelected: (() -> T)? = null,
private val header: String? = null,
private val onItemSelected: ((selectedValue: T?) -> Unit)? = null,
) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private var loadingJobs: ArrayList<Job> = ArrayList()
private lateinit var adapter: SlimAdapter
private var binding: BottomSheetMenuHorBinding = BottomSheetMenuHorBinding.inflate(
LayoutInflater.from(context))
private var listBinding: BottomSheetMenuListBinding = BottomSheetMenuListBinding.inflate(
LayoutInflater.from(context))
override fun show() {
window?.setDimAmount(0f)
// Header
binding.header.isVisible = header != null
binding.headerText.text = header ?: ""
// Alpha
binding.alphaSelectorContainer.isVisible = false
binding.actionContainer.isVisible = false
// List
adapter = SlimAdapter.create()
loadingJobs.add(GlobalScope.launch(Dispatchers.IO) {
listBinding.root.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(context)
listBinding.root.layoutManager = mLayoutManager
adapter
.register<Int>(R.layout.bottom_sheet_menu_item) { position, injector ->
val item = items[position]
val isSelected = item.value == getSelected?.invoke()
injector
.text(R.id.label, item.title)
.textColor(R.id.label, ContextCompat.getColor(context, if (isSelected) R.color.colorAccent else R.color.colorSecondaryText))
.selected(R.id.item, isSelected)
.clicked(R.id.item) {
val oldIdx = items.toList().indexOfFirst { it.value == getSelected?.invoke() }
onItemSelected?.invoke(item.value)
adapter.notifyItemChanged(position)
adapter.notifyItemChanged(oldIdx)
(listBinding.root.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position,0)
}
}
.attachTo(listBinding.root)
adapter.updateData((items.indices).toList())
withContext(Dispatchers.Main) {
binding.loader.isVisible = false
binding.listContainer.addView(listBinding.root)
this@BottomSheetPicker.behavior.state = BottomSheetBehavior.STATE_EXPANDED
binding.listContainer.isVisible = true
val idx = items.toList().indexOfFirst { it.value == getSelected?.invoke() }
(listBinding.root.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(idx,0)
}
})
setContentView(binding.root)
super.show()
}
override fun onStop() {
loadingJobs.forEach { it.cancel() }
super.onStop()
}
class MenuItem<T>(val title: String, val value: T? = null)
}

View File

@ -110,6 +110,7 @@ object Preferences : KotprefModel() {
var customFontName by stringPref(default = "") var customFontName by stringPref(default = "")
var customFontVariant by stringPref(default = "regular") var customFontVariant by stringPref(default = "regular")
var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true) var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true)
var showNextEventOnMultipleLines by booleanPref(default = false)
var showDividers by booleanPref(default = true) var showDividers by booleanPref(default = true)

View File

@ -1,10 +1,20 @@
package com.tommasoberlose.anotherwidget.helpers package com.tommasoberlose.anotherwidget.helpers
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Context.CLIPBOARD_SERVICE
import android.graphics.Color import android.graphics.Color
import android.util.Log
import androidx.core.content.ContextCompat
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import com.tommasoberlose.anotherwidget.utils.toast
import kotlin.math.roundToInt import kotlin.math.roundToInt
object ColorHelper { object ColorHelper {
fun getFontColor(isDark: Boolean): Int { fun getFontColor(isDark: Boolean): Int {
return try { return try {
@ -144,4 +154,40 @@ object ColorHelper {
false false
} }
} }
@SuppressLint("DefaultLocale")
fun Context.copyToClipboard(color: Int?, alpha: Int) {
if (color == null) return toast(getString(R.string.error_copy_color))
with(getSystemService(CLIPBOARD_SERVICE) as ClipboardManager) {
try {
val colorString = Integer.toHexString(color)
val clip = "#%s%s".format(
alpha.toHexValue(),
if (colorString.length > 6) colorString.substring(2) else colorString
).toUpperCase()
setPrimaryClip(ClipData.newPlainText(clip, clip))
toast(getString(R.string.color_copied))
} catch (ex: Exception) {
ex.printStackTrace()
toast(getString(R.string.error_copy_color))
}
}
}
fun Context.isClipboardColor(): Boolean {
with(getSystemService(CLIPBOARD_SERVICE) as ClipboardManager) {
return primaryClip?.getItemAt(0)?.text?.toString()?.isColor() ?: false
}
}
fun Context.pasteFromClipboard(pasteColor: (color: String, alpha: String) -> Unit) {
with(getSystemService(CLIPBOARD_SERVICE) as ClipboardManager) {
primaryClip?.let {
val item = it.getItemAt(0).text.toString().replace("#", "")
val color = if (item.length > 6) item.substring(2) else item
val alpha = if (item.length > 6) item.substring(0, 2) else "00"
pasteColor("#$color", alpha)
}
}
}
} }

View File

@ -12,6 +12,7 @@ import com.chibatching.kotpref.bulk
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.receivers.NotificationListener import com.tommasoberlose.anotherwidget.receivers.NotificationListener
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.ignoreExceptions
import java.lang.Exception import java.lang.Exception
object MediaPlayerHelper { object MediaPlayerHelper {
@ -69,17 +70,26 @@ object MediaPlayerHelper {
isSomeonePlaying = true isSomeonePlaying = true
if (metadata != null) { if (metadata != null) {
Preferences.bulk { Preferences.bulk {
ignoreExceptions {
mediaPlayerTitle = mediaPlayerTitle =
metadata.getText(MediaMetadata.METADATA_KEY_TITLE)?.toString() metadata.getText(MediaMetadata.METADATA_KEY_TITLE)
?.toString()
?: "" ?: ""
}
ignoreExceptions {
mediaPlayerArtist = mediaPlayerArtist =
metadata.getText(MediaMetadata.METADATA_KEY_ARTIST)?.toString() metadata.getText(MediaMetadata.METADATA_KEY_ARTIST)
?.toString()
?: "" ?: ""
}
ignoreExceptions {
mediaPlayerAlbum = mediaPlayerAlbum =
metadata.getText(MediaMetadata.METADATA_KEY_ALBUM)?.toString() metadata.getText(MediaMetadata.METADATA_KEY_ALBUM)
?.toString()
?: "" ?: ""
} }
} }
}
Preferences.mediaPlayerPackage = mc.packageName Preferences.mediaPlayerPackage = mc.packageName
} }

View File

@ -53,12 +53,12 @@ class CustomLocationActivity : AppCompatActivity() {
} }
} }
.register<Address>(R.layout.custom_location_item) { item, injector -> .register<Address>(R.layout.custom_location_item) { item, injector ->
injector.text(R.id.text, item.getAddressLine(0)) injector.text(R.id.text, item.getAddressLine(0) ?: "")
injector.clicked(R.id.item) { injector.clicked(R.id.item) {
Preferences.bulk { Preferences.bulk {
customLocationLat = item.latitude.toString() customLocationLat = item.latitude.toString()
customLocationLon = item.longitude.toString() customLocationLon = item.longitude.toString()
customLocationAdd = item.getAddressLine(0) customLocationAdd = item.getAddressLine(0) ?: ""
setResult(Activity.RESULT_OK) setResult(Activity.RESULT_OK)
finish() finish()
} }

View File

@ -63,6 +63,7 @@ class CalendarFragment : Fragment() {
binding.showAllDayToggle.setCheckedImmediatelyNoEvent(Preferences.calendarAllDay) binding.showAllDayToggle.setCheckedImmediatelyNoEvent(Preferences.calendarAllDay)
binding.showOnlyBusyEventsToggle.setCheckedImmediatelyNoEvent(Preferences.showOnlyBusyEvents) binding.showOnlyBusyEventsToggle.setCheckedImmediatelyNoEvent(Preferences.showOnlyBusyEvents)
binding.showDiffTimeToggle.setCheckedImmediatelyNoEvent(Preferences.showDiffTime) binding.showDiffTimeToggle.setCheckedImmediatelyNoEvent(Preferences.showDiffTime)
binding.showNextEventOnMultipleLinesToggle.setCheckedImmediatelyNoEvent(Preferences.showNextEventOnMultipleLines)
setupListener() setupListener()
@ -90,6 +91,12 @@ class CalendarFragment : Fragment() {
} }
} }
viewModel.showNextEventOnMultipleLines.observe(viewLifecycleOwner) {
maintainScrollPosition {
binding.showNextEventOnMultipleLinesLabel.text = if (it) getString(R.string.settings_enabled) else getString(R.string.settings_disabled)
}
}
viewModel.showDiffTime.observe(viewLifecycleOwner) { viewModel.showDiffTime.observe(viewLifecycleOwner) {
maintainScrollPosition { maintainScrollPosition {
binding.showDiffTimeLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) binding.showDiffTimeLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
@ -231,6 +238,14 @@ class CalendarFragment : Fragment() {
Preferences.showDiffTime = isChecked Preferences.showDiffTime = isChecked
} }
binding.actionShowNextEventOnMultipleLines.setOnClickListener {
binding.showNextEventOnMultipleLinesToggle.isChecked = !binding.showNextEventOnMultipleLinesToggle.isChecked
}
binding.showNextEventOnMultipleLinesToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showNextEventOnMultipleLines = isChecked
}
binding.actionWidgetUpdateFrequency.setOnClickListener { binding.actionWidgetUpdateFrequency.setOnClickListener {
if (Preferences.showEvents && Preferences.showDiffTime) { if (Preferences.showEvents && Preferences.showDiffTime) {
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_widget_update_frequency_title), message = getString(R.string.settings_widget_update_frequency_subtitle)).setSelectedValue(Preferences.widgetUpdateFrequency) BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_widget_update_frequency_title), message = getString(R.string.settings_widget_update_frequency_subtitle)).setSelectedValue(Preferences.widgetUpdateFrequency)

View File

@ -15,6 +15,7 @@ import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.components.BottomSheetPicker
import com.tommasoberlose.anotherwidget.databinding.FragmentTabTypographyBinding import com.tommasoberlose.anotherwidget.databinding.FragmentTabTypographyBinding
import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
@ -167,20 +168,21 @@ class TypographyFragment : Fragment() {
private fun setupListener() { private fun setupListener() {
binding.actionMainTextSize.setOnClickListener { binding.actionMainTextSize.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_main_text_size)).setSelectedValue( BottomSheetPicker(
Preferences.textMainSize) requireContext(),
(40 downTo 10).filter { it % 2 == 0 }.forEach { items = (40 downTo 10).map { BottomSheetPicker.MenuItem("${it}sp", it.toFloat()) },
dialog.addItem("${it}sp", it.toFloat()) getSelected = { Preferences.textMainSize },
header = getString(R.string.title_main_text_size),
onItemSelected = {value ->
if (value != null) Preferences.textMainSize = value
} }
dialog.addOnSelectItemListener { value -> ).show()
Preferences.textMainSize = value
}.show()
} }
binding.actionSecondTextSize.setOnClickListener { binding.actionSecondTextSize.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue( val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue(
Preferences.textSecondSize) Preferences.textSecondSize)
(40 downTo 10).filter { it % 2 == 0 }.forEach { (40 downTo 10).forEach {
dialog.addItem("${it}sp", it.toFloat()) dialog.addItem("${it}sp", it.toFloat())
} }
dialog.addOnSelectItemListener { value -> dialog.addOnSelectItemListener { value ->
@ -209,7 +211,7 @@ class TypographyFragment : Fragment() {
} else { } else {
Preferences.textGlobalAlpha = alpha.toHexValue() Preferences.textGlobalAlpha = alpha.toHexValue()
} }
} },
).show() ).show()
} }
@ -236,7 +238,7 @@ class TypographyFragment : Fragment() {
} else { } else {
Preferences.textSecondaryAlpha = alpha.toHexValue() Preferences.textSecondaryAlpha = alpha.toHexValue()
} }
} },
).show() ).show()
} }

View File

@ -57,6 +57,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
val showUntil = Preferences.asLiveData(Preferences::showUntil) val showUntil = Preferences.asLiveData(Preferences::showUntil)
val showDiffTime = Preferences.asLiveData(Preferences::showDiffTime) val showDiffTime = Preferences.asLiveData(Preferences::showDiffTime)
val showNextEvent = Preferences.asLiveData(Preferences::showNextEvent) val showNextEvent = Preferences.asLiveData(Preferences::showNextEvent)
val showNextEventOnMultipleLines = Preferences.asLiveData(Preferences::showNextEventOnMultipleLines)
val openEventDetails = Preferences.asLiveData(Preferences::openEventDetails) val openEventDetails = Preferences.asLiveData(Preferences::openEventDetails)
val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName) val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName)
val widgetUpdateFrequency = Preferences.asLiveData(Preferences::widgetUpdateFrequency) val widgetUpdateFrequency = Preferences.asLiveData(Preferences::widgetUpdateFrequency)
@ -144,6 +145,7 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
addSource(Preferences.asLiveData(Preferences::calendarAllDay)) { value = true } addSource(Preferences.asLiveData(Preferences::calendarAllDay)) { value = true }
addSource(Preferences.asLiveData(Preferences::showDiffTime)) { value = true } addSource(Preferences.asLiveData(Preferences::showDiffTime)) { value = true }
addSource(Preferences.asLiveData(Preferences::showNextEvent)) { value = true } addSource(Preferences.asLiveData(Preferences::showNextEvent)) { value = true }
addSource(Preferences.asLiveData(Preferences::showNextEventOnMultipleLines)) { value = true }
addSource(Preferences.asLiveData(Preferences::showDeclinedEvents)) { value = true } addSource(Preferences.asLiveData(Preferences::showDeclinedEvents)) { value = true }
addSource(Preferences.asLiveData(Preferences::showInvitedEvents)) { value = true } addSource(Preferences.asLiveData(Preferences::showInvitedEvents)) { value = true }
addSource(Preferences.asLiveData(Preferences::showAcceptedEvents)) { value = true } addSource(Preferences.asLiveData(Preferences::showAcceptedEvents)) { value = true }

View File

@ -107,12 +107,12 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.weather_rect, R.id.weather_rect,
BitmapHelper.getBitmapFromView(bindingView.weatherDateLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.weatherDateLine, draw = false, width = bindingView.weatherDateLine.width, height = bindingView.weatherDateLine.height)
) )
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.weather_sub_line_rect, R.id.weather_sub_line_rect,
BitmapHelper.getBitmapFromView(bindingView.weatherSubLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.weatherSubLine, draw = false, width = bindingView.weatherSubLine.width, height = bindingView.weatherSubLine.height)
) )
} else { } else {
views.setViewVisibility(R.id.weather_rect, View.GONE) views.setViewVisibility(R.id.weather_rect, View.GONE)
@ -123,7 +123,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
// Calendar // Calendar
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.date_rect, R.id.date_rect,
BitmapHelper.getBitmapFromView(bindingView.date, draw = false) BitmapHelper.getBitmapFromView(bindingView.date, draw = false, width = bindingView.date.width, height = bindingView.date.height)
) )
val calPIntent = PendingIntent.getActivity( val calPIntent = PendingIntent.getActivity(
@ -157,7 +157,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
// Action next event // Action next event
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.action_next_rect, R.id.action_next_rect,
BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false) BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false, width = bindingView.actionNext.width, height = bindingView.actionNext.height)
) )
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE) views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
views.setOnClickPendingIntent( views.setOnClickPendingIntent(
@ -186,6 +186,10 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
PendingIntent.FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT
) )
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent) views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
views.setImageViewBitmap(
R.id.next_event_rect,
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false, width = bindingView.nextEvent.width, height = bindingView.nextEvent.height)
)
views.setViewVisibility(R.id.next_event_rect, View.VISIBLE) views.setViewVisibility(R.id.next_event_rect, View.VISIBLE)
// Event time difference // Event time difference
@ -194,15 +198,21 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
R.id.next_event_difference_time_rect, R.id.next_event_difference_time_rect,
BitmapHelper.getBitmapFromView( BitmapHelper.getBitmapFromView(
bindingView.nextEventDifferenceTime, bindingView.nextEventDifferenceTime,
draw = false draw = false,
width = bindingView.nextEventDifferenceTime.width,
height = bindingView.nextEventDifferenceTime.height
) )
) )
views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, eventIntent) views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, eventIntent)
if (!Preferences.showNextEventOnMultipleLines) {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE) views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
} else { } else {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE) views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
} }
} else {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
}
// Event information // Event information
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) { if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
@ -227,12 +237,6 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail) views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
} }
views.setImageViewBitmap(
R.id.next_event_rect,
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false)
)
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE) views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE)
views.setViewVisibility(R.id.weather_sub_line_rect, View.VISIBLE) views.setViewVisibility(R.id.weather_sub_line_rect, View.VISIBLE)
@ -374,12 +378,23 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE) views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE) views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
} }
} else {
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
views.setViewVisibility(R.id.sub_line_rect, View.GONE)
views.setViewVisibility(R.id.weather_sub_line_rect, View.GONE)
// Spacing
views.setViewVisibility(R.id.sub_line_top_margin_small_sans, View.GONE)
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
} }
// Second row // Second row
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.sub_line_rect, R.id.sub_line_rect,
BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false, width = bindingView.subLine.width, height = bindingView.subLine.height)
) )
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
@ -455,8 +470,16 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
bindingView.nextEvent.text = nextEvent.title bindingView.nextEvent.text = nextEvent.title
if (Preferences.showNextEventOnMultipleLines) {
bindingView.nextEvent.apply {
isSingleLine = false
maxLines = 3
gravity = if (rightAligned) Gravity.END else Gravity.START
}
}
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) { if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
bindingView.nextEventDifferenceTime.text = if (!nextEvent.allDay) { val diffTime = if (!nextEvent.allDay) {
SettingsStringHelper.getDifferenceText( SettingsStringHelper.getDifferenceText(
context, context,
now.timeInMillis, now.timeInMillis,
@ -470,7 +493,14 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
nextEvent.startDate nextEvent.startDate
).toLowerCase(Locale.getDefault()) ).toLowerCase(Locale.getDefault())
} }
bindingView.nextEventDifferenceTime.text = diffTime
if (!Preferences.showNextEventOnMultipleLines) {
bindingView.nextEventDifferenceTime.isVisible = true bindingView.nextEventDifferenceTime.isVisible = true
} else {
bindingView.nextEvent.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, diffTime)
bindingView.nextEventDifferenceTime.isVisible = false
}
} else { } else {
bindingView.nextEventDifferenceTime.isVisible = false bindingView.nextEventDifferenceTime.isVisible = false
} }

View File

@ -10,6 +10,7 @@ import android.graphics.Typeface
import android.text.format.DateUtils import android.text.format.DateUtils
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -109,12 +110,12 @@ class StandardWidget(val context: Context) {
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.weather_rect, R.id.weather_rect,
BitmapHelper.getBitmapFromView(bindingView.weatherDateLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.weatherDateLine, draw = false, width = bindingView.weatherDateLine.width, height = bindingView.weatherDateLine.height)
) )
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.weather_sub_line_rect, R.id.weather_sub_line_rect,
BitmapHelper.getBitmapFromView(bindingView.weatherSubLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.weatherSubLine, draw = false, width = bindingView.weatherSubLine.width, height = bindingView.weatherSubLine.height)
) )
} else { } else {
views.setViewVisibility(R.id.weather_rect, View.GONE) views.setViewVisibility(R.id.weather_rect, View.GONE)
@ -125,7 +126,7 @@ class StandardWidget(val context: Context) {
// Calendar // Calendar
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.date_rect, R.id.date_rect,
BitmapHelper.getBitmapFromView(bindingView.date, draw = false) BitmapHelper.getBitmapFromView(bindingView.date, draw = false, width = bindingView.date.width, height = bindingView.date.height)
) )
val calPIntent = PendingIntent.getActivity( val calPIntent = PendingIntent.getActivity(
@ -140,7 +141,7 @@ class StandardWidget(val context: Context) {
// Second row // Second row
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.sub_line_rect, R.id.sub_line_rect,
BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false, width = bindingView.subLine.width, height = bindingView.subLine.height)
) )
val nextAlarm = AlarmHelper.getNextAlarm(context) val nextAlarm = AlarmHelper.getNextAlarm(context)
@ -165,7 +166,7 @@ class StandardWidget(val context: Context) {
// Action next event // Action next event
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.action_next_rect, R.id.action_next_rect,
BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false) BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false, width = bindingView.actionNext.width, height = bindingView.actionNext.height)
) )
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE) views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
views.setOnClickPendingIntent( views.setOnClickPendingIntent(
@ -184,7 +185,7 @@ class StandardWidget(val context: Context) {
// Action previous event // Action previous event
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.action_previous_rect, R.id.action_previous_rect,
BitmapHelper.getBitmapFromView(bindingView.actionPrevious, draw = false) BitmapHelper.getBitmapFromView(bindingView.actionPrevious, draw = false, width = bindingView.actionPrevious.width, height = bindingView.actionPrevious.height)
) )
views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE) views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE)
views.setOnClickPendingIntent( views.setOnClickPendingIntent(
@ -223,11 +224,18 @@ class StandardWidget(val context: Context) {
R.id.next_event_difference_time_rect, R.id.next_event_difference_time_rect,
BitmapHelper.getBitmapFromView( BitmapHelper.getBitmapFromView(
bindingView.nextEventDifferenceTime, bindingView.nextEventDifferenceTime,
draw = false draw = false,
width = bindingView.nextEventDifferenceTime.width,
height = bindingView.nextEventDifferenceTime.height
) )
) )
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, eventIntent) views.setOnClickPendingIntent(R.id.next_event_difference_time_rect, eventIntent)
if (!Preferences.showNextEventOnMultipleLines) {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.VISIBLE)
} else {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
}
} else { } else {
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE) views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
} }
@ -257,7 +265,7 @@ class StandardWidget(val context: Context) {
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.next_event_rect, R.id.next_event_rect,
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false) BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false, width = bindingView.nextEvent.width, height = bindingView.nextEvent.height)
) )
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE) views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE) views.setViewVisibility(R.id.sub_line_rect, View.VISIBLE)
@ -388,7 +396,7 @@ class StandardWidget(val context: Context) {
if (showSomething) { if (showSomething) {
views.setImageViewBitmap( views.setImageViewBitmap(
R.id.sub_line_rect, R.id.sub_line_rect,
BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false) BitmapHelper.getBitmapFromView(bindingView.subLine, draw = false, width = bindingView.subLine.width, height = bindingView.subLine.height)
) )
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE) views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
@ -402,6 +410,17 @@ class StandardWidget(val context: Context) {
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE) views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE) views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
} }
} else {
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
views.setViewVisibility(R.id.sub_line_rect, View.GONE)
views.setViewVisibility(R.id.weather_sub_line_rect, View.GONE)
// Spacing
views.setViewVisibility(R.id.sub_line_top_margin_small_sans, View.GONE)
views.setViewVisibility(R.id.sub_line_top_margin_medium_sans, View.GONE)
views.setViewVisibility(R.id.sub_line_top_margin_large_sans, View.GONE)
} }
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
@ -480,8 +499,16 @@ class StandardWidget(val context: Context) {
bindingView.nextEvent.text = nextEvent.title bindingView.nextEvent.text = nextEvent.title
if (Preferences.showNextEventOnMultipleLines) {
bindingView.nextEvent.apply {
isSingleLine = false
maxLines = 3
gravity = Gravity.CENTER
}
}
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) { if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
bindingView.nextEventDifferenceTime.text = if (!nextEvent.allDay) { val diffTime = if (!nextEvent.allDay) {
SettingsStringHelper.getDifferenceText( SettingsStringHelper.getDifferenceText(
context, context,
now.timeInMillis, now.timeInMillis,
@ -495,7 +522,14 @@ class StandardWidget(val context: Context) {
nextEvent.startDate nextEvent.startDate
).toLowerCase(Locale.getDefault()) ).toLowerCase(Locale.getDefault())
} }
bindingView.nextEventDifferenceTime.text = diffTime
if (!Preferences.showNextEventOnMultipleLines) {
bindingView.nextEventDifferenceTime.isVisible = true bindingView.nextEventDifferenceTime.isVisible = true
} else {
bindingView.nextEvent.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, diffTime)
bindingView.nextEventDifferenceTime.isVisible = false
}
} else { } else {
bindingView.nextEventDifferenceTime.isVisible = false bindingView.nextEventDifferenceTime.isVisible = false
} }

View File

@ -265,3 +265,11 @@ fun View.setOnSingleClickListener(l: View.OnClickListener) {
fun View.setOnSingleClickListener(l: (View) -> Unit) { fun View.setOnSingleClickListener(l: (View) -> Unit) {
setOnClickListener(OnSingleClickListener(l)) setOnClickListener(OnSingleClickListener(l))
} }
fun ignoreExceptions(function: () -> Unit) = run {
try {
function.invoke()
} catch (ex: Exception) {
ex.printStackTrace()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="@color/colorAccent_op30" /> <item android:state_selected="true" android:color="@color/colorAccent_op10" />
<item android:color="@color/colorPrimary" /> <item android:color="@color/colorPrimary" />
</selector> </selector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M16.5,4h-13C2.67,4 2,4.67 2,5.5v9C2,15.33 2.67,16 3.5,16h13c0.83,0 1.5,-0.67 1.5,-1.5v-9C18,4.67 17.33,4 16.5,4zM11.25,13h-5.5C5.34,13 5,12.66 5,12.25v0c0,-0.41 0.34,-0.75 0.75,-0.75h5.5c0.41,0 0.75,0.34 0.75,0.75v0C12,12.66 11.66,13 11.25,13zM14.25,10h-5.5C8.34,10 8,9.66 8,9.25v0C8,8.84 8.34,8.5 8.75,8.5h5.5C14.66,8.5 15,8.84 15,9.25v0C15,9.66 14.66,10 14.25,10zM6.5,9.27c0,0.41 -0.34,0.75 -0.75,0.75S5,9.68 5,9.27c0,-0.41 0.34,-0.75 0.75,-0.75S6.5,8.85 6.5,9.27zM15,12.25c0,0.41 -0.34,0.75 -0.75,0.75s-0.75,-0.34 -0.75,-0.75s0.34,-0.75 0.75,-0.75S15,11.84 15,12.25z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM5,12h2c0.55,0 1,0.45 1,1s-0.45,1 -1,1L5,14c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1zM13,18L5,18c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1zM19,18h-2c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h2c0.55,0 1,0.45 1,1s-0.45,1 -1,1zM19,14h-8c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
</vector>

View File

@ -41,6 +41,35 @@
android:id="@+id/header_text" android:id="@+id/header_text"
android:text="@string/settings_font_color_title" android:text="@string/settings_font_color_title"
android:textColor="@color/colorPrimaryText"/> android:textColor="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:gravity="center_vertical"
android:id="@+id/action_container">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="40dp"
android:layout_height="48dp"
android:padding="8dp"
android:clickable="true"
android:focusable="true"
android:tint="@color/colorPrimaryText"
android:background="?attr/selectableItemBackgroundBorderless"
android:id="@+id/action_copy"
android:src="@drawable/round_content_copy_24" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="8dp"
android:clickable="true"
android:focusable="true"
android:tint="@color/colorPrimaryText"
android:background="?attr/selectableItemBackgroundBorderless"
android:id="@+id/action_paste"
android:src="@drawable/round_content_paste_24" />
</LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -52,6 +81,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/alpha_selector_container" android:id="@+id/alpha_selector_container"
android:visibility="gone"
android:layout_marginTop="-2dp" android:layout_marginTop="-2dp"
android:background="@color/colorPrimary" android:background="@color/colorPrimary"
android:gravity="center_vertical" android:gravity="center_vertical"
@ -115,6 +145,6 @@
android:indeterminate="true" android:indeterminate="true"
android:layout_margin="32dp" android:layout_margin="32dp"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:id="@+id/color_loader" /> android:id="@+id/loader" />
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

View File

@ -9,6 +9,7 @@
app:cardCornerRadius="8dp" app:cardCornerRadius="8dp"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:id="@+id/item"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -253,6 +253,55 @@
android:paddingLeft="20dp" android:paddingLeft="20dp"
android:paddingRight="20dp" android:paddingRight="20dp"
android:textAppearance="@style/AnotherWidget.Settings.Header" /> android:textAppearance="@style/AnotherWidget.Settings.Header" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_next_event_on_multiple_lines"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:scaleY="-1"
android:src="@drawable/round_subtitles_24"
app:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_show_next_event_on_multiple_lines_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_next_event_on_multiple_lines_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<com.kyleduo.switchbutton.SwitchButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:kswThumbWidth="16sp"
app:kswThumbHeight="16sp"
app:kswBackRadius="16dp"
app:kswTintColor="@color/colorAccent"
android:layout_marginEnd="16dp"
android:id="@+id/show_next_event_on_multiple_lines_toggle"
android:buttonTint="@color/colorAccent" />
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -72,7 +72,7 @@
android:layout_weight="1" android:layout_weight="1"
android:maxLines="1" android:maxLines="1"
android:lines="1" android:lines="1"
android:gravity="end" android:gravity="start"
android:ellipsize="end" android:ellipsize="end"
android:includeFontPadding="false" android:includeFontPadding="false"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -85,7 +85,6 @@
android:id="@+id/next_event_difference_time" android:id="@+id/next_event_difference_time"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="marquee"
android:includeFontPadding="false" android:includeFontPadding="false"
style="@style/AnotherWidget.Widget.Title" /> style="@style/AnotherWidget.Widget.Title" />
</LinearLayout> </LinearLayout>

View File

@ -112,6 +112,7 @@
<string name="calendar_sync_notification_channel_name">Events sync service</string> <string name="calendar_sync_notification_channel_name">Events sync service</string>
<string name="calendar_sync_notification_channel_description">Service used to synchronize the calendar events.</string> <string name="calendar_sync_notification_channel_description">Service used to synchronize the calendar events.</string>
<string name="calendar_sync_notification_title">Syncing calendar events…</string> <string name="calendar_sync_notification_title">Syncing calendar events…</string>
<string name="settings_show_next_event_on_multiple_lines_title">Show title on multiple lines</string>
<!-- Weather --> <!-- Weather -->
<string name="settings_weather_title">Weather</string> <string name="settings_weather_title">Weather</string>
@ -368,4 +369,8 @@
<string name="smart_content_header">Smart content</string> <string name="smart_content_header">Smart content</string>
<string name="spacing_settings_header">Spacing</string> <string name="spacing_settings_header">Spacing</string>
<string name="gestures_refresh_widget">None, the widget will be refreshed</string> <string name="gestures_refresh_widget">None, the widget will be refreshed</string>
<string name="settings_disabled">Disabled</string>
<string name="settings_enabled">Enabled</string>
<string name="color_copied">Color copied into the clipboard.</string>
<string name="error_copy_color">The color cannot be copied.</string>
</resources> </resources>