Skip to content

Commit eed7a6a

Browse files
committed
wip: Introduces ScreenOverlay and ModalScreenOverlayDialogFactory
`ScreenOverlay` marks an `Overlay` with a `Screen` defining its content. `ModalScreenOverlayDialogFactory` can show a `ScreenOverlay` as an `android.app.Dialog`, taking care of updating the content view and managing the Back button. It's the much simpler replacement for `ModalViewContainer`. Also introduces two new `ViewEnvironment` values: - `ModalArea`, which allows dialogs to restrict themselves to a subset of the screen - `CoveredByModal`, used to disable touch and keyboard events reliably Updates the Tic Tac Toe sample to use the new hotness. I think the diff of the sample code really highlights how much the new marker interfaces improve our composition story. That said, the `ScrimScreen` bit in the sample is a little rough. In the old code we magically swizzled the scrim into place automatically, and I think in prod I would still do the same, but the sample is complex enough already. For the record, it would be easy and clean to make panel-savvy alternative to `BodyAndModalScreen` -- maybe `BodyAndPanelsScreen` -- that uses a `DecorativeScreenViewFactory` to put the `ScrimScreen` in place and then delegates to a `BodyAndModalScreen` to do the real work. Fixes #259, #138, #99, #204, #314
1 parent 45ece5a commit eed7a6a

File tree

30 files changed

+742
-384
lines changed

30 files changed

+742
-384
lines changed
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package com.squareup.sample.container
22

33
import com.squareup.sample.container.overviewdetail.OverviewDetailContainer
4-
import com.squareup.sample.container.panel.PanelContainer
5-
import com.squareup.sample.container.panel.ScrimContainer
6-
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
4+
import com.squareup.sample.container.panel.PanelOverlayDialogFactory
75
import com.squareup.workflow1.ui.ViewRegistry
6+
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
87

98
@OptIn(WorkflowUiExperimentalApi::class)
109
val SampleContainers = ViewRegistry(
11-
BackButtonViewFactory, OverviewDetailContainer, PanelContainer, ScrimContainer
10+
BackButtonViewFactory, OverviewDetailContainer, PanelOverlayDialogFactory, ScrimContainer
1211
)
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
package com.squareup.sample.container.panel
1+
package com.squareup.sample.container
22

33
import android.animation.ValueAnimator
44
import android.content.Context
55
import android.util.AttributeSet
66
import android.view.View
77
import android.view.ViewGroup
88
import androidx.core.content.ContextCompat
9-
import com.squareup.sample.container.R
9+
import com.squareup.sample.container.panel.ScrimScreen
1010
import com.squareup.workflow1.ui.ManualScreenViewFactory
1111
import com.squareup.workflow1.ui.ScreenViewFactory
1212
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
@@ -17,9 +17,9 @@ import com.squareup.workflow1.ui.bindShowRendering
1717
* A view that renders only its first child, behind a smoke scrim if
1818
* [isDimmed] is true (tablets only). Other children are ignored.
1919
*
20-
* Able to [render][com.squareup.workflow1.ui.showRendering] [ScrimContainerScreen].
20+
* Able to [render][com.squareup.workflow1.ui.showRendering] [ScrimScreen].
2121
*/
22-
class ScrimContainer @JvmOverloads constructor(
22+
internal class ScrimContainer @JvmOverloads constructor(
2323
context: Context,
2424
attributeSet: AttributeSet? = null,
2525
defStyle: Int = 0,
@@ -91,21 +91,21 @@ class ScrimContainer @JvmOverloads constructor(
9191
}
9292

9393
@OptIn(WorkflowUiExperimentalApi::class)
94-
companion object : ScreenViewFactory<ScrimContainerScreen<*>> by ManualScreenViewFactory(
95-
type = ScrimContainerScreen::class,
94+
companion object : ScreenViewFactory<ScrimScreen<*>> by ManualScreenViewFactory(
95+
type = ScrimScreen::class,
9696
viewConstructor = { initialRendering, initialViewEnvironment, contextForNewView, _ ->
9797
val stub = WorkflowViewStub(contextForNewView)
9898

9999
ScrimContainer(contextForNewView)
100-
.apply {
101-
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
102-
addView(stub)
100+
.also { view ->
101+
view.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
102+
view.addView(stub)
103103

104-
bindShowRendering(
105-
initialRendering, initialViewEnvironment
104+
view.bindShowRendering(
105+
initialRendering, initialViewEnvironment
106106
) { rendering, environment ->
107107
stub.show(rendering.wrapped, environment)
108-
isDimmed = rendering.dimmed
108+
view.isDimmed = rendering.dimmed
109109
}
110110
}
111111
}
Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
package com.squareup.sample.container.panel
22

33
import android.content.Context
4-
import android.content.Context.WINDOW_SERVICE
5-
import android.view.Display
6-
import android.view.WindowManager
74
import com.squareup.sample.container.R
85

9-
val Context.isPortrait: Boolean get() = resources.getBoolean(R.bool.is_portrait)
10-
116
val Context.isTablet: Boolean get() = resources.getBoolean(R.bool.is_tablet)
12-
13-
val Context.windowManager: WindowManager get() = getSystemService(WINDOW_SERVICE) as WindowManager
14-
15-
@Suppress("DEPRECATION")
16-
val Context.defaultDisplay: Display get() = windowManager.defaultDisplay

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

Lines changed: 0 additions & 72 deletions
This file was deleted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.squareup.sample.container.panel
2+
3+
import android.app.Dialog
4+
import android.graphics.drawable.ColorDrawable
5+
import android.util.TypedValue
6+
import android.view.View
7+
import com.squareup.sample.container.R
8+
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
9+
import com.squareup.workflow1.ui.container.Bounds
10+
import com.squareup.workflow1.ui.container.ModalScreenOverlayDialogFactory
11+
import com.squareup.workflow1.ui.container.maintainBounds
12+
import com.squareup.workflow1.ui.container.setBounds
13+
14+
@OptIn(WorkflowUiExperimentalApi::class)
15+
internal object PanelOverlayDialogFactory : ModalScreenOverlayDialogFactory<PanelOverlay<*>>(
16+
type = PanelOverlay::class
17+
) {
18+
override fun buildDialogWithContentView(contentView: View): Dialog {
19+
val context = contentView.context
20+
return Dialog(context, R.style.PanelDialog).also { dialog ->
21+
dialog.setContentView(contentView)
22+
23+
val typedValue = TypedValue()
24+
context.theme.resolveAttribute(android.R.attr.windowBackground, typedValue, true)
25+
if (typedValue.type in TypedValue.TYPE_FIRST_COLOR_INT..TypedValue.TYPE_LAST_COLOR_INT) {
26+
dialog.window!!.setBackgroundDrawable(ColorDrawable(typedValue.data))
27+
}
28+
29+
dialog.maintainBounds(contentView) { _, bounds ->
30+
val refinedBounds: Bounds = if (!context.isTablet) {
31+
// On a phone, fill the bounds entirely.
32+
bounds
33+
} else {
34+
if (bounds.height > bounds.width) {
35+
val margin = bounds.height - bounds.width
36+
val topDelta = margin / 2
37+
val bottomDelta = margin - topDelta
38+
bounds.copy(top = bounds.top + topDelta, bottom = bounds.bottom - bottomDelta)
39+
} else {
40+
val margin = bounds.width - bounds.height
41+
val leftDelta = margin / 2
42+
val rightDelta = margin - leftDelta
43+
bounds.copy(left = bounds.left + leftDelta, right = bounds.right - rightDelta)
44+
}
45+
}
46+
dialog.setBounds(refinedBounds)
47+
}
48+
}
49+
}
50+
}

samples/containers/android/src/main/res/values-land/bools.xml

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
3-
<bool name="is_portrait">true</bool>
43
<bool name="is_tablet">false</bool>
54
</resources>

samples/containers/android/src/main/res/values/ids.xml

Lines changed: 0 additions & 5 deletions
This file was deleted.

samples/containers/common/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ plugins {
55

66
dependencies {
77
implementation(project(":workflow-ui:container-common"))
8+
implementation(project(":workflow-ui:core-android"))
89
implementation(project(":workflow-core"))
910

1011
implementation(Dependencies.Kotlin.Stdlib.jdk6)

samples/containers/common/src/main/java/com/squareup/sample/container/panel/PanelContainerScreen.kt

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)