Skip to content
Closed
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
package com.squareup.sample.container

import com.squareup.workflow1.ui.DecorativeScreenViewFactory
import com.squareup.workflow1.ui.Screen
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.acceptRenderings
import com.squareup.workflow1.ui.backPressedHandler
import com.squareup.workflow1.ui.buildView
import com.squareup.workflow1.ui.withShowScreen

/**
* [ScreenViewFactory] that performs the work required by [BackButtonScreen].
* [ScreenViewFactory] that performs the work required by [BackButtonScreen], demonstrating
* some fancy [ScreenViewHolder][com.squareup.workflow1.ui.ScreenViewHolder] tricks in
* the process.
*/
@WorkflowUiExperimentalApi
object BackButtonViewFactory : ScreenViewFactory<BackButtonScreen<*>>
by DecorativeScreenViewFactory(
type = BackButtonScreen::class,
map = { outer -> outer.wrapped },
doShowRendering = { view, innerShowRendering, outerRendering, viewEnvironment ->
if (!outerRendering.override) {
// Place our handler before invoking innerShowRendering, so that
// its later calls to view.backPressedHandler will take precedence
// over ours.
view.backPressedHandler = outerRendering.onBackPressed
}
val BackButtonViewFactory: ScreenViewFactory<BackButtonScreen<*>> =
ScreenViewFactory.of { initialRendering, initialViewEnvironment, context, container ->
initialRendering.wrapped
// Build the view for the wrapped rendering.
.buildView(initialViewEnvironment, context, container)
// Transform it to accept BackButtonScreen directly
.acceptRenderings(initialRendering) { backButtonScreen -> backButtonScreen.wrapped }
// Replace the showScreen method with one that can do a bit of pre- and post-processing
// on the view.
.withShowScreen { backButtonScreen, viewEnvironment ->
if (!backButtonScreen.override) {
// Place our handler before invoking the real showRendering method, so that
// its later calls to view.backPressedHandler will take precedence
// over ours.
view.backPressedHandler = backButtonScreen.onBackPressed
}

innerShowRendering.invoke(outerRendering.wrapped, viewEnvironment)
// The receiver of this lambda is the one that received the withShowScreen call,
// so we're able to call the "real" showScreen method.
showScreen(backButtonScreen, viewEnvironment)

if (outerRendering.override) {
// Place our handler after invoking innerShowRendering, so that ours wins.
view.backPressedHandler = outerRendering.onBackPressed
}
if (backButtonScreen.override) {
// Place our handler after invoking innerShowRendering, so that ours wins.
view.backPressedHandler = backButtonScreen.onBackPressed
}
}
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.squareup.sample.container.panel.ScrimScreen
import com.squareup.workflow1.ui.ManualScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewHolder
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.WorkflowViewStub
import com.squareup.workflow1.ui.bindShowRendering

/**
* A view that renders only its first child, behind a smoke scrim if
Expand All @@ -33,7 +32,7 @@ internal class ScrimContainer @JvmOverloads constructor(

private val child: View
get() = getChildAt(0)
?: error("Child must be set immediately upon creation.")
?: error("Child must be set immediately upon creation.")

var isDimmed: Boolean = false
set(value) {
Expand Down Expand Up @@ -84,30 +83,29 @@ internal class ScrimContainer @JvmOverloads constructor(
ValueAnimator.ofFloat(1f, 0f)
}.apply {
duration = resources.getInteger(android.R.integer.config_shortAnimTime)
.toLong()
.toLong()
addUpdateListener { animation -> scrim.alpha = animation.animatedValue as Float }
start()
}
}

@OptIn(WorkflowUiExperimentalApi::class)
companion object : ScreenViewFactory<ScrimScreen<*>> by ManualScreenViewFactory(
type = ScrimScreen::class,
viewConstructor = { initialRendering, initialViewEnvironment, contextForNewView, _ ->
val stub = WorkflowViewStub(contextForNewView)
companion object : ScreenViewFactory<ScrimScreen<*>> by ScreenViewFactory.of(
viewConstructor = { initialRendering, initialViewEnvironment, contextForNewView, _ ->
val stub = WorkflowViewStub(contextForNewView)

ScrimContainer(contextForNewView)
.also { view ->
view.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
view.addView(stub)
ScrimContainer(contextForNewView)
.let { view ->
view.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
view.addView(stub)

view.bindShowRendering(
initialRendering, initialViewEnvironment
) { rendering, environment ->
stub.show(rendering.content, environment)
view.isDimmed = rendering.dimmed
}
}
}
ScreenViewHolder(
initialRendering, initialViewEnvironment, view
) { rendering, environment ->
stub.show(rendering.content, environment)
view.isDimmed = rendering.dimmed
}
}
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.squareup.sample.container.overviewdetail.OverviewDetailConfig.Detail
import com.squareup.sample.container.overviewdetail.OverviewDetailConfig.Overview
import com.squareup.sample.container.overviewdetail.OverviewDetailConfig.Single
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewRunner
import com.squareup.workflow1.ui.ScreenViewUpdater
import com.squareup.workflow1.ui.ViewEnvironment
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.WorkflowViewStub
Expand All @@ -25,7 +25,7 @@ import com.squareup.workflow1.ui.container.withBackStackStateKeyPrefix
* with [OverviewDetailScreen.overviewRendering] as the base of the stack.
*/
@OptIn(WorkflowUiExperimentalApi::class)
class OverviewDetailContainer(view: View) : ScreenViewRunner<OverviewDetailScreen> {
class OverviewDetailContainer(view: View) : ScreenViewUpdater<OverviewDetailScreen> {

private val overviewStub: WorkflowViewStub? = view.findViewById(R.id.overview_stub)
private val detailStub: WorkflowViewStub? = view.findViewById(R.id.detail_stub)
Expand Down Expand Up @@ -60,14 +60,14 @@ class OverviewDetailContainer(view: View) : ScreenViewRunner<OverviewDetailScree
overviewStub!!.show(rendering.overviewRendering, overviewViewEnvironment)
rendering.detailRendering
?.let { detail ->
detailStub!!.actual.visibility = VISIBLE
detailStub!!.delegateHolder.view.visibility = VISIBLE
detailStub.show(
detail,
viewEnvironment + (OverviewDetailConfig to Detail)
)
}
?: run {
detailStub!!.actual.visibility = INVISIBLE
detailStub!!.delegateHolder.view.visibility = INVISIBLE
}
}
}
Expand All @@ -84,11 +84,9 @@ class OverviewDetailContainer(view: View) : ScreenViewRunner<OverviewDetailScree
stub.show(combined, viewEnvironment + (OverviewDetailConfig to Single))
}

companion object : ScreenViewFactory<OverviewDetailScreen> by ScreenViewRunner.bind(
layoutId = R.layout.overview_detail,
constructor = ::OverviewDetailContainer
companion object : ScreenViewFactory<OverviewDetailScreen> by ScreenViewFactory.ofLayout(R.layout.overview_detail,
{ it: View -> OverviewDetailContainer(it) }
) {
private const val OverviewBackStackKey = "overview"
private const val DetailBackStackKey = "detail"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import android.app.Dialog
import android.graphics.Rect
import android.graphics.drawable.ColorDrawable
import android.util.TypedValue
import android.view.View
import com.squareup.sample.container.R
import com.squareup.workflow1.ui.ScreenViewHolder
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.container.ModalScreenOverlayDialogFactory
import com.squareup.workflow1.ui.container.setBounds
Expand All @@ -17,10 +17,10 @@ import com.squareup.workflow1.ui.container.setBounds
internal object PanelOverlayDialogFactory : ModalScreenOverlayDialogFactory<PanelOverlay<*>>(
type = PanelOverlay::class
) {
override fun buildDialogWithContentView(contentView: View): Dialog {
val context = contentView.context
override fun buildDialogWithContent(content: ScreenViewHolder<*>): Dialog {
val context = content.view.context
return Dialog(context, R.style.PanelDialog).also { dialog ->
dialog.setContentView(contentView)
dialog.setContentView(content.view)

// Welcome to Android. Nothing workflow-related here, this is just how one
// finds the window background color for the theme. I sure hope it's better in Compose.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import com.squareup.sample.container.overviewdetail.OverviewDetailConfig.Overvie
import com.squareup.sample.container.poetryapp.R
import com.squareup.sample.poetry.model.Poem
import com.squareup.workflow1.ui.AndroidScreen
import com.squareup.workflow1.ui.ScreenViewRunner
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewUpdater
import com.squareup.workflow1.ui.ViewEnvironment
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi

Expand All @@ -22,14 +23,13 @@ data class PoemListScreen(
val onPoemSelected: (Int) -> Unit,
val selection: Int = -1
) : AndroidScreen<PoemListScreen> {
override val viewFactory = ScreenViewRunner.bind(
R.layout.list,
::PoemListLayoutRunner
)
override val viewFactory = ScreenViewFactory.ofLayout(
R.layout.list
) { it: View -> PoemListLayoutUpdater(it) }
}

@OptIn(WorkflowUiExperimentalApi::class)
private class PoemListLayoutRunner(view: View) : ScreenViewRunner<PoemListScreen> {
private class PoemListLayoutUpdater(view: View) : ScreenViewUpdater<PoemListScreen> {
init {
view.findViewById<Toolbar>(R.id.list_toolbar)
.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.view.View
import android.widget.TextView
import com.squareup.workflow1.ui.AndroidScreen
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewRunner
import com.squareup.workflow1.ui.ScreenViewUpdater
import com.squareup.workflow1.ui.ViewEnvironment
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.backPressedHandler
Expand All @@ -15,13 +15,13 @@ data class HelloBackButtonScreen(
val onClick: () -> Unit,
val onBackPressed: (() -> Unit)?
) : AndroidScreen<HelloBackButtonScreen> {
override val viewFactory: ScreenViewFactory<HelloBackButtonScreen> = ScreenViewRunner.bind(
R.layout.hello_back_button_layout, ::HelloBackButtonLayoutRunner
)
override val viewFactory: ScreenViewFactory<HelloBackButtonScreen> = ScreenViewFactory.ofLayout(
R.layout.hello_back_button_layout
) { it: View -> HelloBackButtonLayoutUpdater(it) }
}

@OptIn(WorkflowUiExperimentalApi::class)
private class HelloBackButtonLayoutRunner(view: View) : ScreenViewRunner<HelloBackButtonScreen> {
private class HelloBackButtonLayoutUpdater(view: View) : ScreenViewUpdater<HelloBackButtonScreen> {
private val messageView: TextView = view.findViewById(R.id.hello_message)

override fun showRendering(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.squareup.sample.container.overviewdetail.OverviewDetailConfig.Overvie
import com.squareup.sample.container.poetry.R
import com.squareup.workflow1.ui.AndroidScreen
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewRunner
import com.squareup.workflow1.ui.ScreenViewUpdater
import com.squareup.workflow1.ui.ViewEnvironment
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.backPressedHandler
Expand All @@ -28,14 +28,13 @@ data class StanzaListScreen(
val onExit: () -> Unit,
val selection: Int = -1
) : AndroidScreen<StanzaListScreen> {
override val viewFactory: ScreenViewFactory<StanzaListScreen> = ScreenViewRunner.bind(
R.layout.list,
::StanzaListLayoutRunner
)
override val viewFactory: ScreenViewFactory<StanzaListScreen> = ScreenViewFactory.ofLayout(
R.layout.list
) { it: View -> StanzaListLayoutUpdater(it) }
}

@OptIn(WorkflowUiExperimentalApi::class)
private class StanzaListLayoutRunner(view: View) : ScreenViewRunner<StanzaListScreen> {
private class StanzaListLayoutUpdater(view: View) : ScreenViewUpdater<StanzaListScreen> {
private val toolbar = view.findViewById<Toolbar>(R.id.list_toolbar)
private val recyclerView = view.findViewById<RecyclerView>(R.id.list_body)
.apply { layoutManager = LinearLayoutManager(context) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.squareup.sample.container.poetry.R
import com.squareup.workflow1.ui.AndroidScreen
import com.squareup.workflow1.ui.Compatible
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewRunner
import com.squareup.workflow1.ui.ScreenViewUpdater
import com.squareup.workflow1.ui.ViewEnvironment
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.backPressedHandler
Expand All @@ -32,14 +32,13 @@ data class StanzaScreen(
) : AndroidScreen<StanzaScreen>, Compatible {
override val compatibilityKey = "$title: $stanzaNumber"

override val viewFactory: ScreenViewFactory<StanzaScreen> = ScreenViewRunner.bind(
R.layout.stanza_layout,
::StanzaLayoutRunner
)
override val viewFactory: ScreenViewFactory<StanzaScreen> = ScreenViewFactory.ofLayout(
R.layout.stanza_layout
) { it: View -> StanzaLayoutUpdater(it) }
}

@OptIn(WorkflowUiExperimentalApi::class)
private class StanzaLayoutRunner(private val view: View) : ScreenViewRunner<StanzaScreen> {
private class StanzaLayoutUpdater(private val view: View) : ScreenViewUpdater<StanzaScreen> {
private val tabSize = TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_SP, 24f, view.resources.displayMetrics)
.toInt()
Expand Down Expand Up @@ -114,8 +113,7 @@ private class StanzaLayoutRunner(private val view: View) : ScreenViewRunner<Stan
setText(spans, SPANNABLE)
}

companion object : ScreenViewFactory<StanzaScreen> by ScreenViewRunner.bind(
R.layout.stanza_layout,
::StanzaLayoutRunner
companion object : ScreenViewFactory<StanzaScreen> by ScreenViewFactory.ofLayout(R.layout.stanza_layout,
{ it: View -> StanzaLayoutUpdater(it) }
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import android.graphics.Rect
import android.view.View
import androidx.core.content.ContextCompat
import com.squareup.sample.dungeon.board.Board
import com.squareup.workflow1.ui.ManualScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewFactory
import com.squareup.workflow1.ui.ScreenViewHolder
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.bindShowRendering
import kotlin.math.abs
import kotlin.math.min

Expand Down Expand Up @@ -83,10 +82,15 @@ class BoardView(context: Context) : View(context) {
}

@OptIn(WorkflowUiExperimentalApi::class)
companion object : ScreenViewFactory<Board> by ManualScreenViewFactory(
type = Board::class,
companion object : ScreenViewFactory<Board> by ScreenViewFactory.of(
viewConstructor = { initialRendering, initialEnv, contextForNewView, _ ->
BoardView(contextForNewView)
.apply { bindShowRendering(initialRendering, initialEnv) { r, _ -> update(r) } }
.let { view ->
ScreenViewHolder(
initialRendering,
initialEnv,
view
) { r, _ -> view.update(r) }
}
})
}
Loading