From ca1e43f5d1d3ccf5ae9f18def6b36db4ad27f00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=9B=E5=85=89=E5=B9=B4?= Date: Tue, 7 Feb 2023 23:40:19 +0800 Subject: [PATCH 1/8] Better Layout 1. try to compute parent layout when possible. (strench in strench) 2. node.layoutWeight => support flex-like auto-layout 3. node.wrapContent => toggle whether auto-layout should wrap content size --- src/fidget.nim | 8 ++++++ src/fidget/common.nim | 57 ++++++++++++++++++++++++++++++++------ src/fidget/opengl/base.nim | 4 +-- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/fidget.nim b/src/fidget.nim index 4c439815..50c578f5 100644 --- a/src/fidget.nim +++ b/src/fidget.nim @@ -412,6 +412,14 @@ proc layoutAlign*(mode: LayoutAlign) = ## Set the layout alignment mode. current.layoutAlign = mode +proc layoutWeight*(weight: float32) = + ## Set the layout weight. + current.layoutWeight = weight + +proc wrapContent*(flag: bool) = + ## Set the whether wrap content or not. + current.wrapContent = flag + proc layout*(mode: LayoutMode) = ## Set the layout mode. current.layoutMode = mode diff --git a/src/fidget/common.nim b/src/fidget/common.nim index 5c70be59..f45e26be 100644 --- a/src/fidget/common.nim +++ b/src/fidget/common.nim @@ -3,7 +3,7 @@ import chroma, input, sequtils, tables, vmath, json, bumpy when defined(js): import dom2, html/ajax else: - import typography, typography/textboxes, tables, asyncfutures + import typography, typography/textboxes, asyncfutures const clearColor* = color(0, 0, 0, 0) @@ -124,6 +124,8 @@ type constraintsHorizontal*: Constraint constraintsVertical*: Constraint layoutAlign*: LayoutAlign + layoutWeight*: float32 + wrapContent*: bool layoutMode*: LayoutMode counterAxisSizingMode*: CounterAxisSizingMode horizontalPadding*: float32 @@ -313,6 +315,8 @@ proc resetToDefault*(node: Node)= node.constraintsVertical = cMin node.layoutAlign = laMin node.layoutMode = lmNone + node.layoutWeight = 0.0 + node.wrapContent = false node.counterAxisSizingMode = csAuto node.horizontalPadding = 0 node.verticalPadding = 0 @@ -368,10 +372,6 @@ proc consume*(mouse: Mouse) = buttonPress[MOUSE_LEFT] = false proc computeLayout*(parent, node: Node) = - ## Computes constraints and auto-layout. - for n in node.nodes: - computeLayout(node, n) - # Constraints code. case node.constraintsVertical: of cMin: discard @@ -420,6 +420,13 @@ proc computeLayout*(parent, node: Node) = node.box.w = node.textLayoutWidth node.box.h = node.textLayoutHeight + ## Computes constraints and auto-layout. + for n in node.nodes: + if node.layoutMode != lmNone and + (n.layoutWeight != 0 or n.layoutAlign == laStretch): + continue + computeLayout(node, n) + # Auto-layout code. if node.layoutMode == lmVertical: if node.counterAxisSizingMode == csAuto: @@ -429,10 +436,26 @@ proc computeLayout*(parent, node: Node) = if n.layoutAlign != laStretch: maxW = max(maxW, n.box.w) node.box.w = maxW + node.horizontalPadding * 2 + + var remainHeight = node.box.h - node.verticalPadding * 2 - node.itemSpacing * (node.nodes.len - 1).float32 + var totalWeight: float32 + var weightTable: Table[int, float32] + for i, n in node.nodes.pairs: + if n.layoutWeight == 0: + remainHeight -= n.box.h + else: + totalWeight += n.layoutWeight + weightTable[i] = n.layoutWeight + for i, w in weightTable.pairs: + let n = node.nodes[i] + n.box.h = + if remainHeight <= 0: 0.0 + else: remainHeight * w / totalWeight + if n.layoutAlign != laStretch: computeLayout(node, n) var at = 0.0 at += node.verticalPadding - for i, n in node.nodes.reversePairs: + for i, n in node.nodes: if i > 0: at += node.itemSpacing n.box.y = at @@ -450,7 +473,7 @@ proc computeLayout*(parent, node: Node) = computeLayout(node, n) at += n.box.h at += node.verticalPadding - node.box.h = at + if node.wrapContent: node.box.h = at if node.layoutMode == lmHorizontal: if node.counterAxisSizingMode == csAuto: @@ -461,9 +484,25 @@ proc computeLayout*(parent, node: Node) = maxH = max(maxH, n.box.h) node.box.h = maxH + node.verticalPadding * 2 + var remainWidth = node.box.w - node.horizontalPadding * 2 - node.itemSpacing * (node.nodes.len - 1).float32 + var totalWeight: float32 + var weightTable: Table[int, float32] + for i, n in node.nodes.pairs: + if n.layoutWeight == 0: + remainWidth -= n.box.w + else: + totalWeight += n.layoutWeight + weightTable[i] = n.layoutWeight + for i, w in weightTable.pairs: + let n = node.nodes[i] + n.box.w = + if remainWidth <= 0: 0.0 + else: remainWidth * w / totalWeight + if n.layoutAlign != laStretch: computeLayout(node, n) + var at = 0.0 at += node.horizontalPadding - for i, n in node.nodes.reversePairs: + for i, n in node.nodes: if i > 0: at += node.itemSpacing n.box.x = at @@ -481,7 +520,7 @@ proc computeLayout*(parent, node: Node) = computeLayout(node, n) at += n.box.w at += node.horizontalPadding - node.box.w = at + if node.wrapContent: node.box.w = at proc computeScreenBox*(parent, node: Node) = ## Setups screenBoxes for the whole tree. diff --git a/src/fidget/opengl/base.nim b/src/fidget/opengl/base.nim index 70c186ca..7956eb96 100644 --- a/src/fidget/opengl/base.nim +++ b/src/fidget/opengl/base.nim @@ -247,13 +247,13 @@ proc onSetKey( textBox.delete(shift) of LETTER_C: # copy if ctrl: - base.window.setClipboardString(textBox.copy()) + base.window.setClipboardString(textBox.copy().cstring) of LETTER_V: # paste if ctrl: textBox.paste($base.window.getClipboardString()) of LETTER_X: # cut if ctrl: - base.window.setClipboardString(textBox.cut()) + base.window.setClipboardString(textBox.cut().cstring) of LETTER_A: # select all if ctrl: textBox.selectAll() From fae9778062bf91ae239ea8ce026f2297d3d7ede8 Mon Sep 17 00:00:00 2001 From: Luna1996 <2320909844@qq.com> Date: Wed, 8 Feb 2023 16:46:57 +0800 Subject: [PATCH 2/8] Better Text & Text Editor 1. can auto resize only width 2. no strange lift when editing 3. when end editing, will request redraw. ( avoid blank text 4. if not in multiline mode, hit enter will also end editing TODO: when text len is 0, the edit course has been drawn wrong --- src/fidget.nim | 4 ++++ src/fidget/common.nim | 6 +++++- src/fidget/openglbackend.nim | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/fidget.nim b/src/fidget.nim index 50c578f5..7a455bed 100644 --- a/src/fidget.nim +++ b/src/fidget.nim @@ -456,6 +456,10 @@ template binding*(stringVariable: untyped) = keyboard.focus(current) onClickOutside: keyboard.unFocus(current) + refresh() + if not current.multiline and buttonRelease[ENTER]: + keyboard.unFocus(current) + refresh() onInput: if stringVariable != keyboard.input: stringVariable = keyboard.input diff --git a/src/fidget/common.nim b/src/fidget/common.nim index f45e26be..9cb49d52 100644 --- a/src/fidget/common.nim +++ b/src/fidget/common.nim @@ -31,8 +31,9 @@ type TextAutoResize* = enum ## Should text element resize and how. tsNone - tsWidthAndHeight + tsWidth tsHeight + tsWidthAndHeight TextStyle* = object ## Holder for text styles. @@ -412,6 +413,9 @@ proc computeLayout*(parent, node: Node) = of tsNone: # Fixed sized text node. discard + of tsWidth: + # Text will grow down. + node.box.w = node.textLayoutWidth of tsHeight: # Text will grow down. node.box.h = node.textLayoutHeight diff --git a/src/fidget/openglbackend.nim b/src/fidget/openglbackend.nim index e4c7c481..a5026b16 100644 --- a/src/fidget/openglbackend.nim +++ b/src/fidget/openglbackend.nim @@ -125,7 +125,8 @@ proc drawText(node: Node) = if editing: if textBox.size != node.screenBox.wh: textBox.resize(node.screenBox.wh) - node.textLayout = textBox.layout + node.text = keyboard.input + computeTextLayout(node) ctx.saveTransform() ctx.translate(-textBox.scroll) for rect in textBox.selectionRegions(): @@ -193,7 +194,7 @@ proc drawText(node: Node) = let glyphOffset = glyphOffsets[hashFill] - charPos = vec2(pos.rect.x + glyphOffset.x, pos.rect.y + glyphOffset.y) + charPos = pos.rect.xy + glyphOffset if node.strokeWeight > 0 and node.stroke.a > 0: ctx.drawImage( From d96e447236882532fcc877c4b523a1b90419302e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=9B=E5=85=89=E5=B9=B4?= Date: Thu, 9 Feb 2023 01:26:22 +0800 Subject: [PATCH 3/8] 1. better single line text editor 2. get rid of some wraning --- src/fidget/opengl/base.nim | 6 ++++-- src/fidget/openglbackend.nim | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/fidget/opengl/base.nim b/src/fidget/opengl/base.nim index 7956eb96..40cd3d48 100644 --- a/src/fidget/opengl/base.nim +++ b/src/fidget/opengl/base.nim @@ -47,6 +47,8 @@ var cursorGrab*: CursorHandle cursorNSResize*: CursorHandle +proc getWindow*(): staticglfw.Window {.inline.} = window + proc setCursor*(cursor: CursorHandle) = echo "set cursor" window.setCursor(cursor) @@ -247,13 +249,13 @@ proc onSetKey( textBox.delete(shift) of LETTER_C: # copy if ctrl: - base.window.setClipboardString(textBox.copy().cstring) + base.window.setClipboardString(textBox.copy()) of LETTER_V: # paste if ctrl: textBox.paste($base.window.getClipboardString()) of LETTER_X: # cut if ctrl: - base.window.setClipboardString(textBox.cut().cstring) + base.window.setClipboardString(textBox.cut()) of LETTER_A: # select all if ctrl: textBox.selectAll() diff --git a/src/fidget/openglbackend.nim b/src/fidget/openglbackend.nim index a5026b16..5dbb7f3e 100644 --- a/src/fidget/openglbackend.nim +++ b/src/fidget/openglbackend.nim @@ -39,6 +39,7 @@ computeTextLayout = proc(node: Node) = hAlignMode(node.textStyle.textAlignHorizontal), vAlignMode(node.textStyle.textAlignVertical), clip = false, + wrap = false, boundsMin = boundsMin, boundsMax = boundsMax ) @@ -67,7 +68,7 @@ proc focus*(keyboard: Keyboard, node: Node) = hAlignMode(node.textStyle.textAlignHorizontal), vAlignMode(node.textStyle.textAlignVertical), node.multiline, - worldWrap = true, + worldWrap = node.multiline, ) textBox.editable = node.editableText textBox.scrollable = true @@ -125,8 +126,7 @@ proc drawText(node: Node) = if editing: if textBox.size != node.screenBox.wh: textBox.resize(node.screenBox.wh) - node.text = keyboard.input - computeTextLayout(node) + node.textLayout = textBox.layout ctx.saveTransform() ctx.translate(-textBox.scroll) for rect in textBox.selectionRegions(): From 303940261b3e244046d50859187ac0429c4ca7ae Mon Sep 17 00:00:00 2001 From: Luna1996 <2320909844@qq.com> Date: Fri, 10 Feb 2023 16:54:07 +0800 Subject: [PATCH 4/8] 1. more convinient to set box 2. better auto resize 3. eliminate some warning --- src/fidget.nim | 48 ++++++++++++++++++++----- src/fidget/common.nim | 74 ++++++++++++++++++++------------------ src/fidget/opengl/base.nim | 4 +-- 3 files changed, 81 insertions(+), 45 deletions(-) diff --git a/src/fidget.nim b/src/fidget.nim index 7a455bed..728ce652 100644 --- a/src/fidget.nim +++ b/src/fidget.nim @@ -273,13 +273,6 @@ proc orgBox*(x, y, w, h: int|float32|float32) = current.orgBox.w = float32 w current.orgBox.h = float32 h -proc box*(x, y, w, h: float32) = - ## Sets the box dimensions. - current.box.x = x - current.box.y = y - current.box.w = w - current.box.h = h - proc box*( x: int|float32|float64, y: int|float32|float64, @@ -287,14 +280,53 @@ proc box*( h: int|float32|float64 ) = ## Sets the box dimensions with integers + current.box.x = x.float32 + current.box.y = y.float32 + current.box.w = w.float32 + current.box.h = h.float32 ## Always set box before orgBox when doing constraints. - box(float32 x, float32 y, float32 w, float32 h) orgBox(float32 x, float32 y, float32 w, float32 h) proc box*(rect: Rect) = ## Sets the box dimensions with integers box(rect.x, rect.y, rect.w, rect.h) +proc x*(x: int|float32|float64) = + current.box.x = x.float32 + current.orgBox.x = x.float32 + +proc y*(y: int|float32|float64) = + current.box.y = y.float32 + current.orgBox.y = y.float32 + +proc w*(w: int|float32|float64) = + current.box.w = w.float32 + current.orgBox.w = w.float32 + +proc h*(h: int|float32|float64) = + current.box.h = h.float32 + current.orgBox.h = h.float32 + +proc xy*(x, y: int|float32|float64) = + current.box.x = x.float32 + current.box.y = y.float32 + current.orgBox.x = x.float32 + current.orgBox.y = y.float32 + +proc xy*(xy: Vec2) = + current.box.xy = xy + current.orgBox.xy = xy + +proc wh*(w, h: int|float32|float64) = + current.box.w = w.float32 + current.box.h = h.float32 + current.orgBox.w = w.float32 + current.orgBox.h = h.float32 + +proc wh*(wh: Vec2) = + current.box.wh = wh + current.orgBox.wh = wh + proc rotation*(rotationInDeg: float32) = ## Sets rotation in degrees. current.rotation = rotationInDeg diff --git a/src/fidget/common.nim b/src/fidget/common.nim index 9cb49d52..cb5f34cd 100644 --- a/src/fidget/common.nim +++ b/src/fidget/common.nim @@ -443,26 +443,30 @@ proc computeLayout*(parent, node: Node) = var remainHeight = node.box.h - node.verticalPadding * 2 - node.itemSpacing * (node.nodes.len - 1).float32 var totalWeight: float32 - var weightTable: Table[int, float32] + for i, n in node.nodes.pairs: - if n.layoutWeight == 0: - remainHeight -= n.box.h - else: - totalWeight += n.layoutWeight - weightTable[i] = n.layoutWeight - for i, w in weightTable.pairs: - let n = node.nodes[i] - n.box.h = - if remainHeight <= 0: 0.0 - else: remainHeight * w / totalWeight - if n.layoutAlign != laStretch: computeLayout(node, n) - + # set width of stretch + if n.layoutAlign == laStretch: + n.box.w = node.box.w - node.horizontalPadding * 2 + if n.id == "16": echo n.box.w + if n.layoutWeight == 0: computeLayout(node, n) + # record weight + if n.layoutWeight == 0: remainHeight -= n.box.h + else: totalWeight += n.layoutWeight + var at = 0.0 at += node.verticalPadding for i, n in node.nodes: - if i > 0: - at += node.itemSpacing + if i > 0: at += node.itemSpacing + n.box.y = at + + if n.layoutWeight != 0: + n.box.h = + if remainHeight <= 0: 0.0 + else: remainHeight * n.layoutWeight / totalWeight + computeLayout(node, n) + case n.layoutAlign: of laMin: n.box.x = node.horizontalPadding @@ -472,9 +476,7 @@ proc computeLayout*(parent, node: Node) = n.box.x = node.box.w - n.box.w - node.horizontalPadding of laStretch: n.box.x = node.horizontalPadding - n.box.w = node.box.w - node.horizontalPadding * 2 - # Redo the layout for child node. - computeLayout(node, n) + at += n.box.h at += node.verticalPadding if node.wrapContent: node.box.h = at @@ -490,26 +492,30 @@ proc computeLayout*(parent, node: Node) = var remainWidth = node.box.w - node.horizontalPadding * 2 - node.itemSpacing * (node.nodes.len - 1).float32 var totalWeight: float32 - var weightTable: Table[int, float32] + for i, n in node.nodes.pairs: - if n.layoutWeight == 0: - remainWidth -= n.box.w - else: - totalWeight += n.layoutWeight - weightTable[i] = n.layoutWeight - for i, w in weightTable.pairs: - let n = node.nodes[i] - n.box.w = - if remainWidth <= 0: 0.0 - else: remainWidth * w / totalWeight - if n.layoutAlign != laStretch: computeLayout(node, n) + # set width of stretch + if n.layoutAlign == laStretch: + n.box.h = node.box.h - node.verticalPadding * 2 + if n.layoutWeight == 0: computeLayout(node, n) + # record weight + if n.layoutWeight == 0: remainWidth -= n.box.w + else: totalWeight += n.layoutWeight + var at = 0.0 at += node.horizontalPadding for i, n in node.nodes: - if i > 0: - at += node.itemSpacing + if i > 0: at += node.itemSpacing + n.box.x = at + + if n.layoutWeight != 0: + n.box.w = + if remainWidth <= 0: 0.0 + else: remainWidth * n.layoutWeight / totalWeight + computeLayout(node, n) + case n.layoutAlign: of laMin: n.box.y = node.verticalPadding @@ -519,9 +525,7 @@ proc computeLayout*(parent, node: Node) = n.box.y = node.box.h - n.box.h - node.verticalPadding of laStretch: n.box.y = node.verticalPadding - n.box.h = node.box.h - node.verticalPadding * 2 - # Redo the layout for child node. - computeLayout(node, n) + at += n.box.w at += node.horizontalPadding if node.wrapContent: node.box.w = at diff --git a/src/fidget/opengl/base.nim b/src/fidget/opengl/base.nim index 40cd3d48..0cce40eb 100644 --- a/src/fidget/opengl/base.nim +++ b/src/fidget/opengl/base.nim @@ -249,13 +249,13 @@ proc onSetKey( textBox.delete(shift) of LETTER_C: # copy if ctrl: - base.window.setClipboardString(textBox.copy()) + base.window.setClipboardString(textBox.copy().cstring) of LETTER_V: # paste if ctrl: textBox.paste($base.window.getClipboardString()) of LETTER_X: # cut if ctrl: - base.window.setClipboardString(textBox.cut()) + base.window.setClipboardString(textBox.cut().cstring) of LETTER_A: # select all if ctrl: textBox.selectAll() From 42fa9db1339168dae78d1e84ab802c852bd64584 Mon Sep 17 00:00:00 2001 From: Luna1996 <2320909844@qq.com> Date: Fri, 3 Mar 2023 16:48:13 +0800 Subject: [PATCH 5/8] expose window handle --- src/fidget/opengl/base.nim | 4 +++- src/fidget/openglbackend.nim | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/fidget/opengl/base.nim b/src/fidget/opengl/base.nim index 0cce40eb..06195937 100644 --- a/src/fidget/opengl/base.nim +++ b/src/fidget/opengl/base.nim @@ -304,7 +304,7 @@ proc onSetCharCallback(window: staticglfw.Window, character: cuint) {.cdecl.} = keyboard.state = KeyState.Press keyboard.keyString = Rune(character).toUTF8() -proc start*(openglVersion: (int, int), msaa: MSAA, mainLoopMode: MainLoopMode) = +proc start*(openglVersion: (int, int), msaa: MSAA, mainLoopMode: MainLoopMode, hints: openArray[array[0 .. 1, int]]) = if init() == 0: quit("Failed to intialize GLFW.") @@ -319,6 +319,8 @@ proc start*(openglVersion: (int, int), msaa: MSAA, mainLoopMode: MainLoopMode) = windowHint(CONTEXT_VERSION_MAJOR, openglVersion[0].cint) windowHint(CONTEXT_VERSION_MINOR, openglVersion[1].cint) + for hint in hints: windowHint(hint[0].cint, hint[1].cint) + if fullscreen: let monitor = getPrimaryMonitor() diff --git a/src/fidget/openglbackend.nim b/src/fidget/openglbackend.nim index 5dbb7f3e..885ddd10 100644 --- a/src/fidget/openglbackend.nim +++ b/src/fidget/openglbackend.nim @@ -299,11 +299,12 @@ proc setupFidget( msaa: MSAA, mainLoopMode: MainLoopMode, pixelate: bool, - forcePixelScale: float32 + forcePixelScale: float32, + windowHints: openArray[array[0 .. 1, int]] ) = pixelScale = forcePixelScale - base.start(openglVersion, msaa, mainLoopMode) + base.start(openglVersion, msaa, mainLoopMode, windowHints) setWindowTitle(windowTitle) ctx = newContext(pixelate = pixelate, pixelScale = pixelScale) requestedFrame = true @@ -389,7 +390,8 @@ proc startFidget*( msaa = msaaDisabled, mainLoopMode: MainLoopMode = RepaintOnEvent, pixelate = false, - pixelScale = 1.0 + pixelScale = 1.0, + windowHints: openArray[array[0 .. 1, int]] = [] ) = ## Starts Fidget UI library common.fullscreen = fullscreen @@ -398,7 +400,7 @@ proc startFidget*( drawMain = draw tickMain = tick loadMain = load - setupFidget(openglVersion, msaa, mainLoopMode, pixelate, pixelScale) + setupFidget(openglVersion, msaa, mainLoopMode, pixelate, pixelScale, windowHints) mouse.pixelScale = pixelScale when defined(emscripten): # Emscripten can't block so it will call this callback instead. From 70c2fe16aba20197a6a974ec089717ad673d3ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=9B=E5=85=89=E5=B9=B4?= Date: Sun, 5 Mar 2023 23:32:26 +0800 Subject: [PATCH 6/8] image alpha tint --- src/fidget.nim | 1 - src/fidget/common.nim | 3 ++- src/fidget/opengl/base.nim | 13 ++++++------- src/fidget/opengl/context.nim | 2 +- src/fidget/openglbackend.nim | 8 +++++++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/fidget.nim b/src/fidget.nim index 728ce652..668924f6 100644 --- a/src/fidget.nim +++ b/src/fidget.nim @@ -41,7 +41,6 @@ proc preNode(kind: NodeKind, id: string) = current.textStyle = parent.textStyle current.cursorColor = parent.cursorColor current.highlightColor = parent.highlightColor - current.transparency = parent.transparency nodeStack.add(current) inc parent.diffIndex diff --git a/src/fidget/common.nim b/src/fidget/common.nim index cb5f34cd..38498faa 100644 --- a/src/fidget/common.nim +++ b/src/fidget/common.nim @@ -209,6 +209,7 @@ var mouse* = Mouse() keyboard* = Keyboard() requestedFrame*: bool + requestedTick*: bool numNodes*: int popupActive*: bool inPopup*: bool @@ -289,7 +290,7 @@ proc resetToDefault*(node: Node)= # node.screenBox = rect(0,0,0,0) node.textOffset = vec2(0, 0) node.fill = color(0, 0, 0, 0) - node.transparency = 0 + node.transparency = 1 node.strokeWeight = 0 node.stroke = color(0, 0, 0, 0) node.zLevel = 0 diff --git a/src/fidget/opengl/base.nim b/src/fidget/opengl/base.nim index 06195937..f75dc205 100644 --- a/src/fidget/opengl/base.nim +++ b/src/fidget/opengl/base.nim @@ -132,18 +132,17 @@ proc updateLoop*(poll = true) = of RepaintOnEvent: if poll: pollEvents() - if not requestedFrame or minimized: - # Only repaint when necessary - when not defined(emscripten): - sleep(16) + if minimized or not (requestedFrame or (tickMain != nil and requestedTick)): return - requestedFrame = false preInput() - if tickMain != nil: + if tickMain != nil and requestedTick: + requestedTick = false preTick() tickMain() postTick() - drawAndSwap() + if requestedFrame: + requestedFrame = false + drawAndSwap() postInput() of RepaintOnFrame: diff --git a/src/fidget/opengl/context.nim b/src/fidget/opengl/context.nim index a0b25a2f..77d84463 100644 --- a/src/fidget/opengl/context.nim +++ b/src/fidget/opengl/context.nim @@ -424,7 +424,7 @@ proc getOrLoadImageRect(ctx: Context, imagePath: string | Hash): Rect = filePath.add ".png" if hash(filePath) notin ctx.entries: # Need to load imagePath, check to see if the .flippy file is around - echo "[load] ", filePath + # echo "[load] ", filePath if not fileExists(filePath): raise newException(Exception, &"Image '{filePath}' not found") let flippyFilePath = filePath.changeFileExt(".flippy") diff --git a/src/fidget/openglbackend.nim b/src/fidget/openglbackend.nim index 885ddd10..bf119ee6 100644 --- a/src/fidget/openglbackend.nim +++ b/src/fidget/openglbackend.nim @@ -50,6 +50,9 @@ proc refresh*() = ## Request the screen be redrawn requestedFrame = true +proc doTick*() = + requestedTick = true + proc focus*(keyboard: Keyboard, node: Node) = if keyboard.focusNode != node: keyboard.onUnFocusNode = keyboard.focusNode @@ -280,7 +283,10 @@ proc draw*(node: Node) = if node.imageName != "": let path = dataDir / node.imageName - ctx.drawImage(path, size = vec2(node.screenBox.w, node.screenBox.h)) + ctx.drawImage( + path, + color = color(1, 1, 1, node.transparency), + size = vec2(node.screenBox.w, node.screenBox.h)) ctx.restoreTransform() From c60a3b7ad1af47acdb961d1c1194588128f041c9 Mon Sep 17 00:00:00 2001 From: Luna1996 <2320909844@qq.com> Date: Mon, 6 Mar 2023 13:24:32 +0800 Subject: [PATCH 7/8] set root transparency to 1 --- src/fidget/common.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fidget/common.nim b/src/fidget/common.nim index 38498faa..4e9d0efc 100644 --- a/src/fidget/common.nim +++ b/src/fidget/common.nim @@ -335,6 +335,7 @@ proc setupRoot*() = root.uid = newUId() root.highlightColor = parseHtmlColor("#3297FD") root.cursorColor = rgba(0, 0, 0, 255).color + root.transparency = 1 nodeStack = @[root] current = root root.diffIndex = 0 From abe5e8f1234dc3254162646707a0d9b49d557f14 Mon Sep 17 00:00:00 2001 From: Luna1996 <2320909844@qq.com> Date: Wed, 19 Apr 2023 17:51:30 +0800 Subject: [PATCH 8/8] better round rect --- src/fidget/opengl/context.nim | 20 ++++++++++++-------- src/fidget/openglbackend.nim | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/fidget/opengl/context.nim b/src/fidget/opengl/context.nim index 77d84463..db9f8841 100644 --- a/src/fidget/opengl/context.nim +++ b/src/fidget/opengl/context.nim @@ -519,14 +519,16 @@ proc fillRect*(ctx: Context, rect: Rect, color: Color) = uvRect.xy + uvRect.wh / 2, color ) -proc fillRoundedRect*(ctx: Context, rect: Rect, color: Color, radius: float32) = +proc fillRoundedRect*(ctx: Context, rect: Rect, color: Color, nw, ne, se, sw: float32) = # TODO: Make this a 9 patch - let radius = min(radius, min(rect.w/2, rect.h/2)) let hash = hash(( 6118, rect.w.int, rect.h.int, - (radius*100).int + (nw*100).int, + (ne*100).int, + (se*100).int, + (sw*100).int, )) let @@ -539,7 +541,7 @@ proc fillRoundedRect*(ctx: Context, rect: Rect, color: Color, radius: float32) = c.fillStyle = rgba(255, 255, 255, 255) c.fillRoundedRect( rect(0, 0, rect.w, rect.h), - radius + nw, ne, se, sw ) ctx.putImage(hash, image) @@ -555,15 +557,17 @@ proc fillRoundedRect*(ctx: Context, rect: Rect, color: Color, radius: float32) = ) proc strokeRoundedRect*( - ctx: Context, rect: Rect, color: Color, weight: float32, radius: float32 + ctx: Context, rect: Rect, color: Color, weight: float32, nw, ne, se, sw: float32 ) = - let radius = min(radius, min(rect.w/2, rect.h/2)) # TODO: Make this a 9 patch let hash = hash(( 8349, rect.w.int, rect.h.int, - (radius*100).int + (nw*100).int, + (ne*100).int, + (se*100).int, + (sw*100).int, )) let @@ -577,7 +581,7 @@ proc strokeRoundedRect*( c.lineWidth = weight c.strokeRoundedRect( rect(weight / 2, weight / 2, rect.w - weight, rect.h - weight), - radius + nw, ne, se, sw ) ctx.putImage(hash, image) let diff --git a/src/fidget/openglbackend.nim b/src/fidget/openglbackend.nim index bf119ee6..a97bc1b4 100644 --- a/src/fidget/openglbackend.nim +++ b/src/fidget/openglbackend.nim @@ -251,7 +251,11 @@ proc draw*(node: Node) = ctx.fillRoundedRect(rect( 0, 0, node.screenBox.w, node.screenBox.h - ), rgba(255, 0, 0, 255).color, node.cornerRadius[0]) + ), rgba(255, 0, 0, 255).color, + node.cornerRadius[0], + node.cornerRadius[1], + node.cornerRadius[2], + node.cornerRadius[3]) else: ctx.fillRect(rect( 0, 0, @@ -268,7 +272,11 @@ proc draw*(node: Node) = ctx.fillRoundedRect(rect( 0, 0, node.screenBox.w, node.screenBox.h - ), node.fill, node.cornerRadius[0]) + ), node.fill, + node.cornerRadius[0], + node.cornerRadius[1], + node.cornerRadius[2], + node.cornerRadius[3]) else: ctx.fillRect(rect( 0, 0, @@ -279,7 +287,11 @@ proc draw*(node: Node) = ctx.strokeRoundedRect(rect( 0, 0, node.screenBox.w, node.screenBox.h - ), node.stroke, node.strokeWeight, node.cornerRadius[0]) + ), node.stroke, node.strokeWeight, + node.cornerRadius[0], + node.cornerRadius[1], + node.cornerRadius[2], + node.cornerRadius[3]) if node.imageName != "": let path = dataDir / node.imageName