炮塔拖拽初步
This commit is contained in:
parent
24d9faba32
commit
ed60f78d35
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -68,6 +68,9 @@ android {
|
|||
|
||||
|
||||
dependencies {
|
||||
def nav_version = "2.5.1"
|
||||
|
||||
implementation 'com.leinardi.android:speed-dial:3.1.1'
|
||||
// implementation 'com.luolc:emoji-rain:0.1.1'
|
||||
implementation 'me.zhanghai.android.fastscroll:library:1.1.8'
|
||||
// 语种切换框架:https://github.com/getActivity/MultiLanguages
|
||||
|
@ -91,26 +94,24 @@ dependencies {
|
|||
implementation 'androidx.core:core-ktx:1.8.0'
|
||||
implementation 'com.github.deano2390:MaterialShowcaseView:1.3.4'
|
||||
implementation 'com.google.code.gson:gson:2.9.1'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.6-native'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.8-native'
|
||||
implementation 'com.kongzue.stacklabel:stacklabelview:1.1.9'
|
||||
implementation 'io.github.Rosemoe.sora-editor:editor:0.16.5'
|
||||
implementation project(path: ':assistantCoreLibrary')
|
||||
implementation project(path: ':turretsDragView')
|
||||
implementation project(path: ':dialog')
|
||||
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
|
||||
implementation 'com.afollestad.material-dialogs:input:3.3.0'
|
||||
|
||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||
implementation 'com.github.florent37:glidepalette:2.1.2'
|
||||
implementation 'com.github.QuadFlask:colorpicker:0.0.15'
|
||||
implementation 'cat.ereza:customactivityoncrash:2.3.0'
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation 'androidx.appcompat:appcompat:1.4.0'
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.0'
|
||||
implementation 'com.google.android.material:material:1.7.0-beta01'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
|
||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.rust.Concept"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".CustomizeEditTextActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".SearchActivity"
|
||||
android:exported="false" />
|
||||
|
@ -262,9 +265,9 @@
|
|||
<activity
|
||||
android:name=".EditActivity"
|
||||
android:exported="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:label="@string/mod_action1"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".CreateModActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
|
|
@ -4,10 +4,7 @@ import android.content.Intent
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.*
|
||||
import com.coldmint.rust.core.web.ServerConfiguration
|
||||
import com.coldmint.rust.pro.base.BaseActivity
|
||||
import com.coldmint.rust.pro.databinding.ActivityAboutBinding
|
||||
|
@ -96,7 +93,7 @@ class AboutActivity : BaseActivity<ActivityAboutBinding>() {
|
|||
}
|
||||
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_about, menu)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ class ActivateActivity : BaseActivity<ActivityActivateBinding>() {
|
|||
* @param menu Menu
|
||||
* @return Boolean
|
||||
*/
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val inflater = menuInflater
|
||||
inflater.inflate(R.menu.menu_pay, menu)
|
||||
return true
|
||||
|
|
|
@ -63,10 +63,10 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>() {
|
|||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val inflater = menuInflater
|
||||
inflater.inflate(R.menu.menu_browser, menu)
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
|
|
|
@ -0,0 +1,403 @@
|
|||
package com.coldmint.rust.pro
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.palette.graphics.Palette
|
||||
import com.afollestad.materialdialogs.utils.MDUtil.getWidthAndHeight
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions.bitmapTransform
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.pro.base.BaseActivity
|
||||
import com.coldmint.rust.pro.databinding.ActivityCustomizeEditTextBinding
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.GlobalMethod
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.yalantis.ucrop.UCrop
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation
|
||||
import java.io.File
|
||||
|
||||
|
||||
class CustomizeEditTextActivity : BaseActivity<ActivityCustomizeEditTextBinding>() {
|
||||
|
||||
private lateinit var selectFile: ActivityResultLauncher<Intent>
|
||||
private var clipPath: String? = null
|
||||
|
||||
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
|
||||
setReturnButton()
|
||||
title = getString(R.string.customize_edit_text)
|
||||
readData()
|
||||
loadAction()
|
||||
|
||||
val enable = AppSettings.getValue(
|
||||
AppSettings.Setting.CodeEditBackGroundEnable,
|
||||
false
|
||||
)
|
||||
if (enable) {
|
||||
loadImage(
|
||||
AppSettings.getValue(AppSettings.Setting.CodeEditBackGroundPath, ""),
|
||||
AppSettings.getValue(AppSettings.Setting.BlurTransformationValue, 1)
|
||||
)
|
||||
}
|
||||
|
||||
selectFile = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
val key = "选择文件"
|
||||
if (it.resultCode == RESULT_OK) {
|
||||
//选择了文件
|
||||
val intent = it.data
|
||||
val path = intent?.getStringExtra("File") ?: ""
|
||||
val file = File(path)
|
||||
if (file.exists()) {
|
||||
val type = FileOperator.getFileType(file)
|
||||
if (type == "png" || type == "jpg") {
|
||||
val bitmap = BitmapFactory.decodeFile(path)
|
||||
val width = windowManager.getWidthAndHeight().first
|
||||
val height = windowManager.getWidthAndHeight().second
|
||||
val imageWidth = bitmap.width
|
||||
val imageHeight = bitmap.height
|
||||
if (width % imageWidth == 0 && height % imageHeight == 0) {
|
||||
//可以被整除
|
||||
DebugHelper.printLog(key, "图像无需裁剪。")
|
||||
} else {
|
||||
clipPath = AppSettings.createNewCodeEditBackGroundFile()
|
||||
val newFile = File(clipPath)
|
||||
DebugHelper.printLog(key, "前往裁剪 输出路径:${newFile.absolutePath}")
|
||||
UCrop.of(
|
||||
Uri.parse(file.toURI().toString()),
|
||||
Uri.parse(newFile.toURI().toString())
|
||||
)
|
||||
.withAspectRatio(width.toFloat(), height.toFloat())
|
||||
.start(this);
|
||||
}
|
||||
} else {
|
||||
DebugHelper.printLog(key, "文件格式不合法", isError = true)
|
||||
Snackbar.make(
|
||||
viewBinding.button,
|
||||
R.string.bad_file_type,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
} else {
|
||||
DebugHelper.printLog(key, "文件不存在", isError = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK && requestCode == UCrop.REQUEST_CROP) {
|
||||
// val resultUri = UCrop.getOutput(data!!)
|
||||
if (clipPath != null) {
|
||||
loadImage(clipPath!!)
|
||||
} else {
|
||||
Snackbar.make(
|
||||
viewBinding.button,
|
||||
R.string.bad_file_type,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
} else if (resultCode == UCrop.RESULT_ERROR) {
|
||||
// val cropError = UCrop.getError(data!!)
|
||||
Snackbar.make(
|
||||
viewBinding.button,
|
||||
R.string.bad_file_type,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载图像
|
||||
* @param filePath String
|
||||
*/
|
||||
fun loadImage(filePath: String, value: Int = 1) {
|
||||
DebugHelper.printLog("加载文件", "加载了文件${filePath} 模糊度${value}", isError = true)
|
||||
Glide.with(this).load(filePath).apply(
|
||||
bitmapTransform(
|
||||
BlurTransformation(value)
|
||||
)
|
||||
).into(viewBinding.imageView)
|
||||
viewBinding.filePathInputEdit.setText(filePath)
|
||||
viewBinding.imageCardView.isVisible = true
|
||||
viewBinding.dimCardView.isVisible = true
|
||||
viewBinding.autoGenerateColorSchemeButton.isVisible = true
|
||||
viewBinding.slide.value = value.toFloat()
|
||||
viewBinding.filePathInputLayout.endIconDrawable =
|
||||
getDrawable(R.drawable.ic_outline_clear_24)
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取数据
|
||||
*/
|
||||
fun readData() {
|
||||
//读取内容
|
||||
setTextAndColor(
|
||||
viewBinding.textColorEditText,
|
||||
AppSettings.getValue(AppSettings.Setting.TextColor, "")
|
||||
)
|
||||
setTextAndColor(
|
||||
viewBinding.annotationColorEditText,
|
||||
AppSettings.getValue(AppSettings.Setting.AnnotationColor, "")
|
||||
)
|
||||
setTextAndColor(
|
||||
viewBinding.keywordColorEditText,
|
||||
AppSettings.getValue(AppSettings.Setting.KeywordColor, "")
|
||||
)
|
||||
setTextAndColor(
|
||||
viewBinding.sectionColorEditText,
|
||||
AppSettings.getValue(AppSettings.Setting.SectionColor, "")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载事件
|
||||
*/
|
||||
fun loadAction() {
|
||||
viewBinding.autoGenerateColorSchemeButton.setOnClickListener {
|
||||
val bitmap = BitmapFactory.decodeFile(viewBinding.filePathInputEdit.text.toString())
|
||||
Palette.from(bitmap).generate {
|
||||
//充满活力的
|
||||
setTextAndColor(
|
||||
viewBinding.sectionColorEditText,
|
||||
GlobalMethod.colorToString(it?.getVibrantColor(Color.RED) ?: Color.RED)
|
||||
)
|
||||
|
||||
setTextAndColor(
|
||||
viewBinding.annotationColorEditText,
|
||||
GlobalMethod.colorToString(it?.getLightVibrantColor(Color.RED) ?: Color.RED)
|
||||
)
|
||||
setTextAndColor(
|
||||
viewBinding.textColorEditText,
|
||||
GlobalMethod.colorToString(it?.getDarkMutedColor(Color.RED) ?: Color.RED)
|
||||
)
|
||||
setTextAndColor(
|
||||
viewBinding.keywordColorEditText,
|
||||
GlobalMethod.colorToString(it?.getMutedColor(Color.RED) ?: Color.RED)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
viewBinding.filePathInputLayout.setEndIconOnClickListener {
|
||||
val oldFileData = viewBinding.filePathInputEdit.text.toString()
|
||||
if (oldFileData.isBlank()) {
|
||||
val intent = Intent(this, FileManagerActivity::class.java)
|
||||
val bundle = Bundle()
|
||||
bundle.putString("type", "selectFile")
|
||||
intent.putExtra("data", bundle)
|
||||
selectFile.launch(intent)
|
||||
} else {
|
||||
viewBinding.filePathInputEdit.setText("")
|
||||
viewBinding.filePathInputLayout.endIconDrawable = getDrawable(R.drawable.file)
|
||||
viewBinding.imageCardView.isVisible = false
|
||||
viewBinding.dimCardView.isVisible = false
|
||||
viewBinding.autoGenerateColorSchemeButton.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
viewBinding.slide.addOnChangeListener { slider, value, fromUser ->
|
||||
val filePath = viewBinding.filePathInputEdit.text.toString()
|
||||
Glide.with(this).load(filePath).apply(
|
||||
bitmapTransform(
|
||||
BlurTransformation(value.toInt())
|
||||
)
|
||||
).into(viewBinding.imageView)
|
||||
}
|
||||
|
||||
viewBinding.keywordColorEditLayout.setEndIconOnClickListener {
|
||||
GlobalMethod.showColorPickerDialog(this, true) {
|
||||
setTextAndColor(viewBinding.keywordColorEditText, it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
viewBinding.textColorEditLayout.setEndIconOnClickListener {
|
||||
GlobalMethod.showColorPickerDialog(this, true) {
|
||||
setTextAndColor(viewBinding.textColorEditText, it)
|
||||
}
|
||||
}
|
||||
|
||||
viewBinding.sectionColorEditLayout.setEndIconOnClickListener {
|
||||
GlobalMethod.showColorPickerDialog(this, true) {
|
||||
setTextAndColor(viewBinding.sectionColorEditText, it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
viewBinding.annotationColorEditLayout.setEndIconOnClickListener {
|
||||
GlobalMethod.showColorPickerDialog(this, true) {
|
||||
setTextAndColor(viewBinding.annotationColorEditText, it)
|
||||
}
|
||||
}
|
||||
|
||||
viewBinding.resetButton.setOnClickListener {
|
||||
setTextAndColor(viewBinding.keywordColorEditText, "#FF0031C2")
|
||||
setTextAndColor(viewBinding.sectionColorEditText, "#FFE10000")
|
||||
setTextAndColor(viewBinding.textColorEditText, "#FF000000")
|
||||
setTextAndColor(viewBinding.annotationColorEditText, "#FF00AF2C")
|
||||
}
|
||||
|
||||
viewBinding.button.setOnClickListener {
|
||||
saveData()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == android.R.id.home) {
|
||||
showSaveDialogIfNeed()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
fun showSaveDialogIfNeed() {
|
||||
val needSave = needSave()
|
||||
if (needSave) {
|
||||
CoreDialog(this).setTitle(R.string.customize_edit_text)
|
||||
.setMessage(R.string.save_settings).setPositiveButton(R.string.dialog_ok) {
|
||||
saveData()
|
||||
finish()
|
||||
}.setNegativeButton(R.string.dialog_cancel) {
|
||||
finish()
|
||||
}.setCancelable(false).show()
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
|
||||
showSaveDialogIfNeed()
|
||||
return true
|
||||
}
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要保存
|
||||
* @return Boolean
|
||||
*/
|
||||
fun needSave(): Boolean {
|
||||
val textColor = AppSettings.getValue(
|
||||
AppSettings.Setting.TextColor,
|
||||
""
|
||||
)
|
||||
if (viewBinding.textColorEditText.text.toString() != textColor) {
|
||||
return true
|
||||
}
|
||||
|
||||
val annotationColor = AppSettings.getValue(
|
||||
AppSettings.Setting.AnnotationColor,
|
||||
""
|
||||
)
|
||||
if (viewBinding.annotationColorEditText.text.toString() != annotationColor) {
|
||||
return true
|
||||
}
|
||||
val keywordColor = AppSettings.getValue(
|
||||
AppSettings.Setting.KeywordColor,
|
||||
""
|
||||
)
|
||||
if (viewBinding.keywordColorEditText.text.toString() != keywordColor) {
|
||||
return true
|
||||
}
|
||||
|
||||
val sectionColor = AppSettings.getValue(
|
||||
AppSettings.Setting.SectionColor,
|
||||
""
|
||||
)
|
||||
if (viewBinding.sectionColorEditText.text.toString() != sectionColor) {
|
||||
return true
|
||||
}
|
||||
val blurTransformationValue = AppSettings.getValue(
|
||||
AppSettings.Setting.BlurTransformationValue,
|
||||
1
|
||||
)
|
||||
if (viewBinding.slide.value.toInt() != blurTransformationValue) {
|
||||
return true
|
||||
}
|
||||
val codeEditBackGroundPath =
|
||||
AppSettings.getValue(AppSettings.Setting.CodeEditBackGroundPath, "")
|
||||
if (viewBinding.filePathInputEdit.text.toString() != codeEditBackGroundPath) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户数据
|
||||
*/
|
||||
fun saveData() {
|
||||
AppSettings.setValue(
|
||||
AppSettings.Setting.TextColor,
|
||||
viewBinding.textColorEditText.text.toString()
|
||||
)
|
||||
AppSettings.setValue(
|
||||
AppSettings.Setting.AnnotationColor,
|
||||
viewBinding.annotationColorEditText.text.toString()
|
||||
)
|
||||
AppSettings.setValue(
|
||||
AppSettings.Setting.KeywordColor,
|
||||
viewBinding.keywordColorEditText.text.toString()
|
||||
)
|
||||
AppSettings.setValue(
|
||||
AppSettings.Setting.SectionColor,
|
||||
viewBinding.sectionColorEditText.text.toString()
|
||||
)
|
||||
AppSettings.setValue(
|
||||
AppSettings.Setting.BlurTransformationValue,
|
||||
viewBinding.slide.value.toInt()
|
||||
)
|
||||
val filePath = viewBinding.filePathInputEdit.text.toString()
|
||||
val enable = if (filePath.isNullOrBlank()) {
|
||||
false
|
||||
} else {
|
||||
val file = File(filePath)
|
||||
if (file.exists()) {
|
||||
val newPath = AppSettings.createNewCodeEditBackGroundFile()
|
||||
val newFile = File(newPath)
|
||||
FileOperator.copyFile(file, newFile)
|
||||
AppSettings.setValue(AppSettings.Setting.CodeEditBackGroundPath, newPath)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
//如果输入了文件路径那么启用
|
||||
AppSettings.setValue(
|
||||
AppSettings.Setting.CodeEditBackGroundEnable,
|
||||
enable
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文本和颜色
|
||||
* @param textInputEditText TextInputEditText
|
||||
*/
|
||||
fun setTextAndColor(textInputEditText: TextInputEditText, color: String) {
|
||||
try {
|
||||
textInputEditText.setText(color)
|
||||
textInputEditText.setTextColor(Color.parseColor(color))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityCustomizeEditTextBinding {
|
||||
return ActivityCustomizeEditTextBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
package com.coldmint.rust.pro
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
@ -25,6 +27,11 @@ import com.afollestad.materialdialogs.input.getInputField
|
|||
import com.afollestad.materialdialogs.input.input
|
||||
import com.afollestad.materialdialogs.list.ItemListener
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.coldmint.rust.core.AnalysisResult
|
||||
import com.coldmint.rust.core.CodeCompiler2
|
||||
import com.coldmint.rust.core.ModClass
|
||||
|
@ -62,6 +69,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionItem
|
||||
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
@ -211,10 +219,10 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
// if (temCodeInfo == null) {
|
||||
//
|
||||
// } else {
|
||||
// val completionItemConverter = CompletionItemConverter.instance
|
||||
// completionItemConverter.init(this)
|
||||
// val CompletionItemConverter = CompletionItemConverter.instance
|
||||
// CompletionItemConverter.init(this)
|
||||
// list.add(
|
||||
// completionItemConverter.codeInfoToCompletionItem(
|
||||
// CompletionItemConverter.codeInfoToCompletionItem(
|
||||
// temCodeInfo
|
||||
// )
|
||||
// )
|
||||
|
@ -482,6 +490,7 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
initStartView()
|
||||
initEndView()
|
||||
showRenewalTip()
|
||||
loadCustomStyle()
|
||||
} else {
|
||||
val thisIntent = intent
|
||||
val bundle = thisIntent.getBundleExtra("data")
|
||||
|
@ -958,29 +967,9 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
codeToolAdapter.setItemEvent { i, codeToolItemBinding, viewHolder, item ->
|
||||
codeToolItemBinding.root.setOnClickListener {
|
||||
if (item == getString(R.string.symbol11)) {
|
||||
ColorPickerDialogBuilder
|
||||
.with(this@EditActivity)
|
||||
.setTitle(getString(R.string.choose_color))
|
||||
.initialColor(Color.WHITE)
|
||||
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
|
||||
.density(12)
|
||||
.setOnColorSelectedListener {
|
||||
//toast("onColorSelected: 0x" + Integer.toHexString(selectedColor));
|
||||
GlobalMethod.showColorPickerDialog(this) {
|
||||
viewBinding.codeEditor.insertText(it, it.length)
|
||||
}
|
||||
.setPositiveButton(R.string.dialog_ok) { dialog, selectedColor, allColors ->
|
||||
val r = Color.red(selectedColor)
|
||||
val g = Color.green(selectedColor)
|
||||
val b = Color.blue(selectedColor)
|
||||
val builder = StringBuilder()
|
||||
builder.append('#')
|
||||
builder.append(viewModel.convertDigital(r))
|
||||
builder.append(viewModel.convertDigital(g))
|
||||
builder.append(viewModel.convertDigital(b))
|
||||
viewBinding.codeEditor.insertText(builder.toString(), builder.length)
|
||||
}
|
||||
.setNegativeButton(R.string.dialog_cancel) { dialog, which -> }
|
||||
.build()
|
||||
.show()
|
||||
} else if (item == getString(R.string.code_table)) {
|
||||
viewModel.needCheckAutoSave = false
|
||||
startActivity(Intent(this@EditActivity, CodeTableActivity::class.java))
|
||||
|
@ -1065,11 +1054,11 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
// .findCodeByKeyFromSection(lineData, trueSection, number)
|
||||
// }
|
||||
// if (codeInfoList != null && codeInfoList.isNotEmpty()) {
|
||||
// val completionItemConverter =
|
||||
// val CompletionItemConverter =
|
||||
// CompletionItemConverter.instance.init(this)
|
||||
// codeInfoList.forEach {
|
||||
// list.add(
|
||||
// completionItemConverter.codeInfoToCompletionItem(
|
||||
// CompletionItemConverter.codeInfoToCompletionItem(
|
||||
// it
|
||||
// )
|
||||
// )
|
||||
|
@ -1122,9 +1111,9 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
"JetBrainsMono-Regular.ttf"
|
||||
)
|
||||
}
|
||||
val language =
|
||||
AppSettings.getValue(AppSettings.Setting.AppLanguage, Locale.getDefault().language)
|
||||
rustLanguage = RustLanguage(this)
|
||||
// val language =
|
||||
// AppSettings.getValue(AppSettings.Setting.AppLanguage, Locale.getDefault().language)
|
||||
rustLanguage = RustLanguage()
|
||||
rustLanguage.setCodeDataBase(CodeDataBase.getInstance(this))
|
||||
rustLanguage.setFileDataBase(
|
||||
FileDataBase.getInstance(
|
||||
|
@ -1134,25 +1123,53 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
)
|
||||
// rustLanguage.setAnalyzerEnglishMode(viewModel.englishModeLiveData)
|
||||
rustLanguage.setCodeEditor(viewBinding.codeEditor)
|
||||
val night = AppSettings.getValue(AppSettings.Setting.NightMode, false)
|
||||
viewBinding.codeEditor.setAutoCompletionItemAdapter(RustCompletionAdapter())
|
||||
viewBinding.codeEditor.isVerticalScrollBarEnabled = false
|
||||
val path = viewModel.modClass?.modFile?.absolutePath ?: ""
|
||||
CompletionItemConverter.configurationFileConversion(
|
||||
path,
|
||||
"ROOT",
|
||||
path
|
||||
)
|
||||
viewBinding.codeEditor.setEditorLanguage(rustLanguage)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载自动
|
||||
*/
|
||||
fun loadCustomStyle() {
|
||||
val key = "加载自定义编辑框样式"
|
||||
val editorColorScheme = EditorColorScheme()
|
||||
val backgroundColor = GlobalMethod.getThemeColor(this, android.R.attr.windowBackground)
|
||||
val codeEditBackGroundEnable =
|
||||
AppSettings.getValue(AppSettings.Setting.CodeEditBackGroundEnable, false)
|
||||
val backgroundColor =
|
||||
if (codeEditBackGroundEnable) {
|
||||
DebugHelper.printLog(key, "启用背景图像,设置背景为透明。")
|
||||
Color.TRANSPARENT
|
||||
} else {
|
||||
DebugHelper.printLog(key, "未启用背景图像,设置背景为窗口颜色。")
|
||||
GlobalMethod.getThemeColor(this, android.R.attr.windowBackground)
|
||||
}
|
||||
//代码(可识别的关键字)
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.KEYWORD,
|
||||
GlobalMethod.getThemeColor(this, android.R.attr.colorSecondary)
|
||||
Color.parseColor(AppSettings.getValue(AppSettings.Setting.KeywordColor, ""))
|
||||
)
|
||||
//默认文本
|
||||
editorColorScheme.setColor(EditorColorScheme.TEXT_NORMAL, Color.rgb(169, 183, 198))
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.TEXT_NORMAL,
|
||||
Color.parseColor(AppSettings.getValue(AppSettings.Setting.TextColor, ""))
|
||||
)
|
||||
//注释
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.COMMENT,
|
||||
GlobalMethod.getThemeColor(this, android.R.attr.textColorTertiary)
|
||||
Color.parseColor(AppSettings.getValue(AppSettings.Setting.AnnotationColor, ""))
|
||||
)
|
||||
//节
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.FUNCTION_NAME,
|
||||
GlobalMethod.getColorPrimary(this)
|
||||
Color.parseColor(AppSettings.getValue(AppSettings.Setting.SectionColor, ""))
|
||||
)
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.WHOLE_BACKGROUND,
|
||||
|
@ -1162,17 +1179,35 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
EditorColorScheme.LINE_NUMBER_BACKGROUND,
|
||||
backgroundColor
|
||||
)
|
||||
viewBinding.codeEditor.colorScheme = editorColorScheme
|
||||
viewBinding.codeEditor.setAutoCompletionItemAdapter(RustCompletionAdapter())
|
||||
viewBinding.codeEditor.isVerticalScrollBarEnabled = false
|
||||
val path = viewModel.modClass?.modFile?.absolutePath ?: ""
|
||||
// rustLanguage.autoCompleteProvider.setConfigurationFileConversion(
|
||||
// path,
|
||||
// "ROOT",
|
||||
// path
|
||||
// )
|
||||
viewBinding.codeEditor.setEditorLanguage(rustLanguage)
|
||||
editorColorScheme.setColor(EditorColorScheme.COMPLETION_WND_BACKGROUND, backgroundColor)
|
||||
if (codeEditBackGroundEnable) {
|
||||
//设置自定义背景图
|
||||
Glide.with(this)
|
||||
.load(AppSettings.getValue(AppSettings.Setting.CodeEditBackGroundPath, "")).apply(
|
||||
RequestOptions.bitmapTransform(
|
||||
BlurTransformation(
|
||||
AppSettings.getValue(
|
||||
AppSettings.Setting.BlurTransformationValue,
|
||||
1
|
||||
)
|
||||
)
|
||||
)
|
||||
).into(object : CustomTarget<Drawable>() {
|
||||
override fun onResourceReady(
|
||||
resource: Drawable,
|
||||
transition: Transition<in Drawable>?
|
||||
) {
|
||||
window.setBackgroundDrawable(resource)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
viewBinding.codeEditor.colorScheme = editorColorScheme
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.coldmint.rust.core.ModClass
|
|||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import com.bumptech.glide.Glide
|
||||
import android.graphics.BitmapFactory
|
||||
import com.yalantis.ucrop.UCrop
|
||||
|
@ -92,6 +93,19 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载默认图像
|
||||
*/
|
||||
fun loadDefaultImage() {
|
||||
val drawable = getDrawable(R.drawable.image)
|
||||
viewBinding.iconView.setImageDrawable(
|
||||
GlobalMethod.tintDrawable(
|
||||
drawable,
|
||||
ColorStateList.valueOf(GlobalMethod.getColorPrimary(this))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun initData() {
|
||||
val name = mModClass.readValueFromInfoSection("title", "mod")
|
||||
|
@ -103,8 +117,11 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
|
|||
viewBinding.modDescribeEdit.setText(description)
|
||||
}
|
||||
val bitmap = mModClass.modIcon
|
||||
if (bitmap != null) {
|
||||
Glide.with(this@EditModInfoActivity).load(bitmap).apply(GlobalMethod.getRequestOptions()).into(viewBinding.iconView)
|
||||
if (bitmap == null) {
|
||||
loadDefaultImage()
|
||||
} else {
|
||||
Glide.with(this@EditModInfoActivity).load(bitmap)
|
||||
.apply(GlobalMethod.getRequestOptions()).into(viewBinding.iconView)
|
||||
mNeedIcon = true
|
||||
}
|
||||
val musicSourceFolder = mModClass.readValueFromInfoSection("sourceFolder", "music")
|
||||
|
@ -269,7 +286,7 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
|
|||
iconFile.delete()
|
||||
mNeedIcon = false
|
||||
}
|
||||
viewBinding.iconView.setImageResource(R.drawable.image)
|
||||
loadDefaultImage()
|
||||
}
|
||||
false
|
||||
}
|
||||
|
@ -356,7 +373,8 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
|
|||
val bitmap = BitmapFactory.decodeFile(newIconFile.absolutePath)
|
||||
if (bitmap.height == bitmap.width) {
|
||||
if (FileOperator.copyFile(newIconFile, iconFile)) {
|
||||
Glide.with(this@EditModInfoActivity).load(newIconFile).apply(GlobalMethod.getRequestOptions())
|
||||
Glide.with(this@EditModInfoActivity).load(newIconFile)
|
||||
.apply(GlobalMethod.getRequestOptions())
|
||||
.into(viewBinding.iconView)
|
||||
mNeedIcon = true
|
||||
}
|
||||
|
@ -369,7 +387,8 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
|
|||
}
|
||||
} else if (requestCode == UCrop.REQUEST_CROP) {
|
||||
val resultUri = UCrop.getOutput(data)
|
||||
Glide.with(this@EditModInfoActivity).load(resultUri).apply(GlobalMethod.getRequestOptions()).into(viewBinding.iconView)
|
||||
Glide.with(this@EditModInfoActivity).load(resultUri)
|
||||
.apply(GlobalMethod.getRequestOptions()).into(viewBinding.iconView)
|
||||
mNeedIcon = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import android.net.Uri
|
|||
import android.os.*
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
|
@ -23,8 +25,11 @@ import com.afollestad.materialdialogs.actions.setActionButtonEnabled
|
|||
import com.afollestad.materialdialogs.input.getInputField
|
||||
import com.afollestad.materialdialogs.input.input
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import com.afollestad.materialdialogs.utils.MDUtil.isLandscape
|
||||
import com.bumptech.glide.Glide
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
import com.coldmint.dialog.InputDialog
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.core.tool.LineParser
|
||||
import com.coldmint.rust.pro.adapters.FileAdapter
|
||||
|
@ -38,173 +43,17 @@ import com.google.android.material.chip.Chip
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.SnackbarContentLayout
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
import java.lang.Exception
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
||||
// private var directs = Environment.getExternalStorageDirectory()
|
||||
// private var mRoot = directs
|
||||
// var filePath = ""
|
||||
//
|
||||
|
||||
// val executorService = Executors.newSingleThreadExecutor()
|
||||
//
|
||||
// //type可为默认default,选择文件夹selectDirectents,选择文件selectFile
|
||||
// var mStartType: String? = "default"
|
||||
// private var mFileAdapter: FileAdapter? = null
|
||||
// private var mProcessFiles = false
|
||||
// private var additionalData: String? = null
|
||||
// private fun initView() {
|
||||
// title = getString(R.string.file_manager)
|
||||
// setReturnButton()
|
||||
// viewBinding.fileList.layoutManager = LinearLayoutManager(this@FileManagerActivity)
|
||||
// val intent = intent
|
||||
// val bundle = intent.getBundleExtra("data")
|
||||
// if (bundle == null) {
|
||||
// showError("无效的请求。")
|
||||
// finish()
|
||||
// } else {
|
||||
// mStartType = bundle.getString("type")
|
||||
// when (mStartType) {
|
||||
// "default" -> {
|
||||
// }
|
||||
// "selectDirectents" -> {
|
||||
// setTitle(R.string.select_directents)
|
||||
// viewBinding.fab.setIconResource(R.drawable.complete)
|
||||
// viewBinding.fab.postDelayed({
|
||||
// viewBinding.fab.text = getString(R.string.select_directents)
|
||||
// viewBinding.fab.extend()
|
||||
// }, 300)
|
||||
// }
|
||||
// "exportFile" -> {
|
||||
// setTitle(R.string.export_file)
|
||||
// val additional = bundle.getString("additionalData")
|
||||
// if (additional == null) {
|
||||
// showError("请输入 additionalData")
|
||||
// return
|
||||
// } else {
|
||||
// viewBinding.fab.setIconResource(R.drawable.complete)
|
||||
// viewBinding.fab.postDelayed({
|
||||
// viewBinding.fab.text = getString(R.string.export_this)
|
||||
// viewBinding.fab.extend()
|
||||
// }, 300)
|
||||
// }
|
||||
// }
|
||||
// "selectFile" -> {
|
||||
// setTitle(R.string.select_file)
|
||||
// viewBinding.fab.setIconResource(R.drawable.complete)
|
||||
// viewBinding.fab.hide()
|
||||
// }
|
||||
// else -> {
|
||||
// Toast.makeText(this, "意外的请求", Toast.LENGTH_SHORT).show()
|
||||
// finish()
|
||||
// }
|
||||
// }
|
||||
// if (bundle.containsKey("path")) {
|
||||
// directs = File(bundle.getString("path"))
|
||||
// }
|
||||
// if (bundle.containsKey("rootpath")) {
|
||||
// mRoot = File(bundle.getString("rootpath"))
|
||||
// }
|
||||
// if (bundle.containsKey("additionalData")) {
|
||||
// additionalData = bundle.getString("additionalData")
|
||||
// }
|
||||
// }
|
||||
// loadFiles(directs)
|
||||
// }
|
||||
//
|
||||
// private fun tryOpenFile(file: File?) {
|
||||
// if (file == null) {
|
||||
// returnDirects()
|
||||
// } else {
|
||||
// if (file.isDirectory) {
|
||||
// loadFiles(file)
|
||||
// } else {
|
||||
// when (mStartType) {
|
||||
// "default" -> {
|
||||
// when (FileOperator.getFileType(file)) {
|
||||
// "ini", "txt", "template" -> {
|
||||
// val bundle = Bundle()
|
||||
// bundle.putString("path", file.absolutePath)
|
||||
// bundle.putString("modPath", FileOperator.getSuperDirectory(file))
|
||||
// val intent =
|
||||
// Intent(this@FileManagerActivity, EditActivity::class.java)
|
||||
// intent.putExtra("data", bundle)
|
||||
// this@FileManagerActivity.startActivity(intent)
|
||||
// }
|
||||
// "json" -> {
|
||||
// val openList = listOf<String>(
|
||||
// getString(R.string.edit_template), getString(
|
||||
// R.string.open_action1
|
||||
// )
|
||||
// )
|
||||
// MaterialDialog(this).title(R.string.open_type)
|
||||
// .listItems(items = openList) { dialog, offset, text ->
|
||||
// when (text) {
|
||||
// getString(R.string.edit_template) -> {
|
||||
// editTemplate(file)
|
||||
// }
|
||||
// getString(R.string.open_action1) -> {
|
||||
// editText(file)
|
||||
// }
|
||||
// }
|
||||
// }.show()
|
||||
//
|
||||
// }
|
||||
// "zip", "rwmod", "rar" -> {
|
||||
// Toast.makeText(
|
||||
// this@FileManagerActivity,
|
||||
// "点击了压缩文件。",
|
||||
// Toast.LENGTH_SHORT
|
||||
// ).show()
|
||||
// FileOperator.openFile(this@FileManagerActivity, file)
|
||||
// }
|
||||
// else -> {
|
||||
// val ints = intArrayOf(
|
||||
// R.string.open_action1,
|
||||
// R.string.open_action4
|
||||
// )
|
||||
// val items = FileAdapter.conversionSymbol(
|
||||
// this@FileManagerActivity,
|
||||
// ints
|
||||
// )
|
||||
//
|
||||
// MaterialAlertDialogBuilder(this).setItems(
|
||||
// items
|
||||
// ) { dialog, which ->
|
||||
// when (ints[which]) {
|
||||
// R.string.open_action1 -> {
|
||||
// editText(file)
|
||||
// }
|
||||
// R.string.open_action4 -> FileOperator.openFile(
|
||||
// this@FileManagerActivity,
|
||||
// file
|
||||
// )
|
||||
// }
|
||||
// }.show()
|
||||
// }
|
||||
// }
|
||||
// viewBinding.fab.show()
|
||||
// filePath = file.absolutePath
|
||||
// }
|
||||
// "selectFile" -> {
|
||||
// viewBinding.fab.show()
|
||||
// viewBinding.fab.postDelayed({
|
||||
// filePath = file.absolutePath
|
||||
// viewBinding.fab.text =
|
||||
// String.format(getString(R.string.select_file_ok), file.name)
|
||||
// viewBinding.fab.extend()
|
||||
// }, 300)
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
// /**
|
||||
// * 编辑模板
|
||||
|
@ -238,219 +87,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
// intent.putExtra("data", bundle)
|
||||
// this@FileManagerActivity.startActivity(intent)
|
||||
// }
|
||||
//
|
||||
// //加载文件
|
||||
// fun loadFiles(file: File) {
|
||||
// executorService.submit {
|
||||
// if (!file.exists()) {
|
||||
// runOnUiThread {
|
||||
// viewBinding.fileList.isVisible = false
|
||||
// viewBinding.progressBar.isVisible = false
|
||||
// viewBinding.fileError.isVisible = true
|
||||
// viewBinding.fileError.setText(R.string.unable_to_open_this_directory)
|
||||
// viewBinding.fab.hide()
|
||||
// }
|
||||
// return@submit
|
||||
// }
|
||||
//
|
||||
// if (file.isDirectory) {
|
||||
// val files = file.listFiles()
|
||||
// directs = file
|
||||
// val fileArrayList: ArrayList<File?> = ArrayList(listOf(*files))
|
||||
// if (file.absolutePath != mRoot.absolutePath) {
|
||||
// fileArrayList.add(0, null)
|
||||
// }
|
||||
// val finalFileAdapter: FileAdapter =
|
||||
// if (mFileAdapter == null) {
|
||||
// mFileAdapter = FileAdapter(this@FileManagerActivity, fileArrayList)
|
||||
// mFileAdapter!!
|
||||
// } else {
|
||||
// mFileAdapter?.setNewDataList(fileArrayList)
|
||||
// mFileAdapter!!
|
||||
// }
|
||||
// finalFileAdapter.setSortType(FileAdapter.SortType.FileName)
|
||||
// finalFileAdapter.setItemEvent { i, fileItemBinding, viewHolder, itemFile ->
|
||||
// fileItemBinding.root.setOnClickListener {
|
||||
// tryOpenFile(itemFile)
|
||||
// }
|
||||
// fileItemBinding.more.setOnClickListener {
|
||||
// if (itemFile == null) {
|
||||
// return@setOnClickListener
|
||||
// }
|
||||
// val popupMenu =
|
||||
// PopupMenu(this@FileManagerActivity, fileItemBinding.more)
|
||||
// val cutBoardMenu =
|
||||
// popupMenu.menu.addSubMenu(R.string.cut_board_operation)
|
||||
// val fileMenu = popupMenu.menu.addSubMenu(R.string.file_operation)
|
||||
// val bookmarksMenu =
|
||||
// popupMenu.menu.addSubMenu(R.string.bookmarks_operation)
|
||||
// cutBoardMenu.add(R.string.copy_file_name)
|
||||
// cutBoardMenu.add(R.string.copy_file_path)
|
||||
// fileMenu.add(R.string.copy)
|
||||
// fileMenu.add(R.string.cut_off)
|
||||
// fileMenu.add(R.string.mod_action9)
|
||||
// fileMenu.add(R.string.delete_title)
|
||||
// if (bookmarkManager.contains(file)) {
|
||||
// bookmarksMenu.add(R.string.remove_bookmark)
|
||||
// } else {
|
||||
// bookmarksMenu.add(R.string.add_bookmark)
|
||||
// }
|
||||
// bookmarksMenu.add(R.string.bookmark_manager)
|
||||
// addJumpBookMenu(bookmarksMenu)
|
||||
// popupMenu.setOnMenuItemClickListener { item ->
|
||||
// val title = item.title
|
||||
// if (title == getText(R.string.copy_file_name)) {
|
||||
// val name = itemFile.name
|
||||
// GlobalMethod.copyText(
|
||||
// this@FileManagerActivity,
|
||||
// name,
|
||||
// viewBinding.fab
|
||||
// )
|
||||
// } else if (title == getText(R.string.copy_file_path)) {
|
||||
// val path = itemFile.absolutePath
|
||||
// GlobalMethod.copyText(
|
||||
// this@FileManagerActivity,
|
||||
// path,
|
||||
// viewBinding.fab
|
||||
// )
|
||||
// } else if (title == getText(R.string.delete_title)) {
|
||||
// executorService.submit {
|
||||
// FileOperator.delete_files(itemFile)
|
||||
// runOnUiThread {
|
||||
// loadFiles(directs)
|
||||
// }
|
||||
// }
|
||||
// } else if (title == getText(R.string.copy)) {
|
||||
// finalFileAdapter.setSelectPath(itemFile.absolutePath, true)
|
||||
// } else if (title == getText(R.string.cut_off)) {
|
||||
// finalFileAdapter.setSelectPath(itemFile.absolutePath, false)
|
||||
// } else if (title == getText(R.string.mod_action9)) {
|
||||
// val oldName = itemFile.name
|
||||
// MaterialDialog(this@FileManagerActivity).show {
|
||||
// title(R.string.mod_action9)
|
||||
// input(
|
||||
// maxLength = 255,
|
||||
// waitForPositiveButton = false, prefill = oldName
|
||||
// ) { dialog, text ->
|
||||
// if (text.length in 1..255) {
|
||||
// dialog.setActionButtonEnabled(
|
||||
// WhichButton.POSITIVE,
|
||||
// true
|
||||
// )
|
||||
// }
|
||||
// }.positiveButton(R.string.dialog_ok, null) { dialog ->
|
||||
// val newName = dialog.getInputField().text.toString()
|
||||
// if (!newName.isEmpty() || newName != oldName) {
|
||||
// val reNameFile = File("$directs/$newName")
|
||||
// itemFile.renameTo(reNameFile)
|
||||
// loadFiles(directs)
|
||||
// }
|
||||
// }.negativeButton(R.string.dialog_close)
|
||||
// }
|
||||
// } else if (title == getString(R.string.remove_bookmark)) {
|
||||
// val removeBookmark =
|
||||
// bookmarkManager.removeBookmark(itemFile.absolutePath)
|
||||
// if (removeBookmark) {
|
||||
// Snackbar.make(
|
||||
// viewBinding.fab,
|
||||
// R.string.remove_bookmark_success,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).setAction(R.string.symbol10) {
|
||||
// bookmarkManager.addBookmark(
|
||||
// itemFile.absolutePath,
|
||||
// FileOperator.getPrefixName(file)
|
||||
// )
|
||||
// }
|
||||
// .show()
|
||||
// } else {
|
||||
// Snackbar.make(
|
||||
// viewBinding.fab,
|
||||
// R.string.remove_bookmark_fail,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// } else if (title == getString(R.string.add_bookmark)) {
|
||||
// val addBookmark = bookmarkManager.addBookmark(
|
||||
// itemFile.absolutePath,
|
||||
// FileOperator.getPrefixName(file)
|
||||
// )
|
||||
// if (addBookmark) {
|
||||
// Snackbar.make(
|
||||
// viewBinding.fab,
|
||||
// R.string.add_bookmark_success,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// } else {
|
||||
// Snackbar.make(
|
||||
// viewBinding.fab,
|
||||
// R.string.add_bookmark_fail,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// } else if (title == getString(R.string.bookmark_manager)) {
|
||||
// bookmarkManager.save()
|
||||
// startActivity(
|
||||
// Intent(
|
||||
// this@FileManagerActivity,
|
||||
// BookmarkManagerActivity::class.java
|
||||
// )
|
||||
// )
|
||||
// } else {
|
||||
// loadBook(title)
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
// popupMenu.show()
|
||||
// }
|
||||
// }
|
||||
// runOnUiThread {
|
||||
// viewBinding.fileList.adapter = finalFileAdapter
|
||||
// viewBinding.fileList.isVisible = true
|
||||
// viewBinding.fileError.isVisible = false
|
||||
// viewBinding.progressBar.isVisible = false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
|
||||
// /**
|
||||
// * 点击书签项目
|
||||
// */
|
||||
// fun loadBook(menuTitle: CharSequence) {
|
||||
// if (bookmarkMap.containsKey(menuTitle)) {
|
||||
// val path = bookmarkMap[menuTitle]
|
||||
// if (path != null) {
|
||||
// val rootPath = viewModel.getRootPath()
|
||||
// if (path.startsWith(rootPath)) {
|
||||
// val newFile = File(path)
|
||||
// if (newFile.exists()) {
|
||||
// if (newFile.isDirectory) {
|
||||
// viewModel.loadFiles(newFile.absolutePath)
|
||||
// } else {
|
||||
//// tryOpenFile(newFile)
|
||||
// }
|
||||
// } else {
|
||||
// Snackbar.make(
|
||||
// viewBinding.fab,
|
||||
// R.string.bookmark_jump_failed,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// } else {
|
||||
// Snackbar.make(
|
||||
// viewBinding.fab,
|
||||
// R.string.cannot_be_accessed_this_directory,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// override fun onPause() {
|
||||
// viewModel.getBookmarkManager().save()
|
||||
// super.onPause()
|
||||
|
@ -461,10 +98,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
loadMineBookmarksMenu()
|
||||
super.onResume()
|
||||
}
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK) {
|
||||
|
@ -474,20 +108,17 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
val intent = Intent()
|
||||
intent.putExtra("File", path)
|
||||
setResult(RESULT_OK, intent)
|
||||
// bookmarkManager.save()
|
||||
finish()
|
||||
}
|
||||
} else if (viewModel.startTypeData == FileManagerViewModel.StartType.SELECT_FILE && requestCode == 2) {
|
||||
val path = viewModel.parseFilePath(this@FileManagerActivity, data)
|
||||
if (path != null) {
|
||||
val intent = Intent()
|
||||
intent.putExtra("File", path)
|
||||
setResult(RESULT_OK, intent)
|
||||
// bookmarkManager.save()
|
||||
finish()
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, "未设置的操作", Toast.LENGTH_SHORT).show()
|
||||
// val path = viewModel.parseFilePath(this@FileManagerActivity, data)
|
||||
// if (path != null) {
|
||||
// val intent = Intent()
|
||||
// intent.putExtra("File", path)
|
||||
// setResult(RESULT_OK, intent)
|
||||
//// bookmarkManager.save()
|
||||
// finish()
|
||||
// }
|
||||
}
|
||||
// else if (requestCode == 3) {
|
||||
//新建源文件
|
||||
|
@ -509,6 +140,11 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
lateinit var photoAlbumResultLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
lateinit var systemFileManagerResultLauncher: ActivityResultLauncher<String>
|
||||
|
||||
|
||||
//
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val id = item.itemId
|
||||
|
@ -522,22 +158,22 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
viewModel.loadFiles(viewModel.getCurrentPath())
|
||||
return true
|
||||
}
|
||||
R.id.photo_album -> {
|
||||
this@FileManagerActivity.startActivityForResult(
|
||||
Intent(
|
||||
Intent.ACTION_PICK,
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
), 1
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.system_file_manager -> {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "*/*"
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
this@FileManagerActivity.startActivityForResult(intent, 2)
|
||||
return true
|
||||
}
|
||||
// R.id.photo_album -> {
|
||||
// this@FileManagerActivity.startActivityForResult(
|
||||
// Intent(
|
||||
// Intent.ACTION_PICK,
|
||||
// MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
// ), 1
|
||||
// )
|
||||
// return true
|
||||
// }
|
||||
// R.id.system_file_manager -> {
|
||||
// val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
// intent.type = "*/*"
|
||||
// intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
// this@FileManagerActivity.startActivityForResult(intent, 2)
|
||||
// return true
|
||||
// }
|
||||
R.id.creteFolder -> {
|
||||
// createFolderAction()
|
||||
return true
|
||||
|
@ -550,7 +186,6 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||
return if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
|
||||
if (viewModel.getCurrentPath() == viewModel.getRootPath()) {
|
||||
// bookmarkManager.save()
|
||||
finish()
|
||||
true
|
||||
} else {
|
||||
|
@ -823,16 +458,6 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
// return null
|
||||
// }
|
||||
//
|
||||
// override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityFileBinding {
|
||||
// return ActivityFileBinding.inflate(layoutInflater)
|
||||
// }
|
||||
//
|
||||
// override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
|
||||
// if (canUseView) {
|
||||
// initView()
|
||||
// initAction()
|
||||
// }
|
||||
// }
|
||||
private lateinit var menuBinding: MenuBinding
|
||||
private val viewModel: FileManagerViewModel by lazy {
|
||||
ViewModelProvider(this).get(FileManagerViewModel::class.java)
|
||||
|
@ -882,15 +507,30 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
viewModel.loadFiles(viewModel.getCurrentPath())
|
||||
viewBinding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
systemFileManagerResultLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.GetContent()) {
|
||||
val path = viewModel.parseFilePath(this, it)
|
||||
if (path != null) {
|
||||
CoreDialog(this).setTitle(R.string.system_file_manager).setMessage(path)
|
||||
.setPositiveButton(R.string.select_file) {
|
||||
setResultAndFinish(path)
|
||||
}.setNegativeButton(R.string.dialog_cancel) {
|
||||
|
||||
}.setCancelable(false).show()
|
||||
|
||||
} else {
|
||||
Snackbar.make(
|
||||
viewBinding.fab,
|
||||
R.string.bad_file_type,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
FastScrollerBuilder(viewBinding.recyclerView).useMd2Style()
|
||||
.setPopupTextProvider(adapter).build()
|
||||
} else {
|
||||
val bundle = intent.getBundleExtra("data")
|
||||
if (bundle == null) {
|
||||
showError("无效的请求。")
|
||||
finish()
|
||||
return
|
||||
}
|
||||
if (bundle != null) {
|
||||
if (bundle.containsKey("path")) {
|
||||
viewModel.currentPathLiveData.value = bundle.getString("path")
|
||||
}
|
||||
|
@ -898,8 +538,18 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
val type = bundle.getString("type")
|
||||
viewModel.startTypeData = when (type) {
|
||||
"selectDirectents" -> {
|
||||
Snackbar.make(
|
||||
viewBinding.fab,
|
||||
R.string.select_directents,
|
||||
Snackbar.LENGTH_INDEFINITE
|
||||
).setAction(R.string.dialog_ok) {
|
||||
finish()
|
||||
}.setGestureInsetBottomIgnored(true).show()
|
||||
FileManagerViewModel.StartType.SELECT_DIRECTORY
|
||||
}
|
||||
"selectFile" -> {
|
||||
FileManagerViewModel.StartType.SELECT_FILE
|
||||
}
|
||||
else -> {
|
||||
FileManagerViewModel.StartType.DEFAULT
|
||||
}
|
||||
|
@ -909,6 +559,8 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
viewModel.setRootPath(bundle.getString("rootpath"))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
|
@ -920,6 +572,10 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
if (viewModel.startTypeData != FileManagerViewModel.StartType.SELECT_FILE) {
|
||||
menu.removeItem(R.id.selectFile)
|
||||
}
|
||||
menuBinding.systemFileManagerItem.setOnMenuItemClickListener {
|
||||
systemFileManagerResultLauncher.launch("*/*")
|
||||
true
|
||||
}
|
||||
menuBinding.actionSortByType.setOnMenuItemClickListener {
|
||||
viewModel.sortTypeLiveData.value = FileManagerViewModel.SortType.BY_TYPE
|
||||
true
|
||||
|
@ -964,6 +620,16 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置结果并结束界面
|
||||
*/
|
||||
fun setResultAndFinish(path: String) {
|
||||
val temIntent = Intent()
|
||||
temIntent.putExtra("File", path)
|
||||
setResult(RESULT_OK, temIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载观察者
|
||||
|
@ -989,6 +655,17 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
} else {
|
||||
if (file.isDirectory) {
|
||||
viewModel.currentPathLiveData.value = file.absolutePath
|
||||
} else {
|
||||
//文件点击事件
|
||||
if (viewModel.startTypeData == FileManagerViewModel.StartType.SELECT_FILE) {
|
||||
Snackbar.make(
|
||||
viewBinding.fab,
|
||||
R.string.select_file,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).setAction(R.string.dialog_ok) {
|
||||
setResultAndFinish(file.absolutePath)
|
||||
}.setGestureInsetBottomIgnored(true).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1098,8 +775,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
}
|
||||
}
|
||||
viewModel.currentPathLiveData.observe(this) {
|
||||
if (it==null)
|
||||
{
|
||||
if (it == null) {
|
||||
return@observe
|
||||
}
|
||||
val root = getString(R.string.root_path)
|
||||
|
|
|
@ -19,6 +19,7 @@ class LibraryActivity : BaseActivity<ActivityLibraryBinding>() {
|
|||
*/
|
||||
private fun getLibInfoList(): ArrayList<LibInfo> {
|
||||
val libInfoArrayList = ArrayList<LibInfo>()
|
||||
|
||||
libInfoArrayList.add(
|
||||
LibInfo(
|
||||
"Kotlin",
|
||||
|
@ -27,6 +28,22 @@ class LibraryActivity : BaseActivity<ActivityLibraryBinding>() {
|
|||
"Apache License 2.0"
|
||||
)
|
||||
)
|
||||
// libInfoArrayList.add(
|
||||
// LibInfo(
|
||||
// "Light",
|
||||
// "The usual Snackbar, but elegant",
|
||||
// "https://github.com/TonnyL/Light",
|
||||
// "MIT"
|
||||
// )
|
||||
// )
|
||||
libInfoArrayList.add(
|
||||
LibInfo(
|
||||
"FloatingActionButtonSpeedDial",
|
||||
"A Floating Action Button Speed Dial implementation for Android that follows the Material Design specification",
|
||||
"https://github.com/leinardi/FloatingActionButtonSpeedDial",
|
||||
"Apache License 2.0"
|
||||
)
|
||||
)
|
||||
libInfoArrayList.add(
|
||||
LibInfo(
|
||||
"Banner",
|
||||
|
|
|
@ -16,7 +16,10 @@ import androidx.core.view.GravityCompat
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.*
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.navigateUp
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bumptech.glide.Glide
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
|
@ -80,12 +83,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||
navController.navInflater.inflate(R.navigation.main_nav).apply {
|
||||
val use =
|
||||
AppSettings.getValue(AppSettings.Setting.UseTheCommunityAsTheLaunchPage, true)
|
||||
startDestination = if (use) {
|
||||
this.setStartDestination(
|
||||
if (use) {
|
||||
viewBinding.mainButton.hide()
|
||||
R.id.community_item
|
||||
} else {
|
||||
R.id.mod_item
|
||||
}
|
||||
)
|
||||
navController.graph = this
|
||||
}
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
|
@ -448,7 +453,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||
val compressionManager = CompressionManager.instance
|
||||
if (templateDirectory.exists()) {
|
||||
val gson = Gson()
|
||||
val newInfoData = compressionManager.readEntry(formFile, LocalTemplatePackage.INFONAME)
|
||||
val newInfoData =
|
||||
compressionManager.readEntry(formFile, LocalTemplatePackage.INFONAME)
|
||||
if (newInfoData == null) {
|
||||
handler.post {
|
||||
Snackbar.make(
|
||||
|
|
|
@ -10,13 +10,13 @@ import com.coldmint.rust.core.tool.LineParser
|
|||
import com.coldmint.rust.core.interfaces.LineParserEvent
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ClickableSpan
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import android.text.Spanned
|
||||
import android.os.Looper
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.core.view.isVisible
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.pro.adapters.OptimizeAdapter
|
||||
import com.coldmint.rust.pro.databean.OptimizeGroup
|
||||
|
@ -173,7 +173,7 @@ class OptimizeActivity : BaseActivity<ActivityOptimizeBinding>() {
|
|||
* @param file
|
||||
*/
|
||||
private fun analyzeFile(file: File) {
|
||||
if (mFileSignatureCache!!.isChange(file)) {
|
||||
if (mFileSignatureCache.isChange(file)) {
|
||||
hasError = false
|
||||
val type = FileOperator.getFileType(file)
|
||||
when (type) {
|
||||
|
@ -237,22 +237,11 @@ class OptimizeActivity : BaseActivity<ActivityOptimizeBinding>() {
|
|||
spannableString.setSpan(
|
||||
object : ClickableSpan() {
|
||||
override fun onClick(widget: View) {
|
||||
val materialDialog = MaterialDialog(
|
||||
this@OptimizeActivity,
|
||||
MaterialDialog.DEFAULT_BEHAVIOR
|
||||
)
|
||||
materialDialog.title(R.string.details, null)
|
||||
materialDialog.message(
|
||||
null,
|
||||
lineBuilder.toString(),
|
||||
null
|
||||
)
|
||||
materialDialog.positiveButton(
|
||||
R.string.close,
|
||||
null,
|
||||
null
|
||||
)
|
||||
materialDialog.show()
|
||||
CoreDialog(this@OptimizeActivity).setTitle(R.string.details)
|
||||
.setMessage(lineBuilder.toString())
|
||||
.setPositiveButton(R.string.close) {
|
||||
|
||||
}.show()
|
||||
}
|
||||
},
|
||||
tip.indexOf(action),
|
||||
|
@ -278,20 +267,9 @@ class OptimizeActivity : BaseActivity<ActivityOptimizeBinding>() {
|
|||
spannableString.setSpan(
|
||||
object : ClickableSpan() {
|
||||
override fun onClick(widget: View) {
|
||||
val materialDialog = MaterialDialog(
|
||||
this@OptimizeActivity,
|
||||
MaterialDialog.DEFAULT_BEHAVIOR
|
||||
)
|
||||
materialDialog.title(R.string.details, null)
|
||||
materialDialog.message(
|
||||
null,
|
||||
noteBuilder.toString(),
|
||||
null
|
||||
)
|
||||
materialDialog.negativeButton(
|
||||
R.string.edit,
|
||||
null
|
||||
) { materialDialog: MaterialDialog? ->
|
||||
CoreDialog(this@OptimizeActivity).setTitle(R.string.details)
|
||||
.setMessage(noteBuilder.toString())
|
||||
.setPositiveButton(R.string.edit) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("path", file.absolutePath)
|
||||
bundle.putString(
|
||||
|
@ -305,14 +283,9 @@ class OptimizeActivity : BaseActivity<ActivityOptimizeBinding>() {
|
|||
)
|
||||
intent.putExtra("data", bundle)
|
||||
this@OptimizeActivity.startActivity(intent)
|
||||
null
|
||||
}
|
||||
materialDialog.positiveButton(
|
||||
R.string.close,
|
||||
null,
|
||||
null
|
||||
)
|
||||
materialDialog.show()
|
||||
}.setNegativeButton(R.string.close) {
|
||||
|
||||
}.show()
|
||||
}
|
||||
},
|
||||
tip.indexOf(action),
|
||||
|
@ -342,7 +315,7 @@ class OptimizeActivity : BaseActivity<ActivityOptimizeBinding>() {
|
|||
}
|
||||
}
|
||||
if (!hasError) {
|
||||
mFileSignatureCache!!.putFile(file)
|
||||
mFileSignatureCache.putFile(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
|
||||
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
|
||||
if (canUseView) {
|
||||
viewBinding.toolbar.title = getText(R.string.release)
|
||||
title = getText(R.string.release)
|
||||
setReturnButton()
|
||||
val layoutManager = LinearLayoutManager(this)
|
||||
layoutManager.orientation = RecyclerView.HORIZONTAL
|
||||
|
@ -876,7 +876,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
apiCallBack = object : ApiCallBack<ApiResponse> {
|
||||
override fun onResponse(t: ApiResponse) {
|
||||
dialog.dismiss()
|
||||
resetButton()
|
||||
if (t.code == ServerConfiguration.Success_Code) {
|
||||
val temModClass = modClass
|
||||
if (temModClass != null) {
|
||||
|
@ -922,7 +921,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
override fun onFailure(e: Exception) {
|
||||
dialog.dismiss()
|
||||
showInternetError(viewBinding.releaseButton, e)
|
||||
resetButton()
|
||||
}
|
||||
|
||||
}, progressListener = object : ProgressListener {
|
||||
|
@ -944,13 +942,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
}
|
||||
|
||||
})
|
||||
viewBinding.releaseButton.text = getString(R.string.releaseing)
|
||||
viewBinding.releaseButton.setBackgroundColor(
|
||||
GlobalMethod.getThemeColor(
|
||||
this,
|
||||
R.attr.colorPrimaryVariant
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
@ -989,7 +980,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
apiCallBack = object : ApiCallBack<ApiResponse> {
|
||||
override fun onResponse(t: ApiResponse) {
|
||||
dialog.dismiss()
|
||||
resetButton()
|
||||
if (t.code == ServerConfiguration.Success_Code) {
|
||||
val temModClass = modClass
|
||||
if (temModClass != null) {
|
||||
|
@ -1040,7 +1030,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
override fun onFailure(e: Exception) {
|
||||
dialog.dismiss()
|
||||
showInternetError(viewBinding.releaseButton, e)
|
||||
resetButton()
|
||||
}
|
||||
|
||||
}, progressListener = object : ProgressListener {
|
||||
|
@ -1062,13 +1051,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
}
|
||||
|
||||
})
|
||||
viewBinding.releaseButton.text = getString(R.string.releaseing)
|
||||
viewBinding.releaseButton.setBackgroundColor(
|
||||
GlobalMethod.getThemeColor(
|
||||
this,
|
||||
R.attr.colorPrimaryVariant
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1120,15 +1102,6 @@ class ReleaseModActivity : BaseActivity<ActivityReleaseModBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新设置按钮
|
||||
*/
|
||||
fun resetButton() {
|
||||
viewBinding.releaseButton.text = getString(R.string.release)
|
||||
viewBinding.releaseButton.setBackgroundColor(
|
||||
GlobalMethod.getColorPrimary(this)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.util.Log
|
|||
import cat.ereza.customactivityoncrash.config.CaocConfig
|
||||
import com.coldmint.rust.core.web.ServerConfiguration
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||
import com.coldmint.rust.pro.tool.GlobalMethod
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import com.google.android.material.color.DynamicColorsOptions
|
||||
|
@ -28,6 +29,7 @@ class RustApplication : Application() {
|
|||
DynamicColors.isDynamicColorAvailable()
|
||||
)
|
||||
}.build()
|
||||
CompletionItemConverter.init(this)
|
||||
DynamicColors.applyToActivitiesIfAvailable(this, options)
|
||||
//程序崩溃
|
||||
CaocConfig.Builder.create()
|
||||
|
|
|
@ -51,6 +51,13 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>() {
|
|||
val english_editing_mode =
|
||||
manager.findPreference<SwitchPreference>(requireContext().getString(R.string.setting_english_editing_mode))
|
||||
|
||||
val customizeEdit = manager.findPreference<PreferenceScreen>("customize_edit")
|
||||
customizeEdit!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
val intent = Intent(requireContext(), CustomizeEditTextActivity::class.java)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
|
||||
val dynamicColor =
|
||||
manager.findPreference<SwitchPreference>(requireContext().getString(R.string.setting_dynamic_color))
|
||||
if (!DynamicColors.isDynamicColorAvailable()) {
|
||||
|
|
|
@ -9,10 +9,12 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.bumptech.glide.Glide
|
||||
import com.coldmint.rust.core.ModClass
|
||||
import com.coldmint.rust.core.SourceFile
|
||||
import com.coldmint.rust.core.turret.TurretInstaller
|
||||
import com.coldmint.rust.core.turret.TurretSketchpadView
|
||||
import com.coldmint.rust.pro.base.BaseActivity
|
||||
import com.coldmint.rust.pro.databinding.ActivityTurretDesignBinding
|
||||
import java.io.File
|
||||
|
@ -22,9 +24,6 @@ import java.io.File
|
|||
*/
|
||||
class TurretDesignActivity : BaseActivity<ActivityTurretDesignBinding>() {
|
||||
|
||||
lateinit var turretInstaller: TurretInstaller
|
||||
|
||||
val scale = 5
|
||||
|
||||
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
|
||||
if (canUseView) {
|
||||
|
@ -51,18 +50,25 @@ class TurretDesignActivity : BaseActivity<ActivityTurretDesignBinding>() {
|
|||
return
|
||||
} else {
|
||||
val file = mainImage[0]
|
||||
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
|
||||
viewBinding.mainImageView.setImageBitmap(bitmap)
|
||||
val layoutParams = viewBinding.mainImageView.layoutParams
|
||||
layoutParams.width = bitmap.width * scale
|
||||
layoutParams.height = bitmap.height * scale
|
||||
viewBinding.turretSketchpadView.setImage(file.absolutePath)
|
||||
// viewBinding.toolbar.postDelayed({
|
||||
// Toast.makeText(this, "执行", Toast.LENGTH_SHORT).show()
|
||||
// viewBinding.turretsDragView.setBaseImage(file.absolutePath)
|
||||
// }, 1000)
|
||||
// val bitmap = BitmapFactory.decodeFile(file.absolutePath)
|
||||
// viewBinding.mainImageView.setImageBitmap(bitmap)
|
||||
// val layoutParams = viewBinding.mainImageView.layoutParams
|
||||
// layoutParams.width = bitmap.width * scale
|
||||
// layoutParams.height = bitmap.height * scale
|
||||
|
||||
}
|
||||
|
||||
turretInstaller =
|
||||
TurretInstaller(viewBinding.relativeLayout, sourceFile)
|
||||
turretInstaller.setScale(scale)
|
||||
turretInstaller.installAllTurrets()
|
||||
// val sketchpadView = TurretSketchpadView(this)
|
||||
// sketchpadView.
|
||||
// viewBinding.frameLayout.addView(sketchpadView)
|
||||
TurretInstaller.installerAllTurret(viewBinding.frameLayout, sourceFile) {
|
||||
val game = viewBinding.turretSketchpadView.toGameCoordinate(it)
|
||||
// viewBinding.textView.text = "坐标 x:${game.x} y:${game.y}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
import com.coldmint.rust.pro.R
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.color.DynamicColors
|
||||
|
@ -121,13 +122,9 @@ abstract class BaseActivity<ViewBingType : ViewBinding> :
|
|||
* @param msg String 错误信息
|
||||
*/
|
||||
protected fun showError(msg: String) {
|
||||
MaterialDialog(this).show {
|
||||
title(R.string.error).message(text = msg).cancelable(false)
|
||||
.positiveButton(R.string.dialog_close) {
|
||||
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示对话框
|
||||
|
@ -155,10 +152,10 @@ abstract class BaseActivity<ViewBingType : ViewBinding> :
|
|||
"${msg}\n${exception}"
|
||||
}
|
||||
if (view == null) {
|
||||
MaterialDialog(this).show {
|
||||
title(R.string.details).message(text = thisMsg)
|
||||
.positiveButton(R.string.dialog_ok)
|
||||
}
|
||||
CoreDialog(this).setTitle(R.string.details).setMessage(thisMsg)
|
||||
.setPositiveButton(R.string.dialog_ok) {
|
||||
|
||||
}.show()
|
||||
} else {
|
||||
Snackbar.make(
|
||||
view,
|
||||
|
|
|
@ -49,11 +49,11 @@ class RustAnalyzer() : EnglishMode {
|
|||
|
||||
|
||||
/**
|
||||
* 语法分析器
|
||||
* @param content CharSequence
|
||||
* @param colors TextAnalyzeResult
|
||||
* @param delegate Delegate
|
||||
*/
|
||||
// * 语法分析器
|
||||
// * @param content CharSequence
|
||||
// * @param colors TextAnalyzeResult
|
||||
// * @param delegate Delegate
|
||||
// */
|
||||
// override fun analyze(
|
||||
// content: CharSequence,
|
||||
// colors: TextAnalyzeResult,
|
||||
|
|
|
@ -19,14 +19,15 @@ import java.util.ArrayList
|
|||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Cold Mint
|
||||
* @date 2022/1/25 17:32
|
||||
*/
|
||||
@Deprecated("")
|
||||
class RustAutoComplete(val context: Context) : EnglishMode {
|
||||
|
||||
private val debugKey = "自动完成器"
|
||||
private var codeDataBase: CodeDataBase? = null
|
||||
private val executorService = Executors.newCachedThreadPool()
|
||||
private var fileDataBase: FileDataBase? = null
|
||||
private var codeEditor: CodeEditor? = null
|
||||
|
||||
|
@ -41,16 +42,8 @@ class RustAutoComplete(val context: Context) : EnglishMode {
|
|||
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
|
||||
}
|
||||
|
||||
//类型转换器
|
||||
private val completionItemConverter: CompletionItemConverter by lazy {
|
||||
CompletionItemConverter.instance.init(context)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
var keyWord = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为英文模式
|
||||
*/
|
||||
|
@ -62,7 +55,7 @@ class RustAutoComplete(val context: Context) : EnglishMode {
|
|||
*/
|
||||
fun setSourceFolder(sourceFolder: String) {
|
||||
DebugHelper.printLog(debugKey, "已设置源文件目录" + sourceFolder, "设置源文件目录")
|
||||
completionItemConverter.setSourceFilePath(sourceFolder)
|
||||
CompletionItemConverter.setSourceFilePath(sourceFolder)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +69,7 @@ class RustAutoComplete(val context: Context) : EnglishMode {
|
|||
rootCodeName: String,
|
||||
modFolder: String
|
||||
) {
|
||||
completionItemConverter.configurationFileConversion(sourceFilePath, rootCodeName, modFolder)
|
||||
CompletionItemConverter.configurationFileConversion(sourceFilePath, rootCodeName, modFolder)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,277 +142,276 @@ class RustAutoComplete(val context: Context) : EnglishMode {
|
|||
return
|
||||
}
|
||||
|
||||
keyWord = prefix
|
||||
val temCodeEditor: CodeEditor = codeEditor!!
|
||||
val lineData = temCodeEditor.text.getLineString(line)
|
||||
if (lineData.startsWith('[')) {
|
||||
//搜索节
|
||||
val name = lineData.subSequence(1, lineData.length).toString()
|
||||
val list = if (isEnglishMode) {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
||||
} else {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
||||
}
|
||||
list?.forEach {
|
||||
completionPublisher.addItem(completionItemConverter.sectionInfoToCompletionItem(it))
|
||||
}
|
||||
} else {
|
||||
val key = ":"
|
||||
val keyIndex = lineData.lastIndexOf(key)
|
||||
if (keyIndex > -1) {
|
||||
//检查是否可响应变量
|
||||
val start = "\${"
|
||||
val end = "}"
|
||||
val startIndex = lineData.lastIndexOf(start)
|
||||
if (startIndex > -1) {
|
||||
val endIndex = lineData.lastIndexOf(end)
|
||||
if (endIndex < startIndex) {
|
||||
//如果}的位置小于${的位置,说明没有闭合
|
||||
val keyWord =
|
||||
lineData.subSequence(startIndex + start.length, lineData.length)
|
||||
.toString()
|
||||
val previousText =
|
||||
lineData.subSequence(keyIndex + key.length, startIndex).toString()
|
||||
if (keyWord.isNotBlank()) {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
if (it.name.contains(keyWord)) {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
RustAutoComplete.keyWord = keyWord
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// val value =
|
||||
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
|
||||
// Log.d("值", value)
|
||||
//搜索值
|
||||
// frontIndex 前面冒号的位置
|
||||
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
|
||||
val keyValue = if (frontIndex > -1) {
|
||||
lineData.subSequence(frontIndex + key.length, keyIndex)
|
||||
} else {
|
||||
lineData.subSequence(0, keyIndex)
|
||||
}
|
||||
|
||||
val codeInfo =
|
||||
if (isEnglishMode) {
|
||||
codeDataBase!!.getCodeDao().findCodeByCode(keyValue.toString())
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao().findCodeByTranslate(keyValue.toString())
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + prefix + "]",
|
||||
"值检查"
|
||||
)
|
||||
if (codeInfo != null) {
|
||||
val typeInfo = completionItemConverter.getValueType(codeInfo.type)
|
||||
//获取代码的关联列表
|
||||
if (typeInfo != null && typeInfo.list.isNotBlank()) {
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
|
||||
)
|
||||
lineParser.text = typeInfo.list
|
||||
lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
//分析关联提示项目
|
||||
val temCodeInfo =
|
||||
codeDataBase!!.getCodeDao().findCodeByCode(lineData)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (temCodeInfo == null) {
|
||||
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
|
||||
val fileType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
)
|
||||
|
||||
val fileInfo = fileDataBase!!.getFileInfoDao()
|
||||
.searchFileInfoByNameAndType(
|
||||
prefix,
|
||||
fileType.toString(),
|
||||
identifiersPromptNumber
|
||||
)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
|
||||
?: -1) + "]个结果",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (fileInfo != null && fileInfo.isNotEmpty()) {
|
||||
for (fileTable in fileInfo) {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.fileTableToCompletionItem(
|
||||
fileTable
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
//用户自动值类型提示
|
||||
val customType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
fileDataBase!!.getValueDao()
|
||||
.searchValueByKey(
|
||||
prefix,
|
||||
customType,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
?.forEach {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.valueTableToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
|
||||
val type = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
val list = if (isEnglishMode
|
||||
) {
|
||||
codeDataBase!!.getCodeDao().findCodeByCodeInType(
|
||||
prefix,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao().findCodeByTranslateInType(
|
||||
prefix,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
|
||||
"值类型引用"
|
||||
)
|
||||
if (!list.isNullOrEmpty()) {
|
||||
list.forEach {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@section") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
val section = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
// codeEditor!!.textAnalyzeResult.navigation.forEach {
|
||||
// if (section == getSectionType(it.label)) {
|
||||
// result.add(
|
||||
// completionItemConverter.navigationItemToCompletionItem(
|
||||
// val temCodeEditor: CodeEditor = codeEditor!!
|
||||
// val lineData = temCodeEditor.text.getLineString(line)
|
||||
// if (lineData.startsWith('[')) {
|
||||
// //搜索节
|
||||
// val name = lineData.subSequence(1, lineData.length).toString()
|
||||
// val list = if (isEnglishMode) {
|
||||
// codeDataBase!!.getSectionDao()
|
||||
// .searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
||||
// } else {
|
||||
// codeDataBase!!.getSectionDao()
|
||||
// .searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
||||
// }
|
||||
// list?.forEach {
|
||||
// completionPublisher.addItem(CompletionItemConverter.sectionInfoToCompletionItem(it))
|
||||
// }
|
||||
// } else {
|
||||
// val key = ":"
|
||||
// val keyIndex = lineData.lastIndexOf(key)
|
||||
// if (keyIndex > -1) {
|
||||
// //检查是否可响应变量
|
||||
// val start = "\${"
|
||||
// val end = "}"
|
||||
// val startIndex = lineData.lastIndexOf(start)
|
||||
// if (startIndex > -1) {
|
||||
// val endIndex = lineData.lastIndexOf(end)
|
||||
// if (endIndex < startIndex) {
|
||||
// //如果}的位置小于${的位置,说明没有闭合
|
||||
// val keyWord =
|
||||
// lineData.subSequence(startIndex + start.length, lineData.length)
|
||||
// .toString()
|
||||
// val previousText =
|
||||
// lineData.subSequence(keyIndex + key.length, startIndex).toString()
|
||||
// if (keyWord.isNotBlank()) {
|
||||
// RustAnalyzer.localVariableNameList.forEach {
|
||||
// if (it.name.contains(keyWord)) {
|
||||
// completionPublisher.addItem(
|
||||
// CompletionItemConverter.localVariableNameToCompletionItem(
|
||||
// it, previousText
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// RustAnalyzer.localVariableNameList.forEach {
|
||||
// completionPublisher.addItem(
|
||||
// CompletionItemConverter.localVariableNameToCompletionItem(
|
||||
// it, previousText
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// RustAutoComplete.keyWord = keyWord
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//// val value =
|
||||
//// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
|
||||
//// Log.d("值", value)
|
||||
// //搜索值
|
||||
// // frontIndex 前面冒号的位置
|
||||
// val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
|
||||
// val keyValue = if (frontIndex > -1) {
|
||||
// lineData.subSequence(frontIndex + key.length, keyIndex)
|
||||
// } else {
|
||||
// lineData.subSequence(0, keyIndex)
|
||||
// }
|
||||
//
|
||||
// val codeInfo =
|
||||
// if (isEnglishMode) {
|
||||
// codeDataBase!!.getCodeDao().findCodeByCode(keyValue.toString())
|
||||
// } else {
|
||||
// codeDataBase!!.getCodeDao().findCodeByTranslate(keyValue.toString())
|
||||
// }
|
||||
// DebugHelper.printLog(
|
||||
// debugKey,
|
||||
// "值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + prefix + "]",
|
||||
// "值检查"
|
||||
// )
|
||||
// if (codeInfo != null) {
|
||||
// val typeInfo = CompletionItemConverter.getValueType(codeInfo.type)
|
||||
// //获取代码的关联列表
|
||||
// if (typeInfo != null && typeInfo.list.isNotBlank()) {
|
||||
// DebugHelper.printLog(
|
||||
// debugKey,
|
||||
// "值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
|
||||
// )
|
||||
// lineParser.text = typeInfo.list
|
||||
// lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
// //分析关联提示项目
|
||||
// val temCodeInfo =
|
||||
// codeDataBase!!.getCodeDao().findCodeByCode(lineData)
|
||||
// DebugHelper.printLog(
|
||||
// debugKey,
|
||||
// "值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
|
||||
// "关联提示列表分析"
|
||||
// )
|
||||
// if (temCodeInfo == null) {
|
||||
// if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
|
||||
// val fileType = lineData.subSequence(
|
||||
// lineData.indexOf('(') + 1,
|
||||
// lineData.indexOf(')')
|
||||
// )
|
||||
//
|
||||
// val fileInfo = fileDataBase!!.getFileInfoDao()
|
||||
// .searchFileInfoByNameAndType(
|
||||
// prefix,
|
||||
// fileType.toString(),
|
||||
// identifiersPromptNumber
|
||||
// )
|
||||
// DebugHelper.printLog(
|
||||
// debugKey,
|
||||
// "值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
|
||||
// ?: -1) + "]个结果",
|
||||
// "关联提示列表分析"
|
||||
// )
|
||||
// if (fileInfo != null && fileInfo.isNotEmpty()) {
|
||||
// for (fileTable in fileInfo) {
|
||||
// completionPublisher.addItem(
|
||||
// CompletionItemConverter.fileTableToCompletionItem(
|
||||
// fileTable
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// } else if (lineData.startsWith("@customType(") && lineData.endsWith(
|
||||
// ")"
|
||||
// )
|
||||
// ) {
|
||||
// //用户自动值类型提示
|
||||
// val customType = lineData.subSequence(
|
||||
// lineData.indexOf('(') + 1,
|
||||
// lineData.indexOf(')')
|
||||
// ).toString()
|
||||
// fileDataBase!!.getValueDao()
|
||||
// .searchValueByKey(
|
||||
// prefix,
|
||||
// customType,
|
||||
// identifiersPromptNumber
|
||||
// )
|
||||
// ?.forEach {
|
||||
// completionPublisher.addItem(
|
||||
// CompletionItemConverter.valueTableToCompletionItem(
|
||||
// it
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// } else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
|
||||
// val type = lineData.subSequence(
|
||||
// lineData.indexOf('(') + 1,
|
||||
// lineData.indexOf(')')
|
||||
// ).toString()
|
||||
// val list = if (isEnglishMode
|
||||
// ) {
|
||||
// codeDataBase!!.getCodeDao().findCodeByCodeInType(
|
||||
// prefix,
|
||||
// type,
|
||||
// identifiersPromptNumber
|
||||
// )
|
||||
// } else {
|
||||
// codeDataBase!!.getCodeDao().findCodeByTranslateInType(
|
||||
// prefix,
|
||||
// type,
|
||||
// identifiersPromptNumber
|
||||
// )
|
||||
// }
|
||||
// DebugHelper.printLog(
|
||||
// debugKey,
|
||||
// "关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
|
||||
// "值类型引用"
|
||||
// )
|
||||
// if (!list.isNullOrEmpty()) {
|
||||
// list.forEach {
|
||||
// completionPublisher.addItem(
|
||||
// CompletionItemConverter.codeInfoToCompletionItem(
|
||||
// it
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
//无法分析的关联项目
|
||||
// result.add(
|
||||
// CompletionItem(
|
||||
// lineData,
|
||||
// String.format(
|
||||
// completionItemConverter.associatedTip,
|
||||
// codeInfo.translate
|
||||
// } else if (lineData.startsWith("@section") && lineData.endsWith(
|
||||
// ")"
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
}
|
||||
} else {
|
||||
|
||||
val show = if (isEnglishMode) {
|
||||
temCodeInfo.code.contains(prefix)
|
||||
} else {
|
||||
temCodeInfo.translate.contains(prefix)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + prefix + "关键字[" + show + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (show) {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
temCodeInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//如果不包含:搜索键
|
||||
// val navigationList = temCodeEditor.textAnalyzeResult.navigation
|
||||
// var section: String? = null
|
||||
// if (navigationList != null && navigationList.isNotEmpty()) {
|
||||
// for (navigation in navigationList) {
|
||||
// if (navigation.line > line) {
|
||||
// break
|
||||
// ) {
|
||||
// val section = lineData.subSequence(
|
||||
// lineData.indexOf('(') + 1,
|
||||
// lineData.indexOf(')')
|
||||
// ).toString()
|
||||
//// codeEditor!!.textAnalyzeResult.navigation.forEach {
|
||||
//// if (section == getSectionType(it.label)) {
|
||||
//// result.add(
|
||||
//// CompletionItemConverter.navigationItemToCompletionItem(
|
||||
//// it
|
||||
//// )
|
||||
//// )
|
||||
//// }
|
||||
//// }
|
||||
// } else {
|
||||
// section = navigation.label
|
||||
// //无法分析的关联项目
|
||||
//// result.add(
|
||||
//// CompletionItem(
|
||||
//// lineData,
|
||||
//// String.format(
|
||||
//// CompletionItemConverter.associatedTip,
|
||||
//// codeInfo.translate
|
||||
//// )
|
||||
//// )
|
||||
//// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //如果不在任何节内
|
||||
// if (section == null) {
|
||||
// return@submit
|
||||
// }
|
||||
// val trueSection = getSectionType(section)
|
||||
// val list = if (isEnglishMode) {
|
||||
// codeDataBase!!.getCodeDao().findCodeByEnglishCodeKeyFromSection(
|
||||
// prefix,
|
||||
// trueSection,
|
||||
// identifiersPromptNumber
|
||||
// )
|
||||
// } else {
|
||||
// codeDataBase!!.getCodeDao()
|
||||
// .findCodeByKeyFromSection(prefix, trueSection, identifiersPromptNumber)
|
||||
//
|
||||
// val show = if (isEnglishMode) {
|
||||
// temCodeInfo.code.contains(prefix)
|
||||
// } else {
|
||||
// temCodeInfo.translate.contains(prefix)
|
||||
// }
|
||||
// if (list != null && list.isNotEmpty()) {
|
||||
// list.forEach {
|
||||
// result.add(
|
||||
// completionItemConverter.codeInfoToCompletionItem(it)
|
||||
// DebugHelper.printLog(
|
||||
// debugKey,
|
||||
// "值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + prefix + "关键字[" + show + "]",
|
||||
// "关联提示列表分析"
|
||||
// )
|
||||
// if (show) {
|
||||
// completionPublisher.addItem(
|
||||
// CompletionItemConverter.codeInfoToCompletionItem(
|
||||
// temCodeInfo
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
// true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// //如果不包含:搜索键
|
||||
//// val navigationList = temCodeEditor.textAnalyzeResult.navigation
|
||||
//// var section: String? = null
|
||||
//// if (navigationList != null && navigationList.isNotEmpty()) {
|
||||
//// for (navigation in navigationList) {
|
||||
//// if (navigation.line > line) {
|
||||
//// break
|
||||
//// } else {
|
||||
//// section = navigation.label
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// //如果不在任何节内
|
||||
//// if (section == null) {
|
||||
//// return@submit
|
||||
//// }
|
||||
//// val trueSection = getSectionType(section)
|
||||
//// val list = if (isEnglishMode) {
|
||||
//// codeDataBase!!.getCodeDao().findCodeByEnglishCodeKeyFromSection(
|
||||
//// prefix,
|
||||
//// trueSection,
|
||||
//// identifiersPromptNumber
|
||||
//// )
|
||||
//// } else {
|
||||
//// codeDataBase!!.getCodeDao()
|
||||
//// .findCodeByKeyFromSection(prefix, trueSection, identifiersPromptNumber)
|
||||
//// }
|
||||
//// if (list != null && list.isNotEmpty()) {
|
||||
//// list.forEach {
|
||||
//// result.add(
|
||||
//// CompletionItemConverter.codeInfoToCompletionItem(it)
|
||||
//// )
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun isEnglishMode(): Boolean {
|
||||
|
@ -428,6 +420,5 @@ class RustAutoComplete(val context: Context) : EnglishMode {
|
|||
|
||||
override fun setEnglish(englishMode: Boolean) {
|
||||
this.isEnglishMode = englishMode
|
||||
completionItemConverter.setEnglish(englishMode)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import android.os.Bundle
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.pro.edit.autoComplete.AutoCompleteJob
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||
import io.github.rosemoe.sora.text.CharPosition
|
||||
import io.github.rosemoe.sora.text.ContentReference
|
||||
|
||||
/**
|
||||
* 自动完成信息提供者
|
||||
*/
|
||||
class RustAutoCompleteProvider {
|
||||
|
||||
private val key = "自动完成提供者"
|
||||
private val jobList = ArrayList<AutoCompleteJob>()
|
||||
companion object{
|
||||
var keyWord = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加任务
|
||||
* @param job AutoCompleteJob
|
||||
*/
|
||||
fun addJob(job: AutoCompleteJob): AutoCompleteJob {
|
||||
jobList.add(job)
|
||||
DebugHelper.printLog(key, "添加了新任务${job.getName()}")
|
||||
return job
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除任务
|
||||
*/
|
||||
fun removeJob(job: AutoCompleteJob): AutoCompleteJob {
|
||||
jobList.remove(job)
|
||||
DebugHelper.printLog(key, "移除了任务${job.getName()}")
|
||||
return job
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 请求自动完成
|
||||
* @param contentReference ContentReference
|
||||
* @param charPosition CharPosition
|
||||
* @param completionPublisher CompletionPublisher
|
||||
* @param bundle Bundle
|
||||
*/
|
||||
fun requireAutoComplete(
|
||||
contentReference: ContentReference,
|
||||
charPosition: CharPosition,
|
||||
completionPublisher: CompletionPublisher,
|
||||
bundle: Bundle
|
||||
) {
|
||||
val requireKey = "请求自动完成"
|
||||
if (jobList.isEmpty()) {
|
||||
DebugHelper.printLog(key, "没有任务可执行。", requireKey, true)
|
||||
} else {
|
||||
//行内容
|
||||
val lineData = contentReference.getLine(charPosition.getLine())
|
||||
if (lineData.isBlank()) {
|
||||
DebugHelper.printLog(requireKey, "行内容为空,无需提示。")
|
||||
return
|
||||
}
|
||||
//光标前内容
|
||||
val cursorPrefix = lineData.subSequence(0, charPosition.getColumn()).toString()
|
||||
val symbolIndex = cursorPrefix.lastIndexOf(':')
|
||||
keyWord = if (symbolIndex > 0) {
|
||||
//有冒号
|
||||
cursorPrefix.substring(symbolIndex + 1)
|
||||
} else {
|
||||
//无
|
||||
cursorPrefix
|
||||
}
|
||||
var executeNumber = 0
|
||||
jobList.forEach {
|
||||
//如果需要执行
|
||||
if (it.needPerform(contentReference, charPosition)) {
|
||||
executeNumber++
|
||||
it.requireAutoComplete(
|
||||
contentReference,
|
||||
charPosition,
|
||||
completionPublisher,
|
||||
lineData, keyWord
|
||||
)
|
||||
}
|
||||
}
|
||||
DebugHelper.printLog(key, "执行了${executeNumber}个任务。", requireKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -42,18 +42,18 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
|
|||
val editItem = EditItemBinding.inflate(layoutInflater, parent, false)
|
||||
val completionItem = getItem(position) as RustCompletionItem
|
||||
spannableStringBuilder.clear()
|
||||
val label = completionItem.label.toString()
|
||||
val label = completionItem.title
|
||||
spannableStringBuilder.append(label)
|
||||
//节补丁
|
||||
if (RustAutoComplete.keyWord.startsWith('[') && RustAutoComplete.keyWord.length > 1) {
|
||||
RustAutoComplete.keyWord =
|
||||
RustAutoComplete.keyWord.subSequence(1, RustAutoComplete.keyWord.length)
|
||||
if (RustAutoCompleteProvider.keyWord.startsWith('[') && RustAutoCompleteProvider.keyWord.length > 1) {
|
||||
RustAutoCompleteProvider.keyWord =
|
||||
RustAutoCompleteProvider.keyWord.subSequence(1, RustAutoCompleteProvider.keyWord.length)
|
||||
.toString()
|
||||
}
|
||||
val start = label.lowercase(Locale.getDefault())
|
||||
.indexOf(RustAutoComplete.keyWord.lowercase(Locale.getDefault()))
|
||||
.indexOf(RustAutoCompleteProvider.keyWord.lowercase(Locale.getDefault()))
|
||||
if (start > -1) {
|
||||
val end = start + RustAutoComplete.keyWord.length
|
||||
val end = start + RustAutoCompleteProvider.keyWord.length
|
||||
spannableStringBuilder.setSpan(
|
||||
colorSpan,
|
||||
start,
|
||||
|
|
|
@ -48,7 +48,16 @@ class RustCompletionItem(var title: String) : CompletionItem(title) {
|
|||
* @param p2 Int
|
||||
* @param p3 Int
|
||||
*/
|
||||
override fun performCompletion(p0: CodeEditor?, p1: Content?, p2: Int, p3: Int) {
|
||||
|
||||
//CodeEditor editor, Content text, int line, int column
|
||||
override fun performCompletion(editor: CodeEditor, text: Content, line: Int, column: Int) {
|
||||
if (label == null) {
|
||||
return
|
||||
}
|
||||
val keyOffset = RustAutoCompleteProvider.keyWord.length
|
||||
if (keyOffset == 0) {
|
||||
text.insert(line, column, label)
|
||||
} else {
|
||||
text.replace(line, column - keyOffset, line, column, label)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,7 +90,7 @@ class RustIncrementalAnalyzeManager :
|
|||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(EditorColorScheme.COMMENT)
|
||||
TextStyle.makeStyle(EditorColorScheme.TEXT_NORMAL)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ class RustIncrementalAnalyzeManager :
|
|||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(EditorColorScheme.COMMENT)
|
||||
TextStyle.makeStyle(EditorColorScheme.TEXT_NORMAL)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.coldmint.rust.core.database.code.CodeDataBase
|
|||
import com.coldmint.rust.core.database.file.FileDataBase
|
||||
import com.coldmint.rust.core.interfaces.EnglishMode
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.pro.edit.autoComplete.CodeAutoCompleteJob
|
||||
import io.github.rosemoe.sora.lang.Language
|
||||
import io.github.rosemoe.sora.lang.analysis.AnalyzeManager
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||
|
@ -20,23 +21,51 @@ import io.github.rosemoe.sora.text.ContentReference
|
|||
import io.github.rosemoe.sora.text.TextRange
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
import io.github.rosemoe.sora.widget.SymbolPairMatch
|
||||
import java.util.*
|
||||
|
||||
class RustLanguage(
|
||||
private val context: Context,
|
||||
) : Language, EnglishMode {
|
||||
private val mRustAnalyzer: RustAnalyzer by lazy {
|
||||
RustAnalyzer()
|
||||
}
|
||||
class RustLanguage() : Language, EnglishMode {
|
||||
|
||||
private val autoComplete by lazy {
|
||||
RustAutoComplete(context)
|
||||
}
|
||||
|
||||
// private val autoComplete: RustAutoComplete = RustAutoComplete(context)
|
||||
private var isEnglishMode = false
|
||||
private val rustAnalyzeManager by lazy {
|
||||
RustIncrementalAnalyzeManager()
|
||||
}
|
||||
private val codeAutoCompleteJob: CodeAutoCompleteJob by lazy {
|
||||
CodeAutoCompleteJob()
|
||||
}
|
||||
|
||||
private val newlineHandler: Array<NewlineHandler> by lazy {
|
||||
arrayOf<NewlineHandler>(object : NewlineHandler {
|
||||
override fun matchesRequirement(beforeText: String?, afterText: String?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handleNewline(
|
||||
beforeText: String,
|
||||
afterText: String?,
|
||||
tabSize: Int
|
||||
): NewlineHandleResult {
|
||||
var text = "\n"
|
||||
if (beforeText.startsWith("[")) {
|
||||
if (beforeText.endsWith("_")) {
|
||||
text = "name]"
|
||||
} else if (!beforeText.endsWith("]")) {
|
||||
text = "]"
|
||||
}
|
||||
}
|
||||
val newlineHandleResult = NewlineHandleResult(text, 0)
|
||||
return newlineHandleResult
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private val autoCompleteProvider: RustAutoCompleteProvider by lazy {
|
||||
val a = RustAutoCompleteProvider()
|
||||
a.addJob(codeAutoCompleteJob)
|
||||
a
|
||||
}
|
||||
private var codeDataBase: CodeDataBase? = null
|
||||
|
||||
|
||||
/**
|
||||
|
@ -44,8 +73,8 @@ class RustLanguage(
|
|||
* @param codeDataBean CodeDataBase
|
||||
*/
|
||||
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
||||
mRustAnalyzer.setCodeDataBase(codeDataBase)
|
||||
// autoComplete.setCodeDataBase(codeDataBase)
|
||||
this.codeDataBase = codeDataBase
|
||||
this.codeAutoCompleteJob.setCodeDataBase(codeDataBase)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,35 +86,10 @@ class RustLanguage(
|
|||
}
|
||||
|
||||
fun setFileDataBase(fileDataBase: FileDataBase) {
|
||||
// autoComplete.setFileDataBase(fileDataBase)
|
||||
codeAutoCompleteJob.setFileDataBase(fileDataBase)
|
||||
}
|
||||
|
||||
|
||||
//语法分析器
|
||||
// override fun getAnalyzer(): CodeAnalyzer {
|
||||
// return mRustAnalyzer
|
||||
// }
|
||||
|
||||
//自动完成器
|
||||
// override fun getAutoCompleteProvider(): RustAutoComplete {
|
||||
// return autoComplete
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * 是否为自动完成字符
|
||||
// *
|
||||
// * @param ch 字符
|
||||
// * @return 逻辑值
|
||||
// */
|
||||
// override fun isAutoCompleteChar(ch: Char): Boolean {
|
||||
// return when (ch) {
|
||||
// ':', '.', '_', ' ', ',' -> false
|
||||
// else -> true
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
override fun getAnalyzeManager(): AnalyzeManager {
|
||||
return rustAnalyzeManager
|
||||
}
|
||||
|
@ -95,15 +99,17 @@ class RustLanguage(
|
|||
}
|
||||
|
||||
override fun requireAutoComplete(
|
||||
p0: ContentReference,
|
||||
p1: CharPosition,
|
||||
p2: CompletionPublisher,
|
||||
p3: Bundle
|
||||
contentReference: ContentReference,
|
||||
charPosition: CharPosition,
|
||||
completionPublisher: CompletionPublisher,
|
||||
bundle: Bundle
|
||||
) {
|
||||
val line = p0.getLine(p1.getLine())
|
||||
p2.addItem(RustCompletionItem("121221"))
|
||||
p2.updateList()
|
||||
// autoComplete.requireAutoComplete(line,p2,p1.getLine(),p1.getColumn())
|
||||
autoCompleteProvider.requireAutoComplete(
|
||||
contentReference,
|
||||
charPosition,
|
||||
completionPublisher,
|
||||
bundle
|
||||
)
|
||||
}
|
||||
|
||||
override fun getIndentAdvance(p0: ContentReference, p1: Int, p2: Int): Int {
|
||||
|
@ -112,7 +118,7 @@ class RustLanguage(
|
|||
|
||||
//用标签
|
||||
override fun useTab(): Boolean {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getFormatter(): Formatter {
|
||||
|
@ -125,7 +131,7 @@ class RustLanguage(
|
|||
|
||||
override fun getNewlineHandlers(): Array<NewlineHandler>? {
|
||||
//行处理程序,按下回车时
|
||||
return null
|
||||
return newlineHandler
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,7 +143,6 @@ class RustLanguage(
|
|||
}
|
||||
|
||||
override fun setEnglish(englishMode: Boolean) {
|
||||
mRustAnalyzer.setEnglish(englishMode)
|
||||
// autoComplete.setEnglish(englishMode)
|
||||
isEnglishMode = englishMode
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package com.coldmint.rust.pro.edit.autoComplete
|
||||
|
||||
import android.os.Bundle
|
||||
import com.coldmint.rust.pro.edit.RustAutoComplete
|
||||
import com.coldmint.rust.pro.edit.RustCompletionItem
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||
import io.github.rosemoe.sora.text.CharPosition
|
||||
import io.github.rosemoe.sora.text.ContentReference
|
||||
|
||||
|
||||
/**
|
||||
* 自动完成工作接口
|
||||
*/
|
||||
interface AutoCompleteJob {
|
||||
|
||||
|
||||
/**
|
||||
* 获取工作名称
|
||||
*/
|
||||
fun getName():String
|
||||
|
||||
|
||||
/**
|
||||
* 该任务是否需要执行(返回true则执行)
|
||||
* @param contentReference ContentReference
|
||||
* @param charPosition CharPosition
|
||||
* @return String
|
||||
*/
|
||||
fun needPerform(
|
||||
contentReference: ContentReference,
|
||||
charPosition: CharPosition
|
||||
): Boolean
|
||||
|
||||
/**
|
||||
* 请求自动完成
|
||||
* @param contentReference ContentReference
|
||||
* @param charPosition CharPosition
|
||||
* @param completionPublisher CompletionPublisher
|
||||
* @param bundle Bundle
|
||||
* @return ArrayList<RustCompletionItem>
|
||||
*/
|
||||
fun requireAutoComplete(
|
||||
contentReference: ContentReference,
|
||||
charPosition: CharPosition,
|
||||
completionPublisher: CompletionPublisher,
|
||||
lineData: String,
|
||||
keyWord:String
|
||||
)
|
||||
|
||||
}
|
|
@ -0,0 +1,409 @@
|
|||
package com.coldmint.rust.pro.edit.autoComplete
|
||||
|
||||
import android.os.Bundle
|
||||
import com.coldmint.rust.core.SourceFile
|
||||
import com.coldmint.rust.core.database.code.CodeDao
|
||||
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||
import com.coldmint.rust.core.database.file.FileDataBase
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.core.tool.LineParser
|
||||
import com.coldmint.rust.pro.edit.RustAnalyzer
|
||||
import com.coldmint.rust.pro.edit.RustAutoComplete
|
||||
import com.coldmint.rust.pro.edit.RustCompletionItem
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||
import io.github.rosemoe.sora.text.CharPosition
|
||||
import io.github.rosemoe.sora.text.ContentReference
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
|
||||
/**
|
||||
* 代码自动完成项目(来自数据库)
|
||||
*/
|
||||
class CodeAutoCompleteJob : AutoCompleteJob {
|
||||
|
||||
private val debugKey = "代码自动完成(数据库)"
|
||||
private var codeDataBase: CodeDataBase? = null
|
||||
private var fileDataBase: FileDataBase? = null
|
||||
private lateinit var codeDao: CodeDao
|
||||
private val identifiersPromptNumber: Int by lazy {
|
||||
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
|
||||
}
|
||||
private var sectionNameMap: HashMap<String, String> = HashMap()
|
||||
|
||||
|
||||
private val lineParser by lazy {
|
||||
val tem = LineParser()
|
||||
tem.symbol = ","
|
||||
tem
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置代码数据库
|
||||
* @param codeDataBase CodeDataBase
|
||||
*/
|
||||
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
||||
DebugHelper.printLog(debugKey, "已链接数据库,数据库状态:${codeDataBase.isOpen}。")
|
||||
this.codeDataBase = codeDataBase
|
||||
this.codeDao = codeDataBase.getCodeDao()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件数据库
|
||||
* @param fileDataBase FileDataBase
|
||||
*/
|
||||
fun setFileDataBase(fileDataBase: FileDataBase) {
|
||||
DebugHelper.printLog(debugKey, "已链接文件数据库,数据库状态:${fileDataBase.isOpen}。")
|
||||
this.fileDataBase = fileDataBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为英文模式
|
||||
*/
|
||||
private val isEnglishMode by lazy {
|
||||
AppSettings.getValue(AppSettings.Setting.EnglishEditingMode, false)
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return debugKey
|
||||
}
|
||||
|
||||
|
||||
override fun needPerform(
|
||||
contentReference: ContentReference,
|
||||
charPosition: CharPosition
|
||||
): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun requireAutoComplete(
|
||||
contentReference: ContentReference,
|
||||
charPosition: CharPosition,
|
||||
completionPublisher: CompletionPublisher,
|
||||
lineData: String,
|
||||
keyWord: String
|
||||
) {
|
||||
if (codeDataBase == null) {
|
||||
DebugHelper.printLog(debugKey, "数据库为空,无法使用", isError = true)
|
||||
return
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"行内容[" + lineData + "]关键字[" + keyWord + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (lineData.startsWith('[')) {
|
||||
//搜索节
|
||||
val name = lineData.subSequence(1, lineData.length).toString()
|
||||
val list = if (isEnglishMode) {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
||||
} else {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
||||
}
|
||||
list?.forEach {
|
||||
completionPublisher.addItem(CompletionItemConverter.sectionInfoToCompletionItem(it))
|
||||
}
|
||||
} else {
|
||||
val key = ":"
|
||||
val keyIndex = lineData.lastIndexOf(key)
|
||||
if (keyIndex > -1) {
|
||||
//检查是否可响应变量
|
||||
val start = "\${"
|
||||
val end = "}"
|
||||
val startIndex = lineData.lastIndexOf(start)
|
||||
if (startIndex > -1) {
|
||||
val endIndex = lineData.lastIndexOf(end)
|
||||
if (endIndex < startIndex) {
|
||||
//如果}的位置小于${的位置,说明没有闭合
|
||||
val keyWord =
|
||||
lineData.subSequence(startIndex + start.length, lineData.length)
|
||||
.toString()
|
||||
val previousText =
|
||||
lineData.subSequence(keyIndex + key.length, startIndex).toString()
|
||||
if (keyWord.isNotBlank()) {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
if (it.name.contains(keyWord)) {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
// RustAutoComplete.keyWord = keyWord
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// val value =
|
||||
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
|
||||
// Log.d("值", value)
|
||||
//搜索值
|
||||
// frontIndex 前面冒号的位置
|
||||
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
|
||||
val keyValue = if (frontIndex > -1) {
|
||||
lineData.subSequence(frontIndex + key.length, keyIndex)
|
||||
} else {
|
||||
lineData.subSequence(0, keyIndex)
|
||||
}
|
||||
|
||||
val codeInfo =
|
||||
if (isEnglishMode) {
|
||||
codeDao.findCodeByCode(keyValue.toString())
|
||||
} else {
|
||||
codeDao.findCodeByTranslate(keyValue.toString())
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + keyWord + "]",
|
||||
"值检查"
|
||||
)
|
||||
if (codeInfo != null) {
|
||||
val typeInfo = CompletionItemConverter.getValueType(codeInfo.type)
|
||||
//获取代码的关联列表
|
||||
if (typeInfo != null && typeInfo.list.isNotBlank()) {
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
|
||||
)
|
||||
lineParser.text = typeInfo.list
|
||||
lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
//分析关联提示项目
|
||||
val temCodeInfo =
|
||||
codeDao.findCodeByCode(lineData)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (temCodeInfo == null) {
|
||||
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
|
||||
val fileType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
)
|
||||
|
||||
val fileInfo = fileDataBase!!.getFileInfoDao()
|
||||
.searchFileInfoByNameAndType(
|
||||
keyWord,
|
||||
fileType.toString(),
|
||||
identifiersPromptNumber
|
||||
)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
|
||||
?: -1) + "]个结果",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (fileInfo != null && fileInfo.isNotEmpty()) {
|
||||
for (fileTable in fileInfo) {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.fileTableToCompletionItem(
|
||||
fileTable
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
//用户自动值类型提示
|
||||
val customType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
fileDataBase!!.getValueDao()
|
||||
.searchValueByKey(
|
||||
keyWord,
|
||||
customType,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
?.forEach {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.valueTableToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
|
||||
val type = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
val list = if (isEnglishMode
|
||||
) {
|
||||
codeDao.findCodeByCodeInType(
|
||||
keyWord,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
} else {
|
||||
codeDao.findCodeByTranslateInType(
|
||||
keyWord,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
|
||||
"值类型引用"
|
||||
)
|
||||
if (!list.isNullOrEmpty()) {
|
||||
list.forEach {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.codeInfoToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@section") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
// val section = lineData.subSequence(
|
||||
// lineData.indexOf('(') + 1,
|
||||
// lineData.indexOf(')')
|
||||
// ).toString()
|
||||
// codeEditor!!.textAnalyzeResult.navigation.forEach {
|
||||
// if (section == getSectionType(it.label)) {
|
||||
// result.add(
|
||||
// CompletionItemConverter.navigationItemToCompletionItem(
|
||||
// it
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
//无法分析的关联项目
|
||||
// result.add(
|
||||
// CompletionItem(
|
||||
// lineData,
|
||||
// String.format(
|
||||
// CompletionItemConverter.associatedTip,
|
||||
// codeInfo.translate
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
}
|
||||
} else {
|
||||
val show = if (isEnglishMode) {
|
||||
temCodeInfo.code.contains(keyWord)
|
||||
} else {
|
||||
temCodeInfo.translate.contains(keyWord)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + keyWord + "关键字[" + show + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (show) {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.codeInfoToCompletionItem(
|
||||
temCodeInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//如果不包含:搜索键
|
||||
val lineNumber = charPosition.getLine()
|
||||
val section = getSection(lineNumber, contentReference)
|
||||
//如果不在任何节内
|
||||
if (section == null) {
|
||||
DebugHelper.printLog(debugKey, "不在任何节内,无法提示。", isError = true)
|
||||
return
|
||||
}
|
||||
val trueSection = getSectionType(section)
|
||||
val list = if (isEnglishMode) {
|
||||
codeDao.findCodeByEnglishCodeKeyFromSection(
|
||||
keyWord,
|
||||
trueSection,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
} else {
|
||||
codeDao
|
||||
.findCodeByKeyFromSection(keyWord, trueSection, identifiersPromptNumber)
|
||||
}
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
list.forEach {
|
||||
completionPublisher.addItem(
|
||||
CompletionItemConverter.codeInfoToCompletionItem(it)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"在${trueSection}节模糊搜索${keyWord}无结果。",
|
||||
isError = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取光标前的节名
|
||||
* @param lineNumber Int
|
||||
* @param contentReference ContentReference
|
||||
* @return String?
|
||||
*/
|
||||
fun getSection(lineNumber: Int, contentReference: ContentReference): String? {
|
||||
return if (lineNumber > 0) {
|
||||
for (i in lineNumber downTo 0) {
|
||||
val lineData = contentReference.getLine(i)
|
||||
DebugHelper.printLog(debugKey, "检查第${i}行 ${lineData}", "获取光标前的节名")
|
||||
if (lineData.startsWith("[") && lineData.endsWith("]")) {
|
||||
val name = lineData.subSequence(1, lineData.length - 1).toString()
|
||||
DebugHelper.printLog(debugKey, "返回 ${name}", "获取光标前的节名")
|
||||
return name
|
||||
}
|
||||
}
|
||||
DebugHelper.printLog(debugKey, "没有找到节。", "获取光标前的节名", isError = true)
|
||||
null
|
||||
} else {
|
||||
DebugHelper.printLog(debugKey, "行号小于0无法获取。", "获取光标前的节名", isError = true)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取节类型(永远返回英文)
|
||||
* @param section String
|
||||
* @return String
|
||||
*/
|
||||
fun getSectionType(section: String): String {
|
||||
if (sectionNameMap.containsKey(section)) {
|
||||
return sectionNameMap[section] ?: SourceFile.getSectionType(section)
|
||||
}
|
||||
val result = if (isEnglishMode) {
|
||||
SourceFile.getSectionType(section)
|
||||
} else {
|
||||
val sectionInfo = codeDataBase!!.getSectionDao()
|
||||
.findSectionInfoByTranslate(SourceFile.getSectionType(section))
|
||||
sectionInfo?.code ?: SourceFile.getSectionType(section)
|
||||
}
|
||||
sectionNameMap[section] = result
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ import kotlin.Throws
|
|||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import com.hjq.language.MultiLanguages
|
||||
import java.io.File
|
||||
import java.lang.NullPointerException
|
||||
import java.util.*
|
||||
|
||||
|
@ -37,10 +38,24 @@ object AppSettings {
|
|||
}
|
||||
|
||||
enum class Setting {
|
||||
DatabaseDirectory, DatabasePath, TemplateDirectory, AppLanguage, DeveloperMode, CustomSymbol, AutoCreateNomedia, OnlyLoadConantLanguageTemple, NightMode, GamePackage, KeepRwmodFile, EnableRecoveryStation, RecoveryStationFileSaveDays, RecoveryStationFolder, IndependentFolder, SetGameStorage, PackDirectory, IdentifiersPromptNumber, UserName, UseJetBrainsMonoFont, AppID, Account, PassWord, ExpirationTime, CheckBetaUpdate, UpdateData, ShareTip, AgreePolicy, EnglishEditingMode, NightModeFollowSystem, UseMobileNetwork, MapFolder, ModFolder, UseTheCommunityAsTheLaunchPage, AutoSave, ServerAddress, Token, LoginStatus, DynamicColor, ExperiencePlan, FileSortType
|
||||
DatabaseDirectory, DatabasePath, TemplateDirectory, AppLanguage, DeveloperMode, CustomSymbol, AutoCreateNomedia, OnlyLoadConantLanguageTemple, NightMode, GamePackage, KeywordColor, AnnotationColor, TextColor, SectionColor, KeepRwmodFile, EnableRecoveryStation, RecoveryStationFileSaveDays, RecoveryStationFolder, IndependentFolder, SetGameStorage, PackDirectory, IdentifiersPromptNumber, UserName, UseJetBrainsMonoFont, AppID, Account, PassWord, ExpirationTime, CheckBetaUpdate, UpdateData, ShareTip, AgreePolicy, EnglishEditingMode, NightModeFollowSystem, UseMobileNetwork, MapFolder, ModFolder, UseTheCommunityAsTheLaunchPage, AutoSave, ServerAddress, Token, LoginStatus, DynamicColor, ExperiencePlan, FileSortType, CodeEditBackGroundEnable, BlurTransformationValue, CodeEditBackGroundPath
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 创建新的编辑器背景文件(返回文件目录)
|
||||
* @return String
|
||||
*/
|
||||
fun createNewCodeEditBackGroundFile(): String {
|
||||
val folderPath = mApplication.filesDir.absolutePath + "/CodeEditBackground/"
|
||||
val folder = File(folderPath)
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs()
|
||||
}
|
||||
return folderPath + UUID.randomUUID().toString() + ".png"
|
||||
}
|
||||
|
||||
private val map: HashMap<Setting, String> = HashMap<Setting, String>()
|
||||
|
||||
/**
|
||||
|
@ -127,6 +142,14 @@ object AppSettings {
|
|||
map[Setting.AgreePolicy] = "AgreePolicy"
|
||||
map[Setting.LoginStatus] = "LoginStatus"
|
||||
map[Setting.Token] = "Token"
|
||||
map[Setting.BlurTransformationValue] = "BlurTransformationValue"
|
||||
map[Setting.CodeEditBackGroundEnable] = "CodeEditBackGroundEnable"
|
||||
map[Setting.CodeEditBackGroundPath] = "CodeEditBackGroundPath"
|
||||
//KeywordColor, AnnotationColor, TextColor, SectionColor
|
||||
map[Setting.KeywordColor] = mApplication.getString(R.string.setting_keyword_color)
|
||||
map[Setting.AnnotationColor] = mApplication.getString(R.string.setting_annotation_color)
|
||||
map[Setting.TextColor] = mApplication.getString(R.string.setting_text_color)
|
||||
map[Setting.SectionColor] = mApplication.getString(R.string.setting_section_color)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,13 +33,8 @@ import java.lang.StringBuilder
|
|||
* @property canUseFileConversion Boolean
|
||||
* @property valueTypeDao ValueTypeDao?
|
||||
*/
|
||||
class CompletionItemConverter private constructor() : EnglishMode {
|
||||
object CompletionItemConverter {
|
||||
|
||||
companion object {
|
||||
val instance: CompletionItemConverter by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
CompletionItemConverter()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
|
@ -80,14 +75,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
HashMap()
|
||||
}
|
||||
private var isEnglishMode = false
|
||||
|
||||
override fun isEnglishMode(): Boolean {
|
||||
return isEnglishMode
|
||||
}
|
||||
|
||||
override fun setEnglish(englishMode: Boolean) {
|
||||
this.isEnglishMode = englishMode
|
||||
}
|
||||
get() = AppSettings.getValue(AppSettings.Setting.EnglishEditingMode, false)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -135,7 +123,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
NullPointerException("没有初始化。")
|
||||
}
|
||||
val end = if (sectionInfo.needName) {
|
||||
"_]"
|
||||
"_"
|
||||
|
||||
} else {
|
||||
"]"
|
||||
|
@ -213,12 +201,12 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
codeInfo.description, boxDrawable
|
||||
)
|
||||
}
|
||||
val typeList = typeInfo?.list
|
||||
if (typeList != null && typeList.isNotBlank()) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("list", typeList)
|
||||
// val typeList = typeInfo?.list
|
||||
// if (typeList != null && typeList.isNotBlank()) {
|
||||
// val bundle = Bundle()
|
||||
// bundle.putString("list", typeList)
|
||||
// completionItem.extrasData = bundle
|
||||
}
|
||||
// }
|
||||
val offset = typeInfo?.offset
|
||||
if (offset != null && offset.isNotBlank()) {
|
||||
//如果偏移不为空
|
||||
|
|
|
@ -43,6 +43,7 @@ object GlobalMethod {
|
|||
const val DEBUG_SIGN = "963dfd616924b27f9247a35e45bc130a"
|
||||
const val RELEASE_SIGN = "5320b24894fe7ed449842a81a2dfceda"
|
||||
|
||||
|
||||
/**
|
||||
* 获取主题色
|
||||
*
|
||||
|
@ -107,6 +108,87 @@ object GlobalMethod {
|
|||
return requestOptions
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* int颜色值转String
|
||||
* @param color Int
|
||||
* @param useARGB Boolean
|
||||
* @return String
|
||||
*/
|
||||
fun colorToString(color: Int, useARGB: Boolean = true): String {
|
||||
val builder = StringBuilder()
|
||||
builder.append('#')
|
||||
if (useARGB) {
|
||||
builder.append(convertDigital(Color.alpha(color)))
|
||||
}
|
||||
builder.append(convertDigital(Color.red(color)))
|
||||
builder.append(convertDigital(Color.green(color)))
|
||||
builder.append(convertDigital(Color.blue(color)))
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示颜色选择对话框
|
||||
* @param context Context
|
||||
* @param func Function1<String, Unit>
|
||||
*/
|
||||
fun showColorPickerDialog(
|
||||
context: Context,
|
||||
useARGB: Boolean = false, func: ((String) -> Unit)
|
||||
) {
|
||||
ColorPickerDialogBuilder
|
||||
.with(context).showAlphaSlider(useARGB)
|
||||
.setTitle(context.getString(R.string.choose_color))
|
||||
.initialColor(Color.WHITE)
|
||||
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
|
||||
.density(12)
|
||||
.setOnColorSelectedListener {
|
||||
//toast("onColorSelected: 0x" + Integer.toHexString(selectedColor));
|
||||
}
|
||||
.setPositiveButton(R.string.dialog_ok) { dialog, selectedColor, allColors ->
|
||||
func.invoke(colorToString(selectedColor, useARGB))
|
||||
}
|
||||
.setNegativeButton(R.string.dialog_cancel) { dialog, which -> }
|
||||
.build()
|
||||
.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为16进制
|
||||
*
|
||||
* @param num 十进制整数
|
||||
* @return 16进制数
|
||||
*/
|
||||
private fun convertDigital(num: Int): String {
|
||||
return if (num > 255) {
|
||||
"FF"
|
||||
} else {
|
||||
val builder = java.lang.StringBuilder()
|
||||
val result = num / 16
|
||||
val remainder = num % 16
|
||||
when (result) {
|
||||
10 -> builder.append('A')
|
||||
11 -> builder.append('B')
|
||||
12 -> builder.append('C')
|
||||
13 -> builder.append('D')
|
||||
14 -> builder.append('E')
|
||||
15 -> builder.append('F')
|
||||
else -> builder.append(result)
|
||||
}
|
||||
when (remainder) {
|
||||
10 -> builder.append('A')
|
||||
11 -> builder.append('B')
|
||||
12 -> builder.append('C')
|
||||
13 -> builder.append('D')
|
||||
14 -> builder.append('E')
|
||||
15 -> builder.append('F')
|
||||
else -> builder.append(remainder)
|
||||
}
|
||||
builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 显示更新日志
|
||||
* @param context Context
|
||||
|
@ -191,7 +273,6 @@ object GlobalMethod {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//设置删除线
|
||||
fun addDeleteLine(vararg textViews: TextView?) {
|
||||
for (textView in textViews) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.coldmint.rust.core.tool.FileOperator
|
|||
import com.coldmint.rust.pro.base.BaseAndroidViewModel
|
||||
import com.coldmint.rust.pro.livedata.OpenedSourceFileListLiveData
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||
import com.coldmint.rust.pro.tool.GlobalMethod
|
||||
import java.io.File
|
||||
import java.lang.StringBuilder
|
||||
|
@ -189,6 +190,7 @@ class EditViewModel(application: Application) : BaseAndroidViewModel(application
|
|||
}
|
||||
|
||||
override fun onTranslateComplete(code: String) {
|
||||
CompletionItemConverter.setSourceFilePath(path)
|
||||
val openedSourceFile = OpenedSourceFile(path)
|
||||
openedSourceFile.setTranslation(code)
|
||||
val index = openedSourceFileListLiveData.add(openedSourceFile)
|
||||
|
@ -534,40 +536,7 @@ class EditViewModel(application: Application) : BaseAndroidViewModel(application
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为16进制
|
||||
*
|
||||
* @param num 十进制整数
|
||||
* @return 16进制数
|
||||
*/
|
||||
fun convertDigital(num: Int): String {
|
||||
return if (num > 255) {
|
||||
"FF"
|
||||
} else {
|
||||
val builder = StringBuilder()
|
||||
val result = num / 16
|
||||
val remainder = num % 16
|
||||
when (result) {
|
||||
10 -> builder.append('A')
|
||||
11 -> builder.append('B')
|
||||
12 -> builder.append('C')
|
||||
13 -> builder.append('D')
|
||||
14 -> builder.append('E')
|
||||
15 -> builder.append('F')
|
||||
else -> builder.append(result)
|
||||
}
|
||||
when (remainder) {
|
||||
10 -> builder.append('A')
|
||||
11 -> builder.append('B')
|
||||
12 -> builder.append('C')
|
||||
13 -> builder.append('D')
|
||||
14 -> builder.append('E')
|
||||
15 -> builder.append('F')
|
||||
else -> builder.append(remainder)
|
||||
}
|
||||
builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载数据
|
||||
|
|
|
@ -178,17 +178,15 @@ class FileManagerViewModel : BaseViewModel() {
|
|||
return rootPath
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 解析文件路径
|
||||
// *
|
||||
// * @param context 上下文环境
|
||||
// * @param intent 意图
|
||||
// * @return 成功返回文件路径,失败返回null
|
||||
// */
|
||||
fun parseFilePath(context: Context, intent: Intent?): String? {
|
||||
/**
|
||||
* 解析文件路径
|
||||
*
|
||||
* @param context 上下文环境
|
||||
* @param uri 定位符
|
||||
* @return 成功返回文件路径,失败返回null
|
||||
*/
|
||||
fun parseFilePath(context: Context, uri: Uri?): String? {
|
||||
return try {
|
||||
if (intent != null) {
|
||||
val uri = intent.data
|
||||
var chooseFilePath: String? = null
|
||||
if ("file".equals(uri!!.scheme, ignoreCase = true)) { //使用第三方应用打开
|
||||
chooseFilePath = uri.path
|
||||
|
@ -200,7 +198,6 @@ class FileManagerViewModel : BaseViewModel() {
|
|||
getRealPathFromURI(context, uri)
|
||||
}
|
||||
return chooseFilePath
|
||||
}
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -239,7 +236,6 @@ class FileManagerViewModel : BaseViewModel() {
|
|||
return@launch
|
||||
}
|
||||
val arrayList = ArrayList<File?>()
|
||||
Log.d("文件管理器", "当前路径" + path + "根路径" + rootPath + "添加返回" + (path != rootPath))
|
||||
if (path != rootPath) {
|
||||
//如果不是根目录添加返回
|
||||
arrayList.add(null)
|
||||
|
|
|
@ -238,12 +238,23 @@ class StartViewModel(application: Application) : BaseAndroidViewModel(applicatio
|
|||
AppSettings.initSetting(AppSettings.Setting.AutoSave, true)
|
||||
AppSettings.initSetting(AppSettings.Setting.AgreePolicy, false)
|
||||
AppSettings.initSetting(AppSettings.Setting.LoginStatus, false)
|
||||
AppSettings.initSetting(AppSettings.Setting.FileSortType,context.getString(R.string.setting_file_list_action_sort_by_name))
|
||||
AppSettings.initSetting(
|
||||
AppSettings.Setting.FileSortType,
|
||||
context.getString(R.string.setting_file_list_action_sort_by_name)
|
||||
)
|
||||
//如果启用动态颜色
|
||||
AppSettings.initSetting(
|
||||
AppSettings.Setting.DynamicColor,
|
||||
DynamicColors.isDynamicColorAvailable()
|
||||
)
|
||||
AppSettings.initSetting(AppSettings.Setting.KeywordColor, "#FF0031C2")
|
||||
AppSettings.initSetting(AppSettings.Setting.SectionColor, "#FFE10000")
|
||||
AppSettings.initSetting(AppSettings.Setting.TextColor, "#FF000000")
|
||||
AppSettings.initSetting(AppSettings.Setting.AnnotationColor, "#FF00AF2C")
|
||||
AppSettings.initSetting(AppSettings.Setting.CodeEditBackGroundEnable, false)
|
||||
AppSettings.initSetting(AppSettings.Setting.BlurTransformationValue, 1)
|
||||
AppSettings.initSetting(AppSettings.Setting.CodeEditBackGroundPath, "")
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5L16,16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5s1.5,0.67 1.5,1.5S10.33,8 9.5,8zM14.5,8c-0.83,0 -1.5,-0.67 -1.5,-1.5S13.67,5 14.5,5s1.5,0.67 1.5,1.5S15.33,8 14.5,8zM17.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S16.67,9 17.5,9s1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z"/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z"/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15,7v12.97l-4.21,-1.81 -0.79,-0.34 -0.79,0.34L5,19.97L5,7h10m4,-6L8.99,1C7.89,1 7,1.9 7,3h10c1.1,0 2,0.9 2,2v13l2,1L21,3c0,-1.1 -0.9,-2 -2,-2zM15,5L5,5c-1.1,0 -2,0.9 -2,2v16l7,-3 7,3L17,7c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||
|
|
6
app/src/main/res/drawable/ic_outline_clear_24.xml
Normal file
6
app/src/main/res/drawable/ic_outline_clear_24.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12 19,6.41z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_outline_color_lens_24.xml
Normal file
9
app/src/main/res/drawable/ic_outline_color_lens_24.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,22C6.49,22 2,17.51 2,12S6.49,2 12,2s10,4.04 10,9c0,3.31 -2.69,6 -6,6h-1.77c-0.28,0 -0.5,0.22 -0.5,0.5 0,0.12 0.05,0.23 0.13,0.33 0.41,0.47 0.64,1.06 0.64,1.67 0,1.38 -1.12,2.5 -2.5,2.5zM12,4c-4.41,0 -8,3.59 -8,8s3.59,8 8,8c0.28,0 0.5,-0.22 0.5,-0.5 0,-0.16 -0.08,-0.28 -0.14,-0.35 -0.41,-0.46 -0.63,-1.05 -0.63,-1.65 0,-1.38 1.12,-2.5 2.5,-2.5L16,15c2.21,0 4,-1.79 4,-4 0,-3.86 -3.59,-7 -8,-7z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M6.5,11.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M9.5,7.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M14.5,7.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M17.5,11.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
|
||||
</vector>
|
|
@ -1,4 +1,4 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM5.92,19H5v-0.92l9.06,-9.06 0.92,0.92L5.92,19zM20.71,5.63l-2.34,-2.34c-0.2,-0.2 -0.45,-0.29 -0.71,-0.29s-0.51,0.1 -0.7,0.29l-1.83,1.83 3.75,3.75 1.83,-1.83c0.39,-0.39 0.39,-1.02 0,-1.41z"/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM19,19L5,19L5,5h11.17L19,7.83L19,19zM12,12c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3zM6,6h9v4L6,10z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM19,19L5,19L5,5h11.17L19,7.83L19,19zM12,12c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3zM6,6h9v4L6,10z" />
|
||||
</vector>
|
||||
|
|
5
app/src/main/res/drawable/ic_outline_send_24.xml
Normal file
5
app/src/main/res/drawable/ic_outline_send_24.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M4.01,6.03l7.51,3.22 -7.52,-1 0.01,-2.22m7.5,8.72L4,17.97v-2.22l7.51,-1M2.01,3L2,10l15,2 -15,2 0.01,7L23,12 2.01,3z"/>
|
||||
</vector>
|
|
@ -1,5 +1,11 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15.55,13c0.75,0 1.41,-0.41 1.75,-1.03l3.58,-6.49c0.37,-0.66 -0.11,-1.48 -0.87,-1.48L5.21,4l-0.94,-2L1,2v2h2l3.6,7.59 -1.35,2.44C4.52,15.37 5.48,17 7,17h12v-2L7,15l1.1,-2h7.45zM6.16,6h12.15l-2.76,5L8.53,11L6.16,6zM7,18c-1.1,0 -1.99,0.9 -1.99,2S5.9,22 7,22s2,-0.9 2,-2 -0.9,-2 -2,-2zM17,18c-1.1,0 -1.99,0.9 -1.99,2s0.89,2 1.99,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15.55,13c0.75,0 1.41,-0.41 1.75,-1.03l3.58,-6.49c0.37,-0.66 -0.11,-1.48 -0.87,-1.48L5.21,4l-0.94,-2L1,2v2h2l3.6,7.59 -1.35,2.44C4.52,15.37 5.48,17 7,17h12v-2L7,15l1.1,-2h7.45zM6.16,6h12.15l-2.76,5L8.53,11L6.16,6zM7,18c-1.1,0 -1.99,0.9 -1.99,2S5.9,22 7,22s2,-0.9 2,-2 -0.9,-2 -2,-2zM17,18c-1.1,0 -1.99,0.9 -1.99,2s0.89,2 1.99,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
|
||||
</vector>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="215.23438dp"
|
||||
android:height="200dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="1102"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
|
|
269
app/src/main/res/layout/activity_customize_edit_text.xml
Normal file
269
app/src/main/res/layout/activity_customize_edit_text.xml
Normal file
|
@ -0,0 +1,269 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="16dp"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/edit_text_color" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/keywordColorEditLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
app:endIconCheckable="true"
|
||||
app:endIconDrawable="@drawable/ic_outline_color_lens_24"
|
||||
app:endIconMode="custom">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/keywordColorEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:hint="@string/keyword_color"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/sectionColorEditLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:endIconCheckable="true"
|
||||
app:endIconDrawable="@drawable/ic_outline_color_lens_24"
|
||||
app:endIconMode="custom">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/sectionColorEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:hint="@string/section_color"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/textColorEditLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:endIconCheckable="true"
|
||||
app:endIconDrawable="@drawable/ic_outline_color_lens_24"
|
||||
app:endIconMode="custom">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/textColorEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:hint="@string/text_color"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/annotationColorEditLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:endIconCheckable="true"
|
||||
app:endIconDrawable="@drawable/ic_outline_color_lens_24"
|
||||
app:endIconMode="custom">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/annotationColorEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:hint="@string/annotation_color"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="text"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/resetButton"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/restore_default" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="48dp">
|
||||
|
||||
<LinearLayout
|
||||
android:animateLayoutChanges="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/edit_background" />
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/filePathInputLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:endIconCheckable="true"
|
||||
app:endIconDrawable="@drawable/file"
|
||||
app:endIconMode="custom">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/filePathInputEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:hint="@string/file_path"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textMultiLine" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/dimCardView"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dim_value" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/slide"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:stepSize="1.0"
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="30.0" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/imageCardView"
|
||||
android:visibility="gone"
|
||||
style="@style/Widget.Material3.CardView.Outlined"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="450dp"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
<Button
|
||||
android:visibility="gone"
|
||||
android:id="@+id/autoGenerateColorSchemeButton"
|
||||
android:text="@string/auto_generate_color_scheme"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|right"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/edit_function"
|
||||
app:icon="@drawable/round_save_20" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:background="@android:color/transparent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
|
|
@ -62,13 +62,23 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/mod_icon" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:scaleType="centerCrop"
|
||||
android:id="@+id/iconView"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:src="@drawable/image" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -35,32 +34,31 @@
|
|||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:cardElevation="2dp"
|
||||
card_view:cardCornerRadius="2dp">
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_margin="16dp"
|
||||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/required"
|
||||
android:textSize="16sp" />
|
||||
android:text="@string/required" />
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/modIdInputLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:counterEnabled="true"
|
||||
app:counterMaxLength="30"
|
||||
app:helperText="@string/id_tip">
|
||||
|
@ -189,34 +187,34 @@
|
|||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:cardElevation="2dp"
|
||||
card_view:cardCornerRadius="2dp">
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/selectable"
|
||||
android:textSize="16dp" />
|
||||
android:text="@string/selectable" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/mod_icon" />
|
||||
|
@ -238,6 +236,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/screenshot" />
|
||||
|
@ -245,10 +244,12 @@
|
|||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/screenshotRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp" />
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/addScreenshotButton"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/add" />
|
||||
|
@ -256,42 +257,41 @@
|
|||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:cardElevation="2dp"
|
||||
card_view:cardCornerRadius="2dp">
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_margin="16dp"
|
||||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/menu_title1"
|
||||
android:textSize="16sp" />
|
||||
android:text="@string/menu_title1" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp">
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/modPathView"
|
||||
style="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@id/packModButton"
|
||||
android:text="@string/unable_load_mod_info"
|
||||
android:textSize="13sp" />
|
||||
android:text="@string/unable_load_mod_info" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/packModButton"
|
||||
|
@ -311,15 +311,14 @@
|
|||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="60dp"
|
||||
app:cardElevation="2dp"
|
||||
card_view:cardCornerRadius="2dp">
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="60dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -329,32 +328,33 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.Material3.HeadlineMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dynamic"
|
||||
android:textSize="16sp" />
|
||||
android:text="@string/dynamic" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:checked="true"
|
||||
android:text="@string/share_to_dynamic" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<Button
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/releaseButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="@string/release" />
|
||||
android:layout_gravity="bottom|right"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/release"
|
||||
app:icon="@drawable/ic_outline_send_24" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -1,34 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarStyle"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/relativeLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="16dp"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/mainImageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/image" />
|
||||
<FrameLayout
|
||||
android:id="@+id/frameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<com.coldmint.rust.core.turret.TurretSketchpadView
|
||||
android:id="@+id/turretSketchpadView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
|
|
@ -2,21 +2,30 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:windowBackground"
|
||||
android:padding="8dp">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/iconCardView"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconView"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="45dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/image" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/iconView"
|
||||
android:layout_toEndOf="@id/iconCardView"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
android:id="@+id/save_text"
|
||||
android:icon="@drawable/ic_outline_save_24"
|
||||
android:title="@string/edit_function"
|
||||
app:actionViewClass="view"
|
||||
app:showAsAction="always" />
|
||||
|
||||
<item
|
||||
|
@ -27,6 +26,7 @@
|
|||
android:id="@+id/open_game_test"
|
||||
android:title="@string/open_game_test" />
|
||||
|
||||
|
||||
<item
|
||||
android:id="@+id/show_line_number"
|
||||
android:checkable="true"
|
||||
|
@ -40,8 +40,7 @@
|
|||
|
||||
<item
|
||||
android:id="@+id/turret_design"
|
||||
android:title="@string/turret_design"
|
||||
android:visible="false" />
|
||||
android:title="@string/turret_design" />
|
||||
|
||||
<item
|
||||
android:id="@+id/search_view"
|
||||
|
|
|
@ -233,6 +233,7 @@
|
|||
<!--编译错误-->
|
||||
|
||||
<string name="not_save_exit">不保存退出</string>
|
||||
<string name="save_settings">检查到配置信息更新,要保存更改嘛?</string>
|
||||
<string name="saveing">正在保存%1$s...</string>
|
||||
<string name="save_complete">%1$s保存完成。</string>
|
||||
|
||||
|
@ -872,10 +873,26 @@
|
|||
<string name="setting_file_list_action_sort_by_last_modified" translatable="false">ByLastModified</string>
|
||||
<string name="file_sort_type">文件排序方式</string>
|
||||
<string name="setting_file_sort_type" translatable="false">FileSortType</string>
|
||||
<string name="setting_keyword_color" translatable="false">KeywordColor</string>
|
||||
<string name="setting_annotation_color" translatable="false">AnnotationColor</string>
|
||||
<string name="setting_text_color" translatable="false">TextColor</string>
|
||||
<string name="setting_section_color" translatable="false">SectionColor</string>
|
||||
<string name="template_id">模板id</string>
|
||||
<string name="customize_edit_text">定制编辑框</string>
|
||||
<string name="subscription">订阅</string>
|
||||
<string name="de_subscription">退订</string>
|
||||
<string name="de_subscription_msg">要退订%1$s嘛?</string>
|
||||
<string name="keyword_color">关键字颜色</string>
|
||||
<string name="text_color">普通文本颜色</string>
|
||||
<string name="edit_text_color">字体颜色</string>
|
||||
<string name="section_color">节颜色</string>
|
||||
<string name="annotation_color">注释颜色</string>
|
||||
<string name="customize_edit_text_description">定制编辑框字体颜色,编辑框背景图像等等。</string>
|
||||
<string name="restore_default">恢复默认</string>
|
||||
<string name="edit_background">背景</string>
|
||||
<string name="file_path">文件路径</string>
|
||||
<string name="dim_value">模糊度</string>
|
||||
<string name="auto_generate_color_scheme">自动生成配色方案</string>
|
||||
<!-- <string name="search_suggestions_null">无搜索建议。</string>-->
|
||||
<!-- <string name="search_suggestions_number">共%1$d个搜索建议。</string>-->
|
||||
|
||||
|
|
|
@ -107,6 +107,10 @@
|
|||
app:summary="@string/auto_save_describe"
|
||||
app:title="@string/auto_save" />
|
||||
|
||||
<PreferenceScreen
|
||||
app:key="customize_edit"
|
||||
app:title="@string/customize_edit_text"
|
||||
app:summary="@string/customize_edit_text_description"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
|
|
@ -44,10 +44,10 @@ dependencies {
|
|||
annotationProcessor "androidx.room:room-compiler:2.4.0"
|
||||
kapt "androidx.room:room-compiler:2.4.0"
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.0'
|
||||
implementation 'com.google.android.material:material:1.7.0-beta01'
|
||||
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
|
@ -6,6 +6,7 @@ import com.coldmint.rust.core.interfaces.LineParserEvent
|
|||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Environment
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.core.turret.TurretManager
|
||||
import java.io.File
|
||||
|
@ -118,12 +119,14 @@ class SourceFile(text: String) {
|
|||
fun findResourceFiles(value: String?, checkExists: Boolean): Array<File>? {
|
||||
var value = value
|
||||
if (modclass == null || !this::file.isInitialized) {
|
||||
DebugHelper.printLog("搜索资源文件","无法搜索,因为没有初始化文件或模组类。", isError = true)
|
||||
return null
|
||||
}
|
||||
DebugHelper.printLog("搜索资源文件","准备开始 文件路径${file.absolutePath}值${value}")
|
||||
val none = "NONE"
|
||||
val auto = "AUTO"
|
||||
val shared = "SHARED"
|
||||
val root = "ROOT"
|
||||
val shared = "SHARED:"
|
||||
val root = "ROOT:"
|
||||
return if (value == null || value == none || value == auto || value.startsWith(shared)) {
|
||||
null
|
||||
} else {
|
||||
|
@ -136,11 +139,15 @@ class SourceFile(text: String) {
|
|||
if (checkExists) {
|
||||
if (target.exists()) {
|
||||
result.add(target)
|
||||
}else{
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath}解析Root路径为 ${target.absolutePath} 文件不存在!", isError = true)
|
||||
}
|
||||
} else {
|
||||
result.add(target)
|
||||
}
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath}解析Root路径为 ${target.absolutePath}")
|
||||
} else if (value.contains(",")) {
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath}启用多文件解析。")
|
||||
val lineParser = LineParser(value)
|
||||
lineParser.needTrim = true
|
||||
lineParser.symbol = ","
|
||||
|
@ -156,10 +163,13 @@ class SourceFile(text: String) {
|
|||
if (checkExists) {
|
||||
if (target.exists()) {
|
||||
result.add(target)
|
||||
}else{
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath} 多文件分割 第${lineNum}个文件 ${target.absolutePath} 不存在!", isError = true)
|
||||
}
|
||||
} else {
|
||||
result.add(target)
|
||||
}
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath} 多文件分割 第${lineNum}个文件 ${target.absolutePath}")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -173,10 +183,13 @@ class SourceFile(text: String) {
|
|||
if (checkExists) {
|
||||
if (target.exists()) {
|
||||
result.add(target)
|
||||
}else{
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath} 解析常规文件 ${target.absolutePath} 不存在!", isError = true)
|
||||
}
|
||||
} else {
|
||||
result.add(target)
|
||||
}
|
||||
DebugHelper.printLog("搜索资源文件","文件${file.absolutePath} 解析常规文件 ${target.absolutePath}")
|
||||
}
|
||||
if (result.size > 0) {
|
||||
result.toTypedArray()
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.coldmint.rust.core.turret
|
||||
|
||||
/**
|
||||
* 坐标数据
|
||||
* @property x Int
|
||||
* @property y Int
|
||||
* @constructor
|
||||
*/
|
||||
data class CoordinateData(val x: Int = 0, val y: Int = 0)
|
|
@ -1,10 +0,0 @@
|
|||
package com.coldmint.rust.core.turret
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* 可安装的炮塔数据类
|
||||
* @property name String
|
||||
* @constructor
|
||||
*/
|
||||
data class InstallableTurret(val name: String, var x: Int, var y: Int, var imageFile: File? = null)
|
|
@ -0,0 +1,10 @@
|
|||
package com.coldmint.rust.core.turret
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* 炮塔数据类
|
||||
* @property name String
|
||||
* @constructor
|
||||
*/
|
||||
data class TurretData(val name: String, var x: Int, var y: Int, var imageFile: File? = null)
|
|
@ -6,7 +6,9 @@ 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
|
||||
|
@ -15,128 +17,40 @@ import com.coldmint.rust.core.SourceFile
|
|||
* 炮塔安装器
|
||||
* 此类用于安装炮塔,将炮塔安放到视图上
|
||||
*/
|
||||
class TurretInstaller(
|
||||
val parentView: ViewGroup,
|
||||
val turretManager: TurretManager
|
||||
) {
|
||||
|
||||
|
||||
private var scale: Int = 1
|
||||
|
||||
object TurretInstaller {
|
||||
|
||||
/**
|
||||
* 设置缩放比例
|
||||
*/
|
||||
fun setScale(value: Int) {
|
||||
scale = value
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造方法(使用源文件构造)
|
||||
* @param parentView View
|
||||
* 安装全部炮塔到视图
|
||||
* @param frameLayout FrameLayout
|
||||
* @param sourceFile SourceFile
|
||||
* @constructor
|
||||
*/
|
||||
constructor(parentView: ViewGroup, sourceFile: SourceFile) : this(
|
||||
parentView,
|
||||
sourceFile.getTurretManager()
|
||||
)
|
||||
fun installerAllTurret(
|
||||
viewGroup: ViewGroup,
|
||||
sourceFile: SourceFile,
|
||||
coordinateChangeListener: (CoordinateData) -> Unit
|
||||
) {
|
||||
sourceFile.getTurretManager().turretList.forEach {
|
||||
installerTurret(viewGroup, it,coordinateChangeListener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装所有炮塔到视图容器内
|
||||
* 安装单个炮塔到视图
|
||||
* @param frameLayout FrameLayout
|
||||
* @param sourceFile SourceFile
|
||||
*/
|
||||
@SuppressLint("ObjectAnimatorBinding")
|
||||
fun installAllTurrets() {
|
||||
val turretList = turretManager.turretList
|
||||
val size = turretList.size
|
||||
if (size > 0) {
|
||||
turretList.forEach {
|
||||
val imageView = ImageView(parentView.context)
|
||||
val imageFile = it.imageFile
|
||||
if (imageFile == null) {
|
||||
setNoneImage(imageView)
|
||||
} else {
|
||||
val bitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
|
||||
if (bitmap == null) {
|
||||
setNoneImage(imageView)
|
||||
} else {
|
||||
imageView.setImageBitmap(bitmap)
|
||||
val layoutParams =
|
||||
ViewGroup.LayoutParams(bitmap.width * scale, bitmap.height * scale)
|
||||
imageView.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
imageView.setOnTouchListener { view, motionEvent ->
|
||||
if (view == null || motionEvent == null) {
|
||||
false
|
||||
}
|
||||
val x = motionEvent.x
|
||||
val y = motionEvent.y
|
||||
when (motionEvent.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
// val setDown = AnimatorSet()
|
||||
// setDown.playTogether(
|
||||
// ObjectAnimator.ofFloat(this, "scaleX", 1f, 1.5f),
|
||||
// ObjectAnimator.ofFloat(this, "scaleY", 1f, 1.5f),
|
||||
// ObjectAnimator.ofFloat(this, "alpha", 1f, 0.5f)
|
||||
// )
|
||||
// setDown.start()
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
view.setX(x + view.getLeft() + view.getTranslationX() - view.getWidth() / 2);
|
||||
view.setY(y + view.getTop() + view.getTranslationY() - view.getHeight() / 2);
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
// val setUp = AnimatorSet()
|
||||
// setUp.playTogether(
|
||||
// ObjectAnimator.ofFloat(this, "scaleX", 1.5f, 1f),
|
||||
// ObjectAnimator.ofFloat(this, "scaleY", 1.5f, 1f),
|
||||
// ObjectAnimator.ofFloat(this, "alpha", 0.5f, 1f)
|
||||
// );
|
||||
// setUp.start()
|
||||
}
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
parentView.addView(imageView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
|
||||
*/
|
||||
fun px2dip(context: Context, pxValue: Float): Int {
|
||||
val scale = context.resources.displayMetrics.density
|
||||
return (pxValue / scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
|
||||
*/
|
||||
fun dip2px(context: Context, dpValue: Float): Int {
|
||||
val scale = context.resources.displayMetrics.density
|
||||
return (dpValue * scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置空白图像(不受缩放限制)
|
||||
* @param imageView ImageView 图片框
|
||||
* @param size Int 尺寸
|
||||
*/
|
||||
private fun setNoneImage(
|
||||
imageView: ImageView,
|
||||
size: Int = dip2px(parentView.context, 30.toFloat())
|
||||
) {
|
||||
imageView.setImageResource(R.drawable.image)
|
||||
//设置默认图像大小
|
||||
val layoutParams =
|
||||
ViewGroup.LayoutParams(size, size)
|
||||
imageView.layoutParams = layoutParams
|
||||
viewGroup.addView(turretView)
|
||||
}
|
||||
|
||||
}
|
|
@ -13,10 +13,10 @@ import java.io.File
|
|||
class TurretManager(val sourceFile: SourceFile) {
|
||||
|
||||
/**
|
||||
* 可安装的炮塔列表
|
||||
* 炮塔列表
|
||||
*/
|
||||
val turretList by lazy {
|
||||
ArrayList<InstallableTurret>()
|
||||
ArrayList<TurretData>()
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -45,17 +45,17 @@ class TurretManager(val sourceFile: SourceFile) {
|
|||
if (yData != null) {
|
||||
y = yData.toInt()
|
||||
}
|
||||
val installableTurret = InstallableTurret(name, x, y)
|
||||
val turretData = TurretData(name, x, y)
|
||||
val fileList = sourceFile.findResourceFilesFromSection("image", it, false)
|
||||
if (!fileList.isNullOrEmpty()) {
|
||||
val file = fileList.get(0)
|
||||
installableTurret.imageFile = file
|
||||
Log.d("炮塔管理器-$name", file.absolutePath)
|
||||
turretData.imageFile = file
|
||||
Log.d("炮塔管理器-$name", "设置炮塔图像"+file.absolutePath)
|
||||
} else {
|
||||
installableTurret.imageFile = defaultImageFile
|
||||
turretData.imageFile = defaultImageFile
|
||||
Log.d("炮塔管理器-$name", "加载默认图像" + defaultImageFile?.absolutePath)
|
||||
}
|
||||
turretList.add(installableTurret)
|
||||
turretList.add(turretData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
package com.coldmint.rust.core.turret
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.RelativeLayout
|
||||
import com.coldmint.rust.core.R
|
||||
|
||||
/**
|
||||
* 炮塔画板
|
||||
* @constructor
|
||||
*/
|
||||
class TurretSketchpadView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
View(context, attributeSet) {
|
||||
|
||||
|
||||
private val debug = "炮塔画板"
|
||||
private var mainImagePath: String? = null
|
||||
|
||||
//计算中心点
|
||||
private var centreX = 0
|
||||
private var centreY = 0
|
||||
|
||||
//计算绘制点 取图像中点坐标(图像尺寸*缩放比例/2)
|
||||
private var startX = 0
|
||||
private var startY = 0
|
||||
private var endX = 0
|
||||
private var endY = 0
|
||||
|
||||
//单元格宽度
|
||||
private var cellSize = 10
|
||||
|
||||
|
||||
//设置是否绘制坐标
|
||||
var drawCoordinate = true
|
||||
|
||||
init {
|
||||
val typedArray =
|
||||
context.obtainStyledAttributes(attributeSet, R.styleable.turretSketchpadView)
|
||||
//读取自定义属性
|
||||
drawCoordinate = typedArray.getBoolean(R.styleable.turretSketchpadView_drawCoordinate, true)
|
||||
typedArray.recycle()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置主要图像
|
||||
* @param path String
|
||||
*/
|
||||
fun setImage(path: String) {
|
||||
mainImagePath = path
|
||||
invalidate()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转换为游戏坐标
|
||||
* @param androidCoordinateData CoordinateData
|
||||
* @return CoordinateData
|
||||
*/
|
||||
fun toGameCoordinate(androidCoordinateData: CoordinateData): CoordinateData {
|
||||
val x = (androidCoordinateData.x - centreX) / cellSize
|
||||
val y = (androidCoordinateData.y - centreY) / cellSize
|
||||
val game = CoordinateData(x, y)
|
||||
Log.d(
|
||||
debug,
|
||||
"转换坐标,安卓坐标${androidCoordinateData} 游戏坐标${game}"
|
||||
)
|
||||
return game
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算坐标
|
||||
*/
|
||||
private fun calculateCoordinate(bitmap: Bitmap) {
|
||||
//图像
|
||||
val imageWidth = bitmap.width
|
||||
val imageHeight = bitmap.height
|
||||
//计算单元格尺寸
|
||||
val cellX = width / imageWidth
|
||||
val cellY = height / imageHeight
|
||||
cellSize = if (cellX < cellY) {
|
||||
cellX
|
||||
} else {
|
||||
cellY
|
||||
}
|
||||
Log.d(
|
||||
debug,
|
||||
"计算尺寸\n单元格宽:${cellX} 使用视图宽度${width}除以图像宽度${imageWidth}\n单元格高:${cellY} 使用视图宽度${height}除以图像宽度${imageHeight}\n采用${cellSize}作为视图单元格尺寸"
|
||||
)
|
||||
centreX = width / 2
|
||||
centreY = height / 2
|
||||
//计算绘制点 取图像中点坐标(图像尺寸*缩放比例/2)
|
||||
startX = centreX - imageWidth / 2 * cellSize
|
||||
startY = centreY - imageHeight / 2 * cellSize
|
||||
endX = startX + imageWidth * cellSize
|
||||
endY = startY + imageHeight * cellSize
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 绘制坐标
|
||||
* @param canvas Canvas
|
||||
* @param imageHeight Int
|
||||
* @param imageWidth Int
|
||||
*/
|
||||
private fun drawCoordinate(canvas: Canvas) {
|
||||
if (drawCoordinate) {
|
||||
//如果需要绘制
|
||||
val paint = Paint()
|
||||
paint.color = Color.RED
|
||||
//开启描边
|
||||
paint.style = Paint.Style.STROKE
|
||||
paint.strokeWidth = 3f
|
||||
//开始绘制
|
||||
for (y in startY..endY step cellSize) {
|
||||
//Y改变,x不变
|
||||
canvas.drawLine(startX.toFloat(), y.toFloat(), endX.toFloat(), y.toFloat(), paint)
|
||||
}
|
||||
for (x in startX..endX step cellSize) {
|
||||
canvas.drawLine(x.toFloat(), startY.toFloat(), x.toFloat(), endY.toFloat(), paint)
|
||||
}
|
||||
// canvas.drawCircle(centreX.toFloat(), centreY.toFloat(), 30f, paint)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩放图像
|
||||
* @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) {
|
||||
val paint = Paint()
|
||||
val temBitmap = scaleBitmap(bitmap)
|
||||
canvas.drawBitmap(temBitmap, startX.toFloat(), startY.toFloat(), paint)
|
||||
temBitmap.recycle()
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas?) {
|
||||
super.onDraw(canvas)
|
||||
if (mainImagePath != null && canvas != null) {
|
||||
val bitmap = BitmapFactory.decodeFile(mainImagePath)
|
||||
//计算坐标
|
||||
calculateCoordinate(bitmap)
|
||||
//设置图像
|
||||
drawImage(canvas, bitmap)
|
||||
//设置坐标系(如果需要)
|
||||
drawCoordinate(canvas)
|
||||
if (!bitmap!!.isRecycled) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package com.coldmint.rust.core.turret
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Bitmap.createBitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.coldmint.rust.core.R
|
||||
|
||||
/**
|
||||
* 炮塔视图
|
||||
* @constructor
|
||||
*/
|
||||
class TurretView(context: Context, attributeSet: AttributeSet? = null) :
|
||||
View(context, attributeSet) {
|
||||
|
||||
private val debugKey = "炮塔视图"
|
||||
private lateinit var turretData: TurretData
|
||||
private var bitmapW: Int = 0
|
||||
private var bitmapH: Int = 0
|
||||
|
||||
|
||||
/**
|
||||
* 设置炮塔数据
|
||||
* @param turretData TurretData
|
||||
*/
|
||||
fun setTurretData(turretData: TurretData) {
|
||||
this.turretData = turretData
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取炮塔数据(若未初始化返回null)
|
||||
* @return TurretData?
|
||||
*/
|
||||
fun getTurretData(): TurretData? {
|
||||
if (this::turretData.isInitialized) {
|
||||
return turretData
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置炮塔X
|
||||
* @param x Int
|
||||
*/
|
||||
fun setTurretX(x: Int) {
|
||||
if (this::turretData.isInitialized) {
|
||||
turretData.x = x
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置炮塔X
|
||||
* @param y Int
|
||||
*/
|
||||
fun setTurretY(y: Int) {
|
||||
if (this::turretData.isInitialized) {
|
||||
turretData.y = y
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("DrawAllocation")
|
||||
override fun onDraw(canvas: Canvas?) {
|
||||
super.onDraw(canvas)
|
||||
if (this::turretData.isInitialized) {
|
||||
val paint = Paint()
|
||||
val bitmap = if (turretData.imageFile == null) {
|
||||
BitmapFactory.decodeResource(this.resources, R.drawable.image)
|
||||
} else {
|
||||
BitmapFactory.decodeFile(turretData.imageFile!!.absolutePath)
|
||||
}
|
||||
bitmapW = bitmap.width
|
||||
bitmapH = bitmap.height
|
||||
canvas?.drawBitmap(
|
||||
bitmap,
|
||||
(turretData.x - bitmapW / 2).toFloat(),
|
||||
(turretData.y - bitmapH / 2).toFloat(),
|
||||
paint
|
||||
)
|
||||
if (!bitmap.isRecycled) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
} else {
|
||||
Log.e(debugKey, "未设置炮塔数据,停止绘制。")
|
||||
}
|
||||
}
|
||||
}
|
9
assistantCoreLibrary/src/main/res/values/attrs.xml
Normal file
9
assistantCoreLibrary/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--声明样式属性-->
|
||||
<declare-styleable name="turretSketchpadView">
|
||||
<!--是否绘制坐标-->
|
||||
<attr name="drawCoordinate" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
|
@ -36,8 +36,8 @@ dependencies {
|
|||
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.2'
|
||||
implementation 'androidx.core:core-ktx:1.8.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
|
|
@ -2,4 +2,3 @@ include ':app'
|
|||
rootProject.name = "铁锈助手"
|
||||
include ':assistantCoreLibrary'
|
||||
include ':dialog'
|
||||
include ':turretsDragView'
|
||||
|
|
1
turretsDragView/.gitignore
vendored
1
turretsDragView/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
/build
|
|
@ -1,40 +0,0 @@
|
|||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 32
|
||||
|
||||
defaultConfig {
|
||||
minSdk 21
|
||||
targetSdk 32
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles "consumer-rules.pro"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
21
turretsDragView/proguard-rules.pro
vendored
21
turretsDragView/proguard-rules.pro
vendored
|
@ -1,21 +0,0 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
|
@ -1,24 +0,0 @@
|
|||
package com.coldmint.turretsdragview
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.coldmint.turretsdragview.test", appContext.packageName)
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.coldmint.turretsdragview">
|
||||
|
||||
</manifest>
|
|
@ -1,11 +0,0 @@
|
|||
package com.coldmint.turretsdragview
|
||||
|
||||
|
||||
/**
|
||||
* 炮塔数据
|
||||
* @property name String
|
||||
* @property x Int
|
||||
* @property y Int
|
||||
* @constructor
|
||||
*/
|
||||
data class TurretData(val name: String, val x: Int, val y: Int)
|
|
@ -1,84 +0,0 @@
|
|||
package com.coldmint.turretsdragview
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
|
||||
/**
|
||||
* 炮塔拖拽视图
|
||||
*/
|
||||
class TurretsDragView(context: Context) : View(context) {
|
||||
|
||||
val key = "炮塔拖拽视图"
|
||||
|
||||
//主要位图变量
|
||||
private var baseBitmap: Bitmap? = null
|
||||
|
||||
//画布
|
||||
private var canvas: Canvas? = null
|
||||
|
||||
//画笔
|
||||
private val paint by lazy {
|
||||
Paint()
|
||||
}
|
||||
|
||||
//路径与位图之间的映射
|
||||
val map = HashMap<String, Bitmap>()
|
||||
|
||||
|
||||
/**
|
||||
* 获取位图
|
||||
* 优先从映射里读取。
|
||||
* @param path String
|
||||
* @return Bitmap
|
||||
*/
|
||||
fun getBitmap(path: String): Bitmap {
|
||||
var bitmap = map[path]
|
||||
if (bitmap == null) {
|
||||
bitmap = BitmapFactory.decodeFile(path)
|
||||
map[path] = bitmap
|
||||
}
|
||||
return bitmap!!
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置主体图像
|
||||
*/
|
||||
fun setBaseImage(path: String) {
|
||||
baseBitmap = getBitmap(path)
|
||||
}
|
||||
|
||||
/**
|
||||
* 炮塔列表数据
|
||||
*/
|
||||
private val turretList by lazy {
|
||||
ArrayList<TurretData>()
|
||||
}
|
||||
|
||||
/**
|
||||
* 当测量视图
|
||||
* @param widthMeasureSpec Int
|
||||
* @param heightMeasureSpec Int
|
||||
*/
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 当绘制视图
|
||||
* @param canvas Canvas
|
||||
*/
|
||||
override fun onDraw(canvas: Canvas?) {
|
||||
super.onDraw(canvas)
|
||||
this.canvas = canvas
|
||||
if (baseBitmap == null) {
|
||||
Log.e(key, "未设置炮塔主体图像")
|
||||
throw NullPointerException("未设置炮塔主体图像")
|
||||
}else{
|
||||
val matrix = Matrix()
|
||||
canvas!!.drawBitmap(baseBitmap!!,matrix, paint)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package com.coldmint.turretsdragview
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user