@@ -153,6 +153,7 @@ fun TapLockScreen() {
153153 val floatingButtonKey = stringResource(R .string.floating_button_enabled)
154154 val floatingButtonSizeDpKey = stringResource(R .string.floating_button_size_dp)
155155 val floatingButtonOpacityPercentKey = stringResource(R .string.floating_button_opacity_percent)
156+ val lockZoneTopOffsetPercentKey = stringResource(R .string.lock_zone_top_offset_percent)
156157
157158 var showDialog by remember { mutableStateOf(false ) }
158159
@@ -183,7 +184,10 @@ fun TapLockScreen() {
183184 var onboardingStep by remember { mutableIntStateOf(0 ) }
184185 var lockDelayMs by remember { mutableIntStateOf(0 ) }
185186 var lockCount by remember { mutableIntStateOf(0 ) }
186- var lockZonePercent by remember { mutableFloatStateOf(66f ) }
187+ var lockZonePercent by remember { mutableFloatStateOf(TapLockLockZone .DEFAULT_PERCENT .toFloat()) }
188+ var lockZoneTopOffsetPercent by remember {
189+ mutableFloatStateOf(TapLockLockZone .DEFAULT_TOP_OFFSET_PERCENT .toFloat())
190+ }
187191 var edgeZoneWidthDp by remember {
188192 mutableFloatStateOf(TapLockEdgeZones .DEFAULT_WIDTH_DP .toFloat())
189193 }
@@ -216,11 +220,13 @@ fun TapLockScreen() {
216220 val edgeBottomOffsetSliderInteraction = remember { MutableInteractionSource () }
217221 val cornerSizeSliderInteraction = remember { MutableInteractionSource () }
218222 val lockZoneSliderInteraction = remember { MutableInteractionSource () }
223+ val lockZoneTopOffsetSliderInteraction = remember { MutableInteractionSource () }
219224 val isEdgeWidthSliderDragged by edgeWidthSliderInteraction.collectIsDraggedAsState()
220225 val isEdgeTopOffsetSliderDragged by edgeTopOffsetSliderInteraction.collectIsDraggedAsState()
221226 val isEdgeBottomOffsetSliderDragged by edgeBottomOffsetSliderInteraction.collectIsDraggedAsState()
222227 val isCornerSizeSliderDragged by cornerSizeSliderInteraction.collectIsDraggedAsState()
223228 val isLockZoneSliderDragged by lockZoneSliderInteraction.collectIsDraggedAsState()
229+ val isLockZoneTopOffsetSliderDragged by lockZoneTopOffsetSliderInteraction.collectIsDraggedAsState()
224230 var showLockZonePreviewOverlay by remember { mutableStateOf(false ) }
225231 val editableLeftEdgeZoneEnabled = leftEdgeZoneEnabled
226232 val editableRightEdgeZoneEnabled = rightEdgeZoneEnabled
@@ -246,7 +252,7 @@ fun TapLockScreen() {
246252 isCornerSizeSliderDragged
247253 )
248254 val showLockZoneLiveOverlay = lockScreenDoubleTap &&
249- (isLockZoneSliderDragged || showLockZonePreviewOverlay)
255+ (isLockZoneSliderDragged || isLockZoneTopOffsetSliderDragged || showLockZonePreviewOverlay)
250256
251257 LaunchedEffect (showLockZonePreviewOverlay) {
252258 if (showLockZonePreviewOverlay) {
@@ -265,6 +271,27 @@ fun TapLockScreen() {
265271 .edit { putInt(baseKey, value) }
266272 }
267273
274+ fun syncLockZoneState (
275+ zonePercent : Int = lockZonePercent.toInt(),
276+ topOffsetPercent : Int = lockZoneTopOffsetPercent.toInt()
277+ ) {
278+ val clampedZonePercent = TapLockLockZone .clampPercent(zonePercent)
279+ val clampedTopOffsetPercent = TapLockLockZone .clampTopOffsetPercent(
280+ topOffsetPercent,
281+ clampedZonePercent
282+ )
283+ lockZonePercent = clampedZonePercent.toFloat()
284+ lockZoneTopOffsetPercent = clampedTopOffsetPercent.toFloat()
285+ }
286+
287+ fun persistLockZoneSettings () {
288+ syncLockZoneState()
289+ context.getSharedPreferences(sharedPrefName, Context .MODE_PRIVATE ).edit {
290+ putInt(lockZonePercentKey, lockZonePercent.toInt())
291+ putInt(lockZoneTopOffsetPercentKey, lockZoneTopOffsetPercent.toInt())
292+ }
293+ }
294+
268295 fun setEditableEdgeEnabled (side : EdgeZoneSide , isEnabled : Boolean ) {
269296 when (side) {
270297 EdgeZoneSide .LEFT -> leftEdgeZoneEnabled = isEnabled
@@ -366,7 +393,13 @@ fun TapLockScreen() {
366393 showOnboarding = ! prefs.getBoolean(hasCompletedOnboardingKey, false )
367394 lockDelayMs = prefs.getInt(lockDelayMsKey, 0 )
368395 lockCount = prefs.getInt(lockCountKey, 0 )
369- lockZonePercent = prefs.getInt(lockZonePercentKey, 66 ).toFloat()
396+ syncLockZoneState(
397+ zonePercent = prefs.getInt(lockZonePercentKey, TapLockLockZone .DEFAULT_PERCENT ),
398+ topOffsetPercent = prefs.getInt(
399+ lockZoneTopOffsetPercentKey,
400+ TapLockLockZone .DEFAULT_TOP_OFFSET_PERCENT
401+ )
402+ )
370403 edgeZoneWidthDp = prefs.getInt(
371404 edgeZoneWidthDpKey,
372405 TapLockEdgeZones .DEFAULT_WIDTH_DP
@@ -1100,29 +1133,49 @@ fun TapLockScreen() {
11001133 }
11011134
11021135 if (lockScreenDoubleTap) {
1103- val lockZoneKey = stringResource(R .string.lock_zone_percent)
1136+ val maxLockZoneTopOffsetPercent =
1137+ TapLockLockZone .maxTopOffsetPercent(lockZonePercent.toInt())
11041138 Text (
11051139 stringResource(R .string.lock_zone_label, lockZonePercent.toInt()),
11061140 style = MaterialTheme .typography.bodySmall
11071141 )
11081142 Slider (
11091143 value = lockZonePercent,
1110- onValueChange = { lockZonePercent = it },
1111- onValueChangeFinished = {
1112- context.getSharedPreferences(sharedPrefName, Context .MODE_PRIVATE )
1113- .edit { putInt(lockZoneKey, lockZonePercent.toInt()) }
1114- },
1115- valueRange = 20f .. 100f ,
1144+ onValueChange = { syncLockZoneState(zonePercent = it.toInt()) },
1145+ onValueChangeFinished = { persistLockZoneSettings() },
1146+ valueRange = TapLockLockZone .MIN_PERCENT .toFloat()..
1147+ TapLockLockZone .MAX_PERCENT .toFloat(),
11161148 steps = 15 ,
11171149 interactionSource = lockZoneSliderInteraction,
11181150 modifier = Modifier .testTag(" slider_lock_zone" )
11191151 )
1152+ Text (
1153+ stringResource(
1154+ R .string.lock_zone_top_offset_label,
1155+ lockZoneTopOffsetPercent.toInt()
1156+ ),
1157+ style = MaterialTheme .typography.bodySmall
1158+ )
1159+ if (maxLockZoneTopOffsetPercent > 0 ) {
1160+ Slider (
1161+ value = lockZoneTopOffsetPercent,
1162+ onValueChange = { syncLockZoneState(topOffsetPercent = it.toInt()) },
1163+ onValueChangeFinished = { persistLockZoneSettings() },
1164+ valueRange = TapLockLockZone .MIN_TOP_OFFSET_PERCENT .toFloat()..
1165+ maxLockZoneTopOffsetPercent.toFloat(),
1166+ interactionSource = lockZoneTopOffsetSliderInteraction,
1167+ modifier = Modifier .testTag(" slider_lock_zone_top_offset" )
1168+ )
1169+ }
11201170 Text (
11211171 stringResource(R .string.lock_zone_preview_label),
11221172 style = MaterialTheme .typography.bodySmall,
11231173 color = MaterialTheme .colorScheme.onSurfaceVariant
11241174 )
1125- LockScreenZonePreview (lockZonePercent = lockZonePercent.toInt())
1175+ LockScreenZonePreview (
1176+ lockZonePercent = lockZonePercent.toInt(),
1177+ lockZoneTopOffsetPercent = lockZoneTopOffsetPercent.toInt()
1178+ )
11261179 Button (
11271180 onClick = { showLockZonePreviewOverlay = true },
11281181 modifier = Modifier .testTag(" button_lock_zone_preview" )
@@ -1571,7 +1624,10 @@ fun TapLockScreen() {
15711624 }
15721625
15731626 if (showLockZoneLiveOverlay) {
1574- LockScreenZoneLiveOverlay (lockZonePercent = lockZonePercent.toInt())
1627+ LockScreenZoneLiveOverlay (
1628+ lockZonePercent = lockZonePercent.toInt(),
1629+ lockZoneTopOffsetPercent = lockZoneTopOffsetPercent.toInt()
1630+ )
15751631 }
15761632
15771633 if (showEdgeZoneLiveOverlay) {
0 commit comments