mirror of
https://github.com/fcitx5-android/fcitx5-android.git
synced 2026-08-02 04:44:35 +08:00
Test floating keyboard
This commit is contained in:
parent
e205195f38
commit
c7938b928f
@ -35,6 +35,10 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) {
|
||||
val pid = int("pid", 0)
|
||||
val editorInfoInspector = bool("editor_info_inspector", false)
|
||||
val needNotifications = bool("need_notifications", true)
|
||||
val floatingKeyboardXRatio = float("floating_keyboard_x_ratio", 0.5f)
|
||||
val floatingKeyboardYRatio = float("floating_keyboard_y_ratio", 1f)
|
||||
val floatingKeyboardXRatioLandscape = float("floating_keyboard_x_ratio_landscape", 0.5f)
|
||||
val floatingKeyboardYRatioLandscape = float("floating_keyboard_y_ratio_landscape", 1f)
|
||||
}
|
||||
|
||||
inner class Advanced : ManagedPreferenceCategory(R.string.advanced, sharedPreferences) {
|
||||
@ -133,6 +137,8 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) {
|
||||
val expandToolbarByDefault =
|
||||
switch(R.string.expand_toolbar_by_default, "expand_toolbar_by_default", false)
|
||||
val inlineSuggestions = switch(R.string.inline_suggestions, "inline_suggestions", true)
|
||||
val floatingKeyboardEnabled =
|
||||
switch(R.string.floating_keyboard, "floating_keyboard_enabled", false)
|
||||
val toolbarNumRowOnPassword =
|
||||
switch(R.string.toolbar_num_row_on_password, "toolbar_num_row_on_password", true)
|
||||
val popupOnKeyPress = switch(R.string.popup_on_key_press, "popup_on_key_press", true)
|
||||
@ -239,6 +245,26 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) {
|
||||
keyboardBottomPaddingLandscape = secondary
|
||||
}
|
||||
|
||||
val floatingKeyboardWidthPercent: ManagedPreference.PInt
|
||||
val floatingKeyboardWidthPercentLandscape: ManagedPreference.PInt
|
||||
|
||||
init {
|
||||
val (primary, secondary) = twinInt(
|
||||
R.string.floating_keyboard_width,
|
||||
R.string.portrait,
|
||||
"floating_keyboard_width_percent",
|
||||
80,
|
||||
R.string.landscape,
|
||||
"floating_keyboard_width_percent_landscape",
|
||||
80,
|
||||
55,
|
||||
100,
|
||||
"%"
|
||||
) { floatingKeyboardEnabled.getValue() }
|
||||
floatingKeyboardWidthPercent = primary
|
||||
floatingKeyboardWidthPercentLandscape = secondary
|
||||
}
|
||||
|
||||
val horizontalCandidateStyle = enumList(
|
||||
R.string.horizontal_candidate_style,
|
||||
"horizontal_candidate_style",
|
||||
@ -436,4 +462,4 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) {
|
||||
|
||||
fun getInstance() = instance!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import android.content.pm.ActivityInfo
|
||||
import android.content.res.ColorStateList
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@ -598,14 +599,28 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
|
||||
}
|
||||
|
||||
private var inputViewLocation = intArrayOf(0, 0)
|
||||
private val floatingKeyboardTouchableRect = Rect()
|
||||
|
||||
override fun onComputeInsets(outInsets: Insets) {
|
||||
if (inputDeviceMgr.isVirtualKeyboard) {
|
||||
inputView?.keyboardView?.getLocationInWindow(inputViewLocation)
|
||||
outInsets.apply {
|
||||
contentTopInsets = inputViewLocation[1]
|
||||
visibleTopInsets = inputViewLocation[1]
|
||||
touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE
|
||||
if (
|
||||
inputView?.getFloatingKeyboardTouchableRect(floatingKeyboardTouchableRect) == true
|
||||
) {
|
||||
val n = decorView.findViewById<View>(android.R.id.navigationBarBackground)?.height ?: 0
|
||||
val h = decorView.height - n
|
||||
outInsets.apply {
|
||||
contentTopInsets = h
|
||||
visibleTopInsets = floatingKeyboardTouchableRect.top
|
||||
touchableInsets = Insets.TOUCHABLE_INSETS_REGION
|
||||
touchableRegion.set(floatingKeyboardTouchableRect)
|
||||
}
|
||||
} else {
|
||||
inputView?.keyboardView?.getLocationInWindow(inputViewLocation)
|
||||
outInsets.apply {
|
||||
contentTopInsets = inputViewLocation[1]
|
||||
visibleTopInsets = inputViewLocation[1]
|
||||
touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val n = decorView.findViewById<View>(android.R.id.navigationBarBackground)?.height ?: 0
|
||||
|
||||
@ -7,7 +7,9 @@ package org.fcitx.fcitx5.android.input
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.view.inputmethod.EditorInfo
|
||||
@ -15,6 +17,7 @@ import android.view.inputmethod.InlineSuggestionsResponse
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.Keep
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import org.fcitx.fcitx5.android.R
|
||||
import org.fcitx.fcitx5.android.core.CapabilityFlags
|
||||
@ -63,6 +66,10 @@ import splitties.views.dsl.core.view
|
||||
import splitties.views.dsl.core.withTheme
|
||||
import splitties.views.dsl.core.wrapContent
|
||||
import splitties.views.imageDrawable
|
||||
import splitties.views.imageResource
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
class InputView(
|
||||
@ -71,6 +78,13 @@ class InputView(
|
||||
theme: Theme
|
||||
) : BaseInputView(service, fcitx, theme) {
|
||||
|
||||
companion object {
|
||||
private const val MIN_FLOATING_KEYBOARD_WIDTH_PERCENT = 55
|
||||
private const val MAX_FLOATING_KEYBOARD_WIDTH_PERCENT = 100
|
||||
private const val FLOATING_DRAG_HANDLE_HEIGHT_DP = 24
|
||||
private const val FLOATING_RESIZE_HANDLE_SIZE_DP = 40
|
||||
}
|
||||
|
||||
private val keyBorder by ThemeManager.prefs.keyBorder
|
||||
|
||||
private val customBackground = imageView {
|
||||
@ -91,6 +105,12 @@ class InputView(
|
||||
// bottomMargin as WindowInsets (Navigation Bar) offset
|
||||
setOnClickListener(placeholderOnClickListener)
|
||||
}
|
||||
private val resizeHandle = imageView {
|
||||
imageResource = R.drawable.ic_baseline_drag_handle_24
|
||||
scaleType = ImageView.ScaleType.CENTER
|
||||
alpha = 0.72f
|
||||
contentDescription = context.getString(R.string.resize_floating_keyboard)
|
||||
}
|
||||
|
||||
private val scope = DynamicScope()
|
||||
private val themedContext = context.withTheme(R.style.Theme_InputViewTheme)
|
||||
@ -129,23 +149,30 @@ class InputView(
|
||||
}
|
||||
|
||||
private val keyboardPrefs = AppPrefs.getInstance().keyboard
|
||||
private val internalPrefs = AppPrefs.getInstance().internal
|
||||
|
||||
private val focusChangeResetKeyboard by keyboardPrefs.focusChangeResetKeyboard
|
||||
|
||||
private var floatingKeyboardEnabled by keyboardPrefs.floatingKeyboardEnabled
|
||||
private val keyboardHeightPercent = keyboardPrefs.keyboardHeightPercent
|
||||
private val keyboardHeightPercentLandscape = keyboardPrefs.keyboardHeightPercentLandscape
|
||||
private val keyboardSidePadding = keyboardPrefs.keyboardSidePadding
|
||||
private val keyboardSidePaddingLandscape = keyboardPrefs.keyboardSidePaddingLandscape
|
||||
private val keyboardBottomPadding = keyboardPrefs.keyboardBottomPadding
|
||||
private val keyboardBottomPaddingLandscape = keyboardPrefs.keyboardBottomPaddingLandscape
|
||||
private val floatingKeyboardWidthPercent = keyboardPrefs.floatingKeyboardWidthPercent
|
||||
private val floatingKeyboardWidthPercentLandscape = keyboardPrefs.floatingKeyboardWidthPercentLandscape
|
||||
|
||||
private val keyboardSizePrefs = listOf(
|
||||
keyboardPrefs.floatingKeyboardEnabled,
|
||||
keyboardHeightPercent,
|
||||
keyboardHeightPercentLandscape,
|
||||
keyboardSidePadding,
|
||||
keyboardSidePaddingLandscape,
|
||||
keyboardBottomPadding,
|
||||
keyboardBottomPaddingLandscape,
|
||||
floatingKeyboardWidthPercent,
|
||||
floatingKeyboardWidthPercentLandscape,
|
||||
)
|
||||
|
||||
private val keyboardHeightPx: Int
|
||||
@ -154,7 +181,11 @@ class InputView(
|
||||
Configuration.ORIENTATION_LANDSCAPE -> keyboardHeightPercentLandscape
|
||||
else -> keyboardHeightPercent
|
||||
}.getValue()
|
||||
return resources.displayMetrics.heightPixels * percent / 100
|
||||
return (if (floatingKeyboardEnabled) {
|
||||
height.takeIf { it > 0 } ?: resources.displayMetrics.heightPixels
|
||||
} else {
|
||||
resources.displayMetrics.heightPixels
|
||||
}) * percent / 100
|
||||
}
|
||||
|
||||
private val keyboardSidePaddingPx: Int
|
||||
@ -175,15 +206,109 @@ class InputView(
|
||||
return dp(value)
|
||||
}
|
||||
|
||||
private val floatingKeyboardWidthPx: Int
|
||||
get() {
|
||||
val parentWidth = width.takeIf { it > 0 } ?: resources.displayMetrics.widthPixels
|
||||
return parentWidth * activeFloatingKeyboardWidthPercent.getValue() / 100
|
||||
}
|
||||
|
||||
private val floatingDragHandleHeightPx: Int
|
||||
get() = dp(FLOATING_DRAG_HANDLE_HEIGHT_DP)
|
||||
|
||||
private val activeFloatingKeyboardWidthPercent
|
||||
get() = when (resources.configuration.orientation) {
|
||||
Configuration.ORIENTATION_LANDSCAPE -> floatingKeyboardWidthPercentLandscape
|
||||
else -> floatingKeyboardWidthPercent
|
||||
}
|
||||
|
||||
private val activeFloatingKeyboardXRatio
|
||||
get() = when (resources.configuration.orientation) {
|
||||
Configuration.ORIENTATION_LANDSCAPE -> internalPrefs.floatingKeyboardXRatioLandscape
|
||||
else -> internalPrefs.floatingKeyboardXRatio
|
||||
}
|
||||
|
||||
private val activeFloatingKeyboardYRatio
|
||||
get() = when (resources.configuration.orientation) {
|
||||
Configuration.ORIENTATION_LANDSCAPE -> internalPrefs.floatingKeyboardYRatioLandscape
|
||||
else -> internalPrefs.floatingKeyboardYRatio
|
||||
}
|
||||
|
||||
private var navBarBottomInset = 0
|
||||
private var floatingKeyboardX = 0f
|
||||
private var floatingKeyboardY = 0f
|
||||
private var floatingDragStartRawX = 0f
|
||||
private var floatingDragStartRawY = 0f
|
||||
private var floatingDragStartKeyboardX = 0f
|
||||
private var floatingDragStartKeyboardY = 0f
|
||||
private var floatingResizeStartWidth = 0
|
||||
private val inputViewLocation = intArrayOf(0, 0)
|
||||
|
||||
@Keep
|
||||
private val onKeyboardSizeChangeListener = ManagedPreferenceProvider.OnChangeListener { key ->
|
||||
if (keyboardSizePrefs.any { it.key == key }) {
|
||||
if (keyboardPrefs.floatingKeyboardEnabled.key == key) {
|
||||
applyKeyboardMode()
|
||||
} else if (keyboardSizePrefs.any { it.key == key }) {
|
||||
updateKeyboardSize()
|
||||
}
|
||||
}
|
||||
|
||||
val keyboardView: View
|
||||
|
||||
private val floatingKeyboardDragListener = OnTouchListener { _, event ->
|
||||
if (!floatingKeyboardEnabled) return@OnTouchListener false
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
floatingDragStartRawX = event.rawX
|
||||
floatingDragStartRawY = event.rawY
|
||||
floatingDragStartKeyboardX = floatingKeyboardX
|
||||
floatingDragStartKeyboardY = floatingKeyboardY
|
||||
true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
updateFloatingKeyboardPosition(
|
||||
floatingDragStartKeyboardX + event.rawX - floatingDragStartRawX,
|
||||
floatingDragStartKeyboardY + event.rawY - floatingDragStartRawY,
|
||||
persist = true
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private val floatingKeyboardResizeListener = OnTouchListener { _, event ->
|
||||
if (!floatingKeyboardEnabled) return@OnTouchListener false
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
floatingDragStartRawX = event.rawX
|
||||
floatingResizeStartWidth = keyboardView.width
|
||||
true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val parentWidth = width.takeIf { it > 0 } ?: return@OnTouchListener true
|
||||
val delta = if (layoutDirection == LAYOUT_DIRECTION_RTL) {
|
||||
floatingDragStartRawX - event.rawX
|
||||
} else {
|
||||
event.rawX - floatingDragStartRawX
|
||||
}
|
||||
val newWidth = (floatingResizeStartWidth + delta).roundToInt()
|
||||
val percent = (newWidth * 100f / parentWidth)
|
||||
.roundToInt()
|
||||
.coerceIn(MIN_FLOATING_KEYBOARD_WIDTH_PERCENT, MAX_FLOATING_KEYBOARD_WIDTH_PERCENT)
|
||||
activeFloatingKeyboardWidthPercent.setValue(percent)
|
||||
updateKeyboardSize()
|
||||
true
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
// MUST call before any operation
|
||||
setupScope()
|
||||
@ -240,18 +365,33 @@ class InputView(
|
||||
endToStartOf(rightPaddingSpace)
|
||||
bottomOfParent()
|
||||
})
|
||||
add(resizeHandle, lParams(dp(FLOATING_RESIZE_HANDLE_SIZE_DP), dp(FLOATING_RESIZE_HANDLE_SIZE_DP)) {
|
||||
endOfParent()
|
||||
bottomOfParent()
|
||||
})
|
||||
}
|
||||
|
||||
bottomPaddingSpace.setOnTouchListener(floatingKeyboardDragListener)
|
||||
resizeHandle.setOnTouchListener(floatingKeyboardResizeListener)
|
||||
|
||||
updateKeyboardSize()
|
||||
|
||||
add(preedit.ui.root, lParams(matchParent, wrapContent) {
|
||||
above(keyboardView)
|
||||
centerHorizontally()
|
||||
})
|
||||
add(keyboardView, lParams(matchParent, wrapContent) {
|
||||
centerHorizontally()
|
||||
bottomOfParent()
|
||||
})
|
||||
if (floatingKeyboardEnabled) {
|
||||
add(keyboardView, lParams(floatingKeyboardWidthPx, wrapContent) {
|
||||
startOfParent()
|
||||
topOfParent()
|
||||
})
|
||||
} else {
|
||||
add(keyboardView, lParams(matchParent, wrapContent) {
|
||||
centerHorizontally()
|
||||
bottomOfParent()
|
||||
})
|
||||
}
|
||||
post { applyKeyboardMode() }
|
||||
add(popup.root, lParams(matchParent, matchParent) {
|
||||
centerVertically()
|
||||
centerHorizontally()
|
||||
@ -265,13 +405,34 @@ class InputView(
|
||||
height = keyboardHeightPx
|
||||
}
|
||||
bottomPaddingSpace.updateLayoutParams {
|
||||
height = keyboardBottomPaddingPx
|
||||
height = if (floatingKeyboardEnabled) {
|
||||
max(keyboardBottomPaddingPx, floatingDragHandleHeightPx)
|
||||
} else {
|
||||
keyboardBottomPaddingPx
|
||||
}
|
||||
}
|
||||
val sidePadding = keyboardSidePaddingPx
|
||||
if (sidePadding == 0) {
|
||||
if (floatingKeyboardEnabled) {
|
||||
leftPaddingSpace.visibility = GONE
|
||||
rightPaddingSpace.visibility = GONE
|
||||
resizeHandle.visibility = VISIBLE
|
||||
windowManager.view.updateLayoutParams<LayoutParams> {
|
||||
startToEnd = unset
|
||||
endToStart = unset
|
||||
startOfParent()
|
||||
endOfParent()
|
||||
}
|
||||
bottomPaddingSpace.updateLayoutParams<LayoutParams> {
|
||||
startToEnd = unset
|
||||
endToStart = unset
|
||||
startOfParent()
|
||||
endOfParent()
|
||||
}
|
||||
} else if (sidePadding == 0) {
|
||||
// hide side padding space views when unnecessary
|
||||
leftPaddingSpace.visibility = GONE
|
||||
rightPaddingSpace.visibility = GONE
|
||||
resizeHandle.visibility = GONE
|
||||
windowManager.view.updateLayoutParams<LayoutParams> {
|
||||
startToEnd = unset
|
||||
endToStart = unset
|
||||
@ -281,6 +442,7 @@ class InputView(
|
||||
} else {
|
||||
leftPaddingSpace.visibility = VISIBLE
|
||||
rightPaddingSpace.visibility = VISIBLE
|
||||
resizeHandle.visibility = GONE
|
||||
leftPaddingSpace.updateLayoutParams {
|
||||
width = sidePadding
|
||||
}
|
||||
@ -294,17 +456,117 @@ class InputView(
|
||||
endToStartOf(rightPaddingSpace)
|
||||
}
|
||||
}
|
||||
preedit.ui.root.setPadding(sidePadding, 0, sidePadding, 0)
|
||||
kawaiiBar.view.setPadding(sidePadding, 0, sidePadding, 0)
|
||||
val inputSidePadding = if (floatingKeyboardEnabled) 0 else sidePadding
|
||||
preedit.ui.root.setPadding(inputSidePadding, 0, inputSidePadding, 0)
|
||||
kawaiiBar.view.setPadding(inputSidePadding, 0, inputSidePadding, 0)
|
||||
if (floatingKeyboardEnabled) {
|
||||
if (keyboardView.parent != null) {
|
||||
keyboardView.updateLayoutParams<LayoutParams> {
|
||||
width = floatingKeyboardWidthPx
|
||||
}
|
||||
}
|
||||
keyboardView.post {
|
||||
restoreFloatingKeyboardPosition()
|
||||
}
|
||||
}
|
||||
service.window.window?.decorView?.requestLayout()
|
||||
}
|
||||
|
||||
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
|
||||
navBarBottomInset = getNavBarBottomInset(insets)
|
||||
bottomPaddingSpace.updateLayoutParams<LayoutParams> {
|
||||
bottomMargin = getNavBarBottomInset(insets)
|
||||
bottomMargin = navBarBottomInset
|
||||
}
|
||||
if (floatingKeyboardEnabled) {
|
||||
keyboardView.post {
|
||||
restoreFloatingKeyboardPosition()
|
||||
}
|
||||
}
|
||||
return insets
|
||||
}
|
||||
|
||||
private fun applyKeyboardMode() {
|
||||
keyboardView.updateLayoutParams<LayoutParams> {
|
||||
if (floatingKeyboardEnabled) {
|
||||
width = floatingKeyboardWidthPx
|
||||
height = wrapContent
|
||||
startToStart = PARENT_ID
|
||||
topToTop = PARENT_ID
|
||||
endToEnd = unset
|
||||
bottomToBottom = unset
|
||||
} else {
|
||||
width = matchParent
|
||||
height = wrapContent
|
||||
startToStart = unset
|
||||
topToTop = unset
|
||||
endToEnd = unset
|
||||
bottomToBottom = PARENT_ID
|
||||
centerHorizontally()
|
||||
}
|
||||
}
|
||||
keyboardView.translationX = 0f
|
||||
keyboardView.translationY = 0f
|
||||
updateKeyboardSize()
|
||||
kawaiiBar.updateFloatingKeyboardButton()
|
||||
if (floatingKeyboardEnabled) {
|
||||
keyboardView.post { restoreFloatingKeyboardPosition() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun restoreFloatingKeyboardPosition() {
|
||||
if (!floatingKeyboardEnabled || width <= 0 || keyboardView.width <= 0) return
|
||||
val maxX = max(0, width - keyboardView.width).toFloat()
|
||||
val maxY = max(0, height - navBarBottomInset - keyboardView.height).toFloat()
|
||||
val x = maxX * activeFloatingKeyboardXRatio.getValue().coerceIn(0f, 1f)
|
||||
val y = maxY * activeFloatingKeyboardYRatio.getValue().coerceIn(0f, 1f)
|
||||
updateFloatingKeyboardPosition(x, y)
|
||||
}
|
||||
|
||||
private fun updateFloatingKeyboardPosition(x: Float, y: Float, persist: Boolean = false) {
|
||||
if (!floatingKeyboardEnabled) return
|
||||
val maxX = max(0, width - keyboardView.width).toFloat()
|
||||
val maxY = max(0, height - navBarBottomInset - keyboardView.height).toFloat()
|
||||
floatingKeyboardX = min(max(x, 0f), maxX)
|
||||
floatingKeyboardY = min(max(y, 0f), maxY)
|
||||
keyboardView.translationX = floatingKeyboardX
|
||||
keyboardView.translationY = floatingKeyboardY
|
||||
if (persist) {
|
||||
activeFloatingKeyboardXRatio.setValue(if (maxX > 0f) floatingKeyboardX / maxX else 0.5f)
|
||||
activeFloatingKeyboardYRatio.setValue(if (maxY > 0f) floatingKeyboardY / maxY else 1f)
|
||||
}
|
||||
service.window.window?.decorView?.requestLayout()
|
||||
}
|
||||
|
||||
fun getFloatingKeyboardTouchableRect(outRect: Rect): Boolean {
|
||||
if (!floatingKeyboardEnabled || keyboardView.width <= 0 || keyboardView.height <= 0) {
|
||||
return false
|
||||
}
|
||||
keyboardView.getLocationInWindow(inputViewLocation)
|
||||
outRect.set(
|
||||
inputViewLocation[0],
|
||||
inputViewLocation[1],
|
||||
inputViewLocation[0] + keyboardView.width,
|
||||
inputViewLocation[1] + keyboardView.height
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
if (floatingKeyboardEnabled) {
|
||||
keyboardView.post {
|
||||
restoreFloatingKeyboardPosition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleFloatingKeyboard() {
|
||||
floatingKeyboardEnabled = !floatingKeyboardEnabled
|
||||
applyKeyboardMode()
|
||||
}
|
||||
|
||||
fun isFloatingKeyboardEnabled() = floatingKeyboardEnabled
|
||||
|
||||
/**
|
||||
* called when [InputView] is about to show, or restart
|
||||
*/
|
||||
|
||||
@ -55,6 +55,7 @@ import org.fcitx.fcitx5.android.input.candidates.horizontal.HorizontalCandidateC
|
||||
import org.fcitx.fcitx5.android.input.clipboard.ClipboardWindow
|
||||
import org.fcitx.fcitx5.android.input.dependency.UniqueViewComponent
|
||||
import org.fcitx.fcitx5.android.input.dependency.context
|
||||
import org.fcitx.fcitx5.android.input.dependency.inputView
|
||||
import org.fcitx.fcitx5.android.input.dependency.inputMethodService
|
||||
import org.fcitx.fcitx5.android.input.dependency.theme
|
||||
import org.fcitx.fcitx5.android.input.editing.TextEditingWindow
|
||||
@ -92,6 +93,7 @@ class KawaiiBarComponent : UniqueViewComponent<KawaiiBarComponent, FrameLayout>(
|
||||
private val theme by manager.theme()
|
||||
private val service by manager.inputMethodService()
|
||||
private val windowManager: InputWindowManager by manager.must()
|
||||
private val inputView by manager.inputView()
|
||||
private val horizontalCandidate: HorizontalCandidateComponent by manager.must()
|
||||
private val commonKeyActionListener: CommonKeyActionListener by manager.must()
|
||||
private val popup: PopupComponent by manager.must()
|
||||
@ -313,6 +315,10 @@ class KawaiiBarComponent : UniqueViewComponent<KawaiiBarComponent, FrameLayout>(
|
||||
clipboardButton.setOnClickListener {
|
||||
windowManager.attachWindow(ClipboardWindow())
|
||||
}
|
||||
floatingKeyboardButton.setOnClickListener {
|
||||
inputView.toggleFloatingKeyboard()
|
||||
updateFloatingKeyboardButton()
|
||||
}
|
||||
moreButton.setOnClickListener {
|
||||
windowManager.attachWindow(StatusAreaWindow())
|
||||
}
|
||||
@ -343,6 +349,18 @@ class KawaiiBarComponent : UniqueViewComponent<KawaiiBarComponent, FrameLayout>(
|
||||
}
|
||||
}
|
||||
|
||||
fun updateFloatingKeyboardButton() {
|
||||
idleUi.buttonsUi.floatingKeyboardButton.apply {
|
||||
if (inputView.isFloatingKeyboardEnabled()) {
|
||||
setIcon(R.drawable.ic_baseline_keyboard_24)
|
||||
contentDescription = context.getString(R.string.dock_keyboard)
|
||||
} else {
|
||||
setIcon(R.drawable.ic_baseline_open_in_full_24)
|
||||
contentDescription = context.getString(R.string.float_keyboard)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val candidateUi by lazy {
|
||||
CandidateUi(context, theme, horizontalCandidate.view).apply {
|
||||
expandButton.apply {
|
||||
@ -458,6 +476,7 @@ class KawaiiBarComponent : UniqueViewComponent<KawaiiBarComponent, FrameLayout>(
|
||||
shouldShowVoiceInput,
|
||||
if (shouldShowVoiceInput) switchToVoiceInputCallback else hideKeyboardCallback
|
||||
)
|
||||
updateFloatingKeyboardButton()
|
||||
evalIdleUiState()
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,10 @@ class ButtonsBarUi(override val ctx: Context, private val theme: Theme) : Ui {
|
||||
contentDescription = ctx.getString(R.string.clipboard)
|
||||
}
|
||||
|
||||
val floatingKeyboardButton = toolButton(R.drawable.ic_baseline_open_in_full_24).apply {
|
||||
contentDescription = ctx.getString(R.string.float_keyboard)
|
||||
}
|
||||
|
||||
val moreButton = toolButton(R.drawable.ic_baseline_more_horiz_24).apply {
|
||||
contentDescription = ctx.getString(R.string.status_area)
|
||||
}
|
||||
|
||||
@ -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="#ffffff"
|
||||
android:pathData="M5,5h6v2H8.41l3.3,3.29 -1.42,1.42L7,8.41V11H5V5zM13,5h6v6h-2V8.41l-3.29,3.3 -1.42,-1.42 3.3,-3.29H13V5zM10.29,12.29l1.42,1.42L8.41,17H11v2H5v-6h2v2.59l3.29,-3.3zM13.71,12.29l3.29,3.3V13h2v6h-6v-2h2.59l-3.3,-3.29 1.42,-1.42z" />
|
||||
</vector>
|
||||
@ -62,6 +62,8 @@
|
||||
<string name="delete">Delete</string>
|
||||
<string name="clipboard">Clipboard</string>
|
||||
<string name="keyboard_height">Keyboard height</string>
|
||||
<string name="floating_keyboard">Floating keyboard</string>
|
||||
<string name="floating_keyboard_width">Floating keyboard width</string>
|
||||
<string name="virtual_keyboard">Virtual Keyboard</string>
|
||||
<string name="clipboard_suggestion_timeout">Clipboard suggestion timeout</string>
|
||||
<string name="version">Version</string>
|
||||
@ -292,6 +294,9 @@
|
||||
<string name="hide_candidates_list">Hide candidates list</string>
|
||||
<string name="switch_to_voice_input">Switch to voice input</string>
|
||||
<string name="hide_keyboard">Hide keyboard</string>
|
||||
<string name="float_keyboard">Float keyboard</string>
|
||||
<string name="dock_keyboard">Dock keyboard</string>
|
||||
<string name="resize_floating_keyboard">Resize floating keyboard</string>
|
||||
<string name="private_mode">Private mode (tap to toggle toolbar)</string>
|
||||
<string name="hide_toolbar">Hide toolbar</string>
|
||||
<string name="expand_toolbar">Expand toolbar</string>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user