refer to our keyboard attributes, not the system ones

This commit is contained in:
tibbi 2022-01-08 23:08:08 +01:00
parent 731c599c78
commit ed00de9606
5 changed files with 194 additions and 215 deletions

View File

@ -24,9 +24,9 @@ import android.text.TextUtils
import android.util.TypedValue import android.util.TypedValue
import android.util.Xml import android.util.Xml
import androidx.annotation.XmlRes import androidx.annotation.XmlRes
import com.simplemobiletools.commons.helpers.mydebug
import com.simplemobiletools.keyboard.R import com.simplemobiletools.keyboard.R
import org.xmlpull.v1.XmlPullParserException import java.io.FileNotFoundException
import java.io.IOException
import java.util.* import java.util.*
/** /**
@ -87,7 +87,7 @@ class MyKeyboard {
var mKeys: MutableList<Key?>? = null var mKeys: MutableList<Key?>? = null
/** List of modifier keys such as Shift & Alt, if any */ /** List of modifier keys such as Shift & Alt, if any */
private var mModifierKeys: MutableList<Key?>? = null private var mModifierKeys = ArrayList<Key?>()
/** Width of the screen available to fit the keyboard */ /** Width of the screen available to fit the keyboard */
private var mDisplayWidth = 0 private var mDisplayWidth = 0
@ -160,6 +160,7 @@ class MyKeyboard {
/** Vertical gap following this row. */ /** Vertical gap following this row. */
var verticalGap = 0 var verticalGap = 0
var mKeys = ArrayList<Key>() var mKeys = ArrayList<Key>()
/** /**
@ -255,8 +256,7 @@ class MyKeyboard {
/** /**
* Flags that specify the anchoring to edges of the keyboard for detecting touch events * Flags that specify the anchoring to edges of the keyboard for detecting touch events
* that are just out of the boundary of the key. This is a bit mask of * that are just out of the boundary of the key. This is a bit mask of
* [MyKeyboard.EDGE_LEFT], [MyKeyboard.EDGE_RIGHT], [MyKeyboard.EDGE_TOP] and * [MyKeyboard.EDGE_LEFT], [MyKeyboard.EDGE_RIGHT], [MyKeyboard.EDGE_TOP] and [MyKeyboard.EDGE_BOTTOM].
* [MyKeyboard.EDGE_BOTTOM].
*/ */
var edgeFlags: Int var edgeFlags: Int
@ -275,8 +275,7 @@ class MyKeyboard {
/** Create a key with the given top-left coordinate and extract its attributes from /** Create a key with the given top-left coordinate and extract its attributes from
* the XML parser. * the XML parser.
* @param res resources associated with the caller's context * @param res resources associated with the caller's context
* @param parent the row that this key belongs to. The row must already be attached to * @param parent the row that this key belongs to. The row must already be attached to a [MyKeyboard].
* a [Keyboard].
* @param x the x coordinate of the top-left * @param x the x coordinate of the top-left
* @param y the y coordinate of the top-left * @param y the y coordinate of the top-left
* @param parser the XML parser containing the attributes for this key * @param parser the XML parser containing the attributes for this key
@ -315,8 +314,9 @@ class MyKeyboard {
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight) icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
label = a.getText(R.styleable.Keyboard_Key_keyLabel) label = a.getText(R.styleable.Keyboard_Key_keyLabel) ?: ""
text = a.getText(R.styleable.Keyboard_Key_keyOutputText) text = a.getText(R.styleable.Keyboard_Key_keyOutputText)
if (!TextUtils.isEmpty(label)) { if (!TextUtils.isEmpty(label)) {
codes = arrayListOf(label[0].toInt()) codes = arrayListOf(label[0].toInt())
} }
@ -378,6 +378,7 @@ class MyKeyboard {
try { try {
values[count++] = st.nextToken().toInt() values[count++] = st.nextToken().toInt()
} catch (nfe: NumberFormatException) { } catch (nfe: NumberFormatException) {
mydebug("NumberFormatException $nfe")
} }
} }
return values return values
@ -454,26 +455,6 @@ class MyKeyboard {
} }
} }
/**
* Creates a keyboard from the given xml key layout file. Weeds out rows
* that have a keyboard mode defined but don't match the specified mode.
* @param context the application or service context
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
* @param modeId keyboard mode identifier
* @param width sets width of keyboard
* @param height sets height of keyboard
*/
constructor(context: Context, @XmlRes xmlLayoutResId: Int, modeId: Int, width: Int, height: Int) {
mDisplayWidth = width
mDisplayHeight = height
mDefaultHorizontalGap = 0
mDefaultWidth = mDisplayWidth / 10
mDefaultVerticalGap = 0
mDefaultHeight = mDefaultWidth
mKeys = ArrayList()
mKeyboardMode = modeId
loadKeyboard(context, context.resources.getXml(xmlLayoutResId))
}
/** /**
* Creates a keyboard from the given xml key layout file. Weeds out rows * Creates a keyboard from the given xml key layout file. Weeds out rows
* that have a keyboard mode defined but don't match the specified mode. * that have a keyboard mode defined but don't match the specified mode.
@ -640,12 +621,12 @@ class MyKeyboard {
* point is out of range, then an array of size zero is returned. * point is out of range, then an array of size zero is returned.
*/ */
fun getNearestKeys(x: Int, y: Int): IntArray { fun getNearestKeys(x: Int, y: Int): IntArray {
if (x in 0 until minWidth && y >= 0 && y < height) { /*if (x in 0 until minWidth && y >= 0 && y < height) {
val index: Int = y / mCellHeight * GRID_WIDTH + x / mCellWidth val index: Int = y / mCellHeight * GRID_WIDTH + x / mCellWidth
if (index < GRID_SIZE) { if (index < GRID_SIZE) {
return mGridNeighbors[index]!! return mGridNeighbors[index]!!
} }
} }*/
return IntArray(0) return IntArray(0)
} }
@ -660,25 +641,24 @@ class MyKeyboard {
private fun loadKeyboard(context: Context, parser: XmlResourceParser) { private fun loadKeyboard(context: Context, parser: XmlResourceParser) {
var inKey = false var inKey = false
var inRow = false var inRow = false
val leftMostKey = false
var row = 0 var row = 0
var x = 0 var x = 0
var y = 0 var y = 0
var key: Key? = null var key: Key? = null
var currentRow: Row? = null var currentRow: Row? = null
val res = context.resources val res = context.resources
var skipRow = false
try { try {
var event: Int var event: Int
while (parser.next().also { event = it } != XmlResourceParser.END_DOCUMENT) { while (parser.next().also { event = it } != XmlResourceParser.END_DOCUMENT) {
if (event == XmlResourceParser.START_TAG) { if (event == XmlResourceParser.START_TAG) {
val tag = parser.name val tag = parser.name
if (TAG_ROW == tag) { if (TAG_ROW == tag) {
//mydebug("row $currentRow")
inRow = true inRow = true
x = 0 x = 0
currentRow = createRowFromXml(res, parser) currentRow = createRowFromXml(res, parser)
rows.add(currentRow) rows.add(currentRow)
skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode val skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode
if (skipRow) { if (skipRow) {
skipToEndOfRow(parser) skipToEndOfRow(parser)
inRow = false inRow = false
@ -696,9 +676,9 @@ class MyKeyboard {
break break
} }
} }
mModifierKeys!!.add(key) mModifierKeys.add(key)
} else if (key.codes[0] == KEYCODE_ALT) { } else if (key.codes[0] == KEYCODE_ALT) {
mModifierKeys!!.add(key) mModifierKeys.add(key)
} }
currentRow.mKeys.add(key) currentRow.mKeys.add(key)
} else if (TAG_KEYBOARD == tag) { } else if (TAG_KEYBOARD == tag) {
@ -719,12 +699,12 @@ class MyKeyboard {
} }
} }
} }
} catch (e: Exception) { } catch (e: FileNotFoundException) {
mydebug("Exception $e")
} }
height = y - mDefaultVerticalGap height = y - mDefaultVerticalGap
} }
@Throws(XmlPullParserException::class, IOException::class)
private fun skipToEndOfRow(parser: XmlResourceParser) { private fun skipToEndOfRow(parser: XmlResourceParser) {
var event: Int var event: Int
while (parser.next().also { event = it } != XmlResourceParser.END_DOCUMENT) { while (parser.next().also { event = it } != XmlResourceParser.END_DOCUMENT) {

View File

@ -1,4 +1,5 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -9,11 +10,10 @@
android:id="@+id/keyboardView" android:id="@+id/keyboardView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:keyPreviewLayout="@layout/keyboard_key_preview" app:keyPreviewLayout="@layout/keyboard_key_preview"
android:keyTextSize="22sp" app:keyTextSize="22sp"
android:popupLayout="@layout/keyboard_popup_keyboard" app:popupLayout="@layout/keyboard_popup_keyboard"
tools:ignore="ResourceCycle" /> tools:ignore="ResourceCycle" />
<ImageButton <ImageButton
@ -23,7 +23,6 @@
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:clickable="true"
android:src="@drawable/ic_cross_vector" /> android:src="@drawable/ic_cross_vector" />
</LinearLayout> </LinearLayout>

View File

@ -3,4 +3,89 @@
<declare-styleable name="KeyboardViewPreviewState"> <declare-styleable name="KeyboardViewPreviewState">
<attr name="state_long_pressable" format="boolean" /> <attr name="state_long_pressable" format="boolean" />
</declare-styleable> </declare-styleable>
<declare-styleable name="MyKeyboardView">
<attr name="keyboardViewStyle" format="reference" />
<!-- Image for the key. This image needs to be a StateListDrawable, with the following possible states:
normal, pressed, checkable, checkable+pressed, checkable+checked, checkable+checked+pressed. -->
<attr name="keyBackground" format="reference" />
<!-- Size of the text for character keys. -->
<attr name="keyTextSize" format="dimension" />
<!-- Size of the text for custom keys with some text and no icon. -->
<attr name="labelTextSize" format="dimension" />
<!-- Color to use for the label in a key. -->
<attr name="keyTextColor" format="color" />
<!-- Layout resource for key press feedback. -->
<attr name="keyPreviewLayout" format="reference" />
<!-- Vertical offset of the key press feedback from the key. -->
<attr name="keyPreviewOffset" format="dimension" />
<!-- Height of the key press feedback popup. -->
<attr name="keyPreviewHeight" format="dimension" />
<!-- Amount to offset the touch Y coordinate by, for bias correction. -->
<attr name="verticalCorrection" format="dimension" />
<!-- Layout resource for popup keyboards. -->
<attr name="popupLayout" format="reference" />
<attr name="shadowColor" format="color" />
<!-- Horizontal offset of the text shadow. -->
<attr name="shadowDx" format="dimension" />
<!-- Vertical offset of the text shadow. -->
<attr name="shadowDy" format="dimension" />
<!-- Blur radius of the text shadow. -->
<attr name="shadowRadius" format="float" />
</declare-styleable>
<declare-styleable name="Keyboard">
<!-- Default width of a key, in pixels or percentage of display width. -->
<attr name="keyWidth" format="dimension|fraction" />
<!-- Default height of a key, in pixels or percentage of display width. -->
<attr name="keyHeight" format="dimension|fraction" />
<!-- Default horizontal gap between keys. -->
<attr name="horizontalGap" format="dimension|fraction" />
<!-- Default vertical gap between rows of keys. -->
<attr name="verticalGap" format="dimension|fraction" />
</declare-styleable>
<declare-styleable name="Keyboard_Row">
<!-- Row edge flags. -->
<attr name="rowEdgeFlags">
<!-- Row is anchored to the top of the keyboard. -->
<flag name="top" value="4" />
<!-- Row is anchored to the bottom of the keyboard. -->
<flag name="bottom" value="8" />
</attr>
<!-- Mode of the keyboard. If the mode doesn't match the requested keyboard mode, the row will be skipped. -->
<attr name="keyboardMode" format="reference" />
</declare-styleable>
<declare-styleable name="Keyboard_Key">
<!-- The unicode value or comma-separated values that this key outputs. -->
<attr name="codes" format="integer|string" />
<!-- The XML keyboard layout of any popup keyboard. -->
<attr name="popupKeyboard" format="reference" />
<!-- The characters to display in the popup keyboard. -->
<attr name="popupCharacters" format="string" />
<!-- Key edge flags. -->
<attr name="keyEdgeFlags">
<!-- Key is anchored to the left of the keyboard. -->
<flag name="left" value="1" />
<!-- Key is anchored to the right of the keyboard. -->
<flag name="right" value="2" />
</attr>
<!-- Whether this is a modifier key such as Alt or Shift. -->
<attr name="isModifier" format="boolean" />
<!-- Whether this is a toggle key. -->
<attr name="isSticky" format="boolean" />
<!-- Whether long-pressing on this key will make it repeat. -->
<attr name="isRepeatable" format="boolean" />
<!-- The icon to show in the popup preview. -->
<attr name="iconPreview" format="reference" />
<!-- The string of characters to output when this key is pressed. -->
<attr name="keyOutputText" format="string" />
<!-- The label to display on the key. -->
<attr name="keyLabel" format="string" />
<!-- The icon to display on the key instead of the label. -->
<attr name="keyIcon" format="reference" />
<!-- Mode of the keyboard. If the mode doesn't match the requested keyboard mode, the key will be skipped. -->
<attr name="keyboardMode" />
</declare-styleable>
</resources> </resources>

View File

@ -20,89 +20,4 @@
<item name="shadowColor">#BB000000</item> <item name="shadowColor">#BB000000</item>
<item name="shadowRadius">2.75</item> <item name="shadowRadius">2.75</item>
</style> </style>
<declare-styleable name="MyKeyboardView">
<attr name="keyboardViewStyle" format="reference" />
<!-- Image for the key. This image needs to be a StateListDrawable, with the following possible states:
normal, pressed, checkable, checkable+pressed, checkable+checked, checkable+checked+pressed. -->
<attr name="keyBackground" format="reference" />
<!-- Size of the text for character keys. -->
<attr name="keyTextSize" format="dimension" />
<!-- Size of the text for custom keys with some text and no icon. -->
<attr name="labelTextSize" format="dimension" />
<!-- Color to use for the label in a key. -->
<attr name="keyTextColor" format="color" />
<!-- Layout resource for key press feedback. -->
<attr name="keyPreviewLayout" format="reference" />
<!-- Vertical offset of the key press feedback from the key. -->
<attr name="keyPreviewOffset" format="dimension" />
<!-- Height of the key press feedback popup. -->
<attr name="keyPreviewHeight" format="dimension" />
<!-- Amount to offset the touch Y coordinate by, for bias correction. -->
<attr name="verticalCorrection" format="dimension" />
<!-- Layout resource for popup keyboards. -->
<attr name="popupLayout" format="reference" />
<attr name="shadowColor" format="color" />
<!-- Horizontal offset of the text shadow. -->
<attr name="shadowDx" format="dimension" />
<!-- Vertical offset of the text shadow. -->
<attr name="shadowDy" format="dimension" />
<!-- Blur radius of the text shadow. -->
<attr name="shadowRadius" format="float" />
</declare-styleable>
<declare-styleable name="Keyboard">
<!-- Default width of a key, in pixels or percentage of display width. -->
<attr name="keyWidth" format="dimension|fraction" />
<!-- Default height of a key, in pixels or percentage of display width. -->
<attr name="keyHeight" format="dimension|fraction" />
<!-- Default horizontal gap between keys. -->
<attr name="horizontalGap" format="dimension|fraction" />
<!-- Default vertical gap between rows of keys. -->
<attr name="verticalGap" format="dimension|fraction" />
</declare-styleable>
<declare-styleable name="Keyboard_Row">
<!-- Row edge flags. -->
<attr name="rowEdgeFlags">
<!-- Row is anchored to the top of the keyboard. -->
<flag name="top" value="4" />
<!-- Row is anchored to the bottom of the keyboard. -->
<flag name="bottom" value="8" />
</attr>
<!-- Mode of the keyboard. If the mode doesn't match the requested keyboard mode, the row will be skipped. -->
<attr name="keyboardMode" format="reference" />
</declare-styleable>
<declare-styleable name="Keyboard_Key">
<!-- The unicode value or comma-separated values that this key outputs. -->
<attr name="codes" format="integer|string" />
<!-- The XML keyboard layout of any popup keyboard. -->
<attr name="popupKeyboard" format="reference" />
<!-- The characters to display in the popup keyboard. -->
<attr name="popupCharacters" format="string" />
<!-- Key edge flags. -->
<attr name="keyEdgeFlags">
<!-- Key is anchored to the left of the keyboard. -->
<flag name="left" value="1" />
<!-- Key is anchored to the right of the keyboard. -->
<flag name="right" value="2" />
</attr>
<!-- Whether this is a modifier key such as Alt or Shift. -->
<attr name="isModifier" format="boolean" />
<!-- Whether this is a toggle key. -->
<attr name="isSticky" format="boolean" />
<!-- Whether long-pressing on this key will make it repeat. -->
<attr name="isRepeatable" format="boolean" />
<!-- The icon to show in the popup preview. -->
<attr name="iconPreview" format="reference" />
<!-- The string of characters to output when this key is pressed. -->
<attr name="keyOutputText" format="string" />
<!-- The label to display on the key. -->
<attr name="keyLabel" format="string" />
<!-- The icon to display on the key instead of the label. -->
<attr name="keyIcon" format="reference" />
<!-- Mode of the keyboard. If the mode doesn't match the requested keyboard mode, the key will be skipped. -->
<attr name="keyboardMode" />
</declare-styleable>
</resources> </resources>

View File

@ -1,129 +1,129 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<MyKeyboard xmlns:android="http://schemas.android.com/apk/res/android" <MyKeyboard xmlns:app="http://schemas.android.com/apk/res-auto"
android:keyWidth="10%" app:keyBackground="@color/color_primary_dark"
android:keyHeight="60dp" app:keyHeight="60dp"
android:keyBackground="@color/color_primary_dark" app:keyTextColor="@color/color_accent"
android:keyTextColor="@color/color_accent" app:keyWidth="10%"
android:verticalGap="3px"> app:verticalGap="3px">
<Row> <Row>
<Key <Key
android:codes="113" app:codes="113"
android:keyEdgeFlags="left" app:keyEdgeFlags="left"
android:keyLabel="q" /> app:keyLabel="q" />
<Key <Key
android:codes="119" app:codes="119"
android:keyLabel="w" /> app:keyLabel="w" />
<Key <Key
android:codes="101" app:codes="101"
android:keyLabel="e" /> app:keyLabel="e" />
<Key <Key
android:codes="114" app:codes="114"
android:keyLabel="r" /> app:keyLabel="r" />
<Key <Key
android:codes="116" app:codes="116"
android:keyLabel="t" /> app:keyLabel="t" />
<Key <Key
android:codes="121" app:codes="121"
android:keyLabel="y" /> app:keyLabel="y" />
<Key <Key
android:codes="117" app:codes="117"
android:keyLabel="u" /> app:keyLabel="u" />
<Key <Key
android:codes="105" app:codes="105"
android:keyLabel="i" /> app:keyLabel="i" />
<Key <Key
android:codes="111" app:codes="111"
android:keyLabel="o" /> app:keyLabel="o" />
<Key <Key
android:codes="112" app:codes="112"
android:keyEdgeFlags="right" app:keyEdgeFlags="right"
android:keyLabel="p" /> app:keyLabel="p" />
</Row> </Row>
<Row> <Row>
<Key <Key
android:codes="97" app:codes="97"
android:horizontalGap="5%" app:horizontalGap="5%"
android:keyEdgeFlags="left" app:keyEdgeFlags="left"
android:keyLabel="a" /> app:keyLabel="a" />
<Key <Key
android:codes="115" app:codes="115"
android:keyLabel="s" /> app:keyLabel="s" />
<Key <Key
android:codes="100" app:codes="100"
android:keyLabel="d" /> app:keyLabel="d" />
<Key <Key
android:codes="102" app:codes="102"
android:keyLabel="f" /> app:keyLabel="f" />
<Key <Key
android:codes="103" app:codes="103"
android:keyLabel="g" /> app:keyLabel="g" />
<Key <Key
android:codes="104" app:codes="104"
android:keyLabel="h" /> app:keyLabel="h" />
<Key <Key
android:codes="106" app:codes="106"
android:keyLabel="j" /> app:keyLabel="j" />
<Key <Key
android:codes="107" app:codes="107"
android:keyLabel="k" /> app:keyLabel="k" />
<Key <Key
android:codes="108" app:codes="108"
android:keyLabel="l" /> app:keyLabel="l" />
</Row> </Row>
<Row> <Row>
<Key <Key
android:codes="-1" app:codes="-1"
android:keyWidth="15%p" app:keyEdgeFlags="left"
android:keyEdgeFlags="left" app:keyIcon="@drawable/ic_caps_outline_vector"
android:keyIcon="@drawable/ic_caps_outline_vector" /> app:keyWidth="15%p" />
<Key <Key
android:codes="122" app:codes="122"
android:keyLabel="z" /> app:keyLabel="z" />
<Key <Key
android:codes="120" app:codes="120"
android:keyLabel="x" /> app:keyLabel="x" />
<Key <Key
android:codes="99" app:codes="99"
android:keyLabel="c" /> app:keyLabel="c" />
<Key <Key
android:codes="118" app:codes="118"
android:keyLabel="v" /> app:keyLabel="v" />
<Key <Key
android:codes="98" app:codes="98"
android:keyLabel="b" /> app:keyLabel="b" />
<Key <Key
android:codes="110" app:codes="110"
android:keyLabel="n" /> app:keyLabel="n" />
<Key <Key
android:codes="109" app:codes="109"
android:keyLabel="m" /> app:keyLabel="m" />
<Key <Key
android:codes="-5" app:codes="-5"
android:iconPreview="@null" app:iconPreview="@null"
android:isRepeatable="true" app:isRepeatable="true"
android:keyWidth="15%p" app:keyEdgeFlags="right"
android:keyEdgeFlags="right" app:keyIcon="@drawable/ic_clear_vector"
android:keyIcon="@drawable/ic_clear_vector" /> app:keyWidth="15%p" />
</Row> </Row>
<Row android:rowEdgeFlags="bottom"> <Row app:rowEdgeFlags="bottom">
<Key <Key
android:codes="44" app:codes="44"
android:keyWidth="10%p" app:keyEdgeFlags="left"
android:keyEdgeFlags="left" app:keyLabel=","
android:keyLabel="," /> app:keyWidth="10%p" />
<Key <Key
android:codes="32" app:codes="32"
android:iconPreview="@null" app:iconPreview="@null"
android:isRepeatable="true" app:isRepeatable="true"
android:keyWidth="60%p" app:keyLabel=""
android:keyLabel="" /> app:keyWidth="60%p" />
<Key <Key
android:codes="46" app:codes="46"
android:keyLabel="." /> app:keyLabel="." />
<Key <Key
android:codes="-4" app:codes="-4"
android:keyWidth="20%p" app:keyEdgeFlags="right"
android:keyEdgeFlags="right" app:keyIcon="@drawable/ic_enter_vector"
android:keyIcon="@drawable/ic_enter_vector" /> app:keyWidth="20%p" />
</Row> </Row>
</MyKeyboard> </MyKeyboard>