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
138 changes: 108 additions & 30 deletions examples/siwin_graph_bottom_left.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import figdraw/fignodes
import figdraw/figrender

const RunOnce {.booldefine: "figdraw.runOnce".}: bool = false
const FontName {.strdefine: "figdraw.defaultfont".}: string = "Ubuntu.ttf"

proc addRectNode(
renders: var Renders,
Expand All @@ -34,7 +35,7 @@ proc addRectNode(
),
)

proc makeRenderTree(windowW, windowH: float32): Renders =
proc makeRenderTree(windowW, windowH: float32, uiFont: FigFont): Renders =
result = Renders(layers: initOrderedTable[ZLevel, RenderList]())
let z = 0.ZLevel

Expand All @@ -49,6 +50,21 @@ proc makeRenderTree(windowW, windowH: float32): Renders =
),
)

let sceneIdx = result.addChild(
z,
rootIdx,
Fig(
kind: nkTransform,
childCount: 0,
zlevel: z,
transform: TransformStyle(
translation: vec2(0.0'f32, windowH),
matrix: scale(vec3(1.0'f32, -1.0'f32, 1.0'f32)),
useMatrix: true,
),
),
)

let margin = max(36.0'f32, min(windowW, windowH) * 0.08'f32)
let plotRect = rect(
margin,
Expand All @@ -59,66 +75,124 @@ proc makeRenderTree(windowW, windowH: float32): Renders =

result.addRectNode(
z,
rootIdx,
sceneIdx,
plotRect,
rgba(255, 255, 255, 255),
corners = [10.0'f32, 10.0, 10.0, 10.0],
)

let graphIdx = result.addChild(
z,
rootIdx,
Fig(
kind: nkTransform,
childCount: 0,
zlevel: z,
transform: TransformStyle(
# Convert the graph to bottom-left origin coordinates.
translation: vec2(plotRect.x, plotRect.y + plotRect.h),
matrix: scale(vec3(1.0'f32, -1.0'f32, 1.0'f32)),
useMatrix: true,
),
),
)

let gridLines = 10
for i in 0 .. gridLines:
let t = i.float32 / gridLines.float32
let gx = t * plotRect.w
let gy = t * plotRect.h
let
gx = plotRect.x + t * plotRect.w
gy = plotRect.y + t * plotRect.h

result.addRectNode(
z, graphIdx, rect(gx, 0, 1.0'f32, plotRect.h), rgba(225, 229, 238, 255)
z,
sceneIdx,
rect(gx, plotRect.y, 1.0'f32, plotRect.h),
rgba(225, 229, 238, 255),
)
result.addRectNode(
z, graphIdx, rect(0, gy, plotRect.w, 1.0'f32), rgba(225, 229, 238, 255)
z,
sceneIdx,
rect(plotRect.x, gy, plotRect.w, 1.0'f32),
rgba(225, 229, 238, 255),
)

result.addRectNode(
z, graphIdx, rect(0, 0, plotRect.w, 2.0'f32), rgba(60, 65, 80, 255)
z,
sceneIdx,
rect(plotRect.x, plotRect.y, plotRect.w, 2.0'f32),
rgba(60, 65, 80, 255),
)
result.addRectNode(
z, graphIdx, rect(0, 0, 2.0'f32, plotRect.h), rgba(60, 65, 80, 255)
z,
sceneIdx,
rect(plotRect.x, plotRect.y, 2.0'f32, plotRect.h),
rgba(60, 65, 80, 255),
)

let samples = max(120, plotRect.w.int)
let cycles = 2.0'f32 * PI

for i in 0 .. samples:
let t = i.float32 / samples.float32
let x = t * plotRect.w
let x = plotRect.x + t * plotRect.w
let yNorm = clamp(0.5'f32 + 0.35'f32 * sin(t * cycles), 0.0'f32, 1.0'f32)
let y = yNorm * plotRect.h
let y = plotRect.y + yNorm * plotRect.h
result.addRectNode(
z,
graphIdx,
sceneIdx,
rect(x - 1.5'f32, y - 1.5'f32, 3.0'f32, 3.0'f32),
rgba(230, 63, 63, 255),
)

# Origin marker at (0, 0) in graph space.
# Origin marker at (0, 0) in plot-local graph space.
result.addRectNode(
z, graphIdx, rect(-3.0'f32, -3.0'f32, 6.0'f32, 6.0'f32), rgba(39, 169, 110, 255)
z,
sceneIdx,
rect(plotRect.x - 3.0'f32, plotRect.y - 3.0'f32, 6.0'f32, 6.0'f32),
rgba(39, 169, 110, 255),
)

let legendPadding = 12.0'f32
let legendRect = rect(
plotRect.x + plotRect.w - 300.0'f32,
plotRect.y + plotRect.h - 20.0'f32 - 124.0'f32,
280.0'f32,
124.0'f32,
)

discard result.addChild(
z,
sceneIdx,
Fig(
kind: nkRectangle,
childCount: 0,
zlevel: z,
screenBox: legendRect,
fill: rgba(255, 255, 255, 230),
stroke: RenderStroke(weight: 1.2'f32, fill: rgba(120, 130, 150, 180).color),
corners: [8.0'f32, 8.0'f32, 8.0'f32, 8.0'f32],
),
)

let legendText =
"Legend\n" &
"Red points: y = 0.5 + 0.35*sin(2πx)\n" &
"Green point: origin (0, 0)\n" &
"Axes: bottom-left coordinates"
let legendSelectionRange = 0'i16 .. 5'i16
let legendTextRect = rect(
legendRect.x + legendPadding,
legendRect.y + legendPadding,
legendRect.w - legendPadding * 2.0'f32,
legendRect.h - legendPadding * 2.0'f32,
)
let legendLayout = typeset(
rect(0, 0, legendTextRect.w, legendTextRect.h),
[span(uiFont, rgba(35, 40, 52, 255), legendText)],
hAlign = Left,
vAlign = Top,
minContent = false,
wrap = true,
)

discard result.addChild(
z,
sceneIdx,
Fig(
kind: nkText,
childCount: 0,
zlevel: z,
flags: {NfInvertY, NfSelectText},
screenBox: legendTextRect,
fill: rgba(255, 221, 122, 220),
selectionRange: legendSelectionRange,
textLayout: legendLayout,
),
)

when isMainModule:
Expand All @@ -143,6 +217,10 @@ when isMainModule:
renderer.setupBackend(appWindow)
appWindow.title = siwinWindowTitle(renderer, appWindow, "Siwin Bottom-Left Graph")

registerStaticTypeface("Ubuntu.ttf", "../data/Ubuntu.ttf")
let typefaceId = loadTypeface(FontName, @["Ubuntu.ttf"])
let uiFont = FigFont(typefaceId: typefaceId, size: 16.0'f32)

var
frames = 0
fpsFrames = 0
Expand All @@ -151,7 +229,7 @@ when isMainModule:
proc redraw() =
renderer.beginFrame()
let logicalSize = appWindow.logicalSize()
var renders = makeRenderTree(logicalSize.x, logicalSize.y)
var renders = makeRenderTree(logicalSize.x, logicalSize.y, uiFont)
renderer.renderFrame(renders, logicalSize)
renderer.endFrame()

Expand Down
26 changes: 7 additions & 19 deletions examples/siwin_text.nim
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ proc makeRenderTree*(
if rune == Rune(10):
monoLines.inc
let monoHeight = monoLines.float32 * monoLineHeight + monoPad * 2
let invertedLineHeight = uiFont.size * 1.4'f32
let invertedBoxHeight = uiFont.size * 5.0'f32
let sectionGap = 60.0'f32

proc mirroredInputRect(finalRect: Rect): Rect =
Expand All @@ -243,16 +243,16 @@ proc makeRenderTree*(
innerRect.x,
innerRect.y,
innerRect.w,
innerRect.h - monoHeight - invertedLineHeight * 2.0'f32 - sectionGap * 3.0'f32,
innerRect.h - monoHeight - invertedBoxHeight * 2.0'f32 - sectionGap * 3.0'f32,
)
let invertedTextRect = rect(
innerRect.x, textRect.y + textRect.h + sectionGap, innerRect.w, invertedLineHeight
innerRect.x, textRect.y + textRect.h + sectionGap, innerRect.w, invertedBoxHeight
)
let mirroredInvertedTextRect = rect(
innerRect.x,
invertedTextRect.y + invertedTextRect.h + sectionGap,
innerRect.w,
invertedLineHeight,
invertedBoxHeight,
)
let monoRect = rect(
innerRect.x,
Expand All @@ -262,7 +262,7 @@ proc makeRenderTree*(
)

let (layout, highlightRange) = buildBodyTextLayout(uiFont, textRect, modeLine)
let invertedText = "Inverted text line (NfInvertY) with selection"
let invertedText = "Inverted text line (NfInvertY)\nwith selection"
let invertedSelectionRange = findPhraseRange(invertedText, "NfInvertY")
let invertedLayout = typeset(
rect(0, 0, invertedTextRect.w, invertedTextRect.h),
Expand Down Expand Up @@ -306,26 +306,14 @@ proc makeRenderTree*(
),
)

let invertedGlyphBounds = rect(
invertedTextRect.x + invertedLayout.bounding.x,
invertedTextRect.y + invertedLayout.bounding.y,
invertedLayout.bounding.w,
invertedLayout.bounding.h,
)
let mirroredInvertedGlyphBounds = rect(
mirroredInvertedTextRect.x + invertedLayout.bounding.x,
mirroredInvertedTextRect.y + invertedLayout.bounding.y,
invertedLayout.bounding.w,
invertedLayout.bounding.h,
)
discard result.addChild(
z,
cardIdx,
Fig(
kind: nkRectangle,
childCount: 0,
zlevel: z,
screenBox: invertedGlyphBounds,
screenBox: invertedTextRect,
fill: clearColor,
stroke: RenderStroke(weight: 1.5, fill: rgba(38, 38, 38, 155).color),
corners: [4.0'f32, 4.0, 4.0, 4.0],
Expand Down Expand Up @@ -354,7 +342,7 @@ proc makeRenderTree*(
kind: nkRectangle,
childCount: 0,
zlevel: z,
screenBox: mirroredInvertedGlyphBounds,
screenBox: mirroredInvertedTextRect,
fill: clearColor,
stroke: RenderStroke(weight: 1.5, fill: rgba(42, 96, 168, 170).color),
corners: [4.0'f32, 4.0, 4.0, 4.0],
Expand Down
2 changes: 1 addition & 1 deletion figdraw.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "0.22.3"
version = "0.22.4"
author = "Jaremy Creechley"
description = "UI Engine for Nim"
license = "MIT"
Expand Down
Loading
Loading