builtin-programs/editor/draw-editor.folk

When the editor utils library is /utils/ {

# Draw text and cursor
When /editor/ is an editor with /...anything/ &\
     editor /editor/ has margin /margin/ &\
     editor /editor/ has viewport position /vpPos/ &\
     editor /editor/ has viewport size /vpSize/ &\
     editor /editor/ has selected program /program/ &\
     editor /editor/ on program /program/ has font options with /...fontOptions/ {
    lassign $vpPos vpX vpY
    lassign $vpSize vpWidth vpHeight

    # Editor backdrop.
    When $editor has canvas /editorCanvas/ with /...wiOpts/ {
        set bgColor [list 0 0 0 0.8]
        Wish the GPU draws pipeline "fillTriangle" onto canvas $editorCanvas \
            with arguments [list {{1 0 0} {0 1 0} {0 0 1}} \
                                [list -1 -1] [list 1 -1] [list 1 1] $bgColor] \
                 layer -2
        Wish the GPU draws pipeline "fillTriangle" onto canvas $editorCanvas \
            with arguments [list {{1 0 0} {0 1 0} {0 0 1}} \
                                [list -1 -1] [list 1 1] [list -1 1] $bgColor] \
                 layer -2
    }

    # Editor gold dashed outline.
    When $editor has resolved geometry /geom/ &\
         the clock time is /t/ {
        Wish to draw a dashed line onto $editor with points \
            [list [list 0 0] \
                 [list $geom(width) 0] \
                 [list $geom(width) $geom(height)] \
                 [list 0 $geom(height)] \
                 [list 0 0]] \
            color gold width 0.005 dashlength 0.008 \
            dashoffset [expr {fmod($t, 1.6) * 0.01}]
    }

    set textScale [dict get $fontOptions scale]
    set advance [$utils getAdvance $textScale]

    When editor $editor has selected program /program/ &\
         editor buffer for /program/ is /code/ &\
         editor $editor has cursor /cursor/ &\
         editor $editor has cursor position /cursorPos/ &\
         editor $editor has selection anchor /selAnchor/ {
        set lineCount [min [- [llength [split $code "\n"]] $vpY] $vpHeight]
        set lineNumbers [$utils lineNumberView $vpY $lineCount]

        set marginLeft [lindex $margin 3]
        set lineNumbersRight $($marginLeft + $advance*1.5)
        Wish to draw text onto $editor with \
            position [list $lineNumbersRight [lindex $margin 0]] \
            text $lineNumbers color gold \
            scale $textScale anchor topright font NeomatrixCode

        set text [$utils applyTextViewport $code $vpX $vpY $vpWidth $vpHeight]
        set pos [list [+ $lineNumbersRight $advance] [lindex $margin 0]]
        Wish to draw text onto $editor with \
            position $pos text $text \
            scale $textScale anchor topleft font NeomatrixCode

        # Draw selection highlight
        if {$selAnchor ne ""} {
            set rawStart [min $selAnchor $cursor]
            set rawEnd [max $selAnchor $cursor]
            lassign [$utils cursorToXy $code $rawStart] selStartX selStartY
            lassign [$utils cursorToXy $code $rawEnd] selEndX selEndY

            set lines [split $code "\n"]
            for {set ly $selStartY} {$ly <= $selEndY} {incr ly} {
                if {$ly < $vpY || $ly >= $vpY + $vpHeight} continue

                set lineLen [string length [lindex $lines $ly]]

                # Absolute column range for selection on this line
                if {$ly == $selStartY} {
                    set absStart $selStartX
                } else {
                    set absStart 0
                }
                if {$ly == $selEndY} {
                    set absEnd $selEndX
                } else {
                    set absEnd $lineLen
                }

                # Clip to viewport
                set absStart [max $absStart $vpX]
                set absEnd [min $absEnd [+ $vpX $vpWidth]]

                if {$absStart >= $absEnd} continue

                # Convert to display coordinates
                set dispStart [- $absStart $vpX]
                set dispEnd [- $absEnd $vpX]
                set dispRow [- $ly $vpY]

                set x0 $([lindex $pos 0] + $dispStart * $advance)
                set x1 $([lindex $pos 0] + $dispEnd * $advance)
                set y0 $([lindex $pos 1] + $dispRow * $textScale)
                set y1 $($y0 + $textScale)

                Wish to draw a quad onto $editor with \
                    p0 [list $x0 $y0] p1 [list $x1 $y0] \
                    p2 [list $x1 $y1] p3 [list $x0 $y1] \
                    color {0.2 0.4 0.8 0.7} layer -1
            }
        }

        set p1 [vec2 add $cursorPos $pos]
        set p2 [vec2 add $p1 [list 0 [* $textScale 1.2]]]
        set s [/ $textScale 6]
        Wish to draw a circle onto $editor with center $p1 radius $s thickness 0 color green filled true
        Wish to draw a line onto $editor with points [list $p1 $p2] width $s color green
    }
}

}