Amiga WB1.3 Just a bit of fun with Odin+Raylib

Here’s a bit of silliness. Just an Amiga WB 1.3 style of demo.
It’s not at all accurate to the real Amiga workbench but you can move/resize and close it.
You can set up more windows and each will have their own rendering area.

package ray_amigawindow

import rl "vendor:raylib"

WIN_W,WIN_H :: 800,450

WB_BLUE     :: rl.Color{0,85,170,255}
WB_BLACK    :: rl.Color{0,0,34,255}
WB_WHITE    :: rl.Color{255,255,255,255}
WB_ORANGE   :: rl.Color{255,136,0,255}

rnd32 :: proc(lo,hi :f32) -> f32{return f32(rl.GetRandomValue(i32(lo),i32(hi)))}

main :: proc(){    
    using rl
    InitWindow(WIN_W,WIN_H,"Raylib - Amiga window demo")
    SetTargetFPS(60)
    win1:=CreateAmigaWindow("Boxes",14,24,440,260)
    // main loop
    for !WindowShouldClose() {
        // handle mouse inputs for close/resize/move 
        UpdateAmigaWindow(&win1)
        // lets draw stuff to the windows inner texture
        BeginTextureMode(win1.tex)
            ClearBackground(WB_BLUE)
            randcol:Color
            randrec:Rectangle
            tex:=win1.tex.texture
            for i in 1..=60{
                switch GetRandomValue(0,4){
                    case 0: randcol=WB_BLACK
                    case 1: randcol=WB_WHITE
                    case 2: randcol=WB_ORANGE
                    case 3: randcol=WB_BLUE
                }
                randrec={
                    rnd32(-10,f32(tex.width)/2),rnd32(-10,f32(tex.height)/2),
                    rnd32(30,f32(tex.width)),rnd32(30,f32(tex.height))
                }
                DrawRectangleRec(randrec,randcol)
            }
        EndTextureMode()

        BeginDrawing()
            ClearBackground(WB_BLUE)
            DrawAmigaWindow(win1)
        EndDrawing()
    }
    CloseWindow()
}

// ########################################################

AmigaWindow :: struct{
    alive,resizing,moving:bool,
    rec:rl.Rectangle,
    tex:rl.RenderTexture2D,
    right,bottom:f32,
    title:cstring,
    posoffset:rl.Vector2
}

CreateAmigaWindow :: proc(title:cstring,x,y,w,h:f32) -> AmigaWindow{
    newwin:=AmigaWindow{}
    newwin.alive=true
    newwin.rec={x,y,w,h}
    newwin.tex=rl.LoadRenderTexture(i32(w-4),i32(h-4))
    newwin.right=x+w
    newwin.bottom=y+h
    newwin.title=title
    return newwin
}

UpdateAmigaWindow :: proc(aw:^AmigaWindow){
    if !aw.alive do return
    using rl
    // Check if CLOSE clicked
    rec:=Rectangle{aw.rec.x,aw.rec.y,25,25}
    if CheckCollisionPointRec(GetMousePosition(),rec){
        if IsMouseButtonPressed(.LEFT){
            aw.alive=false
            UnloadRenderTexture(aw.tex)
            return
        }
    }
    // check if over mouse is over RESIZE or TITLE BAR area (and if mouse left is down) 
    mouseoverresize:=CheckCollisionPointRec(GetMousePosition(),{aw.right-10,aw.bottom-10,20,20})
    mouseovertitle:=CheckCollisionPointRec(GetMousePosition(),{aw.rec.x+36,aw.rec.y,aw.rec.width-64,24})
    if !aw.resizing && !aw.moving{
        if mouseoverresize || mouseovertitle{
            SetMouseCursor(MouseCursor.RESIZE_ALL)
            if IsMouseButtonDown(.LEFT){
                aw.resizing=mouseoverresize
                aw.moving=mouseovertitle
                aw.posoffset={f32(GetMouseX())-aw.rec.x,f32(GetMouseY())-aw.rec.y}
            }
        }else{
            SetMouseCursor(MouseCursor.DEFAULT)
        }
    }
    if IsMouseButtonUp(.LEFT){aw.resizing=false;aw.moving=false}
    // if window being resized by the user
    if aw.resizing{
        aw.rec.width=max(96,f32(GetMouseX())-aw.rec.x)
        aw.rec.height=max(64,f32(GetMouseY())-aw.rec.y)
        aw.right=aw.rec.x+aw.rec.width
        aw.bottom=aw.rec.y+aw.rec.height
        UnloadRenderTexture(aw.tex)
        aw.tex=LoadRenderTexture(i32(aw.rec.width-4),i32(aw.rec.height-4))
    }
    // if window is being moved by the user
    if aw.moving{
        aw.rec.x=f32(GetMouseX())-aw.posoffset.x
        aw.rec.y=f32(GetMouseY())-aw.posoffset.y
        aw.right=aw.rec.x+aw.rec.width
        aw.bottom=aw.rec.y+aw.rec.height
    }
}

DrawAmigaWindow :: proc(aw:AmigaWindow){
    if !aw.alive do return
    using rl
    // main drawing area
    DrawTexture(aw.tex.texture,i32(aw.rec.x+2),i32(aw.rec.y+2),WHITE)
    // outer rectangle
    DrawRectangleLinesEx(aw.rec,4,WB_WHITE)
    // top title bar area
    DrawRectangleRec({aw.rec.x,aw.rec.y,aw.rec.width,25},WB_WHITE)
    xpos:=i32(aw.rec.x)+32
    DrawText(aw.title,xpos,i32(aw.rec.y)+4,18,WB_BLUE)
    xpos+=MeasureText(aw.title,18)+4
    DrawLineEx({f32(xpos),aw.rec.y+8},{aw.right-32,aw.rec.y+8},4,WB_BLUE)
    DrawLineEx({f32(xpos),aw.rec.y+16},{aw.right-32,aw.rec.y+16},4,WB_BLUE)
    // close button
    DrawRectangleLinesEx({aw.rec.x+4,aw.rec.y+4,22,18},4,WB_BLUE)
    DrawRectangleRec({aw.rec.x+12,aw.rec.y+10,5,5},WB_BLUE)
    // max button (does nothing in this demo)
    DrawRectangleRec({aw.right-24,aw.rec.y+4,16,16},WB_BLACK)
    // resize area indicator (bottom right)
    DrawLineEx({aw.right-24,aw.bottom-2},{aw.right,aw.bottom-2},4,WB_ORANGE)
    DrawLineEx({aw.right-2,aw.bottom-24},{aw.right-2,aw.bottom},4,WB_ORANGE)
}
1 Like