HUD element smart snapping with guides by Avanatiker · Pull Request #145 · lambda-client/lambda · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 162 additions & 5 deletions src/main/kotlin/com/lambda/gui/components/HudGuiLayout.kt
76 changes: 69 additions & 7 deletions src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ object ImGuiBuilder {
* @param scaleMin Minimum scale value
* @param scaleMax Maximum scale value
* @param graphSize Size of the graph
* @param stride Stride between values
* @param stride Sample decimation step (>= 1). Use 0/1 for contiguous data.
*/
@ImGuiDsl
fun plotLines(
Expand All @@ -1283,8 +1283,17 @@ object ImGuiBuilder {
scaleMin: Float = Float.MAX_VALUE,
scaleMax: Float = Float.MAX_VALUE,
graphSize: ImVec2 = ImVec2(),
stride: Int = 1,
) = ImGui.plotLines(label, values, valuesOffset, overlayText, scaleMin, scaleMax, graphSize, stride)
stride: Int = 0,
) {
val (src, sMin, sMax) = preparePlotSeries(values, stride, scaleMin, scaleMax)
val count = src.size
val offset = if (count == 0) 0 else valuesOffset.coerceIn(0, count - 1)
if (count < 2) {
plotLines(label, floatArrayOf(), 0, 0, overlayText, sMin, sMax, graphSize.x, graphSize.y)
return
}
plotLines(label, src, count, offset, overlayText, sMin, sMax, graphSize.x, graphSize.y)
}

/**
* Creates a plot of histogram values.
Expand All @@ -1296,7 +1305,7 @@ object ImGuiBuilder {
* @param scaleMin Minimum scale value
* @param scaleMax Maximum scale value
* @param graphSize Size of the graph
* @param stride Stride between values
* @param stride Sample decimation step (>= 1). Use 0/1 for contiguous data.
*/
@ImGuiDsl
fun plotHistogram(
Expand All @@ -1307,8 +1316,61 @@ object ImGuiBuilder {
scaleMin: Float = Float.MAX_VALUE,
scaleMax: Float = Float.MAX_VALUE,
graphSize: ImVec2 = ImVec2(),
stride: Int = 1,
) = ImGui.plotHistogram(label, values, valuesOffset, overlayText, scaleMin, scaleMax, graphSize, stride)
stride: Int = 0,
) {
val (src, sMin, sMax) = preparePlotSeries(values, stride, scaleMin, scaleMax)
val count = src.size
val offset = if (count == 0) 0 else valuesOffset.coerceIn(0, count - 1)
if (count < 1) {
plotHistogram(label, floatArrayOf(), 0, 0, overlayText, sMin, sMax, graphSize.x, graphSize.y)
return
}
plotHistogram(label, src, count, offset, overlayText, sMin, sMax, graphSize.x, graphSize.y)
}

private fun preparePlotSeries(
values: FloatArray,
stride: Int,
scaleMin: Float,
scaleMax: Float
): Triple<FloatArray, Float, Float> {
val contiguous = (stride <= 1)
val src = if (contiguous) {
values
} else {
val outSize = (values.size + stride - 1) / stride
val out = FloatArray(outSize)
var i = 0
var j = 0
while (i < values.size) {
out[j++] = values[i]
i += stride
}
out
}
var sMin = scaleMin
var sMax = scaleMax
if (sMin == Float.MAX_VALUE && sMax == Float.MAX_VALUE) {
var minV = Float.POSITIVE_INFINITY
var maxV = Float.NEGATIVE_INFINITY
for (v in src) if (v.isFinite()) {
if (v < minV) minV = v
if (v > maxV) maxV = v
}
if (!minV.isFinite() || !maxV.isFinite()) {
minV = 0f; maxV = 1f
}
if (minV == maxV) {
val base = if (minV == 0f) 1f else kotlin.math.abs(minV)
val pad = base * 0.01f
minV -= pad
maxV += pad
}
sMin = minV
sMax = maxV
}
return Triple(src, sMin, sMax)
}

/**
* Creates a main menu bar.
Expand Down Expand Up @@ -1485,7 +1547,7 @@ object ImGuiBuilder {
*
* @param title Title of the modal
* @param value Boolean reference to control visibility
* @param flags Additional window flags
* @param windowFlags Additional window flags
* @param block Content of the modal
*
* @see ImGuiPopupFlags
Expand Down
28 changes: 28 additions & 0 deletions src/main/kotlin/com/lambda/gui/snap/Guide.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2025 Lambda
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.lambda.gui.snap

data class Guide(
val orientation: Orientation,
val pos: Float,
val strength: Int,
val kind: Kind
) {
enum class Orientation { Vertical, Horizontal }
enum class Kind { ElementEdge, ElementCenter, ScreenCenter, Grid }
}
27 changes: 27 additions & 0 deletions src/main/kotlin/com/lambda/gui/snap/RectF.kt
Loading