Skip to content

Commit

Permalink
feat: android nested text runs
Browse files Browse the repository at this point in the history
Diffs=
68d6cda32 feat: android nested text runs (#8126)

Co-authored-by: Gordon <[email protected]>
  • Loading branch information
HayesGordon and HayesGordon committed Sep 13, 2024
1 parent d8b5aad commit baf7cb6
Show file tree
Hide file tree
Showing 14 changed files with 508 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c67b67083abe9d1448137122aeb76f20549ae89b
68d6cda329f2252242dca46b92cb2bc552ee6bfa
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<activity android:name=".LowLevelActivity" />
<activity android:name=".SimpleStateMachineActivity" />
<activity android:name=".NestedInputActivity" />
<activity android:name=".NestedTextRunActivity" />
<activity android:name=".HttpActivity" />
<activity android:name=".ButtonActivity" />
<activity android:name=".BlendActivity" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class DynamicTextActivity : AppCompatActivity(), TextWatcher {
textRun?.text?.let { Log.i("text-value-run", "Run before change: $it") }

// or you can get the current value with:
// animationView.getTextRunValue("name")
// animationView.getTextRunValue("name").let { Log.i("text-value-run", "Run before change: $it") }
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/app/rive/runtime/example/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class MainActivity : AppCompatActivity() {
Pair(R.id.go_http, HttpActivity::class.java),
Pair(R.id.go_simple_state_machine, SimpleStateMachineActivity::class.java),
Pair(R.id.go_nested_input, NestedInputActivity::class.java),
Pair(R.id.go_nested_text_run, NestedTextRunActivity::class.java),
Pair(R.id.go_button, ButtonActivity::class.java),
Pair(R.id.go_blend, BlendActivity::class.java),
Pair(R.id.go_metrics, MetricsActivity::class.java),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package app.rive.runtime.example

import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.RadioButton
import androidx.appcompat.app.AppCompatActivity
import app.rive.runtime.kotlin.RiveAnimationView

class NestedTextRunActivity : AppCompatActivity() {

private val animationView by lazy(LazyThreadSafetyMode.NONE) {
findViewById<RiveAnimationView>(R.id.nested_text_run)
}

fun onButtonClick(view: View) {
if (view is Button) {
when (view.id) {
R.id.set_b1 -> {
Log.d("nested-text-run", animationView.getTextRunValue("ArtboardBRun", "ArtboardB-1").toString())
animationView.setTextRunValue(
textRunName = "ArtboardBRun",
textValue = "ArtboardB-1 Updated",
path = "ArtboardB-1"
)
Log.d("nested-text-run", animationView.getTextRunValue("ArtboardBRun", "ArtboardB-1").toString())
}
R.id.set_b2 -> {
animationView.setTextRunValue(
"ArtboardBRun",
"ArtboardB-2 Updated",
"ArtboardB-2"
)
}
R.id.set_b1_c1 -> {
animationView.setTextRunValue(
"ArtboardCRun",
"ArtboardB-1/C-1 Updated",
"ArtboardB-1/ArtboardC-1"
)
}
R.id.set_b1_c2 -> {
animationView.setTextRunValue(
"ArtboardCRun",
"ArtboardB-1/C-2 Updated",
"ArtboardB-1/ArtboardC-2"
)
}
R.id.set_b2_c1 -> {
animationView.setTextRunValue(
"ArtboardCRun",
"ArtboardB-2/C-1 Updated",
"ArtboardB-2/ArtboardC-1"
)
}
R.id.set_b2_c2 -> {
animationView.setTextRunValue(
"ArtboardCRun",
"ArtboardB-2/C-2 Updated",
"ArtboardB-2/ArtboardC-2"
)
}
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.nested_text_run)
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/layout/main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@
android:text="Nested Inputs"
android:textColor="@color/textColorPrimary" />

<Button
android:id="@+id/go_nested_text_run"
style="@style/Widget.Material3.Button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="4dp"
android:text="Nested Text Runs"
android:textColor="@color/textColorPrimary" />

<Button
android:id="@+id/go_button"
style="@style/Widget.Material3.Button"
Expand Down
81 changes: 81 additions & 0 deletions app/src/main/res/layout/nested_text_run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<app.rive.runtime.kotlin.RiveAnimationView
android:id="@+id/nested_text_run"
android:layout_width="match_parent"
android:layout_height="400dp"
app:riveResource="@raw/runtime_nested_text_runs"
app:riveArtboard="ArtboardA"
app:riveStateMachine="State Machine 1" />

<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"

android:orientation="vertical">

<Button
android:id="@+id/set_b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:textColor="@color/textColorPrimary"
android:text="Set B1" />

<Button
android:id="@+id/set_b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:textColor="@color/textColorPrimary"
android:text="Set B2" />

<Button
android:id="@+id/set_b1_c1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:textColor="@color/textColorPrimary"
android:text="Set B1/C1" />

<Button
android:id="@+id/set_b1_c2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:textColor="@color/textColorPrimary"
android:text="Set B1/C2" />

<Button
android:id="@+id/set_b2_c1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:textColor="@color/textColorPrimary"
android:text="Set B2/C1" />

<Button
android:id="@+id/set_b2_c2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButtonClick"
android:textColor="@color/textColorPrimary"
android:text="Set B2/C2" />

</RadioGroup>
</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package app.rive.runtime.kotlin.core

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
import app.rive.runtime.kotlin.RiveAnimationView
import app.rive.runtime.kotlin.core.errors.RiveException
import app.rive.runtime.kotlin.core.errors.TextValueRunException
import app.rive.runtime.kotlin.test.R
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -14,25 +19,162 @@ class RiveTextValueRunTest {
private val testUtils = TestUtils()
private val appContext = testUtils.context
private lateinit var file: File
private lateinit var nestePathFile: File
private lateinit var mockView: RiveAnimationView

@Before
fun init() {
file = File(
appContext.resources.openRawResource(R.raw.hello_world_text).readBytes()
)
nestePathFile= File(
appContext.resources.openRawResource(R.raw.runtime_nested_text_runs).readBytes()
)

mockView = TestUtils.MockRiveAnimationView(appContext)
}

@Test
fun read_and_update_text_run() {
val textRun = file.firstArtboard.textRun("name")
var artboard = file.firstArtboard;
assertEquals(artboard.dependencies.count(), 0)

val textRun = artboard.textRun("name")

// Confirm original value
assertEquals("world", textRun.text)
assertEquals("world", artboard.getTextRunValue("name"))

var updateValue = "username"

// Setting the text run directly
textRun.text = updateValue
assertEquals(updateValue, textRun.text)
assertEquals(updateValue, artboard.getTextRunValue("name"))

// Setting through the helper method
updateValue = "new value"
artboard.setTextRunValue("name",updateValue)
assertEquals(updateValue, textRun.text)
assertEquals(updateValue, artboard.getTextRunValue("name"))

// Only accessing .textRun should add to the dependencies.
assertEquals(artboard.dependencies.count(), 1)
}

@Test(expected = TextValueRunException::class)
fun read_non_existing_text_run() {
file.firstArtboard.textRun("wrong-name")
}

@Test
fun read_and_update_text_run_at_path() {
val artboard = nestePathFile.firstArtboard;
assertEquals(artboard.dependencies.count(), 0)

nestedTextRunHelper(artboard, "ArtboardBRun", "ArtboardB-1","Artboard B Run", "ArtboardB-1" )
nestedTextRunHelper(artboard, "ArtboardBRun", "ArtboardB-2","Artboard B Run", "ArtboardB-2" )
nestedTextRunHelper(artboard, "ArtboardCRun", "ArtboardB-1/ArtboardC-1","Artboard C Run", "ArtboardB-1/C-1" )
nestedTextRunHelper(artboard, "ArtboardCRun", "ArtboardB-1/ArtboardC-2","Artboard C Run", "ArtboardB-1/C-2" )
nestedTextRunHelper(artboard, "ArtboardCRun", "ArtboardB-2/ArtboardC-1","Artboard C Run", "ArtboardB-2/C-1" )
nestedTextRunHelper(artboard, "ArtboardCRun", "ArtboardB-2/ArtboardC-2","Artboard C Run", "ArtboardB-2/C-2" )

// Only accessing the textRun directly should increase the dependency.
// Calling getTextRunValue and setTextRunValue should not.
assertEquals(artboard.dependencies.count(), 6)
}

private fun nestedTextRunHelper(artboard: Artboard, name: String, path: String, originalValue: String, updatedValue: String) {
// Get the text value run. This should increase the dependency count
val textRun = artboard.textRun(name, path = path)

// Assert the original value is correct
assertEquals(originalValue, textRun.text)
assertEquals(originalValue, artboard.getTextRunValue(name, path = path))

// Update the `textRun` reference directly
textRun.text = updatedValue
assertEquals(updatedValue, textRun.text)
assertEquals(updatedValue, artboard.getTextRunValue(name, path = path))

// Update the text run back to the original value through the helper method
artboard.setTextRunValue(name, originalValue, path)
assertEquals(originalValue, textRun.text)
assertEquals(originalValue, artboard.getTextRunValue(name, path = path))
}

@Test
fun viewSetGetTextRun() {
UiThreadStatement.runOnUiThread {
mockView.setRiveResource(R.raw.hello_world_text, autoplay = false)
mockView.play(listOf("State Machine 1"), areStateMachines = true)
assertEquals(true, mockView.isPlaying)

assertEquals(mockView.controller.activeArtboard?.dependencies?.count(), 1)
val textValue = mockView.getTextRunValue("name")
assertEquals(textValue, "world")

var newValue = "New Value";
mockView.setTextRunValue("name", newValue)
val textValueUpdated = mockView.getTextRunValue("name")
assertEquals(textValueUpdated, newValue)

assertEquals(mockView.controller.activeArtboard?.dependencies?.count(), 1)

// Test for throwing an error when giving a wrong text run name
try {
mockView.setTextRunValue("non_existent_text_run", "Some Value")
fail("Expected an exception to be thrown")
} catch (e: Exception) {
assertTrue(e is RiveException)
assertTrue(e.message?.contains("No Rive TextValueRun found") == true)
}

// Test for throwing an error when giving a wrong text run name for a nested artboard
try {
mockView.setTextRunValue("non_existent_text_run", "Some Value", "ArtboardB-1")
fail("Expected an exception to be thrown")
} catch (e: Exception) {
assertTrue(e is RiveException)
assertTrue(e.message?.contains("No Rive TextValueRun found") == true)
}
}
}
@Test
fun viewSetGetNestedTextRun() {
UiThreadStatement.runOnUiThread {
mockView.setRiveResource(R.raw.runtime_nested_text_runs, autoplay = false)
mockView.play(listOf("State Machine 1"), areStateMachines = true)
assertEquals(true, mockView.isPlaying)

assertEquals(mockView.controller.activeArtboard?.dependencies?.count(), 1)
val textValue = mockView.getTextRunValue("ArtboardBRun", "ArtboardB-1")
assertEquals(textValue, "Artboard B Run")

var newValue = "New Value";
mockView.setTextRunValue("ArtboardBRun", newValue, "ArtboardB-1" )
val textValueUpdated = mockView.getTextRunValue("ArtboardBRun", "ArtboardB-1")
assertEquals(textValueUpdated, newValue)

assertEquals(mockView.controller.activeArtboard?.dependencies?.count(), 1)

// Test for throwing an error when giving a wrong text run name for a nested artboard
try {
mockView.setTextRunValue("non_existent_text_run", "Some Value", "ArtboardB-1")
fail("Expected an exception to be thrown")
} catch (e: Exception) {
assertTrue(e is RiveException)
assertTrue(e.message?.contains("No Rive TextValueRun found") == true)
}

// Test for throwing an error when giving a wrong path for a nested artboard
try {
mockView.setTextRunValue("ArtboardBRun", "Some Value", "non_existent_path")
fail("Expected an exception to be thrown")
} catch (e: Exception) {
assertTrue(e is RiveException)
assertTrue(e.message?.contains("No Rive TextValueRun found") == true)
}
}
}
}
Binary file not shown.
Loading

0 comments on commit baf7cb6

Please sign in to comment.