@@ -21,53 +21,47 @@ import com.lambda.graphics.RenderMain
2121import com.lambda.graphics.animation.AnimationTicker
2222import com.lambda.event.events.GuiEvent
2323import com.lambda.graphics.pipeline.ScissorAdapter
24- import com.lambda.graphics.renderer.gui.font.FontRenderer
25- import com.lambda.graphics.renderer.gui.rect.OutlineRectRenderer
2624import com.lambda.gui.component.HAlign
2725import com.lambda.gui.component.VAlign
2826import com.lambda.gui.component.core.*
2927import com.lambda.util.KeyCode
3028import com.lambda.util.Mouse
3129import com.lambda.util.math.Rect
3230import com.lambda.util.math.Vec2d
33- import java.awt.Color
3431
3532/* *
3633 * Represents a component for creating complex ui structures.
3734 */
3835open class Layout (
3936 val owner : Layout ?
4037) {
41- val rect get() = Rect .basedOn(renderPosition, renderSize)
38+ var rect
39+ get() = Rect .basedOn(position, size)
40+ set(value) { position = value.leftTop; size = value.size }
4241
4342 // ToDo: impl alignmentLayout: Layout, instead of being able to align to the owner only
4443 // Position of the component
4544 var position: Vec2d
4645 get() = Vec2d (positionX, positionY)
4746 set(value) { positionX = value.x; positionY = value.y }
4847
49- private var positionX: Double
48+ var positionX: Double
5049 get() = ownerX + (relativePosX + dockingOffsetX).let {
5150 if (! properties.clampPosition) return @let it
52- it.coerceAtMost(ownerWidth - renderWidth ).coerceAtLeast(0.0 )
51+ it.coerceAtMost(ownerWidth - width ).coerceAtLeast(0.0 )
5352 }; set(value) { relativePosX = value - ownerX - dockingOffsetX }
5453
55- private var positionY: Double
54+ var positionY: Double
5655 get() = ownerY + (relativePosY + dockingOffsetY).let {
5756 if (! properties.clampPosition) return @let it
58- it.coerceAtMost(ownerHeight - renderHeight ).coerceAtLeast(0.0 )
57+ it.coerceAtMost(ownerHeight - height ).coerceAtLeast(0.0 )
5958 }; set(value) { relativePosY = value - ownerY - dockingOffsetY }
6059
61- val leftTop get() = renderPosition
62- val rightTop get() = Vec2d (renderPositionX + renderWidth, renderPositionY )
63- val rightBottom get() = Vec2d (renderPositionX + renderWidth, renderPositionY + renderHeight )
64- val leftBottom get() = Vec2d (renderPositionX, renderPositionY + renderHeight )
60+ val leftTop get() = position
61+ val rightTop get() = Vec2d (positionX + width, positionY )
62+ val rightBottom get() = Vec2d (positionX + width, positionY + height )
63+ val leftBottom get() = Vec2d (positionX, positionY + height )
6564
66- val renderPosition get() = Vec2d (renderPositionX, renderPositionY)
67- val renderPositionX get() = positionXTransform()
68- val renderPositionY get() = positionYTransform()
69- private var positionXTransform = { positionX }
70- private var positionYTransform = { positionY }
7165 private var relativePosX = 0.0
7266 private var relativePosY = 0.0
7367
@@ -76,14 +70,6 @@ open class Layout(
7670 get() = Vec2d (width, height)
7771 set(value) { width = value.x; height = value.y }
7872
79- val renderSize get() = Vec2d (renderWidth, renderHeight)
80-
81- val renderWidth get() = widthTransform()
82- val renderHeight get() = heightTransform()
83-
84- private var widthTransform = { width }
85- private var heightTransform = { height }
86-
8773 var width = 0.0
8874 var height = 0.0
8975
@@ -93,23 +79,23 @@ open class Layout(
9379 field = to
9480
9581 val delta = to.multiplier - from.multiplier
96- relativePosX + = delta * (renderWidth - ownerWidth)
82+ relativePosX + = delta * (width - ownerWidth)
9783 }
9884
9985 private val dockingOffsetX get() = if (horizontalAlignment == HAlign .LEFT ) 0.0
100- else (ownerWidth - renderWidth ) * horizontalAlignment.multiplier
86+ else (ownerWidth - width ) * horizontalAlignment.multiplier
10187
10288 // Vertical alignment
10389 var verticalAlignment = VAlign .TOP ; set(to) {
10490 val from = field
10591 field = to
10692
10793 val delta = to.multiplier - from.multiplier
108- relativePosY + = delta * (renderHeight - ownerHeight)
94+ relativePosY + = delta * (height - ownerHeight)
10995 }
11096
11197 private val dockingOffsetY get() = if (verticalAlignment == VAlign .TOP ) 0.0
112- else (ownerHeight - renderHeight ) * verticalAlignment.multiplier
98+ else (ownerHeight - height ) * verticalAlignment.multiplier
11399
114100 // Use screen limits if [owner] is null
115101 private var screenSize = Vec2d .ZERO
@@ -128,12 +114,12 @@ open class Layout(
128114 // Structure
129115 val children = mutableListOf<Layout >()
130116 var selectedChild: Layout ? = null
131- protected open val renderSelf: Boolean get() = renderWidth > 1 && renderHeight > 1
117+ protected open val renderSelf: Boolean get() = width > 1 && height > 1
132118 protected open val scissorRect get() = rect
133119
134120 // Inputs
135121 protected var mousePosition = Vec2d .ZERO
136- var isHovered = false ; get() = field && ( owner?.isHovered ? : true )
122+ open val isHovered get() = owner?.let { it.selectedChild == this } ? : true
137123
138124 // Actions
139125 private val showActions = mutableListOf<Layout .() - > Unit > ()
@@ -244,7 +230,7 @@ open class Layout(
244230 */
245231 @LayoutBuilder
246232 fun <T : Layout > T.onMouseClick (button : Mouse .Button , action : Mouse .Action , block : T .() -> Unit ) {
247- mouseClickActions + = { butt, act ->
233+ onMouseClick { butt, act ->
248234 if (butt == button && act == action) block()
249235 }
250236 }
@@ -274,15 +260,23 @@ open class Layout(
274260 */
275261 @LayoutBuilder
276262 fun overrideX (transform : () -> Double ) {
277- positionXTransform = transform
263+ positionX = transform()
264+
265+ onUpdate {
266+ positionX = transform()
267+ }
278268 }
279269
280270 /* *
281271 * Force overrides drawn y position of the layout
282272 */
283273 @LayoutBuilder
284274 fun overrideY (transform : () -> Double ) {
285- positionYTransform = transform
275+ positionY = transform()
276+
277+ onUpdate {
278+ positionY = transform()
279+ }
286280 }
287281
288282 /* *
@@ -299,15 +293,23 @@ open class Layout(
299293 */
300294 @LayoutBuilder
301295 fun overrideWidth (transform : () -> Double ) {
302- widthTransform = transform
296+ width = transform()
297+
298+ onUpdate {
299+ width = transform()
300+ }
303301 }
304302
305303 /* *
306304 * Force overrides drawn height of the layout
307305 */
308306 @LayoutBuilder
309307 fun overrideHeight (transform : () -> Double ) {
310- heightTransform = transform
308+ height = transform()
309+
310+ onUpdate {
311+ height = transform()
312+ }
311313 }
312314
313315 /* *
@@ -319,22 +321,6 @@ open class Layout(
319321 overrideHeight(height)
320322 }
321323
322- /* *
323- * Makes this layout expand up to parents rect
324- */
325- @LayoutBuilder
326- fun fillParent (
327- overrideX : () -> Double = { owner?.renderPositionX ? : ownerX },
328- overrideY : () -> Double = { owner?.renderPositionY ? : ownerY },
329- overrideWidth : () -> Double = { owner?.renderWidth ? : ownerWidth },
330- overrideHeight : () -> Double = { owner?.renderHeight ? : ownerHeight }
331- ) {
332- overrideX(overrideX)
333- overrideY(overrideY)
334- overrideWidth(overrideWidth)
335- overrideHeight(overrideHeight)
336- }
337-
338324 /* *
339325 * Removes this layout from its parent
340326 */
@@ -353,19 +339,17 @@ open class Layout(
353339 screenSize = RenderMain .screenSize
354340
355341 // Update relative position and bounds
356- ownerX = owner?.renderPositionX ? : ownerX
357- ownerY = owner?.renderPositionY ? : ownerY
358- ownerWidth = owner?.renderWidth ? : screenSize.x
359- ownerHeight = owner?.renderHeight ? : screenSize.y
360-
361- // Update hover state (don't mark as hovered if hovered pixel is outside the owner)
362- val xh = (mousePosition.x - renderPositionX) in 0.0 .. renderWidth
363- val yh = (mousePosition.y - renderPositionY) in 0.0 .. renderHeight
364- isHovered = xh && yh
342+ ownerX = owner?.positionX ? : ownerX
343+ ownerY = owner?.positionY ? : ownerY
344+ ownerWidth = owner?.width ? : screenSize.x
345+ ownerHeight = owner?.height ? : screenSize.y
365346
366347 // Select an element that's on foreground
367348 selectedChild = if (isHovered) children.lastOrNull {
368- ! it.properties.interactionPassthrough && mousePosition in it.rect
349+ if (it.properties.interactionPassthrough) return @lastOrNull false
350+ val xh = (mousePosition.x - it.positionX) in 0.0 .. it.width
351+ val yh = (mousePosition.y - it.positionY) in 0.0 .. it.height
352+ xh && yh
369353 } else null
370354 }
371355 }
@@ -415,8 +399,7 @@ open class Layout(
415399 children.forEach { child ->
416400 if (e is GuiEvent .Render ) return @forEach
417401 if (e is GuiEvent .MouseClick ) {
418- val hovered = child == selectedChild || (child.isHovered && child.properties.interactionPassthrough)
419- val newAction = if (hovered) e.action else Mouse .Action .Release
402+ val newAction = if (child.isHovered) e.action else Mouse .Action .Release
420403
421404 val newEvent = GuiEvent .MouseClick (e.button, newAction, e.mouse)
422405 child.onEvent(newEvent)
@@ -430,20 +413,6 @@ open class Layout(
430413 val block = {
431414 renderActions.forEach { it(this ) }
432415 if (renderSelf) children.forEach { it.onEvent(e) }
433-
434- /* if (this !is FilledRect && this !is OutlineRect && this !is TextField) {
435- OutlineRectRenderer.outlineRect(
436- rect,
437- glowRadius = 0.5
438- )
439-
440- FontRenderer.drawString(
441- javaClass.simpleName,
442- leftTop + FontRenderer.getHeight(0.5) * 0.5,
443- Color.WHITE,
444- 0.5
445- )
446- }*/
447416 }
448417
449418 if (! properties.scissor) block()
0 commit comments