mirror of
https://github.com/JakeWharton/mosaic.git
synced 2025-11-03 05:46:10 +08:00
Introduce a node layer type (#140)
This owns measurement, placement, and drawing, and will be stackable in the future.
This commit is contained in:
@ -36,59 +36,71 @@ internal fun interface DebugPolicy {
|
|||||||
fun MosaicNode.renderDebug(): String
|
fun MosaicNode.renderDebug(): String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal abstract class MosaicNodeLayer : Placeable(), Measurable {
|
||||||
|
abstract val x: Int
|
||||||
|
abstract val y: Int
|
||||||
|
abstract fun drawTo(canvas: TextCanvas)
|
||||||
|
}
|
||||||
|
|
||||||
internal class MosaicNode(
|
internal class MosaicNode(
|
||||||
var measurePolicy: MeasurePolicy,
|
var measurePolicy: MeasurePolicy,
|
||||||
var drawPolicy: DrawPolicy?,
|
var drawPolicy: DrawPolicy?,
|
||||||
var staticDrawPolicy: StaticDrawPolicy,
|
var staticDrawPolicy: StaticDrawPolicy,
|
||||||
var debugPolicy: DebugPolicy,
|
var debugPolicy: DebugPolicy,
|
||||||
) : Placeable(), Measurable {
|
) : Measurable {
|
||||||
val children = mutableListOf<MosaicNode>()
|
val children = mutableListOf<MosaicNode>()
|
||||||
private var measureResult: MeasureResult = NotMeasured
|
|
||||||
|
|
||||||
override val width get() = measureResult.width
|
private val layer: MosaicNodeLayer = object : MosaicNodeLayer() {
|
||||||
override val height get() = measureResult.height
|
private var measureResult: MeasureResult = NotMeasured
|
||||||
|
|
||||||
/** Measure this node (and any children) and update [width] and [height]. */
|
override val width get() = measureResult.width
|
||||||
override fun measure(): Placeable = apply {
|
override val height get() = measureResult.height
|
||||||
measureResult = measurePolicy.run { MeasureScope.run { measure(children) } }
|
|
||||||
}
|
|
||||||
|
|
||||||
// These two values are set by a call to `placeAt`.
|
override fun measure() = apply {
|
||||||
/** Pixels right relative to parent at which this node will draw. */
|
measureResult = measurePolicy.run { MeasureScope.run { measure(children) } }
|
||||||
var x = 0
|
}
|
||||||
private set
|
|
||||||
/** Pixels down relative to parent at which this node will draw. */
|
|
||||||
var y = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
override fun placeAt(x: Int, y: Int) {
|
override var x = 0
|
||||||
this.x = x
|
private set
|
||||||
this.y = y
|
override var y = 0
|
||||||
measureResult.placeChildren()
|
private set
|
||||||
}
|
|
||||||
|
|
||||||
private fun drawTo(canvas: TextCanvas) {
|
override fun placeAt(x: Int, y: Int) {
|
||||||
val drawPolicy = drawPolicy
|
this.x = x
|
||||||
if (drawPolicy != null) {
|
this.y = y
|
||||||
drawPolicy.performDraw(canvas)
|
measureResult.placeChildren()
|
||||||
} else {
|
}
|
||||||
for (child in children) {
|
|
||||||
if (child.width != 0 && child.height != 0) {
|
override fun drawTo(canvas: TextCanvas) {
|
||||||
val left = child.x
|
val drawPolicy = drawPolicy
|
||||||
val top = child.y
|
if (drawPolicy != null) {
|
||||||
val right = left + child.width - 1
|
drawPolicy.performDraw(canvas)
|
||||||
val bottom = top + child.height - 1
|
} else {
|
||||||
child.drawTo(canvas[top..bottom, left..right])
|
for (child in children) {
|
||||||
|
if (child.width != 0 && child.height != 0) {
|
||||||
|
val left = child.x
|
||||||
|
val top = child.y
|
||||||
|
val right = left + child.width - 1
|
||||||
|
val bottom = top + child.height - 1
|
||||||
|
child.layer.drawTo(canvas[top..bottom, left..right])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun measure(): Placeable = layer.measure()
|
||||||
|
|
||||||
|
val width: Int get() = layer.width
|
||||||
|
val height: Int get() = layer.height
|
||||||
|
val x: Int get() = layer.x
|
||||||
|
val y: Int get() = layer.y
|
||||||
|
|
||||||
fun draw(): TextCanvas {
|
fun draw(): TextCanvas {
|
||||||
val placeable = measure()
|
val placeable = measure()
|
||||||
placeable.place(0, 0)
|
placeable.place(0, 0)
|
||||||
val surface = TextSurface(placeable.width, placeable.height)
|
val surface = TextSurface(placeable.width, placeable.height)
|
||||||
drawTo(surface)
|
layer.drawTo(surface)
|
||||||
return surface
|
return surface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user