mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-15 22:42:47 +00:00
some cleanup after increasing required api level
This commit is contained in:
parent
ffea3271f9
commit
96ad9482fb
42 changed files with 87 additions and 658 deletions
|
@ -2,14 +2,12 @@
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.compat;
|
package org.dslul.openboard.inputmethod.compat;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
public class ClipboardManagerCompat {
|
public class ClipboardManagerCompat {
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.P)
|
|
||||||
public static void clearPrimaryClip(ClipboardManager cm) {
|
public static void clearPrimaryClip(ClipboardManager cm) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
try {
|
try {
|
||||||
|
@ -23,7 +21,6 @@ public class ClipboardManagerCompat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
|
||||||
public static Long getClipTimestamp(ClipData cd) {
|
public static Long getClipTimestamp(ClipData cd) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
return cd.getDescription().getTimestamp();
|
return cd.getDescription().getTimestamp();
|
||||||
|
|
|
@ -1,190 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2011 The Android Open Source Project
|
|
||||||
* modified
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.compat
|
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.Log
|
|
||||||
import java.lang.reflect.Constructor
|
|
||||||
import java.lang.reflect.Field
|
|
||||||
import java.lang.reflect.InvocationTargetException
|
|
||||||
import java.lang.reflect.Method
|
|
||||||
|
|
||||||
object CompatUtils {
|
|
||||||
private val TAG = CompatUtils::class.java.simpleName
|
|
||||||
fun getClass(className: String?): Class<*>? {
|
|
||||||
return try {
|
|
||||||
Class.forName(className!!)
|
|
||||||
} catch (e: ClassNotFoundException) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMethod(targetClass: Class<*>?, name: String?,
|
|
||||||
vararg parameterTypes: Class<*>?): Method? {
|
|
||||||
if (targetClass == null || TextUtils.isEmpty(name)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return targetClass.getMethod(name!!, *parameterTypes)
|
|
||||||
} catch (_: SecurityException) { // ignore
|
|
||||||
} catch (_: NoSuchMethodException) {
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getField(targetClass: Class<*>?, name: String?): Field? {
|
|
||||||
if (targetClass == null || TextUtils.isEmpty(name)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return targetClass.getField(name!!)
|
|
||||||
} catch (_: SecurityException) { // ignore
|
|
||||||
} catch (_: NoSuchFieldException) {
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getConstructor(targetClass: Class<*>?,
|
|
||||||
vararg types: Class<*>?): Constructor<*>? {
|
|
||||||
if (targetClass == null || types == null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return targetClass.getConstructor(*types)
|
|
||||||
} catch (_: SecurityException) { // ignore
|
|
||||||
} catch (_: NoSuchMethodException) {
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun newInstance(constructor: Constructor<*>?, vararg args: Any?): Any? {
|
|
||||||
if (constructor == null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return constructor.newInstance(*args)
|
|
||||||
} catch (e: InstantiationException) {
|
|
||||||
Log.e(TAG, "Exception in newInstance", e)
|
|
||||||
} catch (e: IllegalAccessException) {
|
|
||||||
Log.e(TAG, "Exception in newInstance", e)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
Log.e(TAG, "Exception in newInstance", e)
|
|
||||||
} catch (e: InvocationTargetException) {
|
|
||||||
Log.e(TAG, "Exception in newInstance", e)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun invoke(receiver: Any?, defaultValue: Any?,
|
|
||||||
method: Method?, vararg args: Any?): Any? {
|
|
||||||
if (method == null) {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return method.invoke(receiver, *args)
|
|
||||||
} catch (e: IllegalAccessException) {
|
|
||||||
Log.e(TAG, "Exception in invoke", e)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
Log.e(TAG, "Exception in invoke", e)
|
|
||||||
} catch (e: InvocationTargetException) {
|
|
||||||
Log.e(TAG, "Exception in invoke", e)
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFieldValue(receiver: Any?, defaultValue: Any?,
|
|
||||||
field: Field?): Any? {
|
|
||||||
if (field == null) {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return field[receiver]
|
|
||||||
} catch (e: IllegalAccessException) {
|
|
||||||
Log.e(TAG, "Exception in getFieldValue", e)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
Log.e(TAG, "Exception in getFieldValue", e)
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setFieldValue(receiver: Any?, field: Field?, value: Any?) {
|
|
||||||
if (field == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
field[receiver] = value
|
|
||||||
} catch (e: IllegalAccessException) {
|
|
||||||
Log.e(TAG, "Exception in setFieldValue", e)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
Log.e(TAG, "Exception in setFieldValue", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getClassWrapper(className: String?): ClassWrapper {
|
|
||||||
return ClassWrapper(getClass(className))
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClassWrapper(private val mClass: Class<*>?) {
|
|
||||||
fun exists(): Boolean {
|
|
||||||
return mClass != null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> getMethod(name: String?,
|
|
||||||
defaultValue: T, vararg parameterTypes: Class<*>?): ToObjectMethodWrapper<T> {
|
|
||||||
return ToObjectMethodWrapper(getMethod(mClass, name, *parameterTypes),
|
|
||||||
defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPrimitiveMethod(name: String?, defaultValue: Int,
|
|
||||||
vararg parameterTypes: Class<*>?): ToIntMethodWrapper {
|
|
||||||
return ToIntMethodWrapper(getMethod(mClass, name, *parameterTypes),
|
|
||||||
defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPrimitiveMethod(name: String?, defaultValue: Float,
|
|
||||||
vararg parameterTypes: Class<*>?): ToFloatMethodWrapper {
|
|
||||||
return ToFloatMethodWrapper(getMethod(mClass, name, *parameterTypes),
|
|
||||||
defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPrimitiveMethod(name: String?,
|
|
||||||
defaultValue: Boolean, vararg parameterTypes: Class<*>?): ToBooleanMethodWrapper {
|
|
||||||
return ToBooleanMethodWrapper(getMethod(mClass, name, *parameterTypes),
|
|
||||||
defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
|
||||||
class ToObjectMethodWrapper<T>(private val mMethod: Method?, private val mDefaultValue: T) {
|
|
||||||
operator fun invoke(receiver: Any?, vararg args: Any?): T {
|
|
||||||
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as T
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToIntMethodWrapper(private val mMethod: Method?, private val mDefaultValue: Int) {
|
|
||||||
operator fun invoke(receiver: Any?, vararg args: Any?): Int {
|
|
||||||
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as Int
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToFloatMethodWrapper(private val mMethod: Method?, private val mDefaultValue: Float) {
|
|
||||||
operator fun invoke(receiver: Any?, vararg args: Any?): Float {
|
|
||||||
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as Float
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToBooleanMethodWrapper(private val mMethod: Method?, private val mDefaultValue: Boolean) {
|
|
||||||
operator fun invoke(receiver: Any?, vararg args: Any?): Boolean {
|
|
||||||
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,164 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
* modified
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.compat
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.graphics.Matrix
|
|
||||||
import android.graphics.RectF
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Build.VERSION_CODES
|
|
||||||
import android.view.inputmethod.CursorAnchorInfo
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper for [CursorAnchorInfo], which has been introduced in API Level 21. You can use
|
|
||||||
* this wrapper to avoid direct dependency on newly introduced types.
|
|
||||||
*/
|
|
||||||
open class CursorAnchorInfoCompatWrapper internal constructor() {
|
|
||||||
open val selectionStart: Int
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val selectionEnd: Int
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val composingText: CharSequence?
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val composingTextStart: Int
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val matrix: Matrix?
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun getCharacterBounds(index: Int): RectF? {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun getCharacterBoundsFlags(index: Int): Int {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val insertionMarkerBaseline: Float
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val insertionMarkerBottom: Float
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val insertionMarkerHorizontal: Float
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val insertionMarkerTop: Float
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
open val insertionMarkerFlags: Int
|
|
||||||
get() {
|
|
||||||
throw UnsupportedOperationException("not supported.")
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
|
||||||
private class RealWrapper(private val mInstance: CursorAnchorInfo) : CursorAnchorInfoCompatWrapper() {
|
|
||||||
|
|
||||||
override val selectionStart: Int
|
|
||||||
get() {
|
|
||||||
return mInstance.selectionStart
|
|
||||||
}
|
|
||||||
|
|
||||||
override val selectionEnd: Int
|
|
||||||
get() {
|
|
||||||
return mInstance.selectionEnd
|
|
||||||
}
|
|
||||||
|
|
||||||
override val composingText: CharSequence?
|
|
||||||
get() {
|
|
||||||
return mInstance.composingText
|
|
||||||
}
|
|
||||||
|
|
||||||
override val composingTextStart: Int
|
|
||||||
get() {
|
|
||||||
return mInstance.composingTextStart
|
|
||||||
}
|
|
||||||
|
|
||||||
override val matrix: Matrix?
|
|
||||||
get() {
|
|
||||||
return mInstance.matrix
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCharacterBounds(index: Int): RectF? {
|
|
||||||
return mInstance.getCharacterBounds(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCharacterBoundsFlags(index: Int): Int {
|
|
||||||
return mInstance.getCharacterBoundsFlags(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val insertionMarkerBaseline: Float
|
|
||||||
get() {
|
|
||||||
return mInstance.insertionMarkerBaseline
|
|
||||||
}
|
|
||||||
|
|
||||||
override val insertionMarkerBottom: Float
|
|
||||||
get() {
|
|
||||||
return mInstance.insertionMarkerBottom
|
|
||||||
}
|
|
||||||
|
|
||||||
override val insertionMarkerHorizontal: Float
|
|
||||||
get() {
|
|
||||||
return mInstance.insertionMarkerHorizontal
|
|
||||||
}
|
|
||||||
|
|
||||||
override val insertionMarkerTop: Float
|
|
||||||
get() {
|
|
||||||
return mInstance.insertionMarkerTop
|
|
||||||
}
|
|
||||||
|
|
||||||
override val insertionMarkerFlags: Int
|
|
||||||
get() {
|
|
||||||
return mInstance.insertionMarkerFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
/**
|
|
||||||
* The insertion marker or character bounds have at least one visible region.
|
|
||||||
*/
|
|
||||||
const val FLAG_HAS_VISIBLE_REGION = 0x01
|
|
||||||
/**
|
|
||||||
* The insertion marker or character bounds have at least one invisible (clipped) region.
|
|
||||||
*/
|
|
||||||
const val FLAG_HAS_INVISIBLE_REGION = 0x02
|
|
||||||
/**
|
|
||||||
* The insertion marker or character bounds is placed at right-to-left (RTL) character.
|
|
||||||
*/
|
|
||||||
const val FLAG_IS_RTL = 0x04
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
|
||||||
fun wrap(instance: CursorAnchorInfo?): CursorAnchorInfoCompatWrapper? {
|
|
||||||
return if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
|
|
||||||
null
|
|
||||||
} else instance?.let { RealWrapper(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,18 +14,13 @@ import org.dslul.openboard.inputmethod.latin.utils.locale
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object InputMethodSubtypeCompatUtils {
|
object InputMethodSubtypeCompatUtils {
|
||||||
// Note that InputMethodSubtype.getLanguageTag() is expected to be available in Android N+.
|
|
||||||
private val GET_LANGUAGE_TAG = CompatUtils.getMethod(InputMethodSubtype::class.java, "getLanguageTag")
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getLocaleObject(subtype: InputMethodSubtype): Locale { // Locale.forLanguageTag() is available only in Android L and later.
|
fun getLocaleObject(subtype: InputMethodSubtype): Locale { // Locale.forLanguageTag() is available only in Android L and later.
|
||||||
if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
|
||||||
val languageTag = CompatUtils.invoke(subtype, null, GET_LANGUAGE_TAG) as String?
|
val languageTag = subtype.languageTag
|
||||||
if (!languageTag.isNullOrEmpty()) {
|
if (languageTag.isNotEmpty())
|
||||||
return Locale.forLanguageTag(languageTag)
|
return Locale.forLanguageTag(languageTag)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return LocaleUtils.constructLocaleFromString(subtype.locale())
|
return LocaleUtils.constructLocaleFromString(subtype.locale())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,6 +14,7 @@ import android.text.style.SuggestionSpan
|
||||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting
|
import org.dslul.openboard.inputmethod.annotations.UsedForTesting
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
// todo: this is not compat any more
|
||||||
object SuggestionSpanUtils {
|
object SuggestionSpanUtils {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
* modified
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.compat
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.view.textservice.TextInfo
|
|
||||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting
|
|
||||||
|
|
||||||
object TextInfoCompatUtils {
|
|
||||||
// Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later.
|
|
||||||
private val TEXT_INFO_GET_CHAR_SEQUENCE = CompatUtils.getMethod(TextInfo::class.java, "getCharSequence")
|
|
||||||
|
|
||||||
@get:UsedForTesting
|
|
||||||
val isCharSequenceSupported: Boolean
|
|
||||||
get() = TEXT_INFO_GET_CHAR_SEQUENCE != null
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
@UsedForTesting
|
|
||||||
fun newInstance(charSequence: CharSequence, start: Int, end: Int, cookie: Int,
|
|
||||||
sequenceNumber: Int): TextInfo {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
return TextInfo(charSequence, start, end, cookie, sequenceNumber)
|
|
||||||
return TextInfo(charSequence.subSequence(start, end).toString(), cookie, sequenceNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the result of [TextInfo.getCharSequence] when available. Otherwise returns
|
|
||||||
* the result of [TextInfo.getText] as fall back.
|
|
||||||
* @param textInfo the instance for which [TextInfo.getCharSequence] or
|
|
||||||
* [TextInfo.getText] is called.
|
|
||||||
* @return the result of [TextInfo.getCharSequence] when available. Otherwise returns
|
|
||||||
* the result of [TextInfo.getText] as fall back. If `textInfo` is `null`,
|
|
||||||
* returns `null`.
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
@UsedForTesting
|
|
||||||
fun getCharSequenceOrString(textInfo: TextInfo): CharSequence {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
return textInfo.charSequence
|
|
||||||
val defaultValue = textInfo.text
|
|
||||||
return CompatUtils.invoke(textInfo, defaultValue, TEXT_INFO_GET_CHAR_SEQUENCE) as CharSequence
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,24 +6,44 @@
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.compat
|
package org.dslul.openboard.inputmethod.compat
|
||||||
|
|
||||||
|
import android.graphics.Outline
|
||||||
import android.inputmethodservice.InputMethodService
|
import android.inputmethodservice.InputMethodService
|
||||||
import android.os.Build
|
|
||||||
import android.os.Build.VERSION_CODES
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewOutlineProvider
|
||||||
|
|
||||||
|
// todo: this is not compat any more
|
||||||
object ViewOutlineProviderCompatUtils {
|
object ViewOutlineProviderCompatUtils {
|
||||||
private val EMPTY_INSETS_UPDATER: InsetsUpdater = object : InsetsUpdater {
|
|
||||||
override fun setInsets(insets: InputMethodService.Insets) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setInsetsOutlineProvider(view: View): InsetsUpdater {
|
fun setInsetsOutlineProvider(view: View): InsetsOutlineProvider {
|
||||||
return if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
|
val provider = InsetsOutlineProvider(view)
|
||||||
EMPTY_INSETS_UPDATER
|
view.outlineProvider = provider
|
||||||
} else ViewOutlineProviderCompatUtilsLXX.setInsetsOutlineProvider(view)
|
return provider
|
||||||
}
|
}
|
||||||
|
}
|
||||||
interface InsetsUpdater {
|
|
||||||
fun setInsets(insets: InputMethodService.Insets)
|
class InsetsOutlineProvider(private val mView: View) : ViewOutlineProvider() {
|
||||||
|
private var mLastVisibleTopInsets = NO_DATA
|
||||||
|
init {
|
||||||
|
mView.outlineProvider = this
|
||||||
|
}
|
||||||
|
fun setInsets(insets: InputMethodService.Insets) {
|
||||||
|
val visibleTopInsets = insets.visibleTopInsets
|
||||||
|
if (mLastVisibleTopInsets != visibleTopInsets) {
|
||||||
|
mLastVisibleTopInsets = visibleTopInsets
|
||||||
|
mView.invalidateOutline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOutline(view: View, outline: Outline) {
|
||||||
|
if (mLastVisibleTopInsets == NO_DATA) { // Call default implementation.
|
||||||
|
BACKGROUND.getOutline(view, outline)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO: Revisit this when floating/resize keyboard is supported.
|
||||||
|
outline.setRect(view.left, mLastVisibleTopInsets, view.right, view.bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val NO_DATA = -1
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
* modified
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.compat
|
|
||||||
|
|
||||||
import android.graphics.Outline
|
|
||||||
import android.inputmethodservice.InputMethodService
|
|
||||||
import android.os.Build
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewOutlineProvider
|
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
internal object ViewOutlineProviderCompatUtilsLXX {
|
|
||||||
fun setInsetsOutlineProvider(view: View): InsetsUpdater {
|
|
||||||
val provider = InsetsOutlineProvider(view)
|
|
||||||
view.outlineProvider = provider
|
|
||||||
return provider
|
|
||||||
}
|
|
||||||
|
|
||||||
private class InsetsOutlineProvider(private val mView: View) : ViewOutlineProvider(), InsetsUpdater {
|
|
||||||
private var mLastVisibleTopInsets = NO_DATA
|
|
||||||
override fun setInsets(insets: InputMethodService.Insets) {
|
|
||||||
val visibleTopInsets = insets.visibleTopInsets
|
|
||||||
if (mLastVisibleTopInsets != visibleTopInsets) {
|
|
||||||
mLastVisibleTopInsets = visibleTopInsets
|
|
||||||
mView.invalidateOutline()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOutline(view: View, outline: Outline) {
|
|
||||||
if (mLastVisibleTopInsets == NO_DATA) { // Call default implementation.
|
|
||||||
BACKGROUND.getOutline(view, outline)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO: Revisit this when floating/resize keyboard is supported.
|
|
||||||
outline.setRect(view.left, mLastVisibleTopInsets, view.right, view.bottom)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val NO_DATA = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
mView.outlineProvider = this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,7 +23,7 @@ import org.dslul.openboard.inputmethod.latin.utils.DeviceProtectedUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public final class KeyboardTheme implements Comparable<KeyboardTheme> {
|
public final class KeyboardTheme {
|
||||||
|
|
||||||
// old themes
|
// old themes
|
||||||
public static final String STYLE_MATERIAL = "Material";
|
public static final String STYLE_MATERIAL = "Material";
|
||||||
|
@ -59,43 +59,23 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
|
||||||
|
|
||||||
/* package private for testing */
|
/* package private for testing */
|
||||||
static final KeyboardTheme[] KEYBOARD_THEMES = {
|
static final KeyboardTheme[] KEYBOARD_THEMES = {
|
||||||
new KeyboardTheme(THEME_ID_HOLO_BASE, "HoloBase", R.style.KeyboardTheme_HoloBase,
|
new KeyboardTheme(THEME_ID_HOLO_BASE, "HoloBase", R.style.KeyboardTheme_HoloBase),
|
||||||
VERSION_CODES.BASE),
|
new KeyboardTheme(THEME_ID_LXX_BASE, "LXXBase", R.style.KeyboardTheme_LXX_Base),
|
||||||
new KeyboardTheme(THEME_ID_LXX_BASE, "LXXBase", R.style.KeyboardTheme_LXX_Base,
|
new KeyboardTheme(THEME_ID_LXX_BASE_BORDER, "LXXBaseBorder", R.style.KeyboardTheme_LXX_Base_Border),
|
||||||
VERSION_CODES.LOLLIPOP),
|
new KeyboardTheme(THEME_ID_ROUNDED_BASE, "RoundedBase", R.style.KeyboardTheme_Rounded_Base),
|
||||||
new KeyboardTheme(THEME_ID_LXX_BASE_BORDER, "LXXBaseBorder", R.style.KeyboardTheme_LXX_Base_Border,
|
new KeyboardTheme(THEME_ID_ROUNDED_BASE_BORDER, "RoundedBaseBorder", R.style.KeyboardTheme_Rounded_Base_Border)
|
||||||
VERSION_CODES.LOLLIPOP),
|
|
||||||
new KeyboardTheme(THEME_ID_ROUNDED_BASE, "RoundedBase", R.style.KeyboardTheme_Rounded_Base,
|
|
||||||
VERSION_CODES.LOLLIPOP),
|
|
||||||
new KeyboardTheme(THEME_ID_ROUNDED_BASE_BORDER, "RoundedBaseBorder", R.style.KeyboardTheme_Rounded_Base_Border,
|
|
||||||
VERSION_CODES.LOLLIPOP)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static {
|
|
||||||
// Sort {@link #KEYBOARD_THEME} by descending order of {@link #mMinApiVersion}.
|
|
||||||
Arrays.sort(KEYBOARD_THEMES);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int mThemeId;
|
public final int mThemeId;
|
||||||
public final int mStyleId;
|
public final int mStyleId;
|
||||||
public final String mThemeName;
|
public final String mThemeName;
|
||||||
public final int mMinApiVersion;
|
|
||||||
|
|
||||||
// Note: The themeId should be aligned with "themeId" attribute of Keyboard style
|
// Note: The themeId should be aligned with "themeId" attribute of Keyboard style
|
||||||
// in values/themes-<style>.xml.
|
// in values/themes-<style>.xml.
|
||||||
private KeyboardTheme(final int themeId, final String themeName, final int styleId,
|
private KeyboardTheme(final int themeId, final String themeName, final int styleId) {
|
||||||
final int minApiVersion) {
|
|
||||||
mThemeId = themeId;
|
mThemeId = themeId;
|
||||||
mThemeName = themeName;
|
mThemeName = themeName;
|
||||||
mStyleId = styleId;
|
mStyleId = styleId;
|
||||||
mMinApiVersion = minApiVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(final KeyboardTheme rhs) {
|
|
||||||
if (mMinApiVersion > rhs.mMinApiVersion) return -1;
|
|
||||||
if (mMinApiVersion < rhs.mMinApiVersion) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -672,10 +672,9 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
|
||||||
}
|
}
|
||||||
// crappy workaround...
|
// crappy workaround...
|
||||||
val locale = when (params.mId.locale.toString().lowercase()) {
|
val locale = when (params.mId.locale.toString().lowercase()) {
|
||||||
|
// todo: improve this when switching (rich input) subtype to use language tag
|
||||||
"hi_zz" -> Locale("en", "IN")
|
"hi_zz" -> Locale("en", "IN")
|
||||||
"sr_zz" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
"sr_zz" -> Locale.forLanguageTag("sr-Latn")
|
||||||
Locale.forLanguageTag("sr-Latn")
|
|
||||||
else params.mId.locale // todo: copy strings to sr-rZZ when definitely not increasing min SDK to 21
|
|
||||||
else -> params.mId.locale
|
else -> params.mId.locale
|
||||||
}
|
}
|
||||||
return ril.runInLocale(context.resources, locale)
|
return ril.runInLocale(context.resources, locale)
|
||||||
|
|
|
@ -42,8 +42,8 @@ import android.view.inputmethod.InputMethodSubtype;
|
||||||
import org.dslul.openboard.inputmethod.accessibility.AccessibilityUtils;
|
import org.dslul.openboard.inputmethod.accessibility.AccessibilityUtils;
|
||||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||||
import org.dslul.openboard.inputmethod.compat.EditorInfoCompatUtils;
|
import org.dslul.openboard.inputmethod.compat.EditorInfoCompatUtils;
|
||||||
|
import org.dslul.openboard.inputmethod.compat.InsetsOutlineProvider;
|
||||||
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils;
|
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils;
|
||||||
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
|
|
||||||
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants;
|
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants;
|
||||||
import org.dslul.openboard.inputmethod.event.Event;
|
import org.dslul.openboard.inputmethod.event.Event;
|
||||||
import org.dslul.openboard.inputmethod.event.HangulEventDecoder;
|
import org.dslul.openboard.inputmethod.event.HangulEventDecoder;
|
||||||
|
@ -142,7 +142,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
|
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
|
||||||
private View mInputView;
|
private View mInputView;
|
||||||
private InsetsUpdater mInsetsUpdater;
|
private InsetsOutlineProvider mInsetsUpdater;
|
||||||
private SuggestionStripView mSuggestionStripView;
|
private SuggestionStripView mSuggestionStripView;
|
||||||
|
|
||||||
private RichInputMethodManager mRichImm;
|
private RichInputMethodManager mRichImm;
|
||||||
|
@ -2006,9 +2006,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
|
|
||||||
// slightly modified from Simple Keyboard: https://github.com/rkkr/simple-keyboard/blob/master/app/src/main/java/rkr/simplekeyboard/inputmethod/latin/LatinIME.java
|
// slightly modified from Simple Keyboard: https://github.com/rkkr/simple-keyboard/blob/master/app/src/main/java/rkr/simplekeyboard/inputmethod/latin/LatinIME.java
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private void setNavigationBarColor() {
|
private void setNavigationBarColor() {
|
||||||
final SettingsValues settingsValues = mSettings.getCurrent();
|
final SettingsValues settingsValues = mSettings.getCurrent();
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || !settingsValues.mCustomNavBarColor)
|
if (!settingsValues.mCustomNavBarColor)
|
||||||
return;
|
return;
|
||||||
final int color = settingsValues.mColors.get(ColorType.NAVIGATION_BAR);
|
final int color = settingsValues.mColors.get(ColorType.NAVIGATION_BAR);
|
||||||
final Window window = getWindow().getWindow();
|
final Window window = getWindow().getWindow();
|
||||||
|
@ -2031,7 +2032,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private void clearNavigationBarColor() {
|
private void clearNavigationBarColor() {
|
||||||
final SettingsValues settingsValues = mSettings.getCurrent();
|
final SettingsValues settingsValues = mSettings.getCurrent();
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || !settingsValues.mCustomNavBarColor)
|
if (!settingsValues.mCustomNavBarColor)
|
||||||
return;
|
return;
|
||||||
final Window window = getWindow().getWindow();
|
final Window window = getWindow().getWindow();
|
||||||
if (window == null) {
|
if (window == null) {
|
||||||
|
|
|
@ -1176,14 +1176,11 @@ public final class RichInputConnection implements PrivateCommandPerformer {
|
||||||
* prevents the application from fulfilling the request. (TODO: Improve the API when it turns
|
* prevents the application from fulfilling the request. (TODO: Improve the API when it turns
|
||||||
* out that we actually need more detailed error codes)
|
* out that we actually need more detailed error codes)
|
||||||
*/
|
*/
|
||||||
public boolean requestCursorUpdates(final boolean enableMonitor,
|
public boolean requestCursorUpdates(final boolean enableMonitor, final boolean requestImmediateCallback) {
|
||||||
final boolean requestImmediateCallback) {
|
|
||||||
mIC = mParent.getCurrentInputConnection();
|
mIC = mParent.getCurrentInputConnection();
|
||||||
if (!isConnected()) {
|
if (!isConnected()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
return false;
|
|
||||||
final int cursorUpdateMode = (enableMonitor ? InputConnection.CURSOR_UPDATE_MONITOR : 0)
|
final int cursorUpdateMode = (enableMonitor ? InputConnection.CURSOR_UPDATE_MONITOR : 0)
|
||||||
| (requestImmediateCallback ? InputConnection.CURSOR_UPDATE_IMMEDIATE : 0);
|
| (requestImmediateCallback ? InputConnection.CURSOR_UPDATE_IMMEDIATE : 0);
|
||||||
return mIC.requestCursorUpdates(cursorUpdateMode);
|
return mIC.requestCursorUpdates(cursorUpdateMode);
|
||||||
|
|
|
@ -33,6 +33,7 @@ import androidx.annotation.Nullable;
|
||||||
public class RichInputMethodSubtype {
|
public class RichInputMethodSubtype {
|
||||||
private static final String TAG = RichInputMethodSubtype.class.getSimpleName();
|
private static final String TAG = RichInputMethodSubtype.class.getSimpleName();
|
||||||
|
|
||||||
|
// todo: remove this map when switching (rich input) subtype to use language tag
|
||||||
private static final HashMap<Locale, Locale> sLocaleMap = initializeLocaleMap();
|
private static final HashMap<Locale, Locale> sLocaleMap = initializeLocaleMap();
|
||||||
private static HashMap<Locale, Locale> initializeLocaleMap() {
|
private static HashMap<Locale, Locale> initializeLocaleMap() {
|
||||||
final HashMap<Locale, Locale> map = new HashMap<>();
|
final HashMap<Locale, Locale> map = new HashMap<>();
|
||||||
|
|
|
@ -90,11 +90,10 @@ public class SuggestedWords {
|
||||||
/**
|
/**
|
||||||
* Get suggested word to show as suggestions to UI.
|
* Get suggested word to show as suggestions to UI.
|
||||||
*
|
*
|
||||||
* @param shouldShowLxxSuggestionUi true if showing suggestion UI introduced in LXX and later.
|
|
||||||
* @return the count of suggested word to show as suggestions to UI.
|
* @return the count of suggested word to show as suggestions to UI.
|
||||||
*/
|
*/
|
||||||
public int getWordCountToShow(final boolean shouldShowLxxSuggestionUi) {
|
public int getWordCountToShow() {
|
||||||
if (isPrediction() || !shouldShowLxxSuggestionUi) {
|
if (isPrediction()) {
|
||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
return size() - /* typed word */ 1;
|
return size() - /* typed word */ 1;
|
||||||
|
|
|
@ -155,11 +155,8 @@ public final class InputLogic {
|
||||||
} else {
|
} else {
|
||||||
mInputLogicHandler.reset();
|
mInputLogicHandler.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settingsValues.mShouldShowLxxSuggestionUi) {
|
|
||||||
mConnection.requestCursorUpdates(true, true);
|
mConnection.requestCursorUpdates(true, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this when the subtype changes.
|
* Call this when the subtype changes.
|
||||||
|
|
|
@ -7,8 +7,6 @@ package org.dslul.openboard.inputmethod.latin.settings
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -16,7 +14,6 @@ import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import org.dslul.openboard.inputmethod.latin.BuildConfig
|
import org.dslul.openboard.inputmethod.latin.BuildConfig
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
|
@ -31,15 +28,6 @@ class AboutFragment : SubScreenFragment() {
|
||||||
super.onCreate(icicle)
|
super.onCreate(icicle)
|
||||||
addPreferencesFromResource(R.xml.prefs_screen_about)
|
addPreferencesFromResource(R.xml.prefs_screen_about)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
// need to set icon tint because old android versions don't use the vector drawables
|
|
||||||
for (i in 0 until preferenceScreen.preferenceCount) {
|
|
||||||
val p = preferenceScreen.getPreference(0)
|
|
||||||
val icon = p.icon
|
|
||||||
if (icon != null) DrawableCompat.setTint(icon, Color.WHITE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupHiddenFeatures()
|
setupHiddenFeatures()
|
||||||
setupVersionPref()
|
setupVersionPref()
|
||||||
findPreference<Preference>("log_reader")?.setOnPreferenceClickListener {
|
findPreference<Preference>("log_reader")?.setOnPreferenceClickListener {
|
||||||
|
|
|
@ -120,11 +120,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
|
|
||||||
private fun onClickLoadLibrary(): Boolean {
|
private fun onClickLoadLibrary(): Boolean {
|
||||||
// get architecture for telling user which file to use
|
// get architecture for telling user which file to use
|
||||||
val abi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
val abi = Build.SUPPORTED_ABIS[0]
|
||||||
Build.SUPPORTED_ABIS[0]
|
|
||||||
} else {
|
|
||||||
@Suppress("Deprecation") Build.CPU_ABI
|
|
||||||
}
|
|
||||||
// show delete / add dialog
|
// show delete / add dialog
|
||||||
val builder = AlertDialog.Builder(requireContext())
|
val builder = AlertDialog.Builder(requireContext())
|
||||||
.setTitle(R.string.load_gesture_library)
|
.setTitle(R.string.load_gesture_library)
|
||||||
|
@ -161,11 +157,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
||||||
if (checksum == JniUtils.expectedDefaultChecksum()) {
|
if (checksum == JniUtils.expectedDefaultChecksum()) {
|
||||||
renameToLibfileAndRestart(tmpfile, checksum)
|
renameToLibfileAndRestart(tmpfile, checksum)
|
||||||
} else {
|
} else {
|
||||||
val abi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
val abi = Build.SUPPORTED_ABIS[0]
|
||||||
Build.SUPPORTED_ABIS[0]
|
|
||||||
} else {
|
|
||||||
@Suppress("Deprecation") Build.CPU_ABI
|
|
||||||
}
|
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setMessage(getString(R.string.checksum_mismatch_message, abi))
|
.setMessage(getString(R.string.checksum_mismatch_message, abi))
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ -> renameToLibfileAndRestart(tmpfile, checksum) }
|
.setPositiveButton(android.R.string.ok) { _, _ -> renameToLibfileAndRestart(tmpfile, checksum) }
|
||||||
|
|
|
@ -12,7 +12,6 @@ import androidx.preference.TwoStatePreference
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
import org.dslul.openboard.inputmethod.latin.define.ProductionFlags
|
|
||||||
import java.lang.Float.max
|
import java.lang.Float.max
|
||||||
import java.lang.Float.min
|
import java.lang.Float.min
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -79,10 +78,6 @@ class AppearanceSettingsFragment : SubScreenFragment() {
|
||||||
removePreference("theme_select_colors_night")
|
removePreference("theme_select_colors_night")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
// todo: consider removing the preference, and always set the navbar color
|
|
||||||
removePreference(Settings.PREF_NAVBAR_COLOR)
|
|
||||||
}
|
|
||||||
val metrics = requireContext().resources.displayMetrics
|
val metrics = requireContext().resources.displayMetrics
|
||||||
val widthDp = metrics.widthPixels / metrics.density
|
val widthDp = metrics.widthPixels / metrics.density
|
||||||
val heightDp = metrics.heightPixels / metrics.density
|
val heightDp = metrics.heightPixels / metrics.density
|
||||||
|
|
|
@ -12,7 +12,6 @@ package org.dslul.openboard.inputmethod.latin.settings;
|
||||||
public final class DebugSettings {
|
public final class DebugSettings {
|
||||||
public static final String PREF_DEBUG_MODE = "debug_mode";
|
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_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
|
||||||
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";
|
public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview";
|
||||||
public static final String PREF_SHOW_DEBUG_SETTINGS = "pref_show_debug_settings";
|
public static final String PREF_SHOW_DEBUG_SETTINGS = "pref_show_debug_settings";
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
addPreferencesFromResource(R.xml.prefs_screen_debug);
|
addPreferencesFromResource(R.xml.prefs_screen_debug);
|
||||||
|
|
||||||
if (!Settings.SHOULD_SHOW_LXX_SUGGESTION_UI) {
|
|
||||||
removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI);
|
|
||||||
}
|
|
||||||
|
|
||||||
final PreferenceGroup dictDumpPreferenceGroup = findPreference(PREF_KEY_DUMP_DICTS);
|
final PreferenceGroup dictDumpPreferenceGroup = findPreference(PREF_KEY_DUMP_DICTS);
|
||||||
for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) {
|
for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) {
|
||||||
final Preference pref = new DictDumpPreference(getActivity(), dictName);
|
final Preference pref = new DictDumpPreference(getActivity(), dictName);
|
||||||
|
|
|
@ -13,8 +13,8 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.Switch
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.widget.SwitchCompat
|
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.doAfterTextChanged
|
import androidx.core.widget.doAfterTextChanged
|
||||||
|
@ -114,7 +114,7 @@ private class LanguageAdapter(list: List<MutableList<SubtypeInfo>> = listOf(), c
|
||||||
else isVisible = true
|
else isVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
view.findViewById<SwitchCompat>(R.id.language_switch).apply {
|
view.findViewById<Switch>(R.id.language_switch).apply {
|
||||||
isEnabled = !onlySystemLocales
|
isEnabled = !onlySystemLocales
|
||||||
// take care: isChecked changes if the language is scrolled out of view and comes back!
|
// take care: isChecked changes if the language is scrolled out of view and comes back!
|
||||||
// disable the change listener when setting the checked status on scroll
|
// disable the change listener when setting the checked status on scroll
|
||||||
|
|
|
@ -11,9 +11,9 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.ScrollView
|
import android.widget.ScrollView
|
||||||
|
import android.widget.Switch
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.widget.SwitchCompat
|
|
||||||
import androidx.core.view.get
|
import androidx.core.view.get
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
@ -170,7 +170,7 @@ class LanguageSettingsDialog(
|
||||||
} else {
|
} else {
|
||||||
row.findViewById<View>(R.id.language_details).isGone = true
|
row.findViewById<View>(R.id.language_details).isGone = true
|
||||||
}
|
}
|
||||||
row.findViewById<SwitchCompat>(R.id.language_switch).apply {
|
row.findViewById<Switch>(R.id.language_switch).apply {
|
||||||
isChecked = subtype.isEnabled
|
isChecked = subtype.isEnabled
|
||||||
isEnabled = !onlySystemLocales
|
isEnabled = !onlySystemLocales
|
||||||
setOnCheckedChangeListener { _, b ->
|
setOnCheckedChangeListener { _, b ->
|
||||||
|
@ -186,7 +186,7 @@ class LanguageSettingsDialog(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isAdditionalSubtype(subtype.subtype)) {
|
if (isAdditionalSubtype(subtype.subtype)) {
|
||||||
row.findViewById<SwitchCompat>(R.id.language_switch).isEnabled = true
|
row.findViewById<Switch>(R.id.language_switch).isEnabled = true
|
||||||
row.findViewById<ImageView>(R.id.delete_button).apply {
|
row.findViewById<ImageView>(R.id.delete_button).apply {
|
||||||
isVisible = true
|
isVisible = true
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
|
|
|
@ -12,9 +12,9 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputMethodSubtype
|
import android.view.inputmethod.InputMethodSubtype
|
||||||
|
import android.widget.Switch
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.SwitchCompat
|
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import org.dslul.openboard.inputmethod.latin.R
|
import org.dslul.openboard.inputmethod.latin.R
|
||||||
|
@ -37,7 +37,7 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) {
|
||||||
private val systemLocales = mutableListOf<Locale>()
|
private val systemLocales = mutableListOf<Locale>()
|
||||||
private lateinit var languageFilterList: LanguageFilterList
|
private lateinit var languageFilterList: LanguageFilterList
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
private lateinit var sharedPreferences: SharedPreferences
|
||||||
private lateinit var systemOnlySwitch: SwitchCompat
|
private lateinit var systemOnlySwitch: Switch
|
||||||
private val dictionaryLocales by lazy { getDictionaryLocales(requireContext()).mapTo(HashSet()) { it.languageConsideringZZ() } }
|
private val dictionaryLocales by lazy { getDictionaryLocales(requireContext()).mapTo(HashSet()) { it.languageConsideringZZ() } }
|
||||||
|
|
||||||
private val dictionaryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
private val dictionaryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
|
|
|
@ -9,14 +9,10 @@ package org.dslul.openboard.inputmethod.latin.settings;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.inputmethod.InputMethodSubtype;
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
|
|
||||||
import androidx.core.graphics.drawable.DrawableCompat;
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
|
||||||
|
@ -39,16 +35,6 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
addPreferencesFromResource(R.xml.prefs_screen_preferences);
|
addPreferencesFromResource(R.xml.prefs_screen_preferences);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
// need to set icon tint because old android versions don't use the vector drawables
|
|
||||||
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
|
|
||||||
final Preference p = getPreferenceScreen().getPreference(0);
|
|
||||||
final Drawable icon = p.getIcon();
|
|
||||||
if (icon != null)
|
|
||||||
DrawableCompat.setTint(icon, Color.WHITE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Resources res = getResources();
|
final Resources res = getResources();
|
||||||
final Context context = getActivity();
|
final Context context = getActivity();
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts";
|
public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts";
|
||||||
public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "pref_key_use_double_space_period";
|
public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "pref_key_use_double_space_period";
|
||||||
public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "pref_key_block_potentially_offensive";
|
public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "pref_key_block_potentially_offensive";
|
||||||
public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
|
||||||
public static final String PREF_LANGUAGE_SWITCH_KEY = "pref_language_switch_key";
|
public static final String PREF_LANGUAGE_SWITCH_KEY = "pref_language_switch_key";
|
||||||
public static final String PREF_SHOW_EMOJI_KEY = "pref_show_emoji_key";
|
public static final String PREF_SHOW_EMOJI_KEY = "pref_show_emoji_key";
|
||||||
public static final String PREF_ADDITIONAL_SUBTYPES = "pref_additional_subtypes";
|
public static final String PREF_ADDITIONAL_SUBTYPES = "pref_additional_subtypes";
|
||||||
|
|
|
@ -96,8 +96,6 @@ public class SettingsValues {
|
||||||
public final int mKeyLongpressTimeout;
|
public final int mKeyLongpressTimeout;
|
||||||
public final boolean mEnableEmojiAltPhysicalKey;
|
public final boolean mEnableEmojiAltPhysicalKey;
|
||||||
public final boolean mIsShowAppIconSettingInPreferences;
|
public final boolean mIsShowAppIconSettingInPreferences;
|
||||||
public final boolean mShouldShowLxxSuggestionUi;
|
|
||||||
// Use split layout for keyboard.
|
|
||||||
public final boolean mIsSplitKeyboardEnabled;
|
public final boolean mIsSplitKeyboardEnabled;
|
||||||
public final float mSplitKeyboardSpacerRelativeWidth;
|
public final float mSplitKeyboardSpacerRelativeWidth;
|
||||||
public final int mScreenMetrics;
|
public final int mScreenMetrics;
|
||||||
|
@ -177,8 +175,6 @@ public class SettingsValues {
|
||||||
: 0f;
|
: 0f;
|
||||||
mScreenMetrics = Settings.readScreenMetrics(res);
|
mScreenMetrics = Settings.readScreenMetrics(res);
|
||||||
|
|
||||||
mShouldShowLxxSuggestionUi = Settings.SHOULD_SHOW_LXX_SUGGESTION_UI
|
|
||||||
&& prefs.getBoolean(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI, true);
|
|
||||||
// Compute other readable settings
|
// Compute other readable settings
|
||||||
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
|
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
|
||||||
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
|
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
|
||||||
|
|
|
@ -14,7 +14,6 @@ import android.view.textservice.SentenceSuggestionsInfo;
|
||||||
import android.view.textservice.SuggestionsInfo;
|
import android.view.textservice.SuggestionsInfo;
|
||||||
import android.view.textservice.TextInfo;
|
import android.view.textservice.TextInfo;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.compat.TextInfoCompatUtils;
|
|
||||||
import org.dslul.openboard.inputmethod.latin.NgramContext;
|
import org.dslul.openboard.inputmethod.latin.NgramContext;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.SpannableStringUtils;
|
import org.dslul.openboard.inputmethod.latin.utils.SpannableStringUtils;
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
|
||||||
|
|
||||||
private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti,
|
private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti,
|
||||||
SentenceSuggestionsInfo ssi) {
|
SentenceSuggestionsInfo ssi) {
|
||||||
final CharSequence typedText = TextInfoCompatUtils.getCharSequenceOrString(ti);
|
final CharSequence typedText = ti.getCharSequence();
|
||||||
if (!typedText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
|
if (!typedText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -184,8 +183,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
|
||||||
final CharSequence prevWord;
|
final CharSequence prevWord;
|
||||||
if (sequentialWords && i > 0) {
|
if (sequentialWords && i > 0) {
|
||||||
final TextInfo prevTextInfo = textInfos[i - 1];
|
final TextInfo prevTextInfo = textInfos[i - 1];
|
||||||
final CharSequence prevWordCandidate =
|
final CharSequence prevWordCandidate = prevTextInfo.getCharSequence();
|
||||||
TextInfoCompatUtils.getCharSequenceOrString(prevTextInfo);
|
|
||||||
// Note that an empty string would be used to indicate the initial word
|
// Note that an empty string would be used to indicate the initial word
|
||||||
// in the future.
|
// in the future.
|
||||||
prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate;
|
prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate;
|
||||||
|
|
|
@ -11,7 +11,6 @@ import android.view.textservice.SentenceSuggestionsInfo;
|
||||||
import android.view.textservice.SuggestionsInfo;
|
import android.view.textservice.SuggestionsInfo;
|
||||||
import android.view.textservice.TextInfo;
|
import android.view.textservice.TextInfo;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.compat.TextInfoCompatUtils;
|
|
||||||
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
import org.dslul.openboard.inputmethod.latin.common.Constants;
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.SpacingAndPunctuations;
|
import org.dslul.openboard.inputmethod.latin.settings.SpacingAndPunctuations;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.RunInLocale;
|
import org.dslul.openboard.inputmethod.latin.utils.RunInLocale;
|
||||||
|
@ -124,8 +123,7 @@ public class SentenceLevelAdapter {
|
||||||
|
|
||||||
public SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) {
|
public SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) {
|
||||||
final WordIterator wordIterator = mWordIterator;
|
final WordIterator wordIterator = mWordIterator;
|
||||||
final CharSequence originalText =
|
final CharSequence originalText = originalTextInfo.getCharSequence();
|
||||||
TextInfoCompatUtils.getCharSequenceOrString(originalTextInfo);
|
|
||||||
final int cookie = originalTextInfo.getCookie();
|
final int cookie = originalTextInfo.getCookie();
|
||||||
final int start = -1;
|
final int start = -1;
|
||||||
final int end = originalText.length();
|
final int end = originalText.length();
|
||||||
|
@ -134,7 +132,7 @@ public class SentenceLevelAdapter {
|
||||||
int wordEnd = wordIterator.getEndOfWord(originalText, wordStart);
|
int wordEnd = wordIterator.getEndOfWord(originalText, wordStart);
|
||||||
while (wordStart <= end && wordEnd != -1 && wordStart != -1) {
|
while (wordStart <= end && wordEnd != -1 && wordStart != -1) {
|
||||||
if (wordEnd >= start && wordEnd > wordStart) {
|
if (wordEnd >= start && wordEnd > wordStart) {
|
||||||
final TextInfo ti = TextInfoCompatUtils.newInstance(originalText, wordStart,
|
final TextInfo ti = new TextInfo(originalText, wordStart,
|
||||||
wordEnd, cookie, originalText.subSequence(wordStart, wordEnd).hashCode());
|
wordEnd, cookie, originalText.subSequence(wordStart, wordEnd).hashCode());
|
||||||
wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd));
|
wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd));
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,11 +225,9 @@ final class SuggestionStripLayoutHelper {
|
||||||
final SuggestedWords suggestedWords) {
|
final SuggestedWords suggestedWords) {
|
||||||
final SettingsValues settingsValues = Settings.getInstance().getCurrent();
|
final SettingsValues settingsValues = Settings.getInstance().getCurrent();
|
||||||
final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle,
|
final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle,
|
||||||
settingsValues.mGestureFloatingPreviewTextEnabled,
|
settingsValues.mGestureFloatingPreviewTextEnabled, true);
|
||||||
settingsValues.mShouldShowLxxSuggestionUi);
|
|
||||||
return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect,
|
return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect,
|
||||||
settingsValues.mShouldShowLxxSuggestionUi && shouldOmitTypedWord,
|
shouldOmitTypedWord, mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect);
|
||||||
mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedForTesting
|
@UsedForTesting
|
||||||
|
@ -337,8 +335,7 @@ final class SuggestionStripLayoutHelper {
|
||||||
(PunctuationSuggestions)suggestedWords, stripView);
|
(PunctuationSuggestions)suggestedWords, stripView);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int wordCountToShow = suggestedWords.getWordCountToShow(
|
final int wordCountToShow = suggestedWords.getWordCountToShow();
|
||||||
Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi);
|
|
||||||
final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions(
|
final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions(
|
||||||
suggestedWords, mSuggestionsCountInStrip);
|
suggestedWords, mSuggestionsCountInStrip);
|
||||||
final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);
|
final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);
|
||||||
|
|
|
@ -6,12 +6,10 @@
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.latin.utils;
|
package org.dslul.openboard.inputmethod.latin.utils;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.inputmethodservice.ExtractEditText;
|
import android.inputmethodservice.ExtractEditText;
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.os.Build;
|
|
||||||
import android.text.Layout;
|
import android.text.Layout;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
@ -23,8 +21,7 @@ import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.compat.CursorAnchorInfoCompatWrapper;
|
// todo: remove this? or is there anything it could be useful for?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class allows input methods to extract {@link CursorAnchorInfo} directly from the given
|
* This class allows input methods to extract {@link CursorAnchorInfo} directly from the given
|
||||||
* {@link TextView}. This is useful and even necessary to support full-screen mode where the default
|
* {@link TextView}. This is useful and even necessary to support full-screen mode where the default
|
||||||
|
@ -74,30 +71,12 @@ public final class CursorAnchorInfoUtils {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts {@link CursorAnchorInfoCompatWrapper} from the given {@link TextView}.
|
|
||||||
* @param textView the target text view from which {@link CursorAnchorInfoCompatWrapper} is to
|
|
||||||
* be extracted.
|
|
||||||
* @return the {@link CursorAnchorInfoCompatWrapper} object based on the current layout.
|
|
||||||
* {@code null} if {@code Build.VERSION.SDK_INT} is 20 or prior or {@link TextView} is not
|
|
||||||
* ready to provide layout information.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public static CursorAnchorInfoCompatWrapper extractFromTextView(
|
|
||||||
@NonNull final TextView textView) {
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return CursorAnchorInfoCompatWrapper.wrap(extractFromTextViewInternal(textView));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@link CursorAnchorInfo} from the given {@link TextView}.
|
* Returns {@link CursorAnchorInfo} from the given {@link TextView}.
|
||||||
* @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted.
|
* @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted.
|
||||||
* @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it
|
* @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it
|
||||||
* is not feasible.
|
* is not feasible.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static CursorAnchorInfo extractFromTextViewInternal(@NonNull final TextView textView) {
|
private static CursorAnchorInfo extractFromTextViewInternal(@NonNull final TextView textView) {
|
||||||
final Layout layout = textView.getLayout();
|
final Layout layout = textView.getLayout();
|
||||||
|
|
|
@ -26,7 +26,7 @@ public final class JniUtils {
|
||||||
private static final String CHECKSUM_X86 = "bd946d126c957b5a6dea3bafa07fa36a27950b30e2b684dffc60746d0a1c7ad8";
|
private static final String CHECKSUM_X86 = "bd946d126c957b5a6dea3bafa07fa36a27950b30e2b684dffc60746d0a1c7ad8";
|
||||||
|
|
||||||
public static String expectedDefaultChecksum() {
|
public static String expectedDefaultChecksum() {
|
||||||
final String abi = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Build.SUPPORTED_ABIS[0] : Build.CPU_ABI;
|
final String abi = Build.SUPPORTED_ABIS[0];
|
||||||
return switch (abi) {
|
return switch (abi) {
|
||||||
case "arm64-v8a" -> CHECKSUM_ARM64;
|
case "arm64-v8a" -> CHECKSUM_ARM64;
|
||||||
case "armeabi-v7a" -> CHECKSUM_ARM32;
|
case "armeabi-v7a" -> CHECKSUM_ARM32;
|
||||||
|
|
|
@ -5,9 +5,9 @@ import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Switch
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.widget.SwitchCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
@ -135,7 +135,7 @@ fun reorderMoreKeysDialog(context: Context, key: String, defaultSetting: String,
|
||||||
val displayTextId = context.resources.getIdentifier(text.lowercase(), "string", context.packageName)
|
val displayTextId = context.resources.getIdentifier(text.lowercase(), "string", context.packageName)
|
||||||
val displayText = if (displayTextId == 0) text else context.getString(displayTextId)
|
val displayText = if (displayTextId == 0) text else context.getString(displayTextId)
|
||||||
p0.itemView.findViewById<TextView>(R.id.morekeys_type)?.text = displayText
|
p0.itemView.findViewById<TextView>(R.id.morekeys_type)?.text = displayText
|
||||||
val switch = p0.itemView.findViewById<SwitchCompat>(R.id.morekeys_switch)
|
val switch = p0.itemView.findViewById<Switch>(R.id.morekeys_switch)
|
||||||
switch?.isChecked = wasChecked
|
switch?.isChecked = wasChecked
|
||||||
switch?.isEnabled = !(key.contains(Settings.PREF_MORE_KEYS_ORDER) && text == MORE_KEYS_LAYOUT) // layout can't be disabled
|
switch?.isEnabled = !(key.contains(Settings.PREF_MORE_KEYS_ORDER) && text == MORE_KEYS_LAYOUT) // layout can't be disabled
|
||||||
switch?.setOnCheckedChangeListener { _, isChecked ->
|
switch?.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
android:paddingHorizontal="10dp"
|
android:paddingHorizontal="10dp"
|
||||||
style="@style/PreferenceSubtitleText" />
|
style="@style/PreferenceSubtitleText" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<Switch
|
||||||
android:id="@+id/color_switch"
|
android:id="@+id/color_switch"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" >
|
android:layout_height="wrap_content" >
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<Switch
|
||||||
android:id="@+id/language_switch"
|
android:id="@+id/language_switch"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
android:paddingTop="6dp"
|
android:paddingTop="6dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<Switch
|
||||||
android:id="@+id/language_switch"
|
android:id="@+id/language_switch"
|
||||||
android:text="@string/use_system_language_to_select_input_method_subtypes"
|
android:text="@string/use_system_language_to_select_input_method_subtypes"
|
||||||
style="@style/PreferenceTitleText"
|
style="@style/PreferenceTitleText"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<Switch
|
||||||
android:id="@+id/morekeys_switch"
|
android:id="@+id/morekeys_switch"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (C) 2014 The Android Open Source Project
|
|
||||||
modified
|
|
||||||
SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight">
|
|
||||||
<item name="android:colorAccent">@color/accent</item>
|
|
||||||
<item name="colorAccent">@color/accent</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (C) 2014 The Android Open Source Project
|
|
||||||
SPDX-License-Identifier: Apache-2.0
|
|
||||||
-->
|
|
||||||
|
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<style
|
|
||||||
name="InputView.LXX"
|
|
||||||
parent="InputView"
|
|
||||||
>
|
|
||||||
<item name="android:elevation">8dp</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
|
@ -12,7 +12,6 @@
|
||||||
<string name="prefs_debug_mode" translatable="false">Debug Mode</string>
|
<string name="prefs_debug_mode" translatable="false">Debug Mode</string>
|
||||||
<string name="prefs_show_suggestion_infos" translatable="false">Show suggestion infos</string>
|
<string name="prefs_show_suggestion_infos" translatable="false">Show suggestion infos</string>
|
||||||
<string name="prefs_force_non_distinct_multitouch" translatable="false">Force non-distinct multitouch</string>
|
<string name="prefs_force_non_distinct_multitouch" translatable="false">Force non-distinct multitouch</string>
|
||||||
<string name="prefs_should_show_lxx_suggestion_ui" translatable="false">Show LXX suggestion UI</string>
|
|
||||||
<!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
|
<!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
|
||||||
<string name="sliding_key_input_preview" translatable="false">Show slide indicator</string>
|
<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]-->
|
<!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->
|
||||||
|
|
|
@ -6,5 +6,8 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight" />
|
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight">
|
||||||
|
<item name="android:colorAccent">@color/accent</item>
|
||||||
|
<item name="colorAccent">@color/accent</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
<style
|
<style
|
||||||
name="InputView.LXX"
|
name="InputView.LXX"
|
||||||
parent="InputView"
|
parent="InputView"
|
||||||
/>
|
>
|
||||||
|
<item name="android:elevation">8dp</item>
|
||||||
|
</style>
|
||||||
<!-- LXX KeyboardView theme -->
|
<!-- LXX KeyboardView theme -->
|
||||||
<style
|
<style
|
||||||
name="KeyboardView.LXX"
|
name="KeyboardView.LXX"
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
android:title="@string/prefs_force_non_distinct_multitouch"
|
android:title="@string/prefs_force_non_distinct_multitouch"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:persistent="true" />
|
android:persistent="true" />
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:key="pref_should_show_lxx_suggestion_ui"
|
|
||||||
android:title="@string/prefs_should_show_lxx_suggestion_ui"
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:persistent="true" />
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:key="pref_sliding_key_input_preview"
|
android:key="pref_sliding_key_input_preview"
|
||||||
android:title="@string/sliding_key_input_preview"
|
android:title="@string/sliding_key_input_preview"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue