mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-23 13:08:00 +01:00
rewrite the Directory adapter, prepare it for drag-selection
This commit is contained in:
parent
09d4793e75
commit
44a71c032b
2 changed files with 96 additions and 59 deletions
|
@ -124,6 +124,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
config.temporarilyShowHidden = false
|
config.temporarilyShowHidden = false
|
||||||
|
DirectoryAdapter.cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryloadGallery() {
|
private fun tryloadGallery() {
|
||||||
|
|
|
@ -29,29 +29,36 @@ import java.util.*
|
||||||
class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Directory>, val listener: DirOperationsListener?, val itemClick: (Directory) -> Unit) :
|
class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Directory>, val listener: DirOperationsListener?, val itemClick: (Directory) -> Unit) :
|
||||||
RecyclerView.Adapter<DirectoryAdapter.ViewHolder>() {
|
RecyclerView.Adapter<DirectoryAdapter.ViewHolder>() {
|
||||||
|
|
||||||
val multiSelector = MultiSelector()
|
|
||||||
val views = ArrayList<View>()
|
val views = ArrayList<View>()
|
||||||
val config = activity.config
|
val config = activity.config
|
||||||
var pinnedFolders = config.pinnedFolders
|
var pinnedFolders = config.pinnedFolders
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
val multiSelector = MultiSelector()
|
||||||
var actMode: ActionMode? = null
|
var actMode: ActionMode? = null
|
||||||
val markedItems = HashSet<Int>()
|
|
||||||
var foregroundColor = 0
|
var foregroundColor = 0
|
||||||
var backgroundColor = 0
|
var backgroundColor = 0
|
||||||
var animateGifs = true
|
var animateGifs = true
|
||||||
var itemCnt = 0
|
var itemCnt = 0
|
||||||
|
var itemViews: HashMap<Int, View> = HashMap()
|
||||||
|
val selectedPositions: HashSet<Int> = HashSet()
|
||||||
|
|
||||||
fun toggleItemSelection(itemView: View, select: Boolean, pos: Int = -1) {
|
fun toggleItemSelection(select: Boolean, pos: Int) {
|
||||||
getProperView(itemView).isSelected = select
|
if (itemViews[pos] != null)
|
||||||
|
getProperView(itemViews[pos]!!).isSelected = select
|
||||||
if (pos == -1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (select)
|
if (select)
|
||||||
markedItems.add(pos)
|
selectedPositions.add(pos)
|
||||||
else
|
else
|
||||||
markedItems.remove(pos)
|
selectedPositions.remove(pos)
|
||||||
|
|
||||||
|
if (selectedPositions.isEmpty()) {
|
||||||
|
actMode?.finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTitle(selectedPositions.size)
|
||||||
|
actMode?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getProperView(itemView: View): View {
|
fun getProperView(itemView: View): View {
|
||||||
|
@ -64,6 +71,11 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
fun updateTitle(cnt: Int) {
|
fun updateTitle(cnt: Int) {
|
||||||
actMode?.title = "$cnt / $itemCnt"
|
actMode?.title = "$cnt / $itemCnt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun cleanup() {
|
||||||
|
itemViews.clear()
|
||||||
|
selectedPositions.clear()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -100,26 +112,27 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
|
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
|
||||||
val positions = multiSelector.selectedPositions
|
menu.findItem(R.id.cab_rename).isVisible = selectedPositions.size <= 1
|
||||||
menu.findItem(R.id.cab_rename).isVisible = positions.size <= 1
|
|
||||||
|
|
||||||
checkHideBtnVisibility(menu, positions)
|
checkHideBtnVisibility(menu)
|
||||||
checkPinBtnVisibility(menu, positions)
|
checkPinBtnVisibility(menu)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyActionMode(actionMode: ActionMode?) {
|
override fun onDestroyActionMode(actionMode: ActionMode?) {
|
||||||
super.onDestroyActionMode(actionMode)
|
super.onDestroyActionMode(actionMode)
|
||||||
views.forEach { toggleItemSelection(it, false) }
|
selectedPositions.forEach {
|
||||||
markedItems.clear()
|
getProperView(itemViews[it]!!).isSelected = false
|
||||||
|
}
|
||||||
|
selectedPositions.clear()
|
||||||
actMode = null
|
actMode = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkHideBtnVisibility(menu: Menu, positions: List<Int>) {
|
fun checkHideBtnVisibility(menu: Menu) {
|
||||||
var hiddenCnt = 0
|
var hiddenCnt = 0
|
||||||
var unhiddenCnt = 0
|
var unhiddenCnt = 0
|
||||||
positions.map { dirs[it].path }.forEach {
|
selectedPositions.map { dirs[it].path }.forEach {
|
||||||
if (File(it).containsNoMedia())
|
if (File(it).containsNoMedia())
|
||||||
hiddenCnt++
|
hiddenCnt++
|
||||||
else
|
else
|
||||||
|
@ -130,11 +143,11 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
menu.findItem(R.id.cab_unhide).isVisible = hiddenCnt > 0
|
menu.findItem(R.id.cab_unhide).isVisible = hiddenCnt > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkPinBtnVisibility(menu: Menu, positions: List<Int>) {
|
fun checkPinBtnVisibility(menu: Menu) {
|
||||||
val pinnedFolders = config.pinnedFolders
|
val pinnedFolders = config.pinnedFolders
|
||||||
var pinnedCnt = 0
|
var pinnedCnt = 0
|
||||||
var unpinnedCnt = 0
|
var unpinnedCnt = 0
|
||||||
positions.map { dirs[it].path }.forEach {
|
selectedPositions.map { dirs[it].path }.forEach {
|
||||||
if (pinnedFolders.contains(it))
|
if (pinnedFolders.contains(it))
|
||||||
pinnedCnt++
|
pinnedCnt++
|
||||||
else
|
else
|
||||||
|
@ -147,18 +160,17 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showProperties() {
|
private fun showProperties() {
|
||||||
val selections = multiSelector.selectedPositions
|
if (selectedPositions.size <= 1) {
|
||||||
if (selections.size <= 1) {
|
PropertiesDialog(activity, dirs[selectedPositions.first()].path, config.shouldShowHidden)
|
||||||
PropertiesDialog(activity, dirs[selections[0]].path, config.shouldShowHidden)
|
|
||||||
} else {
|
} else {
|
||||||
val paths = ArrayList<String>()
|
val paths = ArrayList<String>()
|
||||||
selections.forEach { paths.add(dirs[it].path) }
|
selectedPositions.forEach { paths.add(dirs[it].path) }
|
||||||
PropertiesDialog(activity, paths, config.shouldShowHidden)
|
PropertiesDialog(activity, paths, config.shouldShowHidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renameDir() {
|
private fun renameDir() {
|
||||||
val path = dirs[multiSelector.selectedPositions[0]].path
|
val path = dirs[selectedPositions.first()].path
|
||||||
val dir = File(path)
|
val dir = File(path)
|
||||||
if (activity.isAStorageRootFolder(dir.absolutePath)) {
|
if (activity.isAStorageRootFolder(dir.absolutePath)) {
|
||||||
activity.toast(R.string.rename_folder_root)
|
activity.toast(R.string.rename_folder_root)
|
||||||
|
@ -167,8 +179,8 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
|
|
||||||
RenameItemDialog(activity, dir.absolutePath) {
|
RenameItemDialog(activity, dir.absolutePath) {
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
actMode?.finish()
|
|
||||||
listener?.refreshItems()
|
listener?.refreshItems()
|
||||||
|
actMode?.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,11 +238,10 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
|
|
||||||
private fun copyMoveTo(isCopyOperation: Boolean) {
|
private fun copyMoveTo(isCopyOperation: Boolean) {
|
||||||
val files = ArrayList<File>()
|
val files = ArrayList<File>()
|
||||||
val positions = multiSelector.selectedPositions
|
if (selectedPositions.isEmpty())
|
||||||
if (positions.isEmpty())
|
|
||||||
return
|
return
|
||||||
|
|
||||||
positions.forEach {
|
selectedPositions.forEach {
|
||||||
val dir = File(dirs[it].path)
|
val dir = File(dirs[it].path)
|
||||||
files.addAll(dir.listFiles().filter { it.isFile && it.isImageVideoGif() })
|
files.addAll(dir.listFiles().filter { it.isFile && it.isImageVideoGif() })
|
||||||
}
|
}
|
||||||
|
@ -246,8 +257,7 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
fun selectAll() {
|
fun selectAll() {
|
||||||
val cnt = dirs.size
|
val cnt = dirs.size
|
||||||
for (i in 0..cnt - 1) {
|
for (i in 0..cnt - 1) {
|
||||||
markedItems.add(i)
|
selectedPositions.add(i)
|
||||||
multiSelector.setSelected(i, 0, true)
|
|
||||||
notifyItemChanged(i)
|
notifyItemChanged(i)
|
||||||
}
|
}
|
||||||
updateTitle(cnt)
|
updateTitle(cnt)
|
||||||
|
@ -256,18 +266,17 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
|
|
||||||
private fun askConfirmDelete() {
|
private fun askConfirmDelete() {
|
||||||
ConfirmationDialog(activity) {
|
ConfirmationDialog(activity) {
|
||||||
actMode?.finish()
|
|
||||||
deleteFiles()
|
deleteFiles()
|
||||||
|
actMode?.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteFiles() {
|
private fun deleteFiles() {
|
||||||
val selections = multiSelector.selectedPositions
|
val folders = ArrayList<File>(selectedPositions.size)
|
||||||
val folders = ArrayList<File>(selections.size)
|
val removeFolders = ArrayList<Directory>(selectedPositions.size)
|
||||||
val removeFolders = ArrayList<Directory>(selections.size)
|
|
||||||
|
|
||||||
var needPermissionForPath = ""
|
var needPermissionForPath = ""
|
||||||
selections.forEach {
|
selectedPositions.forEach {
|
||||||
val path = dirs[it].path
|
val path = dirs[it].path
|
||||||
if (activity.needsStupidWritePermissions(path) && activity.config.treeUri.isEmpty()) {
|
if (activity.needsStupidWritePermissions(path) && activity.config.treeUri.isEmpty()) {
|
||||||
needPermissionForPath = path
|
needPermissionForPath = path
|
||||||
|
@ -275,8 +284,7 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
}
|
}
|
||||||
|
|
||||||
activity.handleSAFDialog(File(needPermissionForPath)) {
|
activity.handleSAFDialog(File(needPermissionForPath)) {
|
||||||
selections.reverse()
|
selectedPositions.reversed().forEach {
|
||||||
selections.forEach {
|
|
||||||
val directory = dirs[it]
|
val directory = dirs[it]
|
||||||
folders.add(File(directory.path))
|
folders.add(File(directory.path))
|
||||||
removeFolders.add(directory)
|
removeFolders.add(directory)
|
||||||
|
@ -284,16 +292,14 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
}
|
}
|
||||||
|
|
||||||
dirs.removeAll(removeFolders)
|
dirs.removeAll(removeFolders)
|
||||||
markedItems.clear()
|
|
||||||
listener?.tryDeleteFolders(folders)
|
listener?.tryDeleteFolders(folders)
|
||||||
itemCnt = dirs.size
|
itemCnt = dirs.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSelectedPaths(): HashSet<String> {
|
private fun getSelectedPaths(): HashSet<String> {
|
||||||
val positions = multiSelector.selectedPositions
|
val paths = HashSet<String>(selectedPositions.size)
|
||||||
val paths = HashSet<String>(positions.size)
|
selectedPositions.forEach { paths.add(dirs[it].path) }
|
||||||
positions.forEach { paths.add(dirs[it].path) }
|
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +310,8 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val dir = dirs[position]
|
val dir = dirs[position]
|
||||||
views.add(holder.bindView(activity, multiSelectorMode, multiSelector, dir, position, pinnedFolders.contains(dir.path)))
|
views.add(holder.bindView(activity, multiSelectorMode, dir, position, pinnedFolders.contains(dir.path), listener))
|
||||||
|
holder.itemView.tag = holder
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewRecycled(holder: ViewHolder?) {
|
override fun onViewRecycled(holder: ViewHolder?) {
|
||||||
|
@ -314,25 +321,61 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
|
|
||||||
override fun getItemCount() = dirs.size
|
override fun getItemCount() = dirs.size
|
||||||
|
|
||||||
|
fun selectRange(from: Int, to: Int, min: Int, max: Int) {
|
||||||
|
if (from == to) {
|
||||||
|
(min..max).filter { it != from }
|
||||||
|
.forEach { toggleItemSelection(false, it) }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to < from) {
|
||||||
|
for (i in to..from)
|
||||||
|
toggleItemSelection(true, i)
|
||||||
|
|
||||||
|
if (min > -1 && min < to) {
|
||||||
|
(min..to - 1).filter { it != from }
|
||||||
|
.forEach { toggleItemSelection(false, it) }
|
||||||
|
}
|
||||||
|
if (max > -1) {
|
||||||
|
for (i in from + 1..max)
|
||||||
|
toggleItemSelection(false, i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i in from..to)
|
||||||
|
toggleItemSelection(true, i)
|
||||||
|
|
||||||
|
if (max > -1 && max > to) {
|
||||||
|
(to + 1..max).filter { it != from }
|
||||||
|
.forEach { toggleItemSelection(false, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min > -1) {
|
||||||
|
for (i in min..from - 1)
|
||||||
|
toggleItemSelection(false, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ViewHolder(val view: View, val itemClick: (Directory) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
class ViewHolder(val view: View, val itemClick: (Directory) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
||||||
fun bindView(activity: SimpleActivity, multiSelectorCallback: ModalMultiSelectorCallback, multiSelector: MultiSelector, directory: Directory, pos: Int, isPinned: Boolean)
|
fun bindView(activity: SimpleActivity, multiSelectorCallback: ModalMultiSelectorCallback, directory: Directory, pos: Int,
|
||||||
: View {
|
isPinned: Boolean, listener: DirOperationsListener?): View {
|
||||||
|
itemViews.put(pos, itemView)
|
||||||
itemView.apply {
|
itemView.apply {
|
||||||
dir_name.text = directory.name
|
dir_name.text = directory.name
|
||||||
photo_cnt.text = directory.mediaCnt.toString()
|
photo_cnt.text = directory.mediaCnt.toString()
|
||||||
dir_pin.visibility = if (isPinned) View.VISIBLE else View.GONE
|
dir_pin.visibility = if (isPinned) View.VISIBLE else View.GONE
|
||||||
toggleItemSelection(this, markedItems.contains(pos), pos)
|
toggleItemSelection(selectedPositions.contains(pos), pos)
|
||||||
activity.loadImage(directory.tmb, dir_thumbnail)
|
activity.loadImage(directory.tmb, dir_thumbnail)
|
||||||
|
|
||||||
setOnClickListener { viewClicked(multiSelector, directory, pos) }
|
setOnClickListener { viewClicked(multiSelector, directory, pos) }
|
||||||
setOnLongClickListener {
|
setOnLongClickListener {
|
||||||
if (!multiSelector.isSelectable) {
|
if (!multiSelector.isSelectable) {
|
||||||
activity.startSupportActionMode(multiSelectorCallback)
|
activity.startSupportActionMode(multiSelectorCallback)
|
||||||
multiSelector.setSelected(this@ViewHolder, true)
|
toggleItemSelection(true, pos)
|
||||||
updateTitle(multiSelector.selectedPositions.size)
|
|
||||||
toggleItemSelection(this, true, pos)
|
|
||||||
actMode?.invalidate()
|
actMode?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listener!!.itemLongClicked(pos)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,17 +389,8 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
|
|
||||||
fun viewClicked(multiSelector: MultiSelector, directory: Directory, pos: Int) {
|
fun viewClicked(multiSelector: MultiSelector, directory: Directory, pos: Int) {
|
||||||
if (multiSelector.isSelectable) {
|
if (multiSelector.isSelectable) {
|
||||||
val isSelected = multiSelector.selectedPositions.contains(layoutPosition)
|
val isSelected = selectedPositions.contains(layoutPosition)
|
||||||
multiSelector.setSelected(this, !isSelected)
|
toggleItemSelection(!isSelected, pos)
|
||||||
toggleItemSelection(itemView, !isSelected, pos)
|
|
||||||
|
|
||||||
val selectedCnt = multiSelector.selectedPositions.size
|
|
||||||
if (selectedCnt == 0) {
|
|
||||||
actMode?.finish()
|
|
||||||
} else {
|
|
||||||
updateTitle(selectedCnt)
|
|
||||||
}
|
|
||||||
actMode?.invalidate()
|
|
||||||
} else {
|
} else {
|
||||||
itemClick(directory)
|
itemClick(directory)
|
||||||
}
|
}
|
||||||
|
@ -371,5 +405,7 @@ class DirectoryAdapter(val activity: SimpleActivity, val dirs: MutableList<Direc
|
||||||
fun refreshItems()
|
fun refreshItems()
|
||||||
|
|
||||||
fun tryDeleteFolders(folders: ArrayList<File>)
|
fun tryDeleteFolders(folders: ArrayList<File>)
|
||||||
|
|
||||||
|
fun itemLongClicked(position: Int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue