On the train to Wien
This commit is contained in:
parent
f344b29e1e
commit
b28583c1ff
|
@ -1,4 +1,2 @@
|
||||||
include_rules
|
include_rules
|
||||||
: well_of_text.nim |> !nim_bin |> {bin}
|
: well_of_text.nim |> !nim_bin |> {bin}
|
||||||
: text_spans.nim |> !nim_bin |> {bin}
|
|
||||||
: wells.nim |> !nim_bin |> {bin}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[asyncdispatch, options, os, tables]
|
import std/[asyncdispatch, options, os, streams, tables]
|
||||||
import preserves, syndicate, syndicate/[capabilities]
|
import preserves, syndicate, syndicate/[capabilities]
|
||||||
import bumpy, pixie
|
import bumpy, pixie
|
||||||
import sdl2
|
import sdl2
|
||||||
|
@ -59,10 +59,9 @@ func rect(img: Image): bumpy.Rect =
|
||||||
proc newApp(length: cint): App =
|
proc newApp(length: cint): App =
|
||||||
## Create a new square plane of `length` pixels.
|
## Create a new square plane of `length` pixels.
|
||||||
result = App(
|
result = App(
|
||||||
topFrame: newFrame(length shl 1, length shl 1),
|
well: newWell(length, length),
|
||||||
zoomFactor: 1.0,
|
zoomFactor: 1.0,
|
||||||
)
|
)
|
||||||
app.well = newWell(length, length)
|
|
||||||
discard createWindowAndRenderer(
|
discard createWindowAndRenderer(
|
||||||
length, length,
|
length, length,
|
||||||
SDL_WINDOW_RESIZABLE,
|
SDL_WINDOW_RESIZABLE,
|
||||||
|
@ -88,13 +87,14 @@ proc redraw(app: App) =
|
||||||
app.renderer.setDrawColor(0x80, 0x80, 0x80)
|
app.renderer.setDrawColor(0x80, 0x80, 0x80)
|
||||||
app.renderer.clear()
|
app.renderer.clear()
|
||||||
|
|
||||||
let wellRect = well.Rect
|
let wellRect = app.well.rect
|
||||||
if viewPort.overlaps wellRect:
|
if viewPort.overlaps wellRect:
|
||||||
for (pane, rect) in well.intersectingPanes(viewPort)
|
for (index, rect) in app.well.intersectingPanes(viewPort):
|
||||||
|
let texture = app.well.texture(index, app.renderer, rect.wh * app.zoomFactor)
|
||||||
|
if texture.isNil: break
|
||||||
let
|
let
|
||||||
texture = pane.texture(rect.wh *app.zoomFactor)
|
|
||||||
overlap = viewPort and rect
|
overlap = viewPort and rect
|
||||||
src = rect(overlap.xy - app.rect.xy, overlap.wh)
|
src = rect(overlap.xy - rect.xy, overlap.wh)
|
||||||
var dst: bumpy.Rect
|
var dst: bumpy.Rect
|
||||||
dst.x = (overlap.x - viewPort.x) * (sdlViewPort.w / viewPort.w)
|
dst.x = (overlap.x - viewPort.x) * (sdlViewPort.w / viewPort.w)
|
||||||
dst.y = (overlap.y - viewPort.y) * (sdlViewPort.h / viewPort.h)
|
dst.y = (overlap.y - viewPort.y) * (sdlViewPort.h / viewPort.h)
|
||||||
|
@ -107,6 +107,8 @@ proc redraw(app: App) =
|
||||||
overlap.wh * app.zoomFactor
|
overlap.wh * app.zoomFactor
|
||||||
var (sdlSrc, sdlDst) = (src.toSdl, dst.toSdl)
|
var (sdlSrc, sdlDst) = (src.toSdl, dst.toSdl)
|
||||||
app.renderer.copy(texture, addr sdlSrc, addr sdlDst)
|
app.renderer.copy(texture, addr sdlSrc, addr sdlDst)
|
||||||
|
else:
|
||||||
|
echo "no overlap of ", viewPort, " and ", wellRect
|
||||||
app.renderer.present()
|
app.renderer.present()
|
||||||
|
|
||||||
proc resize(app: App) =
|
proc resize(app: App) =
|
||||||
|
@ -126,18 +128,6 @@ proc recenter(app: App) =
|
||||||
app.zoomFactor = 1.0
|
app.zoomFactor = 1.0
|
||||||
app.redraw()
|
app.redraw()
|
||||||
|
|
||||||
proc setImage(app: App; image: Image) =
|
|
||||||
app.rect = image.rect
|
|
||||||
echo "create surface of ", image.width, "x", cint image.height, " pixels"
|
|
||||||
var
|
|
||||||
dataPtr = image.data[0].addr
|
|
||||||
surface = createRGBSurfaceFrom(
|
|
||||||
dataPtr,
|
|
||||||
cint image.width, cint image.height,
|
|
||||||
cint 32, cint 4*image.width,
|
|
||||||
rmask, gmask, bmask, amask)
|
|
||||||
app.texture = createTextureFromSurface(app.renderer, surface)
|
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
|
|
||||||
discard sdl2.init(INIT_TIMER or INIT_VIDEO or INIT_EVENTS)
|
discard sdl2.init(INIT_TIMER or INIT_VIDEO or INIT_EVENTS)
|
||||||
|
@ -145,7 +135,8 @@ proc main() =
|
||||||
|
|
||||||
let
|
let
|
||||||
typeface = readTypeface(typefacePath)
|
typeface = readTypeface(typefacePath)
|
||||||
fontTODO = newFont(typeface, 48)
|
font = newFont(typeface)
|
||||||
|
# TODO
|
||||||
|
|
||||||
app.redraw()
|
app.redraw()
|
||||||
|
|
||||||
|
@ -164,15 +155,17 @@ proc main() =
|
||||||
sdlTimeout = 500
|
sdlTimeout = 500
|
||||||
asyncPollTimeout = 500
|
asyncPollTimeout = 500
|
||||||
|
|
||||||
let streamTODO = newFileStream(stdin)
|
let stream = newFileStream(stdin)
|
||||||
|
# TODO
|
||||||
|
|
||||||
var
|
var
|
||||||
evt = sdl2.defaultEvent
|
evt = sdl2.defaultEvent
|
||||||
mousePanning: bool
|
mousePanning: bool
|
||||||
lineTODO: string
|
line: string
|
||||||
while true:
|
while true:
|
||||||
if readLine(streamTODO, lineTODO):
|
if readLine(stream, line):
|
||||||
app.well.append(line, fontTODO)
|
# TODO
|
||||||
|
app.well.append(line, font)
|
||||||
app.redraw()
|
app.redraw()
|
||||||
# asyncdispatch.poll(0)
|
# asyncdispatch.poll(0)
|
||||||
if waitEventTimeout(evt, sdlTimeout):
|
if waitEventTimeout(evt, sdlTimeout):
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[deques]
|
import std/[deques, streams]
|
||||||
import pixie
|
import bumpy, pixie, sdl2
|
||||||
|
|
||||||
type
|
type
|
||||||
|
Rect = bumpy.Rect
|
||||||
|
|
||||||
Pane* = ref object
|
Pane* = ref object
|
||||||
image: pixie.Image
|
image: pixie.Image
|
||||||
spans: seq[Span]
|
spans: seq[Span]
|
||||||
|
@ -24,12 +26,12 @@ proc newWell*(width, height: int): Well =
|
||||||
|
|
||||||
proc margins*(well): Vec2 = well.dimensions / 9.0
|
proc margins*(well): Vec2 = well.dimensions / 9.0
|
||||||
|
|
||||||
proc bounds*(well): Vec2 = well.margin * 7.0
|
proc bounds*(well): Vec2 = well.margins * 7.0
|
||||||
|
|
||||||
proc rect*(well): Rect =
|
proc rect*(well): Rect =
|
||||||
result.wh = well.dimensions
|
result.wh = well.dimensions
|
||||||
|
|
||||||
proc rectAt(well, offset:int):Rect =
|
proc rectAt(well; offset: int): Rect =
|
||||||
if offset < well.panes.len:
|
if offset < well.panes.len:
|
||||||
let n = succ offset
|
let n = succ offset
|
||||||
result.w = well.dimensions.x / float(2 * n)
|
result.w = well.dimensions.x / float(2 * n)
|
||||||
|
@ -52,14 +54,14 @@ proc append*(well; text: string; font: Font) =
|
||||||
assert well.panes.len > 0
|
assert well.panes.len > 0
|
||||||
let span = newSpan(text, font)
|
let span = newSpan(text, font)
|
||||||
while true:
|
while true:
|
||||||
pane = well.panes[0]
|
let pane = well.panes[0]
|
||||||
pane.spans.add(span)
|
pane.spans.add(span)
|
||||||
var
|
var
|
||||||
arrangement = typeset(spans, frame.bounds)
|
arrangement = typeset(pane.spans, well.bounds)
|
||||||
bounds = layoutBounds arrangement
|
bounds = layoutBounds arrangement
|
||||||
assert bounds.x <= well.boundx.x
|
# assert bounds.x <= well.bounds.x
|
||||||
if bounds.bounds.y <= well.bounds.y:
|
if bounds.y <= well.bounds.y:
|
||||||
doAssert pane.spans.len > 1, "text does not find on a single pane"
|
doAssert pane.spans.len > 0, "text does not find on a single pane - " & $bounds & $well.bounds
|
||||||
pane.arrangement = arrangement
|
pane.arrangement = arrangement
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -70,6 +72,7 @@ proc append*(well; stream: Stream; font: Font) =
|
||||||
while readLine(stream, line):
|
while readLine(stream, line):
|
||||||
append(well, line, font)
|
append(well, line, font)
|
||||||
|
|
||||||
|
#[
|
||||||
proc render*(well; index: Natural; scale: float): Image =
|
proc render*(well; index: Natural; scale: float): Image =
|
||||||
if index < well.panes.len:
|
if index < well.panes.len:
|
||||||
let dimensions = well.dimensions * scale
|
let dimensions = well.dimensions * scale
|
||||||
|
@ -77,17 +80,41 @@ proc render*(well; index: Natural; scale: float): Image =
|
||||||
result = newImage(int dimensions.x, int dimensions.y)
|
result = newImage(int dimensions.x, int dimensions.y)
|
||||||
fill(result, rgba(255, 255, 255, 255))
|
fill(result, rgba(255, 255, 255, 255))
|
||||||
fillText(well.panes[index].arrangment, translate(well.margin))
|
fillText(well.panes[index].arrangment, translate(well.margin))
|
||||||
|
]#
|
||||||
|
|
||||||
|
iterator intersectingPanes*(well; rect: Rect): (int, Rect) =
|
||||||
iterator intersectingPanes(well; rect:Rect): (Pane, Rect) =
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while i <well.panes.len:
|
while i < well.panes.len:
|
||||||
let bounds = well.boundsAt(i)
|
let bounds = well.rectAt(i)
|
||||||
if i and 3:
|
if (i and 3) == 3:
|
||||||
let quad = Rect(0, 0, bounds.x *2.0, bounds.y * 2.0)
|
let quad = rect(vec2(0,0), bounds.wh * 2.0)
|
||||||
if not rect.overlaps quad:
|
if not rect.overlaps quad:
|
||||||
# all further panes are non-intersecting
|
# all further panes are non-intersecting
|
||||||
break
|
break
|
||||||
if rect.overlaps bounds:
|
if rect.overlaps bounds:
|
||||||
yield (well.panes[i], bounds)
|
yield (i, bounds)
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
|
const
|
||||||
|
amask = uint32 0xff000000
|
||||||
|
rmask = uint32 0x000000ff
|
||||||
|
gmask = uint32 0x0000ff00
|
||||||
|
bmask = uint32 0x00ff0000
|
||||||
|
|
||||||
|
proc texture*(well; index: int; renderer: RendererPtr; wh: Vec2): TexturePtr =
|
||||||
|
# TODO:caching
|
||||||
|
if index >= well.panes.len or wh.x < 4 or wh.y < 4: return nil
|
||||||
|
let pane = well.panes[index]
|
||||||
|
let
|
||||||
|
image = newImage(wh.x.int, wh.y.int)
|
||||||
|
zoom = wh / well.dimensions
|
||||||
|
margin = wh / 9.0
|
||||||
|
if not pane.arrangement.isNil:
|
||||||
|
image.fillText(pane.arrangement, scale(zoom) * translate(margin))
|
||||||
|
var surface = createRGBSurfaceFrom(
|
||||||
|
image.data[0].addr, wh.x.cint, wh.y.cint, cint 32, 4 * wh.x.cint,
|
||||||
|
rmask, gmask, bmask, amask,
|
||||||
|
)
|
||||||
|
result = createTextureFromSurface(renderer, surface)
|
||||||
|
destroy(surface)
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,4 @@ bin = @["well_of_text"]
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
requires: "nim", "syndicate", "sdl2"
|
requires: "nim", "syndicate", "sdl2"
|
||||||
srcDir = "src"
|
srcDir = "src"
|
||||||
version = "20230906"
|
version = "20230908"
|
||||||
|
|
Loading…
Reference in New Issue