This repository has been archived by the owner on Nov 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
631 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package mods | ||
|
||
import android.database.sqlite.SQLiteDatabase | ||
import org.jetbrains.anko.db.* | ||
|
||
enum class ModType(val v: Int) { | ||
Plugin(1), | ||
Resource(2); | ||
|
||
companion object { | ||
private val reverseValues: Map<Int, ModType> = values().associate { it.v to it } | ||
fun valueFrom(i: Int): ModType = reverseValues.getValue(i) | ||
} | ||
} | ||
|
||
/** | ||
* Representation of a single mod in the database | ||
* @param type Type of the mod: plugin or resource | ||
* @param filename Filename of the mod, without the path | ||
* @param order Load order, or order in the list | ||
* @param enabled Whether the mod is enabled | ||
*/ | ||
class Mod(val type: ModType, val filename: String, var order: Int, var enabled: Boolean) { | ||
|
||
/// Set to true when DB update is needed to keep consistency | ||
var dirty: Boolean = false | ||
|
||
/** | ||
* Updates the representation of this mod in the database | ||
* @param db Database connection | ||
*/ | ||
fun update(db: SQLiteDatabase) { | ||
db.update("mod", | ||
"load_order" to order, | ||
"enabled" to enabled) | ||
.whereArgs("filename = {filename} AND type = {type}", | ||
"filename" to filename, | ||
"type" to type.v).exec() | ||
} | ||
|
||
/** | ||
* Inserts this mod into the database | ||
* @param db Database connection | ||
*/ | ||
fun insert(db: SQLiteDatabase) { | ||
db.insert("mod", | ||
"type" to type.v, | ||
"filename" to filename, | ||
"load_order" to order, | ||
"enabled" to (if (enabled) 1 else 0)) | ||
} | ||
} | ||
|
||
class ModRowParser : RowParser<Mod> { | ||
override fun parseRow(columns: Array<Any?>): Mod { | ||
return Mod( | ||
ModType.valueFrom((columns[0] as Long).toInt()), | ||
columns[1] as String, | ||
(columns[2] as Long).toInt(), | ||
(columns[3] as Long) != 0L) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package mods | ||
|
||
import android.support.v7.widget.RecyclerView | ||
import android.support.v7.widget.helper.ItemTouchHelper | ||
|
||
/** | ||
* Callback for dragging the mods around to change load order | ||
*/ | ||
class ModMoveCallback(private val mAdapter: ModsAdapter) : ItemTouchHelper.Callback() { | ||
|
||
override fun isLongPressDragEnabled(): Boolean { | ||
return true | ||
} | ||
|
||
override fun isItemViewSwipeEnabled(): Boolean { | ||
return false | ||
} | ||
|
||
|
||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) { | ||
|
||
} | ||
|
||
override fun getMovementFlags(recyclerView: RecyclerView, | ||
viewHolder: RecyclerView.ViewHolder): Int { | ||
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN | ||
return ItemTouchHelper.Callback.makeMovementFlags(dragFlags, 0) | ||
} | ||
|
||
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, | ||
target: RecyclerView.ViewHolder): Boolean { | ||
mAdapter.onRowMoved(viewHolder.adapterPosition, target.adapterPosition) | ||
return true | ||
} | ||
|
||
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, | ||
actionState: Int) { | ||
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { | ||
if (viewHolder is ModsAdapter.ModViewHolder) { | ||
mAdapter.onRowSelected(viewHolder) | ||
} | ||
} | ||
|
||
super.onSelectedChanged(viewHolder, actionState) | ||
} | ||
|
||
override fun clearView(recyclerView: RecyclerView?, | ||
viewHolder: RecyclerView.ViewHolder) { | ||
super.clearView(recyclerView, viewHolder) | ||
|
||
if (viewHolder is ModsAdapter.ModViewHolder) { | ||
mAdapter.onRowClear(viewHolder) | ||
} | ||
} | ||
|
||
/** | ||
* Speed up dragging of a list element | ||
*/ | ||
override fun interpolateOutOfBoundsScroll(recyclerView: RecyclerView, viewSize: Int, | ||
viewSizeOutOfBounds: Int, totalSize: Int, | ||
msSinceStartScroll: Long): Int { | ||
val direction = Math.signum(viewSizeOutOfBounds.toFloat()).toInt() | ||
return 20 * direction | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package mods | ||
|
||
import android.annotation.SuppressLint | ||
import android.graphics.Color | ||
import android.support.v7.widget.RecyclerView | ||
import android.support.v7.widget.helper.ItemTouchHelper | ||
import android.view.LayoutInflater | ||
import android.view.MotionEvent | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.widget.CheckBox | ||
import android.widget.ImageView | ||
import android.widget.TextView | ||
import com.libopenmw.openmw.R | ||
import java.util.* | ||
|
||
/** | ||
* An adapter to put a ModsCollection into a UI list | ||
*/ | ||
class ModsAdapter(private val collection: ModsCollection) : RecyclerView.Adapter<ModsAdapter.ModViewHolder>() { | ||
|
||
lateinit var touchHelper: ItemTouchHelper | ||
|
||
/** | ||
* A row representation of a mod | ||
*/ | ||
inner class ModViewHolder(internal var rowView: View) : RecyclerView.ViewHolder(rowView) { | ||
val mTitle: TextView = rowView.findViewById(R.id.txtTitle) | ||
val mHandle: ImageView = rowView.findViewById(R.id.handle) | ||
val mCheckbox: CheckBox = rowView.findViewById(R.id.modCheckbox) | ||
} | ||
|
||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ModViewHolder { | ||
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.mod_item, parent, false) | ||
return ModViewHolder(itemView) | ||
} | ||
|
||
@SuppressLint("ClickableViewAccessibility") | ||
override fun onBindViewHolder(holder: ModViewHolder, position: Int) { | ||
val mod = collection.mods[position] | ||
holder.mTitle.text = mod.filename | ||
holder.mHandle.setOnTouchListener { _, event -> | ||
if (event.action == MotionEvent.ACTION_DOWN) { | ||
touchHelper.startDrag(holder) | ||
} | ||
false | ||
} | ||
holder.mCheckbox.isChecked = mod.enabled | ||
holder.mCheckbox.setOnClickListener { | ||
mod.enabled = (it as CheckBox).isChecked | ||
mod.dirty = true | ||
collection.update() | ||
} | ||
} | ||
|
||
override fun getItemCount(): Int { | ||
return collection.mods.size | ||
} | ||
|
||
private fun swapMods(from: Int, to: Int) { | ||
// Swap the orders | ||
val tmp = collection.mods[from].order | ||
collection.mods[from].order = collection.mods[to].order | ||
collection.mods[to].order = tmp | ||
|
||
// Swap the mods inside the list | ||
Collections.swap(collection.mods, from, to) | ||
|
||
// Mark mods as dirty to update when the user releases currently dragged mod | ||
collection.mods[from].dirty = true | ||
collection.mods[to].dirty = true | ||
} | ||
|
||
fun onRowMoved(fromPosition: Int, toPosition: Int) { | ||
if (fromPosition < toPosition) { | ||
for (i in fromPosition until toPosition) { | ||
swapMods(i, i + 1) | ||
} | ||
} else { | ||
for (i in fromPosition downTo toPosition + 1) { | ||
swapMods(i, i - 1) | ||
} | ||
} | ||
notifyItemMoved(fromPosition, toPosition) | ||
} | ||
|
||
fun onRowSelected(modViewHolder: ModViewHolder) { | ||
modViewHolder.rowView.setBackgroundColor(Color.LTGRAY) | ||
} | ||
|
||
fun onRowClear(modViewHolder: ModViewHolder) { | ||
modViewHolder.rowView.setBackgroundColor(Color.WHITE) | ||
collection.update() | ||
} | ||
} |
Oops, something went wrong.