forked from github/szkolny
[UI] Add event type colors to type dropdown.
This commit is contained in:
parent
db598af28a
commit
297867cbf3
@ -4,8 +4,6 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.event
|
||||
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
@ -26,7 +24,6 @@ import pl.szczodrzynski.edziennik.data.api.events.ApiTaskErrorEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskFinishedEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||
@ -35,7 +32,6 @@ import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.RegistrationConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.modules.views.TimeDropdown.Companion.DISPLAY_LESSONS
|
||||
import pl.szczodrzynski.edziennik.utils.Anim
|
||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
@ -323,57 +319,41 @@ class EventManualDialog(
|
||||
selectDefault(defaultLesson?.displayTeacherId)
|
||||
}
|
||||
|
||||
with (b.typeDropdown) {
|
||||
db = app.db
|
||||
profileId = this@EventManualDialog.profileId
|
||||
loadItems()
|
||||
selectDefault(editingEvent?.type)
|
||||
selectDefault(defaultType)
|
||||
|
||||
val deferred = async(Dispatchers.Default) {
|
||||
// get the event type list
|
||||
var eventTypes = app.db.eventTypeDao().getAllNow(profileId)
|
||||
|
||||
if (eventTypes.none { it.id in -1L..10L }) {
|
||||
eventTypes = app.db.eventTypeDao().addDefaultTypes(activity, profileId)
|
||||
onTypeSelected = {
|
||||
b.typeColor.background.setTintColor(it.color)
|
||||
customColor = null
|
||||
}
|
||||
}
|
||||
|
||||
b.typeDropdown.clear()
|
||||
b.typeDropdown += eventTypes.map { TextInputDropDown.Item(it.id, it.name, tag = it) }
|
||||
}
|
||||
deferred.await()
|
||||
|
||||
b.typeDropdown.isEnabled = true
|
||||
|
||||
defaultType?.let {
|
||||
b.typeDropdown.select(it)
|
||||
}
|
||||
|
||||
b.typeDropdown.selected?.let { item ->
|
||||
customColor = (item.tag as EventType).color
|
||||
}
|
||||
|
||||
// copy IDs from event being edited
|
||||
// copy data from event being edited
|
||||
editingEvent?.let {
|
||||
b.topic.setText(it.topic)
|
||||
b.typeDropdown.select(it.type)?.let { item ->
|
||||
customColor = (item.tag as EventType).color
|
||||
}
|
||||
if (it.color != null && it.color != -1)
|
||||
if (it.color != -1)
|
||||
customColor = it.color
|
||||
}
|
||||
|
||||
b.typeColor.background.setTintColor(
|
||||
customColor
|
||||
?: b.typeDropdown.getSelected()?.color
|
||||
?: Event.COLOR_DEFAULT
|
||||
)
|
||||
|
||||
// copy IDs from the LessonFull
|
||||
defaultLesson?.let {
|
||||
b.teamDropdown.select(it.displayTeamId)
|
||||
}
|
||||
|
||||
b.typeDropdown.setOnChangeListener {
|
||||
b.typeColor.background.colorFilter = PorterDuffColorFilter((it.tag as EventType).color, PorterDuff.Mode.SRC_ATOP)
|
||||
customColor = null
|
||||
return@setOnChangeListener true
|
||||
}
|
||||
|
||||
(customColor ?: Event.COLOR_DEFAULT).let {
|
||||
b.typeColor.background.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_ATOP)
|
||||
}
|
||||
|
||||
b.typeColor.onClick {
|
||||
val currentColor = (b.typeDropdown.selected?.tag as EventType?)?.color ?: Event.COLOR_DEFAULT
|
||||
val currentColor = customColor
|
||||
?: b.typeDropdown.getSelected()?.color
|
||||
?: Event.COLOR_DEFAULT
|
||||
val colorPickerDialog = ColorPickerDialog.newBuilder()
|
||||
.setColor(currentColor)
|
||||
.create()
|
||||
@ -381,7 +361,7 @@ class EventManualDialog(
|
||||
object : ColorPickerDialogListener {
|
||||
override fun onDialogDismissed(dialogId: Int) {}
|
||||
override fun onColorSelected(dialogId: Int, color: Int) {
|
||||
b.typeColor.background.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
b.typeColor.background.setTintColor(color)
|
||||
customColor = color
|
||||
}
|
||||
})
|
||||
@ -597,7 +577,12 @@ class EventManualDialog(
|
||||
}
|
||||
}
|
||||
|
||||
onSaveListener?.invoke(eventObject.withMetadata(metadataObject))
|
||||
onSaveListener?.invoke(eventObject.withMetadata(metadataObject).also {
|
||||
it.subjectLongName = b.subjectDropdown.selected?.text?.toString()
|
||||
it.teacherName = b.teacherDropdown.selected?.text?.toString()
|
||||
it.teamName = b.teamDropdown.selected?.text?.toString()
|
||||
it.typeName = b.typeDropdown.selected?.text?.toString()
|
||||
})
|
||||
dialog.dismiss()
|
||||
Toast.makeText(activity, R.string.saved, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-4-14.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.views
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||
|
||||
class EventTypeDropdown : TextInputDropDown {
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
private val activity: AppCompatActivity?
|
||||
get() {
|
||||
var context: Context? = context ?: return null
|
||||
if (context is AppCompatActivity) return context
|
||||
while (context is ContextWrapper) {
|
||||
if (context is AppCompatActivity)
|
||||
return context
|
||||
context = context.baseContext
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
lateinit var db: AppDb
|
||||
var profileId: Int = 0
|
||||
var onTypeSelected: ((eventType: EventType) -> Unit)? = null
|
||||
|
||||
override fun create(context: Context) {
|
||||
super.create(context)
|
||||
isEnabled = false
|
||||
}
|
||||
|
||||
suspend fun loadItems() {
|
||||
val types = withContext(Dispatchers.Default) {
|
||||
val list = mutableListOf<Item>()
|
||||
|
||||
var types = db.eventTypeDao().getAllNow(profileId)
|
||||
|
||||
if (types.none { it.id in -1L..10L }) {
|
||||
types = db.eventTypeDao().addDefaultTypes(context, profileId)
|
||||
}
|
||||
|
||||
list += types.map {
|
||||
Item(it.id, it.name, tag = it, icon = IconicsDrawable(context).apply {
|
||||
icon = CommunityMaterial.Icon.cmd_circle
|
||||
sizeDp = 24
|
||||
colorInt = it.color
|
||||
})
|
||||
}
|
||||
|
||||
list
|
||||
}
|
||||
|
||||
clear().append(types)
|
||||
isEnabled = true
|
||||
|
||||
setOnChangeListener {
|
||||
when (it.tag) {
|
||||
is EventType -> {
|
||||
// selected an event type
|
||||
onTypeSelected?.invoke(it.tag)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an event type by the [typeId].
|
||||
*/
|
||||
fun selectType(typeId: Long) {
|
||||
select(typeId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an event type by the [typeId] **if it's not selected yet**.
|
||||
*/
|
||||
fun selectDefault(typeId: Long?) {
|
||||
if (typeId == null || selected != null)
|
||||
return
|
||||
selectType(typeId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently selected event type.
|
||||
* ### Returns:
|
||||
* - null if no valid type is selected
|
||||
* - [EventType] - the selected event type
|
||||
*/
|
||||
fun getSelected(): EventType? {
|
||||
return when (selected?.tag) {
|
||||
is EventType -> selected?.tag as EventType
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
@ -84,6 +84,9 @@ class TeacherDropdown : TextInputDropDown {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a teacher by the [teacherId].
|
||||
*/
|
||||
fun selectTeacher(teacherId: Long) {
|
||||
if (select(teacherId) == null)
|
||||
select(Item(
|
||||
@ -93,6 +96,9 @@ class TeacherDropdown : TextInputDropDown {
|
||||
))
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a teacher by the [teacherId] **if it's not selected yet**.
|
||||
*/
|
||||
fun selectDefault(teacherId: Long?) {
|
||||
if (teacherId == null || selected != null)
|
||||
return
|
||||
|
@ -1,7 +1,11 @@
|
||||
package pl.szczodrzynski.edziennik.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
import androidx.appcompat.view.menu.MenuPopupHelper
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
@ -33,6 +37,7 @@ open class TextInputDropDown : TextInputEditText {
|
||||
setText(selected?.displayText ?: selected?.text)
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
open fun create(context: Context) {
|
||||
val drawable = IconicsDrawable(context, CommunityMaterial.Icon.cmd_chevron_down).apply {
|
||||
colorInt = Themes.getPrimaryTextColor(context)
|
||||
@ -58,7 +63,9 @@ open class TextInputDropDown : TextInputEditText {
|
||||
val popup = PopupMenu(context, this)
|
||||
|
||||
items.forEachIndexed { index, item ->
|
||||
popup.menu.add(0, item.id.toInt(), index, item.text)
|
||||
popup.menu.add(0, item.id.toInt(), index, item.text).also {
|
||||
it.icon = item.icon
|
||||
}
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener { menuItem ->
|
||||
@ -70,29 +77,46 @@ open class TextInputDropDown : TextInputEditText {
|
||||
true
|
||||
}
|
||||
|
||||
popup.setOnDismissListener {
|
||||
val helper = MenuPopupHelper(context, popup.menu as MenuBuilder, this)
|
||||
helper.setForceShowIcon(true)
|
||||
helper.setOnDismissListener {
|
||||
clearFocus()
|
||||
}
|
||||
|
||||
popup.show()
|
||||
helper.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun select(item: Item): Item? {
|
||||
/**
|
||||
* Select an arbitrary [item]. Allows to select an item not present
|
||||
* in the original list.
|
||||
*/
|
||||
fun select(item: Item): Item {
|
||||
selected = item
|
||||
updateText()
|
||||
error = null
|
||||
return item
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an item by its ID. Returns the selected item
|
||||
* if found.
|
||||
*/
|
||||
fun select(id: Long?): Item? {
|
||||
return items.singleOrNull { it.id == id }?.let { select(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an item by its tag. Returns the selected item
|
||||
* if found.
|
||||
*/
|
||||
fun select(tag: Any?): Item? {
|
||||
return items.singleOrNull { it.tag == tag }?.let { select(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an item by its index. Returns the selected item
|
||||
* if the index exists.
|
||||
*/
|
||||
fun select(index: Int): Item? {
|
||||
return items.getOrNull(index)?.let { select(it) }
|
||||
}
|
||||
@ -143,5 +167,11 @@ open class TextInputDropDown : TextInputEditText {
|
||||
}
|
||||
}
|
||||
|
||||
class Item(val id: Long, val text: CharSequence, val displayText: CharSequence? = null, val tag: Any? = null)
|
||||
class Item(
|
||||
val id: Long,
|
||||
val text: CharSequence,
|
||||
val displayText: CharSequence? = null,
|
||||
val tag: Any? = null,
|
||||
val icon: Drawable? = null
|
||||
)
|
||||
}
|
||||
|
@ -94,7 +94,7 @@
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/dialog_event_manual_type">
|
||||
|
||||
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||
<pl.szczodrzynski.edziennik.ui.modules.views.EventTypeDropdown
|
||||
android:id="@+id/typeDropdown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
Loading…
Reference in New Issue
Block a user