Word Wrap Textbox

This function will wrap the text in the named textbox (or all textboxes on the top graph) to the indicated size. Adapted from "Word Wrap Control Text" by Adam Light (aclight).

Function/S WordWrapTextBox(textBoxName,wrapWidth[,windowName])
    String textBoxName
    Variable wrapWidth
    String windowName
   
    if(ParamIsDefault(windowName))
        windowName=WinName(0,5)
    endif
    Variable layout_=(WinType(windowName)==3)
    if(!strlen(textBoxName))
        String annotations=AnnotationList(windowName)
        Variable i,textboxes
        for(i=0;i<ItemsInList(annotations);i+=1)
            String info=AnnotationInfo(windowName,textBoxName,1)
            String type=StringByKey("TYPE",info)
            if(StringMatch(type,"Textbox")) // Apply word wrapping to textboxes in graphs and layouts.  
                textboxName=StringFromList(i,annotations)
                if(layout_) // Layout
                    String layout_info=LayoutInfo(windowName,textboxName)
                    Variable selected=NumberByKey("SELECTED",layout_info)
                    if(!selected)
                        continue // Only apply word wrapping to selected textboxes in layouts.  
                    endif
                endif
                String result=WordWrapTextBox(textboxName,wrapWidth,windowName=windowName)
                textboxes+=1
            endif
        endfor
        if(textboxes==0)
            return ""
        else
            return result
        endif
    endif
   
    Variable currentLineNum = 0
    // determine the dimensions of the control where this text will be placed
   
    info=AnnotationInfo(windowName,textBoxName,1)
    if(strlen(info))       
        String textStr=StringByKey("TEXT",info)
        String rect=StringByKey("RECT",info)
        Variable left,top,right,bottom
        sscanf rect,"%f,%f,%f,%f",left,top,right,bottom
        Variable textHeight=bottom-top
    else                        // Textbox doesn't exist.
        return ""              
    endif
   
    // Protect double carriage returns and carriage returns followed by tabs.  
    textStr=ReplaceString("\r\r",textStr,"<|r>")
    textStr=ReplaceString("\r\t",textStr,"<|t>")
    // Kill old carriage returns.  
    textStr=ReplaceString("\r",textStr,"")
    // Bring back protected characters.  
    textStr=ReplaceString("<|r>",textStr,"\r\r")
    textStr=ReplaceString("<|t>",textStr,"\r\t")

    Make /o/T/n=0 outputTextWave
    String returnTextStr=""
    Variable firstLineNum=0

    // get the font information for the default font used in this panel
    if(layout_)
        DefaultGuiFont all
    else
        DefaultGuiFont/W=$(windowName) all
    endif
    String defaultFontName = S_name
    Variable defaultTextFontSize = V_value
    Variable defaultTextFontStyle = V_flag

    // now read information from title control to see if
    // a non-default font size, style, or name is being used   
    Variable textFontSize=NaN, textFontStyle=NaN
    String fontName, escapedFontName
    sscanf textStr,"\Z%d",textfontSize
    if (numtype(textFontSize) != 0)     // default font size is used
        textFontSize = defaultTextFontSize
        if (numtype(textFontSize) != 0)
            textFontSize = 12
        endif
    endif
    sscanf textStr,"\f%d",textfontStyle
    if (numtype(textFontStyle) != 0)        // default font style is used
        textFontStyle = defaultTextFontStyle
        if (numtype(textFontStyle) != 0)
            textFontStyle = 0
        endif
    endif      
    sscanf textStr,"\S'%[A-Za-z]'",fontName
    if (cmpstr(fontName, "") == 0)  // no font name found
        fontName = defaultFontName
        if (cmpstr(fontName, "") == 0)      // will be true if S_name above is ""
            fontName = GetDefaultFont(windowName)
        endif
    endif
   
    // Determine the height, in pixels, of a line of text
    Variable lineHeight = FontSizeHeight(fontName, textFontSize, textFontStyle)
    Variable maxNumLines = Inf//floor(textHeight / lineHeight)

    // search for spaces, check length of string up to that point + length of new text, and decide whether
    // to add the new word or add a line break
    Variable sourceStringPos = 0
    Variable nextSpacePos, nextCRPos, nextBreakPos
    Variable currentTextWidth, newTextWidth
    Variable breakIsCR = 0
    String nextWordString = ""
    String currentLineString = ""

    do
        nextSpacePos = strsearch(textStr, " ", sourceStringPos)
        nextSpacePos = nextSpacePos >= 0 ? nextSpacePos : inf       // set to inf if space is not found
        nextCRPos = strsearch(textStr, "\r", sourceStringPos)
        nextCRPos = nextCRPos >= 0 ? nextCRPos : inf        // set to inf if \r is not found
        if (nextCRPos >= 0 && nextCRPos < nextSpacePos)
            breakIsCR = 1
        else
            breakIsCR = 0
        endif
        nextBreakPos = min(nextSpacePos, nextCRPos)

        if (numtype(nextBreakPos) == 1)     // nextBreakPos == inf means there are no more spaces or \r
            if (strlen(textStr) == sourceStringPos) // at the end of the string
                returnTextStr += currentLineString 
                break
            else
                nextWordString = textStr[sourceStringPos, inf]
                sourceStringPos = strlen(textStr)
            endif
        else
            nextWordString = textStr[sourceStringPos, nextBreakPos]
        endif
        currentTextWidth = FontSizeStringWidth(fontName, textFontSize, textFontStyle, currentLineString)
        newTextWidth = FontSizeStringWidth(fontName, textFontSize, textFontStyle, nextWordString)
        if ((currentTextWidth + newTextWidth + 5) <= wrapWidth)     // add this word        // leave 5px padding
            currentLineString += nextWordString
            if (numtype(nextBreakPos) == 1)
                break
            elseif (breakIsCR)
                sourceStringPos = nextBreakPos + 1
                returnTextStr += currentLineString
                Redimension/N=(currentLineNum + 1) outputTextWave
                outputTextWave[currentLineNum] = currentLineString
                currentLineString = ""
                currentLineNum += 1
            else
                sourceStringPos = nextBreakPos + 1
            endif
        else                                                    // add a new line and then add this word
            returnTextStr += currentLineString
            returnTextStr += "\r"
            Redimension/N=(currentLineNum + 1) outputTextWave
            outputTextWave[currentLineNum] = currentLineString + "\r"
            currentLineNum += 1
            currentLineString = nextWordString
            if (numtype(nextBreakPos) == 1)
                break
            else
                sourceStringPos = nextBreakPos + 1
            endif
        endif
    while(sourceStringPos < strlen(textStr) - 1)
    returnTextStr += currentLineString      // add last part of string to return string
    Redimension/N=(currentLineNum + 1) outputTextWave
    outputTextWave[currentLineNum] = currentLineString + "\r"
   
    Variable n
    String finalOutputString = ""
    Variable numLinesToReturn = min(DimSize(outputTextWave, 0), maxNumLines + firstLineNum)
    For (n=firstLineNum; n<numLinesToReturn; n+=1)
        finalOutputString += outputTextWave[n]
    EndFor
    finalOutputString=RemoveEnding(finalOutputString,"\r")
   
    KillWaves /Z outputTextWave
    Textbox /W=$windowName /C/N=$textboxName finalOutputString
    return finalOutputString
End

Forum

Support

Gallery

Igor Pro 8

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More