Skip to content

Commit

Permalink
Migrate View Row+Column away from subtype (#2442)
Browse files Browse the repository at this point in the history
When widgets switch to abstract classes, this will no longer be allowed.
  • Loading branch information
JakeWharton authored Nov 12, 2024
1 parent dfa2914 commit 21e6302
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ import androidx.core.widget.NestedScrollView
import androidx.core.widget.NestedScrollView.OnScrollChangeListener as OnScrollChangeListenerCompat
import app.cash.redwood.Modifier
import app.cash.redwood.layout.api.Constraint
import app.cash.redwood.layout.api.CrossAxisAlignment
import app.cash.redwood.layout.api.MainAxisAlignment
import app.cash.redwood.layout.api.Overflow
import app.cash.redwood.layout.widget.Column
import app.cash.redwood.layout.widget.Row
import app.cash.redwood.ui.Density
import app.cash.redwood.ui.Margin
import app.cash.redwood.ui.Px
import app.cash.redwood.widget.ChangeListener
import app.cash.redwood.widget.ViewGroupChildren
Expand All @@ -37,6 +42,46 @@ import app.cash.redwood.yoga.FlexDirection
import app.cash.redwood.yoga.Node
import app.cash.redwood.yoga.isHorizontal

internal class ViewColumn(context: Context) :
Column<View>,
ChangeListener {
private val delegate = ViewFlexContainer(context, FlexDirection.Column)

override val value get() = delegate.value
override var modifier by delegate::modifier

override val children get() = delegate.children

override fun width(width: Constraint) = delegate.width(width)
override fun height(height: Constraint) = delegate.height(height)
override fun margin(margin: Margin) = delegate.margin(margin)
override fun overflow(overflow: Overflow) = delegate.overflow(overflow)
override fun horizontalAlignment(horizontalAlignment: CrossAxisAlignment) = delegate.crossAxisAlignment(horizontalAlignment)
override fun verticalAlignment(verticalAlignment: MainAxisAlignment) = delegate.mainAxisAlignment(verticalAlignment)
override fun onScroll(onScroll: ((Px) -> Unit)?) = delegate.onScroll(onScroll)
override fun onEndChanges() = delegate.onEndChanges()
}

internal class ViewRow(context: Context) :
Row<View>,
ChangeListener {
private val delegate = ViewFlexContainer(context, FlexDirection.Row)

override val value get() = delegate.value
override var modifier by delegate::modifier

override val children get() = delegate.children

override fun width(width: Constraint) = delegate.width(width)
override fun height(height: Constraint) = delegate.height(height)
override fun margin(margin: Margin) = delegate.margin(margin)
override fun overflow(overflow: Overflow) = delegate.overflow(overflow)
override fun horizontalAlignment(horizontalAlignment: MainAxisAlignment) = delegate.mainAxisAlignment(horizontalAlignment)
override fun verticalAlignment(verticalAlignment: CrossAxisAlignment) = delegate.crossAxisAlignment(verticalAlignment)
override fun onScroll(onScroll: ((Px) -> Unit)?) = delegate.onScroll(onScroll)
override fun onEndChanges() = delegate.onEndChanges()
}

internal class ViewFlexContainer(
private val context: Context,
private val direction: FlexDirection,
Expand Down Expand Up @@ -73,7 +118,7 @@ internal class ViewFlexContainer(
},
)

private var onScroll: ((Px) -> Unit)? = null
internal var onScroll: ((Px) -> Unit)? = null

override var modifier: Modifier = Modifier

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@ import app.cash.redwood.layout.widget.Column
import app.cash.redwood.layout.widget.RedwoodLayoutWidgetFactory
import app.cash.redwood.layout.widget.Row
import app.cash.redwood.layout.widget.Spacer
import app.cash.redwood.yoga.FlexDirection

public class ViewRedwoodLayoutWidgetFactory(
private val context: Context,
) : RedwoodLayoutWidgetFactory<View> {
override fun Box(): Box<View> = ViewBox(context)

override fun Column(): Column<View> = ViewFlexContainer(context, FlexDirection.Column)
override fun Column(): Column<View> = ViewColumn(context)

override fun Row(): Row<View> = ViewFlexContainer(context, FlexDirection.Row)
override fun Row(): Row<View> = ViewRow(context)

override fun Spacer(): Spacer<View> = ViewSpacer(context)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import app.cash.paparazzi.DeviceConfig
import app.cash.paparazzi.Paparazzi
import app.cash.redwood.layout.AbstractFlexContainerTest
import app.cash.redwood.layout.TestFlexContainer
import app.cash.redwood.layout.api.Constraint
import app.cash.redwood.layout.api.Overflow
import app.cash.redwood.layout.widget.Column
import app.cash.redwood.layout.widget.Row
import app.cash.redwood.layout.widget.Spacer
import app.cash.redwood.snapshot.testing.ViewSnapshotter
import app.cash.redwood.snapshot.testing.ViewTestWidgetFactory
Expand Down Expand Up @@ -57,9 +61,15 @@ class ViewFlexContainerTest(
.apply { (this as TestFlexContainer<*>).applyDefaults() }
}

override fun row() = flexContainer(FlexDirection.Row)
override fun row(): Row<View> = ViewRow(paparazzi.context).apply {
value.setBackgroundColor(defaultBackgroundColor)
applyDefaults()
}

override fun column() = flexContainer(FlexDirection.Column)
override fun column(): Column<View> = ViewColumn(paparazzi.context).apply {
value.setBackgroundColor(defaultBackgroundColor)
applyDefaults()
}

override fun spacer(backgroundColor: Int): Spacer<View> {
return ViewSpacer(paparazzi.context)
Expand All @@ -75,16 +85,18 @@ class ViewFlexContainerTest(
) : TestFlexContainer<View>,
YogaFlexContainer<View> by delegate,
ChangeListener by delegate {
private var onScroll: ((Px) -> Unit)? = null
override val value: View get() = delegate.value
override var modifier by delegate::modifier

override val children: ViewGroupChildren = delegate.children

override fun onScroll(onScroll: ((Px) -> Unit)?) {
this.onScroll = onScroll
}
override fun width(width: Constraint) = delegate.width(width)
override fun height(height: Constraint) = delegate.height(height)
override fun overflow(overflow: Overflow) = delegate.overflow(overflow)
override fun onScroll(onScroll: ((Px) -> Unit)?) = delegate.onScroll(onScroll)

override fun scroll(offset: Px) {
onScroll?.invoke(offset)
delegate.onScroll?.invoke(offset)
}
}
}

0 comments on commit 21e6302

Please sign in to comment.