Compare commits

...

33 Commits

Author SHA1 Message Date
Patrick Goldinger
fe6930fb76 Release v0.3.2 2020-12-27 21:48:48 +01:00
Patrick Goldinger
6a10f0a01a Swap underscore and percentage sign in symbols layout (#101) 2020-12-27 21:39:51 +01:00
Patrick Goldinger
30717eeb90 Merge pull request #115 from yashx/cleanUp
InputView Code Cleanup
2020-12-27 21:26:09 +01:00
Patrick Goldinger
a664ab18c9 Merge pull request #114 from florisboard/feat-toggle-ext-popup-priority
Add hint priority mode setting
2020-12-27 21:00:11 +01:00
yashx
f50983d7ab InputView Code Cleanup 2020-12-28 01:02:56 +05:30
Patrick Goldinger
be858802c5 Fix old hint strings not removed from translated files 2020-12-27 20:03:29 +01:00
Patrick Goldinger
1ba690e53a Add hint priority mode setting (#39) 2020-12-27 19:44:24 +01:00
Patrick Goldinger
e16f81d350 Merge pull request #111 from yashx/timber
Switch to Timber for Logging
2020-12-27 18:27:10 +01:00
Patrick Goldinger
0de2039d72 Merge pull request #110 from florisboard/feat-private-mode
Add private mode (aka incognito mode) base
2020-12-27 16:23:02 +01:00
Patrick Goldinger
50b6a63468 Add private mode theme attributes 2020-12-27 16:16:53 +01:00
yashx
8cb644b418 Switch to Timber for Logging 2020-12-27 11:33:09 +05:30
Patrick Goldinger
f138124670 Add private mode (aka incognito mode) base (#106) 2020-12-26 23:24:27 +01:00
Patrick Goldinger
0f76d7f9df Merge pull request #107 from yashx/undoRedo
Added Undo Redo Buttons to Quick Actions in Smart Bar
2020-12-26 21:20:35 +01:00
Patrick Goldinger
27b9ec4628 Merge pull request #108 from florisboard/fix-typing-ux
Improve input UX and performance
2020-12-26 21:13:51 +01:00
Patrick Goldinger
ac733ed1dc Further improve input UX 2020-12-26 21:09:11 +01:00
yashx
6d15708f95 Switch to emulating hardware key press to paste 2020-12-26 22:03:54 +05:30
Patrick Goldinger
4377f3e41c Improve input performance by avoiding object allocation 2020-12-26 16:26:58 +01:00
Patrick Goldinger
1e690018d7 Merge pull request #100 from yashx/hardwareDelete
Switch to emulating hardware key press to delete
2020-12-26 11:37:32 +01:00
yashx
93bb5d2714 Added Undo Redo Buttons to Quick Actions in Smart Bar 2020-12-26 15:23:38 +05:30
Patrick Goldinger
ad2b08a342 Merge pull request #102 from The-Quantum-Alpha/patch-1
Create canadian_french.json
2020-12-26 03:55:21 +01:00
The Quantum Alpha
9e6508cee4 yeah, whatever with the config.json
🇨🇦fr
2020-12-25 21:49:12 -05:00
The Quantum Alpha
f735c138fb Create canadian_french.json
qwerty, but with éàè
2020-12-25 20:56:49 -05:00
yashx
d663947fec Switch to emulating hardware key press to delete 2020-12-26 01:31:22 +05:30
Patrick Goldinger
c800617e26 Merge pull request #99 from yashx/arrowsFix
Fix left and right arrow in clipboard cursor row
2020-12-25 20:57:54 +01:00
yashx
f47c7abaf3 Fix left and right arrow in clipboard cursor row 2020-12-26 00:27:40 +05:30
Patrick Goldinger
faf06ee234 Merge pull request #97 from yashx/deleteGesture
Delete Key gesture Improvents
2020-12-25 19:39:33 +01:00
Patrick Goldinger
07c41f9c27 Merge pull request #98 from florisboard/fix-key-delete-crash-on-hold
Fix key delete crash on holding down
2020-12-25 19:34:10 +01:00
Patrick Goldinger
80a0d9edab Fix scheduled timer crash in media and editing as well 2020-12-25 19:20:12 +01:00
Patrick Goldinger
cd943a9d4a Fix key delete crash on holding down
Fix key delete crash on holding down 2
2020-12-25 19:12:06 +01:00
yashx
c3d3107b12 Added Delete Words Precisely 2020-12-25 20:34:36 +05:30
yashx
b91fac8e76 Fix Delete current word 2020-12-25 18:11:30 +05:30
Patrick Goldinger
e2c784f4cf Merge pull request #92 from Surendrajat/ci 2020-12-24 16:07:57 +01:00
Surendrajat
f83bdd8a28 Enable automatic build CI workflows
fix executable permission

add badge in README too

upload artifact

fix name
2020-12-24 15:55:23 +01:00
52 changed files with 711 additions and 240 deletions

32
.github/workflows/android.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: FlorisBoard CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew clean assemble
- uses: actions/upload-artifact@v2
with:
name: app-debug.apk
path: app/build/outputs/apk/debug/app-debug.apk

View File

@@ -1,7 +1,7 @@
<img align="left" width="80" height="80"
src="fastlane/metadata/android/en-US/images/icon.png" alt="App icon">
# FlorisBoard [![Release](https://img.shields.io/github/v/release/florisboard/florisboard)](https://github.com/florisboard/florisboard/releases) [![Crowdin](https://badges.crowdin.net/florisboard/localized.svg)](https://crowdin.florisboard.patrickgold.dev)
# FlorisBoard [![Release](https://img.shields.io/github/v/release/florisboard/florisboard)](https://github.com/florisboard/florisboard/releases) [![Crowdin](https://badges.crowdin.net/florisboard/localized.svg)](https://crowdin.florisboard.patrickgold.dev) ![FlorisBoard CI](https://github.com/florisboard/florisboard/workflows/FlorisBoard%20CI/badge.svg?event=push)
**FlorisBoard** is a free and open-source keyboard for Android 6.0+
devices. It aims at being modern, user-friendly and customizable while

View File

@@ -10,8 +10,8 @@ android {
applicationId "dev.patrickgold.florisboard"
minSdkVersion 23
targetSdkVersion 29
versionCode 20
versionName "0.3.1"
versionCode 21
versionName "0.3.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -53,4 +53,5 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7"
implementation 'com.jaredrummler:colorpicker:1.1.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
}

View File

@@ -18,7 +18,8 @@
"esperanto": "Esperanto",
"esperanto_with_hx": "Esperanto with 'ĥ'",
"colemak": "Colemak",
"dvorak": "Dvorak"
"dvorak": "Dvorak",
"canadian_french": "Canadian French (QWERTY)"
},
"defaultSubtypes": [
{
@@ -64,7 +65,7 @@
{
"id": 302,
"languageTag": "fr-CA",
"preferredLayout": "qwerty"
"preferredLayout": "canadian_french"
},
{
"id": 303,

View File

@@ -0,0 +1,40 @@
{
"type": "characters",
"name": "canadian_french",
"direction": "ltr",
"arrangement": [
[
{ "code": 113, "label": "q" },
{ "code": 119, "label": "w" },
{ "code": 101, "label": "e" },
{ "code": 114, "label": "r" },
{ "code": 116, "label": "t" },
{ "code": 121, "label": "y" },
{ "code": 117, "label": "u" },
{ "code": 105, "label": "i" },
{ "code": 111, "label": "o" },
{ "code": 112, "label": "p" },
{ "code": 232, "label": "è" }
], [
{ "code": 97, "label": "a" },
{ "code": 115, "label": "s" },
{ "code": 100, "label": "d" },
{ "code": 102, "label": "f" },
{ "code": 103, "label": "g" },
{ "code": 104, "label": "h" },
{ "code": 106, "label": "j" },
{ "code": 107, "label": "k" },
{ "code": 108, "label": "l" },
{ "code": 233, "label": "é" },
{ "code": 224, "label": "à" }
], [
{ "code": 122, "label": "z" },
{ "code": 120, "label": "x" },
{ "code": 99, "label": "c" },
{ "code": 118, "label": "v" },
{ "code": 98, "label": "b" },
{ "code": 110, "label": "n" },
{ "code": 109, "label": "m" }
]
]
}

View File

@@ -15,7 +15,10 @@
{ "code": 163, "label": "£" },
{ "code": 165, "label": "¥" }
] },
{ "code": 95, "label": "_", "popup": [] },
{ "code": 37, "label": "%", "popup": [
{ "code": 8240, "label": "‰" },
{ "code": 8453, "label": "℅" }
] },
{ "code": 38, "label": "&", "popup": [] },
{ "code": 45, "label": "-", "popup": [
{ "code": 8212, "label": "—" },

View File

@@ -54,10 +54,7 @@
] },
{ "code": 92, "label": "\\", "popup": [] }
], [
{ "code": 37, "label": "%", "popup": [
{ "code": 8240, "label": "‰" },
{ "code": 8453, "label": "℅" }
] },
{ "code": 95, "label": "_", "popup": [] },
{ "code": 169, "label": "©", "popup": [] },
{ "code": 174, "label": "®", "popup": [] },
{ "code": 8482, "label": "™", "popup": [] },

View File

@@ -47,6 +47,10 @@
"oneHandedButton": {
"fgColor": "#424242"
},
"privateMode": {
"bgColor": "#A000FF",
"fgColor": "#FFFFFF"
},
"smartbar": {
"bgColor": "transparent",
"fgColor": "@window/textColor",

View File

@@ -47,6 +47,10 @@
"oneHandedButton": {
"fgColor": "#EEEEEE"
},
"privateMode": {
"bgColor": "#A000FF",
"fgColor": "#FFFFFF"
},
"smartbar": {
"bgColor": "transparent",
"fgColor": "@window/textColor",

View File

@@ -28,6 +28,7 @@ import android.util.Log
import android.view.inputmethod.InputMethodManager
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.core.FlorisBoard
import timber.log.Timber
import java.io.File
import java.lang.ref.WeakReference
import kotlin.system.exitProcess
@@ -49,7 +50,6 @@ abstract class CrashUtility private constructor() {
private const val NOTIFICATION_ID = 0xFBAD0100
private const val UNHANDLED_STACKTRACE_FILE_EXT = "stacktrace"
private const val TAG = "CrashUtility"
private var lastActivityCreated: WeakReference<Activity?> = WeakReference(null)
@@ -63,15 +63,14 @@ abstract class CrashUtility private constructor() {
*/
fun install(context: Context?): Boolean {
if (context == null) {
Log.e(
TAG,
Timber.e(
"install($context): Can't install crash handler with a null Context object, doing nothing!"
)
return false
}
val oldHandler = Thread.getDefaultUncaughtExceptionHandler()
if (oldHandler is UncaughtExceptionHandler) {
Log.i(TAG, "install($context): Crash handler is already installed, doing nothing!")
Timber.i("install($context): Crash handler is already installed, doing nothing!")
} else {
val application = context.applicationContext
if (application != null && application is Application) {
@@ -83,19 +82,16 @@ abstract class CrashUtility private constructor() {
application.filesDir.absolutePath
)
)
Log.i(
TAG,
Timber.i(
"install($context): Successfully installed crash handler for this application!"
)
} catch (e: SecurityException) {
Log.e(
TAG,
Timber.e(
"install($context): Failed to install crash handler, probably due to missing runtime permission 'setDefaultUncaughtExceptionHandler':\n$e"
)
return false
} catch (e: Exception) {
Log.e(
TAG,
Timber.e(
"install($context): Failed to install crash handler due to an unspecified error:\n$e"
)
return false
@@ -130,20 +126,17 @@ abstract class CrashUtility private constructor() {
)
notificationManager.createNotificationChannel(notificationChannel)
}
Log.i(
TAG,
Timber.i(
"install($context): Successfully created crash handler notification channel!"
)
} catch (e: Exception) {
Log.e(
TAG,
Timber.e(
"install($context): Failed to create crash handler notification channel due to an unspecified error:\n$e"
)
}
}
} else {
Log.e(
TAG,
Timber.e(
"install($context): Can't install crash handler with a null Application object, doing nothing!"
)
return false
@@ -168,7 +161,7 @@ abstract class CrashUtility private constructor() {
pathname.name.endsWith(".$UNHANDLED_STACKTRACE_FILE_EXT")
})?.forEach { file ->
val newLine = System.lineSeparator()
Log.i(TAG, "Reading unhandled stacktrace: ${file.name}")
Timber.i("Reading unhandled stacktrace: ${file.name}")
retString.append("~~~ ${file.name} ~~~$newLine$newLine")
retString.append(readFile(file))
file.delete()
@@ -355,7 +348,7 @@ abstract class CrashUtility private constructor() {
private val path: String
) : Thread.UncaughtExceptionHandler {
override fun uncaughtException(thread: Thread?, throwable: Throwable?) {
Log.e(TAG, "Detected application crash, executing custom crash handler.")
Timber.e("Detected application crash, executing custom crash handler.")
thread ?: return
throwable ?: return
val timestamp = System.currentTimeMillis()

View File

@@ -23,10 +23,13 @@ import android.content.Context
import android.inputmethodservice.InputMethodService
import android.net.Uri
import android.os.Build
import android.os.SystemClock
import android.text.InputType
import android.view.KeyCharacterMap
import android.view.KeyEvent
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.ExtractedTextRequest
import android.view.inputmethod.InputConnection
import android.view.inputmethod.InputContentInfo
import androidx.annotation.RequiresApi
import dev.patrickgold.florisboard.ime.text.key.KeyCode
@@ -89,6 +92,7 @@ class EditorInstance private constructor(private val ims: InputMethodService?) {
}
var isNewSelectionInBoundsOfOld: Boolean = false
private set
var isPrivateMode: Boolean = false
var isRawInputEditor: Boolean = true
private set
var packageName: String = "undefined"
@@ -254,24 +258,19 @@ class EditorInstance private constructor(private val ims: InputMethodService?) {
*/
fun deleteBackwards(): Boolean {
val ic = ims?.currentInputConnection ?: return false
if (isRawInputEditor) {
return sendSystemKeyEvent(KeyEvent.KEYCODE_DEL)
return if (isRawInputEditor) {
sendSystemKeyEvent(KeyEvent.KEYCODE_DEL)
} else {
ic.beginBatchEdit()
markComposingRegion(null)
if (selection.isCursorMode && selection.start > 0) {
val length = detectLastUnicodeCharacterLengthBeforeCursor()
ic.deleteSurroundingText(length, 0)
} else if (selection.isSelectionMode) {
ic.commitText("", 1)
}
sendSystemKeyEvent(KeyEvent.KEYCODE_DEL)
updateEditorState()
reevaluateCurrentWord()
if (isComposingEnabled) {
markComposingRegion(currentWord)
}
ic.endBatchEdit()
return true
true
}
}
@@ -287,21 +286,89 @@ class EditorInstance private constructor(private val ims: InputMethodService?) {
*/
fun deleteWordsBeforeCursor(n: Int): Boolean {
val ic = ims?.currentInputConnection ?: return false
return if (n < 1 || isRawInputEditor) {
return if (n < 1 || isRawInputEditor || !selection.isValid || !selection.isCursorMode) {
false
} else {
ic.beginBatchEdit()
markComposingRegion(null)
if (currentWord.isValid) {
ic.setSelection(currentWord.start, currentWord.end)
ic.commitText("", 1)
getWordsInString(cachedText.substring(0, selection.start)).run {
get(size - n.coerceAtLeast(0)).range
}.run {
ic.setSelection(first, selection.start)
}
ic.commitText("", 1)
updateEditorState()
reevaluateCurrentWord()
ic.endBatchEdit()
true
}
}
/**
* Finds all words in the given string with the correct regex for current subtype.
* TODO: currently only supports en-US
*
* @param string String to select words from
* @return Words in [string] as a List of [MatchResult]
*/
private fun getWordsInString(string: String):List<MatchResult>{
val wordRegexPattern = "[\\p{L}]+".toRegex()
return wordRegexPattern.findAll(
string
).toList()
}
/**
* Undoes the last action
*
* @return True on success, false if an error occurred or the input connection is invalid.
*/
fun performUndo(): Boolean{
val ic = ims?.currentInputConnection ?: return false
return if (isRawInputEditor) {
sendSystemKeyEventCtrl(KeyEvent.KEYCODE_Z)
true
} else {
ic.beginBatchEdit()
markComposingRegion(null)
sendSystemKeyEventCtrl(KeyEvent.KEYCODE_Z)
updateEditorState()
reevaluateCurrentWord()
if (isComposingEnabled) {
markComposingRegion(currentWord)
}
ic.endBatchEdit()
true
}
}
/**
* Redoes the last Undo action
*
* @return True on success, false if an error occurred or the input connection is invalid.
*/
fun performRedo(): Boolean{
val ic = ims?.currentInputConnection ?: return false
return if (isRawInputEditor) {
sendSystemKeyEventCtrlShift(KeyEvent.KEYCODE_Z)
true
} else {
ic.beginBatchEdit()
markComposingRegion(null)
sendSystemKeyEventCtrlShift(KeyEvent.KEYCODE_Z)
updateEditorState()
reevaluateCurrentWord()
if (isComposingEnabled) {
markComposingRegion(currentWord)
}
ic.endBatchEdit()
true
}
}
/**
* Gets [n] characters after the cursor's current position. The resulting string may be any
* length ranging from 0 to n.
@@ -379,19 +446,21 @@ class EditorInstance private constructor(private val ims: InputMethodService?) {
* @return True on success, false if an error occurred or the input connection is invalid.
*/
fun performClipboardPaste(): Boolean {
val clipData: ClipData? = clipboardManager?.primaryClip
val item: ClipData.Item? = clipData?.getItemAt(0)
return when {
item?.text != null -> {
commitText(item.text.toString())
}
item?.uri != null -> {
commitContent(item.uri, clipData.description)
}
else -> {
false
}
}
// val clipData: ClipData? = clipboardManager?.primaryClip
// val item: ClipData.Item? = clipData?.getItemAt(0)
// return when {
// item?.text != null -> {
// commitText(item.text.toString())
// }
// item?.uri != null -> {
// commitContent(item.uri, clipData.description)
// }
// else -> {
// false
// }
// }
sendSystemKeyEventCtrl(KeyEvent.KEYCODE_V)
return true
}
/**
@@ -453,6 +522,66 @@ class EditorInstance private constructor(private val ims: InputMethodService?) {
)
}
/**
* Sends a given [keyCode] with Ctrl pressed with [sendDownUpKeyEvents]
*
* @param keyCode The key code to send, use a key code defined in Android's [KeyEvent], not in
* [KeyCode] or this call may send a weird character, as this key codes do not match!!
*/
fun sendSystemKeyEventCtrl(keyCode: Int) {
val ic = ims?.currentInputConnection ?: return
sendDownUpKeyEvents(keyCode, KeyEvent.META_CTRL_ON)
}
/**
* Sends a given [keyCode] with Ctrl and Shift pressed with [sendDownUpKeyEvents]
*
* @param keyCode The key code to send, use a key code defined in Android's [KeyEvent], not in
* [KeyCode] or this call may send a weird character, as this key codes do not match!!
*/
fun sendSystemKeyEventCtrlShift(keyCode: Int) {
val ic = ims?.currentInputConnection ?: return
sendDownUpKeyEvents(keyCode, KeyEvent.META_SHIFT_ON or KeyEvent.META_CTRL_ON)
}
/**
* Same as [InputMethodService.sendDownUpKeyEvents] but also allows to set metaStae
*
* @param keyEventCode The key code to send, use a key code defined in Android's [KeyEvent]
* @param metaState Flags indicating which meta keys are currently pressed.
*/
fun sendDownUpKeyEvents(keyEventCode: Int, metaState: Int) {
val ic = ims?.currentInputConnection ?: return
val eventTime = SystemClock.uptimeMillis()
ic.sendKeyEvent(
KeyEvent(
eventTime,
eventTime,
KeyEvent.ACTION_DOWN,
keyEventCode,
0,
metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD,
0,
KeyEvent.FLAG_SOFT_KEYBOARD or KeyEvent.FLAG_KEEP_TOUCH_MODE
)
)
ic.sendKeyEvent(
KeyEvent(
eventTime,
SystemClock.uptimeMillis(),
KeyEvent.ACTION_UP,
keyEventCode,
0,
metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD,
0,
KeyEvent.FLAG_SOFT_KEYBOARD or KeyEvent.FLAG_KEEP_TOUCH_MODE
)
)
}
/**
* Sets the selection region of this instance and notifies the input connection.
*
@@ -478,6 +607,44 @@ class EditorInstance private constructor(private val ims: InputMethodService?) {
}
}
/**
*Adds one word on the left of selection to it
*
* @return True on success, false if no new words are selected
*/
fun leftAppendWordToSelection(): Boolean{
// no words left to select
if (selection.start <= 0)
return false
val stringBeforeSelection = cachedText.substring(
0,
selection.start
)
getWordsInString(stringBeforeSelection).last().range.apply {
setSelection(first, selection.end)
}
return true
}
/**
*Removes one word on the left from the selection
*
* @return True on success, false if no new words are deselected
*/
fun leftPopWordFromSelection(): Boolean{
// no words left to pop
if (selection.start >= selection.end)
return false
val stringInsideSelection = cachedText.substring(
selection.start,
selection.end
)
getWordsInString(stringInsideSelection).first().range.apply {
setSelection(selection.start + last + 1, selection.end)
}
return true
}
/**
* Detects the length of the character before the cursor, as many Unicode characters nowadays
* are longer than 1 Java char and thus the length has to be calculated in order to avoid
@@ -675,7 +842,7 @@ class ImeOptions private constructor(imeOptions: Int) {
PREVIOUS -> EditorInfo.IME_ACTION_PREVIOUS
SEARCH -> EditorInfo.IME_ACTION_SEARCH
SEND -> EditorInfo.IME_ACTION_SEND
UNSPECIFIED-> EditorInfo.IME_ACTION_UNSPECIFIED
UNSPECIFIED -> EditorInfo.IME_ACTION_UNSPECIFIED
}
}
}

View File

@@ -17,11 +17,15 @@
package dev.patrickgold.florisboard.ime.core
import android.app.Application
import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.crashutility.CrashUtility
import timber.log.Timber
class FlorisApplication : Application() {
override fun onCreate() {
super.onCreate()
CrashUtility.install(this)
if (BuildConfig.DEBUG)
Timber.plant(Timber.DebugTree())
}
}

View File

@@ -45,6 +45,7 @@ import dev.patrickgold.florisboard.ime.text.key.KeyData
import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardMode
import dev.patrickgold.florisboard.settings.SettingsMainActivity
import dev.patrickgold.florisboard.util.*
import timber.log.Timber
import java.lang.ref.WeakReference
/**
@@ -94,16 +95,15 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
companion object {
private const val IME_ID: String = "dev.patrickgold.florisboard/.ime.core.FlorisBoard"
private const val IME_ID_DEBUG: String = "dev.patrickgold.florisboard.debug/dev.patrickgold.florisboard.ime.core.FlorisBoard"
private val TAG: String? = FlorisBoard::class.simpleName
fun checkIfImeIsEnabled(context: Context): Boolean {
val activeImeIds = Settings.Secure.getString(
context.contentResolver,
Settings.Secure.ENABLED_INPUT_METHODS
)
Timber.i("List of active IMEs: $activeImeIds")
return when {
BuildConfig.DEBUG -> {
Log.i(FlorisBoard::class.simpleName, "List of active IMEs: $activeImeIds")
activeImeIds.split(":").contains(IME_ID_DEBUG)
}
else -> {
@@ -117,9 +117,9 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
context.contentResolver,
Settings.Secure.DEFAULT_INPUT_METHOD
)
Timber.i("Selected IME: $selectedImeId")
return when {
BuildConfig.DEBUG -> {
Log.i(FlorisBoard::class.simpleName, "Selected IME: $selectedImeId")
selectedImeId == IME_ID_DEBUG
}
else -> {
@@ -165,7 +165,7 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
.build()
)
}
if (BuildConfig.DEBUG) Log.i(TAG, "onCreate()")
Timber.i("onCreate()")
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
@@ -191,7 +191,7 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
@SuppressLint("InflateParams")
override fun onCreateInputView(): View? {
if (BuildConfig.DEBUG) Log.i(TAG, "onCreateInputView()")
Timber.i("onCreateInputView()")
baseContext.setTheme(currentThemeResId)
@@ -203,7 +203,7 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
fun registerInputView(inputView: InputView) {
if (BuildConfig.DEBUG) Log.i(TAG, "registerInputView($inputView)")
Timber.i("registerInputView($inputView)")
this.inputView = inputView
initializeOneHandedEnvironment()
@@ -215,7 +215,7 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
override fun onDestroy() {
if (BuildConfig.DEBUG) Log.i(TAG, "onDestroy()")
Timber.i("onDestroy()")
clipboardManager?.removePrimaryClipChangedListener(this)
osHandler.removeCallbacksAndMessages(null)
@@ -227,15 +227,15 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
if (BuildConfig.DEBUG) Log.i(TAG, "onStartInput($attribute, $restarting)")
Timber.i("onStartInput($attribute, $restarting)")
super.onStartInput(attribute, restarting)
currentInputConnection?.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE)
}
override fun onStartInputView(info: EditorInfo?, restarting: Boolean) {
if (BuildConfig.DEBUG) Log.i(TAG, "onStartInputView($info, $restarting)")
Log.i(TAG, "onStartInputView: " + info?.debugSummarize())
Timber.i("onStartInputView($info, $restarting)")
Timber.i("onStartInputView: ${info?.debugSummarize()}")
super.onStartInputView(info, restarting)
activeEditorInstance = EditorInstance.from(info, this)
@@ -245,7 +245,7 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
override fun onFinishInputView(finishingInput: Boolean) {
if (BuildConfig.DEBUG) Log.i(TAG, "onFinishInputView($finishingInput)")
Timber.i( "onFinishInputView($finishingInput)")
if (finishingInput) {
activeEditorInstance = EditorInstance.default()
@@ -256,14 +256,14 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
override fun onFinishInput() {
if (BuildConfig.DEBUG) Log.i(TAG, "onFinishInput()")
Timber.i("onFinishInput()")
super.onFinishInput()
currentInputConnection?.requestCursorUpdates(0)
}
override fun onWindowShown() {
if (BuildConfig.DEBUG) Log.i(TAG, "onWindowShown()")
Timber.i("onWindowShown()")
prefs.sync()
val newIsNumberRowVisible = prefs.keyboard.numberRow
@@ -282,14 +282,14 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
override fun onWindowHidden() {
if (BuildConfig.DEBUG) Log.i(TAG, "onWindowHidden()")
Timber.i("onWindowHidden()")
super.onWindowHidden()
eventListeners.toList().forEach { it?.get()?.onWindowHidden() }
}
override fun onConfigurationChanged(newConfig: Configuration) {
if (BuildConfig.DEBUG) Log.i(TAG, "onConfigurationChanged($newConfig)")
Timber.i("onConfigurationChanged($newConfig)")
if (isInputViewShown) {
updateOneHandedPanelVisibility()
}
@@ -302,7 +302,7 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
newSelStart: Int, newSelEnd: Int,
candidatesStart: Int, candidatesEnd: Int
) {
if (BuildConfig.DEBUG) Log.i(TAG, "onUpdateSelection($oldSelStart, $oldSelEnd, $newSelStart, $newSelEnd, $candidatesStart, $candidatesEnd)")
Timber.i("onUpdateSelection($oldSelStart, $oldSelEnd, $newSelStart, $newSelEnd, $candidatesStart, $candidatesEnd)")
super.onUpdateSelection(
oldSelStart, oldSelEnd,
@@ -361,14 +361,12 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
inputView?.setBackgroundColor(prefs.theme.keyboardBgColor)
inputView?.oneHandedCtrlPanelStart?.setBackgroundColor(prefs.theme.oneHandedBgColor)
inputView?.oneHandedCtrlPanelEnd?.setBackgroundColor(prefs.theme.oneHandedBgColor)
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_move_start)
?.imageTintList = ColorStateList.valueOf(prefs.theme.oneHandedButtonFgColor)
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_move_end)
?.imageTintList = ColorStateList.valueOf(prefs.theme.oneHandedButtonFgColor)
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_close_start)
?.imageTintList = ColorStateList.valueOf(prefs.theme.oneHandedButtonFgColor)
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_close_end)
?.imageTintList = ColorStateList.valueOf(prefs.theme.oneHandedButtonFgColor)
ColorStateList.valueOf(prefs.theme.oneHandedButtonFgColor).also {
inputView?.oneHandedCtrlMoveStart?.imageTintList = it
inputView?.oneHandedCtrlMoveEnd?.imageTintList = it
inputView?.oneHandedCtrlCloseStart?.imageTintList = it
inputView?.oneHandedCtrlCloseEnd?.imageTintList = it
}
eventListeners.toList().forEach { it?.get()?.onApplyThemeAttributes() }
}
@@ -517,14 +515,12 @@ class FlorisBoard : InputMethodService(), ClipboardManager.OnPrimaryClipChangedL
}
private fun initializeOneHandedEnvironment() {
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_move_start)
?.setOnClickListener { v -> onOneHandedPanelButtonClick(v) }
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_move_end)
?.setOnClickListener { v -> onOneHandedPanelButtonClick(v) }
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_close_start)
?.setOnClickListener { v -> onOneHandedPanelButtonClick(v) }
inputView?.findViewById<ImageButton>(R.id.one_handed_ctrl_close_end)
?.setOnClickListener { v -> onOneHandedPanelButtonClick(v) }
{ v:View -> onOneHandedPanelButtonClick(v) }.also {
inputView?.oneHandedCtrlMoveStart?.setOnClickListener(it)
inputView?.oneHandedCtrlMoveEnd?.setOnClickListener(it)
inputView?.oneHandedCtrlCloseStart?.setOnClickListener(it)
inputView?.oneHandedCtrlCloseEnd?.setOnClickListener(it)
}
}
private fun onOneHandedPanelButtonClick(v: View) {

View File

@@ -21,6 +21,7 @@ import android.content.res.Configuration
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.util.Log
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.ViewFlipper
import dev.patrickgold.florisboard.BuildConfig
@@ -28,6 +29,7 @@ import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.text.key.KeyVariation
import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardMode
import dev.patrickgold.florisboard.util.ViewLayoutUtils
import timber.log.Timber
import kotlin.math.roundToInt
/**
@@ -52,6 +54,14 @@ class InputView : LinearLayout {
private set
var oneHandedCtrlPanelEnd: LinearLayout? = null
private set
var oneHandedCtrlMoveStart: ImageButton? = null
private set
var oneHandedCtrlMoveEnd: ImageButton? = null
private set
var oneHandedCtrlCloseStart: ImageButton? = null
private set
var oneHandedCtrlCloseEnd: ImageButton? = null
private set
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
@@ -62,13 +72,17 @@ class InputView : LinearLayout {
)
override fun onAttachedToWindow() {
if (BuildConfig.DEBUG) Log.i(this::class.simpleName, "onAttachedToWindow()")
Timber.i("onAttachedToWindow()")
super.onAttachedToWindow()
mainViewFlipper = findViewById(R.id.main_view_flipper)
oneHandedCtrlPanelStart = findViewById(R.id.one_handed_ctrl_panel_start)
oneHandedCtrlPanelEnd = findViewById(R.id.one_handed_ctrl_panel_end)
oneHandedCtrlMoveStart = findViewById(R.id.one_handed_ctrl_move_start)
oneHandedCtrlMoveEnd = findViewById(R.id.one_handed_ctrl_move_end)
oneHandedCtrlCloseStart = findViewById(R.id.one_handed_ctrl_close_start)
oneHandedCtrlCloseEnd = findViewById(R.id.one_handed_ctrl_close_end)
florisboard.registerInputView(this)
}

View File

@@ -24,6 +24,7 @@ import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.text.gestures.DistanceThreshold
import dev.patrickgold.florisboard.ime.text.gestures.SwipeAction
import dev.patrickgold.florisboard.ime.text.gestures.VelocityThreshold
import dev.patrickgold.florisboard.ime.text.key.KeyHintMode
import dev.patrickgold.florisboard.util.VersionName
import kotlin.collections.HashMap
@@ -166,6 +167,7 @@ class PrefHelper(
companion object {
const val SETTINGS_THEME = "advanced__settings_theme"
const val SHOW_APP_ICON = "advanced__show_app_icon"
const val FORCE_PRIVATE_MODE = "advanced__force_private_mode"
}
var settingsTheme: String = ""
@@ -174,6 +176,9 @@ class PrefHelper(
var showAppIcon: Boolean = false
get() = prefHelper.getPref(SHOW_APP_ICON, true)
private set
var forcePrivateMode: Boolean
get() = prefHelper.getPref(FORCE_PRIVATE_MODE, false)
set(v) = prefHelper.setPref(FORCE_PRIVATE_MODE, v)
}
/**
@@ -307,8 +312,8 @@ class PrefHelper(
const val FONT_SIZE_MULTIPLIER_LANDSCAPE = "keyboard__font_size_multiplier_landscape"
const val HEIGHT_FACTOR = "keyboard__height_factor"
const val HEIGHT_FACTOR_CUSTOM = "keyboard__height_factor_custom"
const val HINTED_NUMBER_ROW = "keyboard__hinted_number_row"
const val HINTED_SYMBOLS = "keyboard__hinted_symbols"
const val HINTED_NUMBER_ROW_MODE = "keyboard__hinted_number_row_mode"
const val HINTED_SYMBOLS_MODE = "keyboard__hinted_symbols_mode"
const val LONG_PRESS_DELAY = "keyboard__long_press_delay"
const val NUMBER_ROW = "keyboard__number_row"
const val ONE_HANDED_MODE = "keyboard__one_handed_mode"
@@ -334,12 +339,12 @@ class PrefHelper(
var heightFactorCustom: Int
get() = prefHelper.getPref(HEIGHT_FACTOR_CUSTOM, 100)
set(v) = prefHelper.setPref(HEIGHT_FACTOR_CUSTOM, v)
var hintedNumberRow: Boolean
get() = prefHelper.getPref(HINTED_NUMBER_ROW, true)
set(v) = prefHelper.setPref(HINTED_NUMBER_ROW, v)
var hintedSymbols: Boolean
get() = prefHelper.getPref(HINTED_SYMBOLS, true)
set(v) = prefHelper.setPref(HINTED_SYMBOLS, v)
var hintedNumberRowMode: KeyHintMode
get() = KeyHintMode.fromString(prefHelper.getPref(HINTED_NUMBER_ROW_MODE, KeyHintMode.ENABLED_ACCENT_PRIORITY.toString()))
set(v) = prefHelper.setPref(HINTED_NUMBER_ROW_MODE, v)
var hintedSymbolsMode: KeyHintMode
get() = KeyHintMode.fromString(prefHelper.getPref(HINTED_SYMBOLS_MODE, KeyHintMode.ENABLED_ACCENT_PRIORITY.toString()))
set(v) = prefHelper.setPref(HINTED_SYMBOLS_MODE, v)
var longPressDelay: Int = 0
get() = prefHelper.getPref(LONG_PRESS_DELAY, 300)
private set
@@ -447,6 +452,8 @@ class PrefHelper(
const val MEDIA_FG_COLOR_ALT = "theme__media_fgColorAlt"
const val ONE_HANDED_BG_COLOR = "theme__oneHanded_bgColor"
const val ONE_HANDED_BUTTON_FG_COLOR = "theme__oneHandedButton_fgColor"
const val PRIVATE_MODE_BG_COLOR = "theme__privateMode_bgColor"
const val PRIVATE_MODE_FG_COLOR = "theme__privateMode_fgColor"
const val SMARTBAR_BG_COLOR = "theme__smartbar_bgColor"
const val SMARTBAR_FG_COLOR = "theme__smartbar_fgColor"
const val SMARTBAR_FG_COLOR_ALT = "theme__smartbar_fgColorAlt"
@@ -523,6 +530,12 @@ class PrefHelper(
var oneHandedButtonFgColor: Int
get() = prefHelper.getPref(ONE_HANDED_BUTTON_FG_COLOR, 0)
set(v) = prefHelper.setPref(ONE_HANDED_BUTTON_FG_COLOR, v)
var privateModeBgColor: Int
get() = prefHelper.getPref(PRIVATE_MODE_BG_COLOR, 0)
set(v) = prefHelper.setPref(PRIVATE_MODE_BG_COLOR, v)
var privateModeFgColor: Int
get() = prefHelper.getPref(PRIVATE_MODE_FG_COLOR, 0)
set(v) = prefHelper.setPref(PRIVATE_MODE_FG_COLOR, v)
var smartbarBgColor: Int
get() = prefHelper.getPref(SMARTBAR_BG_COLOR, 0)
set(v) = prefHelper.setPref(SMARTBAR_BG_COLOR, v)

View File

@@ -17,6 +17,7 @@
package dev.patrickgold.florisboard.ime.media
import android.annotation.SuppressLint
import android.os.Handler
import android.util.Log
import android.view.MotionEvent
import android.view.View
@@ -34,7 +35,10 @@ import dev.patrickgold.florisboard.ime.media.emoticon.EmoticonKeyboardView
import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.key.KeyData
import dev.patrickgold.florisboard.ime.text.key.KeyType
import dev.patrickgold.florisboard.util.cancelAll
import dev.patrickgold.florisboard.util.postAtScheduledRate
import kotlinx.coroutines.*
import timber.log.Timber
import java.util.*
/**
@@ -56,7 +60,7 @@ class MediaInputManager private constructor() : CoroutineScope by MainScope(),
private var activeTab: Tab? = null
private var mediaViewFlipper: ViewFlipper? = null
private var osTimer: Timer? = null
private var repeatedKeyPressHandler: Handler? = null
private var tabLayout: TabLayout? = null
private val tabViews = EnumMap<Tab, LinearLayout>(Tab::class.java)
@@ -78,6 +82,11 @@ class MediaInputManager private constructor() : CoroutineScope by MainScope(),
florisboard.addEventListener(this)
}
override fun onCreateInputView() {
super.onCreateInputView()
repeatedKeyPressHandler = Handler(florisboard.context.mainLooper)
}
/**
* Called when a new input view has been registered. Used to initialize all media-relevant
* views and layouts.
@@ -85,7 +94,7 @@ class MediaInputManager private constructor() : CoroutineScope by MainScope(),
*/
@SuppressLint("ClickableViewAccessibility")
override fun onRegisterInputView(inputView: InputView) {
if (BuildConfig.DEBUG) Log.i(this::class.simpleName, "onRegisterInputView(inputView)")
Timber.i("onRegisterInputView(inputView)")
launch(Dispatchers.Default) {
mediaViewGroup = inputView.findViewById(R.id.media_input)
@@ -126,7 +135,7 @@ class MediaInputManager private constructor() : CoroutineScope by MainScope(),
* Clean-up of resources and stopping all coroutines.
*/
override fun onDestroy() {
if (BuildConfig.DEBUG) Log.i(this::class.simpleName, "onDestroy()")
Timber.i("onDestroy()")
cancel()
instance = null
@@ -151,17 +160,14 @@ class MediaInputManager private constructor() : CoroutineScope by MainScope(),
florisboard.keyPressVibrate()
florisboard.keyPressSound(data)
if (data?.code == KeyCode.DELETE && data.type == KeyType.ENTER_EDITING) {
osTimer = Timer()
osTimer?.scheduleAtFixedRate(object : TimerTask() {
override fun run() {
florisboard.textInputManager.sendKeyPress(data)
}
}, 500, 50)
val delayMillis = florisboard.prefs.keyboard.longPressDelay.toLong()
repeatedKeyPressHandler?.postAtScheduledRate(delayMillis, 25) {
florisboard.textInputManager.sendKeyPress(data)
}
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
osTimer?.cancel()
osTimer = null
repeatedKeyPressHandler?.cancelAll()
if (event.actionMasked != MotionEvent.ACTION_CANCEL && data != null) {
florisboard.textInputManager.sendKeyPress(data)
}

View File

@@ -21,6 +21,7 @@ import android.graphics.Paint
import android.graphics.Typeface
import android.util.Log
import androidx.core.graphics.PaintCompat
import timber.log.Timber
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
@@ -171,13 +172,13 @@ fun parseRawEmojiSpecsFile(
}
}
} catch (e: IOException) {
Log.e("EmojiLayoutDataMap", "parseRawEmojiSpecsFile(): $e")
Timber.e("parseRawEmojiSpecsFile(): $e")
} finally {
if (reader != null) {
try {
reader.close()
} catch (e: IOException) {
Log.e("EmojiLayoutDataMap", "parseRawEmojiSpecsFile(): $e")
Timber.e("parseRawEmojiSpecsFile(): $e")
}
}
}

View File

@@ -34,6 +34,7 @@ import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.key.KeyData
import dev.patrickgold.florisboard.ime.text.key.KeyView
import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardView
import dev.patrickgold.florisboard.util.ViewLayoutUtils
/**
* Manages the creation and dismissal of key popups as well as the checks if the pointer moved
@@ -146,11 +147,13 @@ class KeyPopupManager<T_KBD: View, T_KV: View>(private val keyboardView: T_KBD)
* @return A new [PopupWindow] already preconfigured and ready-to-go.
*/
private fun createPopupWindow(view: View): PopupWindow {
return PopupWindow(keyboardView.context).apply {
return PopupWindow(view.context).apply {
animationStyle = 0
contentView = view
elevation = ViewLayoutUtils.convertDpToPixel(2.0f, view.context)
enterTransition = null
exitTransition = null
isAttachedInDecor = false
isClippingEnabled = false
isFocusable = false
isTouchable = false

View File

@@ -22,6 +22,7 @@ import android.util.Log
import android.view.KeyEvent
import android.view.inputmethod.*
import android.widget.LinearLayout
import android.widget.Toast
import android.widget.ViewFlipper
import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.R
@@ -37,6 +38,7 @@ import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardView
import dev.patrickgold.florisboard.ime.text.layout.LayoutManager
import dev.patrickgold.florisboard.ime.text.smartbar.SmartbarView
import kotlinx.coroutines.*
import timber.log.Timber
import java.util.*
/**
@@ -82,7 +84,6 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
private var isManualSelectionModeRight: Boolean = false
companion object {
private val TAG: String? = TextInputManager::class.simpleName
private var instance: TextInputManager? = null
@Synchronized
@@ -103,7 +104,7 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
* background).
*/
override fun onCreate() {
if (BuildConfig.DEBUG) Log.i(TAG, "onCreate()")
Timber.i("onCreate()")
var subtypes = florisboard.subtypeManager.subtypes
if (subtypes.isEmpty()) {
@@ -129,7 +130,7 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
* Sets up the newly registered input view.
*/
override fun onRegisterInputView(inputView: InputView) {
if (BuildConfig.DEBUG) Log.i(TAG, "onRegisterInputView(inputView)")
Timber.i("onRegisterInputView(inputView)")
launch(Dispatchers.Default) {
textViewGroup = inputView.findViewById(R.id.text_input)
@@ -158,7 +159,7 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
* Cancels all coroutines and cleans up.
*/
override fun onDestroy() {
if (BuildConfig.DEBUG) Log.i(TAG, "onDestroy()")
Timber.i("onDestroy()")
cancel()
osHandler.removeCallbacksAndMessages(null)
@@ -206,14 +207,18 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
KeyboardMode.CHARACTERS
}
}
instance.isComposingEnabled = when (keyboardMode) {
KeyboardMode.NUMERIC,
KeyboardMode.PHONE,
KeyboardMode.PHONE2 -> false
else -> keyVariation != KeyVariation.PASSWORD &&
florisboard.prefs.suggestion.enabled// &&
//!instance.inputAttributes.flagTextAutoComplete &&
//!instance.inputAttributes.flagTextNoSuggestions
instance.apply {
isComposingEnabled = when (keyboardMode) {
KeyboardMode.NUMERIC,
KeyboardMode.PHONE,
KeyboardMode.PHONE2 -> false
else -> keyVariation != KeyVariation.PASSWORD &&
florisboard.prefs.suggestion.enabled// &&
//!instance.inputAttributes.flagTextAutoComplete &&
//!instance.inputAttributes.flagTextNoSuggestions
}
isPrivateMode = florisboard.prefs.advanced.forcePrivateMode ||
imeOptions.flagNoPersonalizedLearning
}
if (!florisboard.prefs.correction.rememberCapsLockState) {
capsLock = false
@@ -323,6 +328,10 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
setActiveKeyboardMode(KeyboardMode.CHARACTERS)
}
override fun onSmartbarPrivateModeButtonClicked() {
Toast.makeText(florisboard.context, R.string.private_mode_dialog__title, Toast.LENGTH_LONG).show()
}
override fun onSmartbarQuickActionPressed(quickActionId: Int) {
when (quickActionId) {
R.id.quick_action_switch_to_editing_context -> {
@@ -335,11 +344,27 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
R.id.quick_action_switch_to_media_context -> florisboard.setActiveInput(R.id.media_input)
R.id.quick_action_open_settings -> florisboard.launchSettings()
R.id.quick_action_one_handed_toggle -> florisboard.toggleOneHandedMode()
R.id.quick_action_undo -> {
handleUndo()
return
}
R.id.quick_action_redo -> {
handleRedo()
return
}
}
smartbarView?.isQuickActionsVisible = false
smartbarView?.updateSmartbarState()
}
private fun handleUndo(){
activeEditorInstance.performUndo()
}
private fun handleRedo(){
activeEditorInstance.performRedo()
}
/**
* Handles a [KeyCode.DELETE] event.
*/
@@ -653,7 +678,7 @@ class TextInputManager private constructor() : CoroutineScope by MainScope(),
}
}
else -> {
Log.e(TAG,"sendKeyPress(keyData): Received unknown key: $keyData")
Timber.e("sendKeyPress(keyData): Received unknown key: $keyData")
}
}
}

View File

@@ -23,6 +23,7 @@ import android.content.res.Configuration
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Typeface
import android.os.Handler
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.Button
@@ -32,7 +33,8 @@ import dev.patrickgold.florisboard.ime.core.FlorisBoard
import dev.patrickgold.florisboard.ime.core.PrefHelper
import dev.patrickgold.florisboard.ime.text.key.KeyCode
import dev.patrickgold.florisboard.ime.text.key.KeyData
import java.util.*
import dev.patrickgold.florisboard.util.cancelAll
import dev.patrickgold.florisboard.util.postAtScheduledRate
/**
* View class for managing and rendering an editing key.
@@ -42,7 +44,7 @@ class EditingKeyView : AppCompatImageButton {
private val prefs: PrefHelper = PrefHelper.getDefaultInstance(context)
private val data: KeyData
private var isKeyPressed: Boolean = false
private var osTimer: Timer? = null
private val repeatedKeyPressHandler: Handler = Handler(context.mainLooper)
private var label: String? = null
private var labelPaint: Paint = Paint().apply {
@@ -100,23 +102,20 @@ class EditingKeyView : AppCompatImageButton {
KeyCode.ARROW_RIGHT,
KeyCode.ARROW_UP,
KeyCode.DELETE -> {
osTimer = Timer()
osTimer?.scheduleAtFixedRate(object : TimerTask() {
override fun run() {
val delayMillis = prefs.keyboard.longPressDelay.toLong()
repeatedKeyPressHandler.postAtScheduledRate(delayMillis, 25) {
if (isKeyPressed) {
florisboard?.textInputManager?.sendKeyPress(data)
if (!isKeyPressed) {
osTimer?.cancel()
osTimer = null
}
} else {
repeatedKeyPressHandler.cancelAll()
}
}, 500, 50)
}
}
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
isKeyPressed = false
osTimer?.cancel()
osTimer = null
repeatedKeyPressHandler.cancelAll()
if (event.actionMasked != MotionEvent.ACTION_CANCEL) {
florisboard?.textInputManager?.sendKeyPress(data)
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 Patrick Goldinger
*
* 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 dev.patrickgold.florisboard.ime.text.key
import java.util.*
/**
* Enum for the key hint modes.
*/
enum class KeyHintMode {
DISABLED,
ENABLED_HINT_PRIORITY,
ENABLED_ACCENT_PRIORITY,
ENABLED_SMART_PRIORITY;
companion object {
fun fromString(string: String): KeyHintMode {
return valueOf(string.toUpperCase(Locale.ROOT))
}
}
override fun toString(): String {
return super.toString().toLowerCase(Locale.ROOT)
}
}

View File

@@ -38,6 +38,9 @@ import dev.patrickgold.florisboard.ime.text.gestures.SwipeAction
import dev.patrickgold.florisboard.ime.text.gestures.SwipeGesture
import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardMode
import dev.patrickgold.florisboard.ime.text.keyboard.KeyboardView
import dev.patrickgold.florisboard.util.cancelAll
import dev.patrickgold.florisboard.util.postAtScheduledRate
import dev.patrickgold.florisboard.util.postDelayed
import dev.patrickgold.florisboard.util.setBackgroundTintColor2
import java.util.*
@@ -61,8 +64,8 @@ class KeyView(
updateKeyPressedBackground()
}
private var hasTriggeredGestureMove: Boolean = false
private var osHandler: Handler? = null
private var osTimer: Timer? = null
private val longKeyPressHandler: Handler = Handler(context.mainLooper)
private val repeatedKeyPressHandler: Handler = Handler(context.mainLooper)
private val prefs: PrefHelper = PrefHelper.getDefaultInstance(context)
private var shouldBlockNextKeyCode: Boolean = false
@@ -143,19 +146,26 @@ class KeyView(
elevation = 4.0f
var hintKeyData: KeyData? = null
var hintKeyMode: KeyHintMode = KeyHintMode.DISABLED
val hintedNumber = data.hintedNumber
if (prefs.keyboard.hintedNumberRow && hintedNumber != null) {
if (prefs.keyboard.hintedNumberRowMode != KeyHintMode.DISABLED && hintedNumber != null) {
hintKeyData = hintedNumber
hintKeyMode = prefs.keyboard.hintedNumberRowMode
}
val hintedSymbol = data.hintedSymbol
if (prefs.keyboard.hintedSymbols && hintedSymbol != null) {
if (prefs.keyboard.hintedSymbolsMode != KeyHintMode.DISABLED && hintedSymbol != null) {
hintKeyData = hintedSymbol
hintKeyMode = prefs.keyboard.hintedSymbolsMode
}
dataPopupWithHint = if (hintKeyData == null) {
data.popup.toMutableList()
} else {
val popupList = data.popup.toMutableList()
popupList.add(hintKeyData)
if (hintKeyMode == KeyHintMode.ENABLED_HINT_PRIORITY) {
popupList.add(0, hintKeyData)
} else {
popupList.add(hintKeyData)
}
popupList
}
@@ -210,14 +220,14 @@ class KeyView(
if (event == null || !isEnabled) return false
if (swipeGestureDetector.onTouchEvent(event)) {
isKeyPressed = false
osHandler?.removeCallbacksAndMessages(null)
osTimer?.cancel()
osTimer = null
longKeyPressHandler.cancelAll()
repeatedKeyPressHandler.cancelAll()
keyboardView.popupManager.hide()
return true
}
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
val delayMillis = prefs.keyboard.longPressDelay.toLong()
hasTriggeredGestureMove = false
shouldBlockNextKeyCode = false
florisboard?.prefs?.keyboard?.let {
@@ -228,23 +238,22 @@ class KeyView(
isKeyPressed = true
florisboard?.keyPressVibrate()
florisboard?.keyPressSound(data)
if (data.code == KeyCode.DELETE && data.type == KeyType.ENTER_EDITING) {
osTimer = Timer()
osTimer?.scheduleAtFixedRate(object : TimerTask() {
override fun run() {
florisboard?.textInputManager?.sendKeyPress(data)
if (!isKeyPressed) {
osTimer?.cancel()
osTimer = null
when (data.code) {
KeyCode.ARROW_DOWN,
KeyCode.ARROW_LEFT,
KeyCode.ARROW_RIGHT,
KeyCode.ARROW_UP,
KeyCode.DELETE -> {
repeatedKeyPressHandler.postAtScheduledRate(delayMillis, 25) {
if (isKeyPressed) {
florisboard?.textInputManager?.sendKeyPress(data)
} else {
repeatedKeyPressHandler.cancelAll()
}
}
}, 500, 50)
}
}
val delayMillis = prefs.keyboard.longPressDelay
if (osHandler == null) {
osHandler = Handler()
}
osHandler?.postDelayed({
longKeyPressHandler.postDelayed(delayMillis) {
if (dataPopupWithHint.isNotEmpty()) {
keyboardView.popupManager.extend(this)
}
@@ -257,7 +266,7 @@ class KeyView(
)
shouldBlockNextKeyCode = true
}
}, delayMillis.toLong())
}
}
MotionEvent.ACTION_MOVE -> {
if (keyboardView.popupManager.isShowingExtendedPopup) {
@@ -281,9 +290,8 @@ class KeyView(
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
isKeyPressed = false
osHandler?.removeCallbacksAndMessages(null)
osTimer?.cancel()
osTimer = null
longKeyPressHandler.cancelAll()
repeatedKeyPressHandler.cancelAll()
if (hasTriggeredGestureMove && data.code == KeyCode.DELETE) {
hasTriggeredGestureMove = false
florisboard?.activeEditorInstance?.apply {
@@ -296,7 +304,6 @@ class KeyView(
keyboardView.popupManager.hide()
if (event.actionMasked != MotionEvent.ACTION_CANCEL && !shouldBlockNextKeyCode && retData != null) {
florisboard?.textInputManager?.sendKeyPress(retData)
performClick()
} else {
shouldBlockNextKeyCode = false
}
@@ -327,6 +334,15 @@ class KeyView(
shouldBlockNextKeyCode = true
true
}
SwipeAction.DELETE_WORDS_PRECISELY -> {
florisboard?.activeEditorInstance?.apply {
leftAppendWordToSelection()
}
hasTriggeredGestureMove = true
shouldBlockNextKeyCode = true
true
}
else -> false
}
SwipeGesture.Direction.RIGHT -> when (prefs.gestures.deleteKeySwipeLeft) {
@@ -340,6 +356,14 @@ class KeyView(
shouldBlockNextKeyCode = true
true
}
SwipeAction.DELETE_WORDS_PRECISELY -> {
florisboard?.activeEditorInstance?.apply {
leftPopWordFromSelection()
}
shouldBlockNextKeyCode = true
true
}
else -> false
}
else -> false
@@ -629,11 +653,11 @@ class KeyView(
) {
label = getComputedLetter()
val hintedNumber = data.hintedNumber
if (prefs.keyboard.hintedNumberRow && hintedNumber != null) {
if (prefs.keyboard.hintedNumberRowMode != KeyHintMode.DISABLED && hintedNumber != null) {
hintedLabel = getComputedLetter(hintedNumber)
}
val hintedSymbol = data.hintedSymbol
if (prefs.keyboard.hintedSymbols && hintedSymbol != null) {
if (prefs.keyboard.hintedSymbolsMode != KeyHintMode.DISABLED && hintedSymbol != null) {
hintedLabel = getComputedLetter(hintedSymbol)
}

View File

@@ -19,6 +19,7 @@ package dev.patrickgold.florisboard.ime.text.smartbar
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.ime.core.PrefHelper
import dev.patrickgold.florisboard.util.setBackgroundTintColor2
@@ -52,7 +53,12 @@ class SmartbarQuickActionButton : androidx.appcompat.widget.AppCompatImageButton
}
private fun updateTheme() {
setBackgroundTintColor2(this, prefs.theme.smartbarButtonBgColor)
setColorFilter(prefs.theme.smartbarButtonFgColor)
if (id == R.id.private_mode_button) {
setBackgroundTintColor2(this, prefs.theme.privateModeBgColor)
setColorFilter(prefs.theme.privateModeFgColor)
} else {
setBackgroundTintColor2(this, prefs.theme.smartbarButtonBgColor)
setColorFilter(prefs.theme.smartbarButtonFgColor)
}
}
}

View File

@@ -19,13 +19,11 @@ package dev.patrickgold.florisboard.ime.text.smartbar
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.Button
import androidx.annotation.IdRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import dev.patrickgold.florisboard.BuildConfig
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.databinding.SmartbarBinding
import dev.patrickgold.florisboard.ime.core.FlorisBoard
@@ -38,6 +36,7 @@ import dev.patrickgold.florisboard.util.setDrawableTintColor2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.lang.ref.WeakReference
import kotlin.math.roundToInt
@@ -83,7 +82,7 @@ class SmartbarView : ConstraintLayout {
* TextInputManager, which then starts working together with this view.
*/
override fun onAttachedToWindow() {
if (BuildConfig.DEBUG) Log.i(this::class.simpleName, "onAttachedToWindow()")
Timber.i("onAttachedToWindow()")
super.onAttachedToWindow()
@@ -141,6 +140,10 @@ class SmartbarView : ConstraintLayout {
}
}
binding.privateModeButton.setOnClickListener {
eventListener?.get()?.onSmartbarPrivateModeButtonClicked()
}
for (quickAction in binding.quickActions.children) {
if (quickAction is SmartbarQuickActionButton) {
quickAction.setOnClickListener { eventListener?.get()?.onSmartbarQuickActionPressed(quickAction.id) }
@@ -258,15 +261,19 @@ class SmartbarView : ConstraintLayout {
KeyVariation.PASSWORD -> false
else -> true
},
actionEndAreaId = null
actionEndAreaId = when {
florisboard.activeEditorInstance.isPrivateMode -> R.id.private_mode_button
else -> null
}
)
}
}
fun onPrimaryClipChanged() {
if (prefs.suggestion.enabled && prefs.suggestion.suggestClipboardContent) {
if (prefs.suggestion.enabled && prefs.suggestion.suggestClipboardContent &&
florisboard?.activeEditorInstance?.isPrivateMode == false) {
shouldSuggestClipboardContents = true
val item = florisboard?.clipboardManager?.primaryClip?.getItemAt(0)
val item = florisboard.clipboardManager?.primaryClip?.getItemAt(0)
when {
item?.text != null -> {
binding.clipboardSuggestion.text = item.text
@@ -283,10 +290,8 @@ class SmartbarView : ConstraintLayout {
}
fun resetClipboardSuggestion() {
if (prefs.suggestion.enabled && prefs.suggestion.suggestClipboardContent) {
shouldSuggestClipboardContents = false
updateSmartbarState()
}
shouldSuggestClipboardContents = false
updateSmartbarState()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
@@ -333,6 +338,7 @@ class SmartbarView : ConstraintLayout {
fun onSmartbarBackButtonPressed() {}
//fun onSmartbarCandidatePressed() {}
//fun onSmartbarCandidateLongPressed() {}
fun onSmartbarPrivateModeButtonClicked() {}
fun onSmartbarQuickActionPressed(@IdRes quickActionId: Int) {}
}
}

View File

@@ -162,6 +162,9 @@ data class Theme(
prefs.theme.oneHandedButtonFgColor = theme.getAttr("oneHandedButton/fgColor", "#424242")
prefs.theme.privateModeBgColor = theme.getAttr("privateMode/bgColor", "#A000FF")
prefs.theme.privateModeFgColor = theme.getAttr("privateMode/fgColor", "#FFFFFF")
prefs.theme.smartbarBgColor = theme.getAttr("smartbar/bgColor", "#E0E0E0")
prefs.theme.smartbarFgColor = theme.getAttr("smartbar/fgColor", "#000000")
prefs.theme.smartbarFgColorAlt = theme.getAttr("smartbar/fgColorAlt", "#4A000000")

View File

@@ -0,0 +1,21 @@
package dev.patrickgold.florisboard.util
import android.os.Handler
fun Handler.postAtScheduledRate(delayMillis: Long, periodMillis: Long, r: Runnable) {
val internalRunnable = object : Runnable {
override fun run() {
this@postAtScheduledRate.postDelayed(this, periodMillis)
r.run()
}
}
this.postDelayed(internalRunnable, delayMillis)
}
fun Handler.postDelayed(delayMillis: Long, r: Runnable) {
this.postDelayed(r, delayMillis)
}
fun Handler.cancelAll() {
this.removeCallbacksAndMessages(null)
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,1L3,5v6c0,5.55 3.84,10.74 9,12 5.16,-1.26 9,-6.45 9,-12L21,5l-9,-4zM12,11.99h7c-0.53,4.12 -3.28,7.79 -7,8.94L12,12L5,12L5,6.3l7,-3.11v8.8z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12.5,8c-2.65,0 -5.05,0.99 -6.9,2.6L2,7v9h9l-3.62,-3.62c1.39,-1.16 3.16,-1.88 5.12,-1.88 3.54,0 6.55,2.31 7.6,5.5l2.37,-0.78C21.08,11.03 17.15,8 12.5,8z"/>
</vector>

View File

@@ -1,13 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp"/>
<solid android:color="#CDAFAFAF"/>
<corners android:radius="@dimen/key_borderRadius"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@android:color/white"/>

View File

@@ -79,6 +79,18 @@
android:id="@+id/quick_actions"
style="@style/SmartbarContainer">
<dev.patrickgold.florisboard.ime.text.smartbar.SmartbarQuickActionButton
android:id="@+id/quick_action_undo"
style="@style/SmartbarQuickAction"
android:contentDescription="@string/smartbar__quick_action__undo"
android:src="@drawable/ic_undo"/>
<dev.patrickgold.florisboard.ime.text.smartbar.SmartbarQuickActionButton
android:id="@+id/quick_action_redo"
style="@style/SmartbarQuickAction"
android:contentDescription="@string/smartbar__quick_action__redo"
android:src="@drawable/ic_redo"/>
<dev.patrickgold.florisboard.ime.text.smartbar.SmartbarQuickActionButton
android:id="@+id/quick_action_switch_to_media_context"
style="@style/SmartbarQuickAction"
@@ -128,14 +140,11 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<!-- Placeholder on the right which reserves the space for a second button -->
<dev.patrickgold.florisboard.ime.text.smartbar.SmartbarQuickActionButton
android:id="@+id/placeholder"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/smartbar_button_margin"
android:clickable="false"
android:visibility="invisible"/>
android:id="@+id/private_mode_button"
style="@style/SmartbarQuickAction.PrivateModeButton"
android:contentDescription="@string/smartbar__quick_action__private_mode"
android:src="@drawable/ic_security"/>
</dev.patrickgold.florisboard.ime.core.FlorisViewFlipper>

View File

@@ -93,10 +93,6 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">المفاتيح</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">صف الأعداد</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">إظهار صف الأعداد فوق تخطيط الحروف</string>
<string name="pref__keyboard__hinted_number_row__label" comment="Preference title">تلميح لصف الأعداد</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">الصف الأول لتخطيط الحروف يشير إلى صف الأرقام</string>
<string name="pref__keyboard__hinted_symbols__label" comment="Preference title">تلميح للرموز</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">الصف الثاني و الثالث لتخطيط الحروف يشير إلى الرموز</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">مضاعف حجم الخط (عمودي)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">مضاعف حجم الخط (أفقي)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">نظام التخطيط</string>

View File

@@ -91,8 +91,6 @@
<string name="pref__theme__navBarIsLight_summary" comment="Summary of Nav bar is light theme preference">Nastavte na Zapnuto pro tmavé nebo vypnuté pro světlé popředí.</string>
<string name="settings__keyboard__title" comment="Title of Keyboard preferences fragment">Předvolby Klávesnice</string>
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Šipka</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">První řádek rozvržení znaků naznačuje číslo řádku</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Druhá a třetí řada znakových symbolů nápovědy</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Multiplikátor velikosti písma (portrét)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Multiplikátor velikosti písma (Krajina)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Rozložení</string>

View File

@@ -91,8 +91,6 @@
<string name="pref__theme__navBarIsLight_summary" comment="Summary of Nav bar is light theme preference">EIN für dunklen oder AUS für hellen Vordergrund.</string>
<string name="settings__keyboard__title" comment="Title of Keyboard preferences fragment">Tastatur-Einstellungen</string>
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Tasten</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Erste Reihe der Tastatur deutet Zahlenreihe im Hintergrund an</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Zweite und dritte Reihe der Tastatur deuten Symbole im Hintergrund an</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Schriftgröße anpassen (Hochformat)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Schriftgröße anpassen (Querformat)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Layout</string>

View File

@@ -91,8 +91,6 @@
<string name="pref__theme__navBarIsLight_summary" comment="Summary of Nav bar is light theme preference">Ορίστε ΕΝΕΡΓΟΠΟΙΗΜΈΝΟ για σκούρο ή ΑΠΕΝΕΡΓΟΠΟΙΗΜΈΝΟ για φωτεινό προσκήνιο.</string>
<string name="settings__keyboard__title" comment="Title of Keyboard preferences fragment">Προτιμήσεις Πληκτρολογίου</string>
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Πλήκτρα</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Η πρώτη σειρά χαρακτήρων υπονοεί τη σειρά αριθμών</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Η δεύτερη και τρίτη σειρά διάταξης χαρακτήρων υπονοούν σύμβολα</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Πολλαπλασιαστής μεγέθους γραμματοσειράς (πορτραίτο)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Πολλαπλασιαστής μεγέθους γραμματοσειράς (τοπίο)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Διάταξη</string>

View File

@@ -43,10 +43,6 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">کلیدها</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">ردیف عدد</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">ردیف عددی که بالای چیدمان کاراکتر ها نمایش داده می شود</string>
<string name="pref__keyboard__hinted_number_row__label" comment="Preference title">ردیف عددی همیار</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">اولین ردیف از چیدمان کاراکتر ها به ردیف عدد اشاره می کند</string>
<string name="pref__keyboard__hinted_symbols__label" comment="Preference title">نشانه های همیار</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">دومین و سویم ردیف از کاراکتر ها در چیدمان به نماد ها اشاره می کند</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">اندازه فونت چند برابری(عمودی)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">اندازه فونت چند برابری(افقی)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">چیدمان</string>

View File

@@ -91,8 +91,6 @@
<string name="pref__theme__navBarIsLight_summary" comment="Summary of Nav bar is light theme preference">Aseta päälle tummia tai pois päältä vaaleita painikkeita varten.</string>
<string name="settings__keyboard__title" comment="Title of Keyboard preferences fragment">Näppäimistön asetukset</string>
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Painikkeet</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Numerot ensimmäisen näppäinrivin painikkeilla</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Symbolit toisen ja kolmannen näppäinrivin painikkeilla</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Fonttikoon kerroin (pystysuunnassa)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Fonttikoon kerroin (vaakasuunnassa)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Ulkoasu</string>

View File

@@ -93,10 +93,6 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Touches</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">Rangée de numéros</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">Afficher la rangée de numéros au dessus de la disposition des caractères</string>
<string name="pref__keyboard__hinted_number_row__label" comment="Preference title">Rangée de numéros subtile</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Première rangée de la configuration des caractères indique la rangée des numéros</string>
<string name="pref__keyboard__hinted_symbols__label" comment="Preference title">Astuce des symboles</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Deuxième et troisième rangées de la configuration des caractères indique des symboles</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Multiplicateur de la taille de la police (portrait)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Multiplicateur de la taille de la police (paysage)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Disposition</string>

View File

@@ -93,8 +93,6 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Billentyűk</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">Számsor</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">Számsor megjelenítése a karakterelrendezés felett</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">A karakterelrendezés első sora utal a számsorra</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Második és harmadik sor karakter elrendezés tipp szimbólumok</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Betűméret szorzó (álló)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Betűméret szorzó (fekvő)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Elrendezés</string>

View File

@@ -91,8 +91,6 @@
<string name="pref__theme__navBarIsLight_summary" comment="Summary of Nav bar is light theme preference">Imposta a ON per un colore di primo piano scuro e OFF per uno chiaro.</string>
<string name="settings__keyboard__title" comment="Title of Keyboard preferences fragment">Tastiera preferenze</string>
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Tasti</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Prima riga dei tasti contiene suggerimenti per i numeri</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">La seconda e terza riga suggeriscono simboli</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Moltiplicatore della dimensione del testo (ritratto)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Moltiplicatore della dimensione del testo (panorama)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Layout</string>

View File

@@ -91,8 +91,6 @@
<string name="pref__theme__navBarIsLight_summary" comment="Summary of Nav bar is light theme preference">Start op voor donker of uit voor lichte voorgrond.</string>
<string name="settings__keyboard__title" comment="Title of Keyboard preferences fragment">Toetsenbordvoorkeuren</string>
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Toets</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Eerste rij tekenopmaak geeft nummer rij</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Tweede en derde rij tekenopmaak hint symbolen</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Lettergrootte multiplier (portret)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Lettergrootte multiplier (landschap)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Lay</string>

View File

@@ -93,10 +93,6 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Teclas</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">Linha de números</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">Mostrar linha de números em cima do teclado</string>
<string name="pref__keyboard__hinted_number_row__label" comment="Preference title">Sugerir linha de números</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">A primeira linha de letras sugere números</string>
<string name="pref__keyboard__hinted_symbols__label" comment="Preference title">Sugerir símbolos</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">As segunda e terceira linhas de letras sugere símbolos</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Multiplicador de tamanho da fonte (retrato)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Multiplicador de tamanho da fonte (paisagem)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Layout</string>

View File

@@ -93,8 +93,6 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Teclas</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">Linha de números</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">Mostrar linha de números em cima do teclado</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">Mostrar números na primeira linha do teclado</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Mostrar símbolos na segunda e na terceira linha do teclado</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Multiplicador do tipo de letra (vertical)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Multiplicador do tipo de letra (horizontal)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Disposição</string>

View File

@@ -21,6 +21,20 @@
<item>custom</item>
</string-array>
<!-- TODO: implement smart priority -->
<string-array name="pref__keyboard__hint_mode__entries">
<item>@string/pref__keyboard__hint_mode__disabled</item>
<item>@string/pref__keyboard__hint_mode__enabled_hint_priority</item>
<item>@string/pref__keyboard__hint_mode__enabled_accent_priority</item>
<!--<item>@string/pref__keyboard__hint_mode__enabled_smart_priority</item>-->
</string-array>
<string-array name="pref__keyboard__hint_mode__values">
<item>disabled</item>
<item>enabled_hint_priority</item>
<item>enabled_accent_priority</item>
<!--<item>enabled_smart_priority</item>-->
</string-array>
<string-array name="pref__keyboard__one_handed_mode__entries">
<item>@string/pref__keyboard__one_handed_mode__off</item>
<item>@string/pref__keyboard__one_handed_mode__right</item>
@@ -66,18 +80,17 @@
<item>switch_to_next_subtype</item>
</string-array>
<!-- TODO: Implement precise word deleting -->
<string-array name="pref__gestures__swipe_action_delete__entries">
<item>@string/pref__gestures__swipe_action__no_action</item>
<item>@string/pref__gestures__swipe_action__delete_characters_precisely</item>
<item>@string/pref__gestures__swipe_action__delete_word</item>
<!--<item>@string/pref__gestures__swipe_action__delete_words_precisely</item>-->
<item>@string/pref__gestures__swipe_action__delete_words_precisely</item>
</string-array>
<string-array name="pref__gestures__swipe_action_delete__values">
<item>no_action</item>
<item>delete_characters_precisely</item>
<item>delete_word</item>
<!--<item>delete_words_precisely</item>-->
<item>delete_words_precisely</item>
</string-array>
<string-array name="pref__gestures__swipe_velocity_threshold__entries">

View File

@@ -8,6 +8,12 @@
<string name="one_handed__move_start_btn_content_description" comment="Content description for the one-handed move to left button">Move keyboard to the left.</string>
<string name="one_handed__move_end_btn_content_description" comment="Content description for the one-handed move to right button">Move keyboard to the right.</string>
<!-- Private mode info dialog strings -->
<string name="private_mode_dialog__title" comment="Title of the private mode dialog">Private mode</string>
<!--
<string name="private_mode_dialog__text" comment="Text of the private mode dialog">The icon you just clicked at indicates that FlorisBoard works in the private mode. This means that all features which require to process and temporarily save your input stop working. This applies at minimum to the following features (if they\'ve been turned on previously):\n\n - Next word algorithm adjustments\n\n - Clipboard paste suggestions\n\n - Clipboard history\n\nFlorisBoard enters this mode either if an app requests it or if it was specifically enabled in the advanced settings.</string>
-->
<!-- Media strings -->
<string name="media__tab__emojis" comment="Tab description for emojis in the media UI">Emojis</string>
<string name="media__tab__emoticons" comment="Tab description for emoticons in the media UI">Emoticons</string>
@@ -31,6 +37,9 @@
<string name="smartbar__quick_action__open_settings" comment="Content-description for the settings quick action in Smartbar">Open settings.</string>
<string name="smartbar__quick_action__switch_to_editing_context" comment="Content-description for the editing quick action in Smartbar">Switch to text editing panel.</string>
<string name="smartbar__quick_action__switch_to_media_context" comment="Content-description for the media quick action in Smartbar">Switch to media input view.</string>
<string name="smartbar__quick_action__undo" comment="Content-description for the undo quick action in Smartbar">Undo button to reverse the last action</string>
<string name="smartbar__quick_action__redo" comment="Content-description for the redo quick action in Smartbar">Redo button to reverse the last Undo</string>
<string name="smartbar__quick_action__private_mode" comment="Content-description for the private mode button in Smartbar">If visible, indicates that private mode is active. When clicked, shows info about the private mode.</string>
<!-- Settings UI strings -->
<string name="settings__title" comment="Title of Settings">Settings</string>
@@ -86,6 +95,7 @@
<string name="settings__theme__group_media" comment="Theme group label">Media context</string>
<string name="settings__theme__group_one_handed" comment="Theme group label">One-handed</string>
<string name="settings__theme__group_one_handed_button" comment="Theme group label">One-handed button</string>
<string name="settings__theme__group_private_mode" comment="Theme group label">Private mode</string>
<string name="settings__theme__group_smartbar" comment="Theme group label">Smartbar</string>
<string name="settings__theme__group_smartbar_button" comment="Theme group label">Smartbar button</string>
<string name="pref__theme__colorPrimary_title" comment="Title of Color primary theme preference">Primary color</string>
@@ -103,10 +113,12 @@
<string name="pref__keyboard__group_keys__label" comment="Preference group title">Keys</string>
<string name="pref__keyboard__number_row__label" comment="Preference title">Number row</string>
<string name="pref__keyboard__number_row__summary" comment="Preference summary">Show number row on top of character layout</string>
<string name="pref__keyboard__hinted_number_row__label" comment="Preference title">Hinted number row</string>
<string name="pref__keyboard__hinted_number_row__summary" comment="Preference summary">First row of character layout hints number row</string>
<string name="pref__keyboard__hinted_symbols__label" comment="Preference title">Hinted symbols</string>
<string name="pref__keyboard__hinted_symbols__summary" comment="Preference summary">Second and third row of character layout hint symbols</string>
<string name="pref__keyboard__hinted_number_row_mode__label" comment="Preference title">Hinted number row</string>
<string name="pref__keyboard__hinted_symbols_mode__label" comment="Preference title">Hinted symbols</string>
<string name="pref__keyboard__hint_mode__disabled" comment="Preference value">Disabled</string>
<string name="pref__keyboard__hint_mode__enabled_hint_priority" comment="Preference value">Enabled (Hint is prioritized)</string>
<string name="pref__keyboard__hint_mode__enabled_accent_priority" comment="Preference value">Enabled (Accent is prioritized)</string>
<string name="pref__keyboard__hint_mode__enabled_smart_priority" comment="Preference value">Enabled (Smart prioritization)</string>
<string name="pref__keyboard__font_size_multiplier_portrait__label" comment="Preference title">Font size multiplier (portrait)</string>
<string name="pref__keyboard__font_size_multiplier_landscape__label" comment="Preference title">Font size multiplier (landscape)</string>
<string name="pref__keyboard__group_layout__label" comment="Preference group title">Layout</string>
@@ -196,6 +208,8 @@
<string name="pref__advanced__settings_theme__light" comment="Possible value of Settings theme preference in Advanced">Light</string>
<string name="pref__advanced__settings_theme__dark" comment="Possible value of Settings theme preference in Advanced">Dark</string>
<string name="pref__advanced__show_app_icon__label" comment="Label of Show app icon preference in Advanced">Show app icon in launcher</string>
<string name="pref__advanced__force_private_mode__label" comment="Label of Force private mode preference in Advanced">Force private mode</string>
<string name="pref__advanced__force_private_mode__summary" comment="Summary of Force private mode preference in Advanced">Will disable any features which have to temporarily work with your input data</string>
<!-- About UI strings -->
<string name="about__title" comment="Title of About activity">About</string>

View File

@@ -72,6 +72,10 @@
<item name="android:autoMirrored">true</item>
</style>
<style name="SmartbarQuickAction.PrivateModeButton">
<item name="android:background">@drawable/shape_rect_rounded</item>
</style>
<style name="TextEditingButton" parent="Widget.AppCompat.Button.Borderless">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">0dp</item>

View File

@@ -18,4 +18,12 @@
app:title="@string/pref__advanced__show_app_icon__label"
app:useSimpleSummaryProvider="true"/>
<SwitchPreferenceCompat
android:defaultValue="false"
app:key="advanced__force_private_mode"
app:iconSpaceReserved="false"
app:title="@string/pref__advanced__force_private_mode__label"
app:summary="@string/pref__advanced__force_private_mode__summary"
app:useSimpleSummaryProvider="true"/>
</PreferenceScreen>

View File

@@ -13,19 +13,23 @@
app:title="@string/pref__keyboard__number_row__label"
app:summary="@string/pref__keyboard__number_row__summary"/>
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="keyboard__hinted_number_row"
<ListPreference
android:defaultValue="enabled_accent_priority"
app:entries="@array/pref__keyboard__hint_mode__entries"
app:entryValues="@array/pref__keyboard__hint_mode__values"
app:key="keyboard__hinted_number_row_mode"
app:iconSpaceReserved="false"
app:title="@string/pref__keyboard__hinted_number_row__label"
app:summary="@string/pref__keyboard__hinted_number_row__summary"/>
app:title="@string/pref__keyboard__hinted_number_row_mode__label"
app:useSimpleSummaryProvider="true"/>
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="keyboard__hinted_symbols"
<ListPreference
android:defaultValue="enabled_accent_priority"
app:entries="@array/pref__keyboard__hint_mode__entries"
app:entryValues="@array/pref__keyboard__hint_mode__values"
app:key="keyboard__hinted_symbols_mode"
app:iconSpaceReserved="false"
app:title="@string/pref__keyboard__hinted_symbols__label"
app:summary="@string/pref__keyboard__hinted_symbols__summary"/>
app:title="@string/pref__keyboard__hinted_symbols_mode__label"
app:useSimpleSummaryProvider="true"/>
<dev.patrickgold.florisboard.settings.components.DialogSeekBarPreference
app:allowDividerAbove="false"

View File

@@ -182,6 +182,24 @@
</PreferenceCategory>
<PreferenceCategory
app:title="@string/settings__theme__group_private_mode"
app:iconSpaceReserved="false">
<com.jaredrummler.android.colorpicker.ColorPreferenceCompat
android:defaultValue="0xFFA000FF"
android:key="theme__privateMode_bgColor"
android:title="@string/settings__theme__background"
app:iconSpaceReserved="false"/>
<com.jaredrummler.android.colorpicker.ColorPreferenceCompat
android:defaultValue="0xFFFFFFFF"
android:key="theme__privateMode_fgColor"
android:title="@string/settings__theme__foreground"
app:iconSpaceReserved="false"/>
</PreferenceCategory>
<PreferenceCategory
app:title="@string/settings__theme__group_smartbar"
app:iconSpaceReserved="false">

View File

@@ -0,0 +1,7 @@
- Complete rework of the Smartbar + new features (see PR #91 for more details)
- Add Colemak keyboard layout (#72)
- Add Dvorak keyboard layout (#72)
- Add Esperanto keyboard layout (thanks @jeremiah-miller)
- Add Hungarian keyboard layout (thanks @zoli111)
- Fix event listener NullPointerException (#73, #81)
- Other bug fixes and improvements

View File

@@ -0,0 +1,9 @@
- Add option to prioritize hints in the extended popups (#39)
- Add private mode (#106)
- Add precise word deletion (#25) (thanks @yashx)
- Add undo/redo for pasting (#70) (thanks @yashx)
- Add Canadian-French keyboard layout (thanks @The-Quantum-Alpha)
- Improve delete key behavior (thanks @yashx)
- Improve input UX and performance
- Fix delete key crash on holding down
- Other bug fixes and improvements

0
gradlew vendored Normal file → Executable file
View File