Skip to content

Commit 753ebe9

Browse files
committed
each view has a window assigned at init
1 parent 6e98eae commit 753ebe9

File tree

83 files changed

+1479
-1170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1479
-1170
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ nakefile
33
test/main
44
*.exe
55
build/
6+
.debug
7+
.vscode

doc/context.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Context
2+
=======
3+
4+
WindowView
5+
----------
6+
7+
Interfaces with window and graphics backend.
8+
9+
Each view has a graphics context.
10+
11+
TODO: The context may be unique or shared between windows depending on backend.
12+
13+
A view may need app data and backend data to properly initialize itself.
14+
15+
Some backends (js) do not currently support sharing between opengl contexts.
16+
17+

editor/nakefile.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ preprocessResources = proc(b: Builder) =
1111
let sf = f.splitFile()
1212
if sf.ext == ".nimx":
1313
b.copyResourceAsIs(f.replace("res/", ""))
14+
15+
task "debug", "Build for debugging":
16+
let b = newBuilder()
17+
b.additionalNimFlags.add "--debugger:on"
18+
b.runAfterBuild = false
19+
b.build()

nakefile.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,9 @@ task "docs", "Build documentation":
3434
direShell "nim rst2html " & f & " &>/dev/null"
3535

3636
copyDir "../js", "./livedemo"
37+
38+
task "debug", "Build for debugging":
39+
let b = newBuilder()
40+
b.additionalNimFlags.add "--debugger:on"
41+
b.runAfterBuild = false
42+
b.build()

nimx/abstract_window.nim

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,20 @@ method drawWindow*(w: Window) {.base.} =
8383
w.needsDisplay = false
8484

8585
w.recursiveDrawSubviews()
86-
let c = currentContext()
86+
let c = w.gfxCtx
8787

8888
let profiler = sharedProfiler()
8989
if profiler.enabled:
9090
updateFps()
91-
profiler["Overdraw"] = GetOverdrawValue()
92-
profiler["DIPs"] = GetDIPValue()
91+
profiler["Overdraw"] = getOverdrawValue(w.gfxCtx)
92+
profiler["DIPs"] = getDIPValue(w.gfxCtx)
9393
profiler["Animations"] = totalAnims
9494

9595
const fontSize = 14
9696
const profilerWidth = 110
97-
var font = systemFont()
97+
var font = systemFont(c.fontCtx)
9898
let old_size = font.size
99-
font.size = fontSize
99+
`size=`(font, c.fontCtx, fontSize)
100100
var rect = newRect(w.frame.width - profilerWidth, 5, profilerWidth - 5, Coord(profiler.len) * font.height)
101101
c.fillColor = newGrayColor(1, 0.8)
102102
c.strokeWidth = 0
@@ -108,9 +108,9 @@ method drawWindow*(w: Window) {.base.} =
108108
pt.x = w.frame.width - profilerWidth
109109
c.drawText(font, pt, k & ": " & v)
110110
pt.y = pt.y + fontSize
111-
font.size = old_size
112-
ResetOverdrawValue()
113-
ResetDIPValue()
111+
`size=`(font, c.fontCtx, old_size)
112+
resetOverdrawValue(c)
113+
resetDIPValue(c)
114114

115115
let dc = currentDragSystem()
116116
if not dc.pItem.isNil:
@@ -125,8 +125,7 @@ method drawWindow*(w: Window) {.base.} =
125125
c.drawRect(rect)
126126

127127
method draw*(w: Window, rect: Rect) =
128-
let c = currentContext()
129-
let gl = c.gl
128+
let gl = w.gfxCtx.gl
130129
if w.mActiveBgColor != w.backgroundColor:
131130
gl.clearColor(w.backgroundColor.r, w.backgroundColor.g, w.backgroundColor.b, w.backgroundColor.a)
132131
w.mActiveBgColor = w.backgroundColor
@@ -207,8 +206,8 @@ var newFullscreenWindow*: proc(): Window
207206
var newWindowWithNative*: proc(handle: pointer, r: Rect): Window
208207
var newFullscreenWindowWithNative*: proc(handle: pointer): Window
209208

210-
method init*(w: Window, frame: Rect) =
211-
procCall w.View.init(frame)
209+
method init*(w: Window, _: Window, frame: Rect) =
210+
procCall w.View.init(w, frame)
212211
w.window = w
213212
w.needsDisplay = true
214213
w.mCurrentTouches = newTable[int, View]()

nimx/button.nim

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -52,38 +52,38 @@ Button.properties:
5252
imageMarginLeft
5353
image
5454

55-
proc newButton*(r: Rect): Button =
55+
proc newButton*(w: Window, r: Rect): Button =
5656
result.new()
57-
result.init(r)
57+
result.init(w, r)
5858

59-
proc newButton*(parent: View = nil, position: Point = newPoint(0, 0), size: Size = newSize(100, 20), title: string = "Button"): Button =
60-
result = newButton(newRect(position.x, position.y, size.width, size.height))
59+
proc newButton*(parent: View = nil, w: Window, position: Point = newPoint(0, 0), size: Size = newSize(100, 20), title: string = "Button"): Button =
60+
result = newButton(w, newRect(position.x, position.y, size.width, size.height))
6161
result.title = title
6262
if not isNil(parent):
6363
parent.addSubview(result)
6464

65-
proc newCheckbox*(r: Rect): Button =
66-
result = newButton(r)
65+
proc newCheckbox*(w: Window, r: Rect): Button =
66+
result = newButton(w, r)
6767
result.style = bsCheckbox
6868
result.behavior = bbToggle
6969

70-
proc newRadiobox*(r: Rect): Button =
71-
result = newButton(r)
70+
proc newRadiobox*(w: Window, r: Rect): Button =
71+
result = newButton(w, r)
7272
result.style = bsRadiobox
7373
result.behavior = bbToggle
7474

75-
proc newImageButton*(r: Rect): Button =
76-
result = newButton(r)
75+
proc newImageButton*(w: Window, r: Rect): Button =
76+
result = newButton(w, r)
7777
result.style = bsImage
7878

79-
proc newImageButton*(parent: View = nil, position: Point = newPoint(0, 0), size: Size = newSize(100, 20), image: Image = nil): Button =
80-
result = newImageButton(newRect(position.x, position.y, size.width, size.height))
79+
proc newImageButton*(parent: View = nil, w: Window, position: Point = newPoint(0, 0), size: Size = newSize(100, 20), image: Image = nil): Button =
80+
result = newImageButton(w, newRect(position.x, position.y, size.width, size.height))
8181
result.image = image
8282
if not isNil(parent):
8383
parent.addSubview(result)
8484

85-
method init*(b: Button, frame: Rect) =
86-
procCall b.Control.init(frame)
85+
method init*(b: Button, w: Window, frame: Rect) =
86+
procCall b.Control.init(w, frame)
8787
b.state = bsUp
8888
b.enabled = true
8989
b.backgroundColor = whiteColor()
@@ -93,29 +93,31 @@ method init*(b: Button, frame: Rect) =
9393
b.imageMarginTop = 2
9494
b.imageMarginBottom = 2
9595

96-
method init*(b: Checkbox, frame: Rect) =
97-
procCall b.Button.init(frame)
96+
method init*(b: Checkbox, w: Window, frame: Rect) =
97+
procCall b.Button.init(w, frame)
9898
b.style = bsCheckbox
9999
b.behavior = bbToggle
100100

101-
method init*(b: Radiobox, frame: Rect) =
102-
procCall b.Button.init(frame)
101+
method init*(b: Radiobox, w: Window, frame: Rect) =
102+
procCall b.Button.init(w, frame)
103103
b.style = bsRadiobox
104104
b.behavior = bbToggle
105105

106106
proc drawTitle(b: Button, xOffset: Coord) =
107+
template gfxCtx: untyped = b.window.gfxCtx
108+
template fontCtx: untyped = b.window.gfxCtx.fontCtx
109+
template gl: untyped = b.window.gfxCtx.gl
107110
if b.title.len != 0:
108-
let c = currentContext()
109-
c.fillColor = if b.state == bsDown and b.style == bsRegular:
111+
gfxCtx.fillColor = if b.state == bsDown and b.style == bsRegular:
110112
whiteColor()
111113
else:
112114
blackColor()
113115

114-
let font = systemFont()
116+
let font = systemFont(fontCtx)
115117
var titleRect = b.bounds
116-
var pt = centerInRect(font.sizeOfString(b.title), titleRect)
118+
var pt = centerInRect(sizeOfString(fontCtx, gl, font, b.title), titleRect)
117119
if pt.x < xOffset: pt.x = xOffset
118-
c.drawText(font, pt, b.title)
120+
gfxCtx.drawText(font, pt, b.title)
119121

120122
var regularButtonComposition = newComposition """
121123
uniform vec4 uStrokeColor;
@@ -134,7 +136,7 @@ void compose() {
134136
"""
135137

136138
proc drawRegularBezel(b: Button) =
137-
regularButtonComposition.draw b.bounds:
139+
draw b.window.gfxCtx, regularButtonComposition, b.bounds:
138140
if b.state == bsUp:
139141
setUniform("uStrokeColor", newGrayColor(0.78))
140142
setUniform("uFillColorStart", if b.enabled: b.backgroundColor else: grayColor())
@@ -162,10 +164,10 @@ proc drawCheckboxStyle(b: Button, r: Rect) =
162164
let
163165
size = b.bounds.height
164166
bezelRect = newRect(0, 0, size, size)
165-
c = currentContext()
167+
c = b.window.gfxCtx
166168

167169
if b.value != 0:
168-
checkButtonComposition.draw bezelRect:
170+
draw c, checkButtonComposition, bezelRect:
169171
setUniform("uStrokeColor", selectionColor)
170172
setUniform("uFillColor", selectionColor)
171173
setUniform("uRadius", 4.0)
@@ -182,7 +184,7 @@ proc drawCheckboxStyle(b: Button, r: Rect) =
182184
c.drawLine(newPoint(size / 4.0, size * 1.0 / 2.0), newPoint(size / 4.0 * 2.0, size * 1.0 / 2.0 + size / 5.0 - c.strokeWidth / 2.0))
183185
c.drawLine(newPoint(size / 4.0 * 2.0 - c.strokeWidth / 2.0, size * 1.0 / 2.0 + size / 5.0), newPoint(size / 4.0 * 3.0 - c.strokeWidth / 2.0, size / 4.0))
184186
else:
185-
checkButtonComposition.draw bezelRect:
187+
draw c, checkButtonComposition, bezelRect:
186188
setUniform("uStrokeColor", newGrayColor(0.78))
187189
setUniform("uFillColor", whiteColor())
188190
setUniform("uRadius", 4.0)
@@ -206,16 +208,17 @@ void compose() {
206208

207209
proc drawRadioboxStyle(b: Button, r: Rect) =
208210
let bezelRect = newRect(0, 0, b.bounds.height, b.bounds.height)
211+
let c = b.window.gfxCtx
209212

210213
# Selected
211214
if b.value != 0:
212-
radioButtonComposition.draw bezelRect:
215+
draw c, radioButtonComposition, bezelRect:
213216
setUniform("uStrokeColor", selectionColor)
214217
setUniform("uFillColor", selectionColor)
215218
setUniform("uRadioValue", bezelRect.height * 0.3)
216219
setUniform("uStrokeWidth", 0.0)
217220
else:
218-
radioButtonComposition.draw bezelRect:
221+
draw c, radioButtonComposition, bezelRect:
219222
setUniform("uStrokeColor", newGrayColor(0.78))
220223
setUniform("uFillColor", whiteColor())
221224
setUniform("uRadioValue", 1.0)
@@ -224,7 +227,7 @@ proc drawRadioboxStyle(b: Button, r: Rect) =
224227
b.drawTitle(bezelRect.width + 1)
225228

226229
proc drawImage(b: Button) =
227-
let c = currentContext()
230+
let c = b.window.gfxCtx
228231
let r = b.bounds
229232
if b.imageMarginLeft != 0 or b.imageMarginRight != 0 or
230233
b.imageMarginTop != 0 or b.imageMarginBottom != 0:
@@ -315,12 +318,8 @@ method onTouchEv*(b: Button, e: var Event): bool =
315318
result = b.handleToggleTouchEv(e)
316319

317320
registerClass(Button)
318-
319-
const checkBox = proc(): RootRef= newCheckbox(zeroRect)
320-
registerClass(Checkbox, checkBox)
321-
322-
const radiButton = proc(): RootRef = newRadiobox(zeroRect)
323-
registerClass(Radiobox, radiButton)
321+
registerClass(Checkbox)
322+
registerClass(Radiobox)
324323

325324
genVisitorCodeForView(Button)
326325
genVisitorCodeForView(Checkbox)

nimx/class_registry.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,13 @@ template registerClass*(a: typedesc) =
9696
return res
9797
registerClass(a, c)
9898

99-
template isClassRegistered*(name: string): bool = name in classFactory
100-
10199
proc newObjectOfClass*(name: string): RootRef =
102100
let c = classFactory.getOrDefault(name)
103101
if c.creatorProc.isNil: raise newException(Exception, "Class '" & name & "' is not registered")
104102
result = c.creatorProc()
105103

104+
template isClassRegistered*(name: string): bool = name in classFactory
105+
106106
iterator registeredClasses*(): string =
107107
for k in classFactory.keys: yield k
108108

nimx/clip_view.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import nimx / meta_extensions / [ property_desc, visitors_gen, serializers_gen ]
33

44
type ClipView* = ref object of View
55

6-
proc newClipView*(r: Rect): ClipView =
6+
proc newClipView*(w: Window, r: Rect): ClipView =
77
result.new()
8-
result.init(r)
8+
result.init(w, r)
99
result.autoresizingMask = { afFlexibleWidth, afFlexibleHeight }
1010

1111
method subviewDidChangeDesiredSize*(v: ClipView, sub: View, desiredSize: Size) =

nimx/collection_view.nim

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ const
4040

4141
proc updateLayout*(v: CollectionView)
4242

43-
proc newCollectionView*(r: Rect, itemSize: Size, layoutDirection: LayoutDirection, layoutWidth: int = LayoutWidthAuto): CollectionView =
43+
proc newCollectionView*(w: Window, r: Rect, itemSize: Size, layoutDirection: LayoutDirection, layoutWidth: int = LayoutWidthAuto): CollectionView =
4444
## CollectionView constructor
4545
result.new()
4646
result.layoutDirection = layoutDirection
4747
result.layoutWidth = layoutWidth
4848
result.itemSize = itemSize
49-
result.init(r)
49+
result.init(w, r)
5050

5151
method clipType*(v: CollectionView): ClipType = ctDefaultClip
5252

@@ -162,8 +162,8 @@ proc updateLayout*(v: CollectionView) =
162162
v.scrollOffset = 0.0
163163
v.update()
164164

165-
method init*(v: CollectionView, r: Rect) =
166-
procCall v.View.init(r)
165+
method init*(v: CollectionView, w: Window, r: Rect) =
166+
procCall v.View.init(w, r)
167167
v.rangeCache.dirty = true
168168
v.offset = 2.0
169169
let scrollListener = new(CollectionScrollListener)
@@ -204,7 +204,6 @@ CollectionView.properties:
204204
layoutWidth
205205
itemSize
206206

207-
const collectionCreator = proc(): RootRef = newCollectionView(zeroRect, zeroSize, LeftToRight)
208-
registerClass(CollectionView, collectionCreator)
207+
registerClass(CollectionView)
209208
genVisitorCodeForView(CollectionView)
210209
genSerializeCodeForView(CollectionView)

0 commit comments

Comments
 (0)