mirror of
https://github.com/JakeWharton/mosaic.git
synced 2025-11-03 05:46:10 +08:00
Put nodes in charge of rendering themselves
This commit is contained in:
@ -4,10 +4,13 @@ import androidx.compose.runtime.AbstractApplier
|
|||||||
import com.facebook.yoga.YogaMeasureOutput
|
import com.facebook.yoga.YogaMeasureOutput
|
||||||
import com.facebook.yoga.YogaNode
|
import com.facebook.yoga.YogaNode
|
||||||
import com.facebook.yoga.YogaNodeFactory
|
import com.facebook.yoga.YogaNodeFactory
|
||||||
|
import com.jakewharton.crossword.TextCanvas
|
||||||
import com.jakewharton.crossword.visualCodePointCount
|
import com.jakewharton.crossword.visualCodePointCount
|
||||||
|
|
||||||
internal sealed class MosaicNode {
|
internal sealed class MosaicNode {
|
||||||
val yoga: YogaNode = YogaNodeFactory.create()
|
val yoga: YogaNode = YogaNodeFactory.create()
|
||||||
|
|
||||||
|
abstract fun render(canvas: TextCanvas)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TextNode(initialValue: String = "") : MosaicNode() {
|
internal class TextNode(initialValue: String = "") : MosaicNode() {
|
||||||
@ -26,12 +29,30 @@ internal class TextNode(initialValue: String = "") : MosaicNode() {
|
|||||||
yoga.dirty()
|
yoga.dirty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun render(canvas: TextCanvas) {
|
||||||
|
value.split('\n').forEachIndexed { index, line ->
|
||||||
|
canvas.write(index, 0, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString() = "Text($value)"
|
override fun toString() = "Text($value)"
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class BoxNode : MosaicNode() {
|
internal class BoxNode : MosaicNode() {
|
||||||
val children = mutableListOf<MosaicNode>()
|
val children = mutableListOf<MosaicNode>()
|
||||||
|
|
||||||
|
override fun render(canvas: TextCanvas) {
|
||||||
|
for (child in children) {
|
||||||
|
val childYoga = child.yoga
|
||||||
|
val left = childYoga.layoutX.toInt()
|
||||||
|
val top = childYoga.layoutY.toInt()
|
||||||
|
val right = left + childYoga.layoutWidth.toInt()
|
||||||
|
val bottom = top + childYoga.layoutHeight.toInt()
|
||||||
|
val clipped = canvas.clip(left, top, right, bottom)
|
||||||
|
child.render(clipped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString() = children.joinToString(prefix = "Box(", postfix = ")")
|
override fun toString() = children.joinToString(prefix = "Box(", postfix = ")")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,24 +7,3 @@ internal fun MosaicNode.renderToString(): String {
|
|||||||
render(surface)
|
render(surface)
|
||||||
return surface.toString()
|
return surface.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MosaicNode.render(canvas: TextCanvas) {
|
|
||||||
when (this) {
|
|
||||||
is TextNode -> {
|
|
||||||
value.split('\n').forEachIndexed { index, line ->
|
|
||||||
canvas.write(index, 0, line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is BoxNode -> {
|
|
||||||
for (child in children) {
|
|
||||||
val childYoga = child.yoga
|
|
||||||
val left = childYoga.layoutX.toInt()
|
|
||||||
val top = childYoga.layoutY.toInt()
|
|
||||||
val right = left + childYoga.layoutWidth.toInt()
|
|
||||||
val bottom = top + childYoga.layoutHeight.toInt()
|
|
||||||
val clipped = canvas.clip(left, top, right, bottom)
|
|
||||||
child.render(clipped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user