dynamic sizing

This commit is contained in:
2026-01-05 14:41:26 -06:00
parent 3b44c20469
commit a107a268f7
2 changed files with 82 additions and 57 deletions

121
main.go
View File

@@ -20,37 +20,56 @@ import (
var ( var (
snapshotsPath string snapshotsPath string
storage *Storage storage *Storage
sourceWidth, sourceHeight int
targetWidth, targetHeight int
) )
func bootstrap() { type Layout struct {
monitor rl.RectangleInt32
window rl.RectangleInt32
controls rl.RectangleInt32
viewport rl.RectangleInt32
graphics rl.RectangleInt32
}
func bootstrap() Layout {
rl.InitWindow(800, 600, "bootstrap") rl.InitWindow(800, 600, "bootstrap")
monitor := rl.GetCurrentMonitor() monitor := rl.GetCurrentMonitor()
fmt.Printf("Using monitor %d\n", monitor) fmt.Printf("Using monitor %d\n", monitor)
// derive defaults from the monitor size
monitorWidth := rl.GetMonitorWidth(monitor) monitorWidth := rl.GetMonitorWidth(monitor)
monitorHeight := rl.GetMonitorHeight(monitor) monitorHeight := rl.GetMonitorHeight(monitor)
defaultTargetWidth := int(float32(monitorWidth) * 0.95) // use a large portion of the available space, but not all of it!
defaultTargetHeight := int(float32(monitorHeight) * 0.9) defaultWindowWidth := int(float32(monitorWidth) * 0.95)
defaultSourceWidth := 5*defaultTargetWidth defaultWindowHeight := int(float32(monitorHeight) * 0.9)
defaultSourceHeight := 5*defaultTargetHeight windowWidth := defaultWindowWidth
windowHeight := defaultWindowHeight
// set controls to use 1/6th of the width
controlsRelWidth := 1.0 / 12.0
defaultGraphicsWidth := 5*int((float64(defaultWindowWidth)*(1.0-controlsRelWidth)))
defaultGraphicsHeight := 5*defaultWindowHeight
graphicsWidth := defaultGraphicsWidth
graphicsHeight := defaultGraphicsHeight
fmt.Printf("monitor : %d x %d / window : %d x %d / buffer : %d x %d", fmt.Printf("monitor : %d x %d / window : %d x %d / buffer : %d x %d",
monitorWidth, monitorHeight, monitorWidth, monitorHeight,
defaultTargetWidth, defaultTargetHeight, defaultWindowWidth, defaultWindowHeight,
defaultSourceWidth, defaultSourceHeight) defaultGraphicsWidth, defaultWindowHeight)
flag.StringVar(&snapshotsPath, "path", "snapshots", "Path to snapshots and db") flag.StringVar(&snapshotsPath, "path", "snapshots", "Path to snapshots and db")
flag.IntVar(&sourceWidth, "bw", defaultSourceWidth, "Width of the internal graphics source") flag.IntVar(&graphicsWidth, "gw", defaultGraphicsWidth, "Width of the internal graphics buffer. Can be much larger than the screen.")
flag.IntVar(&sourceHeight, "bh", defaultSourceHeight, "Height of the internal graphics source") flag.IntVar(&graphicsHeight, "gh", defaultGraphicsHeight, "Height of the internal graphics buffer. Can be much larger than the screen.")
flag.IntVar(&targetWidth, "w", defaultTargetWidth, "Width of the display window") flag.IntVar(&windowWidth, "w", defaultWindowWidth, "Width of the display window")
flag.IntVar(&targetHeight, "h", defaultTargetHeight, "Height of the display window") flag.IntVar(&windowHeight, "h", defaultWindowHeight, "Height of the display window")
flag.Parse() flag.Parse()
controlsWidth := int(float64(windowWidth) * controlsRelWidth)
viewportWidth := windowWidth - controlsWidth
rl.CloseWindow() rl.CloseWindow()
log.Printf("Storing snapshots at '%s'\n", snapshotsPath) log.Printf("Storing snapshots at '%s'\n", snapshotsPath)
@@ -62,16 +81,24 @@ func bootstrap() {
log.Printf("Error loading storage: %v\n", err) log.Printf("Error loading storage: %v\n", err)
os.Exit(1) os.Exit(1)
} }
return Layout {
monitor: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(monitorWidth), Height: int32(monitorHeight) },
window: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(windowWidth), Height: int32(windowHeight) },
controls: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(controlsWidth), Height: int32(windowHeight) },
viewport: rl.RectangleInt32{ X: int32(controlsWidth), Y: 0, Width: int32(viewportWidth), Height: int32(windowHeight) },
graphics: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(graphicsWidth), Height: int32(graphicsHeight) },
}
} }
func main() { func main() {
log := log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile) log := log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
bootstrap() layout := bootstrap()
//rl.SetConfigFlags(rl.FlagMsaa4xHint) //rl.SetConfigFlags(rl.FlagMsaa4xHint)
rl.InitWindow(int32(targetWidth), int32(targetHeight), "sumi sierpinski arrow") rl.InitWindow(layout.window.Width, layout.window.Height, "sumi sierpinski arrow")
// reproducable flourescent color cycle // reproducable flourescent color cycle
colorCycle := g.NewFixedColorCycle(g.FlourescentColors).Shuffle(0) colorCycle := g.NewFixedColorCycle(g.FlourescentColors).Shuffle(0)
@@ -89,8 +116,8 @@ func main() {
//imageField := NewImageField("/home/d/Dropbox/art/data/moses_statue.jpg") //imageField := NewImageField("/home/d/Dropbox/art/data/moses_statue.jpg")
field := field :=
&TranslateField { &TranslateField {
x: -float32(sourceWidth / 2.0), x: -float32(layout.graphics.Width / 2.0),
y: -float32(sourceHeight / 2.0), y: -float32(layout.graphics.Height / 2.0),
field: &ScaleField{ field: &ScaleField{
scale: 100.0, scale: 100.0,
field: &AdderField { field: &AdderField {
@@ -104,7 +131,7 @@ func main() {
//sierpinskiLayer := &SierpinskiArrow { dirty: true } //sierpinskiLayer := &SierpinskiArrow { dirty: true }
sketch := NewSketch(int32(sourceWidth), int32(sourceHeight)) sketch := NewSketch(layout.graphics.Width, layout.graphics.Height)
fieldColor := colorCycle.Next() fieldColor := colorCycle.Next()
fmt.Printf("field color = %v\n", fieldColor) fmt.Printf("field color = %v\n", fieldColor)
@@ -157,18 +184,11 @@ func main() {
// begin drawing // begin drawing
t := time.Since(t0).Seconds() t := time.Since(t0).Seconds()
targetBounds := rl.Rectangle {
X: float32(targetWidth) / 4.0,
Y: 0,
Width: float32(targetWidth) * 3.0 / 4.0,
Height: float32(targetHeight),
}
// set up RenderCtx // set up RenderCtx
renderCtx := &RenderCtx{ renderCtx := &RenderCtx{
TargetBounds: targetBounds, TargetBounds: layout.viewport,
SourceWidth: int32(sourceWidth), SourceWidth: layout.graphics.Width,
SourceHeight: int32(sourceHeight), SourceHeight: layout.graphics.Height,
Time: t, Time: t,
Ports: ports.Eval(t), Ports: ports.Eval(t),
} }
@@ -192,43 +212,48 @@ func main() {
gui.SetStyle(gui.DEFAULT, gui.BORDER_COLOR_NORMAL, 0x404040FF) gui.SetStyle(gui.DEFAULT, gui.BORDER_COLOR_NORMAL, 0x404040FF)
y := float32(10) y := float32(10)
minX := float32(20)
maxX := float32(layout.controls.X + layout.controls.Width - 20)
sliderWidth := maxX - minX - 20
controlRowHeight := 20
for _, layerTools := range sketch.layerToolsOrdered { for _, layerTools := range sketch.layerToolsOrdered {
config := layerTools.config config := layerTools.config
gui.Label(rl.Rectangle{X: 20, Y: y, Width: 120, Height: 24}, layerTools.name) gui.Label(rl.Rectangle{X: minX, Y: y, Width: 120, Height: 24}, layerTools.name)
y += 30 y += float32(controlRowHeight + 10)
config.visible = gui.Toggle(rl.Rectangle{X: 30, Y: y, Width: 16, Height: 16}, "A", config.visible) config.visible = gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "A", config.visible)
config.a = uint8(gui.Slider(rl.Rectangle{X: 50, Y: y, Width: 264, Height: 16}, "", "", float32(config.a), 0, 255)) config.a = uint8(gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", float32(config.a), 0, 255))
y += 24 y += float32(controlRowHeight)
config.rVisible = gui.Toggle(rl.Rectangle{X: 30, Y: y, Width: 16, Height: 16}, "R", config.rVisible) config.rVisible = gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "R", config.rVisible)
config.r = uint8(gui.Slider(rl.Rectangle{X: 50, Y: y, Width: 264, Height: 16}, "", "", float32(config.r), 0, 255)) config.r = uint8(gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", float32(config.r), 0, 255))
y += 24 y += float32(controlRowHeight)
config.gVisible = gui.Toggle(rl.Rectangle{X: 30, Y: y, Width: 16, Height: 16}, "G", config.gVisible) config.gVisible = gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "G", config.gVisible)
config.g = uint8(gui.Slider(rl.Rectangle{X: 50, Y: y, Width: 264, Height: 16}, "", "", float32(config.g), 0, 255)) config.g = uint8(gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", float32(config.g), 0, 255))
y += 24 y += float32(controlRowHeight)
config.bVisible = gui.Toggle(rl.Rectangle{X: 30, Y: y, Width: 16, Height: 16}, "B", config.bVisible) config.bVisible = gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "B", config.bVisible)
config.b = uint8(gui.Slider(rl.Rectangle{X: 50, Y: y, Width: 264, Height: 16}, "", "", float32(config.b), 0, 255)) config.b = uint8(gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", float32(config.b), 0, 255))
y += 24 y += float32(controlRowHeight)
config.desaturate = !gui.Toggle(rl.Rectangle{X: 30, Y: y, Width: 16, Height: 16}, "S", !config.desaturate) config.desaturate = !gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "S", !config.desaturate)
config.saturation = gui.Slider(rl.Rectangle{X: 50, Y: y, Width: 264, Height: 16}, "", "", config.saturation, 0, 100) config.saturation = gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", config.saturation, 0, 100)
y += 24 y += float32(controlRowHeight)
gui.Label(rl.Rectangle{X: 30, Y: y, Width: 16, Height: 16}, "K") gui.Label(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "K")
config.kValue = gui.Slider(rl.Rectangle{X: 50, Y: y, Width: 264, Height: 16}, "", "", config.kValue, 0, 2) config.kValue = gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", config.kValue, 0, 2)
y += 30 y += float32(controlRowHeight + 10)
} }
rl.EndDrawing() rl.EndDrawing()

View File

@@ -21,7 +21,7 @@ type TextureCam struct {
/** RenderCtx **/ /** RenderCtx **/
type RenderCtx struct { type RenderCtx struct {
TargetBounds rl.Rectangle TargetBounds rl.RectangleInt32
SourceWidth int32 SourceWidth int32
SourceHeight int32 SourceHeight int32
Time float64 Time float64
@@ -200,7 +200,7 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
func (s *Sketch) calcOutputRectKeepingAspectRatio(ctx *RenderCtx) rl.Rectangle { func (s *Sketch) calcOutputRectKeepingAspectRatio(ctx *RenderCtx) rl.Rectangle {
sourceAspect := float32(ctx.SourceWidth) / float32(ctx.SourceHeight) sourceAspect := float32(ctx.SourceWidth) / float32(ctx.SourceHeight)
targetAspect := ctx.TargetBounds.Width / ctx.TargetBounds.Height targetAspect := float32(ctx.TargetBounds.Width) / float32(ctx.TargetBounds.Height)
outputWidth := ctx.TargetBounds.Width outputWidth := ctx.TargetBounds.Width
outputHeight := ctx.TargetBounds.Height outputHeight := ctx.TargetBounds.Height
@@ -209,12 +209,12 @@ func (s *Sketch) calcOutputRectKeepingAspectRatio(ctx *RenderCtx) rl.Rectangle {
// source is relatively taller than the target // source is relatively taller than the target
// so we set the output height to the target height // so we set the output height to the target height
// and calculate the width based on source aspect and center // and calculate the width based on source aspect and center
outputWidth = outputHeight * sourceAspect outputWidth = int32(float32(outputHeight) * sourceAspect)
} else { } else {
// source is relatively wider than the target // source is relatively wider than the target
// so we set the output width to the target width // so we set the output width to the target width
// and calculate the height based on source aspect and center // and calculate the height based on source aspect and center
outputHeight = outputWidth / sourceAspect outputHeight = int32(float32(outputWidth) / sourceAspect)
} }
// output width and height are correct -- center within TargetBounds // output width and height are correct -- center within TargetBounds
@@ -222,9 +222,9 @@ func (s *Sketch) calcOutputRectKeepingAspectRatio(ctx *RenderCtx) rl.Rectangle {
y := ctx.TargetBounds.Y + ctx.TargetBounds.Height / 2.0 - outputHeight / 2.0 y := ctx.TargetBounds.Y + ctx.TargetBounds.Height / 2.0 - outputHeight / 2.0
return rl.Rectangle{ return rl.Rectangle{
X: x, Y: y, X: float32(x), Y: float32(y),
Width: outputWidth, Width: float32(outputWidth),
Height: outputHeight, Height: float32(outputHeight),
} }
} }
@@ -244,7 +244,7 @@ func (s *Sketch) Update(ctx *RenderCtx) {
if rl.IsMouseButtonDown(rl.MouseRightButton) { if rl.IsMouseButtonDown(rl.MouseRightButton) {
// get mouse delta from last frame // get mouse delta from last frame
delta := rl.GetMouseDelta() delta := rl.GetMouseDelta()
sourceScale := float32(ctx.SourceWidth) / ctx.TargetBounds.Width sourceScale := float32(ctx.SourceWidth) / float32(ctx.TargetBounds.Width)
// compute the amount to move scaled by the camera zoom // compute the amount to move scaled by the camera zoom
delta = rl.Vector2Scale(delta, -sourceScale/s.cam.Zoom) delta = rl.Vector2Scale(delta, -sourceScale/s.cam.Zoom)
delta.Y = -delta.Y delta.Y = -delta.Y