同步更新

This commit is contained in:
coldmint 2022-08-22 15:32:10 +08:00
parent ed60f78d35
commit 62096ab2c3
39 changed files with 938 additions and 307 deletions

Binary file not shown.

View File

@ -13,6 +13,9 @@ import android.text.SpannableString
import android.view.* import android.view.*
import android.widget.PopupMenu import android.widget.PopupMenu
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
@ -80,6 +83,9 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
ViewModelProvider(this).get(EditViewModel::class.java) ViewModelProvider(this).get(EditViewModel::class.java)
} }
private lateinit var turretCoordinateResults: ActivityResultLauncher<Intent>
private lateinit var rustLanguage: RustLanguage private lateinit var rustLanguage: RustLanguage
private var fileAdapter: FileAdapter? = null private var fileAdapter: FileAdapter? = null
@ -491,7 +497,12 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
initEndView() initEndView()
showRenewalTip() showRenewalTip()
loadCustomStyle() loadCustomStyle()
turretCoordinateResults =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
viewModel.reloadCode()
}
} else { } else {
title = getString(R.string.mod_action1)
val thisIntent = intent val thisIntent = intent
val bundle = thisIntent.getBundleExtra("data") val bundle = thisIntent.getBundleExtra("data")
if (bundle == null) { if (bundle == null) {
@ -1243,12 +1254,21 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
} }
} }
R.id.turret_design -> { R.id.turret_design -> {
val goIntent = Intent(this, TurretDesignActivity::class.java) val needSave = viewModel.checkOneFileIfNeedSave(
val modPath = viewModel.modClass!!.modFile.absolutePath viewBinding.tabLayout.selectedTabPosition,
val filePath = viewModel.getNowOpenFilePath() viewBinding.codeEditor.text.toString()
goIntent.putExtra("modPath", modPath) )
goIntent.putExtra("filePath", filePath) if (needSave) {
startActivity(goIntent) Snackbar.make(viewBinding.codeEditor, R.string.save_tip, Snackbar.LENGTH_SHORT)
.show()
} else {
val goIntent = Intent(this, TurretDesignActivity::class.java)
val modPath = viewModel.modClass!!.modFile.absolutePath
val filePath = viewModel.getNowOpenFilePath()
goIntent.putExtra("modPath", modPath)
goIntent.putExtra("filePath", filePath)
turretCoordinateResults.launch(goIntent)
}
} }
R.id.display_source_code -> { R.id.display_source_code -> {
val file = File(viewModel.getNowOpenFilePath()) val file = File(viewModel.getNowOpenFilePath())

View File

@ -260,80 +260,75 @@ class EditUserInfoActivity : BaseActivity<ActivityEditUserInfoBinding>() {
}) })
viewBinding.button.setOnClickListener { viewBinding.button.setOnClickListener {
val type = viewBinding.button.text.toString() val userName = viewBinding.userNameView.text.toString()
when (type) { val introduce = viewBinding.signatureView.text.toString()
getString(R.string.edit_function) -> { val genderValue = viewBinding.sexView.text.toString()
val userName = viewBinding.userNameView.text.toString() val boy = getString(R.string.boy)
val introduce = viewBinding.signatureView.text.toString() if (!checkUserName(userName)) {
val genderValue = viewBinding.sexView.text.toString() return@setOnClickListener
val boy = getString(R.string.boy) }
if (!checkUserName(userName)) { if (!checkIntroduce(introduce)) {
return@setOnClickListener return@setOnClickListener
} }
if (!checkIntroduce(introduce)) { val gender = if (genderValue == boy) {
return@setOnClickListener 1
} } else {
val gender = if (genderValue == boy) { -1
1 }
} else { viewBinding.button.hide()
-1 val token =
} AppSettings.getValue(AppSettings.Setting.Token, "")
viewBinding.button.hide() User.updateSpaceInfo(
val token = token,
AppSettings.getValue(AppSettings.Setting.Token, "") userName,
User.updateSpaceInfo( introduce,
token, gender,
userName, object : ApiCallBack<ApiResponse> {
introduce, override fun onResponse(t: ApiResponse) {
gender, if (t.code == ServerConfiguration.Success_Code) {
object : ApiCallBack<ApiResponse> { if (needCleanCache) {
override fun onResponse(t: ApiResponse) { Thread {
if (t.code == ServerConfiguration.Success_Code) { Glide.get(this@EditUserInfoActivity).clearDiskCache()
if (needCleanCache) { runOnUiThread {
Thread { Glide.get(this@EditUserInfoActivity).clearMemory()
Glide.get(this@EditUserInfoActivity).clearDiskCache()
runOnUiThread {
Glide.get(this@EditUserInfoActivity).clearMemory()
finish()
}
}.start()
} else {
finish() finish()
} }
} else { }.start()
viewBinding.button.show() } else {
val data = t.data finish()
if (data != null && ServerConfiguration.isEvent(data)) { }
when (data) { } else {
"@event:用户名占用" -> { viewBinding.button.show()
setErrorAndInput( val data = t.data
viewBinding.userNameView, if (data != null && ServerConfiguration.isEvent(data)) {
getString(R.string.user_name_error), when (data) {
viewBinding.userNameInputLayout "@event:用户名占用" -> {
) setErrorAndInput(
} viewBinding.userNameView,
} getString(R.string.user_name_error),
} else { viewBinding.userNameInputLayout
Snackbar.make( )
viewBinding.button,
t.message,
Snackbar.LENGTH_SHORT
).show()
} }
} }
} else {
Snackbar.make(
viewBinding.button,
t.message,
Snackbar.LENGTH_SHORT
).show()
} }
}
}
override fun onFailure(e: Exception) { override fun onFailure(e: Exception) {
viewBinding.button.show() viewBinding.button.show()
showInternetError(viewBinding.button, e) showInternetError(viewBinding.button, e)
} }
}, },
ServerConfiguration.toRelativePath(iconLink ?: ""), ServerConfiguration.toRelativePath(iconLink ?: ""),
ServerConfiguration.toRelativePath(coverLink ?: "") ServerConfiguration.toRelativePath(coverLink ?: "")
) )
}
}
} }
} }

View File

@ -1,22 +1,20 @@
package com.coldmint.rust.pro package com.coldmint.rust.pro
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.BitmapFactory
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.text.Editable
import android.view.MotionEvent import android.text.TextWatcher
import android.view.View import android.view.*
import android.widget.Toast import android.widget.Toast
import com.bumptech.glide.Glide import com.coldmint.dialog.CoreDialog
import com.coldmint.rust.core.ModClass import com.coldmint.rust.core.ModClass
import com.coldmint.rust.core.SourceFile import com.coldmint.rust.core.SourceFile
import com.coldmint.rust.core.turret.TurretInstaller import com.coldmint.rust.core.turret.TurretManager
import com.coldmint.rust.core.turret.TurretSketchpadView
import com.coldmint.rust.pro.base.BaseActivity import com.coldmint.rust.pro.base.BaseActivity
import com.coldmint.rust.pro.databinding.ActivityTurretDesignBinding import com.coldmint.rust.pro.databinding.ActivityTurretDesignBinding
import com.coldmint.rust.pro.fragments.EditTurretInfoFragment
import com.coldmint.rust.pro.tool.GlobalMethod
import com.google.android.material.snackbar.Snackbar
import java.io.File import java.io.File
/** /**
@ -24,7 +22,9 @@ import java.io.File
*/ */
class TurretDesignActivity : BaseActivity<ActivityTurretDesignBinding>() { class TurretDesignActivity : BaseActivity<ActivityTurretDesignBinding>() {
private lateinit var turretManager: TurretManager
@SuppressLint("RestrictedApi")
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) { override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) { if (canUseView) {
setReturnButton() setReturnButton()
@ -44,32 +44,78 @@ class TurretDesignActivity : BaseActivity<ActivityTurretDesignBinding>() {
val modClass = ModClass(File(modPath)) val modClass = ModClass(File(modPath))
val sourceFile = SourceFile(File(filePath), modClass) val sourceFile = SourceFile(File(filePath), modClass)
val mainImage = sourceFile.findResourceFilesFromSection("image", "graphics", true) val mainImage = sourceFile.findResourceFilesFromSection("image", "graphics", false)
if (mainImage.isNullOrEmpty()) { if (mainImage.isNullOrEmpty()) {
showError("请设置主体图像")
showError(getString(R.string.please_set_main_image))
return return
} else { } else {
val file = mainImage[0] val file = mainImage[0]
if (!file.exists()){
showError(getString(R.string.file_not_exist))
return
}
viewBinding.turretSketchpadView.coordinateColor = GlobalMethod.getColorPrimary(this)
viewBinding.turretSketchpadView.setImage(file.absolutePath) viewBinding.turretSketchpadView.setImage(file.absolutePath)
// viewBinding.toolbar.postDelayed({ turretManager = sourceFile.getTurretManager()
// Toast.makeText(this, "执行", Toast.LENGTH_SHORT).show() turretManager.installerAllTurret(
// viewBinding.turretsDragView.setBaseImage(file.absolutePath) viewBinding.frameLayout,
// }, 1000) viewBinding.turretSketchpadView
// val bitmap = BitmapFactory.decodeFile(file.absolutePath) )
// viewBinding.mainImageView.setImageBitmap(bitmap) turretManager
// val layoutParams = viewBinding.mainImageView.layoutParams .setCoordinateChangeListener { gameCoordinateData, turretData ->
// layoutParams.width = bitmap.width * scale viewBinding.infoView.text =
// layoutParams.height = bitmap.height * scale "x:${gameCoordinateData.x} y:${gameCoordinateData.y}"
}
//设置自动完成
viewBinding.autoCompleteText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(
s: CharSequence?,
start: Int,
before: Int,
count: Int
) {
}
override fun afterTextChanged(s: Editable?) {
turretManager.useTurret(s.toString())
}
})
val nameList = ArrayList<String>()
var isFirst = true
turretManager.turretList.forEach {
if (isFirst) {
viewBinding.autoCompleteText.setText(it.name)
isFirst = false
}
nameList.add(it.name)
}
viewBinding.autoCompleteText.setSimpleItems(nameList.toTypedArray())
} }
// val sketchpadView = TurretSketchpadView(this)
// sketchpadView. viewBinding.button.setOnClickListener {
// viewBinding.frameLayout.addView(sketchpadView) val data = turretManager.getTurretView(viewBinding.autoCompleteText.text.toString())
TurretInstaller.installerAllTurret(viewBinding.frameLayout, sourceFile) { if (data != null) {
val game = viewBinding.turretSketchpadView.toGameCoordinate(it) val editTurretInfoFragment = EditTurretInfoFragment(data)
// viewBinding.textView.text = "坐标 x:${game.x} y:${game.y}" editTurretInfoFragment.show(supportFragmentManager, "Edit")
} else {
Toast.makeText(this, R.string.not_find_turret, Toast.LENGTH_SHORT).show()
}
} }
} }
} }
@ -77,4 +123,59 @@ class TurretDesignActivity : BaseActivity<ActivityTurretDesignBinding>() {
return ActivityTurretDesignBinding.inflate(layoutInflater) return ActivityTurretDesignBinding.inflate(layoutInflater)
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_turret_design, menu)
val item = menu.findItem(R.id.display_coordinate_system)
val suggestedDisplay = viewBinding.turretSketchpadView.isSuggestedDisplayCoordinateSystem()
if (!suggestedDisplay) {
//如果不建议显示,且正在显示那么提示用户
if (viewBinding.turretSketchpadView.drawCoordinate) {
CoreDialog(this).setTitle(R.string.turret_design)
.setMessage(R.string.automatically_disable_coordinate_system)
.setPositiveButton(R.string.dialog_ok) {
}.show()
viewBinding.turretSketchpadView.drawCoordinate = false
}
item.isEnabled = false
item.isChecked = false
}
return true
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
saveData()
return true
}
return super.onKeyDown(keyCode, event)
}
/**
* 保存数据
*/
fun saveData() {
turretManager.saveChange()
finish()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.display_coordinate_system -> {
viewBinding.turretSketchpadView.drawCoordinate =
!viewBinding.turretSketchpadView.drawCoordinate
item.isChecked = viewBinding.turretSketchpadView.drawCoordinate
}
R.id.show_guides -> {
viewBinding.turretSketchpadView.drawAuxiliaryLine =
!viewBinding.turretSketchpadView.drawAuxiliaryLine
item.isChecked = viewBinding.turretSketchpadView.drawAuxiliaryLine
}
android.R.id.home -> {
saveData()
}
}
return super.onOptionsItemSelected(item)
}
} }

View File

@ -11,9 +11,10 @@ import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.base.BaseAdapter import com.coldmint.rust.pro.base.BaseAdapter
import com.coldmint.rust.pro.databinding.WebModItemBinding import com.coldmint.rust.pro.databinding.WebModItemBinding
import com.coldmint.rust.pro.tool.GlobalMethod import com.coldmint.rust.pro.tool.GlobalMethod
import me.zhanghai.android.fastscroll.PopupTextProvider
class WebModAdapter( context: Context, dataList: MutableList<WebModListData.Data>) : class WebModAdapter( context: Context, dataList: MutableList<WebModListData.Data>) :
BaseAdapter<WebModItemBinding, WebModListData.Data>(context, dataList) { BaseAdapter<WebModItemBinding, WebModListData.Data>(context, dataList) , PopupTextProvider {
override fun getViewBindingObject( override fun getViewBindingObject(
layoutInflater: LayoutInflater, layoutInflater: LayoutInflater,
@ -61,4 +62,8 @@ class WebModAdapter( context: Context, dataList: MutableList<WebModListData.Dat
.into(viewBinding.modIcon) .into(viewBinding.modIcon)
} }
} }
override fun getPopupText(position: Int): String {
return dataList[position].downloadNumber.toString()
}
} }

View File

@ -47,7 +47,7 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
//节补丁 //节补丁
if (RustAutoCompleteProvider.keyWord.startsWith('[') && RustAutoCompleteProvider.keyWord.length > 1) { if (RustAutoCompleteProvider.keyWord.startsWith('[') && RustAutoCompleteProvider.keyWord.length > 1) {
RustAutoCompleteProvider.keyWord = RustAutoCompleteProvider.keyWord =
RustAutoCompleteProvider.keyWord.subSequence(1, RustAutoCompleteProvider.keyWord.length) RustAutoCompleteProvider.keyWord.subSequence(0, RustAutoCompleteProvider.keyWord.length)
.toString() .toString()
} }
val start = label.lowercase(Locale.getDefault()) val start = label.lowercase(Locale.getDefault())

View File

@ -57,6 +57,7 @@ class CommunityFragment : BaseFragment<CommunityFragmentBinding>() {
override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) { override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) {
viewBinding.pager.adapter = communityAdapter viewBinding.pager.adapter = communityAdapter
viewBinding.pager.isSaveEnabled = false
loadTab() loadTab()
} }

View File

@ -0,0 +1,91 @@
package com.coldmint.rust.pro.fragments
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.coldmint.rust.core.turret.CoordinateData
import com.coldmint.rust.core.turret.TurretData
import com.coldmint.rust.core.turret.TurretView
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.base.BaseFragment
import com.coldmint.rust.pro.databinding.FragmentEditTurretInfoBinding
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* 编辑炮塔信息碎片
* @property fragmentEditTurretInfoBinding FragmentEditTurretInfoBinding
*/
class EditTurretInfoFragment(val turretView: TurretView) : BottomSheetDialogFragment() {
private lateinit var fragmentEditTurretInfoBinding: FragmentEditTurretInfoBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
fragmentEditTurretInfoBinding =
FragmentEditTurretInfoBinding.inflate(layoutInflater, container, false)
return fragmentEditTurretInfoBinding.root
}
fun enableButton() {
val x = fragmentEditTurretInfoBinding.xInputEditText.text.toString()
val y = fragmentEditTurretInfoBinding.yInputEditText.text.toString()
fragmentEditTurretInfoBinding.saveButton.isEnabled = !(x.isBlank() || y.isBlank())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
fragmentEditTurretInfoBinding.xInputEditText.setText(turretView.getTurretData()!!.gameCoordinateData.x.toString())
fragmentEditTurretInfoBinding.yInputEditText.setText(turretView.getTurretData()!!.gameCoordinateData.y.toString())
fragmentEditTurretInfoBinding.xInputEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val text = s.toString()
if (text.isBlank()) {
fragmentEditTurretInfoBinding.xInputEditLayout.error =
getString(R.string.please_enter_the_x_coordinate)
} else {
fragmentEditTurretInfoBinding.xInputEditLayout.isErrorEnabled = false
}
enableButton()
}
})
fragmentEditTurretInfoBinding.yInputEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val text = s.toString()
if (text.isBlank()) {
fragmentEditTurretInfoBinding.yInputEditLayout.error =
getString(R.string.please_enter_the_y_coordinate)
} else {
fragmentEditTurretInfoBinding.yInputEditLayout.isErrorEnabled = false
}
enableButton()
}
})
fragmentEditTurretInfoBinding.saveButton.setOnClickListener {
val x = fragmentEditTurretInfoBinding.xInputEditText.text.toString().toInt()
val y = fragmentEditTurretInfoBinding.yInputEditText.text.toString().toInt()
turretView.setGameCoordinateData(CoordinateData(x, y))
dialog?.dismiss()
}
}
}

View File

@ -36,6 +36,7 @@ import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import me.zhanghai.android.fastscroll.FastScrollScrollView import me.zhanghai.android.fastscroll.FastScrollScrollView
import me.zhanghai.android.fastscroll.FastScrollerBuilder import me.zhanghai.android.fastscroll.FastScrollerBuilder
import java.io.File import java.io.File
@ -69,7 +70,7 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
index: Int? = null index: Int? = null
) { ) {
val scope = CoroutineScope(Job()) val scope = CoroutineScope(Job())
scope.run { scope.launch {
val targetFile = modClass.modFile val targetFile = modClass.modFile
val errorFolder = val errorFolder =
File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName) File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName)
@ -182,7 +183,7 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
fun loadModList() { fun loadModList() {
val scope = CoroutineScope(Job()) val scope = CoroutineScope(Job())
val handler = Handler(Looper.getMainLooper()) val handler = Handler(Looper.getMainLooper())
scope.run { scope.launch {
val dataList = viewModel.loadMod() val dataList = viewModel.loadMod()
handler.post { handler.post {
viewBinding.progressBar.isVisible = true viewBinding.progressBar.isVisible = true

View File

@ -15,6 +15,7 @@ import com.coldmint.rust.pro.WebModInfoActivity
import com.coldmint.rust.pro.adapters.WebModAdapter import com.coldmint.rust.pro.adapters.WebModAdapter
import com.coldmint.rust.pro.base.BaseFragment import com.coldmint.rust.pro.base.BaseFragment
import com.coldmint.rust.pro.databinding.FragmentRankingBinding import com.coldmint.rust.pro.databinding.FragmentRankingBinding
import me.zhanghai.android.fastscroll.FastScrollerBuilder
/** /**
* 排行榜 * 排行榜
@ -43,6 +44,11 @@ class RankingFragment : BaseFragment<FragmentRankingBinding>() {
} }
} }
}) })
viewBinding.swipeRefreshLayout.setOnRefreshListener {
loadMods()
viewBinding.swipeRefreshLayout.isRefreshing = false
}
} }
override fun onResume() { override fun onResume() {
@ -58,13 +64,15 @@ class RankingFragment : BaseFragment<FragmentRankingBinding>() {
if (list != null && list.isNotEmpty()) { if (list != null && list.isNotEmpty()) {
viewBinding.progressBar.isVisible = false viewBinding.progressBar.isVisible = false
viewBinding.textview.isVisible = false viewBinding.textview.isVisible = false
viewBinding.recyclerView.isVisible = true viewBinding.swipeRefreshLayout.isVisible = true
viewBinding.recyclerView.adapter = createAdapter(list) val adapter = createAdapter(list)
viewBinding.recyclerView.adapter = adapter
linearLayoutManager.scrollToPositionWithOffset( linearLayoutManager.scrollToPositionWithOffset(
lastPosition, lastPosition,
lastOffset lastOffset
) )
FastScrollerBuilder(viewBinding.recyclerView).useMd2Style()
.setPopupTextProvider(adapter).build()
} else { } else {
showInfoToView(R.string.network_error) showInfoToView(R.string.network_error)
} }
@ -113,7 +121,7 @@ class RankingFragment : BaseFragment<FragmentRankingBinding>() {
*/ */
fun showInfoToView(textRes: Int? = null, text: String? = null) { fun showInfoToView(textRes: Int? = null, text: String? = null) {
viewBinding.progressBar.isVisible = false viewBinding.progressBar.isVisible = false
viewBinding.recyclerView.isVisible = false viewBinding.swipeRefreshLayout.isVisible = false
viewBinding.textview.isVisible = true viewBinding.textview.isVisible = true
if (textRes == null) { if (textRes == null) {
viewBinding.textview.setText(textRes) viewBinding.textview.setText(textRes)

View File

@ -176,6 +176,32 @@ class EditViewModel(application: Application) : BaseAndroidViewModel(application
openedSourceFileListLiveData.remove(openedSourceFile) openedSourceFileListLiveData.remove(openedSourceFile)
} }
/**
* 重载当前打开的文件
*/
fun reloadCode() {
executorService.submit {
openedSourceFileListLiveData.value.forEach {
if (it.file.absolutePath == getNowOpenFilePath()) {
val code = FileOperator.readFile(File(getNowOpenFilePath())) ?: return@submit
it.setTranslation(code)
codeCompiler2.translation(code, object : CodeTranslatorListener {
override fun beforeTranslate() {
}
override fun onTranslateComplete(code: String) {
codeLiveData.postValue(code)
loadingLiveData.postValue(false)
}
})
return@submit
}
}
}
}
/** /**
* 打开文件 * 打开文件
* 打开文件到编辑器内 * 打开文件到编辑器内
@ -229,7 +255,7 @@ class EditViewModel(application: Application) : BaseAndroidViewModel(application
/** /**
* 检查文件是否需要保存 * 检查文件是否需要保存
* @param selectedIndex Int * @param selectedIndex Int
* @param text String * @param text String
*/ */
@ -250,6 +276,18 @@ class EditViewModel(application: Application) : BaseAndroidViewModel(application
} }
/**
*检查当前文件是否需要保存
* @param selectedIndex Int
* @param text String
* @return Boolean
*/
fun checkOneFileIfNeedSave(selectedIndex: Int, text: String): Boolean {
val openedSourceFile = openedSourceFileListLiveData.value[selectedIndex]
return openedSourceFile.isChanged(text)
}
/** /**
* 移除文件在数据库内 * 移除文件在数据库内
* @param file File * @param file File
@ -537,7 +575,6 @@ class EditViewModel(application: Application) : BaseAndroidViewModel(application
} }
/** /**
* 加载数据 * 加载数据
*/ */

View File

@ -154,10 +154,10 @@
android:layout_marginBottom="48dp"> android:layout_marginBottom="48dp">
<LinearLayout <LinearLayout
android:animateLayoutChanges="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_margin="16dp" android:layout_margin="16dp"
android:animateLayoutChanges="true"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@ -190,10 +190,10 @@
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/dimCardView" android:id="@+id/dimCardView"
android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"> android:layout_marginTop="16dp"
android:visibility="gone">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -224,11 +224,11 @@
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/imageCardView" android:id="@+id/imageCardView"
android:visibility="gone"
style="@style/Widget.Material3.CardView.Outlined" style="@style/Widget.Material3.CardView.Outlined"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"> android:layout_marginTop="16dp"
android:visibility="gone">
<ImageView <ImageView
android:id="@+id/imageView" android:id="@+id/imageView"
@ -240,13 +240,13 @@
<Button <Button
android:visibility="gone"
android:id="@+id/autoGenerateColorSchemeButton" android:id="@+id/autoGenerateColorSchemeButton"
android:text="@string/auto_generate_color_scheme"
style="@style/Widget.Material3.Button.OutlinedButton" style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_marginTop="16dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:text="@string/auto_generate_color_scheme"
android:visibility="gone" />
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
@ -256,14 +256,13 @@
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/button" android:id="@+id/button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|right" android:layout_gravity="bottom|right"
android:layout_margin="16dp" android:layout_margin="16dp"
android:text="@string/edit_function" android:src="@drawable/round_save_20" />
app:icon="@drawable/round_save_20" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -139,26 +139,26 @@
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<!-- <RelativeLayout--> <!-- <RelativeLayout-->
<!-- android:layout_width="match_parent"--> <!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"--> <!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="8dp">--> <!-- android:layout_marginTop="8dp">-->
<!-- <TextView--> <!-- <TextView-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"--> <!-- android:layout_height="wrap_content"-->
<!-- android:layout_centerVertical="true"--> <!-- android:layout_centerVertical="true"-->
<!-- android:text="@string/profile_picture_box_color" />--> <!-- android:text="@string/profile_picture_box_color" />-->
<!-- <Button--> <!-- <Button-->
<!-- android:id="@+id/changeColorButton"--> <!-- android:id="@+id/changeColorButton"-->
<!-- style="@style/Widget.Material3.Button.OutlinedButton"--> <!-- style="@style/Widget.Material3.Button.OutlinedButton"-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"--> <!-- android:layout_height="wrap_content"-->
<!-- android:layout_alignParentEnd="true"--> <!-- android:layout_alignParentEnd="true"-->
<!-- android:text="@string/choose_color" />--> <!-- android:text="@string/choose_color" />-->
<!-- </RelativeLayout>--> <!-- </RelativeLayout>-->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -186,13 +186,12 @@
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/button" android:id="@+id/button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|right" android:layout_gravity="bottom|right"
android:layout_margin="16dp" android:layout_margin="16dp"
app:icon="@drawable/ic_outline_save_24" android:src="@drawable/round_save_20"
android:text="@string/edit_function"
android:visibility="gone" /> android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -64,13 +64,13 @@
</LinearLayout> </LinearLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="44dp" android:layout_height="44dp"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_margin="16dp" android:layout_margin="16dp"
app:icon="@drawable/add" /> android:src="@drawable/add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -53,7 +53,7 @@
app:defaultNavHost="true" app:defaultNavHost="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/mainButton" android:id="@+id/mainButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -61,8 +61,7 @@
android:layout_margin="16dp" android:layout_margin="16dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp" android:layout_marginBottom="24dp"
android:text="@string/create" android:src="@drawable/add" />
app:icon="@drawable/add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -263,11 +263,10 @@
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/packButton" android:id="@+id/packButton"
app:icon="@drawable/zip"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|right" android:layout_gravity="bottom|right"
android:layout_margin="16dp" android:layout_margin="16dp"
android:text="@string/packmod" /> app:icon="@drawable/zip" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -348,13 +348,12 @@
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/releaseButton" android:id="@+id/releaseButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|right" android:layout_gravity="bottom|right"
android:layout_margin="16dp" android:layout_margin="16dp"
android:text="@string/release" android:src="@drawable/ic_outline_send_24" />
app:icon="@drawable/ic_outline_send_24" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -86,7 +86,7 @@
</LinearLayout> </LinearLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -94,7 +94,6 @@
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_margin="16dp" android:layout_margin="16dp"
app:icon="@drawable/build" android:src="@drawable/build"/>
android:text="@string/build_unit"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context=".MainActivity"> tools:context=".MainActivity">
@ -31,56 +32,95 @@
android:id="@+id/frameLayout" android:id="@+id/frameLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_above="@id/cardView"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_gravity="center"> android:layout_gravity="center">
<com.coldmint.rust.core.turret.TurretSketchpadView <com.coldmint.rust.core.turret.TurretSketchpadView
android:id="@+id/turretSketchpadView" android:id="@+id/turretSketchpadView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardView"
style="@style/Widget.Material3.CardView.Filled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/nameView"
style="@style/TextAppearance.Material3.HeadlineSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/control_panel" />
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_marginTop="16dp"
android:hint="@string/turret"
android:layout_height="wrap_content">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:layout_width="match_parent"
android:inputType="none"
android:id="@+id/autoCompleteText"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp">
<TextView
android:id="@+id/infoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/button"
android:text="@string/info" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="@string/edit" />
</RelativeLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</RelativeLayout> </RelativeLayout>
<FrameLayout
android:id="@+id/standard_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<!-- Drag handle for accessibility -->
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- Bottom sheet contents. -->
<!-- <TextView-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/title"/>-->
<!-- <TextView-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/supporting_text"/>-->
<!-- <Button-->
<!-- android:id="@+id/bottomsheet_button"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/action" />-->
<!-- <com.google.android.material.switchmaterial.SwitchMaterial-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/switch_label"/>-->
</FrameLayout>
<!-- <com.google.android.material.floatingactionbutton.FloatingActionButton-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_gravity="right|bottom"-->
<!-- android:layout_margin="16dp"-->
<!-- android:src="@drawable/add" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -44,13 +44,12 @@
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_margin="16dp" android:layout_margin="16dp"
android:text="@string/create_unit" android:src="@drawable/add" />
app:icon="@drawable/add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -304,9 +304,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|right" android:layout_gravity="bottom|right"
android:layout_margin="16dp" android:layout_margin="16dp"
android:text="@string/installation" android:src="@drawable/cloud_download"
android:visibility="gone" android:visibility="gone" />
app:icon="@drawable/cloud_download" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
style="@style/TextAppearance.Material3.HeadlineSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/xInputEditLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:hint="@string/coordinates_x">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/xInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="numberSigned" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/yInputEditLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="@string/coordinates_y">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/yInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="numberSigned" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/saveButton"
style="@style/Widget.Material3.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/edit_function" />
</LinearLayout>

View File

@ -12,21 +12,27 @@
<TextView <TextView
android:id="@+id/textview" android:id="@+id/textview"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/no_content" android:text="@string/no_content"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:visibility="gone" /> android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="16dp" android:visibility="gone"
android:layout_marginTop="8dp" android:id="@+id/swipeRefreshLayout">
android:layout_marginRight="16dp"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout> </LinearLayout>

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:padding="8dp">
<TextView <TextView
android:id="@+id/operation" android:id="@+id/operation"
style="@style/TextAppearance.Material3.TitleSmall" style="@style/TextAppearance.Material3.TitleSmall"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/mod_tags" /> android:text="@string/mod_tags" />
</LinearLayout> </LinearLayout>

View File

@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:padding="8dp"> android:padding="8dp">
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/display_coordinate_system"
android:checkable="true"
android:checked="true"
android:title="@string/display_coordinate_system" />
<item
android:id="@+id/show_guides"
android:checkable="true"
android:checked="true"
android:title="@string/show_guides" />
</menu>

View File

@ -355,6 +355,9 @@
<string name="code_language_on">英文</string> <string name="code_language_on">英文</string>
<string name="code_language_off">中文</string> <string name="code_language_off">中文</string>
<string name="save_tip">请先保存当前内容。</string> <string name="save_tip">请先保存当前内容。</string>
<string name="not_find_turret">找不到炮塔。</string>
<string name="please_enter_the_x_coordinate">请输入X坐标。</string>
<string name="please_enter_the_y_coordinate">请输入Y坐标。</string>
<string name="copy_rule">复制规则</string> <string name="copy_rule">复制规则</string>
<string name="rule">规则</string> <string name="rule">规则</string>
<string name="search_rule">查找规则</string> <string name="search_rule">查找规则</string>
@ -454,6 +457,7 @@
<string name="view_the_report_object">查看(%1$s)</string> <string name="view_the_report_object">查看(%1$s)</string>
<string name="bookmark_already_exists">此书签已存在,请更换路径。</string> <string name="bookmark_already_exists">此书签已存在,请更换路径。</string>
<string name="feedback">意见反馈</string> <string name="feedback">意见反馈</string>
<string name="please_set_main_image">请设置主体图像。</string>
<string name="setting_use_jetBrains_mono_font" translatable="false">UseJetBrainsMonoFont</string> <string name="setting_use_jetBrains_mono_font" translatable="false">UseJetBrainsMonoFont</string>
<string name="use_jetBrains_mono_font">使用JetBrains Mono字体</string> <string name="use_jetBrains_mono_font">使用JetBrains Mono字体</string>
<string name="use_jetBrains_mono_font_describe">助手内置的字体,强烈推荐使用。</string> <string name="use_jetBrains_mono_font_describe">助手内置的字体,强烈推荐使用。</string>
@ -893,6 +897,13 @@
<string name="file_path">文件路径</string> <string name="file_path">文件路径</string>
<string name="dim_value">模糊度</string> <string name="dim_value">模糊度</string>
<string name="auto_generate_color_scheme">自动生成配色方案</string> <string name="auto_generate_color_scheme">自动生成配色方案</string>
<string name="display_coordinate_system">显示坐标系</string>
<string name="automatically_disable_coordinate_system">当前图像尺寸过大,已禁用坐标系显示。</string>
<string name="coordinates_x">x坐标</string>
<string name="coordinates_y">y坐标</string>
<string name="turret">炮塔</string>
<string name="control_panel">控制面板</string>
<string name="show_guides">显示辅助线</string>
<!-- <string name="search_suggestions_null">无搜索建议。</string>--> <!-- <string name="search_suggestions_null">无搜索建议。</string>-->
<!-- <string name="search_suggestions_number">共%1$d个搜索建议。</string>--> <!-- <string name="search_suggestions_number">共%1$d个搜索建议。</string>-->

View File

@ -7,4 +7,9 @@ import java.io.File
* @property name String * @property name String
* @constructor * @constructor
*/ */
data class TurretData(val name: String, var x: Int, var y: Int, var imageFile: File? = null) data class TurretData(
val name: String,
var gameCoordinateData: CoordinateData,
var scaleValue: Float = 1f,
var imageFile: File? = null
)

View File

@ -1,56 +0,0 @@
package com.coldmint.rust.core.turret
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.graphics.drawable.Drawable.createFromPath
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import com.coldmint.rust.core.R
import com.coldmint.rust.core.SourceFile
/**
* 炮塔安装器
* 此类用于安装炮塔将炮塔安放到视图上
*/
object TurretInstaller {
/**
* 安装全部炮塔到视图
* @param frameLayout FrameLayout
* @param sourceFile SourceFile
*/
fun installerAllTurret(
viewGroup: ViewGroup,
sourceFile: SourceFile,
coordinateChangeListener: (CoordinateData) -> Unit
) {
sourceFile.getTurretManager().turretList.forEach {
installerTurret(viewGroup, it,coordinateChangeListener)
}
}
/**
* 安装单个炮塔到视图
* @param frameLayout FrameLayout
* @param sourceFile SourceFile
*/
fun installerTurret(viewGroup: ViewGroup, turretData: TurretData, coordinateChangeListener: (CoordinateData) -> Unit
) {
val turretView = TurretView(viewGroup.context)
turretView.setTurretData(turretData)
turretView.setOnTouchListener { view, motionEvent ->
turretView.setTurretX(motionEvent.x.toInt())
turretView.setTurretY(motionEvent.y.toInt())
coordinateChangeListener.invoke(CoordinateData(motionEvent.x.toInt(),motionEvent.y.toInt()))
turretView.invalidate()
true
}
viewGroup.addView(turretView)
}
}

View File

@ -1,6 +1,7 @@
package com.coldmint.rust.core.turret package com.coldmint.rust.core.turret
import android.util.Log import android.util.Log
import android.view.ViewGroup
import com.coldmint.rust.core.SourceFile import com.coldmint.rust.core.SourceFile
import java.io.File import java.io.File
@ -12,6 +13,7 @@ import java.io.File
*/ */
class TurretManager(val sourceFile: SourceFile) { class TurretManager(val sourceFile: SourceFile) {
/** /**
* 炮塔列表 * 炮塔列表
*/ */
@ -19,6 +21,30 @@ class TurretManager(val sourceFile: SourceFile) {
ArrayList<TurretData>() ArrayList<TurretData>()
} }
//坐标改变监听器
private var coordinateChangeListener: ((CoordinateData, TurretData) -> Unit)? = null
/**
* 设置坐标改变监听器
* @param coordinateChangeListener Function2<CoordinateData, TurretData, Unit>?
*/
fun setCoordinateChangeListener(coordinateChangeListener: ((CoordinateData, TurretData) -> Unit)?) {
this.coordinateChangeListener = coordinateChangeListener
if (turretList.size > 0) {
turretList.forEach {
viewMap[it.name]?.setCoordinateChangeListener(coordinateChangeListener)
}
}
}
/**
* 炮塔和视图的映射
*/
private val viewMap by lazy {
HashMap<String, TurretView>()
}
init { init {
val allSection = sourceFile.allSection val allSection = sourceFile.allSection
val size = allSection.size val size = allSection.size
@ -45,12 +71,12 @@ class TurretManager(val sourceFile: SourceFile) {
if (yData != null) { if (yData != null) {
y = yData.toInt() y = yData.toInt()
} }
val turretData = TurretData(name, x, y) val turretData = TurretData(name, CoordinateData(x, y))
val fileList = sourceFile.findResourceFilesFromSection("image", it, false) val fileList = sourceFile.findResourceFilesFromSection("image", it, false)
if (!fileList.isNullOrEmpty()) { if (!fileList.isNullOrEmpty()) {
val file = fileList.get(0) val file = fileList.get(0)
turretData.imageFile = file turretData.imageFile = file
Log.d("炮塔管理器-$name", "设置炮塔图像"+file.absolutePath) Log.d("炮塔管理器-$name", "设置炮塔图像" + file.absolutePath)
} else { } else {
turretData.imageFile = defaultImageFile turretData.imageFile = defaultImageFile
Log.d("炮塔管理器-$name", "加载默认图像" + defaultImageFile?.absolutePath) Log.d("炮塔管理器-$name", "加载默认图像" + defaultImageFile?.absolutePath)
@ -62,4 +88,82 @@ class TurretManager(val sourceFile: SourceFile) {
} }
/**
* 保存改变的代码
* @return Boolean
*/
fun saveChange(): Boolean {
turretList.forEach {
val section = "turret_" + it.name
sourceFile.writeValueFromSection("x", it.gameCoordinateData.x.toString(),section)
sourceFile.writeValueFromSection("y", it.gameCoordinateData.y.toString(),section)
}
return sourceFile.save()
}
/**
* 安装全部炮塔到视图
* @param frameLayout FrameLayout
* @param sourceFile SourceFile
*/
fun installerAllTurret(
viewGroup: ViewGroup,
turretSketchpadView: TurretSketchpadView
) {
viewMap.clear()
turretList.forEach {
installerTurret(viewGroup, it, turretSketchpadView)
}
}
/**
* 获取炮塔数据
* @param name String 炮塔名称
* @return TurretData?
*/
fun getTurretView(name: String): TurretView? {
return viewMap[name]
}
/**
* 使用炮塔激活其视图拖动禁用其他
* @param turretData TurretData
* @return TurretView?
*/
fun useTurret(
turretName: String
) {
turretList.forEach {
val use = it.name == turretName
val view = viewMap[it.name]
if (view == null) {
Log.e("炮塔管理器", "无法找到 ${it.name} 炮塔。")
} else {
view.setCanDrag(use)
}
Log.d("炮塔管理器", "${it.name} 可用${use}")
}
}
/**
* 安装单个炮塔到视图
* @param frameLayout FrameLayout
* @param sourceFile SourceFile
*/
fun installerTurret(
viewGroup: ViewGroup,
turretData: TurretData,
turretSketchpadView: TurretSketchpadView
) {
val turretView = TurretView(viewGroup.context)
turretView.setTurretData(turretData)
turretView.setCoordinateChangeListener(coordinateChangeListener)
turretView.setTurretSketchpadView(turretSketchpadView)
viewMap[turretData.name] = turretView
viewGroup.addView(turretView)
}
} }

View File

@ -18,12 +18,36 @@ class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null)
View(context, attributeSet) { View(context, attributeSet) {
companion object {
/**
* 缩放图像
* @param bitmap Bitmap
* @param size Float
* @return Bitmap
*/
fun scaleBitmap(bitmap: Bitmap, size: Float): Bitmap {
//创建新的图像背景
val matrix = Matrix()
matrix.setScale(size, size)
return Bitmap.createBitmap(
bitmap,
0,
0,
bitmap.getWidth(),
bitmap.getHeight(),
matrix,
true
)
}
}
private val debug = "炮塔画板" private val debug = "炮塔画板"
private var mainImagePath: String? = null private var mainImagePath: String? = null
//计算中心点 //计算中心点
private var centreX = 0 private var centreX = -1
private var centreY = 0 private var centreY = -1
//计算绘制点 取图像中点坐标(图像尺寸*缩放比例/2) //计算绘制点 取图像中点坐标(图像尺寸*缩放比例/2)
private var startX = 0 private var startX = 0
@ -34,9 +58,40 @@ class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null)
//单元格宽度 //单元格宽度
private var cellSize = 10 private var cellSize = 10
//关键坐标(用于绘制关键线)
private var keyCoordinate: CoordinateData? = null
/**
* 是否建议显示坐标系
* 如果单元格宽度大于10那么显示
* @return Boolean
*/
fun isSuggestedDisplayCoordinateSystem(): Boolean {
return cellSize > 10
}
//是否绘制关键线
var drawAuxiliaryLine = true
set(value) {
field = value
invalidate()
}
//设置是否绘制坐标 //设置是否绘制坐标
var drawCoordinate = true var drawCoordinate = true
set(value) {
field = value
invalidate()
}
//设置坐标颜色
var coordinateColor = Color.RED
set(value) {
field = value
invalidate()
}
init { init {
val typedArray = val typedArray =
@ -67,11 +122,74 @@ class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null)
val game = CoordinateData(x, y) val game = CoordinateData(x, y)
Log.d( Log.d(
debug, debug,
"转换坐标,安卓坐标${androidCoordinateData} 游戏坐标${game}" "转换游戏坐标,安卓坐标${androidCoordinateData} 游戏坐标${game}"
) )
return game return game
} }
/**
* 转换为安卓坐标
* @param gameCoordinateData CoordinateData
* @return CoordinateData
*/
fun toAndroidCoordinate(gameCoordinateData: CoordinateData): CoordinateData {
val x = (gameCoordinateData.x * cellSize) + centreX
val y = (gameCoordinateData.y * cellSize) + centreY
val androidCoordinateData = CoordinateData(x, y)
Log.d(
debug,
"转换安卓坐标,中心点${centreX} ${centreY}安卓坐标${androidCoordinateData} 游戏坐标${gameCoordinateData}"
)
return androidCoordinateData
}
/**
* 设置关键坐标
* @param coordinateData CoordinateData
*/
fun setKeyCoordinate(coordinateData: CoordinateData) {
if (centreX != -1 && centreY != -1) {
keyCoordinate = coordinateData
Log.d(debug, "已设置关键坐标${coordinateData}")
invalidate()
} else {
Log.e(debug, "设置关键坐标失败。")
}
}
/**
* 绘制辅助线
* @param androidCoordinateData CoordinateData
*/
private fun drawAuxiliaryLines(canvas: Canvas, androidCoordinateData: CoordinateData) {
if (!drawAuxiliaryLine) {
return
}
val paint = Paint()
paint.color = Color.RED
paint.strokeWidth = 5f
paint.style = Paint.Style.STROKE
//横线
canvas.drawLine(
startX.toFloat(),
androidCoordinateData.y.toFloat(),
endX.toFloat(),
androidCoordinateData.y.toFloat(),
paint
)
//竖线
canvas.drawLine(
androidCoordinateData.x.toFloat(),
startY.toFloat(),
androidCoordinateData.x.toFloat(),
endY.toFloat(),
paint
)
}
/** /**
* 计算坐标 * 计算坐标
*/ */
@ -111,7 +229,7 @@ class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null)
if (drawCoordinate) { if (drawCoordinate) {
//如果需要绘制 //如果需要绘制
val paint = Paint() val paint = Paint()
paint.color = Color.RED paint.color = coordinateColor
//开启描边 //开启描边
paint.style = Paint.Style.STROKE paint.style = Paint.Style.STROKE
paint.strokeWidth = 3f paint.strokeWidth = 3f
@ -127,33 +245,13 @@ class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null)
} }
} }
/**
* 缩放图像
* @param bitmap Bitmap
* @param size Float
* @return Bitmap
*/
fun scaleBitmap(bitmap: Bitmap, size: Float = cellSize.toFloat()): Bitmap {
//创建新的图像背景
val matrix = Matrix()
matrix.setScale(size, size)
return Bitmap.createBitmap(
bitmap,
0,
0,
bitmap.getWidth(),
bitmap.getHeight(),
matrix,
true
)
}
/** /**
* 绘制主体图像 * 绘制主体图像
*/ */
private fun drawImage(canvas: Canvas, bitmap: Bitmap) { private fun drawImage(canvas: Canvas, bitmap: Bitmap) {
val paint = Paint() val paint = Paint()
val temBitmap = scaleBitmap(bitmap) val temBitmap = scaleBitmap(bitmap, cellSize.toFloat())
canvas.drawBitmap(temBitmap, startX.toFloat(), startY.toFloat(), paint) canvas.drawBitmap(temBitmap, startX.toFloat(), startY.toFloat(), paint)
temBitmap.recycle() temBitmap.recycle()
} }
@ -168,6 +266,10 @@ class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null)
drawImage(canvas, bitmap) drawImage(canvas, bitmap)
//设置坐标系(如果需要) //设置坐标系(如果需要)
drawCoordinate(canvas) drawCoordinate(canvas)
//标记关键坐标
if (keyCoordinate != null) {
drawAuxiliaryLines(canvas, keyCoordinate!!)
}
if (!bitmap!!.isRecycled) { if (!bitmap!!.isRecycled) {
bitmap.recycle() bitmap.recycle()
} }

View File

@ -9,7 +9,9 @@ import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.MotionEvent
import android.view.View import android.view.View
import android.widget.Toast
import com.coldmint.rust.core.R import com.coldmint.rust.core.R
/** /**
@ -19,11 +21,54 @@ import com.coldmint.rust.core.R
class TurretView(context: Context, attributeSet: AttributeSet? = null) : class TurretView(context: Context, attributeSet: AttributeSet? = null) :
View(context, attributeSet) { View(context, attributeSet) {
private val debugKey = "炮塔视图" private var debugKey = "炮塔视图"
private lateinit var turretData: TurretData private lateinit var turretData: TurretData
private var bitmapW: Int = 0 private var bitmapW: Int = 0
private var bitmapH: Int = 0 private var bitmapH: Int = 0
private var turretSketchpadView: TurretSketchpadView? = null
private var coordinateChangeListener: ((CoordinateData, TurretData) -> Unit)? = null
//是否可以拖动
private var canDrag = false
/**
* 设置坐标监听器
* @param coordinateChangeListener Function2<CoordinateData, TurretData, Unit>?
*/
fun setCoordinateChangeListener(coordinateChangeListener: ((CoordinateData, TurretData) -> Unit)?) {
this.coordinateChangeListener = coordinateChangeListener
}
/**
* 设置是否可用拖到
* @param canDrag Boolean
*/
fun setCanDrag(canDrag: Boolean) {
Log.d(debugKey, "${turretData.name} 可拖动状态${canDrag}")
this.canDrag = canDrag
if (canDrag) {
val and = turretSketchpadView?.toAndroidCoordinate(turretData.gameCoordinateData)
if (and != null) {
turretSketchpadView?.setKeyCoordinate(and)
}else{
Log.e(debugKey, "可拖动状态,辅助线定位失败。")
}
}
}
/**
* 设置游戏坐标
* @param coordinateData CoordinateData
*/
fun setGameCoordinateData(coordinateData: CoordinateData) {
val android = turretSketchpadView?.toAndroidCoordinate(coordinateData)
if (android != null) {
turretSketchpadView?.setKeyCoordinate(android)
}
turretData.gameCoordinateData = coordinateData
invalidate()
}
/** /**
* 设置炮塔数据 * 设置炮塔数据
@ -31,6 +76,15 @@ class TurretView(context: Context, attributeSet: AttributeSet? = null) :
*/ */
fun setTurretData(turretData: TurretData) { fun setTurretData(turretData: TurretData) {
this.turretData = turretData this.turretData = turretData
this.debugKey = "炮塔视图_" + turretData.name
}
/**
* 设置画板
* @param sketchpadView TurretSketchpadView
*/
fun setTurretSketchpadView(sketchpadView: TurretSketchpadView) {
this.turretSketchpadView = sketchpadView
} }
@ -46,42 +100,73 @@ class TurretView(context: Context, attributeSet: AttributeSet? = null) :
} }
/** /**
* 设置炮塔X * 设置炮塔坐标数据
* @param x Int * @param coordinateData
*/ */
fun setTurretX(x: Int) { fun setTurretGameCoordinateData(coordinateData: CoordinateData) {
if (this::turretData.isInitialized) { if (this::turretData.isInitialized) {
turretData.x = x turretData.gameCoordinateData = coordinateData
} }
} }
/** /**
* 设置炮塔X * 当出现触摸事件
* @param y Int * @param event MotionEvent
* @return Boolean 返回true已被处理
*/ */
fun setTurretY(y: Int) { override fun onTouchEvent(event: MotionEvent?): Boolean {
if (this::turretData.isInitialized) { if (event != null) {
turretData.y = y val action = event.action
} when (action) {
} MotionEvent.ACTION_DOWN -> {
return canDrag
}
MotionEvent.ACTION_MOVE -> {
Log.d(debugKey, "收到移动${turretData.name} 可拖动状态${canDrag}")
if (canDrag) {
val and = CoordinateData(event.x.toInt(), event.y.toInt())
val gameCoordinateData = turretSketchpadView!!.toGameCoordinate(and)
setTurretGameCoordinateData(gameCoordinateData)
turretSketchpadView!!.setKeyCoordinate(and)
coordinateChangeListener?.invoke(gameCoordinateData, turretData)
invalidate()
return true
}
}
}
}
return false
}
@SuppressLint("DrawAllocation") @SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas?) { override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas) super.onDraw(canvas)
if (this::turretData.isInitialized) { if (this::turretData.isInitialized) {
if (turretSketchpadView == null) {
Log.e(debugKey, "未绑定画板,停止绘制。")
return
}
val paint = Paint() val paint = Paint()
val bitmap = if (turretData.imageFile == null) { var bitmap = if (turretData.imageFile == null) {
BitmapFactory.decodeResource(this.resources, R.drawable.image) BitmapFactory.decodeResource(this.resources, R.drawable.image)
} else { } else {
BitmapFactory.decodeFile(turretData.imageFile!!.absolutePath) BitmapFactory.decodeFile(turretData.imageFile!!.absolutePath)
} }
if (turretData.scaleValue != 1f) {
bitmap = TurretSketchpadView.scaleBitmap(
bitmap, turretData.scaleValue
)
}
val androidCoordinate =
turretSketchpadView!!.toAndroidCoordinate(turretData.gameCoordinateData)
bitmapW = bitmap.width bitmapW = bitmap.width
bitmapH = bitmap.height bitmapH = bitmap.height
canvas?.drawBitmap( canvas?.drawBitmap(
bitmap, bitmap,
(turretData.x - bitmapW / 2).toFloat(), (androidCoordinate.x - bitmapW / 2).toFloat(),
(turretData.y - bitmapH / 2).toFloat(), (androidCoordinate.y - bitmapH / 2).toFloat(),
paint paint
) )
if (!bitmap.isRecycled) { if (!bitmap.isRecycled) {