mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-10 00:27:45 +00:00
pull updates accidentally committed to hangul_update branch
This commit is contained in:
commit
7b9ba8d60e
67 changed files with 330 additions and 1020 deletions
|
@ -111,13 +111,11 @@ public class ProximityInfo {
|
|||
return count;
|
||||
}
|
||||
|
||||
private long createNativeProximityInfo(
|
||||
@NonNull final TouchPositionCorrection touchPositionCorrection) {
|
||||
final List<Key>[] gridNeighborKeys = mGridNeighbors;
|
||||
private long createNativeProximityInfo(@NonNull final TouchPositionCorrection touchPositionCorrection) {
|
||||
final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||
Arrays.fill(proximityCharsArray, Constants.NOT_A_CODE);
|
||||
for (int i = 0; i < mGridSize; ++i) {
|
||||
final List<Key> neighborKeys = gridNeighborKeys[i];
|
||||
final List<Key> neighborKeys = mGridNeighbors[i];
|
||||
final int proximityCharsLength = neighborKeys.size();
|
||||
int infoIndex = i * MAX_PROXIMITY_CHARS_SIZE;
|
||||
for (int j = 0; j < proximityCharsLength; ++j) {
|
||||
|
@ -243,10 +241,9 @@ public class ProximityInfo {
|
|||
}
|
||||
|
||||
private void computeNearestNeighbors() {
|
||||
final int defaultWidth = mMostCommonKeyWidth;
|
||||
final int keyCount = mSortedKeys.size();
|
||||
final int gridSize = mGridNeighbors.length;
|
||||
final int threshold = (int) (defaultWidth * SEARCH_DISTANCE);
|
||||
final int threshold = (int) (mMostCommonKeyWidth * SEARCH_DISTANCE);
|
||||
final int thresholdSquared = threshold * threshold;
|
||||
// Round-up so we don't have any pixels outside the grid
|
||||
final int lastPixelXCoordinate = mGridWidth * mCellWidth - 1;
|
||||
|
|
|
@ -18,9 +18,9 @@ import org.dslul.openboard.inputmethod.latin.SuggestedWords
|
|||
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils
|
||||
|
||||
class AccessibilityUtils private constructor() {
|
||||
private var mContext: Context? = null
|
||||
private var mAccessibilityManager: AccessibilityManager? = null
|
||||
private var mAudioManager: AudioManager? = null
|
||||
private lateinit var mContext: Context
|
||||
private lateinit var mAccessibilityManager: AccessibilityManager
|
||||
private lateinit var mAudioManager: AudioManager
|
||||
/** The most recent auto-correction. */
|
||||
private var mAutoCorrectionWord: String? = null
|
||||
/** The most recent typed word for auto-correction. */
|
||||
|
@ -39,7 +39,7 @@ class AccessibilityUtils private constructor() {
|
|||
* @return `true` if accessibility is enabled.
|
||||
*/
|
||||
val isAccessibilityEnabled: Boolean
|
||||
get() = ENABLE_ACCESSIBILITY && mAccessibilityManager!!.isEnabled
|
||||
get() = ENABLE_ACCESSIBILITY && mAccessibilityManager.isEnabled
|
||||
|
||||
/**
|
||||
* Returns `true` if touch exploration is enabled. Currently, this
|
||||
|
@ -49,7 +49,7 @@ class AccessibilityUtils private constructor() {
|
|||
* @return `true` if touch exploration is enabled.
|
||||
*/
|
||||
val isTouchExplorationEnabled: Boolean
|
||||
get() = isAccessibilityEnabled && mAccessibilityManager!!.isTouchExplorationEnabled
|
||||
get() = isAccessibilityEnabled && mAccessibilityManager.isTouchExplorationEnabled
|
||||
|
||||
/**
|
||||
* Returns whether the device should obscure typed password characters.
|
||||
|
@ -61,12 +61,12 @@ class AccessibilityUtils private constructor() {
|
|||
if (editorInfo == null) return false
|
||||
// The user can optionally force speaking passwords.
|
||||
if (Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD != null) {
|
||||
val speakPassword = Settings.Secure.getInt(mContext!!.contentResolver,
|
||||
val speakPassword = Settings.Secure.getInt(mContext.contentResolver,
|
||||
Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0
|
||||
if (speakPassword) return false
|
||||
}
|
||||
// Always speak if the user is listening through headphones.
|
||||
return if (mAudioManager!!.isWiredHeadsetOn || mAudioManager!!.isBluetoothA2dpOn) {
|
||||
return if (mAudioManager.isWiredHeadsetOn || mAudioManager.isBluetoothA2dpOn) {
|
||||
false
|
||||
} else InputTypeUtils.isPasswordInputType(editorInfo.inputType)
|
||||
// Don't speak if the IME is connected to a password field.
|
||||
|
@ -105,9 +105,9 @@ class AccessibilityUtils private constructor() {
|
|||
if (!TextUtils.isEmpty(mAutoCorrectionWord)) {
|
||||
if (!TextUtils.equals(mAutoCorrectionWord, mTypedWord)) {
|
||||
return if (shouldObscure) { // This should never happen, but just in case...
|
||||
mContext!!.getString(R.string.spoken_auto_correct_obscured,
|
||||
mContext.getString(R.string.spoken_auto_correct_obscured,
|
||||
keyCodeDescription)
|
||||
} else mContext!!.getString(R.string.spoken_auto_correct, keyCodeDescription,
|
||||
} else mContext.getString(R.string.spoken_auto_correct, keyCodeDescription,
|
||||
mTypedWord, mAutoCorrectionWord)
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ class AccessibilityUtils private constructor() {
|
|||
* @param text The text to speak.
|
||||
*/
|
||||
fun announceForAccessibility(view: View, text: CharSequence?) {
|
||||
if (!mAccessibilityManager!!.isEnabled) {
|
||||
if (!mAccessibilityManager.isEnabled) {
|
||||
Log.e(TAG, "Attempted to speak when accessibility was disabled!")
|
||||
return
|
||||
}
|
||||
|
@ -154,10 +154,9 @@ class AccessibilityUtils private constructor() {
|
|||
* @param editorInfo The input connection's editor info attribute.
|
||||
* @param restarting Whether the connection is being restarted.
|
||||
*/
|
||||
fun onStartInputViewInternal(view: View, editorInfo: EditorInfo?,
|
||||
restarting: Boolean) {
|
||||
fun onStartInputViewInternal(view: View, editorInfo: EditorInfo?, restarting: Boolean) {
|
||||
if (shouldObscureInput(editorInfo)) {
|
||||
val text = mContext!!.getText(R.string.spoken_use_headphones)
|
||||
val text = mContext.getText(R.string.spoken_use_headphones)
|
||||
announceForAccessibility(view, text)
|
||||
}
|
||||
}
|
||||
|
@ -169,8 +168,8 @@ class AccessibilityUtils private constructor() {
|
|||
* @param event The event to send.
|
||||
*/
|
||||
fun requestSendAccessibilityEvent(event: AccessibilityEvent?) {
|
||||
if (mAccessibilityManager!!.isEnabled) {
|
||||
mAccessibilityManager!!.sendAccessibilityEvent(event)
|
||||
if (mAccessibilityManager.isEnabled) {
|
||||
mAccessibilityManager.sendAccessibilityEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,10 +179,10 @@ class AccessibilityUtils private constructor() {
|
|||
private val PACKAGE = AccessibilityUtils::class.java.getPackage()!!.name
|
||||
val instance = AccessibilityUtils()
|
||||
/*
|
||||
* Setting this constant to {@code false} will disable all keyboard
|
||||
* accessibility code, regardless of whether Accessibility is turned on in
|
||||
* the system settings. It should ONLY be used in the event of an emergency.
|
||||
*/
|
||||
* Setting this constant to {@code false} will disable all keyboard
|
||||
* accessibility code, regardless of whether Accessibility is turned on in
|
||||
* the system settings. It should ONLY be used in the event of an emergency.
|
||||
*/
|
||||
private const val ENABLE_ACCESSIBILITY = true
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -15,7 +15,30 @@ import java.util.*
|
|||
|
||||
internal class KeyCodeDescriptionMapper private constructor() {
|
||||
// Sparse array of spoken description resource IDs indexed by key codes
|
||||
private val mKeyCodeMap = SparseIntArray()
|
||||
private val mKeyCodeMap = SparseIntArray().apply {
|
||||
// Special non-character codes defined in Keyboard
|
||||
put(Constants.CODE_SPACE, R.string.spoken_description_space)
|
||||
put(Constants.CODE_DELETE, R.string.spoken_description_delete)
|
||||
put(Constants.CODE_ENTER, R.string.spoken_description_return)
|
||||
put(Constants.CODE_SETTINGS, R.string.spoken_description_settings)
|
||||
put(Constants.CODE_SHIFT, R.string.spoken_description_shift)
|
||||
put(Constants.CODE_SHORTCUT, R.string.spoken_description_mic)
|
||||
put(Constants.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol)
|
||||
put(Constants.CODE_TAB, R.string.spoken_description_tab)
|
||||
put(Constants.CODE_LANGUAGE_SWITCH, R.string.spoken_description_language_switch)
|
||||
put(Constants.CODE_ACTION_NEXT, R.string.spoken_description_action_next)
|
||||
put(Constants.CODE_ACTION_PREVIOUS, R.string.spoken_description_action_previous)
|
||||
put(Constants.CODE_EMOJI, R.string.spoken_description_emoji)
|
||||
// Because the upper-case and lower-case mappings of the following letters is depending on
|
||||
// the locale, the upper case descriptions should be defined here. The lower case
|
||||
// descriptions are handled in {@link #getSpokenLetterDescriptionId(Context,int)}.
|
||||
// U+0049: "I" LATIN CAPITAL LETTER I
|
||||
// U+0069: "i" LATIN SMALL LETTER I
|
||||
// U+0130: "İ" LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
// U+0131: "ı" LATIN SMALL LETTER DOTLESS I
|
||||
put(0x0049, R.string.spoken_letter_0049)
|
||||
put(0x0130, R.string.spoken_letter_0130)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized description of the action performed by a specified
|
||||
|
@ -27,8 +50,7 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
* @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured.
|
||||
* @return a character sequence describing the action performed by pressing the key
|
||||
*/
|
||||
fun getDescriptionForKey(context: Context, keyboard: Keyboard?,
|
||||
key: Key, shouldObscure: Boolean): String? {
|
||||
fun getDescriptionForKey(context: Context, keyboard: Keyboard?, key: Key, shouldObscure: Boolean): String? {
|
||||
val code = key.code
|
||||
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
|
||||
val description = getDescriptionForSwitchAlphaSymbol(context, keyboard)
|
||||
|
@ -39,17 +61,19 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
if (code == Constants.CODE_SHIFT) {
|
||||
return getDescriptionForShiftKey(context, keyboard)
|
||||
}
|
||||
if (code == Constants.CODE_ENTER) { // The following function returns the correct description in all action and
|
||||
// regular enter cases, taking care of all modes.
|
||||
if (code == Constants.CODE_ENTER) {
|
||||
// The following function returns the correct description in all action and
|
||||
// regular enter cases, taking care of all modes.
|
||||
return getDescriptionForActionKey(context, keyboard, key)
|
||||
}
|
||||
if (code == Constants.CODE_OUTPUT_TEXT) {
|
||||
val outputText = key.outputText
|
||||
val outputText = key.outputText ?: return context.getString(R.string.spoken_description_unknown)
|
||||
val description = getSpokenEmoticonDescription(context, outputText)
|
||||
return if (TextUtils.isEmpty(description)) outputText else description
|
||||
}
|
||||
// Just attempt to speak the description.
|
||||
if (code != Constants.CODE_UNSPECIFIED) { // If the key description should be obscured, now is the time to do it.
|
||||
if (code != Constants.CODE_UNSPECIFIED) {
|
||||
// If the key description should be obscured, now is the time to do it.
|
||||
val isDefinedNonCtrl = (Character.isDefined(code)
|
||||
&& !Character.isISOControl(code))
|
||||
if (shouldObscure && isDefinedNonCtrl) {
|
||||
|
@ -74,7 +98,8 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
* @param codePoint The code point from which to obtain a description.
|
||||
* @return a character sequence describing the code point.
|
||||
*/
|
||||
fun getDescriptionForCodePoint(context: Context, codePoint: Int): String? { // If the key description should be obscured, now is the time to do it.
|
||||
fun getDescriptionForCodePoint(context: Context, codePoint: Int): String? {
|
||||
// If the key description should be obscured, now is the time to do it.
|
||||
val index = mKeyCodeMap.indexOfKey(codePoint)
|
||||
if (index >= 0) {
|
||||
return context.getString(mKeyCodeMap.valueAt(index))
|
||||
|
@ -141,8 +166,7 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
val resourceName = String.format(Locale.ROOT, resourceNameFormat, code)
|
||||
val resources = context.resources
|
||||
// Note that the resource package name may differ from the context package name.
|
||||
val resourcePackageName = resources.getResourcePackageName(
|
||||
R.string.spoken_description_unknown)
|
||||
val resourcePackageName = resources.getResourcePackageName(R.string.spoken_description_unknown)
|
||||
val resId = resources.getIdentifier(resourceName, "string", resourcePackageName)
|
||||
if (resId != 0) {
|
||||
mKeyCodeMap.append(code, resId)
|
||||
|
@ -170,12 +194,8 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
* @param keyboard The keyboard on which the key resides.
|
||||
* @return a character sequence describing the action performed by pressing the key
|
||||
*/
|
||||
private fun getDescriptionForSwitchAlphaSymbol(context: Context,
|
||||
keyboard: Keyboard?): String? {
|
||||
val keyboardId = keyboard!!.mId
|
||||
val elementId = keyboardId.mElementId
|
||||
val resId: Int
|
||||
resId = when (elementId) {
|
||||
private fun getDescriptionForSwitchAlphaSymbol(context: Context, keyboard: Keyboard?): String? {
|
||||
val resId = when (val elementId = keyboard?.mId?.mElementId) {
|
||||
KeyboardId.ELEMENT_ALPHABET, KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_to_symbol
|
||||
KeyboardId.ELEMENT_SYMBOLS, KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> R.string.spoken_description_to_alpha
|
||||
KeyboardId.ELEMENT_PHONE -> R.string.spoken_description_to_symbol
|
||||
|
@ -195,12 +215,8 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
* @param keyboard The keyboard on which the key resides.
|
||||
* @return A context-sensitive description of the "Shift" key.
|
||||
*/
|
||||
private fun getDescriptionForShiftKey(context: Context,
|
||||
keyboard: Keyboard?): String {
|
||||
val keyboardId = keyboard!!.mId
|
||||
val elementId = keyboardId.mElementId
|
||||
val resId: Int
|
||||
resId = when (elementId) {
|
||||
private fun getDescriptionForShiftKey(context: Context, keyboard: Keyboard?): String {
|
||||
val resId: Int = when (keyboard?.mId?.mElementId) {
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_caps_lock
|
||||
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED -> R.string.spoken_description_shift_shifted
|
||||
KeyboardId.ELEMENT_SYMBOLS -> R.string.spoken_description_symbols_shift
|
||||
|
@ -218,16 +234,12 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
* @param key The key to describe.
|
||||
* @return Returns a context-sensitive description of the "Enter" action key.
|
||||
*/
|
||||
private fun getDescriptionForActionKey(context: Context, keyboard: Keyboard?,
|
||||
key: Key): String {
|
||||
val keyboardId = keyboard!!.mId
|
||||
val actionId = keyboardId.imeAction()
|
||||
val resId: Int
|
||||
private fun getDescriptionForActionKey(context: Context, keyboard: Keyboard?, key: Key): String {
|
||||
// Always use the label, if available.
|
||||
if (!TextUtils.isEmpty(key.label)) {
|
||||
return key.label!!.trim { it <= ' ' }
|
||||
}
|
||||
resId = when (actionId) {
|
||||
val resId = when (keyboard?.mId?.imeAction()) {
|
||||
EditorInfo.IME_ACTION_SEARCH -> R.string.label_search_key
|
||||
EditorInfo.IME_ACTION_GO -> R.string.label_go_key
|
||||
EditorInfo.IME_ACTION_SEND -> R.string.label_send_key
|
||||
|
@ -240,10 +252,9 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
}
|
||||
|
||||
// TODO: Remove this method once TTS supports emoticon verbalization.
|
||||
private fun getSpokenEmoticonDescription(context: Context,
|
||||
outputText: String?): String? {
|
||||
private fun getSpokenEmoticonDescription(context: Context, outputText: String): String? {
|
||||
val sb = StringBuilder(SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX)
|
||||
val textLength = outputText!!.length
|
||||
val textLength = outputText.length
|
||||
var index = 0
|
||||
while (index < textLength) {
|
||||
val codePoint = outputText.codePointAt(index)
|
||||
|
@ -253,36 +264,10 @@ internal class KeyCodeDescriptionMapper private constructor() {
|
|||
val resourceName = sb.toString()
|
||||
val resources = context.resources
|
||||
// Note that the resource package name may differ from the context package name.
|
||||
val resourcePackageName = resources.getResourcePackageName(
|
||||
R.string.spoken_description_unknown)
|
||||
val resourcePackageName = resources.getResourcePackageName(R.string.spoken_description_unknown)
|
||||
val resId = resources.getIdentifier(resourceName, "string", resourcePackageName)
|
||||
return if (resId == 0) null else resources.getString(resId)
|
||||
}
|
||||
}
|
||||
|
||||
init { // Special non-character codes defined in Keyboard
|
||||
mKeyCodeMap.put(Constants.CODE_SPACE, R.string.spoken_description_space)
|
||||
mKeyCodeMap.put(Constants.CODE_DELETE, R.string.spoken_description_delete)
|
||||
mKeyCodeMap.put(Constants.CODE_ENTER, R.string.spoken_description_return)
|
||||
mKeyCodeMap.put(Constants.CODE_SETTINGS, R.string.spoken_description_settings)
|
||||
mKeyCodeMap.put(Constants.CODE_SHIFT, R.string.spoken_description_shift)
|
||||
mKeyCodeMap.put(Constants.CODE_SHORTCUT, R.string.spoken_description_mic)
|
||||
mKeyCodeMap.put(Constants.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol)
|
||||
mKeyCodeMap.put(Constants.CODE_TAB, R.string.spoken_description_tab)
|
||||
mKeyCodeMap.put(Constants.CODE_LANGUAGE_SWITCH,
|
||||
R.string.spoken_description_language_switch)
|
||||
mKeyCodeMap.put(Constants.CODE_ACTION_NEXT, R.string.spoken_description_action_next)
|
||||
mKeyCodeMap.put(Constants.CODE_ACTION_PREVIOUS,
|
||||
R.string.spoken_description_action_previous)
|
||||
mKeyCodeMap.put(Constants.CODE_EMOJI, R.string.spoken_description_emoji)
|
||||
// Because the upper-case and lower-case mappings of the following letters is depending on
|
||||
// the locale, the upper case descriptions should be defined here. The lower case
|
||||
// descriptions are handled in {@link #getSpokenLetterDescriptionId(Context,int)}.
|
||||
// U+0049: "I" LATIN CAPITAL LETTER I
|
||||
// U+0069: "i" LATIN SMALL LETTER I
|
||||
// U+0130: "İ" LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
// U+0131: "ı" LATIN SMALL LETTER DOTLESS I
|
||||
mKeyCodeMap.put(0x0049, R.string.spoken_letter_0049)
|
||||
mKeyCodeMap.put(0x0130, R.string.spoken_letter_0130)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,14 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardView
|
|||
*
|
||||
* @param <KV> The keyboard view class type.
|
||||
</KV> */
|
||||
open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyboardView: KV, protected val mKeyDetector: KeyDetector) : AccessibilityDelegateCompat() {
|
||||
open class KeyboardAccessibilityDelegate<KV : KeyboardView>(
|
||||
protected val mKeyboardView: KV,
|
||||
protected val mKeyDetector: KeyDetector
|
||||
) : AccessibilityDelegateCompat() {
|
||||
private var mKeyboard: Keyboard? = null
|
||||
private var mAccessibilityNodeProvider: KeyboardAccessibilityNodeProvider<KV>? = null
|
||||
private var mLastHoverKey: Key? = null
|
||||
|
||||
|
||||
protected open var lastHoverKey: Key?
|
||||
get() = mLastHoverKey
|
||||
set(key) {
|
||||
|
@ -45,14 +47,14 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
* @param keyboard The keyboard that is being set to the wrapping view.
|
||||
*/
|
||||
open var keyboard: Keyboard?
|
||||
get() = mKeyboard
|
||||
set(keyboard) {
|
||||
if (keyboard == null) {
|
||||
return
|
||||
get() = mKeyboard
|
||||
set(keyboard) {
|
||||
if (keyboard == null) {
|
||||
return
|
||||
}
|
||||
mAccessibilityNodeProvider?.setKeyboard(keyboard)
|
||||
mKeyboard = keyboard
|
||||
}
|
||||
mAccessibilityNodeProvider?.setKeyboard(keyboard)
|
||||
mKeyboard = keyboard
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a window state change event with the specified string resource id.
|
||||
|
@ -63,7 +65,7 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
if (resId == 0) {
|
||||
return
|
||||
}
|
||||
val context = mKeyboardView!!.context
|
||||
val context = mKeyboardView.context
|
||||
sendWindowStateChanged(context.getString(resId))
|
||||
}
|
||||
|
||||
|
@ -74,7 +76,7 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
*/
|
||||
protected fun sendWindowStateChanged(text: String?) {
|
||||
val stateChange = AccessibilityUtils.obtainEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
|
||||
mKeyboardView!!.onInitializeAccessibilityEvent(stateChange)
|
||||
mKeyboardView.onInitializeAccessibilityEvent(stateChange)
|
||||
stateChange.text.add(text)
|
||||
stateChange.contentDescription = null
|
||||
val parent = mKeyboardView.parent
|
||||
|
@ -91,19 +93,21 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
*/
|
||||
override fun getAccessibilityNodeProvider(host: View): KeyboardAccessibilityNodeProvider<KV> {
|
||||
return accessibilityNodeProvider
|
||||
}// Instantiate the provide only when requested. Since the system
|
||||
// will call this method multiple times it is a good practice to
|
||||
// cache the provider instance.
|
||||
}
|
||||
// Instantiate the provide only when requested. Since the system
|
||||
// will call this method multiple times it is a good practice to
|
||||
// cache the provider instance.
|
||||
|
||||
/**
|
||||
* @return A lazily-instantiated node provider for this view delegate.
|
||||
*/
|
||||
protected val accessibilityNodeProvider: KeyboardAccessibilityNodeProvider<KV>
|
||||
get() { // Instantiate the provide only when requested. Since the system
|
||||
// will call this method multiple times it is a good practice to
|
||||
// cache the provider instance.
|
||||
return mAccessibilityNodeProvider ?: KeyboardAccessibilityNodeProvider(mKeyboardView, this)
|
||||
}
|
||||
get() {
|
||||
// Instantiate the provide only when requested. Since the system
|
||||
// will call this method multiple times it is a good practice to
|
||||
// cache the provider instance.
|
||||
return mAccessibilityNodeProvider ?: KeyboardAccessibilityNodeProvider(mKeyboardView, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a key that a hover event is on.
|
||||
|
@ -177,7 +181,7 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
lastKey?.let { onHoverExitFrom(it) }
|
||||
val key = getHoverKeyOf(event)
|
||||
// Make sure we're not getting an EXIT event because the user slid
|
||||
// off the keyboard area, then force a key press.
|
||||
// off the keyboard area, then force a key press.
|
||||
key?.let { performClickOn(it)
|
||||
onHoverExitFrom(it) }
|
||||
mLastHoverKey = null
|
||||
|
@ -208,7 +212,7 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
val eventTime = SystemClock.uptimeMillis()
|
||||
val touchEvent = MotionEvent.obtain(
|
||||
eventTime, eventTime, touchAction, x.toFloat(), y.toFloat(), 0 /* metaState */)
|
||||
mKeyboardView!!.onTouchEvent(touchEvent)
|
||||
mKeyboardView.onTouchEvent(touchEvent)
|
||||
touchEvent.recycle()
|
||||
}
|
||||
|
||||
|
@ -222,7 +226,7 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
Log.d(TAG, "onHoverEnterTo: key=$key")
|
||||
}
|
||||
key.onPressed()
|
||||
mKeyboardView!!.invalidateKey(key)
|
||||
mKeyboardView.invalidateKey(key)
|
||||
val provider = accessibilityNodeProvider
|
||||
provider.onHoverEnterTo(key)
|
||||
provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS)
|
||||
|
@ -245,7 +249,7 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
Log.d(TAG, "onHoverExitFrom: key=$key")
|
||||
}
|
||||
key.onReleased()
|
||||
mKeyboardView!!.invalidateKey(key)
|
||||
mKeyboardView.invalidateKey(key)
|
||||
val provider = accessibilityNodeProvider
|
||||
provider.onHoverExitFrom(key)
|
||||
}
|
||||
|
@ -255,17 +259,18 @@ open class KeyboardAccessibilityDelegate<KV : KeyboardView?>(protected val mKeyb
|
|||
*
|
||||
* @param key A key to be long pressed on.
|
||||
*/
|
||||
open fun performLongClickOn(key: Key) { // A extended class should override this method to implement long press.
|
||||
open fun performLongClickOn(key: Key) {
|
||||
// A extended class should override this method to implement long press.
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = KeyboardAccessibilityDelegate::class.java.simpleName
|
||||
const val DEBUG_HOVER = false
|
||||
const val HOVER_EVENT_POINTER_ID = 0
|
||||
private val TAG = KeyboardAccessibilityDelegate::class.java.simpleName
|
||||
const val DEBUG_HOVER = false
|
||||
const val HOVER_EVENT_POINTER_ID = 0
|
||||
}
|
||||
|
||||
init {
|
||||
// Ensure that the view has an accessibility delegate.
|
||||
ViewCompat.setAccessibilityDelegate(mKeyboardView!!, this)
|
||||
ViewCompat.setAccessibilityDelegate(mKeyboardView, this) // todo: see the warning, this may be bad
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.dslul.openboard.inputmethod.accessibility
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
|
@ -28,10 +27,14 @@ import org.dslul.openboard.inputmethod.latin.settings.Settings
|
|||
* virtual views, thus conveying their logical structure.
|
||||
*
|
||||
*/
|
||||
class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
||||
delegate: KeyboardAccessibilityDelegate<KV>) : AccessibilityNodeProviderCompat() {
|
||||
private val mKeyCodeDescriptionMapper: KeyCodeDescriptionMapper
|
||||
private val mAccessibilityUtils: AccessibilityUtils
|
||||
class KeyboardAccessibilityNodeProvider<KV : KeyboardView>(
|
||||
/** The keyboard view to provide an accessibility node info. */
|
||||
private val mKeyboardView: KV,
|
||||
/** The accessibility delegate. */
|
||||
private val mDelegate: KeyboardAccessibilityDelegate<KV>
|
||||
) : AccessibilityNodeProviderCompat() {
|
||||
private val mKeyCodeDescriptionMapper: KeyCodeDescriptionMapper = KeyCodeDescriptionMapper.instance
|
||||
private val mAccessibilityUtils: AccessibilityUtils = AccessibilityUtils.instance
|
||||
/** Temporary rect used to calculate in-screen bounds. */
|
||||
private val mTempBoundsInScreen = Rect()
|
||||
/** The parent view's cached on-screen location. */
|
||||
|
@ -40,12 +43,8 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
private var mAccessibilityFocusedView = UNDEFINED
|
||||
/** The virtual view identifier for the hovering node. */
|
||||
private var mHoveringNodeId = UNDEFINED
|
||||
/** The keyboard view to provide an accessibility node info. */
|
||||
private val mKeyboardView: KV
|
||||
/** The accessibility delegate. */
|
||||
private val mDelegate: KeyboardAccessibilityDelegate<KV>
|
||||
/** The current keyboard. */
|
||||
private var mKeyboard: Keyboard? = null
|
||||
private var mKeyboard: Keyboard? = mKeyboardView.keyboard
|
||||
|
||||
/**
|
||||
* Sets the keyboard represented by this node provider.
|
||||
|
@ -57,10 +56,8 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
}
|
||||
|
||||
private fun getKeyOf(virtualViewId: Int): Key? {
|
||||
if (mKeyboard == null) {
|
||||
return null
|
||||
}
|
||||
val sortedKeys = mKeyboard!!.sortedKeys
|
||||
val keyboard = mKeyboard ?: return null
|
||||
val sortedKeys = keyboard.sortedKeys
|
||||
// Use a virtual view id as an index of the sorted keys list.
|
||||
return if (virtualViewId >= 0 && virtualViewId < sortedKeys.size) {
|
||||
sortedKeys[virtualViewId]
|
||||
|
@ -68,10 +65,8 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
}
|
||||
|
||||
private fun getVirtualViewIdOf(key: Key): Int {
|
||||
if (mKeyboard == null) {
|
||||
return View.NO_ID
|
||||
}
|
||||
val sortedKeys = mKeyboard!!.sortedKeys
|
||||
val keyboard = mKeyboard ?: return View.NO_ID
|
||||
val sortedKeys = keyboard.sortedKeys
|
||||
val size = sortedKeys.size
|
||||
for (index in 0 until size) {
|
||||
if (sortedKeys[index] === key) { // Use an index of the sorted keys list as a virtual view id.
|
||||
|
@ -94,7 +89,7 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
val virtualViewId = getVirtualViewIdOf(key)
|
||||
val keyDescription = getKeyDescription(key)
|
||||
val event = AccessibilityUtils.obtainEvent(eventType)
|
||||
event.packageName = mKeyboardView!!.context.packageName
|
||||
event.packageName = mKeyboardView.context.packageName
|
||||
event.className = key.javaClass.name
|
||||
event.contentDescription = keyDescription
|
||||
event.isEnabled = true
|
||||
|
@ -109,8 +104,8 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
return
|
||||
}
|
||||
// Start hovering on the key. Because our accessibility model is lift-to-type, we should
|
||||
// report the node info without click and long click actions to avoid unnecessary
|
||||
// announcements.
|
||||
// report the node info without click and long click actions to avoid unnecessary
|
||||
// announcements.
|
||||
mHoveringNodeId = id
|
||||
// Invalidate the node info of the key.
|
||||
sendAccessibilityEventForKey(key, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)
|
||||
|
@ -120,7 +115,7 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
fun onHoverExitFrom(key: Key) {
|
||||
mHoveringNodeId = UNDEFINED
|
||||
// Invalidate the node info of the key to be able to revert the change we have done
|
||||
// in {@link #onHoverEnterTo(Key)}.
|
||||
// in {@link #onHoverEnterTo(Key)}.
|
||||
sendAccessibilityEventForKey(key, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)
|
||||
sendAccessibilityEventForKey(key, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT)
|
||||
}
|
||||
|
@ -152,13 +147,15 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
if (virtualViewId == UNDEFINED) {
|
||||
return null
|
||||
}
|
||||
if (virtualViewId == View.NO_ID) { // We are requested to create an AccessibilityNodeInfo describing
|
||||
// this View, i.e. the root of the virtual sub-tree.
|
||||
val keyboard = mKeyboard ?: return null
|
||||
if (virtualViewId == View.NO_ID) {
|
||||
// We are requested to create an AccessibilityNodeInfo describing
|
||||
// this View, i.e. the root of the virtual sub-tree.
|
||||
val rootInfo = AccessibilityNodeInfoCompat.obtain(mKeyboardView)
|
||||
ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView!!, rootInfo)
|
||||
ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView, rootInfo)
|
||||
updateParentLocation()
|
||||
// Add the virtual children of the root View.
|
||||
val sortedKeys = mKeyboard!!.sortedKeys
|
||||
val sortedKeys = keyboard.sortedKeys
|
||||
val size = sortedKeys.size
|
||||
for (index in 0 until size) {
|
||||
val key = sortedKeys[index]
|
||||
|
@ -180,12 +177,11 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
val boundsInParent = key.hitBox
|
||||
// Calculate the key's in-screen bounds.
|
||||
mTempBoundsInScreen.set(boundsInParent)
|
||||
mTempBoundsInScreen.offset(
|
||||
CoordinateUtils.x(mParentLocation), CoordinateUtils.y(mParentLocation))
|
||||
mTempBoundsInScreen.offset(CoordinateUtils.x(mParentLocation), CoordinateUtils.y(mParentLocation))
|
||||
val boundsInScreen = mTempBoundsInScreen
|
||||
// Obtain and initialize an AccessibilityNodeInfo with information about the virtual view.
|
||||
val info = AccessibilityNodeInfoCompat.obtain()
|
||||
info.packageName = mKeyboardView!!.context.packageName
|
||||
info.packageName = mKeyboardView.context.packageName
|
||||
info.className = key.javaClass.name
|
||||
info.contentDescription = keyDescription
|
||||
info.setBoundsInParent(boundsInParent)
|
||||
|
@ -195,7 +191,7 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
info.isEnabled = key.isEnabled
|
||||
info.isVisibleToUser = true
|
||||
// Don't add ACTION_CLICK and ACTION_LONG_CLOCK actions while hovering on the key.
|
||||
// See {@link #onHoverEnterTo(Key)} and {@link #onHoverExitFrom(Key)}.
|
||||
// See {@link #onHoverEnterTo(Key)} and {@link #onHoverExitFrom(Key)}.
|
||||
if (virtualViewId != mHoveringNodeId) {
|
||||
info.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK)
|
||||
if (key.isLongPressEnabled) {
|
||||
|
@ -227,14 +223,12 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
return when (action) {
|
||||
AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS -> {
|
||||
mAccessibilityFocusedView = getVirtualViewIdOf(key)
|
||||
sendAccessibilityEventForKey(
|
||||
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
|
||||
sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
|
||||
true
|
||||
}
|
||||
AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS -> {
|
||||
mAccessibilityFocusedView = UNDEFINED
|
||||
sendAccessibilityEventForKey(
|
||||
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED)
|
||||
sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED)
|
||||
true
|
||||
}
|
||||
AccessibilityNodeInfoCompat.ACTION_CLICK -> {
|
||||
|
@ -269,14 +263,13 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
* @return The context-specific description of the key.
|
||||
*/
|
||||
private fun getKeyDescription(key: Key): String? {
|
||||
val editorInfo = mKeyboard!!.mId.mEditorInfo
|
||||
val editorInfo = mKeyboard?.mId?.mEditorInfo
|
||||
val shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo)
|
||||
val currentSettings = Settings.getInstance().current
|
||||
val keyCodeDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
|
||||
mKeyboardView!!.context, mKeyboard, key, shouldObscure)
|
||||
mKeyboardView.context, mKeyboard, key, shouldObscure)
|
||||
return if (currentSettings.isWordSeparator(key.code)) {
|
||||
mAccessibilityUtils.getAutoCorrectionDescription(
|
||||
keyCodeDescription, shouldObscure)
|
||||
mAccessibilityUtils.getAutoCorrectionDescription(keyCodeDescription, shouldObscure)
|
||||
} else keyCodeDescription
|
||||
}
|
||||
|
||||
|
@ -284,7 +277,7 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
* Updates the parent's on-screen location.
|
||||
*/
|
||||
private fun updateParentLocation() {
|
||||
mKeyboardView!!.getLocationOnScreen(mParentLocation)
|
||||
mKeyboardView.getLocationOnScreen(mParentLocation)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -293,13 +286,4 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView?>(keyboardView: KV,
|
|||
private const val UNDEFINED = Int.MAX_VALUE
|
||||
}
|
||||
|
||||
init {
|
||||
mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.instance
|
||||
mAccessibilityUtils = AccessibilityUtils.instance
|
||||
mKeyboardView = keyboardView
|
||||
mDelegate = delegate
|
||||
// Since this class is constructed lazily, we might not get a subsequent
|
||||
// call to setKeyboard() and therefore need to call it now.
|
||||
setKeyboard(keyboardView!!.keyboard)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,33 +14,18 @@ import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils
|
|||
* This class represents a delegate that can be registered in [MainKeyboardView] to enhance
|
||||
* accessibility support via composition rather via inheritance.
|
||||
*/
|
||||
class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
||||
keyDetector: KeyDetector) : KeyboardAccessibilityDelegate<MainKeyboardView?>(mainKeyboardView, keyDetector), LongPressTimerCallback {
|
||||
companion object {
|
||||
private val TAG = MainKeyboardAccessibilityDelegate::class.java.simpleName
|
||||
/** Map of keyboard modes to resource IDs. */
|
||||
private val KEYBOARD_MODE_RES_IDS = SparseIntArray()
|
||||
private const val KEYBOARD_IS_HIDDEN = -1
|
||||
|
||||
init {
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATE, R.string.keyboard_mode_date)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATETIME, R.string.keyboard_mode_date_time)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_EMAIL, R.string.keyboard_mode_email)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_IM, R.string.keyboard_mode_im)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_NUMBER, R.string.keyboard_mode_number)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_PHONE, R.string.keyboard_mode_phone)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TEXT, R.string.keyboard_mode_text)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TIME, R.string.keyboard_mode_time)
|
||||
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_URL, R.string.keyboard_mode_url)
|
||||
}
|
||||
}
|
||||
|
||||
class MainKeyboardAccessibilityDelegate(
|
||||
mainKeyboardView: MainKeyboardView,
|
||||
keyDetector: KeyDetector
|
||||
) : KeyboardAccessibilityDelegate<MainKeyboardView>(mainKeyboardView, keyDetector), LongPressTimerCallback {
|
||||
/** The most recently set keyboard mode. */
|
||||
private var mLastKeyboardMode = KEYBOARD_IS_HIDDEN
|
||||
// The rectangle region to ignore hover events.
|
||||
private val mBoundsToIgnoreHoverEvent = Rect()
|
||||
private val mAccessibilityLongPressTimer: AccessibilityLongPressTimer// Since this method is called even when accessibility is off, make sure
|
||||
// to check the state before announcing anything.
|
||||
private val mAccessibilityLongPressTimer = AccessibilityLongPressTimer(this /* callback */, mainKeyboardView.context)
|
||||
|
||||
// Since this method is called even when accessibility is off, make sure
|
||||
// to check the state before announcing anything.
|
||||
// Announce the language name only when the language is changed.
|
||||
// Announce the mode only when the mode is changed.
|
||||
// Announce the keyboard type only when the type is changed.
|
||||
|
@ -58,7 +43,7 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
val lastKeyboardMode = mLastKeyboardMode
|
||||
mLastKeyboardMode = keyboard.mId.mMode
|
||||
// Since this method is called even when accessibility is off, make sure
|
||||
// to check the state before announcing anything.
|
||||
// to check the state before announcing anything.
|
||||
if (!AccessibilityUtils.instance.isAccessibilityEnabled) {
|
||||
return
|
||||
}
|
||||
|
@ -107,7 +92,7 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
* @param keyboard The new keyboard.
|
||||
*/
|
||||
private fun announceKeyboardMode(keyboard: Keyboard) {
|
||||
val context = mKeyboardView!!.context
|
||||
val context = mKeyboardView.context
|
||||
val modeTextResId = KEYBOARD_MODE_RES_IDS[keyboard.mId.mMode]
|
||||
if (modeTextResId == 0) {
|
||||
return
|
||||
|
@ -129,22 +114,25 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
resId = when (keyboard.mId.mElementId) {
|
||||
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET -> {
|
||||
if (lastElementId == KeyboardId.ELEMENT_ALPHABET
|
||||
|| lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { // Transition between alphabet mode and automatic shifted mode should be silently
|
||||
// ignored because it can be determined by each key's talk back announce.
|
||||
|| lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
|
||||
// Transition between alphabet mode and automatic shifted mode should be silently
|
||||
// ignored because it can be determined by each key's talk back announce.
|
||||
return
|
||||
}
|
||||
R.string.spoken_description_mode_alpha
|
||||
}
|
||||
KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED -> {
|
||||
if (lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { // Resetting automatic shifted mode by pressing the shift key causes the transition
|
||||
// from automatic shifted to manual shifted that should be silently ignored.
|
||||
if (lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
|
||||
// Resetting automatic shifted mode by pressing the shift key causes the transition
|
||||
// from automatic shifted to manual shifted that should be silently ignored.
|
||||
return
|
||||
}
|
||||
R.string.spoken_description_shiftmode_on
|
||||
}
|
||||
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED -> {
|
||||
if (lastElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) { // Resetting caps locked mode by pressing the shift key causes the transition
|
||||
// from shift locked to shift lock shifted that should be silently ignored.
|
||||
if (lastElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) {
|
||||
// Resetting caps locked mode by pressing the shift key causes the transition
|
||||
// from shift locked to shift lock shifted that should be silently ignored.
|
||||
return
|
||||
}
|
||||
R.string.spoken_description_shiftmode_locked
|
||||
|
@ -169,12 +157,13 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
override fun performClickOn(key: Key) {
|
||||
val x = key.hitBox.centerX()
|
||||
val y = key.hitBox.centerY()
|
||||
if (KeyboardAccessibilityDelegate.DEBUG_HOVER) {
|
||||
if (DEBUG_HOVER) {
|
||||
Log.d(TAG, "performClickOn: key=" + key
|
||||
+ " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y))
|
||||
}
|
||||
if (mBoundsToIgnoreHoverEvent.contains(x, y)) { // This hover exit event points to the key that should be ignored.
|
||||
// Clear the ignoring region to handle further hover events.
|
||||
if (mBoundsToIgnoreHoverEvent.contains(x, y)) {
|
||||
// This hover exit event points to the key that should be ignored.
|
||||
// Clear the ignoring region to handle further hover events.
|
||||
mBoundsToIgnoreHoverEvent.setEmpty()
|
||||
return
|
||||
}
|
||||
|
@ -184,7 +173,7 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
override fun onHoverEnterTo(key: Key) {
|
||||
val x = key.hitBox.centerX()
|
||||
val y = key.hitBox.centerY()
|
||||
if (KeyboardAccessibilityDelegate.DEBUG_HOVER) {
|
||||
if (DEBUG_HOVER) {
|
||||
Log.d(TAG, "onHoverEnterTo: key=" + key
|
||||
+ " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y))
|
||||
}
|
||||
|
@ -193,7 +182,7 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
return
|
||||
}
|
||||
// This hover enter event points to the key that isn't in the ignoring region.
|
||||
// Further hover events should be handled.
|
||||
// Further hover events should be handled.
|
||||
mBoundsToIgnoreHoverEvent.setEmpty()
|
||||
super.onHoverEnterTo(key)
|
||||
if (key.isLongPressEnabled) {
|
||||
|
@ -204,7 +193,7 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
override fun onHoverExitFrom(key: Key) {
|
||||
val x = key.hitBox.centerX()
|
||||
val y = key.hitBox.centerY()
|
||||
if (KeyboardAccessibilityDelegate.DEBUG_HOVER) {
|
||||
if (DEBUG_HOVER) {
|
||||
Log.d(TAG, "onHoverExitFrom: key=" + key
|
||||
+ " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y))
|
||||
}
|
||||
|
@ -213,43 +202,56 @@ class MainKeyboardAccessibilityDelegate(mainKeyboardView: MainKeyboardView,
|
|||
}
|
||||
|
||||
override fun performLongClickOn(key: Key) {
|
||||
if (KeyboardAccessibilityDelegate.Companion.DEBUG_HOVER) {
|
||||
if (DEBUG_HOVER) {
|
||||
Log.d(TAG, "performLongClickOn: key=$key")
|
||||
}
|
||||
val tracker = PointerTracker.getPointerTracker(KeyboardAccessibilityDelegate.Companion.HOVER_EVENT_POINTER_ID)
|
||||
val tracker = PointerTracker.getPointerTracker(HOVER_EVENT_POINTER_ID)
|
||||
val eventTime = SystemClock.uptimeMillis()
|
||||
val x = key.hitBox.centerX()
|
||||
val y = key.hitBox.centerY()
|
||||
val downEvent = MotionEvent.obtain(
|
||||
eventTime, eventTime, MotionEvent.ACTION_DOWN, x.toFloat(), y.toFloat(), 0 /* metaState */)
|
||||
val downEvent = MotionEvent.obtain(eventTime, eventTime, MotionEvent.ACTION_DOWN, x.toFloat(), y.toFloat(), 0)
|
||||
// Inject a fake down event to {@link PointerTracker} to handle a long press correctly.
|
||||
tracker.processMotionEvent(downEvent, mKeyDetector)
|
||||
downEvent.recycle()
|
||||
// Invoke {@link PointerTracker#onLongPressed()} as if a long press timeout has passed.
|
||||
tracker.onLongPressed()
|
||||
// If {@link Key#hasNoPanelAutoMoreKeys()} is true (such as "0 +" key on the phone layout)
|
||||
// or a key invokes IME switcher dialog, we should just ignore the next
|
||||
// {@link #onRegisterHoverKey(Key,MotionEvent)}. It can be determined by whether
|
||||
// {@link PointerTracker} is in operation or not.
|
||||
if (tracker.isInOperation) { // This long press shows a more keys keyboard and further hover events should be
|
||||
// handled.
|
||||
// or a key invokes IME switcher dialog, we should just ignore the next
|
||||
// {@link #onRegisterHoverKey(Key,MotionEvent)}. It can be determined by whether
|
||||
// {@link PointerTracker} is in operation or not.
|
||||
if (tracker.isInOperation) {
|
||||
// This long press shows a more keys keyboard and further hover events should be
|
||||
// handled.
|
||||
mBoundsToIgnoreHoverEvent.setEmpty()
|
||||
return
|
||||
}
|
||||
// This long press has handled at {@link MainKeyboardView#onLongPress(PointerTracker)}.
|
||||
// We should ignore further hover events on this key.
|
||||
// We should ignore further hover events on this key.
|
||||
mBoundsToIgnoreHoverEvent.set(key.hitBox)
|
||||
if (key.hasNoPanelAutoMoreKey()) { // This long press has registered a code point without showing a more keys keyboard.
|
||||
// We should talk back the code point if possible.
|
||||
val codePointOfNoPanelAutoMoreKey = key.moreKeys!![0].mCode
|
||||
if (key.hasNoPanelAutoMoreKey()) {
|
||||
// This long press has registered a code point without showing a more keys keyboard.
|
||||
// We should talk back the code point if possible.
|
||||
val codePointOfNoPanelAutoMoreKey = key.moreKeys?.get(0)?.mCode ?: return
|
||||
val text: String = KeyCodeDescriptionMapper.instance.getDescriptionForCodePoint(
|
||||
mKeyboardView!!.context, codePointOfNoPanelAutoMoreKey)!!
|
||||
text.let { sendWindowStateChanged(it) }
|
||||
mKeyboardView.context, codePointOfNoPanelAutoMoreKey) ?: return
|
||||
sendWindowStateChanged(text)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
mAccessibilityLongPressTimer = AccessibilityLongPressTimer(
|
||||
this /* callback */, mainKeyboardView.context)
|
||||
companion object {
|
||||
private val TAG = MainKeyboardAccessibilityDelegate::class.java.simpleName
|
||||
/** Map of keyboard modes to resource IDs. */
|
||||
private val KEYBOARD_MODE_RES_IDS = SparseIntArray().apply {
|
||||
put(KeyboardId.MODE_DATE, R.string.keyboard_mode_date)
|
||||
put(KeyboardId.MODE_DATETIME, R.string.keyboard_mode_date_time)
|
||||
put(KeyboardId.MODE_EMAIL, R.string.keyboard_mode_email)
|
||||
put(KeyboardId.MODE_IM, R.string.keyboard_mode_im)
|
||||
put(KeyboardId.MODE_NUMBER, R.string.keyboard_mode_number)
|
||||
put(KeyboardId.MODE_PHONE, R.string.keyboard_mode_phone)
|
||||
put(KeyboardId.MODE_TEXT, R.string.keyboard_mode_text)
|
||||
put(KeyboardId.MODE_TIME, R.string.keyboard_mode_time)
|
||||
put(KeyboardId.MODE_URL, R.string.keyboard_mode_url)
|
||||
}
|
||||
private const val KEYBOARD_IS_HIDDEN = -1
|
||||
}
|
||||
}
|
|
@ -11,8 +11,10 @@ import org.dslul.openboard.inputmethod.keyboard.PointerTracker
|
|||
* This class represents a delegate that can be registered in [MoreKeysKeyboardView] to
|
||||
* enhance accessibility support via composition rather via inheritance.
|
||||
*/
|
||||
class MoreKeysKeyboardAccessibilityDelegate(moreKeysKeyboardView: MoreKeysKeyboardView,
|
||||
keyDetector: KeyDetector) : KeyboardAccessibilityDelegate<MoreKeysKeyboardView?>(moreKeysKeyboardView, keyDetector) {
|
||||
class MoreKeysKeyboardAccessibilityDelegate(
|
||||
moreKeysKeyboardView: MoreKeysKeyboardView,
|
||||
keyDetector: KeyDetector
|
||||
) : KeyboardAccessibilityDelegate<MoreKeysKeyboardView>(moreKeysKeyboardView, keyDetector) {
|
||||
private val mMoreKeysKeyboardValidBounds = Rect()
|
||||
private var mOpenAnnounceResId = 0
|
||||
private var mCloseAnnounceResId = 0
|
||||
|
@ -42,7 +44,7 @@ class MoreKeysKeyboardAccessibilityDelegate(moreKeysKeyboardView: MoreKeysKeyboa
|
|||
val y = event.getY(actionIndex).toInt()
|
||||
val pointerId = event.getPointerId(actionIndex)
|
||||
val eventTime = event.eventTime
|
||||
mKeyboardView!!.onDownEvent(x, y, pointerId, eventTime)
|
||||
mKeyboardView.onDownEvent(x, y, pointerId, eventTime)
|
||||
}
|
||||
|
||||
override fun onHoverMove(event: MotionEvent) {
|
||||
|
@ -52,7 +54,7 @@ class MoreKeysKeyboardAccessibilityDelegate(moreKeysKeyboardView: MoreKeysKeyboa
|
|||
val y = event.getY(actionIndex).toInt()
|
||||
val pointerId = event.getPointerId(actionIndex)
|
||||
val eventTime = event.eventTime
|
||||
mKeyboardView!!.onMoveEvent(x, y, pointerId, eventTime)
|
||||
mKeyboardView.onMoveEvent(x, y, pointerId, eventTime)
|
||||
}
|
||||
|
||||
override fun onHoverExit(event: MotionEvent) {
|
||||
|
@ -70,20 +72,21 @@ class MoreKeysKeyboardAccessibilityDelegate(moreKeysKeyboardView: MoreKeysKeyboa
|
|||
val pointerId = event.getPointerId(actionIndex)
|
||||
val eventTime = event.eventTime
|
||||
// A hover exit event at one pixel width or height area on the edges of more keys keyboard
|
||||
// are treated as closing.
|
||||
mMoreKeysKeyboardValidBounds[0, 0, mKeyboardView!!.width] = mKeyboardView.height
|
||||
// are treated as closing.
|
||||
mMoreKeysKeyboardValidBounds[0, 0, mKeyboardView.width] = mKeyboardView.height
|
||||
mMoreKeysKeyboardValidBounds.inset(CLOSING_INSET_IN_PIXEL, CLOSING_INSET_IN_PIXEL)
|
||||
if (mMoreKeysKeyboardValidBounds.contains(x, y)) { // Invoke {@link MoreKeysKeyboardView#onUpEvent(int,int,int,long)} as if this hover
|
||||
// exit event selects a key.
|
||||
if (mMoreKeysKeyboardValidBounds.contains(x, y)) {
|
||||
// Invoke {@link MoreKeysKeyboardView#onUpEvent(int,int,int,long)} as if this hover
|
||||
// exit event selects a key.
|
||||
mKeyboardView.onUpEvent(x, y, pointerId, eventTime)
|
||||
// TODO: Should fix this reference. This is a hack to clear the state of
|
||||
// {@link PointerTracker}.
|
||||
// {@link PointerTracker}.
|
||||
PointerTracker.dismissAllMoreKeysPanels()
|
||||
return
|
||||
}
|
||||
// Close the more keys keyboard.
|
||||
// TODO: Should fix this reference. This is a hack to clear the state of
|
||||
// {@link PointerTracker}.
|
||||
// TODO: Should fix this reference. This is a hack to clear the state of
|
||||
// {@link PointerTracker}.
|
||||
PointerTracker.dismissAllMoreKeysPanels()
|
||||
}
|
||||
|
||||
|
@ -91,4 +94,4 @@ class MoreKeysKeyboardAccessibilityDelegate(moreKeysKeyboardView: MoreKeysKeyboa
|
|||
private val TAG = MoreKeysKeyboardAccessibilityDelegate::class.java.simpleName
|
||||
private const val CLOSING_INSET_IN_PIXEL = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ open class CursorAnchorInfoCompatWrapper internal constructor() {
|
|||
*/
|
||||
const val FLAG_IS_RTL = 0x04
|
||||
|
||||
@kotlin.jvm.JvmStatic
|
||||
@JvmStatic
|
||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||
fun wrap(instance: CursorAnchorInfo?): CursorAnchorInfoCompatWrapper? {
|
||||
return if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
|
||||
|
|
|
@ -6,12 +6,9 @@ import java.util.*
|
|||
object EditorInfoCompatUtils {
|
||||
// Note that EditorInfo.IME_FLAG_FORCE_ASCII has been introduced
|
||||
// in API level 16 (Build.VERSION_CODES.JELLY_BEAN).
|
||||
private val FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField(
|
||||
EditorInfo::class.java, "IME_FLAG_FORCE_ASCII")
|
||||
private val OBJ_IME_FLAG_FORCE_ASCII: Int? = CompatUtils.getFieldValue(
|
||||
null /* receiver */, null /* defaultValue */, FIELD_IME_FLAG_FORCE_ASCII) as Int
|
||||
private val FIELD_HINT_LOCALES = CompatUtils.getField(
|
||||
EditorInfo::class.java, "hintLocales")
|
||||
private val FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField(EditorInfo::class.java, "IME_FLAG_FORCE_ASCII")
|
||||
private val OBJ_IME_FLAG_FORCE_ASCII: Int? = CompatUtils.getFieldValue(null, null, FIELD_IME_FLAG_FORCE_ASCII) as? Int
|
||||
private val FIELD_HINT_LOCALES = CompatUtils.getField(EditorInfo::class.java, "hintLocales")
|
||||
|
||||
@JvmStatic
|
||||
fun hasFlagForceAscii(imeOptions: Int): Boolean {
|
||||
|
@ -20,8 +17,7 @@ object EditorInfoCompatUtils {
|
|||
|
||||
@JvmStatic
|
||||
fun imeActionName(imeOptions: Int): String {
|
||||
val actionId = imeOptions and EditorInfo.IME_MASK_ACTION
|
||||
return when (actionId) {
|
||||
return when (val actionId = imeOptions and EditorInfo.IME_MASK_ACTION) {
|
||||
EditorInfo.IME_ACTION_UNSPECIFIED -> "actionUnspecified"
|
||||
EditorInfo.IME_ACTION_NONE -> "actionNone"
|
||||
EditorInfo.IME_ACTION_GO -> "actionGo"
|
||||
|
@ -57,8 +53,7 @@ object EditorInfoCompatUtils {
|
|||
if (editorInfo == null) {
|
||||
return null
|
||||
}
|
||||
val localeList = CompatUtils.getFieldValue(editorInfo, null, FIELD_HINT_LOCALES)
|
||||
?: return null
|
||||
val localeList = CompatUtils.getFieldValue(editorInfo, null, FIELD_HINT_LOCALES) ?: return null
|
||||
return if (LocaleListCompatUtils.isEmpty(localeList)) {
|
||||
null
|
||||
} else LocaleListCompatUtils[localeList, 0]
|
||||
|
|
|
@ -8,8 +8,7 @@ import java.security.NoSuchAlgorithmException
|
|||
object MD5Calculator {
|
||||
@Throws(IOException::class)
|
||||
fun checksum(`in`: InputStream): String? { // This code from the Android documentation for MessageDigest. Nearly verbatim.
|
||||
val digester: MessageDigest
|
||||
digester = try {
|
||||
val digester: MessageDigest = try {
|
||||
MessageDigest.getInstance("MD5")
|
||||
} catch (e: NoSuchAlgorithmException) {
|
||||
return null // Platform does not support MD5 : can't check, so return null
|
||||
|
@ -26,4 +25,4 @@ object MD5Calculator {
|
|||
}
|
||||
return s.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,10 +88,10 @@ class InputTransaction(// Initial conditions
|
|||
|
||||
companion object {
|
||||
// UPDATE_LATER is stronger than UPDATE_NOW. The reason for this is, if we have to update later,
|
||||
// it's because something will change that we can't evaluate now, which means that even if we
|
||||
// re-evaluate now we'll have to do it again later. The only case where that wouldn't apply
|
||||
// would be if we needed to update now to find out the new state right away, but then we
|
||||
// can't do it with this deferred mechanism anyway.
|
||||
// it's because something will change that we can't evaluate now, which means that even if we
|
||||
// re-evaluate now we'll have to do it again later. The only case where that wouldn't apply
|
||||
// would be if we needed to update now to find out the new state right away, but then we
|
||||
// can't do it with this deferred mechanism anyway.
|
||||
const val SHIFT_NO_UPDATE = 0
|
||||
const val SHIFT_UPDATE_NOW = 1
|
||||
const val SHIFT_UPDATE_LATER = 2
|
||||
|
|
|
@ -173,14 +173,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
keyboardView.setKeyboard(newKeyboard);
|
||||
mCurrentInputView.setKeyboardTopPadding(newKeyboard.mTopPadding);
|
||||
keyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn);
|
||||
keyboardView.setKeyPreviewAnimationParams(
|
||||
currentSettingsValues.mHasCustomKeyPreviewAnimationParams,
|
||||
currentSettingsValues.mKeyPreviewShowUpStartXScale,
|
||||
currentSettingsValues.mKeyPreviewShowUpStartYScale,
|
||||
currentSettingsValues.mKeyPreviewShowUpDuration,
|
||||
currentSettingsValues.mKeyPreviewDismissEndXScale,
|
||||
currentSettingsValues.mKeyPreviewDismissEndYScale,
|
||||
currentSettingsValues.mKeyPreviewDismissDuration);
|
||||
keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady());
|
||||
final boolean subtypeChanged = (oldKeyboard == null)
|
||||
|| !newKeyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
|
||||
|
|
|
@ -304,7 +304,7 @@ public class KeyboardView extends View {
|
|||
|
||||
mShowsHints = Settings.getInstance().getCurrent().mShowsHints;
|
||||
final float scale = Settings.getInstance().getCurrent().mKeyboardHeightScale;
|
||||
mIconScaleFactor = scale < 0.8f ? scale + 0.2f : scale;
|
||||
mIconScaleFactor = scale < 0.8f ? scale + 0.2f : 1f;
|
||||
final Paint paint = mPaint;
|
||||
final Drawable background = getBackground();
|
||||
// Calculate clip region and set.
|
||||
|
|
|
@ -92,9 +92,6 @@ import java.util.WeakHashMap;
|
|||
* @attr ref R.styleable#MainKeyboardView_keyPreviewLayout
|
||||
* @attr ref R.styleable#MainKeyboardView_keyPreviewOffset
|
||||
* @attr ref R.styleable#MainKeyboardView_keyPreviewHeight
|
||||
* @attr ref R.styleable#MainKeyboardView_keyPreviewLingerTimeout
|
||||
* @attr ref R.styleable#MainKeyboardView_keyPreviewShowUpAnimator
|
||||
* @attr ref R.styleable#MainKeyboardView_keyPreviewDismissAnimator
|
||||
* @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardLayout
|
||||
* @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardForActionLayout
|
||||
* @attr ref R.styleable#MainKeyboardView_backgroundDimAlpha
|
||||
|
@ -422,27 +419,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
|
|||
mKeyPreviewDrawParams.setPopupEnabled(previewEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the key preview popup animations and set animations' parameters.
|
||||
*
|
||||
* @param hasCustomAnimationParams false to use the default key preview popup animations
|
||||
* specified by keyPreviewShowUpAnimator and keyPreviewDismissAnimator attributes.
|
||||
* true to override the default animations with the specified parameters.
|
||||
* @param showUpStartXScale from this x-scale the show up animation will start.
|
||||
* @param showUpStartYScale from this y-scale the show up animation will start.
|
||||
* @param showUpDuration the duration of the show up animation in milliseconds.
|
||||
* @param dismissEndXScale to this x-scale the dismiss animation will end.
|
||||
* @param dismissEndYScale to this y-scale the dismiss animation will end.
|
||||
* @param dismissDuration the duration of the dismiss animation in milliseconds.
|
||||
*/
|
||||
public void setKeyPreviewAnimationParams(final boolean hasCustomAnimationParams,
|
||||
final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
|
||||
final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
|
||||
mKeyPreviewDrawParams.setAnimationParams(hasCustomAnimationParams,
|
||||
showUpStartXScale, showUpStartYScale, showUpDuration,
|
||||
dismissEndXScale, dismissEndYScale, dismissDuration);
|
||||
}
|
||||
|
||||
private void locatePreviewPlacerView() {
|
||||
getLocationInWindow(mOriginCoords);
|
||||
mDrawingPreviewPlacerView.setKeyboardViewGeometry(mOriginCoords, getWidth(), getHeight());
|
||||
|
|
|
@ -95,6 +95,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
|
|||
setOnTouchListener(this@ClipboardHistoryView)
|
||||
setOnClickListener(this@ClipboardHistoryView)
|
||||
colorFilter = colors.keyTextFilter
|
||||
colors.setBackgroundColor(background, BackgroundType.SUGGESTION)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public final class AlphabetShiftState {
|
||||
private static final String TAG = AlphabetShiftState.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
|
@ -112,6 +114,7 @@ public final class AlphabetShiftState {
|
|||
return mState == MANUAL_SHIFTED_FROM_AUTO;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(mState);
|
||||
|
|
|
@ -46,7 +46,7 @@ public final class DrawingPreviewPlacerView extends RelativeLayout {
|
|||
}
|
||||
|
||||
public void addPreview(final AbstractDrawingPreview preview) {
|
||||
if (mPreviews.indexOf(preview) < 0) {
|
||||
if (!mPreviews.contains(preview)) {
|
||||
mPreviews.add(preview);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setPreviewPosition(final PointerTracker tracker) {
|
||||
public void setPreviewPosition(@NonNull final PointerTracker tracker) {
|
||||
if (!isPreviewEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
|
|||
* @param canvas The canvas where preview text is drawn.
|
||||
*/
|
||||
@Override
|
||||
public void drawPreview(final Canvas canvas) {
|
||||
public void drawPreview(@NonNull final Canvas canvas) {
|
||||
if (!isPreviewEnabled() || mSuggestedWords.isEmpty()
|
||||
|| TextUtils.isEmpty(mSuggestedWords.getWord(0))) {
|
||||
return;
|
||||
|
@ -161,8 +161,6 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
|
|||
}
|
||||
final String text = mSuggestedWords.getWord(0);
|
||||
|
||||
final RectF rectangle = mGesturePreviewRectangle;
|
||||
|
||||
final int textHeight = mParams.mGesturePreviewTextHeight;
|
||||
final float textWidth = mParams.getTextPaint().measureText(text);
|
||||
final float hPad = mParams.mGesturePreviewHorizontalPadding;
|
||||
|
@ -175,7 +173,7 @@ public class GestureFloatingTextDrawingPreview extends AbstractDrawingPreview {
|
|||
mParams.mDisplayWidth - rectWidth);
|
||||
final float rectY = CoordinateUtils.y(mLastPointerCoords)
|
||||
- mParams.mGesturePreviewTextOffset - rectHeight;
|
||||
rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
|
||||
mGesturePreviewRectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
|
||||
|
||||
mPreviewTextX = (int)(rectX + hPad + textWidth / 2.0f);
|
||||
mPreviewTextY = (int)(rectY + vPad) + textHeight;
|
||||
|
|
|
@ -146,7 +146,7 @@ public final class GestureStrokeRecognitionPoints {
|
|||
}
|
||||
|
||||
// TODO: Make this package private
|
||||
public final boolean isStartOfAGesture() {
|
||||
public boolean isStartOfAGesture() {
|
||||
if (!hasDetectedFastMove()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ public final class GestureStrokeRecognitionPoints {
|
|||
mLastMajorEventY = y;
|
||||
}
|
||||
|
||||
private final boolean hasDetectedFastMove() {
|
||||
private boolean hasDetectedFastMove() {
|
||||
return mDetectFastMoveTime > 0;
|
||||
}
|
||||
|
||||
|
@ -303,18 +303,18 @@ public final class GestureStrokeRecognitionPoints {
|
|||
}
|
||||
|
||||
// TODO: Make this package private
|
||||
public final boolean hasRecognitionTimePast(
|
||||
public boolean hasRecognitionTimePast(
|
||||
final long currentTime, final long lastRecognitionTime) {
|
||||
return currentTime > lastRecognitionTime + mRecognitionParams.mRecognitionMinimumTime;
|
||||
}
|
||||
|
||||
// TODO: Make this package private
|
||||
public final void appendAllBatchPoints(final InputPointers out) {
|
||||
public void appendAllBatchPoints(final InputPointers out) {
|
||||
appendBatchPoints(out, getLength());
|
||||
}
|
||||
|
||||
// TODO: Make this package private
|
||||
public final void appendIncrementalBatchPoints(final InputPointers out) {
|
||||
public void appendIncrementalBatchPoints(final InputPointers out) {
|
||||
appendBatchPoints(out, mIncrementalRecognitionSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
|||
import android.content.res.TypedArray;
|
||||
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.common.Colors;
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
||||
|
||||
/**
|
||||
|
|
|
@ -102,9 +102,8 @@ final class GestureTrailDrawingPoints {
|
|||
eventTimes[i] -= elapsedTime;
|
||||
}
|
||||
final int[] xCoords = mXCoordinates.getPrimitiveArray();
|
||||
final int downIndex = trailSize;
|
||||
xCoords[downIndex] = markAsDownEvent(xCoords[downIndex]);
|
||||
mCurrentTimeBase = downTime - eventTimes[downIndex];
|
||||
xCoords[trailSize] = markAsDownEvent(xCoords[trailSize]);
|
||||
mCurrentTimeBase = downTime - eventTimes[trailSize];
|
||||
mCurrentStrokeId = strokeId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import android.graphics.Rect;
|
|||
import android.os.Handler;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dslul.openboard.inputmethod.keyboard.PointerTracker;
|
||||
|
||||
/**
|
||||
|
@ -56,7 +58,7 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview im
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setKeyboardViewGeometry(final int[] originCoords, final int width,
|
||||
public void setKeyboardViewGeometry(@NonNull final int[] originCoords, final int width,
|
||||
final int height) {
|
||||
super.setKeyboardViewGeometry(originCoords, width, height);
|
||||
mOffscreenOffsetY = (int)(height
|
||||
|
@ -127,7 +129,7 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview im
|
|||
* @param canvas The canvas where the preview is drawn.
|
||||
*/
|
||||
@Override
|
||||
public void drawPreview(final Canvas canvas) {
|
||||
public void drawPreview(@NonNull final Canvas canvas) {
|
||||
if (!isPreviewEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
@ -154,7 +156,7 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview im
|
|||
* @param tracker The new location of the preview is based on the points in PointerTracker.
|
||||
*/
|
||||
@Override
|
||||
public void setPreviewPosition(final PointerTracker tracker) {
|
||||
public void setPreviewPosition(@NonNull final PointerTracker tracker) {
|
||||
if (!isPreviewEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -16,14 +16,8 @@
|
|||
|
||||
package org.dslul.openboard.inputmethod.keyboard.internal;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.res.TypedArray;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
|
||||
|
@ -105,10 +99,4 @@ public final class KeyPreviewDrawParams {
|
|||
return mShowPopup;
|
||||
}
|
||||
|
||||
public void setAnimationParams(final boolean hasCustomAnimationParams,
|
||||
final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
|
||||
final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
|
||||
//TODO: remove
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public final class KeyboardIconsSet {
|
|||
NAME_SWITCH_ONEHANDED_KEY, R.styleable.Keyboard_iconSwitchOneHandedMode,
|
||||
};
|
||||
|
||||
private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
|
||||
private static final int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
|
||||
private static final String[] ICON_NAMES = new String[NUM_ICONS];
|
||||
private final Drawable[] mIcons = new Drawable[NUM_ICONS];
|
||||
private final int[] mIconResourceIds = new int[NUM_ICONS];
|
||||
|
|
|
@ -91,15 +91,12 @@ public class KeyboardParams {
|
|||
new TouchPositionCorrection();
|
||||
|
||||
// Comparator to sort {@link Key}s from top-left to bottom-right order.
|
||||
private static final Comparator<Key> ROW_COLUMN_COMPARATOR = new Comparator<Key>() {
|
||||
@Override
|
||||
public int compare(final Key lhs, final Key rhs) {
|
||||
if (lhs.getY() < rhs.getY()) return -1;
|
||||
if (lhs.getY() > rhs.getY()) return 1;
|
||||
if (lhs.getX() < rhs.getX()) return -1;
|
||||
if (lhs.getX() > rhs.getX()) return 1;
|
||||
return 0;
|
||||
}
|
||||
private static final Comparator<Key> ROW_COLUMN_COMPARATOR = (lhs, rhs) -> {
|
||||
if (lhs.getY() < rhs.getY()) return -1;
|
||||
if (lhs.getY() > rhs.getY()) return 1;
|
||||
if (lhs.getX() < rhs.getX()) return -1;
|
||||
if (lhs.getX() > rhs.getX()) return 1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
public KeyboardParams() {
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
|||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dslul.openboard.inputmethod.event.Event;
|
||||
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
||||
|
@ -73,8 +75,9 @@ public final class KeyboardState {
|
|||
|
||||
private final SwitchActions mSwitchActions;
|
||||
|
||||
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
|
||||
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
|
||||
private final ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
|
||||
private final ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
|
||||
private final AlphabetShiftState mAlphabetShiftState = new AlphabetShiftState();
|
||||
|
||||
// TODO: Merge {@link #mSwitchState}, {@link #mIsAlphabetMode}, {@link #mAlphabetShiftState},
|
||||
// {@link #mIsSymbolShifted}, {@link #mPrevMainKeyboardWasShiftLocked}, and
|
||||
|
@ -93,7 +96,6 @@ public final class KeyboardState {
|
|||
private static final int MODE_CLIPBOARD = 3;
|
||||
private static final int MODE_NUMPAD = 4;
|
||||
private int mMode = MODE_ALPHABET;
|
||||
private AlphabetShiftState mAlphabetShiftState = new AlphabetShiftState();
|
||||
private boolean mIsSymbolShifted;
|
||||
private boolean mPrevMainKeyboardWasShiftLocked;
|
||||
private boolean mPrevSymbolsKeyboardWasShifted;
|
||||
|
@ -111,6 +113,7 @@ public final class KeyboardState {
|
|||
public int mMode;
|
||||
public int mShiftMode;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
if (!mIsValid) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.dslul.openboard.inputmethod.latin.utils.RunInLocale;
|
|||
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public final class KeyboardTextsTable {
|
|||
return text;
|
||||
}
|
||||
// Validity check.
|
||||
if (index >= 0 && index < TEXTS_DEFAULT.length) {
|
||||
if (index < TEXTS_DEFAULT.length) {
|
||||
return TEXTS_DEFAULT[index];
|
||||
}
|
||||
// Throw exception for debugging purpose.
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.util.Log;
|
|||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Utilities for matrix operations. Don't instantiate objects inside this class to prevent
|
||||
|
@ -154,10 +155,10 @@ public class MatrixUtils {
|
|||
Log.d(TAG, "Dump matrix: " + title);
|
||||
Log.d(TAG, "/*---------------------");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < row; ++i) {
|
||||
for (float[] floats : a) {
|
||||
sb.setLength(0);
|
||||
for (int j = 0; j < column; ++j) {
|
||||
sb.append(String.format("%4f", a[i][j])).append(' ');
|
||||
sb.append(String.format(Locale.ROOT, "%4f", floats[j])).append(' ');
|
||||
}
|
||||
Log.d(TAG, sb.toString());
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/* package */ class ModifierKeyState {
|
||||
protected static final String TAG = ModifierKeyState.class.getSimpleName();
|
||||
protected static final boolean DEBUG = false;
|
||||
|
@ -67,6 +69,7 @@ import android.util.Log;
|
|||
return mState == CHORDING;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(mState);
|
||||
|
|
|
@ -30,7 +30,7 @@ public final class NonDistinctMultitouchHelper {
|
|||
private static final int MAIN_POINTER_TRACKER_ID = 0;
|
||||
private int mOldPointerCount = 1;
|
||||
private Key mOldKey;
|
||||
private int[] mLastCoords = CoordinateUtils.newInstance();
|
||||
private final int[] mLastCoords = CoordinateUtils.newInstance();
|
||||
|
||||
public void processMotionEvent(final MotionEvent me, final KeyDetector keyDetector) {
|
||||
final int pointerCount = me.getPointerCount();
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class PointerTrackerQueue {
|
||||
|
@ -176,10 +178,9 @@ public final class PointerTrackerQueue {
|
|||
|
||||
public boolean hasModifierKeyOlderThan(final Element pointer) {
|
||||
synchronized (mExpandableArrayOfActivePointers) {
|
||||
final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
|
||||
final int arraySize = mArraySize;
|
||||
for (int index = 0; index < arraySize; index++) {
|
||||
final Element element = expandableArray.get(index);
|
||||
final Element element = mExpandableArrayOfActivePointers.get(index);
|
||||
if (element == pointer) {
|
||||
return false; // Stop searching modifier key.
|
||||
}
|
||||
|
@ -193,10 +194,9 @@ public final class PointerTrackerQueue {
|
|||
|
||||
public boolean isAnyInDraggingFinger() {
|
||||
synchronized (mExpandableArrayOfActivePointers) {
|
||||
final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
|
||||
final int arraySize = mArraySize;
|
||||
for (int index = 0; index < arraySize; index++) {
|
||||
final Element element = expandableArray.get(index);
|
||||
final Element element = mExpandableArrayOfActivePointers.get(index);
|
||||
if (element.isInDraggingFinger()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -210,29 +210,28 @@ public final class PointerTrackerQueue {
|
|||
if (DEBUG) {
|
||||
Log.d(TAG, "cancelAllPointerTracker: " + this);
|
||||
}
|
||||
final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
|
||||
final int arraySize = mArraySize;
|
||||
for (int index = 0; index < arraySize; index++) {
|
||||
final Element element = expandableArray.get(index);
|
||||
final Element element = mExpandableArrayOfActivePointers.get(index);
|
||||
element.cancelTrackingForAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
synchronized (mExpandableArrayOfActivePointers) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
|
||||
final int arraySize = mArraySize;
|
||||
for (int index = 0; index < arraySize; index++) {
|
||||
final Element element = expandableArray.get(index);
|
||||
final Element element = mExpandableArrayOfActivePointers.get(index);
|
||||
if (sb.length() > 0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(element.toString());
|
||||
}
|
||||
return "[" + sb.toString() + "]";
|
||||
return "[" + sb + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.dslul.openboard.inputmethod.keyboard.internal;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/* package */ final class ShiftKeyState extends ModifierKeyState {
|
||||
private static final int PRESSING_ON_SHIFTED = 3; // both temporary shifted & shift locked
|
||||
private static final int IGNORING = 4;
|
||||
|
@ -53,6 +55,7 @@ import android.util.Log;
|
|||
return mState == IGNORING;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(mState);
|
||||
|
|
|
@ -21,6 +21,8 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dslul.openboard.inputmethod.keyboard.PointerTracker;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.common.CoordinateUtils;
|
||||
|
@ -79,7 +81,7 @@ public final class SlidingKeyInputDrawingPreview extends AbstractDrawingPreview
|
|||
* @param canvas The canvas where the preview is drawn.
|
||||
*/
|
||||
@Override
|
||||
public void drawPreview(final Canvas canvas) {
|
||||
public void drawPreview(@NonNull final Canvas canvas) {
|
||||
if (!isPreviewEnabled() || !mShowsSlidingKeyInputPreview) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ public class SmoothingUtils {
|
|||
Arrays.fill(m0[i], 0);
|
||||
for (int j = 0; j < COEFF_COUNT; ++j) {
|
||||
final int pow = i + j;
|
||||
for (int k = 0; k < N; ++k) {
|
||||
m0[i][j] += (float) Math.pow(xs[k], pow);
|
||||
for (float x : xs) {
|
||||
m0[i][j] += (float) Math.pow(x, pow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,9 @@ public abstract class UniqueKeysCache {
|
|||
@Override
|
||||
public void clear() {}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Key getUniqueKey(Key key) { return key; }
|
||||
public Key getUniqueKey(@NonNull Key key) { return key; }
|
||||
};
|
||||
|
||||
@NonNull
|
||||
|
@ -63,8 +64,9 @@ public abstract class UniqueKeysCache {
|
|||
mCache.clear();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Key getUniqueKey(final Key key) {
|
||||
public Key getUniqueKey(@NonNull final Key key) {
|
||||
if (!mEnabled) {
|
||||
return key;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ class KeyboardWrapperView @JvmOverloads constructor(
|
|||
val scale = Settings.getInstance().current.mKeyboardHeightScale
|
||||
// scale one-handed mode button height if keyboard height scale is < 80%
|
||||
// more relevant: also change the distance, so the buttons are actually visible
|
||||
val heightScale = scale + 0.2f
|
||||
val heightScale = if (scale < 0.8f) scale + 0.2f else 1f
|
||||
val buttonsLeft = if (isLeftGravity) keyboardView.measuredWidth else 0
|
||||
stopOneHandedModeBtn.layout(
|
||||
buttonsLeft + (spareWidth - stopOneHandedModeBtn.measuredWidth) / 2,
|
||||
|
|
|
@ -36,7 +36,10 @@ class Colors (
|
|||
val keyHintText: Int
|
||||
) {
|
||||
val navBar: Int
|
||||
/** brightened or darkened variant of [background], to be used if exact background color would be
|
||||
* bad contrast, e.g. more keys popup or no border space bar */
|
||||
val adjustedBackground: Int
|
||||
/** brightened or darkened variant of [keyText] */
|
||||
val adjustedKeyText: Int
|
||||
val spaceBarText: Int
|
||||
|
||||
|
@ -49,7 +52,9 @@ class Colors (
|
|||
val spaceBarFilter: ColorFilter
|
||||
val keyTextFilter: ColorFilter
|
||||
val accentColorFilter: ColorFilter
|
||||
/** color filter for the white action key icons in material theme, switches to gray if necessary for contrast */
|
||||
val actionKeyIconColorFilter: ColorFilter?
|
||||
/** color filter for the clipboard pin, used only in holo theme */
|
||||
val clipboardPinFilter: ColorFilter?
|
||||
|
||||
private val backgroundStateList: ColorStateList
|
||||
|
@ -58,8 +63,10 @@ class Colors (
|
|||
private val actionKeyStateList: ColorStateList
|
||||
private val spaceBarStateList: ColorStateList
|
||||
private val adjustedBackgroundStateList: ColorStateList
|
||||
private val suggestionBackgroundList: ColorStateList
|
||||
|
||||
val keyboardBackground: Drawable?
|
||||
/** custom drawable used for keyboard background */
|
||||
private val keyboardBackground: Drawable?
|
||||
|
||||
init {
|
||||
accentColorFilter = colorFilter(accent)
|
||||
|
@ -86,14 +93,20 @@ class Colors (
|
|||
backgroundFilter = colorFilter(background)
|
||||
adjustedKeyText = brightenOrDarken(keyText, true)
|
||||
|
||||
// color to be used if exact background color would be bad contrast, e.g. more keys popup or no border space bar
|
||||
val doubleAdjustedBackground: Int
|
||||
if (isDarkColor(background)) {
|
||||
adjustedBackground = brighten(background)
|
||||
adjustedBackgroundStateList = stateList(brighten(adjustedBackground), adjustedBackground)
|
||||
doubleAdjustedBackground = brighten(adjustedBackground)
|
||||
} else {
|
||||
adjustedBackground = darken(background)
|
||||
adjustedBackgroundStateList = stateList(darken(adjustedBackground), adjustedBackground)
|
||||
doubleAdjustedBackground = darken(adjustedBackground)
|
||||
}
|
||||
adjustedBackgroundStateList = stateList(doubleAdjustedBackground, adjustedBackground)
|
||||
suggestionBackgroundList = if (!hasKeyBorders && themeStyle == THEME_STYLE_MATERIAL)
|
||||
stateList(doubleAdjustedBackground, Color.TRANSPARENT)
|
||||
else
|
||||
stateList(adjustedBackground, Color.TRANSPARENT)
|
||||
|
||||
adjustedBackgroundFilter = colorFilter(adjustedBackground)
|
||||
if (hasKeyBorders) {
|
||||
keyBackgroundFilter = colorFilter(keyBackground)
|
||||
|
@ -148,7 +161,7 @@ class Colors (
|
|||
DrawableCompat.setTintList(background, colorStateList)
|
||||
}
|
||||
|
||||
// using !! for the color filter because null is only returned for unsupported modes, which are not used
|
||||
// using !! for the color filter because null is only returned for unsupported blend modes, which are not used
|
||||
private fun colorFilter(color: Int, mode: BlendModeCompat = BlendModeCompat.MODULATE): ColorFilter =
|
||||
BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, mode)!!
|
||||
|
||||
|
@ -189,5 +202,20 @@ class Colors (
|
|||
}
|
||||
|
||||
enum class BackgroundType {
|
||||
BACKGROUND, KEY, FUNCTIONAL, ACTION, ACTION_MORE_KEYS, SPACE, ADJUSTED_BACKGROUND, SUGGESTION
|
||||
/** generic background */
|
||||
BACKGROUND,
|
||||
/** key background */
|
||||
KEY,
|
||||
/** functional key background */
|
||||
FUNCTIONAL,
|
||||
/** action key background */
|
||||
ACTION,
|
||||
/** action key more keys background */
|
||||
ACTION_MORE_KEYS,
|
||||
/** space bar background */
|
||||
SPACE,
|
||||
/** background with some contrast to [BACKGROUND], based on adjustedBackground color */
|
||||
ADJUSTED_BACKGROUND,
|
||||
/** background for suggestions and similar, transparent when not pressed */
|
||||
SUGGESTION
|
||||
}
|
||||
|
|
|
@ -27,20 +27,6 @@ package org.dslul.openboard.inputmethod.latin.settings;
|
|||
public final class DebugSettings {
|
||||
public static final String PREF_DEBUG_MODE = "debug_mode";
|
||||
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
|
||||
public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
|
||||
"pref_has_custom_key_preview_animation_params";
|
||||
public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
|
||||
"pref_key_preview_dismiss_duration";
|
||||
public static final String PREF_KEY_PREVIEW_DISMISS_END_X_SCALE =
|
||||
"pref_key_preview_dismiss_end_x_scale";
|
||||
public static final String PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE =
|
||||
"pref_key_preview_dismiss_end_y_scale";
|
||||
public static final String PREF_KEY_PREVIEW_SHOW_UP_DURATION =
|
||||
"pref_key_preview_show_up_duration";
|
||||
public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE =
|
||||
"pref_key_preview_show_up_start_x_scale";
|
||||
public static final String PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE =
|
||||
"pref_key_preview_show_up_start_y_scale";
|
||||
public static final String PREF_SHOULD_SHOW_LXX_SUGGESTION_UI =
|
||||
"pref_should_show_lxx_suggestion_ui";
|
||||
public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview";
|
||||
|
|
|
@ -19,9 +19,7 @@ package org.dslul.openboard.inputmethod.latin.settings;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.Preference;
|
||||
|
@ -32,9 +30,6 @@ import org.dslul.openboard.inputmethod.latin.DictionaryDumpBroadcastReceiver;
|
|||
import org.dslul.openboard.inputmethod.latin.DictionaryFacilitatorImpl;
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ApplicationUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* "Debug mode" settings sub screen.
|
||||
|
@ -64,23 +59,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
|
|||
pref.setOnPreferenceClickListener(this);
|
||||
dictDumpPreferenceGroup.addPreference(pref);
|
||||
}
|
||||
final Resources res = getResources();
|
||||
setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
|
||||
res.getInteger(R.integer.config_key_preview_show_up_duration));
|
||||
setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
|
||||
res.getInteger(R.integer.config_key_preview_dismiss_duration));
|
||||
final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
|
||||
res, R.fraction.config_key_preview_show_up_start_scale);
|
||||
final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
|
||||
res, R.fraction.config_key_preview_dismiss_end_scale);
|
||||
setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
|
||||
defaultKeyPreviewShowUpStartScale);
|
||||
setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
|
||||
defaultKeyPreviewShowUpStartScale);
|
||||
setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
|
||||
defaultKeyPreviewDismissEndScale);
|
||||
setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
|
||||
defaultKeyPreviewDismissEndScale);
|
||||
|
||||
mServiceNeedsRestart = false;
|
||||
mDebugMode = findPreference(DebugSettings.PREF_DEBUG_MODE);
|
||||
|
@ -144,94 +122,4 @@ public final class DebugSettingsFragment extends SubScreenFragment
|
|||
}
|
||||
}
|
||||
|
||||
private void setupKeyPreviewAnimationScale(final String prefKey, final float defaultValue) {
|
||||
final SharedPreferences prefs = getSharedPreferences();
|
||||
final Resources res = getResources();
|
||||
final SeekBarDialogPreference pref = findPreference(prefKey);
|
||||
if (pref == null) {
|
||||
return;
|
||||
}
|
||||
pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
|
||||
private static final float PERCENTAGE_FLOAT = 100.0f;
|
||||
|
||||
private float getValueFromPercentage(final int percentage) {
|
||||
return percentage / PERCENTAGE_FLOAT;
|
||||
}
|
||||
|
||||
private int getPercentageFromValue(final float floatValue) {
|
||||
return (int)(floatValue * PERCENTAGE_FLOAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeValue(final int value, final String key) {
|
||||
prefs.edit().putFloat(key, getValueFromPercentage(value)).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDefaultValue(final String key) {
|
||||
prefs.edit().remove(key).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readValue(final String key) {
|
||||
return getPercentageFromValue(
|
||||
Settings.readKeyPreviewAnimationScale(prefs, key, defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readDefaultValue(final String key) {
|
||||
return getPercentageFromValue(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueText(final int value) {
|
||||
if (value < 0) {
|
||||
return res.getString(R.string.settings_system_default);
|
||||
}
|
||||
return String.format(Locale.ROOT, "%d%%", value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void feedbackValue(final int value) {}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupKeyPreviewAnimationDuration(final String prefKey, final int defaultValue) {
|
||||
final SharedPreferences prefs = getSharedPreferences();
|
||||
final Resources res = getResources();
|
||||
final SeekBarDialogPreference pref = findPreference(prefKey);
|
||||
if (pref == null) {
|
||||
return;
|
||||
}
|
||||
pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
|
||||
@Override
|
||||
public void writeValue(final int value, final String key) {
|
||||
prefs.edit().putInt(key, value).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDefaultValue(final String key) {
|
||||
prefs.edit().remove(key).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readValue(final String key) {
|
||||
return Settings.readKeyPreviewAnimationDuration(prefs, key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readDefaultValue(final String key) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueText(final int value) {
|
||||
return res.getString(R.string.abbreviation_unit_milliseconds, Integer.toString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void feedbackValue(final int value) {}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,10 +48,10 @@ public final class GestureSettingsFragment extends SubScreenFragment {
|
|||
final SharedPreferences prefs = getSharedPreferences();
|
||||
final Resources res = getResources();
|
||||
setPreferenceVisible(Settings.PREF_GESTURE_PREVIEW_TRAIL,
|
||||
Settings.readGestureInputEnabled(prefs, res));
|
||||
Settings.readGestureInputEnabled(prefs));
|
||||
setPreferenceVisible(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT,
|
||||
Settings.readGestureInputEnabled(prefs, res));
|
||||
Settings.readGestureInputEnabled(prefs));
|
||||
setPreferenceVisible(Settings.PREF_GESTURE_SPACE_AWARE,
|
||||
Settings.readGestureInputEnabled(prefs, res));
|
||||
Settings.readGestureInputEnabled(prefs));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,13 +46,6 @@ public class LocalSettingsConstants {
|
|||
// correctly set for it to work on a new device.
|
||||
DebugSettings.PREF_DEBUG_MODE,
|
||||
DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH,
|
||||
DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS,
|
||||
DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
|
||||
DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
|
||||
DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
|
||||
DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
|
||||
DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
|
||||
DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
|
||||
DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI,
|
||||
DebugSettings.PREF_SLIDING_KEY_INPUT_PREVIEW
|
||||
};
|
||||
|
|
|
@ -262,17 +262,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
res.getBoolean(R.bool.config_block_potentially_offensive));
|
||||
}
|
||||
|
||||
public static boolean readFromBuildConfigIfGestureInputEnabled(final Resources res) {
|
||||
if (!JniUtils.sHaveGestureLib) {
|
||||
return false;
|
||||
}
|
||||
return res.getBoolean(R.bool.config_gesture_input_enabled_by_build_config);
|
||||
}
|
||||
|
||||
public static boolean readGestureInputEnabled(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
return readFromBuildConfigIfGestureInputEnabled(res)
|
||||
&& prefs.getBoolean(PREF_GESTURE_INPUT, true);
|
||||
public static boolean readGestureInputEnabled(final SharedPreferences prefs) {
|
||||
return JniUtils.sHaveGestureLib && prefs.getBoolean(PREF_GESTURE_INPUT, true);
|
||||
}
|
||||
|
||||
public static boolean readFromBuildConfigIfToShowKeyPreviewPopupOption(final Resources res) {
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
|||
import org.dslul.openboard.inputmethod.latin.common.Colors;
|
||||
import org.dslul.openboard.inputmethod.latin.spellcheck.AndroidSpellCheckerService;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.AsyncResultHolder;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.TargetPackageInfoGetterTask;
|
||||
|
||||
|
@ -132,15 +131,6 @@ public class SettingsValues {
|
|||
// User-defined colors
|
||||
public final Colors mColors;
|
||||
|
||||
// Debug settings
|
||||
public final boolean mHasCustomKeyPreviewAnimationParams;
|
||||
public final int mKeyPreviewShowUpDuration;
|
||||
public final int mKeyPreviewDismissDuration;
|
||||
public final float mKeyPreviewShowUpStartXScale;
|
||||
public final float mKeyPreviewShowUpStartYScale;
|
||||
public final float mKeyPreviewDismissEndXScale;
|
||||
public final float mKeyPreviewDismissEndYScale;
|
||||
|
||||
@Nullable
|
||||
public final String mAccount;
|
||||
|
||||
|
@ -198,7 +188,7 @@ public class SettingsValues {
|
|||
Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true);
|
||||
mShowAppIcon = Settings.readShowSetupWizardIcon(prefs, context);
|
||||
mIsShowAppIconSettingInPreferences = prefs.contains(Settings.PREF_SHOW_SETUP_WIZARD_ICON);
|
||||
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
|
||||
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs);
|
||||
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
|
||||
mCloudSyncEnabled = prefs.getBoolean(LocalSettingsConstants.PREF_ENABLE_CLOUD_SYNC, false);
|
||||
mAccount = prefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME,
|
||||
|
@ -211,30 +201,7 @@ public class SettingsValues {
|
|||
readSuggestionsEnabled(prefs);
|
||||
mIncognitoModeEnabled = Settings.readAlwaysIncognitoMode(prefs) || mInputAttributes.mNoLearning
|
||||
|| mInputAttributes.mIsPasswordField;
|
||||
mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
|
||||
mKeyboardHeightScale = Settings.readKeyboardHeight(prefs, DEFAULT_SIZE_SCALE);
|
||||
mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration(
|
||||
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
|
||||
res.getInteger(R.integer.config_key_preview_show_up_duration));
|
||||
mKeyPreviewDismissDuration = Settings.readKeyPreviewAnimationDuration(
|
||||
prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
|
||||
res.getInteger(R.integer.config_key_preview_dismiss_duration));
|
||||
final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
|
||||
res, R.fraction.config_key_preview_show_up_start_scale);
|
||||
final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
|
||||
res, R.fraction.config_key_preview_dismiss_end_scale);
|
||||
mKeyPreviewShowUpStartXScale = Settings.readKeyPreviewAnimationScale(
|
||||
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
|
||||
defaultKeyPreviewShowUpStartScale);
|
||||
mKeyPreviewShowUpStartYScale = Settings.readKeyPreviewAnimationScale(
|
||||
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
|
||||
defaultKeyPreviewShowUpStartScale);
|
||||
mKeyPreviewDismissEndXScale = Settings.readKeyPreviewAnimationScale(
|
||||
prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
|
||||
defaultKeyPreviewDismissEndScale);
|
||||
mKeyPreviewDismissEndYScale = Settings.readKeyPreviewAnimationScale(
|
||||
prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
|
||||
defaultKeyPreviewDismissEndScale);
|
||||
mDisplayOrientation = res.getConfiguration().orientation;
|
||||
mAppWorkarounds = new AsyncResultHolder<>("AppWorkarounds");
|
||||
final PackageInfo packageInfo = TargetPackageInfoGetterTask.getCachedPackageInfo(
|
||||
|
@ -438,18 +405,6 @@ public class SettingsValues {
|
|||
sb.append("\n mAppWorkarounds = ");
|
||||
final AppWorkaroundsUtils awu = mAppWorkarounds.get(null, 0);
|
||||
sb.append("" + (null == awu ? "null" : awu.toString()));
|
||||
sb.append("\n mKeyPreviewShowUpDuration = ");
|
||||
sb.append("" + mKeyPreviewShowUpDuration);
|
||||
sb.append("\n mKeyPreviewDismissDuration = ");
|
||||
sb.append("" + mKeyPreviewDismissDuration);
|
||||
sb.append("\n mKeyPreviewShowUpStartScaleX = ");
|
||||
sb.append("" + mKeyPreviewShowUpStartXScale);
|
||||
sb.append("\n mKeyPreviewShowUpStartScaleY = ");
|
||||
sb.append("" + mKeyPreviewShowUpStartYScale);
|
||||
sb.append("\n mKeyPreviewDismissEndScaleX = ");
|
||||
sb.append("" + mKeyPreviewDismissEndXScale);
|
||||
sb.append("\n mKeyPreviewDismissEndScaleY = ");
|
||||
sb.append("" + mKeyPreviewDismissEndYScale);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.dslul.openboard.inputmethod.latin.suggestions;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
|
@ -125,8 +126,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
|
||||
/**
|
||||
* Construct a {@link SuggestionStripView} for showing suggestions to be picked by the user.
|
||||
* @param context
|
||||
* @param attrs
|
||||
*/
|
||||
public SuggestionStripView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.suggestionStripViewStyle);
|
||||
|
@ -151,7 +150,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
word.setContentDescription(getResources().getString(R.string.spoken_empty_suggestion));
|
||||
word.setOnClickListener(this);
|
||||
word.setOnLongClickListener(this);
|
||||
colors.setBackgroundColor(word.getBackground(), BackgroundType.SUGGESTION); // only necessary in some Android versions
|
||||
colors.setBackgroundColor(word.getBackground(), BackgroundType.SUGGESTION);
|
||||
mWordViews.add(word);
|
||||
final View divider = inflater.inflate(R.layout.suggestion_divider, null);
|
||||
mDividerViews.add(divider);
|
||||
|
@ -172,8 +171,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
final Resources res = context.getResources();
|
||||
mMoreSuggestionsModalTolerance = res.getDimensionPixelOffset(
|
||||
R.dimen.config_more_suggestions_modal_tolerance);
|
||||
mMoreSuggestionsSlidingDetector = new GestureDetector(
|
||||
context, mMoreSuggestionsSlidingListener);
|
||||
mMoreSuggestionsSlidingDetector = new GestureDetector(context, mMoreSuggestionsSlidingListener);
|
||||
|
||||
final TypedArray keyboardAttr = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.Keyboard, defStyle, R.style.SuggestionStripView);
|
||||
|
@ -194,7 +192,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
mVoiceKey.setColorFilter(colors.getKeyText());
|
||||
mOtherKey.setColorFilter(colors.getKeyText());
|
||||
|
||||
// only necessary in some Android versions
|
||||
colors.setBackgroundColor(mClipboardKey.getBackground(), BackgroundType.SUGGESTION);
|
||||
colors.setBackgroundColor(mVoiceKey.getBackground(), BackgroundType.SUGGESTION);
|
||||
colors.setBackgroundColor(mOtherKey.getBackground(), BackgroundType.SUGGESTION);
|
||||
|
@ -202,7 +199,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
|
||||
/**
|
||||
* A connection back to the input method.
|
||||
* @param listener
|
||||
*/
|
||||
public void setListener(final Listener listener, final View inputView) {
|
||||
mListener = listener;
|
||||
|
@ -231,11 +227,15 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
mLayoutHelper.setMoreSuggestionsHeight(remainingHeight);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility") // why would "null" need to call View#performClick?
|
||||
public void clear() {
|
||||
mSuggestionsStrip.removeAllViews();
|
||||
removeAllDebugInfoViews();
|
||||
mStripVisibilityGroup.showSuggestionsStrip();
|
||||
dismissMoreSuggestionsPanel();
|
||||
for (final TextView word : mWordViews) {
|
||||
word.setOnTouchListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAllDebugInfoViews() {
|
||||
|
@ -288,6 +288,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("ClickableViewAccessibility") // no need for View#performClick, we return false mostly anyway
|
||||
public boolean onLongClick(final View view) {
|
||||
if (view == mClipboardKey) {
|
||||
ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
|
@ -487,6 +488,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("ClickableViewAccessibility") // ok, perform click again, but why?
|
||||
public boolean onTouchEvent(final MotionEvent me) {
|
||||
if (!mMoreSuggestionsView.isShowingInParent()) {
|
||||
// Ignore any touch event while more suggestions panel hasn't been shown.
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dslul.openboard.inputmethod.latin.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dslul.openboard.inputmethod.latin.R;
|
||||
|
||||
/**
|
||||
* Helper class to get the metadata URI and the additional ID.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class MetadataFileUriGetter {
|
||||
private MetadataFileUriGetter() {
|
||||
// This helper class is not instantiable.
|
||||
}
|
||||
|
||||
public static String getMetadataUri(final Context context) {
|
||||
return context.getString(R.string.dictionary_pack_metadata_uri);
|
||||
}
|
||||
|
||||
public static String getMetadataAdditionalId(final Context context) {
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2012, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<objectAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="altCodeKeyWhileTypingAnimAlpha"
|
||||
android:valueType="intType"
|
||||
android:duration="1000"
|
||||
android:valueFrom="128"
|
||||
android:valueTo="255" />
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2012, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<objectAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="altCodeKeyWhileTypingAnimAlpha"
|
||||
android:valueType="intType"
|
||||
android:duration="3000"
|
||||
android:valueFrom="255"
|
||||
android:valueTo="128" />
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2014, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="0.94" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="0.94" />
|
||||
</set>
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2014, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="1.00" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="0.94" />
|
||||
</set>
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2014, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="17"
|
||||
android:valueFrom="0.98"
|
||||
android:valueTo="1.00" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="17"
|
||||
android:valueFrom="0.98"
|
||||
android:valueTo="1.00" />
|
||||
</set>
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2014, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="17"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="1.00" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="17"
|
||||
android:valueFrom="0.98"
|
||||
android:valueTo="1.00" />
|
||||
</set>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2014, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Until KitKat (API 19), {@link android.widget.Spinner} of dialog mode in a Dialog can't
|
||||
handle orientation change correctly. Using dropdown mode avoids the issue.
|
||||
This file overrides values/spinner-style.xml on KitKat and up. -->
|
||||
<style name="additionalSubtypeSpinnerStyle">
|
||||
<item name="android:spinnerMode">dialog</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -119,13 +119,6 @@
|
|||
<attr name="keyPreviewOffset" format="dimension" />
|
||||
<!-- Height of the key press feedback popup. -->
|
||||
<attr name="keyPreviewHeight" format="dimension" />
|
||||
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
|
||||
<!-- Delay after key releasing and key press feedback dismissing in millisecond -->
|
||||
<attr name="keyPreviewLingerTimeout" format="integer" />
|
||||
<!-- Key preview show up animator -->
|
||||
<attr name="keyPreviewShowUpAnimator" format="reference" />
|
||||
<!-- Key preview dismiss animator -->
|
||||
<attr name="keyPreviewDismissAnimator" format="reference" />
|
||||
<!-- Layout resource for more keys keyboard -->
|
||||
<attr name="moreKeysKeyboardLayout" format="reference" />
|
||||
<!-- Layout resource for more keys keyboard of action key -->
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2013, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- Whether phrase gestures are enabled by default -->
|
||||
<bool name="config_default_phrase_gesture_enabled">false</bool>
|
||||
</resources>
|
|
@ -35,12 +35,6 @@
|
|||
|
||||
<integer name="config_ignore_alt_code_key_timeout">350</integer>
|
||||
|
||||
<integer name="config_key_preview_show_up_duration">0</integer>
|
||||
<integer name="config_key_preview_dismiss_duration">0</integer>
|
||||
<fraction name="config_key_preview_show_up_start_scale">100%</fraction>
|
||||
<fraction name="config_key_preview_dismiss_end_scale">100%</fraction>
|
||||
<!-- TODO: consolidate key preview linger timeout with the above animation parameters. -->
|
||||
<integer name="config_key_preview_linger_timeout">0</integer>
|
||||
<!-- Suppress showing key preview duration after batch input in millisecond -->
|
||||
<integer name="config_suppress_key_preview_after_batch_input_duration">100</integer>
|
||||
|
||||
|
@ -53,8 +47,6 @@
|
|||
<integer name="config_longpress_timeout_step">10</integer>
|
||||
<integer name="config_accessibility_long_press_key_timeout">3000</integer>
|
||||
<integer name="config_max_more_keys_column">5</integer>
|
||||
<integer name="config_more_keys_keyboard_fadein_anim_time">0</integer>
|
||||
<integer name="config_more_keys_keyboard_fadeout_anim_time">100</integer>
|
||||
|
||||
<!-- Long pressing shift will invoke caps-lock if > 0, never invoke caps-lock if == 0 -->
|
||||
<integer name="config_longpress_shift_lock_timeout">1200</integer>
|
||||
|
@ -69,7 +61,7 @@
|
|||
<dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
|
||||
|
||||
<integer name="config_language_on_spacebar_final_alpha">128</integer>
|
||||
<dimen name="config_language_on_spacebar_horizontal_margin">1dp</dimen>
|
||||
<dimen name="config_language_on_spacebar_horizontal_margin">3dp</dimen>
|
||||
|
||||
<integer name="config_gesture_floating_preview_text_linger_timeout">200</integer>
|
||||
<integer name="config_gesture_trail_fadeout_start_delay">100</integer>
|
||||
|
@ -146,8 +138,4 @@
|
|||
<dimen name="config_accessibility_edge_slop">8dp</dimen>
|
||||
|
||||
<integer name="config_user_dictionary_max_word_length">48</integer>
|
||||
|
||||
<!-- Personalization configuration -->
|
||||
<!-- -1 means periocical wipe of the personalization dict is disabled. -->
|
||||
<integer name="config_personalization_dict_wipe_interval_in_days">-1</integer>
|
||||
</resources>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2013, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- Configuration values for Dictionary pack. -->
|
||||
<resources>
|
||||
<!-- Settings for the dictionary pack -->
|
||||
<bool name="allow_over_metered">false</bool>
|
||||
<bool name="allow_over_roaming">false</bool>
|
||||
<bool name="dict_downloads_visible_in_download_UI">false</bool>
|
||||
<bool name="metadata_downloads_visible_in_download_UI">false</bool>
|
||||
<bool name="display_notification_for_auto_update">true</bool>
|
||||
<bool name="display_notification_for_user_requested_update">true</bool>
|
||||
</resources>
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2013, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="dictionary_pack_client_id" translatable="false">org.dslul.openboard.inputmethod.latin</string>
|
||||
<string name="dictionary_pack_metadata_uri" translatable="false"></string>
|
||||
<string name="local_metadata_filename" translatable="false">metadata.json</string>
|
||||
</resources>
|
|
@ -27,20 +27,6 @@
|
|||
<string name="sliding_key_input_preview" translatable="false">Show slide indicator</string>
|
||||
<!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->
|
||||
<string name="sliding_key_input_preview_summary" translatable="false">Display visual cue while sliding from Shift or Symbol keys</string>
|
||||
<!-- Title of the settings for customize key popup animation parameters [CHAR LIMIT=35] -->
|
||||
<string name="prefs_customize_key_preview_animation" translatable="false">Customize key preview animation</string>
|
||||
<!-- Title of the settings for key popup show up animation duration (in milliseconds) [CHAR LIMIT=35] -->
|
||||
<string name="prefs_key_popup_show_up_duration_settings" translatable="false">Key popup show up duration</string>
|
||||
<!-- Title of the settings for key popup dismiss animation duration (in milliseconds) [CHAR LIMIT=35] -->
|
||||
<string name="prefs_key_popup_dismiss_duration_settings" translatable="false">Key popup dismiss duration</string>
|
||||
<!-- Title of the settings for key popup show up animation start X-scale (in percentile) [CHAR LIMIT=35] -->
|
||||
<string name="prefs_key_popup_show_up_start_x_scale_settings" translatable="false">Key popup show up start X scale</string>
|
||||
<!-- Title of the settings for key popup show up animation start Y-scale (in percentile) [CHAR LIMIT=35] -->
|
||||
<string name="prefs_key_popup_show_up_start_y_scale_settings" translatable="false">Key popup show up start Y scale</string>
|
||||
<!-- Title of the settings for key popup dismiss animation end X-scale (in percentile) [CHAR LIMIT=35] -->
|
||||
<string name="prefs_key_popup_dismiss_end_x_scale_settings" translatable="false">Key popup dismiss end X scale</string>
|
||||
<!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] -->
|
||||
<string name="prefs_key_popup_dismiss_end_y_scale_settings" translatable="false">Key popup dismiss end Y scale</string>
|
||||
<!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] -->
|
||||
<!-- Title of the settings group for dumping dictionary files that have been created on the device [CHAR LIMIT=35] -->
|
||||
<string name="prefs_dump_dynamic_dicts" translatable="false">Dump dictionary</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2012, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<bool name="config_gesture_input_enabled_by_build_config">true</bool>
|
||||
</resources>
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2015 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- The text shown on the suggestion bar to request the contacts permission info. -->
|
||||
</resources>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2014, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Until KitKat (API 19), {@link android.widget.Spinner} of dialog mode in a Dialog can't
|
||||
handle orientation change correctly. Using dropdown mode avoids the issue.
|
||||
This file is overridden by values-v19/spinner-style.xml on KitKat and up. -->
|
||||
<style name="additionalSubtypeSpinnerStyle">
|
||||
<item name="android:spinnerMode">dropdown</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -78,13 +78,11 @@
|
|||
<item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
|
||||
<item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
|
||||
<item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
|
||||
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
|
||||
<item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
|
||||
<item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
|
||||
<item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
|
||||
<item name="languageOnSpacebarTextRatio">@fraction/config_language_on_spacebar_text_ratio</item>
|
||||
<item name="languageOnSpacebarFinalAlpha">@integer/config_language_on_spacebar_final_alpha</item>
|
||||
<item name="languageOnSpacebarFadeoutAnimator">@anim/language_on_spacebar_fadeout</item>
|
||||
<item name="languageOnSpacebarFadeoutAnimator">@animator/language_on_spacebar_fadeout</item>
|
||||
<!-- Remove animations for now because it could drain a non-negligible amount of battery while typing.
|
||||
<item name="altCodeKeyWhileTypingFadeoutAnimator">@anim/alt_code_key_while_typing_fadeout</item>
|
||||
<item name="altCodeKeyWhileTypingFadeinAnimator">@anim/alt_code_key_while_typing_fadein</item>
|
||||
|
|
|
@ -64,8 +64,6 @@
|
|||
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_holo_white</item>
|
||||
<item name="keyPreviewHeight">@dimen/config_key_preview_height_holo</item>
|
||||
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
||||
<item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_holo</item>
|
||||
<item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_holo</item>
|
||||
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_holo_white</item>
|
||||
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
|
||||
<item name="gestureTrailColor">@color/highlight_color_holo_white</item>
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_light</item>
|
||||
<item name="keyPreviewHeight">@dimen/config_key_preview_height_lxx</item>
|
||||
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_lxx</item>
|
||||
<item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
|
||||
<item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_lxx</item>
|
||||
<item name="gestureFloatingPreviewTextColor">@color/auto_correct_color_lxx_light</item>
|
||||
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_light</item>
|
||||
<item name="gestureTrailColor">@color/gesture_trail_color_lxx_light</item>
|
||||
|
|
|
@ -41,41 +41,6 @@
|
|||
android:summary="@string/sliding_key_input_preview_summary"
|
||||
android:defaultValue="true"
|
||||
android:persistent="true" />
|
||||
<SwitchPreferenceCompat
|
||||
android:key="pref_has_custom_key_preview_animation_params"
|
||||
android:title="@string/prefs_customize_key_preview_animation"
|
||||
android:defaultValue="false"
|
||||
android:persistent="true" />
|
||||
<org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference
|
||||
android:dependency="pref_has_custom_key_preview_animation_params"
|
||||
android:key="pref_key_preview_show_up_start_x_scale"
|
||||
android:title="@string/prefs_key_popup_show_up_start_x_scale_settings"
|
||||
latin:maxValue="100" /> <!-- percent -->
|
||||
<org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference
|
||||
android:dependency="pref_has_custom_key_preview_animation_params"
|
||||
android:key="pref_key_preview_show_up_start_y_scale"
|
||||
android:title="@string/prefs_key_popup_show_up_start_y_scale_settings"
|
||||
latin:maxValue="100" /> <!-- percent -->
|
||||
<org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference
|
||||
android:dependency="pref_has_custom_key_preview_animation_params"
|
||||
android:key="pref_key_preview_dismiss_end_x_scale"
|
||||
android:title="@string/prefs_key_popup_dismiss_end_x_scale_settings"
|
||||
latin:maxValue="100" /> <!-- percent -->
|
||||
<org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference
|
||||
android:dependency="pref_has_custom_key_preview_animation_params"
|
||||
android:key="pref_key_preview_dismiss_end_y_scale"
|
||||
android:title="@string/prefs_key_popup_dismiss_end_y_scale_settings"
|
||||
latin:maxValue="100" /> <!-- percent -->
|
||||
<org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference
|
||||
android:dependency="pref_has_custom_key_preview_animation_params"
|
||||
android:key="pref_key_preview_show_up_duration"
|
||||
android:title="@string/prefs_key_popup_show_up_duration_settings"
|
||||
latin:maxValue="100" /> <!-- milliseconds -->
|
||||
<org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference
|
||||
android:dependency="pref_has_custom_key_preview_animation_params"
|
||||
android:key="pref_key_preview_dismiss_duration"
|
||||
android:title="@string/prefs_key_popup_dismiss_duration_settings"
|
||||
latin:maxValue="100" /> <!-- milliseconds -->
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_dump_dictionaries"
|
||||
android:title="@string/prefs_dump_dynamic_dicts">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue