Allow color customization of local events as well

This commit is contained in:
Naveen 2023-04-30 14:40:05 +05:30
parent e63397a4e8
commit 4503281860
3 changed files with 469 additions and 19 deletions

View file

@ -31,7 +31,6 @@ import com.simplemobiletools.calendar.pro.adapters.AutoCompleteTextViewAdapter
import com.simplemobiletools.calendar.pro.dialogs.*
import com.simplemobiletools.calendar.pro.extensions.*
import com.simplemobiletools.calendar.pro.helpers.*
import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.models.*
import com.simplemobiletools.commons.dialogs.ConfirmationAdvancedDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
@ -40,11 +39,13 @@ import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.views.MyAutoCompleteTextView
import kotlinx.android.synthetic.main.activity_event.*
import kotlinx.android.synthetic.main.activity_event.view.*
import kotlinx.android.synthetic.main.activity_event.view.event_reminder_2
import kotlinx.android.synthetic.main.activity_event.view.event_reminder_3
import kotlinx.android.synthetic.main.item_attendee.view.*
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import java.util.*
import java.util.Calendar
import java.util.TimeZone
import java.util.regex.Pattern
class EventActivity : SimpleActivity() {
@ -834,25 +835,55 @@ class EventActivity : SimpleActivity() {
private fun showEventColorDialog() {
hideKeyboard()
ensureBackgroundThread {
val eventType = eventsHelper.getEventTypeWithCalDAVCalendarId(calendarId = mEventCalendarId)!!
val eventColors = getEventColors(eventType)
runOnUiThread {
val currentColor = if (mEventColor == 0) {
eventType.color
} else {
mEventColor
}
val isLocalEvent = mEventCalendarId == STORED_LOCALLY_ONLY
if (isLocalEvent) {
showCustomEventColorDialog()
} else {
showCalDAVEventColorDialog()
}
}
}
SelectEventColorDialog(activity = this, colors = eventColors, currentColor = currentColor) { newColor ->
if (newColor != currentColor) {
mEventColor = newColor
updateEventColorInfo(defaultColor = eventType.color)
}
private fun showCustomEventColorDialog() {
val eventType = eventTypesDB.getEventTypeWithId(mEventTypeId)!!
val currentColor = if (mEventColor == 0) {
eventType.color
} else {
mEventColor
}
runOnUiThread {
ColorPickerDialog(activity = this, color = currentColor) { wasPositivePressed, newColor ->
if (wasPositivePressed) {
gotNewEventColor(newColor, currentColor, eventType.color)
}
}
}
}
private fun showCalDAVEventColorDialog() {
val eventType = eventsHelper.getEventTypeWithCalDAVCalendarId(calendarId = mEventCalendarId)!!
val eventColors = getEventColors(eventType)
val currentColor = if (mEventColor == 0) {
eventType.color
} else {
mEventColor
}
runOnUiThread {
SelectEventColorDialog(activity = this, colors = eventColors, currentColor = currentColor) { newColor ->
gotNewEventColor(newColor, currentColor, eventType.color)
}
}
}
private fun gotNewEventColor(newColor: Int, currentColor: Int, defaultColor: Int) {
if (newColor != currentColor) {
mEventColor = newColor
updateEventColorInfo(defaultColor = defaultColor)
}
}
private fun checkReminderTexts() {
updateReminder1Text()
updateReminder2Text()
@ -1018,9 +1049,17 @@ class EventActivity : SimpleActivity() {
setPadding(paddingLeft, mediumMargin, paddingRight, mediumMargin)
}
event_caldav_color_image.beGone()
event_caldav_color_holder.beGone()
event_caldav_color_divider.beGone()
ensureBackgroundThread {
val eventType = eventTypesDB.getEventTypeWithId(mEventTypeId)
if (eventType != null) {
runOnUiThread {
event_caldav_color_image.beVisible()
event_caldav_color_holder.beVisible()
event_caldav_color_divider.beVisible()
updateEventColorInfo(eventType.color)
}
}
}
} else {
event_caldav_calendar_email.text = currentCalendar.accountName
@ -1326,6 +1365,7 @@ class EventActivity : SimpleActivity() {
}
}
}
1 -> {
ensureBackgroundThread {
eventsHelper.addEventRepeatLimit(mEvent.id!!, mEventOccurrenceTS)

View file

@ -0,0 +1,247 @@
package com.simplemobiletools.calendar.pro.dialogs
import android.app.Activity
import android.graphics.Color
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.EditText
import android.widget.ImageView
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.isQPlus
import com.simplemobiletools.commons.views.ColorPickerSquare
import kotlinx.android.synthetic.main.dialog_color_picker.view.*
import java.util.LinkedList
private const val RECENT_COLORS_NUMBER = 5
// forked from https://github.com/yukuku/ambilwarna
class ColorPickerDialog(
val activity: Activity,
color: Int,
val removeDimmedBackground: Boolean = false,
val currentColorCallback: ((color: Int) -> Unit)? = null,
val callback: (wasPositivePressed: Boolean, color: Int) -> Unit
) {
var viewHue: View
var viewSatVal: ColorPickerSquare
var viewCursor: ImageView
var viewNewColor: ImageView
var viewTarget: ImageView
var newHexField: EditText
var viewContainer: ViewGroup
private val baseConfig = activity.baseConfig
private val currentColorHsv = FloatArray(3)
private val backgroundColor = baseConfig.backgroundColor
private var isHueBeingDragged = false
private var wasDimmedBackgroundRemoved = false
private var dialog: AlertDialog? = null
init {
Color.colorToHSV(color, currentColorHsv)
val view = activity.layoutInflater.inflate(R.layout.dialog_color_picker, null).apply {
if (isQPlus()) {
isForceDarkAllowed = false
}
viewHue = color_picker_hue
viewSatVal = color_picker_square
viewCursor = color_picker_hue_cursor
viewNewColor = color_picker_new_color
viewTarget = color_picker_cursor
viewContainer = color_picker_holder
newHexField = color_picker_new_hex
viewSatVal.setHue(getHue())
viewNewColor.setFillWithStroke(getColor(), backgroundColor)
color_picker_old_color.setFillWithStroke(color, backgroundColor)
val hexCode = getHexCode(color)
color_picker_old_hex.text = "#$hexCode"
color_picker_old_hex.setOnLongClickListener {
activity.copyToClipboard(hexCode)
true
}
newHexField.setText(hexCode)
setupRecentColors()
}
viewHue.setOnTouchListener(OnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
isHueBeingDragged = true
}
if (event.action == MotionEvent.ACTION_MOVE || event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_UP) {
var y = event.y
if (y < 0f)
y = 0f
if (y > viewHue.measuredHeight) {
y = viewHue.measuredHeight - 0.001f // to avoid jumping the cursor from bottom to top.
}
var hue = 360f - 360f / viewHue.measuredHeight * y
if (hue == 360f)
hue = 0f
currentColorHsv[0] = hue
updateHue()
newHexField.setText(getHexCode(getColor()))
if (event.action == MotionEvent.ACTION_UP) {
isHueBeingDragged = false
}
return@OnTouchListener true
}
false
})
viewSatVal.setOnTouchListener(OnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_MOVE || event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_UP) {
var x = event.x
var y = event.y
if (x < 0f)
x = 0f
if (x > viewSatVal.measuredWidth)
x = viewSatVal.measuredWidth.toFloat()
if (y < 0f)
y = 0f
if (y > viewSatVal.measuredHeight)
y = viewSatVal.measuredHeight.toFloat()
currentColorHsv[1] = 1f / viewSatVal.measuredWidth * x
currentColorHsv[2] = 1f - 1f / viewSatVal.measuredHeight * y
moveColorPicker()
viewNewColor.setFillWithStroke(getColor(), backgroundColor)
newHexField.setText(getHexCode(getColor()))
return@OnTouchListener true
}
false
})
newHexField.onTextChangeListener {
if (it.length == 6 && !isHueBeingDragged) {
try {
val newColor = Color.parseColor("#$it")
Color.colorToHSV(newColor, currentColorHsv)
updateHue()
moveColorPicker()
} catch (ignored: Exception) {
}
}
}
val textColor = activity.getProperTextColor()
val builder = activity.getAlertDialogBuilder()
.setPositiveButton(R.string.ok) { _, _ -> confirmNewColor() }
.setNeutralButton(R.string.default_color) { _, _ -> confirmDefaultColor() }
.setOnCancelListener { dialogDismissed() }
builder.apply {
activity.setupDialogStuff(view, this) { alertDialog ->
dialog = alertDialog
view.color_picker_arrow.applyColorFilter(textColor)
view.color_picker_hex_arrow.applyColorFilter(textColor)
viewCursor.applyColorFilter(textColor)
}
}
view.onGlobalLayout {
moveHuePicker()
moveColorPicker()
}
}
private fun View.setupRecentColors() {
val recentColors = baseConfig.colorPickerRecentColors
if (recentColors.isNotEmpty()) {
recent_colors.beVisible()
val squareSize = context.resources.getDimensionPixelSize(R.dimen.colorpicker_hue_width)
recentColors.take(RECENT_COLORS_NUMBER).forEach { recentColor ->
val recentColorView = ImageView(context)
recentColorView.id = View.generateViewId()
recentColorView.layoutParams = ViewGroup.LayoutParams(squareSize, squareSize)
recentColorView.setFillWithStroke(recentColor, backgroundColor)
recentColorView.setOnClickListener { newHexField.setText(getHexCode(recentColor)) }
recent_colors.addView(recentColorView)
recent_colors_flow.addView(recentColorView)
}
}
}
private fun dialogDismissed() {
callback(false, 0)
}
private fun confirmDefaultColor() {
callback(true, 0)
}
private fun confirmNewColor() {
val hexValue = newHexField.value
val newColor = if (hexValue.length == 6) {
Color.parseColor("#$hexValue")
} else {
getColor()
}
addRecentColor(newColor)
callback(true, newColor)
}
private fun addRecentColor(color: Int) {
var recentColors = baseConfig.colorPickerRecentColors
recentColors.remove(color)
if (recentColors.size >= RECENT_COLORS_NUMBER) {
val numberOfColorsToDrop = recentColors.size - RECENT_COLORS_NUMBER + 1
recentColors = LinkedList(recentColors.dropLast(numberOfColorsToDrop))
}
recentColors.addFirst(color)
baseConfig.colorPickerRecentColors = recentColors
}
private fun getHexCode(color: Int) = color.toHex().substring(1)
private fun updateHue() {
viewSatVal.setHue(getHue())
moveHuePicker()
viewNewColor.setFillWithStroke(getColor(), backgroundColor)
if (removeDimmedBackground && !wasDimmedBackgroundRemoved) {
dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
wasDimmedBackgroundRemoved = true
}
currentColorCallback?.invoke(getColor())
}
private fun moveHuePicker() {
var y = viewHue.measuredHeight - getHue() * viewHue.measuredHeight / 360f
if (y == viewHue.measuredHeight.toFloat())
y = 0f
viewCursor.x = (viewHue.left - viewCursor.width).toFloat()
viewCursor.y = viewHue.top + y - viewCursor.height / 2
}
private fun moveColorPicker() {
val x = getSat() * viewSatVal.measuredWidth
val y = (1f - getVal()) * viewSatVal.measuredHeight
viewTarget.x = viewSatVal.left + x - viewTarget.width / 2
viewTarget.y = viewSatVal.top + y - viewTarget.height / 2
}
private fun getColor() = Color.HSVToColor(currentColorHsv)
private fun getHue() = currentColorHsv[0]
private fun getSat() = currentColorHsv[1]
private fun getVal() = currentColorHsv[2]
}

View file

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/color_picker_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/activity_margin"
android:layout_marginBottom="@dimen/activity_margin">
<RelativeLayout
android:id="@+id/color_picker_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/recent_colors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/activity_margin"
android:layout_marginTop="@dimen/activity_margin">
<androidx.constraintlayout.helper.widget.Flow
android:id="@+id/recent_colors_flow"
android:layout_width="match_parent"
android:layout_height="0dp"
app:flow_horizontalAlign="start"
app:flow_horizontalGap="@dimen/activity_margin"
app:flow_horizontalStyle="packed"
app:flow_maxElementsWrap="5"
app:flow_verticalGap="@dimen/medium_margin"
app:flow_wrapMode="chain"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout
android:id="@+id/color_picker_top_holder"
android:layout_width="match_parent"
android:layout_height="@dimen/colorpicker_size_with_padding"
android:layout_below="@+id/recent_colors"
android:gravity="center_horizontal">
<com.simplemobiletools.commons.views.ColorPickerSquare
android:id="@+id/color_picker_square"
android:layout_width="@dimen/colorpicker_size"
android:layout_height="@dimen/colorpicker_size"
android:layout_centerVertical="true"
android:layerType="software" />
<ImageView
android:id="@+id/color_picker_hue"
android:layout_width="@dimen/colorpicker_hue_width"
android:layout_height="@dimen/colorpicker_size"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/medium_margin"
android:layout_toEndOf="@id/color_picker_square"
android:scaleType="fitXY"
android:src="@drawable/img_color_picker_hue" />
<ImageView
android:id="@+id/color_picker_hue_cursor"
android:layout_width="8dp"
android:layout_height="wrap_content"
android:src="@drawable/ic_chevron_right_unpadded_vector" />
<ImageView
android:id="@+id/color_picker_cursor"
android:layout_width="@dimen/activity_margin"
android:layout_height="@dimen/activity_margin"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/color_picker_circle" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/color_picker_hex_codes_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/color_picker_top_holder">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/color_picker_old_hex"
android:layout_width="@dimen/colorpicker_color_width"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_toStartOf="@+id/color_picker_hex_arrow"
android:gravity="center"
android:textSize="@dimen/normal_text_size" />
<ImageView
android:id="@+id/color_picker_hex_arrow"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignTop="@+id/color_picker_new_hex"
android:layout_alignBottom="@+id/color_picker_new_hex"
android:layout_centerInParent="true"
android:layout_marginStart="@dimen/normal_margin"
android:layout_marginEnd="@dimen/normal_margin"
android:scaleType="centerInside"
android:src="@drawable/ic_arrow_right_vector" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/color_picker_new_hex_label"
android:layout_width="wrap_content"
android:layout_height="@dimen/colorpicker_items_height"
android:layout_alignTop="@+id/color_picker_new_hex"
android:layout_alignBottom="@+id/color_picker_new_hex"
android:layout_toEndOf="@+id/color_picker_hex_arrow"
android:gravity="center"
android:text="#"
android:textSize="@dimen/normal_text_size" />
<com.simplemobiletools.commons.views.MyEditText
android:id="@+id/color_picker_new_hex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/color_picker_new_hex_label"
android:digits="0123456789ABCDEFabcdef"
android:ems="5"
android:gravity="start"
android:lines="1"
android:maxLength="6"
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/color_picker_bottom_holder"
android:layout_width="match_parent"
android:layout_height="@dimen/colorpicker_items_height"
android:layout_below="@id/color_picker_hex_codes_holder"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin">
<ImageView
android:id="@+id/color_picker_old_color"
android:layout_width="@dimen/colorpicker_items_height"
android:layout_height="@dimen/colorpicker_items_height"
android:layout_toStartOf="@+id/color_picker_arrow"
android:background="@android:color/white" />
<ImageView
android:id="@+id/color_picker_arrow"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerInParent="true"
android:layout_marginStart="@dimen/normal_margin"
android:layout_marginEnd="@dimen/normal_margin"
android:scaleType="centerInside"
android:src="@drawable/ic_arrow_right_vector" />
<ImageView
android:id="@+id/color_picker_new_color"
android:layout_width="@dimen/colorpicker_items_height"
android:layout_height="@dimen/colorpicker_items_height"
android:layout_toEndOf="@+id/color_picker_arrow"
android:background="@android:color/white" />
</RelativeLayout>
</RelativeLayout>
</ScrollView>