RustAssistant/app/src/main/java/com/coldmint/rust/pro/EditModInfoActivity.kt

582 lines
22 KiB
Kotlin
Raw Normal View History

2022-04-04 14:03:10 +00:00
package com.coldmint.rust.pro
import com.coldmint.rust.pro.base.BaseActivity
import com.coldmint.rust.core.ModClass
import android.annotation.SuppressLint
import android.os.Bundle
import android.content.Intent
2022-08-19 06:51:28 +00:00
import android.content.res.ColorStateList
2022-04-04 14:03:10 +00:00
import com.bumptech.glide.Glide
import android.graphics.BitmapFactory
import com.yalantis.ucrop.UCrop
import androidx.recyclerview.widget.LinearLayoutManager
import android.os.Build
import android.graphics.drawable.AnimatedVectorDrawable
import android.net.Uri
import android.view.KeyEvent
2022-08-14 02:43:53 +00:00
import android.view.LayoutInflater
2022-04-04 14:03:10 +00:00
import android.view.MenuItem
import android.view.View
import android.widget.*
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.pro.adapters.MapAndMusicAdapter
import com.coldmint.rust.pro.databinding.ActivityEditModInfoBinding
import com.coldmint.rust.pro.tool.GlobalMethod
import java.io.File
import java.lang.StringBuilder
import java.util.ArrayList
class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
private var mExpandMusicList = false
private var mExpandMapList = false
private var mNeedIcon = false
private lateinit var mModClass: ModClass
private lateinit var dataBaseFiles: DataBaseFiles
data class DataBaseFiles(
private val oldFile: File,
private val oldShmFile: File,
private val oldWalFile: File
) {
/**
* 重命名数据库
* @param dataBaseFiles DataBaseFiles
*/
fun renameTo(dataBaseFiles: DataBaseFiles) {
oldFile.renameTo(dataBaseFiles.oldFile)
oldShmFile.renameTo(dataBaseFiles.oldShmFile)
oldWalFile.renameTo(dataBaseFiles.oldWalFile)
}
}
/**
* 创建文件数据库
* @param name
*/
fun createDataBaseFiles(name: String): DataBaseFiles {
val dataBasePath = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
applicationContext.dataDir.absolutePath + "/databases/"
} else {
FileOperator.getSuperDirectory(
cacheDir
) + "/databases/"
}
return DataBaseFiles(
File(dataBasePath + name),
File(dataBasePath + name + "-shm"),
File(dataBasePath + name + "-wal")
)
}
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) {
2022-08-10 09:27:38 +00:00
title = getText(R.string.mod_action2)
2022-04-04 14:03:10 +00:00
setReturnButton()
val intent = intent
val bundle = intent.getBundleExtra("data")
if (bundle == null) {
showError("无效的文件")
return
}
val modPath = bundle.getString("modPath")
mModClass = ModClass(File(modPath))
dataBaseFiles = createDataBaseFiles(mModClass.modName)
initData()
initAction()
}
}
2022-08-19 06:51:28 +00:00
/**
* 加载默认图像
*/
fun loadDefaultImage() {
val drawable = getDrawable(R.drawable.image)
viewBinding.iconView.setImageDrawable(
GlobalMethod.tintDrawable(
drawable,
ColorStateList.valueOf(GlobalMethod.getColorPrimary(this))
)
)
}
2022-04-04 14:03:10 +00:00
fun initData() {
val name = mModClass.readValueFromInfoSection("title", "mod")
if (name != null) {
viewBinding.modNameEdit.setText(name)
}
val description = mModClass.readValueFromInfoSection("description", "mod")
if (description != null) {
viewBinding.modDescribeEdit.setText(description)
}
val modIcon = mModClass.modIcon
if (modIcon == null) {
2022-08-19 06:51:28 +00:00
loadDefaultImage()
} else {
Glide.with(this@EditModInfoActivity).load(modIcon)
2022-08-19 06:51:28 +00:00
.apply(GlobalMethod.getRequestOptions()).into(viewBinding.iconView)
2022-04-04 14:03:10 +00:00
mNeedIcon = true
}
val musicSourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "music")
if (musicSourceFolder == null) {
enableMusic(false)
} else {
enableMusic(true)
val playExclusivelyData = mModClass.readValueFromInfoSection(
"whenUsingUnitsFromThisMod_playExclusively",
"music"
)
if (playExclusivelyData == null) {
viewBinding.playExclusively.isChecked = false
} else {
viewBinding.playExclusively.isChecked = playExclusivelyData == "true"
}
}
val mapSourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "maps")
if (mapSourceFolder == null) {
enableMap(false)
} else {
enableMap(true)
val addExtraMapsForPath =
mModClass.readValueFromInfoSection("addExtraMapsForPath", "maps")
if (addExtraMapsForPath == null) {
viewBinding.addExtraMapsForPathSwitch.isChecked = false
} else {
viewBinding.addExtraMapsForPathSwitch.isChecked = addExtraMapsForPath == "true"
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
if (saveInfoFile()) {
finish()
}
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
if (saveInfoFile()) {
finish()
}
return true
}
return super.onKeyDown(keyCode, event)
}
/**
* 保存信息文件
*
* @return true保存成功, false保存失败
*/
private fun saveInfoFile(): Boolean {
val resultBuilder = StringBuilder()
resultBuilder.append("[mod]\ntitle:")
val modName = viewBinding.modNameEdit.text.toString()
if (modName.isBlank()) {
setErrorAndInput(
viewBinding.modNameEdit,
getString(R.string.name_error),
viewBinding.modNameInputLayout
)
return false
}
resultBuilder.append(modName)
resultBuilder.append("\ndescription:")
val description = viewBinding.modDescribeEdit.text.toString()
if (description.isBlank()) {
setErrorAndInput(
viewBinding.modDescribeEdit,
getString(R.string.describe_error),
viewBinding.modDescribeInputLayout
)
return false
}
if (description.contains("\n")) {
setErrorAndInput(
viewBinding.modDescribeEdit,
getString(R.string.describe_error2),
viewBinding.modDescribeInputLayout
)
return false
}
resultBuilder.append(description)
if (mNeedIcon) {
var iconName = mModClass.readValueFromInfoSection("thumbnail", "mod")
if (iconName == null) {
iconName = "icon.png"
}
resultBuilder.append("\nthumbnail:")
resultBuilder.append(iconName)
}
val enabledMusicData = viewBinding.enabledMusic.text.toString()
if (enabledMusicData == getString(R.string.disabled)) {
var sourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "music")
if (sourceFolder == null) {
sourceFolder = "music/"
}
resultBuilder.append("\n[music]\nsourceFolder:")
resultBuilder.append(sourceFolder)
if (viewBinding.playExclusively.isChecked) {
resultBuilder.append("\nwhenUsingUnitsFromThisMod_playExclusively:true")
}
}
val enabledMapData = viewBinding.enabledMap.text.toString()
if (enabledMapData == getString(R.string.disabled)) {
var sourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "maps")
if (sourceFolder == null) {
sourceFolder = "maps/"
}
resultBuilder.append("\n[maps]\nsourceFolder:")
resultBuilder.append(sourceFolder)
if (viewBinding.addExtraMapsForPathSwitch.isChecked) {
resultBuilder.append("\naddExtraMapsForPath:true")
}
}
//更新缓存目录
val newDataBase = createDataBaseFiles(modName)
dataBaseFiles.renameTo(newDataBase)
return FileOperator.writeFile(mModClass.infoFile, resultBuilder.toString())
}
fun initAction() {
viewBinding.modNameEdit.addTextChangedListener {
viewBinding.modNameInputLayout.isErrorEnabled = false
}
viewBinding.modDescribeEdit.addTextChangedListener {
viewBinding.modDescribeInputLayout.isErrorEnabled = false
}
viewBinding.iconView.setOnClickListener {
val popupMenu = GlobalMethod.createPopMenu(it)
2022-04-04 14:03:10 +00:00
if (mNeedIcon) {
popupMenu.menu.add(R.string.change_image)
popupMenu.menu.add(R.string.del_image)
} else {
popupMenu.menu.add(R.string.select_image)
}
popupMenu.setOnMenuItemClickListener { item ->
val title = item.title.toString()
if (title == getString(R.string.change_image) || title == getString(R.string.select_image)) {
//选择文件
val startIntent =
Intent(this@EditModInfoActivity, FileManagerActivity::class.java)
val fileBundle = Bundle()
fileBundle.putString("type", "selectFile")
fileBundle.putString("path", mModClass.modFile.absolutePath)
startIntent.putExtra("data", fileBundle)
startActivityForResult(startIntent, 3)
} else {
val iconFile = iconPath
if (iconFile.exists()) {
iconFile.delete()
mNeedIcon = false
}
2022-08-19 06:51:28 +00:00
loadDefaultImage()
2022-04-04 14:03:10 +00:00
}
false
}
popupMenu.show()
}
viewBinding.expandMusicList.setOnClickListener { showMusicConfigurationView(mExpandMusicList) }
viewBinding.expandMapList.setOnClickListener { showMapConfigurationView(mExpandMapList) }
viewBinding.enabledMusic.setOnClickListener {
val type = viewBinding.enabledMusic.text.toString()
enableMusic(type == getString(R.string.enabled))
}
viewBinding.enabledMap.setOnClickListener {
val type = viewBinding.enabledMap.text.toString()
enableMap(type == getString(R.string.enabled))
}
viewBinding.addMusic.setOnClickListener { //选择文件
val startIntent = Intent(this@EditModInfoActivity, FileManagerActivity::class.java)
val fileBundle = Bundle()
fileBundle.putString("type", "selectFile")
fileBundle.putString("path", mModClass.modFile.absolutePath)
startIntent.putExtra("data", fileBundle)
startActivityForResult(startIntent, 1)
}
viewBinding.addMap.setOnClickListener { //选择文件
val startIntent = Intent(this@EditModInfoActivity, FileManagerActivity::class.java)
val fileBundle = Bundle()
fileBundle.putString("type", "selectFile")
fileBundle.putString("path", mModClass.modFile.absolutePath)
startIntent.putExtra("data", fileBundle)
startActivityForResult(startIntent, 2)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && data != null) {
if (requestCode == 1) {
val filePath = data.getStringExtra("File") ?: return
val from = File(filePath)
if (FileOperator.getFileType(from) == "ogg") {
val musicFolder = musicFolder
val to = File(musicFolder.absolutePath + "/" + from.name)
if (FileOperator.copyFile(from, to)) {
showMusicConfigurationView(false)
}
} else {
Toast.makeText(
this@EditModInfoActivity,
R.string.bad_file_type,
Toast.LENGTH_SHORT
).show()
}
} else if (requestCode == 2) {
val filePath = data.getStringExtra("File") ?: return
val from = File(filePath)
if (FileOperator.getFileType(from) == "tmx") {
val fromPath = from.absolutePath
val symbol = fromPath.indexOf(".tmx")
val mapFolder = mapFolder
val iconFile = File(fromPath.substring(0, symbol) + "_map.png")
if (iconFile.exists()) {
val newIcon = File(mapFolder.absolutePath + "/" + iconFile.name)
FileOperator.copyFile(iconFile, newIcon)
}
val to = File(mapFolder.absolutePath + "/" + from.name)
if (FileOperator.copyFile(from, to)) {
showMapConfigurationView(false)
}
} else {
Toast.makeText(
this@EditModInfoActivity,
R.string.bad_file_type,
Toast.LENGTH_SHORT
).show()
}
} else if (requestCode == 3) {
val filePath = data.getStringExtra("File") ?: return
val newIconFile = File(filePath)
val iconFile = iconPath
if (newIconFile.absolutePath != iconFile.absolutePath) {
if (iconFile.exists()) {
iconFile.delete()
}
val bitmap = BitmapFactory.decodeFile(newIconFile.absolutePath)
2023-02-16 12:25:27 +00:00
if (bitmap != null && bitmap.height == bitmap.width) {
2022-04-04 14:03:10 +00:00
if (FileOperator.copyFile(newIconFile, iconFile)) {
2022-08-19 06:51:28 +00:00
Glide.with(this@EditModInfoActivity).load(newIconFile)
.apply(GlobalMethod.getRequestOptions())
2022-04-04 14:03:10 +00:00
.into(viewBinding.iconView)
mNeedIcon = true
}
} else {
UCrop.of(
Uri.parse(newIconFile.toURI().toString()),
Uri.parse(iconFile.toURI().toString())
).withAspectRatio(1f, 1f).start(this@EditModInfoActivity)
}
}
} else if (requestCode == UCrop.REQUEST_CROP) {
val resultUri = UCrop.getOutput(data)
2022-08-19 06:51:28 +00:00
Glide.with(this@EditModInfoActivity).load(resultUri)
.apply(GlobalMethod.getRequestOptions()).into(viewBinding.iconView)
2022-04-04 14:03:10 +00:00
mNeedIcon = true
}
}
}
/**
* 启用背景音乐
*
* @param enable 是否启用
*/
fun enableMusic(enable: Boolean) {
if (enable) {
viewBinding.musicListView.isVisible = true
viewBinding.addMusic.isVisible = true
viewBinding.musicPathView.isVisible = false
viewBinding.expandMusicList.isVisible = true
viewBinding.enabledMusic.text = getString(R.string.disabled)
} else {
showMusicConfigurationView(true)
viewBinding.musicListView.isVisible = false
viewBinding.addMusic.isVisible = false
viewBinding.expandMusicList.isVisible = false
viewBinding.enabledMusic.text = getText(R.string.enabled)
viewBinding.musicPathView.text = getString(R.string.no_enabled)
viewBinding.musicPathView.isVisible = true
}
}
/**
* 获取音乐目录
*
* @return 音乐目录
*/
private val musicFolder: File
private get() {
var sourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "music")
if (sourceFolder == null) {
sourceFolder = "music/"
}
return File(mModClass.modFile.absolutePath + "/" + sourceFolder)
}
/**
* 获取图标路径
*
* @return 图标路径
*/
private val iconPath: File
private get() {
var iconName = mModClass.readValueFromInfoSection("thumbnail", "mod")
if (iconName == null) {
iconName = "icon.png"
}
return File(mModClass.modFile.absolutePath + "/" + iconName)
}
/**
* 展示音乐配置视图
*
* @param hide 隐藏视图
*/
@SuppressLint("StringFormatMatches")
fun showMusicConfigurationView(hide: Boolean) {
if (hide) {
viewBinding.expandMusicList.setImageResource(R.drawable.animator_expand_off)
mExpandMusicList = false
viewBinding.musicOperation.isVisible = false
viewBinding.musicPathView.isVisible = false
} else {
viewBinding.expandMusicList.setImageResource(R.drawable.animator_expand_on)
mExpandMusicList = true
viewBinding.musicOperation.isVisible = true
val musicFolder = musicFolder
if (!musicFolder.exists()) {
musicFolder.mkdirs()
}
val files = ArrayList<File>()
val fileArray = musicFolder.listFiles()
if (fileArray.isNotEmpty()) {
for (f in fileArray) {
if (FileOperator.getFileType(f) == "ogg") {
files.add(f)
}
}
}
val mapAndMusicAdapter = MapAndMusicAdapter(this, files, true)
val layoutManager = LinearLayoutManager(this@EditModInfoActivity)
mapAndMusicAdapter.setItemChangeEvent { changeType, i, file, i2 ->
viewBinding.musicPathView.text =
String.format(getString(R.string.filenum), i2)
}
viewBinding.musicListView.layoutManager = layoutManager
viewBinding.musicListView.adapter = mapAndMusicAdapter
viewBinding.musicPathView.isVisible = true
viewBinding.musicPathView.text = String.format(getString(R.string.filenum), files.size)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
(viewBinding.expandMusicList.drawable as AnimatedVectorDrawable).start()
} else {
(viewBinding.expandMusicList.drawable as AnimatedVectorDrawableCompat).start()
}
}
/**
* 启用地图
*
* @param enable 是否启用
*/
fun enableMap(enable: Boolean) {
if (enable) {
viewBinding.expandMapList.isVisible = true
viewBinding.addMap.isVisible = true
viewBinding.mapPathView.isVisible = false
viewBinding.enabledMap.text = getString(R.string.disabled)
} else {
showMapConfigurationView(true)
viewBinding.expandMapList.isVisible = false
viewBinding.addMap.isVisible = false
viewBinding.enabledMap.text = getText(R.string.enabled)
viewBinding.mapPathView.text = getString(R.string.no_enabled)
viewBinding.mapPathView.isVisible = true
}
}
/**
* 获取地图目录
*
* @return 地图目录
*/
private val mapFolder: File
private get() {
var sourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "map")
if (sourceFolder == null) {
sourceFolder = "maps/"
}
return File(mModClass.modFile.absolutePath + "/" + sourceFolder)
}
/**
* 展示地图配置视图
*
* @param hide 隐藏视图
*/
@SuppressLint("StringFormatMatches")
fun showMapConfigurationView(hide: Boolean) {
if (hide) {
viewBinding.expandMapList.setImageResource(R.drawable.animator_expand_off)
mExpandMapList = false
viewBinding.mapOperation.isVisible = false
viewBinding.mapPathView.isVisible = false
} else {
viewBinding.expandMapList.setImageResource(R.drawable.animator_expand_on)
mExpandMapList = true
viewBinding.mapOperation.isVisible = true
val mapFolder = mapFolder
if (!mapFolder.exists()) {
mapFolder.mkdirs()
}
val files = ArrayList<File>()
val fileArray = mapFolder.listFiles()
if (fileArray.isNotEmpty()) {
for (f in fileArray) {
if (FileOperator.getFileType(f) == "tmx") {
files.add(f)
}
}
}
val mapAndMapAdapter = MapAndMusicAdapter(this, files, false)
val layoutManager = LinearLayoutManager(this@EditModInfoActivity)
mapAndMapAdapter.setItemChangeEvent { changeType, i, file, i2 ->
viewBinding.mapPathView.text =
String.format(getString(R.string.filenum), i2)
}
viewBinding.mapListView.layoutManager = layoutManager
viewBinding.mapListView.adapter = mapAndMapAdapter
viewBinding.mapPathView.isVisible = true
viewBinding.mapPathView.text = String.format(getString(R.string.filenum), files.size)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
(viewBinding.expandMapList.drawable as AnimatedVectorDrawable).start()
} else {
(viewBinding.expandMapList.drawable as AnimatedVectorDrawableCompat).start()
}
}
2022-08-14 02:43:53 +00:00
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityEditModInfoBinding {
2022-04-04 14:03:10 +00:00
return ActivityEditModInfoBinding.inflate(layoutInflater)
}
}