Skip to content
Open
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
4 changes: 3 additions & 1 deletion app/src/main/java/it/palsoftware/pastiera/SettingsManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ object SettingsManager {
private const val KEY_SHIFT_BACKSPACE_DELETE = "shift_backspace_delete" // Shift + Backspace performs forward delete
private const val KEY_ALT_BACKSPACE_DELETE = "alt_backspace_delete" // Alt + Backspace performs forward delete
private const val KEY_BACKSPACE_AT_START_DELETE = "backspace_at_start_delete" // Backspace at line start performs forward delete
private const val KEY_PASTIERINA_MODE_OVERRIDE = "pastierina_mode_override" // pastierina | full_status_bar
private const val KEY_PASTIERINA_MODE_OVERRIDE = "pastierina_mode_override" // pastierina | unified | full_status_bar
private const val KEY_PASTIERINA_MODE_ACTIVE = "pastierina_mode_active" // Current effective state
private const val KEY_SOFTWARE_KEYBOARD_MODE = "software_keyboard_mode" // auto | force_hardware | force_virtual
const val KEY_SOFTWARE_KEYBOARD_MODE_RUNTIME_OVERRIDE = "software_keyboard_mode_runtime_override"
Expand Down Expand Up @@ -437,6 +437,7 @@ object SettingsManager {

enum class StatusBarPresentationMode(val storageValue: String) {
PASTIERINA("pastierina"),
UNIFIED("unified"),
FULL_STATUS_BAR("full_status_bar")
}

Expand Down Expand Up @@ -560,6 +561,7 @@ object SettingsManager {
return when (value) {
StatusBarPresentationMode.PASTIERINA.storageValue,
"force_minimal" -> StatusBarPresentationMode.PASTIERINA
StatusBarPresentationMode.UNIFIED.storageValue -> StatusBarPresentationMode.UNIFIED
else -> StatusBarPresentationMode.FULL_STATUS_BAR
}
}
Expand Down
38 changes: 19 additions & 19 deletions app/src/main/java/it/palsoftware/pastiera/StatusBarButtonsScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.activity.compose.BackHandler
import it.palsoftware.pastiera.R

private enum class StatusBarEditorMode { Extended, Pastierina }
private enum class StatusBarEditorMode { Extended, Unified, Pastierina }

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand Down Expand Up @@ -61,13 +61,10 @@ fun StatusBarButtonsScreen(
}
var editorMode by remember {
mutableStateOf(
if (
SettingsManager.getStatusBarPresentationMode(context) ==
SettingsManager.StatusBarPresentationMode.PASTIERINA
) {
StatusBarEditorMode.Pastierina
} else {
StatusBarEditorMode.Extended
when (SettingsManager.getStatusBarPresentationMode(context)) {
SettingsManager.StatusBarPresentationMode.FULL_STATUS_BAR -> StatusBarEditorMode.Extended
SettingsManager.StatusBarPresentationMode.UNIFIED -> StatusBarEditorMode.Unified
SettingsManager.StatusBarPresentationMode.PASTIERINA -> StatusBarEditorMode.Pastierina
}
)
}
Expand Down Expand Up @@ -230,21 +227,24 @@ fun StatusBarButtonsScreen(
editorMode = mode
SettingsManager.setStatusBarPresentationMode(
context,
if (mode == StatusBarEditorMode.Pastierina) {
SettingsManager.StatusBarPresentationMode.PASTIERINA
} else {
SettingsManager.StatusBarPresentationMode.FULL_STATUS_BAR
when (mode) {
StatusBarEditorMode.Extended ->
SettingsManager.StatusBarPresentationMode.FULL_STATUS_BAR
StatusBarEditorMode.Unified ->
SettingsManager.StatusBarPresentationMode.UNIFIED
StatusBarEditorMode.Pastierina ->
SettingsManager.StatusBarPresentationMode.PASTIERINA
}
)
},
shape = SegmentedButtonDefaults.itemShape(index, StatusBarEditorMode.entries.size)
) {
Text(
text = stringResource(
if (mode == StatusBarEditorMode.Extended) {
R.string.extended_status_bar_title
} else {
R.string.pastierina_status_bar_buttons_title
when (mode) {
StatusBarEditorMode.Extended -> R.string.extended_status_bar_option
StatusBarEditorMode.Unified -> R.string.unified_status_bar_option
StatusBarEditorMode.Pastierina -> R.string.pastierina_status_bar_option
}
),
maxLines = 1
Expand All @@ -254,11 +254,11 @@ fun StatusBarButtonsScreen(
}

StatusBarLayoutPreview(
leftSlots = if (editorMode == StatusBarEditorMode.Extended) leftSlots else pastierinaLeftSlots,
rightSlots = if (editorMode == StatusBarEditorMode.Extended) rightSlots else pastierinaRightSlots,
leftSlots = if (editorMode != StatusBarEditorMode.Pastierina) leftSlots else pastierinaLeftSlots,
rightSlots = if (editorMode != StatusBarEditorMode.Pastierina) rightSlots else pastierinaRightSlots,
centerText = if (editorMode == StatusBarEditorMode.Extended && variationsVisible) {
"· · ·"
} else if (editorMode == StatusBarEditorMode.Pastierina) {
} else if (editorMode != StatusBarEditorMode.Extended) {
stringResource(R.string.pastierina_preview_suggestions)
} else null
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ class KeyboardVisibilityController(
statusBarPresentationMode = when (statusBarPresentationMode) {
SettingsManager.StatusBarPresentationMode.PASTIERINA ->
SettingsManager.StatusBarPresentationMode.FULL_STATUS_BAR
SettingsManager.StatusBarPresentationMode.UNIFIED ->
SettingsManager.StatusBarPresentationMode.PASTIERINA
SettingsManager.StatusBarPresentationMode.FULL_STATUS_BAR ->
SettingsManager.StatusBarPresentationMode.PASTIERINA
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3035,10 +3035,16 @@ class StatusBarController(
val activeTheme = activeThemeSettings(isFullSoftwareKeyboardMode)
val activeColors = activeTheme.toKeyboardThemeColors()
val softwareThemeSettings = if (isFullSoftwareKeyboardMode) activeTheme else softwareTheme()
val unifiedStatusBar =
SettingsManager.getStatusBarPresentationMode(context) ==
SettingsManager.StatusBarPresentationMode.UNIFIED &&
!isFullSoftwareKeyboardMode
variationBarView?.onVariationSelectedListener = onVariationSelectedListener
variationBarView?.onCursorMovedListener = onCursorMovedListener
variationBarView?.onSuggestionCommitted = onSuggestionCommitted
variationBarView?.onHideSuggestion = onHideSuggestion
variationBarView?.updateInputConnection(inputConnection)
variationBarView?.forceVariationAreaVisible = isFullSoftwareKeyboardMode
variationBarView?.forceVariationAreaVisible = isFullSoftwareKeyboardMode || unifiedStatusBar
variationBarView?.setSymModeActive((snapshot.symPage > 0 && !isSoftwareKeyboardOverlayPage) || snapshot.clipboardOverlay)
variationBarView?.updateLanguageButtonText()
updateClipboardCount(snapshot.clipboardCount)
Expand Down Expand Up @@ -3103,7 +3109,8 @@ class StatusBarController(
if (showLedStrip) {
ledStatusView.update(snapshot)
}
val showSecondRow = !pastierinaModeActive
val expansionActive = expansionSuggestions.isNotEmpty()
val showSecondRow = !pastierinaModeActive && !(unifiedStatusBar && expansionActive)
val variationsBar = if (showSecondRow) variationBarView else null
val variationsWrapperView = if (showSecondRow) variationsWrapper else null
if (!showSecondRow) {
Expand All @@ -3112,8 +3119,7 @@ class StatusBarController(
val experimentalEnabled = SettingsManager.isExperimentalSuggestionsEnabled(context)
val suggestionsEnabledSetting = SettingsManager.getSuggestionsEnabled(context)
// Keep the suggestion/status row stable in both full-status-bar and Pastierina mode.
val expansionActive = expansionSuggestions.isNotEmpty()
val showFullBar = expansionActive || (
val showFullBar = expansionActive || (!unifiedStatusBar &&
suggestionsEnabledSetting &&
(experimentalEnabled || isFullSoftwareKeyboardMode) &&
(isFullSoftwareKeyboardMode || !snapshot.shouldDisableSuggestions) &&
Expand Down Expand Up @@ -3260,7 +3266,7 @@ class StatusBarController(
isEnabled = true
isClickable = true
}
val snapshotForVariations = if (snapshot.suggestions.isNotEmpty()) {
val snapshotForVariations = if (!unifiedStatusBar && snapshot.suggestions.isNotEmpty()) {
snapshot.copy(suggestions = emptyList(), addWordCandidate = null)
} else snapshot
variationsBar?.showVariations(snapshotForVariations, inputConnection)
Expand Down Expand Up @@ -3308,7 +3314,7 @@ class StatusBarController(
isEnabled = true
isClickable = true
}
val snapshotForVariations = if (snapshot.suggestions.isNotEmpty()) {
val snapshotForVariations = if (!unifiedStatusBar && snapshot.suggestions.isNotEmpty()) {
snapshot.copy(suggestions = emptyList(), addWordCandidate = null)
} else snapshot
variationsBar?.showVariations(snapshotForVariations, inputConnection)
Expand All @@ -3325,7 +3331,7 @@ class StatusBarController(
isEnabled = true
isClickable = true
}
val snapshotForVariations = if (snapshot.suggestions.isNotEmpty()) {
val snapshotForVariations = if (!unifiedStatusBar && snapshot.suggestions.isNotEmpty()) {
snapshot.copy(suggestions = emptyList(), addWordCandidate = null)
} else snapshot
variationsBar?.showVariations(snapshotForVariations, inputConnection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import it.palsoftware.pastiera.inputmethod.TextSelectionHelper
import it.palsoftware.pastiera.inputmethod.NotificationHelper
import it.palsoftware.pastiera.inputmethod.VariationButtonHandler
import it.palsoftware.pastiera.inputmethod.SpeechRecognitionActivity
import it.palsoftware.pastiera.inputmethod.suggestions.SuggestionButtonHandler
import it.palsoftware.pastiera.data.variation.VariationRepository
import android.graphics.Paint
import android.text.TextUtils
Expand Down Expand Up @@ -73,6 +74,8 @@ class VariationBarView(
var onSpeechRecognitionRequested: (() -> Unit)? = null
var onAddUserWord: ((String) -> Unit)? = null
var onAddUserWordSubstitutionRequested: ((String) -> Unit)? = null
var onSuggestionCommitted: (() -> Unit)? = null
var onHideSuggestion: ((String) -> Unit)? = null
var onLanguageSwitchRequested: (() -> Unit)? = null
var onClipboardRequested: (() -> Unit)? = null
var onEmojiPickerRequested: (() -> Unit)? = null
Expand Down Expand Up @@ -407,9 +410,11 @@ class VariationBarView(
// Legacy variations: always honor them when present, independent of suggestions.
val hasDynamicVariations = canShowVariations && snapshot.variations.isNotEmpty()
val hasSuggestions = canShowSuggestions && snapshot.suggestions.isNotEmpty()
val hasAddWordCandidate = canShowSuggestions && !snapshot.addWordCandidate.isNullOrBlank()
val useDynamicVariations = statusBarVariationsEnabled && !staticModeEnabled && hasDynamicVariations
val allowStaticFallback = statusBarVariationsEnabled &&
(forceVariationAreaVisible || staticModeEnabled || snapshot.shouldDisableVariations)
var isSuggestionContent = false

val effectiveVariations: List<String>
val isStaticContent: Boolean
Expand All @@ -422,6 +427,12 @@ class VariationBarView(
statusBarVariationsEnabled && hasSuggestions -> {
effectiveVariations = snapshot.suggestions
isStaticContent = false
isSuggestionContent = true
}
statusBarVariationsEnabled && hasAddWordCandidate -> {
effectiveVariations = listOfNotNull(snapshot.addWordCandidate)
isStaticContent = false
isSuggestionContent = true
}
allowStaticFallback -> {
val variations = if (snapshot.isEmailField) {
Expand Down Expand Up @@ -555,6 +566,7 @@ class VariationBarView(
val variationSlotsForSizing = when {
!reservesVariationArea -> 0
isStaticContent -> rawDisplayedVariations.size
isSuggestionContent -> rawDisplayedVariations.size.coerceIn(1, 3)
resizeDynamicVariationsToContent -> rawDisplayedVariations.size.coerceAtMost(dynamicSlotCount)
else -> dynamicSlotCount
}
Expand Down Expand Up @@ -708,6 +720,8 @@ class VariationBarView(
variationButtonHeight,
maxButtonWidth,
isStaticContent,
isSuggestionContent,
snapshot.shouldDisableAutoCapitalize,
isAddCandidate,
isLast,
spacingBetweenButtons
Expand Down Expand Up @@ -1098,6 +1112,8 @@ class VariationBarView(
buttonHeight: Int,
maxButtonWidth: Int,
isStatic: Boolean,
isSuggestionContent: Boolean,
shouldDisableAutoCapitalize: Boolean,
isAddCandidate: Boolean,
isLast: Boolean,
spacingBetweenButtons: Int
Expand Down Expand Up @@ -1177,6 +1193,14 @@ class VariationBarView(
context,
onVariationSelectedListener
)
} else if (isSuggestionContent) {
SuggestionButtonHandler.createSuggestionClickListener(
variation,
inputConnection,
onVariationSelectedListener,
shouldDisableAutoCapitalize = shouldDisableAutoCapitalize,
onSuggestionCommitted = onSuggestionCommitted
)
} else {
VariationButtonHandler.createVariationClickListener(
variation,
Expand All @@ -1195,6 +1219,12 @@ class VariationBarView(
onAddUserWordSubstitutionRequested?.invoke(variation)
true
}
} else if (isSuggestionContent) {
setOnLongClickListener {
performHapticFeedback(android.view.HapticFeedbackConstants.LONG_PRESS)
onHideSuggestion?.invoke(variation)
true
}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1550,9 +1550,12 @@ Each key can be configured as Keycode, Action, Native Ctrl, or None. Use overrid

<!-- Status Bar Buttons Configuration -->
<string name="status_bar_buttons_title">Status Bar</string>
<string name="status_bar_buttons_description">Configure the Status Bar and Pastierina Mode.</string>
<string name="status_bar_buttons_description">Configure the status bar style and buttons.</string>
<string name="status_bar_style_section">Status bar style</string>
<string name="extended_status_bar_title">Extended Status Bar</string>
<string name="extended_status_bar_option">Extended</string>
<string name="unified_status_bar_option">Unified</string>
<string name="pastierina_status_bar_option">Pastierina</string>
<string name="extended_status_bar_features_section">Extended features</string>
<string name="status_bar_buttons_section">Buttons</string>
<string name="pastierina_preview_suggestions">Suggestions</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package it.palsoftware.pastiera

import android.content.Context
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [33])
class SettingsManagerStatusBarPresentationTest {
private val context: Context
get() = RuntimeEnvironment.getApplication()

@After
fun tearDown() {
SettingsManager.getPreferences(context).edit().clear().commit()
}

@Test
fun unifiedPresentationModeRoundTrips() {
SettingsManager.setStatusBarPresentationMode(
context,
SettingsManager.StatusBarPresentationMode.UNIFIED
)

assertEquals(
SettingsManager.StatusBarPresentationMode.UNIFIED,
SettingsManager.getStatusBarPresentationMode(context)
)
}

@Test
fun unknownPresentationModeFallsBackToExtended() {
SettingsManager.getPreferences(context).edit()
.putString("pastierina_mode_override", "unknown")
.commit()

assertEquals(
SettingsManager.StatusBarPresentationMode.FULL_STATUS_BAR,
SettingsManager.getStatusBarPresentationMode(context)
)
}
}
Loading