ultrasonic-app-subsonic-and.../ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/ServerRowAdapter.kt

210 lines
6.7 KiB
Kotlin
Raw Normal View History

2021-02-08 21:46:31 +01:00
package org.moire.ultrasonic.fragment
import android.content.Context
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.TextView
2021-10-14 17:17:32 +02:00
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ServerSetting
import org.moire.ultrasonic.model.ServerSettingsModel
2021-10-14 17:17:32 +02:00
import org.moire.ultrasonic.util.ServerColor
import org.moire.ultrasonic.util.Util
/**
* Row Adapter to be used in the Server List
* Converts a Server Setting into a displayable Row, and sets up the Row's context menu
* @param manageMode: set to True if the default action by clicking the row is to edit the server
* In Manage Mode the "Offline" setting is not visible, and the servers can be edited by
* clicking the row.
*/
internal class ServerRowAdapter(
private var context: Context,
private var data: Array<ServerSetting>,
private val model: ServerSettingsModel,
private val activeServerProvider: ActiveServerProvider,
private val manageMode: Boolean,
private val serverDeletedCallback: ((Int) -> Unit),
private val serverEditRequestedCallback: ((Int) -> Unit)
) : BaseAdapter() {
companion object {
private const val MENU_ID_EDIT = 1
private const val MENU_ID_DELETE = 2
private const val MENU_ID_UP = 3
private const val MENU_ID_DOWN = 4
}
var inflater: LayoutInflater =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
fun setData(data: Array<ServerSetting>) {
this.data = data
notifyDataSetChanged()
}
override fun getCount(): Int {
return if (manageMode) data.size else data.size + 1
}
override fun getItem(position: Int): Any {
return data[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
/**
* Creates the Row representation of a Server Setting
*/
@Suppress("LongMethod")
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
var index = position
// Skip "Offline" in manage mode
if (manageMode) index++
var vi: View? = convertView
if (vi == null) vi = inflater.inflate(R.layout.server_row, parent, false)
val text = vi?.findViewById<TextView>(R.id.server_name)
val description = vi?.findViewById<TextView>(R.id.server_description)
2021-10-14 17:17:32 +02:00
val layout = vi?.findViewById<ConstraintLayout>(R.id.server_layout)
val image = vi?.findViewById<ImageView>(R.id.server_image)
val serverMenu = vi?.findViewById<ImageButton>(R.id.server_menu)
2021-10-14 17:17:32 +02:00
val setting = data.singleOrNull { t -> t.index == index }
if (index == 0) {
text?.text = context.getString(R.string.main_offline)
description?.text = ""
} else {
2020-09-25 10:43:33 +02:00
text?.text = setting?.name ?: ""
description?.text = setting?.url ?: ""
if (setting == null) serverMenu?.visibility = View.INVISIBLE
}
val icon: Drawable?
val background: Drawable?
// Configure icons for the row
if (index == 0) {
serverMenu?.visibility = View.INVISIBLE
icon = Util.getDrawableFromAttribute(context, R.attr.screen_on_off)
background = ContextCompat.getDrawable(context, R.drawable.circle)
} else {
icon = ContextCompat.getDrawable(context, R.drawable.ic_menu_server_dark)
background = ContextCompat.getDrawable(context, R.drawable.circle)
}
// Set colors
icon?.setTint(ServerColor.getForegroundColor(context, setting?.color))
background?.setTint(ServerColor.getBackgroundColor(context, setting?.color))
// Set the final drawables
image?.setImageDrawable(icon)
image?.background = background
// Highlight the Active Server's row by changing its background
if (index == activeServerProvider.getActiveServer().index) {
2021-10-30 16:07:47 +02:00
layout?.background = ContextCompat.getDrawable(context, R.drawable.select_ripple)
} else {
2021-10-30 16:07:47 +02:00
layout?.background = ContextCompat.getDrawable(context, R.drawable.default_ripple)
}
// Add the context menu for the row
2021-10-30 16:07:47 +02:00
serverMenu?.background = ContextCompat.getDrawable(
context,
R.drawable.select_ripple_circle
)
serverMenu?.setOnClickListener { view -> serverMenuClick(view, index) }
return vi
}
/**
* Builds the Context Menu of a row when the "more" icon is clicked
*/
private fun serverMenuClick(view: View, position: Int) {
val menu = PopupMenu(context, view)
val firstServer = 1
var lastServer = count - 1
if (!manageMode) {
menu.menu.add(
Menu.NONE,
MENU_ID_EDIT,
Menu.NONE,
context.getString(R.string.server_menu_edit)
)
} else {
lastServer++
}
menu.menu.add(
Menu.NONE,
MENU_ID_DELETE,
Menu.NONE,
context.getString(R.string.server_menu_delete)
)
if (position != firstServer) {
menu.menu.add(
Menu.NONE,
MENU_ID_UP,
Menu.NONE,
context.getString(R.string.server_menu_move_up)
)
}
if (position != lastServer) {
menu.menu.add(
Menu.NONE,
MENU_ID_DOWN,
Menu.NONE,
context.getString(R.string.server_menu_move_down)
)
}
menu.show()
menu.setOnMenuItemClickListener { menuItem -> popupMenuItemClick(menuItem, position) }
}
/**
* Handles the click on a context menu item
*/
private fun popupMenuItemClick(menuItem: MenuItem, position: Int): Boolean {
when (menuItem.itemId) {
MENU_ID_EDIT -> {
serverEditRequestedCallback.invoke(position)
return true
}
MENU_ID_DELETE -> {
serverDeletedCallback.invoke(position)
return true
}
MENU_ID_UP -> {
model.moveItemUp(position)
return true
}
MENU_ID_DOWN -> {
model.moveItemDown(position)
return true
}
else -> return false
}
}
}