Skip to content
Open
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
2 changes: 1 addition & 1 deletion figuro.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "0.16.1"
version = "0.16.2"
author = "Jaremy Creechley"
description = "UI Engine for Nim"
license = "MIT"
Expand Down
3 changes: 2 additions & 1 deletion src/figuro/common/inputs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type
WindowInfo* = object
box*: Box ## Screen size in logical coordinates.
running*, focused*, minimized*, fullscreen*: bool
autoSavePosition*: bool
pixelRatio*: float32 ## Multiplier to convert from screen coords to pixels

variantp ClipboardContents:
Expand Down Expand Up @@ -42,7 +43,7 @@ type AppInputs* = object
keyRelease*: set[UiKey]
keyToggle*: set[UiKey]

window*: Option[WindowInfo]
windowInfo*: Option[WindowInfo]

proc click*(inputs: AppInputs): bool =
when defined(clickOnDown):
Expand Down
1 change: 1 addition & 0 deletions src/figuro/common/nodes/uinodes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type
theme*: Theme
configFile*: string
saveWindowState*: bool
atlasSize*: int
clipboards*: RChan[ClipboardContents]

Figuro* = ref object of Agent
Expand Down
7 changes: 6 additions & 1 deletion src/figuro/renderer/opengl/renderer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,18 @@ proc renderRoot*(ctx: Context, nodes: var Renders) {.forbids: [AppMainThreadEff]
# echo "img: ", img
ctx.putImage(img[0], img[1])

# clearColorBuffer(color(1.0, 1.0, 1.0, 1.0))
if 0.ZLevel in nodes.layers and nodes.layers[0.ZLevel].nodes.len() > 0:
clearColorBuffer(nodes.layers[0.ZLevel].nodes[0].fill)
else:
clearColorBuffer(color(1.0, 1.0, 1.0, 1.0))

for zlvl, list in nodes.layers.pairs():
for rootIdx in list.rootIds:
ctx.render(list.nodes, rootIdx, -1.NodeIdx)

proc renderFrame*(renderer: OpenGLRenderer) =
let ctx: Context = renderer.ctx
clearColorBuffer(color(1.0, 1.0, 1.0, 1.0))
ctx.beginFrame(renderer.window.info.box.wh.scaled())
ctx.saveTransform()
ctx.scale(ctx.pixelScale)
Expand Down
32 changes: 24 additions & 8 deletions src/figuro/renderer/openglBackend.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,40 @@ export baserenderer

proc createRenderer*[F](frame: WeakRef[F]): Renderer =

let atlasSize = 2048 shl (app.uiScale.round().toInt() + 1)
let window = newWindexWindow(frame)
let renderer = newOpenGLRenderer(window, frame, atlasSize)
if frame[].atlasSize == -1:
frame[].atlasSize = 2048 shl (app.uiScale.round().toInt() + 1)

info "Using Atlas Size", atlasSize= frame[].atlasSize
let window = newRendererWindow(frame)
let renderer = newOpenGLRenderer(window, frame, frame[].atlasSize)

# window defaults
frame[].windowInfo.focused = true
frame[].windowInfo.autoSavePosition = true

if app.autoUiScale:
let scale = renderer.window.getScaleInfo()
app.uiScale = min(scale.x, scale.y)

let winCfg = frame.loadLastWindow()
if winCfg.size.x != 0 and winCfg.size.y != 0:
let sz = vec2(x= winCfg.size.x.float32, y= winCfg.size.y.float32).descaled()
frame[].windowInfo.box.w = sz.x.UiScalar
frame[].windowInfo.box.h = sz.y.UiScalar
renderer.window.setWindowSize(frame)

if frame[].windowInfo.autoSavePosition:
let winCfg = frame.loadLastWindow()
info "Loaded window config", winCfg= winCfg
if winCfg.size.x != 0 and winCfg.size.y != 0:
let sz = vec2(x= winCfg.size.x.float32, y= winCfg.size.y.float32).descaled()
frame[].windowInfo.box.w = sz.x.UiScalar
frame[].windowInfo.box.h = sz.y.UiScalar
renderer.window.setWindowSize(frame)
let pos = vec2(x= winCfg.pos.x.float32, y= winCfg.pos.y.float32).descaled()
frame[].windowInfo.box.x = pos.x.UiScalar
frame[].windowInfo.box.y = pos.y.UiScalar
renderer.window.setWindowPos(frame)

window.configureWindowEvents(renderer)

renderer.window.frame[].windowInfo.running = true
app.requestedFrame.inc

renderer.window.setVisible(true)
return renderer
185 changes: 42 additions & 143 deletions src/figuro/renderer/openglSiwin.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import std/strformat
import pkg/pixie
import pkg/opengl
import pkg/siwin
import pkg/sigils/weakrefs
import pkg/chronicles

import opengl/glutils
import opengl/glcommons
import opengl/renderer
import ./utils/glutils

import ../common/nodes/uinodes
import ../common/rchannels
import ../common/wincfgs
import ../common/shared
import ../common/keys

import pkg/sigils/weakrefs
import pkg/chronicles
import ./utils/baserenderer

export AppFrame

Expand All @@ -27,17 +28,17 @@ var
when defined(glDebugMessageCallback):
import strformat, strutils

proc convertStyle*(fs: FrameStyle): WindowStyle
# proc convertStyle*(fs: FrameStyle): WindowStyle

type
RendererSiwin* = ref object of Renderer
RendererSiwin* = ref object of RendererWindow
window: Window

proc setupWindow*(
frame: WeakRef[AppFrame],
window: Window,
) =
let style: WindowStyle = frame[].windowStyle.convertStyle()
# let style: WindowStyle = frame[].windowStyle.convertStyle()
assert not frame.isNil
if frame[].windowInfo.fullscreen:
window.fullscreen = frame[].windowInfo.fullscreen
Expand All @@ -51,77 +52,71 @@ proc setupWindow*(
"Failed to open window. GL version:" & &"{openglVersion[0]}.{$openglVersion[1]}"
)

window.makeContextCurrent()
# window.makeContextCurrent()

let winCfg = frame.loadLastWindow()

window.`style=`(style)
# window.`style=`(style)
window.`pos=`(winCfg.pos)

proc newSiwinRenderer*(
frame: WeakRef[AppFrame],
forcePixelScale: float32,
atlasSize: int,
): RendererSiwin =
let window = newWindow("Figuro", ivec2(1280, 800), visible = false)
let window = newSiwinGlobals().newOpenglWindow()

result = RendererSiwin(window: window, frame: frame)
startOpenGL(openglVersion)

setupWindow(frame, window)

configureRenderer(result, frame, forcePixelScale, atlasSize)

proc convertStyle*(fs: FrameStyle): WindowStyle =
case fs
of FrameStyle.DecoratedResizable:
WindowStyle.DecoratedResizable
of FrameStyle.DecoratedFixedSized:
WindowStyle.Decorated
of FrameStyle.Undecorated:
WindowStyle.Undecorated
of FrameStyle.Transparent:
WindowStyle.Transparent

proc toUi*(wbtn: windex.ButtonView): set[UiMouse] =
when defined(nimscript):
for b in set[Button](wbtn):
result.incl UiButton(b.int)
else:
copyMem(addr result, unsafeAddr wbtn, sizeof(ButtonView))
configureBaseWindow(result)

method setWindowSize*(w: RendererSiwin, size: IVec2) =
w.window.`size=`(size)


method swapBuffers*(r: RendererSiwin) =
r.window.swapBuffers()
# r.window.swapBuffers()
discard

method pollEvents*(r: RendererSiwin) =
windex.pollEvents()
# windex.pollEvents()
discard

method getScaleInfo*(r: RendererSiwin): ScaleInfo =
let scale = r.window.contentScale()
result.x = scale
result.y = scale
# let scale = r.window.contentScale()
# result.x = scale
# result.y = scale
result.x = 1.0
result.y = 1.0

var lastMouse = Mouse()
var lastMouse: keys.Mouse

proc copyInputs*(w: Window): AppInputs =
result = AppInputs(mouse: lastMouse)
result.buttonRelease = toUi w.buttonReleased()
result.buttonPress = toUi w.buttonPressed()
result.buttonDown = toUi w.buttonDown()
result.buttonToggle = toUi w.buttonToggle()
# result.buttonRelease = toUi w.buttonReleased()
# result.buttonPress = toUi w.buttonPressed()
# result.buttonDown = toUi w.buttonDown()
# result.buttonToggle = toUi w.buttonToggle()

method copyInputs*(r: RendererSiwin): AppInputs =
copyInputs(r.window)

method setClipboard*(r: RendererSiwin, cb: ClipboardContents) =
match cb:
ClipboardStr(str):
windex.setClipboardString(str)
# windex.setClipboardString(str)
discard
ClipboardEmpty:
discard

method getClipboard*(r: RendererSiwin): ClipboardContents =
let str = windex.getClipboardString()
return ClipboardStr(str)
# let str = windex.getClipboardString()
# return ClipboardStr(str)
# return ClipboardEmpty
discard

method setTitle*(r: RendererSiwin, name: string) =
r.window.title = name
Expand All @@ -133,7 +128,8 @@ method getWindowInfo*(r: RendererSiwin): WindowInfo =
app.requestedFrame.inc

result.minimized = r.window.minimized()
result.pixelRatio = r.window.contentScale()
# result.pixelRatio = r.window.contentScale()
result.pixelRatio = 1.0

var cwidth, cheight: cint
let size = r.window.size()
Expand All @@ -148,103 +144,6 @@ method configureWindowEvents*(renderer: RendererSiwin) =
let uxInputList = renderer.uxInputList
let frame = renderer.frame

window.runeInputEnabled = true

window.onCloseRequest = proc() =
notice "onCloseRequest"
if frame[].saveWindowState:
let wc = WindowConfig(pos: window.pos, size: window.size)
writeWindowConfig(wc, winCfgFile)
app.running = false

window.onMove = proc() =
discard
# debug "window moved: ", pos= window.pos

window.onResize = proc() =
# updateWindowSize(renderer.frame, window)
let windowState = renderer.getWindowInfo()
var uxInput = window.copyInputs()
uxInput.window = some windowState
uxInputList.push(uxInput)
pollAndRender(renderer, poll = false)

window.onFocusChange = proc() =
var uxInput = window.copyInputs()
uxInput.window = some renderer.getWindowInfo()
uxInputList.push(uxInput)

window.onMouseMove = proc() =
var uxInput = AppInputs()
let pos = vec2(window.mousePos())
uxInput.mouse.pos = pos.descaled()
let prevPos = vec2(window.mousePrevPos())
uxInput.mouse.prev = prevPos.descaled()
uxInput.mouse.consumed = false
lastMouse = uxInput.mouse
lastMouse.consumed = true
uxInputList.push(uxInput)

window.onScroll = proc() =
var uxInput = AppInputs(mouse: lastMouse)
uxInput.mouse.consumed = false
uxInput.mouse.wheelDelta = window.scrollDelta().descaled()
uxInputList.push(uxInput)

window.onButtonPress = proc(button: windex.Button) =
let uxInput = window.copyInputs()
when defined(debugEvents):
stdout.styledWriteLine(
{styleDim},
fgWhite,
"buttonPress ",
{styleBright},
fgGreen,
$uxInput.buttonPress,
fgWhite,
"buttonRelease ",
fgGreen,
$uxInput.buttonRelease,
fgWhite,
"buttonDown ",
{styleBright},
fgGreen,
$uxInput.buttonDown,
) # fgBlue, " time: " & $(time - lastButtonRelease) )
uxInputList.push(uxInput)

window.onButtonRelease = proc(button: Button) =
let uxInput = window.copyInputs()
when defined(debugEvents):
stdout.styledWriteLine(
{styleDim},
fgWhite,
"release ",
fgGreen,
$button,
fgWhite,
"buttonRelease ",
fgGreen,
$uxInput.buttonRelease,
fgWhite,
"buttonDown ",
{styleBright},
fgGreen,
$uxInput.buttonDown,
fgWhite,
"buttonPress ",
{styleBright},
fgGreen,
$uxInput.buttonPress,
)
uxInputList.push(uxInput)

window.onRune = proc(rune: Rune) =
var uxInput = AppInputs(mouse: lastMouse)
uxInput.keyboard.rune = some rune
when defined(debugEvents):
stdout.styledWriteLine(
{styleDim}, fgWhite, "keyboardInput: ", {styleDim}, fgGreen, $rune
)
uxInputList.push(uxInput)
# window.runeInputEnabled = true


Loading