Skip to content

Commit 0dd2ace

Browse files
committed
wip: time to burn down decorator
1 parent f89881b commit 0dd2ace

File tree

5 files changed

+64
-62
lines changed

5 files changed

+64
-62
lines changed

samples/containers/android/src/main/java/com/squareup/sample/container/panel/PanelOverlayDialogFactory.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import com.squareup.workflow1.ui.container.setBounds
1717
internal object PanelOverlayDialogFactory : ModalScreenOverlayDialogFactory<PanelOverlay<*>>(
1818
type = PanelOverlay::class
1919
) {
20-
override fun buildDialogWithContentView(contentView: View): Dialog {
21-
val context = contentView.context
20+
override fun buildDialogWithContent(content: View): Dialog {
21+
val context = content.context
2222
return Dialog(context, R.style.PanelDialog).also { dialog ->
23-
dialog.setContentView(contentView)
23+
dialog.setContentView(content)
2424

2525
// Welcome to Android. Nothing workflow-related here, this is just how one
2626
// finds the window background color for the theme. I sure hope it's better in Compose.

workflow-ui/container-android/src/main/java/com/squareup/workflow1/ui/modal/ModalViewContainer.kt

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,17 @@ import android.view.ViewGroup
1212
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
1313
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
1414
import androidx.annotation.IdRes
15-
import com.squareup.workflow1.ui.asScreen
1615
import com.squareup.workflow1.ui.BuilderViewFactory
1716
import com.squareup.workflow1.ui.ViewEnvironment
1817
import com.squareup.workflow1.ui.ViewRegistry
1918
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
19+
import com.squareup.workflow1.ui.asScreen
2020
import com.squareup.workflow1.ui.backPressedHandler
2121
import com.squareup.workflow1.ui.bindShowRendering
2222
import com.squareup.workflow1.ui.buildView
2323
import com.squareup.workflow1.ui.modal.ModalViewContainer.Companion.binding
2424
import com.squareup.workflow1.ui.onBackPressedDispatcherOwnerOrNull
2525
import com.squareup.workflow1.ui.showRendering
26-
import com.squareup.workflow1.ui.start
2726
import kotlin.reflect.KClass
2827

2928
/**
@@ -65,45 +64,47 @@ public open class ModalViewContainer @JvmOverloads constructor(
6564
initialModalRendering: Any,
6665
initialViewEnvironment: ViewEnvironment
6766
): DialogRef<Any> {
68-
val view = asScreen(initialModalRendering).buildView(
69-
viewEnvironment = initialViewEnvironment,
70-
contextForNewView = this.context,
71-
container = this
72-
)
73-
.apply {
74-
start()
75-
// If the modal's root view has no backPressedHandler, add a no-op one to
76-
// ensure that the `onBackPressed` call below will not leak up to handlers
77-
// that should be blocked by this modal session.
78-
if (backPressedHandler == null) backPressedHandler = { }
79-
}
67+
val view = asScreen(initialModalRendering)
68+
.buildView(
69+
viewEnvironment = initialViewEnvironment,
70+
contextForNewView = this.context,
71+
container = this
72+
)
73+
.let { holder ->
74+
holder.start()
75+
holder.view
76+
}
77+
// If the modal's root view has no backPressedHandler, add a no-op one to
78+
// ensure that the `onBackPressed` call below will not leak up to handlers
79+
// that should be blocked by this modal session.
80+
if (view.backPressedHandler == null) view.backPressedHandler = { }
8081

8182
return buildDialogForView(view)
82-
.apply {
83-
// Dialogs are modal windows and so they block events, including back button presses
84-
// -- that's their job! But we *want* the Activity's onBackPressedDispatcher to fire
85-
// when back is pressed, so long as it doesn't look past this modal window for handlers.
86-
//
87-
// Here, we handle the ACTION_UP portion of a KEYCODE_BACK key event, and below
88-
// we make sure that the root view has a backPressedHandler that will consume the
89-
// onBackPressed call if no child of the root modal view does.
83+
.apply {
84+
// Dialogs are modal windows and so they block events, including back button presses
85+
// -- that's their job! But we *want* the Activity's onBackPressedDispatcher to fire
86+
// when back is pressed, so long as it doesn't look past this modal window for handlers.
87+
//
88+
// Here, we handle the ACTION_UP portion of a KEYCODE_BACK key event, and below
89+
// we make sure that the root view has a backPressedHandler that will consume the
90+
// onBackPressed call if no child of the root modal view does.
9091

91-
setOnKeyListener { _, keyCode, keyEvent ->
92-
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == ACTION_UP) {
93-
view.context.onBackPressedDispatcherOwnerOrNull()
94-
?.onBackPressedDispatcher
95-
?.let {
96-
if (it.hasEnabledCallbacks()) it.onBackPressed()
97-
}
98-
true
99-
} else {
100-
false
101-
}
92+
setOnKeyListener { _, keyCode, keyEvent ->
93+
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == ACTION_UP) {
94+
view.context.onBackPressedDispatcherOwnerOrNull()
95+
?.onBackPressedDispatcher
96+
?.let {
97+
if (it.hasEnabledCallbacks()) it.onBackPressed()
98+
}
99+
true
100+
} else {
101+
false
102102
}
103103
}
104-
.run {
105-
DialogRef(initialModalRendering, initialViewEnvironment, this, view)
106-
}
104+
}
105+
.run {
106+
DialogRef(initialModalRendering, initialViewEnvironment, this, view)
107+
}
107108
}
108109

109110
override fun updateDialog(dialogRef: DialogRef<Any>) {
@@ -118,14 +119,14 @@ public open class ModalViewContainer @JvmOverloads constructor(
118119
type: KClass<H>
119120
) : com.squareup.workflow1.ui.ViewFactory<H>
120121
by BuilderViewFactory(
121-
type = type,
122-
viewConstructor = { initialRendering, initialEnv, context, _ ->
123-
ModalViewContainer(context).apply {
124-
this.id = id
125-
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
126-
bindShowRendering(initialRendering, initialEnv, ::update)
127-
}
122+
type = type,
123+
viewConstructor = { initialRendering, initialEnv, context, _ ->
124+
ModalViewContainer(context).apply {
125+
this.id = id
126+
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
127+
bindShowRendering(initialRendering, initialEnv, ::update)
128128
}
129+
}
129130
)
130131

131132
public companion object {

workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/WorkflowViewStub.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,24 +238,24 @@ public class WorkflowViewStub @JvmOverloads constructor(
238238
WorkflowLifecycleOwner.get(it)?.destroyOnDetach()
239239
}
240240

241-
val newWorkflowView = screen.buildView(
241+
val newViewHolder = screen.buildView(
242242
viewEnvironment,
243243
parent.context,
244244
parent
245245
).withStarter { view, doStart ->
246246
WorkflowLifecycleOwner.installOn(view.view)
247247
doStart()
248248
}
249-
newWorkflowView.start()
249+
newViewHolder.start()
250250

251-
val newAndroidView = newWorkflowView.view
251+
val newAndroidView = newViewHolder.view
252252

253253
if (inflatedId != NO_ID) newAndroidView.id = inflatedId
254254
if (updatesVisibility) newAndroidView.visibility = visibility
255255
background?.let { newAndroidView.background = it }
256256
propagateSavedStateRegistryOwner(newAndroidView)
257257
replaceOldViewInParent(parent, newAndroidView)
258-
delegateHolder = newWorkflowView
258+
delegateHolder = newViewHolder
259259
}
260260

261261
/**

workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/ModalScreenOverlayDialogFactory.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import android.view.View
1111
import android.view.Window
1212
import android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1313
import com.squareup.workflow1.ui.R
14+
import com.squareup.workflow1.ui.ScreenViewHolder
1415
import com.squareup.workflow1.ui.ViewEnvironment
1516
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
1617
import com.squareup.workflow1.ui.backPressedHandler
@@ -35,9 +36,9 @@ public abstract class ModalScreenOverlayDialogFactory<O : ScreenOverlay<*>>(
3536

3637
/**
3738
* Called from [buildDialog]. Builds (but does not show) the [Dialog] to
38-
* display a [contentView] built for a [ScreenOverlay.content].
39+
* display a [content] view built for a [ScreenOverlay.content].
3940
*/
40-
public abstract fun buildDialogWithContentView(contentView: View): Dialog
41+
public abstract fun buildDialogWithContent(content: ScreenViewHolder<*>): Dialog
4142

4243
/**
4344
* If the [ScreenOverlay] displayed by a [dialog] created by this
@@ -61,21 +62,21 @@ public abstract class ModalScreenOverlayDialogFactory<O : ScreenOverlay<*>>(
6162
initialEnvironment: ViewEnvironment,
6263
context: Context
6364
): Dialog {
64-
val contentView = initialRendering.content.buildView(initialEnvironment, context).apply {
65+
val contentHolder = initialRendering.content.buildView(initialEnvironment, context).apply {
6566
start()
6667
// If the content view has no backPressedHandler, add a no-op one to
6768
// ensure that the `onBackPressed` call below will not leak up to handlers
6869
// that should be blocked by this modal session.
6970
if (view.backPressedHandler == null) view.backPressedHandler = { }
7071
}
7172

72-
return buildDialogWithContentView(contentView).also { dialog ->
73+
return buildDialogWithContent(contentHolder).also { dialog ->
7374
val window = requireNotNull(dialog.window) { "Dialog must be attached to a window." }
7475

7576
// There is no Dialog.getContentView method, and no reliable way to reverse
7677
// engineer one (no, android.R.id.content doesn't work). So we stick the
7778
// contentView in a tag here, where updateDialog can find it later.
78-
window.peekDecorView()?.setTag(R.id.workflow_modal_dialog_content, contentView)
79+
window.peekDecorView()?.setTag(R.id.workflow_modal_dialog_content, contentHolder)
7980
?: throw IllegalStateException("Expected decorView to have been built.")
8081

8182
val realWindowCallback = window.callback
@@ -85,15 +86,15 @@ public abstract class ModalScreenOverlayDialogFactory<O : ScreenOverlay<*>>(
8586
event.action == ACTION_UP
8687

8788
return when {
88-
isBackPress -> contentView.environment?.get(ModalScreenOverlayOnBackPressed)
89-
?.onBackPressed(contentView) == true
89+
isBackPress -> contentHolder.environment[ModalScreenOverlayOnBackPressed]
90+
.onBackPressed(contentHolder)
9091
else -> realWindowCallback.dispatchKeyEvent(event)
9192
}
9293
}
9394
}
9495

9596
window.setFlags(FLAG_NOT_TOUCH_MODAL, FLAG_NOT_TOUCH_MODAL)
96-
dialog.maintainBounds(contentView) { d, b -> updateBounds(d, Rect(b)) }
97+
dialog.maintainBounds(contentHolder.view) { d, b -> updateBounds(d, Rect(b)) }
9798
}
9899
}
99100

workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/ModalScreenOverlayOnBackPressed.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.squareup.workflow1.ui.container
22

3-
import android.view.View
3+
import com.squareup.workflow1.ui.ScreenViewHolder
44
import com.squareup.workflow1.ui.ViewEnvironmentKey
55
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
66
import com.squareup.workflow1.ui.container.ModalScreenOverlayOnBackPressed.Handler
@@ -26,11 +26,11 @@ public object ModalScreenOverlayOnBackPressed : ViewEnvironmentKey<Handler>(
2626
*
2727
* @return true if the back press event was consumed
2828
*/
29-
public fun onBackPressed(contentView: View): Boolean
29+
public fun onBackPressed(content: ScreenViewHolder<*>): Boolean
3030
}
3131

32-
override val default: Handler = Handler { view ->
33-
view.context.onBackPressedDispatcherOwnerOrNull()
32+
override val default: Handler = Handler { viewHolder ->
33+
viewHolder.view.context.onBackPressedDispatcherOwnerOrNull()
3434
?.onBackPressedDispatcher
3535
?.let {
3636
if (it.hasEnabledCallbacks()) it.onBackPressed()

0 commit comments

Comments
 (0)