Skip to content

Commit

Permalink
scene-graph: add pivot values to CanvasItem (#296)
Browse files Browse the repository at this point in the history
* graph: add pivotX and pivotY to CanvasItem

graph: add originX and originY to Control to use for pivot render calculations

graph: rework drawing on many Controls to respect the pivot / origin

* graph: update PaddedContainer and PanelContainer to respect pivot when fitting children

* graph: update TextureProgress to draw respecting the pivot

* graph: update NinePatchRect and CanvasLayerContainer to respect the pivot and origin

* examples: revert hello scene graph back to original
  • Loading branch information
LeHaine authored Jan 11, 2025
1 parent eb6213c commit 6a58f13
Show file tree
Hide file tree
Showing 22 changed files with 461 additions and 307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.littlekt.graphics.HAlign
import com.littlekt.graphics.VAlign
import com.littlekt.graphics.webgpu.*
import com.littlekt.input.Key
import com.littlekt.math.geom.Angle
import com.littlekt.math.geom.degrees
import com.littlekt.math.geom.radians
import com.littlekt.util.viewport.ExtendViewport
Expand All @@ -39,7 +38,7 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
TextureUsage.RENDER_ATTACHMENT,
preferredFormat,
PresentMode.FIFO,
surfaceCapabilities.alphaModes[0]
surfaceCapabilities.alphaModes[0],
)

val graph =
Expand All @@ -56,7 +55,7 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
minHeight = 100f
column {
repeat(10) {
label { text = "hi: this is rreally lognadsfda ad$it" }
label { text = "hi: this is rreallylognadsfda ad$it" }
}
}
}
Expand All @@ -76,25 +75,37 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
globalY += 1f
}
}
onRender += { batch, camera, shapeRenderer ->
batch.draw(icon, globalX, globalY, rotation = globalRotation)
onRender += { batch, _, _ ->
val originX = icon.width * pivotX
val originY = icon.height * pivotY
batch.draw(
texture = icon,
x = globalX - originX,
y = globalY - originY,
originX = originX,
originY = originY,
rotation = globalRotation,
)
}
camera2d { active = true }
}

var rotation = Angle.ZERO
node2d {
x = 100f
y = 20f
onRender += { batch, camera, shapeRenderer ->
onRender += { batch, _, _ ->
rotation += 0.01.radians
val originX = icon.width * pivotX
val originY = icon.height * pivotY
batch.draw(
icon,
globalX,
globalY,
texture = icon,
x = globalX - originX,
y = globalY - originY,
originX = originX,
originY = originY,
scaleX = 2f,
scaleY = 2f,
rotation = rotation
rotation = globalRotation,
)
}
}
Expand Down Expand Up @@ -132,7 +143,7 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
TextureUsage.RENDER_ATTACHMENT,
preferredFormat,
PresentMode.FIFO,
surfaceCapabilities.alphaModes[0]
surfaceCapabilities.alphaModes[0],
)
}

Expand Down Expand Up @@ -169,10 +180,10 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
storeOp = StoreOp.STORE,
clearColor =
if (preferredFormat.srgb) Color.DARK_GRAY.toLinear()
else Color.DARK_GRAY
else Color.DARK_GRAY,
)
),
label = "Init render pass"
label = "Init render pass",
)
graph.update(dt)
graph.render(commandEncoder, renderPassDescriptor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package com.littlekt.graph.node
import com.littlekt.graph.SceneGraph
import com.littlekt.graph.node.render.Material
import com.littlekt.graph.node.resource.InputEvent
import com.littlekt.graph.util.*
import com.littlekt.graph.util.Signal
import com.littlekt.graph.util.TripleSignal
import com.littlekt.graph.util.signal
import com.littlekt.graph.util.signal3v
import com.littlekt.graphics.Camera
import com.littlekt.graphics.g2d.Batch
import com.littlekt.graphics.g2d.shape.ShapeRenderer
Expand All @@ -24,6 +27,7 @@ abstract class CanvasItem : Node() {
const val SCALE_DIRTY = 2
const val ROTATION_DIRTY = 3
const val CLEAN = 0
const val PIVOT_DIRTY = 5

private val tempVec = MutableVec2f()
}
Expand Down Expand Up @@ -372,6 +376,28 @@ abstract class CanvasItem : Node() {
return _globalToLocalTransform
}

/** A point between 0f to 1f. */
var pivotX: Float = 0f
set(value) {
if (value == field) return
require(value in 0f..1f) { "Value must be between 0f and 1f!" }
field = value
if (insideTree) {
dirty(PIVOT_DIRTY)
}
}

/** A point between 0f to 1f. */
var pivotY: Float = 0f
set(value) {
if (value == field) return
require(value in 0f..1f) { "Value must be between 0f and 1f!" }
field = value
if (insideTree) {
dirty(PIVOT_DIRTY)
}
}

override val membersAndPropertiesString: String
get() =
"${super.membersAndPropertiesString}, visible=$visible, globalPosition=$globalPosition, position=$position, globalRotation=$globalRotation, rotation=$rotation, globalScale=$globalScale, scale=$scale"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ interface Drawable {
batch: Batch,
x: Float,
y: Float,
originX: Float,
originY: Float,
width: Float,
height: Float,
scaleX: Float = 1f,
scaleY: Float = 1f,
rotation: Angle = Angle.ZERO,
color: Color = tint
color: Color = tint,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ object EmptyDrawable : Drawable {
batch: Batch,
x: Float,
y: Float,
originX: Float,
originY: Float,
width: Float,
height: Float,
scaleX: Float,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,27 @@ class NinePatchDrawable(val ninePatch: NinePatch) : Drawable {
batch: Batch,
x: Float,
y: Float,
originX: Float,
originY: Float,
width: Float,
height: Float,
scaleX: Float,
scaleY: Float,
rotation: Angle,
color: Color
color: Color,
) {
ninePatch.draw(batch, x, y, width, height, 0f, 0f, scaleX, scaleY, rotation, color)
ninePatch.draw(
batch = batch,
x = x,
y = y,
originX = originX,
originY = originY,
width = width,
height = height,
scaleX = scaleX,
scaleY = scaleY,
rotation = rotation,
color = color,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.littlekt.graph.node.resource

import com.littlekt.graphics.*
import com.littlekt.graphics.Color
import com.littlekt.graphics.Texture
import com.littlekt.graphics.g2d.Batch
import com.littlekt.graphics.g2d.TextureSlice
import com.littlekt.graphics.slice
import com.littlekt.math.geom.Angle

/**
Expand All @@ -29,23 +31,27 @@ class TextureSliceDrawable(val slice: TextureSlice) : Drawable {
batch: Batch,
x: Float,
y: Float,
originX: Float,
originY: Float,
width: Float,
height: Float,
scaleX: Float,
scaleY: Float,
rotation: Angle,
color: Color
color: Color,
) {
batch.draw(
slice,
x,
y,
slice = slice,
x = x,
y = y,
originX = originX,
originY = originY,
width = width,
height = height,
scaleX = scaleX,
scaleY = scaleY,
rotation = rotation,
color = color
color = color,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ abstract class BoxContainer : Container() {
MinSizeCache(
minSize = minSize,
willStretch = willStretch,
finalSize = minSize
finalSize = minSize,
)
}
childrenCount++
Expand Down Expand Up @@ -229,7 +229,7 @@ abstract class BoxContainer : Container() {
tHeight = height
}

fitChild(child, tx, ty, tWidth, tHeight)
fitChild(child, tx - originX, ty - originY, tWidth, tHeight)
ofs = to
idx++
}
Expand All @@ -240,6 +240,6 @@ abstract class BoxContainer : Container() {
private data class MinSizeCache(
var minSize: Int = 0,
var willStretch: Boolean = false,
var finalSize: Int = 0
var finalSize: Int = 0,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,29 +202,33 @@ open class Button : BaseButton() {
}

drawable.draw(
batch,
globalX,
globalY,
batch = batch,
x = globalX - originX,
y = globalY - originY,
originX = originX,
originY = originY,
width = width,
height = height,
scaleX = globalScaleX,
scaleY = globalScaleY,
rotation = rotation,
color = drawable.tint
rotation = globalRotation,
color = drawable.tint,
)

if (hasFocus) {
val focusDrawable = getThemeDrawable(themeVars.focus)
focusDrawable.draw(
batch,
globalX,
globalY,
batch = batch,
x = globalX - originX,
y = globalY - originY,
originX = originX,
originY = originY,
width = width,
height = height,
scaleX = globalScaleX,
scaleY = globalScaleY,
rotation = rotation,
color = focusDrawable.tint
rotation = globalRotation,
color = focusDrawable.tint,
)
}
cache.let {
Expand Down Expand Up @@ -271,7 +275,7 @@ open class Button : BaseButton() {
scaleY = fontScaleY,
horizontalAlign,
wrap,
ellipsis
ellipsis,
)
val textWidth: Float = max(layout.width, width)
val textHeight: Float = if (wrap || text.contains("\n")) layout.height else font.capHeight
Expand Down Expand Up @@ -303,6 +307,8 @@ open class Button : BaseButton() {
}
}
ty = ty.roundToInt().toFloat()
tx -= originX
ty -= originY

layout.setText(
font,
Expand All @@ -313,7 +319,7 @@ open class Button : BaseButton() {
scaleY = fontScaleY,
horizontalAlign,
wrap,
ellipsis
ellipsis,
)
cache.setText(layout, tx, ty, fontScaleX, fontScaleY)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,19 @@ open class CanvasLayerContainer : Container() {
fbos.forEach {
it.resizeFbo(
(width / shrink.toFloat()).toInt(),
(height / shrink.toFloat()).toInt()
(height / shrink.toFloat()).toInt(),
)
}
dirty = false
}
fbos.forEach { fbo ->
val target = fbo.target
batch.draw(
target,
globalX - margin / shrink + offsetX,
globalY - margin / shrink + offsetY,
texture = target,
x = globalX - margin / shrink + offsetX - originX,
y = globalY - margin / shrink + offsetY - originY,
originX = originX,
originY = originY,
width =
if (stretch) width + margin * 2 / shrink
else target.width.toFloat() + margin * 2 / shrink,
Expand All @@ -134,7 +136,7 @@ open class CanvasLayerContainer : Container() {
else target.height.toFloat() + margin * 2 / shrink,
scaleX = globalScaleX,
scaleY = globalScaleY,
rotation = globalRotation
rotation = globalRotation,
)
}
}
Expand Down Expand Up @@ -178,7 +180,7 @@ open class CanvasLayerContainer : Container() {
if (it is CanvasLayer) {
temp.scale(
1f / (width / it.virtualWidth) * shrink,
1f / (height / it.virtualHeight) * shrink
1f / (height / it.virtualHeight) * shrink,
)
it.propagateHit(temp.x, temp.y)
} else {
Expand Down Expand Up @@ -207,7 +209,7 @@ open class CanvasLayerContainer : Container() {
if (it is CanvasLayer) {
temp.scale(
1f / (width / it.virtualWidth) * shrink,
1f / (height / it.virtualHeight) * shrink
1f / (height / it.virtualHeight) * shrink,
)
event.canvasX = temp.x
event.canvasY = temp.y
Expand Down Expand Up @@ -239,7 +241,7 @@ open class CanvasLayerContainer : Container() {
if (it is CanvasLayer) {
temp.scale(
1f / (width / it.virtualWidth) * shrink,
1f / (height / it.virtualHeight) * shrink
1f / (height / it.virtualHeight) * shrink,
)
event.canvasX = temp.x
event.canvasY = temp.y
Expand Down
Loading

0 comments on commit 6a58f13

Please sign in to comment.