Skip to content

Commit

Permalink
align widget and some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Hobbyshop committed Apr 27, 2024
1 parent 92338a6 commit fc6b742
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 17 deletions.
81 changes: 81 additions & 0 deletions src/main/kotlin/com/neptuneclient/voidui/widgets/Align.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.neptuneclient.voidui.widgets

import com.neptuneclient.voidui.framework.BoxConstraints
import com.neptuneclient.voidui.framework.Offset
import com.neptuneclient.voidui.framework.Size
import com.neptuneclient.voidui.framework.Widget

/**
* A widget which aligns a child at a relative position.
* It stretches itself to the maximum size of the constraints.
*
* @param child The child which will be aligned.
* @param alignment The alignment factor.
*/
class Align(
private val child: Widget,
private val alignment: Alignment = Alignment.topLeft
) : Widget() {

override fun layout(constraints: BoxConstraints) {
child.layout(constraints)
size = Size(constraints.maxWidth, constraints.maxHeight)
}

override fun postLayoutInit(parentOffset: Offset, parent: Widget) {
super.postLayoutInit(parentOffset + alignment.align(size, child.size), parent)
offset = parentOffset
}

override fun build(): Widget {
return child
}

}

/**
* A data class to hold values about the relative alignment of a widget inside its parent.
*
* @param x The x-axis alignment.
* @param y The y-axis alignment.
*/
data class Alignment(val x: Double, val y: Double) {

companion object {
val topLeft = Alignment(-1.0, -1.0)

val topCenter = Alignment(0.0, -1.0)

val topRight = Alignment(1.0, -1.0)

val centerLeft = Alignment(-1.0, 0.0)

val center = Alignment(0.0, 0.0)

val centerRight = Alignment(1.0, 0.0)

val bottomLeft = Alignment(-1.0, 1.0)

val bottomCenter = Alignment(0.0, 1.0)

val bottomRight = Alignment(1.0, 1.0)
}

/**
* Aligns a child size within the parent's size according to [x] and [y].
*
* @param baseSize The larger size which acts as a container for the smaller size.
* @param childSize The smaller size which will be aligned.
*
* @return The aligned offset from the top left corner of the base size.
*/
fun align(baseSize: Size, childSize: Size): Offset {
// x and y values between 0 and 1
val relX = (x + 1) / 2f
val relY = (y + 1) / 2f
val size = baseSize - childSize

return Offset(size.width * relX.toFloat(), size.height * relY.toFloat())
}

}
6 changes: 2 additions & 4 deletions src/main/kotlin/com/neptuneclient/voidui/widgets/Container.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ class Container(
border = border,
cornerRadius = cornerRadius,
child = if (width != null || height != null) {
val w = width ?: 0f
val h = height ?: 0f
SizedBox(
width = w,
height = h,
width = width,
height = height,
child = Padding(padding, child)
)
} else {
Expand Down
15 changes: 10 additions & 5 deletions src/main/kotlin/com/neptuneclient/voidui/widgets/SizedBox.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.neptuneclient.voidui.widgets
import com.neptuneclient.voidui.framework.BoxConstraints
import com.neptuneclient.voidui.framework.Size
import com.neptuneclient.voidui.framework.Widget
import kotlin.math.max

/**
* A widget which has a fixed size.
Expand All @@ -14,14 +13,20 @@ import kotlin.math.max
*/
class SizedBox(
private val child: Widget,
private val width: Float = 0f,
private val height: Float = 0f,
private val width: Float? = null,
private val height: Float? = null,
) : Widget() {

override fun layout(constraints: BoxConstraints) {
child.layout(constraints)
val childConstraints = BoxConstraints(
constraints.minWidth,
width ?: constraints.maxWidth,
constraints.minHeight,
height ?: constraints.maxHeight
)
child.layout(childConstraints)

val s = Size(max(width, child.size.width), max(height, child.size.height))
val s = Size(width ?: child.size.width, height ?: child.size.height)
size = constraints.constrain(s)
}

Expand Down
28 changes: 20 additions & 8 deletions src/test/kotlin/com/neptuneclient/voidui/tests/ScreenTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.neptuneclient.voidui.event.MouseClickedEvent
import com.neptuneclient.voidui.event.MouseReleasedEvent
import com.neptuneclient.voidui.framework.Offset
import com.neptuneclient.voidui.framework.Screen
import com.neptuneclient.voidui.framework.Size
import com.neptuneclient.voidui.framework.Widget
import com.neptuneclient.voidui.objects.Border
import com.neptuneclient.voidui.objects.CornerRadius
Expand All @@ -21,10 +22,15 @@ fun EpicButton(label: String): Widget {
color = Color(140, 60, 255),
cornerRadius = CornerRadius.all(10f),
border = Border(1f, Color(255, 255, 255, 100)),
width = 300f,
height = 39f,

child = Padding(
padding = EdgeInsets.symmetric(10f, 50f),
child = Text(label)
child = Align(
alignment = Alignment.center,
child = Padding(
padding = EdgeInsets.symmetric(10f, 0f),
child = Text(label)
)
)
)
}
Expand All @@ -34,11 +40,17 @@ class TestScreen(voidUI: VoidUI) : Screen(voidUI) {
override fun build(): Widget {
return Positioned(
position = Offset(300f, 300f),
child = Column(
gap = 20f,
children = arrayOf(
EpicButton("Singleplayer"),
EpicButton("Multiplayer")
child = Container(
color = Color(16, 14, 20),
cornerRadius = CornerRadius.all(10f),
padding = EdgeInsets.all(20f),

child = Column(
gap = 20f,
children = arrayOf(
EpicButton("Singleplayer"),
EpicButton("Multiplayer")
)
)
)
)
Expand Down

0 comments on commit fc6b742

Please sign in to comment.