!!
This commit is contained in:
parent
de9592764a
commit
c06aff7133
@ -3,7 +3,20 @@
|
|||||||
<component name="deploymentTargetDropDown">
|
<component name="deploymentTargetDropDown">
|
||||||
<value>
|
<value>
|
||||||
<entry key="app">
|
<entry key="app">
|
||||||
<State />
|
<State>
|
||||||
|
<runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="RUNNING_DEVICE_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="SERIAL_NUMBER" />
|
||||||
|
<value value="8cb784d4" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<timeTargetWasSelectedWithDropDown value="2024-11-24T11:06:07.206200396Z" />
|
||||||
|
</State>
|
||||||
</entry>
|
</entry>
|
||||||
</value>
|
</value>
|
||||||
</component>
|
</component>
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package com.sortug.thaiinput
|
package com.sortug.thaiinput
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
typealias InputToolsResponse = List<Any>
|
sealed interface InputToolsResponse{
|
||||||
|
data class Success(
|
||||||
|
val results: List<TransliterationResult>
|
||||||
|
): InputToolsResponse
|
||||||
|
data object FailedToParse: InputToolsResponse
|
||||||
|
}
|
||||||
|
|
||||||
data class ParsedResponse(
|
data class ParsedResponse(
|
||||||
val status: String,
|
val status: String,
|
||||||
@ -14,3 +20,22 @@ data class TransliterationResult(
|
|||||||
val options: List<String>,
|
val options: List<String>,
|
||||||
val metadata: Map<String, Any>?
|
val metadata: Map<String, Any>?
|
||||||
)
|
)
|
||||||
|
public fun parseResponse(response: List<Any>): InputToolsResponse {
|
||||||
|
Log.d("THAI_IME", "parsing API response: $response")
|
||||||
|
return when (response[0] as String) {
|
||||||
|
"SUCCESS" -> {
|
||||||
|
val dataList = response[1] as List<*>
|
||||||
|
val results = dataList.map { item ->
|
||||||
|
val itemList = item as List<*>
|
||||||
|
TransliterationResult(
|
||||||
|
wholeString = itemList[0] as String,
|
||||||
|
options = (itemList[1] as List<*>).filterIsInstance<String>(),
|
||||||
|
metadata = if (itemList.size > 3) itemList[3] as? Map<String, Any> else null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InputToolsResponse.Success(results)
|
||||||
|
}
|
||||||
|
"FAILED_TO_PARSE_REQUEST_BODY" -> InputToolsResponse.FailedToParse
|
||||||
|
else -> throw IllegalStateException("Unknown response status: ${response[0]}")
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ interface GoogleInputToolsApiService {
|
|||||||
@Query("ie") ie: String = "utf-8",
|
@Query("ie") ie: String = "utf-8",
|
||||||
@Query("oe") oe: String = "utf-8",
|
@Query("oe") oe: String = "utf-8",
|
||||||
@Query("app") app: String = "demopage"
|
@Query("app") app: String = "demopage"
|
||||||
): InputToolsResponse
|
): List<Any>
|
||||||
@GET("request")
|
@GET("request")
|
||||||
suspend fun getRawInputSuggestions(
|
suspend fun getRawInputSuggestions(
|
||||||
@Query("text") text: String,
|
@Query("text") text: String,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package com.sortug.thaiinput
|
package com.sortug.thaiinput
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.inputmethodservice.InputMethodService
|
import android.inputmethodservice.InputMethodService
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputConnection
|
import android.view.inputmethod.InputConnection
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -21,6 +22,7 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
updateCurrentInputDisplay(newValue)
|
updateCurrentInputDisplay(newValue)
|
||||||
}
|
}
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
private lateinit var keyboardContainer: LinearLayout
|
||||||
private lateinit var suggestionsContainer: LinearLayout
|
private lateinit var suggestionsContainer: LinearLayout
|
||||||
private lateinit var currentInputDisplay: TextView
|
private lateinit var currentInputDisplay: TextView
|
||||||
|
|
||||||
@ -28,53 +30,60 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
private fun updateCurrentInputDisplay(text: String) {
|
private fun updateCurrentInputDisplay(text: String) {
|
||||||
currentInputDisplay.text = text
|
currentInputDisplay.text = text
|
||||||
}
|
}
|
||||||
|
private val syms = listOf(
|
||||||
|
"1234567890".toList(),
|
||||||
|
"!@#$%^&*()".toList(),
|
||||||
|
"\".:?/-=+".toList()
|
||||||
|
)
|
||||||
|
private val letters = listOf(
|
||||||
|
"QWERTYUIOP".toList(),
|
||||||
|
"ASDFGHJKL".toList(),
|
||||||
|
"ZXCVBNM".toList()
|
||||||
|
)
|
||||||
|
|
||||||
|
private val fonts = listOf(
|
||||||
|
Typeface.NORMAL,
|
||||||
|
// Typeface.createFromAsset(assets, "fonts/round.ttf")
|
||||||
|
)
|
||||||
|
|
||||||
|
private var currentFontIndex = 0
|
||||||
|
|
||||||
override fun onCreateInputView(): View {
|
override fun onCreateInputView(): View {
|
||||||
val inputView = layoutInflater.inflate(R.layout.keyboard_layout, null) as LinearLayout
|
Log.d("THAI_IME", "onCreateInputView called") // Add this debug log
|
||||||
// options box
|
val inputView = layoutInflater.inflate(R.layout.keyboard_layout, null)
|
||||||
val scrollView = HorizontalScrollView(this).apply {
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create suggestions container
|
// Initialize views using findViewById
|
||||||
suggestionsContainer = LinearLayout(this).apply {
|
currentInputDisplay = inputView.findViewById(R.id.current_input_display)
|
||||||
orientation = LinearLayout.HORIZONTAL
|
suggestionsContainer = inputView.findViewById(R.id.suggestions_container)
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
keyboardContainer = inputView.findViewById(R.id.keyboard_container)
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
currentInputDisplay = TextView(this).apply{
|
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
).apply {
|
|
||||||
setMargins(10, 10, 10, 10)
|
|
||||||
}
|
|
||||||
setTextColor(Color.BLACK)
|
|
||||||
setBackgroundColor(Color.LTGRAY)
|
|
||||||
textSize = 18f
|
|
||||||
setPadding(10, 10, 10, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
inputView.addView(currentInputDisplay)
|
// Set up the keyboard
|
||||||
scrollView.addView(suggestionsContainer)
|
setKeyboard(letters)
|
||||||
inputView.addView(scrollView)
|
|
||||||
setupKeyboardKeys(inputView)
|
Log.d("THAI_IME", "Keyboard container child count: ${keyboardContainer.childCount}")
|
||||||
return inputView
|
return inputView
|
||||||
}
|
}
|
||||||
private fun setupKeyboardKeys(keyboardView: LinearLayout){
|
|
||||||
val keys = listOf(
|
|
||||||
"qwertyuiop".toList(),
|
private fun setSpecialKey(row: LinearLayout, txt: String, onClick: (String) -> Unit, width: Float = 1.5f){
|
||||||
"asdfghjkl".toList(),
|
val button = Button(this).apply{
|
||||||
"zkcvbnm".toList()
|
text = txt
|
||||||
)
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
var rowLayout: LinearLayout? = null
|
0,
|
||||||
keys.forEachIndexed { rowIndex, row ->
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
width
|
||||||
|
).apply {
|
||||||
|
setMargins(4, 4, 4, 4)
|
||||||
|
}
|
||||||
|
setTextColor(Color.LTGRAY)
|
||||||
|
setBackgroundColor(Color.BLACK)
|
||||||
|
setOnClickListener {onClick(txt)}
|
||||||
|
}
|
||||||
|
row.addView(button)
|
||||||
|
}
|
||||||
|
private fun setKeyboard(rows: List<List<Char>>) {
|
||||||
|
rows.forEachIndexed { rowIndex, row ->
|
||||||
|
Log.d("THAI_IME", "setting row :$row $rowIndex")
|
||||||
val rowLayout = LinearLayout(this).apply {
|
val rowLayout = LinearLayout(this).apply {
|
||||||
orientation = LinearLayout.HORIZONTAL
|
orientation = LinearLayout.HORIZONTAL
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
@ -82,33 +91,36 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (rowIndex == 2) { // Third row
|
if (rowIndex == 2){setSpecialKey(rowLayout, "1!", ::handleShift)}
|
||||||
// Add Shift key
|
// set keys proper
|
||||||
val shiftButton = createSpecialButton("⇧") { onShiftPressed() }
|
|
||||||
rowLayout.addView(shiftButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
row.forEach { char ->
|
row.forEach { char ->
|
||||||
|
Log.d("THAI_IME", "setting char :$char")
|
||||||
val button = Button(this).apply {
|
val button = Button(this).apply {
|
||||||
text = char.toString()
|
text = char.toString()
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
0,
|
0,
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
1f
|
1f
|
||||||
)
|
).apply{
|
||||||
setOnClickListener { onKeyPressed(if (isShiftActive) char.toString() else char.lowercaseChar().toString()) }
|
setMargins(4, 4, 4, 4)
|
||||||
|
}
|
||||||
|
setTextColor(Color.LTGRAY)
|
||||||
|
textSize = 18f
|
||||||
|
setBackgroundColor(Color.BLACK)
|
||||||
|
setOnClickListener {
|
||||||
|
if (isShiftActive) {
|
||||||
|
noApiCall(char.toString())
|
||||||
|
}else{
|
||||||
|
onKeyPressed(char.lowercaseChar().toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rowLayout.addView(button)
|
rowLayout.addView(button)
|
||||||
}
|
}
|
||||||
if (rowIndex == 2) { // Third row
|
|
||||||
// Add Backspace key
|
|
||||||
val backspaceButton = createSpecialButton("⌫") { onBackspace() }
|
|
||||||
rowLayout.addView(backspaceButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyboardView.addView(rowLayout)
|
if (rowIndex == 2) {setSpecialKey(rowLayout,"⌫", ::onBackspace)}
|
||||||
|
keyboardContainer.addView(rowLayout)
|
||||||
}
|
}
|
||||||
// Add a row for space
|
|
||||||
val spaceRow = LinearLayout(this).apply {
|
val spaceRow = LinearLayout(this).apply {
|
||||||
orientation = LinearLayout.HORIZONTAL
|
orientation = LinearLayout.HORIZONTAL
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
@ -116,21 +128,10 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
setSpecialKey(spaceRow, "F", ::changeFont, 0.4f)
|
||||||
val spaceButton = Button(this).apply {
|
setSpecialKey(spaceRow, "␣", {_ -> noApiCall(" ")}, 1f)
|
||||||
text = "Space"
|
setSpecialKey(spaceRow, "↵", {_ -> noApiCall("\n")}, 0.4f)
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
keyboardContainer.addView(spaceRow)
|
||||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
)
|
|
||||||
setOnClickListener { onSpace() }
|
|
||||||
}
|
|
||||||
spaceRow.addView(spaceButton)
|
|
||||||
|
|
||||||
keyboardView.addView(spaceRow)
|
|
||||||
|
|
||||||
Log.d("MyKeyboardService", "Keyboard keys set up")
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createSpecialButton(text: String, onClickListener: () -> Unit): Button {
|
private fun createSpecialButton(text: String, onClickListener: () -> Unit): Button {
|
||||||
@ -145,35 +146,15 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onShiftPressed() {
|
|
||||||
isShiftActive = !isShiftActive
|
|
||||||
Log.d("MyKeyboardService", "Shift pressed. Active: $isShiftActive")
|
|
||||||
// You might want to update the appearance of the Shift key here
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onBackspace() {
|
private fun onBackspace(_thing: String) {
|
||||||
Log.d("MyKeyboardService", "onBackspace called")
|
Log.d("MyKeyboardService", "onBackspace called")
|
||||||
val inputConnection = currentInputConnection ?: return
|
val inputConnection = currentInputConnection ?: return
|
||||||
|
|
||||||
// Only make API request if we still have text
|
// Only make API request if we still have text
|
||||||
if (currentInput.isNotEmpty()) {
|
if (currentInput.isNotEmpty()) {
|
||||||
currentInput = currentInput.substring(0, currentInput.length - 1)
|
currentInput = currentInput.substring(0, currentInput.length - 1)
|
||||||
coroutineScope.launch {
|
apiCall()
|
||||||
try {
|
|
||||||
val response = withContext(Dispatchers.IO) {
|
|
||||||
RetrofitClient.googleInputToolsApiService.getInputSuggestions(currentInput)
|
|
||||||
}
|
|
||||||
|
|
||||||
val parsedResponse = parseResponse(response)
|
|
||||||
val options = parsedResponse.results.flatMap { it.options }
|
|
||||||
|
|
||||||
Log.d("MyKeyboardService", "Parsed options after backspace: $options")
|
|
||||||
displaySuggestions(options)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("MyKeyboardService", "Error in API call after backspace", e)
|
|
||||||
displaySuggestions(listOf("Error: ${e.message}"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
inputConnection.deleteSurroundingText(1, 0)
|
inputConnection.deleteSurroundingText(1, 0)
|
||||||
// Clear suggestions if we've deleted all text
|
// Clear suggestions if we've deleted all text
|
||||||
@ -181,64 +162,56 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
}
|
}
|
||||||
Log.d("MyKeyboardService", "Current input after backspace: $currentInput")
|
Log.d("MyKeyboardService", "Current input after backspace: $currentInput")
|
||||||
}
|
}
|
||||||
private fun onSpace(){
|
|
||||||
val inputConnection = currentInputConnection ?: return
|
|
||||||
inputConnection.commitText(" ", 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
coroutineScope.cancel()
|
coroutineScope.cancel()
|
||||||
}
|
}
|
||||||
private fun onKeyPressed(text: String) {
|
private fun onKeyPressed(text: String) {
|
||||||
Log.d("MyKeyboardService", "onKeyPressed called with text: $text")
|
Log.d("MyKeyboardService", "onKeyPressed called with text: $text")
|
||||||
val inputConnection: InputConnection = currentInputConnection ?: return
|
|
||||||
currentInput += text
|
currentInput += text
|
||||||
Log.d("MyKeyboardService", "Current input: $currentInput")
|
Log.d("MyKeyboardService", "Current input: $currentInput")
|
||||||
|
|
||||||
Log.d("MyKeyboardService", "Key pressed: $text")
|
Log.d("MyKeyboardService", "Key pressed: $text")
|
||||||
|
apiCall()
|
||||||
|
}
|
||||||
|
private fun noApiCall(text: String){
|
||||||
|
val inputConnection: InputConnection = currentInputConnection ?: return
|
||||||
|
inputConnection.commitText(text, 1)
|
||||||
|
}
|
||||||
|
private fun apiCall(){
|
||||||
|
if (currentInput.isNotEmpty()){
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
try {
|
try {
|
||||||
// val rawResponse = withContext(Dispatchers.IO) {
|
Log.d("THAI_IME", "API request input: $currentInput")
|
||||||
// RetrofitClient.googleInputToolsApiService.getRawInputSuggestions(currentInput.toString())
|
val response = withContext(Dispatchers.IO) {
|
||||||
// }
|
RetrofitClient.googleInputToolsApiService.getInputSuggestions(currentInput)
|
||||||
// val rawJson = rawResponse.body()?.string() ?: "Empty response"
|
}
|
||||||
// Log.d("MyKeyboardService", "Raw API Response: $rawJson")
|
Log.d("THAI_IME", "raw API response: $response")
|
||||||
|
when (val apiResponse = parseResponse(response)){
|
||||||
val result = withContext(Dispatchers.IO) {
|
is InputToolsResponse.Success -> {
|
||||||
RetrofitClient.googleInputToolsApiService.getInputSuggestions(currentInput.toString())
|
val options = apiResponse.results.flatMap{it.options}
|
||||||
|
Log.d("MyKeyboardService", "Parsed options after backspace: $options")
|
||||||
|
displaySuggestions((options))
|
||||||
|
}
|
||||||
|
is InputToolsResponse.FailedToParse -> {
|
||||||
|
Log.e("THAI_IME", "Failed to parse request body: $currentInput")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val parsedResponse = parseResponse(result)
|
|
||||||
val options = parsedResponse.results.flatMap { it.options }
|
|
||||||
displaySuggestions(options)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("MyKeyboardService", "Unhandled error in HTTP request", e)
|
Log.e("MyKeyboardService", "Error in API call after backspace", e)
|
||||||
|
displaySuggestions(listOf("Error: ${e.message}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle exceptions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private fun parseResponse(response: InputToolsResponse): ParsedResponse {
|
|
||||||
val status = response[0] as String
|
|
||||||
val dataList = response[1] as List<*>
|
|
||||||
val results = dataList.map { item ->
|
|
||||||
val itemList = item as List<*>
|
|
||||||
TransliterationResult(
|
|
||||||
wholeString = itemList[0] as String,
|
|
||||||
options = (itemList[1] as List<*>).filterIsInstance<String>(),
|
|
||||||
metadata = if (itemList.size > 3) itemList[3] as? Map<String, Any> else null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return ParsedResponse(status, results)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun displaySuggestions(options: List<String>){
|
private fun displaySuggestions(options: List<String>){
|
||||||
suggestionsContainer.removeAllViews()
|
suggestionsContainer.removeAllViews()
|
||||||
options.forEach{ option ->
|
options.forEach{ option ->
|
||||||
val button = Button(this).apply{
|
val button = Button(this).apply{
|
||||||
text = option
|
text = option
|
||||||
|
textSize = 20f
|
||||||
|
// typeface = fonts[currentFontIndex] // Set the current font
|
||||||
setOnClickListener { onSuggestionClicked(option) }
|
setOnClickListener { onSuggestionClicked(option) }
|
||||||
layoutParams = LinearLayout.LayoutParams(
|
layoutParams = LinearLayout.LayoutParams(
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
@ -261,7 +234,88 @@ class MyKeyboardService : InputMethodService() {
|
|||||||
suggestionsContainer.removeAllViews()
|
suggestionsContainer.removeAllViews()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleShift(_thing: String){
|
||||||
|
Log.d("THAI_IME", "shift pressed")
|
||||||
|
isShiftActive = !isShiftActive
|
||||||
|
val keys = if (isShiftActive) syms else letters
|
||||||
|
keyboardContainer.removeAllViews()
|
||||||
|
setKeyboard(keys)
|
||||||
|
}
|
||||||
|
private fun changeFont(_thing: String){
|
||||||
|
currentFontIndex = (currentFontIndex + 1) % fonts.size
|
||||||
|
Log.d("THAI_IME", "🔤 Changed font to index: $currentFontIndex")
|
||||||
|
// Refresh suggestions with new font
|
||||||
|
redrawCurrentSuggestions()
|
||||||
|
}
|
||||||
|
private fun redrawCurrentSuggestions() {
|
||||||
|
val currentButtons = mutableListOf<String>()
|
||||||
|
for (i in 0 until suggestionsContainer.childCount) {
|
||||||
|
val button = suggestionsContainer.getChildAt(i) as? Button
|
||||||
|
button?.text?.toString()?.let { currentButtons.add(it) }
|
||||||
|
}
|
||||||
|
displaySuggestions(currentButtons)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Add methods for handling shift and number toggle
|
// TODO: Add methods for handling shift and number toggle
|
||||||
}
|
}
|
||||||
|
object ViewDebugUtils {
|
||||||
|
fun getViewHierarchy(view: View?, level: Int = 0): String {
|
||||||
|
if (view == null) return "null"
|
||||||
|
|
||||||
|
val indent = " ".repeat(level)
|
||||||
|
val builder = StringBuilder()
|
||||||
|
|
||||||
|
// Basic view information
|
||||||
|
builder.append("$indent${view.javaClass.simpleName} {")
|
||||||
|
builder.append("\n${indent} id: ${getViewId(view)}")
|
||||||
|
builder.append("\n${indent} width: ${view.width}, height: ${view.height}")
|
||||||
|
builder.append("\n${indent} visibility: ${getVisibilityString(view.visibility)}")
|
||||||
|
|
||||||
|
// Layout parameters
|
||||||
|
val params = view.layoutParams
|
||||||
|
if (params != null) {
|
||||||
|
builder.append("\n${indent} layout_width: ${getLayoutParamSize(params.width)}")
|
||||||
|
builder.append("\n${indent} layout_height: ${getLayoutParamSize(params.height)}")
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ViewGroups, recursively print children
|
||||||
|
if (view is ViewGroup) {
|
||||||
|
builder.append("\n${indent} children: [")
|
||||||
|
for (i in 0 until view.childCount) {
|
||||||
|
builder.append("\n${getViewHierarchy(view.getChildAt(i), level + 2)}")
|
||||||
|
}
|
||||||
|
if (view.childCount > 0) builder.append("\n$indent ]")
|
||||||
|
else builder.append("]")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("\n$indent}")
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getViewId(view: View): String {
|
||||||
|
val id = view.id
|
||||||
|
return when {
|
||||||
|
id == View.NO_ID -> "NO_ID"
|
||||||
|
else -> try {
|
||||||
|
view.resources.getResourceEntryName(id)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
id.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVisibilityString(visibility: Int): String = when (visibility) {
|
||||||
|
View.VISIBLE -> "VISIBLE"
|
||||||
|
View.INVISIBLE -> "INVISIBLE"
|
||||||
|
View.GONE -> "GONE"
|
||||||
|
else -> visibility.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLayoutParamSize(size: Int): String = when (size) {
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT -> "MATCH_PARENT"
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT -> "WRAP_CONTENT"
|
||||||
|
else -> size.toString()
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,54 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/keyboard_layout"
|
android:id="@+id/keyboard_main_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
>
|
android:background="@android:color/darker_gray">
|
||||||
|
|
||||||
|
<!-- Top Bar -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/keyboard_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:text="SORKB"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:background="@android:color/black"
|
||||||
|
android:elevation="4dp" />
|
||||||
|
|
||||||
|
<!-- Current Input Display -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/current_input_display"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textColor="@android:color/darker_gray"
|
||||||
|
android:background="@android:color/black" />
|
||||||
|
|
||||||
|
<!-- Suggestions Scroll View -->
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:id="@+id/suggestions_scroll_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/suggestions_container"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
|
<!-- Keyboard Container -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/keyboard_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
8
app/src/main/res/layout/old_keyboard_layout.xml
Normal file
8
app/src/main/res/layout/old_keyboard_layout.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/keyboard_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user