Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
layoutUtils (library for text layout)
#1
Hi,

Here’s a small library that lets me define layouts for displaying text screens containing variable data.
Thank you for your feedback.

layoutUtils.bi
Code: (Select All)
$INCLUDEONCE

type layoutUtils_layoutType
    id as integer
    layoutName as string
    fullpath as string
    content as string
    resolved as string
    prepared as integer
end type

type layoutUtils_elementType
    index as integer
    position as integer
    length as integer
    reference as string
end type

redim shared layoutUtils_layoutList(0) as layoutUtils_layoutType
redim shared layoutUtils_elementList(0) as layoutUtils_elementType

layoutUtils.bm
Code: (Select All)
$INCLUDEONCE

'------------------------------------------------------------------------------
' layoutUtils Library
'
' Overview:
'   The layoutUtils library provides a simple framework for creating, loading,
'   parsing, and manipulating layout data structures represented as strings.
'   Layouts can be built directly from in-memory strings, loaded from external
'   files, or defined in DATA statements. The library supports placeholder
'   references within layouts that can be dynamically resolved or replaced, and
'   allows retrieval of the final resolved content.
'
' Key Features:
'   1. Layout Creation & Loading
'      - layoutUtils_build%: Create a new layout directly from a string, assign
'        it a name, and prepare it for reference resolution.
'      - layoutUtils_load%: Load layout content from an external file.
'      - layoutUtils_loadData%: Load layout content from embedded DATA statements.
'      - Internally manages all layouts in layoutUtils_layoutList.
'
'   2. Reference Extraction & Tracking
'      - Scan layout content for placeholder patterns "<&reference>".
'      - Record each placeholder’s layout index, position, length, and name in
'        layoutUtils_elementList for subsequent processing.
'
'   3. Reference Resolution & Replacement
'      - layoutUtils_populateIndex: Replace a named reference in a layout by index.
'      - layoutUtils_populate: Replace a named reference in a layout by name.
'      - Automatically preserves field width by padding or truncating the replacement.
'
'   4. Layout Retrieval
'      - layoutUtils_getPopulatedIndex$: Return the fully resolved content
'        of a layout by its numeric index.
'      - layoutUtils_getPopulated$: Return the fully resolved content of a
'        layout by its name.
'
'   5. Utility Functions
'      - layoutUtils_find: Locate a layout by name and return its index.
'      - layoutUtils_reset / layoutUtils_resetIndex: Restore a layout’s
'        resolved content back to its original raw content.
'      - layoutUtils_getNext$: Extract the next placeholder substring from layout
'        content between the markers "<&" and ">".
'
' Usage Workflow:
'   1. Create or load a layout:
'        idx1 = layoutUtils_build("intro", rawStringContent, "")
'        idx2 = layoutUtils_load("level1", "C:\layouts\level1.layout")
'        idx3 = layoutUtils_loadData("level2", 5)
'
'   2. Layout preparation (automatic during build/load):
'        success = layoutUtils_prepare(idx1)
'
'   3. Populate references:
'        layoutUtils_populate("level1", "playerStart", "X:10,Y:20")
'
'   4. Retrieve the final resolved layout content:
'        final$. = layoutUtils_getPopulated("level1")
'        final$. = layoutUtils_getPopulatedIndex(idx1)
'
'   5. Reset to original content (if needed):
'        layoutUtils_reset("level1")
'
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' Function: layoutUtils_build%
' Purpose : Adds a new layout to the layoutUtils_layoutList array and prepares it.
'
' Parameters:
'   layoutName  - (string) The name of the layout to be added.
'   content  - (string) The content/data of the layout.
'   fullpath - (string) The full file path associated with the layout.
'
' Returns:
'   (integer) The index of the newly added layout in the layoutUtils_layoutList array.
'
' Description:
'   This function creates a new layoutUtils_layoutType object, assigns it an ID,
'   sets its properties (layoutName, fullpath, content), and appends it to the
'   layoutUtils_layoutList array. It then prepares the layout using layoutUtils_prepare
'   and stores the result in the 'prepared' field. The function returns the index
'   of the newly added layout.
'------------------------------------------------------------------------------
function layoutUtils_build% (layoutName as string, content as string, fullpath as string)
    dim res as layoutUtils_layoutType
    dim last%
    last% = ubound(layoutUtils_layoutList) + 1
    redim _preserve layoutUtils_layoutList(last%) as layoutUtils_layoutType
    dim layout as layoutUtils_layoutType
    layout.id = last%
    layout.layoutName = layoutName
    layout.fullpath = fullpath
    layout.content = content$
    layoutUtils_layoutList(last%) = layout
    layoutUtils_layoutList(last%).prepared = layoutUtils_prepare(last%)
    layoutUtils_build = last%
end function

'------------------------------------------------------------------------------
' Function: layoutUtils_load%
' Purpose : Loads a layout from a file and adds it to the layoutUtils_layoutList array.
'
' Parameters:
'   layoutName  - (string) The name to assign to the loaded layout.
'   fullpath - (string) The full file path to load the layout content from.
'
' Returns:
'   (integer) The index of the newly added layout in the layoutUtils_layoutList array.
'
' Description:
'   This function opens the specified file in binary mode, reads its content,
'   and creates a new layout entry using layoutUtils_build. The layout is then
'   prepared and stored in the layoutUtils_layoutList array.
'------------------------------------------------------------------------------
function layoutUtils_load% (layoutName as string, fullpath as string)
    open fullpath for binary as #1
    dim content$, c as _unsigned _byte
    do until eof(1)
        get #1,,c
        content$ = content$ + chr$(c)
    loop
    close #1
    layoutUtils_load = layoutUtils_build (layoutName, content$, fullpath)
end function

'------------------------------------------------------------------------------
' Function: layoutUtils_loadData%
' Purpose : Loads a layout from DATA statements and adds it to the layoutUtils_layoutList array.
'
' Parameters:
'   layoutName - (string) The name to assign to the loaded layout.
'   length  - (integer) The number of DATA lines to read for the layout content.
'
' Returns:
'   (integer) The index of the newly added layout in the layoutUtils_layoutList array.
'
' Description:
'   This function reads the specified number of lines from DATA statements,
'   concatenates them with line breaks, and creates a new layout entry using
'   layoutUtils_build. The layout is then prepared and stored in the
'   layoutUtils_layoutList array.
'------------------------------------------------------------------------------
function layoutUtils_loadData% (layoutName as string, length as integer)
    dim content$, i%, c$
    for i% = 1 to length
        read c$
        content$ = content$ + c$ + _STR_NAT_EOL
    next i%
    layoutUtils_loadData = layoutUtils_build (layoutName, content$, "")
end function

'------------------------------------------------------------------------------
' Function: layoutUtils_prepare%
' Purpose : Scans the layout content for references and populates the layoutUtils_elementList array.
'
' Parameters:
'   index - (integer) The index of the layout in layoutUtils_layoutList to prepare.
'
' Returns:
'   (integer) 1 if preparation is successful.
'
' Description:
'   This function searches the layout content for reference patterns (e.g., <&reference>)
'   and records their positions, lengths, and reference names in the layoutUtils_elementList array.
'   Each found reference is stored as a layoutUtils_elementType object.
'------------------------------------------------------------------------------
function layoutUtils_prepare% (index as integer)
    layoutUtils_prepare = 0
    dim position%
    position% = 1
    dim ref as string
    do
        ref = layoutUtils_getNext (index, position%)
        if ref = "" then exit do
        dim length%
        length% = len(ref) + 3
        dim n%
        n% = instr(,ref,".")
        dim reference$
        if n% > 0 then
            reference$ = left$(ref,n%-1)
        else
            reference$ = ref
        end if
        dim res as layoutUtils_elementType
        res.index = index
        res.position = position% - 2
        res.length = length%
        res.reference = reference$
        dim last%
        last% = ubound(layoutUtils_elementList) + 10
        redim _preserve layoutUtils_elementList(last%) as layoutUtils_elementType
        layoutUtils_elementList(last%).index = res.index
        layoutUtils_elementList(last%).position = res.position
        layoutUtils_elementList(last%).length = res.length
        layoutUtils_elementList(last%).reference = res.reference
    loop
    layoutUtils_prepare = 1
end function

'------------------------------------------------------------------------------
' Function: layoutUtils_find
' Purpose : Finds the index of a layout in the layoutUtils_layoutList array by its name.
'
' Parameters:
'   layoutName - (string) The name of the layout to search for.
'
' Returns:
'   (integer) The index of the layout if found, otherwise 0.
'
' Description:
'   This function iterates through the layoutUtils_layoutList array and compares
'   each layout's name to the provided name. If a match is found, it returns
'   the index of the layout. If no match is found, it returns 0.
'------------------------------------------------------------------------------
function layoutUtils_find (layoutName as string)
    layoutUtils_find = 0
    dim i%, maxi%
    maxi% = ubound(layoutUtils_layoutList)
    for i% = 1 to maxi% + 1
        if i% > maxi% then exit sub
        if layoutUtils_layoutList(i%).layoutName = layoutName then exit for
    next i%
    layoutUtils_find = i%
end function

'------------------------------------------------------------------------------
' Subroutine: layoutUtils_resetIndex
' Purpose   : Resets the resolved content of a layout to its original content.
'
' Parameters:
'   index - (integer) The index of the layout in layoutUtils_layoutList to reset.
'
' Description:
'   This subroutine sets the 'resolved' field of the specified layout to its
'   original 'content', effectively undoing any replacements or modifications.
'------------------------------------------------------------------------------
sub layoutUtils_resetIndex (index as integer)
    layoutUtils_layoutList(index).resolved = layoutUtils_layoutList(index).content
end sub

'------------------------------------------------------------------------------
' Subroutine: layoutUtils_reset
' Purpose   : Resets the resolved content of a layout (by name) to its original content.
'
' Parameters:
'   layoutName - (string) The name of the layout to reset.
'
' Description:
'   This subroutine finds the layout index by name and calls layoutUtils_resetIndex
'   to restore the 'resolved' field to its original 'content'.
'------------------------------------------------------------------------------
sub layoutUtils_reset (layoutName as string)
    dim i%
    i% = layoutUtils_find(layoutName)
    if i% > 0 then
        layoutUtils_resetIndex(i%)
    end if
end sub

'------------------------------------------------------------------------------
' Function: layoutUtils_findReference
' Purpose : Finds the index of a reference in the layoutUtils_elementList array for a given layout.
'
' Parameters:
'   index  - (integer) The index of the layout in layoutUtils_layoutList.
'   reference - (string) The reference name to search for.
'
' Returns:
'   (integer) The index of the reference in layoutUtils_elementList if found, otherwise 0.
'
' Description:
'   This function iterates through the layoutUtils_elementList array and compares
'   each element's index and reference name to the provided values. If a match
'   is found, it returns the index of the reference. If no match is found, it returns 0.
'------------------------------------------------------------------------------
function layoutUtils_findReference (index as integer, reference as string)
    layoutUtils_findReference = 0
    dim i%, maxi%
    maxi% = ubound(layoutUtils_elementList)
    for i% = 1 to maxi% + 1
        if i% > maxi% then exit sub
        if layoutUtils_elementList(i%).index = index and layoutUtils_elementList(i%).reference = reference then exit for
    next i%
    layoutUtils_findReference = i%
end function

'------------------------------------------------------------------------------
' Subroutine: layoutUtils_populateIndex
' Purpose   : Replaces a reference in the resolved layout content with a replacement string.
'
' Parameters:
'   index         - (integer) The index of the layout in layoutUtils_layoutList.
'   reference        - (string) The reference name to replace.
'   replacementString- (string) The string to insert in place of the reference.
'
' Description:
'   This subroutine finds the reference in the layoutUtils_elementList for the given layout.
'   It then replaces the corresponding substring in the 'resolved' field of the layout with
'   the replacement string, padded or truncated to match the reference length.
'------------------------------------------------------------------------------
sub layoutUtils_populateIndex (index as integer, reference as string, replacementString as string)
    dim refIndex%
    refIndex% = layoutUtils_findReference(index%, reference)
    mid$( _
            layoutUtils_layoutList(index%).resolved, _
            layoutUtils_elementList(refIndex%).position _
        ) = _
    left$( _
            replacementString$ + space$( layoutUtils_elementList(refIndex%).length ), _
            layoutUtils_elementList(refIndex%).length _
        )
end sub

'------------------------------------------------------------------------------
' Subroutine: layoutUtils_populate
' Purpose   : Replaces a reference in the resolved layout content (by layout name) with a replacement string.
'
' Parameters:
'   layoutName       - (string) The name of the layout in layoutUtils_layoutList.
'   reference        - (string) The reference name to replace.
'   replacementString- (string) The string to insert in place of the reference.
'
' Description:
'   This subroutine finds the layout index by name and calls layoutUtils_populateIndex
'   to replace the specified reference in the resolved content with the replacement string.
'------------------------------------------------------------------------------
sub layoutUtils_populate (layoutName as string, reference as string, replacementString as string)
    dim index%
    index% = layoutUtils_find(layoutName)
    layoutUtils_populateIndex index%, reference, replacementString
end sub

'------------------------------------------------------------------------------
' Function: layoutUtils_getPopulatedIndex$
' Purpose : Returns the resolved (populated) content of a layout by its index.
'
' Parameters:
'   index - (integer) The index of the layout in layoutUtils_layoutList.
'
' Returns:
'   (string) The resolved content of the layout if the index is valid, otherwise an empty string.
'
' Description:
'   This function checks if the provided index is within the valid range of layoutUtils_layoutList.
'   If valid, it returns the 'resolved' field of the layout, which contains the content with all
'   references replaced. If the index is invalid, it returns an empty string.
'------------------------------------------------------------------------------
function layoutUtils_getPopulatedIndex$ (index as integer)
    if index > 0 and index <= ubound(layoutUtils_layoutList) then
        layoutUtils_getPopulatedIndex = layoutUtils_layoutList(index).resolved
    else
        layoutUtils_getPopulatedIndex = ""
    end if
end function

'------------------------------------------------------------------------------
' Function: layoutUtils_getPopulated$
' Purpose : Returns the resolved (populated) content of a layout by its name.
'
' Parameters:
'   layoutName - (string) The name of the layout in layoutUtils_layoutList.
'
' Returns:
'   (string) The resolved content of the layout if found, otherwise an empty string.
'
' Description:
'   This function finds the layout index by name and returns the 'resolved' field,
'   which contains the content with all references replaced. If the layout is not
'   found, it returns an empty string.
'------------------------------------------------------------------------------
function layoutUtils_getPopulated$ (layoutName as string)
    dim index%
    index% = layoutUtils_find(layoutName)
    layoutUtils_getPopulated = layoutUtils_getPopulatedIndex(index%)
end function

'------------------------------------------------------------------------------
' Function: layoutUtils_getNext$ (layoutNumber%, position%)
'
' Description:
'   Extracts the next substring found between the markers "<&" and ">" from the
'   content of a layout identified by layoutNumber%, starting the search at position%.
'
' Parameters:
'   layoutNumber%  - The index of the layout in layoutUtils_layoutList to search within.
'   position%   - The position in the content string to start searching from.
'
' Returns:
'   A string containing the substring found between "<&" and ">" markers.
'   Returns an empty string if no such substring is found.
'
' Example Usage:
'   nextValue$ = layoutUtils_getNext$(1, 10)
'
' Notes:
'   - The function updates position% to the start of the found substring.
'   - If no marker is found, the function returns an empty string.
'------------------------------------------------------------------------------
function layoutUtils_getNext$ (layoutNumber%, position%)
    dim beginning$, middle$, ending$
    dim l%, b%, e%, m%
    dim content$
    content$ = layoutUtils_layoutList(layoutNumber%).content
    beginning$ = "<&"
    middle$ = ""
    ending$ = ">"
    l% = len(beginning$)
    b% = instr(position%,content$,beginning$)
    if b% = 0 then
        layoutUtils_getNext = ""
        exit sub
    end if
    e% = instr(b%+l%,content$,ending$)
    position% = b%+l%
    middle$ = mid$(content$,position%,e%-b%-l%)
    layoutUtils_getNext = middle$
end function

And also a test program to demonstrate how it works and why it’s useful.

layoutUtilsTesterFunctional.bas
Code: (Select All)
Option _Explicit

' Include layout utility declarations
'$include: '../library/layoutUtils.bi'

' Create two off‐screen buffers (800×600, 32‐bit) for text and graphics
screen _NewImage(800, 600, 32)
dim as single textDest, grafDest
textDest = _NewImage(800, 600, 32)
grafDest = _NewImage(800, 600, 32)

'=====================================================================
' Define first screen layout (User Information) using DATA statements
'=====================================================================
LAYOUT1:
    DATA "                                                                            "
    DATA "   +-----------------------------------------------------------------------+"
    DATA "   |                          User Information                       <&pg> |"
    DATA "   +-----------------------------------------------------------------------+"
    DATA "   |                                                                       |"
    DATA "   |    Last Name          <&lastName.................................>    |"
    DATA "   |    First Name         <&firstName................................>    |"
    DATA "   |                                                                       |"
    DATA "   |  Address:                                                             |"
    DATA "   |                                                                       |"
    DATA "   |    Street Address     <&streetAddress......................>          |"
    DATA "   |    Apartment / Suite  <&apartmentSuite...................>            |"
    DATA "   |    City               <&city...............................>          |"
    DATA "   |    State / Province   <&stateProvince.....................>           |"
    DATA "   |    ZIP / Postal       <&zipPostal.........................>           |"
    DATA "   |    Country            <&country...........................>           |"
    DATA "   |                                                                       |"
    DATA "   +-----------------------------------------------------------------------+"
    DATA "                                        [L:list] [N:next] [P:prev] [Q:quit] "

'==================================================================
' Define second screen layout (User List) using DATA statements
'==================================================================
LAYOUT2:
    DATA "                                                                               "
    DATA " +----------------------------------------------------------------------------+"
    DATA " |                                 User List                                  |"
    DATA " +------------------+------------------+--------------------+-----------------+"
    DATA " | Last Name        | First Name       | City               | State           |"
    DATA " +------------------+------------------+--------------------+-----------------+"
    DATA " | <&last1........> | <&first1.......> | <&city1..........> | <&state1......> |"
    DATA " | <&last2........> | <&first2.......> | <&city2..........> | <&state2......> |"
    DATA " | <&last3........> | <&first3.......> | <&city3..........> | <&state3......> |"
    DATA " +------------------+------------------+--------------------+-----------------+"
    DATA "                                                           [R:return] [Q:quit] "

'==================================================================
' Load screen layouts into memory using layoutUtils library
'==================================================================
dim m1%, m2%
restore layout1
m1% = layoutUtils_loadData ("user", 19)   ' Load 19 lines for layout1 under name "user"
restore layout2
m2% = layoutUtils_loadData ("list", 11)   ' Load 11 lines for layout2 under name "list"

'==================================================================
' Define sample database entries (3 users, each with 9 fields)
'==================================================================
TEST1:
    DATA "1/3","Smith","John","123 Maple Street","Apt. 4B","Springfield","Illinois","62704","United States"
    DATA "2/3","Doe","Jane","456 Oak Avenue","Suite 12","Madison","Wisconsin","53703","United States"
    DATA "3/3","Brown","Charlie","789 Pine Road","Unit 5","Portland","Oregon","97205","United States"

' Initialize the in‐memory database array and fill it from TEST1
dim db$(1 To 3, 0 To 8)
restore TEST1
dim i%, j%
for i% = 1 to 3
    for j% = 0 to 8
        read db$(i%, j%)
    next j%
next i%

'==================================================================
' Main loop showing the User Information screen
'==================================================================
dim k$, user%
user% = 1   ' Start with the first user

SCREEN1:
    ' Populate the layout placeholders for the current user
    populateLayout1 m1%, db$(), user%
    ' Render text layer into off‐screen buffer
    refreshDestWithLayout "user", textDest

    do
        _limit 60           ' Cap frame rate to ~60 FPS
        _dest grafDest      ' Draw graphics into grafDest
        cls                 ' Clear graphics buffer
        drawCircle          ' Draw animated circle behind text
        _putimage , textDest, grafDest  ' Blit text buffer over graphics
        _dest 0             ' Set drawing back to actual screen
        _putimage , grafDest, 0          ' Present final composed image

        select case _keyhit   ' Handle key input
            case 81 or 113   ' Q or q to quit
                system
            case 78 or 110   ' N or n to go to next user
                if user% < 3 then
                    user% = user% + 1
                    exit do
                end if
            case 80 or 112   ' P or p to go to previous user
                if user% > 1 then
                    user% = user% - 1
                    exit do
                end if
            case 76 or 108   ' L or l to show user list
                gosub screen2
                exit do
        end select
    loop

    goto SCREEN1

'==================================================================
' Subroutine to display the User List screen
'==================================================================
SCREEN2:
    ' Fill in the list layout with all database entries
    populateLayout2 "list", db$()
    refreshDestWithLayout "list", textDest

    do
        _limit 60
        _dest grafDest
        cls
        drawTriangle    ' Draw rotating triangle graphic
        _putimage , textDest, grafDest
        _dest 0
        _putimage , grafDest, 0

        select case _keyhit
            case 81 or 113   ' Q or q to quit
                system
            case 82 or 114   ' R or r to return to info screen
                exit do
        end select
    loop

    return   ' Return back to SCREEN1 loop

system   ' Exit the program

'==================================================================
' Subroutine: populateLayout1
' Fills placeholders in the User Information layout
'==================================================================
sub populateLayout1 (layoutId as integer, database() as string, user as integer)
    layoutUtils_resetIndex layoutId
    layoutUtils_populateIndex layoutId, "pg", database(user, 0)
    layoutUtils_populateIndex layoutId, "lastName", database(user, 1)
    layoutUtils_populateIndex layoutId, "firstName", database(user, 2)
    layoutUtils_populateIndex layoutId, "streetAddress", database(user, 3)
    layoutUtils_populateIndex layoutId, "apartmentSuite", database(user, 4)
    layoutUtils_populateIndex layoutId, "city", database(user, 5)
    layoutUtils_populateIndex layoutId, "stateProvince", database(user, 6)
    layoutUtils_populateIndex layoutId, "zipPostal", database(user, 7)
    layoutUtils_populateIndex layoutId, "country", database(user, 8)
end sub

'==================================================================
' Subroutine: populateLayout2
' Fills placeholders in the User List layout
'==================================================================
sub populateLayout2 (layoutName as string, database() as string)
    layoutUtils_reset layoutName
    layoutUtils_populate layoutName, "last1", database(1, 1)
    layoutUtils_populate layoutName, "first1", database(1, 2)
    layoutUtils_populate layoutName, "city1", database(1, 5)
    layoutUtils_populate layoutName, "state1", database(1, 6)
    layoutUtils_populate layoutName, "last2", database(2, 1)
    layoutUtils_populate layoutName, "first2", database(2, 2)
    layoutUtils_populate layoutName, "city2", database(2, 5)
    layoutUtils_populate layoutName, "state2", database(2, 6)
    layoutUtils_populate layoutName, "last3", database(3, 1)
    layoutUtils_populate layoutName, "first3", database(3, 2)
    layoutUtils_populate layoutName, "city3", database(3, 5)
    layoutUtils_populate layoutName, "state3", database(3, 6)
end sub

'==================================================================
' Subroutine: refreshDestWithLayout
' Renders a populated layout into the specified destination buffer
'==================================================================
sub refreshDestWithLayout (layoutName as string, destination as double)
    dim prevDestination
    prevDestination = _dest         ' Remember previous drawing target
    _dest destination               ' Switch to the off‐screen buffer
    cls , _rgba(0,0,0,0)            ' Clear with fully transparent background
    _printmode _KEEPBACKGROUND      ' Preserve any background pixels
    print layoutUtils_getPopulated(layoutName)   ' Print layout text
    _dest prevDestination           ' Restore the original drawing target
end sub

'==================================================================
' Subroutine: drawCircle
' Draws an animated pulsing circle at the center of the screen
'==================================================================
sub drawCircle ()
    static growing as integer
    static rFactor as single
    dim cx%, cy%, r%

    cx% = _width / 2
    cy% = _height / 2

    ' Initialize animation parameters on first run
    if rFactor = 0 then
        rFactor = 0.10
        growing = 1
    end if

    ' Pulse the radius factor up and down
    if growing then
        rFactor = rFactor + 0.001
        if rFactor >= 0.48 then growing = 0
    else
        rFactor = rFactor - 0.001
        if rFactor <= 0.10 then growing = 1
    end if

    r% = rFactor * _min(_width, _height)
    circle (cx%, cy%), r%, _rgba(255,255,0,100)
end sub

'==================================================================
' Subroutine: drawTriangle
' Draws a continuously rotating semi‐transparent triangle
'==================================================================
sub drawTriangle ()
    static angleOffset#
    angleOffset# = angleOffset# - _pi / 180   ' Decrease rotation by 1° each frame

    dim cx%, cy%, r%
    cx% = _width / 2
    cy% = _height / 2
    r% = 0.48 * _min(_width, _height)

    ' Calculate the three vertex angles
    dim angle1#, angle2#, angle3#
    angle1# = angleOffset#
    angle2# = angleOffset# + 2 * _pi / 3
    angle3# = angleOffset# + 4 * _pi / 3

    ' Compute vertex coordinates
    dim x1%, y1%, x2%, y2%, x3%, y3%
    x1% = cx% + r% * cos(angle1#)
    y1% = cy% - r% * sin(angle1#)
    x2% = cx% + r% * cos(angle2#)
    y2% = cy% - r% * sin(angle2#)
    x3% = cx% + r% * cos(angle3#)
    y3% = cy% - r% * sin(angle3#)

    ' Draw triangle edges
    line (x1%, y1%)-(x2%, y2%), _rgba(0,255,0,100)
    line (x2%, y2%)-(x3%, y3%), _rgba(0,255,0,100)
    line (x3%, y3%)-(x1%, y1%), _rgba(0,255,0,100)
end sub

' Include the binary module for layoutUtils implementation
'$include: '../library/layoutUtils.bm'
Reply


Messages In This Thread
layoutUtils (library for text layout) - by Herve - 07-14-2025, 09:10 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Format Library eoredson 8 388 02-28-2026, 03:31 AM
Last Post: eoredson
  SPV Video library. ahenry3068 10 571 01-21-2026, 06:46 PM
Last Post: ahenry3068
  Large 2D Graphics Library TarotRedhand 6 2,566 12-05-2023, 05:17 AM
Last Post: grymmjack
  Huge Matrices Library [Updated] TarotRedhand 8 2,568 05-17-2022, 11:42 AM
Last Post: TarotRedhand

Forum Jump:


Users browsing this thread: 1 Guest(s)