Word Wrap Textbox

Takes the text box with name 'textBoxName' (or for textBoxName="", all textboxes in a graph or all selected textboxes in a layout) in the top window or in window 'windowName', and adds deletes carriage returns to wrap lines to achieve a width of 'wrapWidth'. Adapted from the WordWrapControlText package created by Adam Light.



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 is 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 textbox 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
I just added in the proper tags to make the Igor code readable.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More