Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions app/src/main/kotlin/org/fossify/keyboard/helpers/MyKeyboard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ class MyKeyboard {
const val KEYCODE_DELETE = -5
const val KEYCODE_SPACE = 32
const val KEYCODE_EMOJI_OR_LANGUAGE = -6
const val KEYCODE_POPUP_EMOJI = -7
const val KEYCODE_POPUP_SETTINGS = -8

// Key roles for special keys
const val KEY_ROLE_TOOLS = "tools"

fun getDimensionOrFraction(a: TypedArray, index: Int, base: Int, defValue: Int): Int {
val value = a.peekValue(index) ?: return defValue
Expand Down Expand Up @@ -169,6 +174,9 @@ class MyKeyboard {
/** Popup characters showing after long pressing the key */
var popupCharacters: CharSequence? = null

/** Role identifier for special keys (e.g., "tools" for the tools popup host key) */
var role: String? = null

/**
* Flags that specify the anchoring to edges of the keyboard for detecting touch events that are just out of the boundary of the key.
* This is a bit mask of [MyKeyboard.EDGE_LEFT], [MyKeyboard.EDGE_RIGHT].
Expand Down Expand Up @@ -221,7 +229,7 @@ class MyKeyboard {
secondaryIcon?.setBounds(0, 0, secondaryIcon!!.intrinsicWidth, secondaryIcon!!.intrinsicHeight)

topSmallNumber = a.getString(R.styleable.MyKeyboard_Key_topSmallNumber) ?: ""

role = a.getString(R.styleable.MyKeyboard_Key_keyRole)

a.recycle()
}
Expand Down Expand Up @@ -271,7 +279,6 @@ class MyKeyboard {
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
* @param enterKeyType determines what icon should we show on Enter key
*/
@JvmOverloads
constructor(context: Context, @XmlRes xmlLayoutResId: Int, enterKeyType: Int) {
mDisplayWidth = context.resources.displayMetrics.widthPixels
mDefaultHorizontalGap = 0
Expand Down Expand Up @@ -378,8 +385,9 @@ class MyKeyboard {
if (context.config.showNumbersRow) {
// Removes numbers (i.e 0-9) from the popupCharacters if numbers row is enabled
key.apply {
val hadPopupCharacters = popupCharacters != null
popupCharacters = popupCharacters?.replace(Regex("\\d+"), "")
if (popupCharacters.isNullOrEmpty()) {
if (hadPopupCharacters && popupCharacters.isNullOrEmpty()) {
popupResId = 0
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.fossify.keyboard.services

import android.annotation.SuppressLint
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.drawable.Icon
Expand Down Expand Up @@ -37,6 +38,7 @@ import androidx.core.view.updatePadding
import org.fossify.commons.extensions.*
import org.fossify.commons.helpers.*
import org.fossify.keyboard.R
import org.fossify.keyboard.activities.SettingsActivity
import org.fossify.keyboard.databinding.KeyboardViewKeyboardBinding
import org.fossify.keyboard.extensions.config
import org.fossify.keyboard.extensions.getKeyboardBackgroundColor
Expand Down Expand Up @@ -268,6 +270,13 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared
}
}

MyKeyboard.KEYCODE_POPUP_EMOJI -> keyboardView?.openEmojiPalette()
MyKeyboard.KEYCODE_POPUP_SETTINGS -> Intent(this, SettingsActivity::class.java)
.apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(this)
}

else -> {
var codeChar = code.toChar()
val originalText = inputConnection.getExtractedText(ExtractedTextRequest(), 0)?.text
Expand Down Expand Up @@ -634,6 +643,16 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared
}
}
}

// When emoji key is enabled, show settings-only popup with no hint on tools key
if (config.showEmojiKey) {
val currentKeys = keyboard.mKeys ?: return keyboard
val toolsKey = currentKeys.firstOrNull { it.role == MyKeyboard.KEY_ROLE_TOOLS }
if (toolsKey != null) {
toolsKey.popupResId = R.xml.popup_tools
toolsKey.secondaryIcon = null
}
}
}
return keyboard
}
Expand Down
118 changes: 74 additions & 44 deletions app/src/main/kotlin/org/fossify/keyboard/views/MyKeyboardView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_DELETE
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_EMOJI_OR_LANGUAGE
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_ENTER
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_MODE_CHANGE
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_POPUP_EMOJI
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_POPUP_SETTINGS
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_SHIFT
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_SPACE
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_SYMBOLS_MODE_CHANGE
Expand Down Expand Up @@ -722,9 +724,9 @@ class MyKeyboardView @JvmOverloads constructor(
canvas.drawText(row, key.width / 2f, startY + textSize * index, paint)
}

if (key.topSmallNumber.isNotEmpty() && !(context.config.showNumbersRow && Regex("\\d").matches(
key.topSmallNumber
))
if (
key.topSmallNumber.isNotEmpty()
&& !(context.config.showNumbersRow && Regex("\\d").matches(key.topSmallNumber))
) {
val bounds = Rect().also {
smallLetterPaint.getTextBounds(
Expand All @@ -749,6 +751,9 @@ class MyKeyboardView @JvmOverloads constructor(
)
}

// Draw secondary icons for label-based keys
drawSecondaryIcon(key, canvas, textColor)

// Turn off drop shadow
paint.setShadowLayer(0f, 0f, 0f, 0)
} else if (key.icon != null && mKeyboard != null) {
Expand All @@ -765,7 +770,15 @@ class MyKeyboardView @JvmOverloads constructor(
val contrastColor = mPrimaryColor.getContrastColor()
key.icon!!.applyColorFilter(contrastColor)
key.secondaryIcon?.applyColorFilter(contrastColor.adjustAlpha(0.6f))
} else if (code == KEYCODE_DELETE || code == KEYCODE_SHIFT || code == KEYCODE_EMOJI_OR_LANGUAGE) {
} else if (
code in arrayOf(
KEYCODE_DELETE,
KEYCODE_SHIFT,
KEYCODE_EMOJI_OR_LANGUAGE,
KEYCODE_POPUP_EMOJI,
KEYCODE_POPUP_SETTINGS
)
) {
key.icon!!.applyColorFilter(textColor)
key.secondaryIcon?.applyColorFilter(
if (key.pressed) {
Expand All @@ -779,10 +792,9 @@ class MyKeyboardView @JvmOverloads constructor(
val keyIcon = key.icon!!
val secondaryIcon = key.secondaryIcon
if (secondaryIcon != null) {
// When secondary icon exists, shrink main icon to 90%
val keyIconWidth = (keyIcon.intrinsicWidth * 0.9f).toInt()
val keyIconHeight = (keyIcon.intrinsicHeight * 0.9f).toInt()
val secondaryIconWidth = (secondaryIcon.intrinsicWidth * 0.5f).toInt()
val secondaryIconHeight = (secondaryIcon.intrinsicHeight * 0.5f).toInt()

val centerX = key.width / 2
val centerY = key.height / 2
Expand All @@ -798,20 +810,7 @@ class MyKeyboardView @JvmOverloads constructor(
)
keyIcon.draw(canvas)

val secondaryIconPaddingRight = 10
val secondaryIconLeft =
key.width - secondaryIconPaddingRight - secondaryIconWidth
val secondaryIconRight = secondaryIconLeft + secondaryIconWidth

val secondaryIconTop = 14 // This will act as a topPadding
val secondaryIconBottom = secondaryIconTop + secondaryIconHeight

secondaryIcon.setBounds(
secondaryIconLeft, secondaryIconTop, secondaryIconRight, secondaryIconBottom
)
secondaryIcon.draw(canvas)

secondaryIcon.draw(canvas)
drawSecondaryIcon(key, canvas, textColor)
} else {
val drawableX = (key.width - keyIcon.intrinsicWidth) / 2
val drawableY = (key.height - keyIcon.intrinsicHeight) / 2
Expand Down Expand Up @@ -897,6 +896,25 @@ class MyKeyboardView @JvmOverloads constructor(
return resources.getDrawable(drawableId, context.theme)
}

private fun drawSecondaryIcon(key: MyKeyboard.Key, canvas: Canvas, textColor: Int) {
val secondaryIcon = key.secondaryIcon ?: return
secondaryIcon.applyColorFilter(
if (key.pressed) textColor else mTextColor.adjustAlpha(0.6f)
)
val secondaryIconWidth = (secondaryIcon.intrinsicWidth * 0.5f).toInt()
val secondaryIconHeight = (secondaryIcon.intrinsicHeight * 0.5f).toInt()
val secondaryIconPaddingRight = 10
val secondaryIconLeft = key.width - secondaryIconPaddingRight - secondaryIconWidth
val secondaryIconRight = secondaryIconLeft + secondaryIconWidth
val secondaryIconTop = 14
val secondaryIconBottom = secondaryIconTop + secondaryIconHeight

secondaryIcon.setBounds(
secondaryIconLeft, secondaryIconTop, secondaryIconRight, secondaryIconBottom
)
secondaryIcon.draw(canvas)
}

private fun handleClipboard() {
if (mToolbarHolder != null && mPopupParent.id != R.id.mini_keyboard_view && context.config.showClipboardContent) {
val clipboardContent = context.getCurrentClip()
Expand Down Expand Up @@ -1178,36 +1196,21 @@ class MyKeyboardView @JvmOverloads constructor(
*/
private fun onLongPress(popupKey: MyKeyboard.Key, me: MotionEvent): Boolean {
if (popupKey.code == KEYCODE_SPACE) {
return if (!mCursorControlActive) {
setCurrentKeyPressed(false)
mRepeatKeyIndex = NOT_A_KEY
mHandler?.removeMessages(MSG_REPEAT)
vibrateIfNeeded()
SwitchLanguageDialog(this) {
mOnKeyboardActionListener?.reloadKeyboard()
}
true
} else false
return onSpaceBarLongPressed()
} else if (popupKey.code == KEYCODE_EMOJI_OR_LANGUAGE) {
setCurrentKeyPressed(false)
if (context.config.showEmojiKey) {
openEmojiPalette()
} else {
SwitchLanguageDialog(this) {
mOnKeyboardActionListener?.reloadKeyboard()
}
}
return true
return onEmojiOrLanguageLongPressed()
} else {
val popupKeyboardId = popupKey.popupResId
if (popupKeyboardId != 0) {
mMiniKeyboardContainer = mMiniKeyboardCache[popupKey]

// For 'number' and 'phone' keyboards the count of popup keys might be bigger than count of keys in the main keyboard.
// And therefore the width of the key might be smaller than width declared in MyKeyboard.Key.width for the main keyboard.
val popupKeyWidth = popupKey.calcKeyWidth(
containerWidth = mMiniKeyboardContainer?.measuredWidth ?: width
)
val popupKeyWidth = if (popupKey.popupCharacters != null) {
popupKey.calcKeyWidth(containerWidth = mMiniKeyboardContainer?.measuredWidth ?: width)
} else {
popupKey.width
}

if (mMiniKeyboardContainer == null) {
val inflater =
Expand Down Expand Up @@ -1243,8 +1246,9 @@ class MyKeyboardView @JvmOverloads constructor(
mPopupX = popupKey.x
mPopupY = popupKey.y

val widthToUse =
mMiniKeyboardContainer!!.measuredWidth - (popupKey.popupCharacters!!.length / 2) * popupKeyWidth
// Use popupCharacters length if available, otherwise use actual key count from the loaded keyboard
val popupKeyCount = popupKey.popupCharacters?.length ?: mMiniKeyboard!!.mKeys.size
val widthToUse = mMiniKeyboardContainer!!.measuredWidth - (popupKeyCount / 2) * popupKeyWidth
mPopupX = mPopupX + popupKeyWidth - widthToUse
mPopupY -= mMiniKeyboardContainer!!.measuredHeight
val x = mPopupX + mCoordinates[0]
Expand Down Expand Up @@ -1606,6 +1610,32 @@ class MyKeyboardView @JvmOverloads constructor(
setupStoredClips()
}

private fun onSpaceBarLongPressed(): Boolean {
return if (!mCursorControlActive) {
setCurrentKeyPressed(false)
mRepeatKeyIndex = NOT_A_KEY
mHandler?.removeMessages(MSG_REPEAT)
vibrateIfNeeded()
SwitchLanguageDialog(this) {
mOnKeyboardActionListener?.reloadKeyboard()
}
true
} else false
}

private fun onEmojiOrLanguageLongPressed(): Boolean {
setCurrentKeyPressed(false)
if (context.config.showEmojiKey) {
openEmojiPalette()
} else {
SwitchLanguageDialog(this) {
mOnKeyboardActionListener?.reloadKeyboard()
}
}

return true
}

private fun setupStoredClips() {
ensureBackgroundThread {
val clips = ArrayList<ListItem>()
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@
<attr name="secondaryKeyIcon" format="reference" />
<!-- Top small number shown above letters of the first row. -->
<attr name="topSmallNumber" format="string" />
<!-- Role identifier for special keys (e.g., "tools" for the tools popup host key). -->
<attr name="keyRole" format="string" />
</declare-styleable>
</resources>
13 changes: 8 additions & 5 deletions app/src/main/res/xml/keys_letters_belarusian_cyrl.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,17 @@
app:keyWidth="8%p" />
<Key
app:keyLabel="і"
app:keyWidth="8%p"
app:popupCharacters="иї"
app:popupKeyboard="@xml/keyboard_popup_template"
app:keyWidth="8%p" />
app:popupKeyboard="@xml/keyboard_popup_template" />
<Key
app:keyLabel="т"
app:keyWidth="8%p" />
<Key
app:keyLabel="ь"
app:keyWidth="8%p"
app:popupCharacters="ъ"
app:popupKeyboard="@xml/keyboard_popup_template"
app:keyWidth="8%p" />
app:popupKeyboard="@xml/keyboard_popup_template" />
<Key
app:keyLabel="б"
app:keyWidth="8%p" />
Expand All @@ -164,7 +164,10 @@
app:keyWidth="15%p" />
<Key
app:keyLabel=","
app:keyWidth="10%p" />
app:keyWidth="10%p"
app:keyRole="tools"
app:popupKeyboard="@xml/popup_tools_with_emoji_key"
app:secondaryKeyIcon="@drawable/ic_emoji_emotions_outline_vector" />
<Key
app:code="-6"
app:keyEdgeFlags="left"
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/xml/keys_letters_belarusian_latn.xml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@
app:keyWidth="15%p" />
<Key
app:keyLabel=","
app:keyWidth="10%p" />
app:keyWidth="10%p"
app:keyRole="tools"
app:popupKeyboard="@xml/popup_tools_with_emoji_key"
app:secondaryKeyIcon="@drawable/ic_emoji_emotions_outline_vector" />
<Key
app:code="-6"
app:keyEdgeFlags="left"
Expand Down
13 changes: 8 additions & 5 deletions app/src/main/res/xml/keys_letters_bengali.xml
Original file line number Diff line number Diff line change
Expand Up @@ -191,22 +191,25 @@
app:keyWidth="15%p" />
<Key
app:keyLabel=","
app:keyWidth="10%p" />
app:keyWidth="10%p"
app:keyRole="tools"
app:popupKeyboard="@xml/popup_tools_with_emoji_key"
app:secondaryKeyIcon="@drawable/ic_emoji_emotions_outline_vector" />
<Key
app:code="-6"
app:keyEdgeFlags="left"
app:keyIcon="@drawable/ic_emoji_emotions_outline_vector"
app:secondaryKeyIcon="@drawable/ic_language_outlined"
app:keyWidth="10%p" />
app:keyWidth="10%p"
app:secondaryKeyIcon="@drawable/ic_language_outlined" />
<Key
app:code="32"
app:isRepeatable="true"
app:keyWidth="40%p" />
<Key
app:keyLabel="."
app:keyWidth="10%p"
app:popupCharacters=",?!;:'…"
app:popupKeyboard="@xml/keyboard_popup_template"
app:keyWidth="10%p" />
app:popupKeyboard="@xml/keyboard_popup_template" />
<Key
app:code="-4"
app:keyEdgeFlags="right"
Expand Down
Loading
Loading