Skip to content

Commit

Permalink
Add VAlign and HAlign for dialog box position
Browse files Browse the repository at this point in the history
  • Loading branch information
jobe-m committed Aug 9, 2024
1 parent 74cafc3 commit f703607
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import kotlinx.serialization.*
/**
* Component which is used to implement a publish-subscribe event/message passing system.
* It is used by [EventSystem].
*
* Hint: Not yet used in KorGE-Fleks.
*/
@Serializable @SerialName("Info")
data class EventComponent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package korlibs.korge.fleks.entity.config

import AppConfig
import com.github.quillraven.fleks.*
import korlibs.image.text.*
import korlibs.korge.fleks.components.*
Expand All @@ -22,10 +23,10 @@ data class DialogBoxConfig(
private val duration: Float,

// Position and size
private val x: Float = 0f,
private val y: Float = 0f,
@Serializable(with = HAlignAsString::class) private val positionHAlign: HorizontalAlign,
@Serializable(with = VAlignAsString::class) private val positionVAlign: VerticalAlign,
private val width: Float,
private val height: Float,
private val numberOfLines: Int, // TODO get this from placed text

// Color and alpha channel of text and graphics
private val tint: RgbaComponent.Rgb = RgbaComponent.Rgb.WHITE,
Expand All @@ -43,14 +44,40 @@ data class DialogBoxConfig(
private val text: String,
private val textFontName: String,
private val textRangeEnd: Int = 0, // initial value for drawing the text into the dialog
@Serializable(with = HorizontalAlignAsDouble::class) private val horizontalAlign: HorizontalAlign = HorizontalAlign.LEFT,
@Serializable(with = VerticalAlignAsDouble::class) private val verticalAlign: VerticalAlign = VerticalAlign.TOP,
@Serializable(with = HAlignAsString::class) private val textHAlign: HorizontalAlign = HorizontalAlign.LEFT,
@Serializable(with = VAlignAsString::class) private val textVAlign: VerticalAlign = VerticalAlign.TOP,
) : EntityConfig {

enum class AvatarPosition { LEFT_TOP, RIGHT_TOP /*, LEFT_BOTTOM, RIGHT_BOTTOM*/ }

private val textSize = 13f // TODO get this from used font (lineHeight)
private val height: Float = textSize * numberOfLines + 2

private fun hAlign(h: HorizontalAlign, width: Float) : Float {
if (h.ratio * AppConfig.TARGET_VIRTUAL_WIDTH < 10) return 10f
if (h.ratio * AppConfig.TARGET_VIRTUAL_WIDTH > AppConfig.TARGET_VIRTUAL_WIDTH - 10) return AppConfig.TARGET_VIRTUAL_WIDTH - width - 10
return (h.ratio * AppConfig.TARGET_VIRTUAL_WIDTH).toFloat()
}

private fun vAlign(v: VerticalAlign, height: Float) : Float {
if (v.ratio * AppConfig.TARGET_VIRTUAL_HEIGHT < 34) return 34f
if (v.ratio * AppConfig.TARGET_VIRTUAL_HEIGHT > AppConfig.TARGET_VIRTUAL_HEIGHT - 10) return AppConfig.TARGET_VIRTUAL_HEIGHT - height - 10
return (v.ratio * AppConfig.TARGET_VIRTUAL_HEIGHT).toFloat()
}

override fun World.entityConfigure(entity: Entity) : Entity {
val avatarLeftInitialX = x + 10f

val textBoxWidth = width + 14 // 190 <- 176
val textBoxHeight = height + 8 // 49 <- 41
val textBoxX = hAlign(positionHAlign, textBoxWidth)
val textBoxY = vAlign(positionVAlign, textBoxHeight)
val textFieldX = textBoxX + 7
val textFieldY = textBoxY + 4
val textFieldWidth = width
val textFieldHeight = height


val avatarLeftInitialX = textBoxX + 10f
val avatarRightInitialX = AppConfig.TARGET_VIRTUAL_WIDTH - 20f - 38f
val avatarInitialX = when (avatarPosition) {
AvatarPosition.LEFT_TOP -> avatarLeftInitialX - avatarMoveX
Expand All @@ -62,36 +89,41 @@ data class DialogBoxConfig(
}
// Avatar image entity
val avatar = entity {
it += PositionComponent(x = avatarInitialX, y = y - 24f)
it += PositionComponent(x = avatarInitialX, y = textBoxY - 24f)
it += SpriteComponent(name = avatarName)
it += RgbaComponent().apply {
tint = this@DialogBoxConfig.tint
alpha = this@DialogBoxConfig.alpha
}
it += RenderLayerTag.FG_DIALOGS
it += LayerComponent(layerIndex = 102)
// it += RenderLayerTag.DEBUG
}
val textField = entity {
it += PositionComponent(x = this@DialogBoxConfig.x, y = this@DialogBoxConfig.y)
// TODO replace SpriteComponent by NinePatchComponent (decide if we want a ninePatch property in SpriteComponent or a new component...)
it += SpriteComponent(name = textFieldName)
val textBox = entity {
it += PositionComponent(x = textBoxX, y = textBoxY)
it += NinePatchComponent(
name = textFieldName,
width = textBoxWidth,
height = textBoxHeight
)
it += RgbaComponent().apply {
tint = this@DialogBoxConfig.tint
alpha = this@DialogBoxConfig.alpha
}
it += RenderLayerTag.FG_DIALOGS
it += LayerComponent(layerIndex = 100)
// it += RenderLayerTag.DEBUG
}
val text = entity {
it += PositionComponent(x = this@DialogBoxConfig.x + 7f, y = this@DialogBoxConfig.y + 4f)
val textField = entity {
it += PositionComponent(x = textFieldX, y = textFieldY)
it += TextFieldComponent(
text = this@DialogBoxConfig.text,
fontName = this@DialogBoxConfig.textFontName,
textRangeEnd = this@DialogBoxConfig.textRangeEnd,
width = this@DialogBoxConfig.width,
height = this@DialogBoxConfig.height,
horizontalAlign = this@DialogBoxConfig.horizontalAlign,
verticalAlign = this@DialogBoxConfig.verticalAlign
text = text,
fontName = textFontName,
textRangeEnd = textRangeEnd,
width = textFieldWidth,
height = textFieldHeight,
horizontalAlign = textHAlign,
verticalAlign = textVAlign
)
it += LayerComponent(layerIndex = 101)
it += RgbaComponent().apply {
Expand All @@ -109,25 +141,25 @@ data class DialogBoxConfig(
// Fade in of Dialog with avatar
TweenRgba(entity = avatar, alpha = 1f, duration = 0.5f, easing = Easing.EASE_OUT_QUAD),
TweenPosition(entity = avatar, x = avatarTweenX, duration = 0.5f, easing = Easing.EASE_OUT_QUAD),
TweenRgba(entity = textField, alpha = 1f, delay = 0.3f, duration = 0.3f, easing = Easing.EASE_OUT_QUAD),
TweenRgba(entity = textBox, alpha = 1f, delay = 0.3f, duration = 0.3f, easing = Easing.EASE_OUT_QUAD),
// Type write text into the dialog
TweenTextField(entity = text, textRangeEnd = this@DialogBoxConfig.text.length, delay = 0.3f + 0.8f, duration = this@DialogBoxConfig.text.length * 0.07f)
TweenTextField(entity = textField, textRangeEnd = text.length, delay = 0.3f + 0.8f, duration = text.length * 0.07f)
)
),
Wait(duration = this@DialogBoxConfig.duration),
Wait(duration = duration),
ParallelTweens(
duration = 1f,
tweens = listOf(
// Fade out of Dialog with avatar
TweenRgba(entity = avatar, alpha = 0f, duration = 0.5f, easing = Easing.EASE_IN_QUAD),
TweenPosition(entity = avatar, x = avatarInitialX, duration = 0.5f, easing = Easing.EASE_IN_QUAD),
TweenRgba(entity = textField, alpha = 0f, duration = 0.3f, easing = Easing.EASE_IN_QUAD),
TweenRgba(entity = text, alpha = 0f, duration = 0.3f, easing = Easing.EASE_IN_QUAD)
TweenRgba(entity = textBox, alpha = 0f, duration = 0.3f, easing = Easing.EASE_IN_QUAD),
TweenRgba(entity = textField, alpha = 0f, duration = 0.3f, easing = Easing.EASE_IN_QUAD)
)
),
DeleteEntity(entity = avatar),
DeleteEntity(entity = textBox),
DeleteEntity(entity = textField),
DeleteEntity(entity = text),
DeleteEntity(entity = it)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ObjectRenderSystem(
private val comparator: EntityComparator = compareEntity(world) { entA, entB -> entA[LayerComponent].layerIndex.compareTo(entB[LayerComponent].layerIndex) }
) : View() {
private val family: Family = world.family { all(layerTag, LayerComponent, PositionComponent, RgbaComponent)
.any(LayerComponent, SpriteComponent, LayeredSpriteComponent, TextFieldComponent, SpriteLayersComponent)
.any(LayerComponent, SpriteComponent, LayeredSpriteComponent, TextFieldComponent, SpriteLayersComponent, NinePatchComponent)
}
private val assetStore: AssetStore = world.inject(name = "AssetStore")

Expand Down Expand Up @@ -154,13 +154,13 @@ class ObjectRenderSystem(
val indices = TexturedVertexArray.quadIndices(numQuads)
val tva = TexturedVertexArray(numQuads * 4, indices)
var index = 0
val viewBounds = RectangleInt(0, 0, (width).toInt(), (height).toInt())
ninePatch.info.computeScale(viewBounds) { segment, x, y, width, height ->
val viewBounds = RectangleInt(x.toInt(), y.toInt(), width.toInt(), height.toInt())
ninePatch.info.computeScale(viewBounds) { segment, xx, yy, ww, hh ->
val bmpSlice = ninePatch.getSegmentBmpSlice(segment)
tva.quad(index++ * 4,
x.toFloat(), y.toFloat(),
width.toFloat(), height.toFloat(),
Matrix.IDENTITY, bmpSlice, renderColorMul
xx.toFloat(), yy.toFloat(),
ww.toFloat(), hh.toFloat(),
Matrix.IDENTITY, bmpSlice, rgba
)
}

Expand Down

0 comments on commit f703607

Please sign in to comment.