Unify focus rings on the approved accent straddle style
This commit is contained in:
parent
93a41ea2d3
commit
ef3ae3f21b
18 changed files with 173 additions and 54 deletions
|
|
@ -90,6 +90,7 @@ class DiscoverCaptureTest {
|
|||
}
|
||||
|
||||
@Test fun st029_discover() = capture("st-029")
|
||||
@Test fun focusFilterChip() = capture("st-120") { it.focus(1, 0) }
|
||||
@Test fun st030_picksCollection() = capture("st-030") { state -> state.openCollection(state.lanes.first { it.id == "pk-movie" }) }
|
||||
@Test fun st031_hidden() = capture("st-031") { hidden(it) }
|
||||
@Test fun st032_restore() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package org.justinvisser.wolfskin.design
|
||||
|
||||
import android.app.Application
|
||||
import android.graphics.BitmapFactory
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.requiredSize
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.onRoot
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import java.io.File
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
/** Opaque content must not cover either half of the shared accent focus stroke. */
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [34], application = Application::class, qualifiers = "w960dp-h540dp-xhdpi")
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class FocusRingTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test fun ringStraddlesOpaqueSurfaceAndDisappearsWithoutFocus() {
|
||||
rule.activity.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
@Suppress("DEPRECATION")
|
||||
rule.activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
val focused = mutableStateOf(true)
|
||||
val radius = mutableStateOf(WolfskinTokens.Radius.button)
|
||||
rule.setContent {
|
||||
Box(Modifier.requiredSize(120.dp).background(WolfskinTokens.Color.bg)) {
|
||||
Box(Modifier.offset(40.dp, 40.dp).size(60.dp)
|
||||
.focusRing(focused.value, radius.value, WolfskinTokens.Focus.ringControlRing)
|
||||
.background(WolfskinTokens.Color.surface, RoundedCornerShape(radius.value)))
|
||||
}
|
||||
}
|
||||
val file = File.createTempFile("focus-ring-", ".png")
|
||||
try {
|
||||
for (corner in listOf(WolfskinTokens.Radius.button, 30.dp, WolfskinTokens.Radius.card)) {
|
||||
rule.runOnIdle { radius.value = corner }
|
||||
rule.mainClock.advanceTimeBy(1000)
|
||||
rule.waitForIdle()
|
||||
rule.onRoot().captureRoboImage(file.absolutePath)
|
||||
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
|
||||
for ((x, expected) in listOf(77 to WolfskinTokens.Color.bg, 78 to WolfskinTokens.Color.accent,
|
||||
79 to WolfskinTokens.Color.accent, 80 to WolfskinTokens.Color.accent,
|
||||
81 to WolfskinTokens.Color.accent, 82 to WolfskinTokens.Color.surface)) {
|
||||
assertPixel("Left edge x=$x, radius=$corner", expected.toArgb(), bitmap.getPixel(x, 140))
|
||||
assertPixel("Top edge y=$x, radius=$corner", expected.toArgb(), bitmap.getPixel(140, x))
|
||||
}
|
||||
bitmap.recycle()
|
||||
}
|
||||
rule.runOnIdle { focused.value = false }
|
||||
rule.mainClock.advanceTimeBy(1000)
|
||||
rule.waitForIdle()
|
||||
rule.onRoot().captureRoboImage(file.absolutePath)
|
||||
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
|
||||
assertEquals(WolfskinTokens.Color.bg.toArgb(), bitmap.getPixel(79, 140))
|
||||
assertEquals(WolfskinTokens.Color.surface.toArgb(), bitmap.getPixel(80, 140))
|
||||
bitmap.recycle()
|
||||
} finally { file.delete() }
|
||||
}
|
||||
private fun assertPixel(label: String, expected: Int, actual: Int) {
|
||||
// Circular edge coverage can differ by a few channel values at pixel centres.
|
||||
for (shift in listOf(0, 8, 16, 24)) {
|
||||
val difference = kotlin.math.abs((expected ushr shift and 255) - (actual ushr shift and 255))
|
||||
assertTrue("$label: channel $shift differs by $difference", difference <= 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,5 +116,6 @@ class HomeCaptureTest {
|
|||
@Test fun st102_filmTile() = capture("st-102", person = "mindel", row = "new", column = 4)
|
||||
@Test fun st103_heroRatings() = capture("st-103")
|
||||
@Test fun spacingNextUpFirstFocused() = capture("spacing-next-up", row = "nu")
|
||||
@Test fun focusHeroDetails() = capture("focus-hero-details", column = 1)
|
||||
@Test fun xHomeDiscoverStart() = capture("x-home-discover-start", row = "pk-m")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ class LibraryCaptureTest {
|
|||
@Test fun st113_uncachedWhileDown() = capture("st-113", reachable = false)
|
||||
@Test fun unsignedRatingsHidden() = capture("library-unsigned", ratings = false)
|
||||
@Test fun spacingShowsFirstFocused() = capture("spacing-shows", "mindel", "shows")
|
||||
@Test fun focusToolbarChip() = capture("focus-toolbar-chip") { it.toolbar = true; it.tool = 0 }
|
||||
@Test fun spacingLetterRailClearsFocusedFifthColumn() = capture("spacing-letter-rail") { grid ->
|
||||
val original = grid.source
|
||||
grid.source = List(200) { index ->
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ class ShellCaptureTest {
|
|||
}
|
||||
|
||||
@Test fun st001_launch() = capture("st-001")
|
||||
@Test fun focusNavAvatar() = capture("focus-nav-avatar") { it.pickerVisible = false; it.focusNav(it.tabs.size) }
|
||||
@Test fun st002_gear() {
|
||||
capture("st-002") { it.pickerIndex = 2; it.gearFocused = true }
|
||||
val layouts = mutableListOf<TextLayoutResult>()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue