Here is a complete example.
Code: Select all
; v1.01, tested with PB 5.10 on Windows XP x86 (should be cross-platform, though)
Procedure.i GetTextWidth (window.i, gadget.i, text$)
; in : window: window number
; gadget: gadget number
; text$ : This function does not require that the text is
; actually shown in the gadget.
; out: width of text$ in pixels
Protected width.i=-1
If StartDrawing(WindowOutput(window))
DrawingFont(GetGadgetFont(gadget))
width = TextWidth(text$)
StopDrawing()
EndIf
ProcedureReturn width ; -1 on error
EndProcedure
Procedure.i GetTextLen (window.i, gadget.i, text$, width.i)
; in : window: window number
; gadget: gadget number
; width : available width in pixels
; text$ : This function does not require that the text is
; actually shown in the gadget.
; out: maximum number of characters of text$ (counted from the left)
; which fit into the available width
Protected length.i=-1
If StartDrawing(WindowOutput(window))
DrawingFont(GetGadgetFont(gadget))
length = Len(text$)
While length > 0 And TextWidth(Left(text$, length)) > width
length - 1
Wend
StopDrawing()
EndIf
ProcedureReturn length ; -1 on error
EndProcedure
Procedure.s LineWrapW (window.i, gadget.i, line$, softWrapWidth.i, hardWrapWidth.i=-1, delimList$=" "+Chr(9), nl$=#LF$, indent$="")
; -- Word wrap in *one line* in a window (can have a variable-width font)
; in: line$ : line which is to be wrapped
; indent$: "" or a string consisting of blanks, used for indenting lines of list items
;
; For the meaning of the other parameters see function WordWrapW().
Protected.i posn, found, i, softWrapPosn, hardWrapPosn, firstChar=Len(indent$)+1
Protected ret$=""
softWrapPosn = GetTextLen(window, gadget, line$, softWrapWidth)
If softWrapPosn < firstChar
ProcedureReturn line$
EndIf
posn = Len(line$)
While posn > softWrapPosn
; search for rightmost delimiter <= softWrapPosn:
For i = softWrapPosn To firstChar Step -1
found = FindString(delimList$, Mid(line$,i,1))
If found
posn = i
Break
EndIf
Next
If found = 0 ; if there is no delimiter <= softWrapPosn
If hardWrapWidth < 0
; insert hard wrap at position of soft wrap:
posn = softWrapPosn
Else
; search for leftmost delimiter > softWrapPosn:
For i = softWrapPosn+1 To posn
found = FindString(delimList$, Mid(line$,i,1))
If found
posn = i
Break
EndIf
Next
If hardWrapWidth > 0
hardWrapPosn = GetTextLen(window, gadget, line$, hardWrapWidth)
If hardWrapPosn < posn
; insert hard wrap at given position:
posn = hardWrapPosn
EndIf
EndIf
EndIf
EndIf
ret$ + RTrim(Left(line$, posn)) + nl$
line$ = LTrim(Mid(line$, posn+1))
If line$ <> ""
line$ = indent$ + line$
EndIf
softWrapPosn = GetTextLen(window, gadget, line$, softWrapWidth)
posn = Len(line$)
Wend
ProcedureReturn ret$ + line$
EndProcedure
Procedure.s WordWrapW (window.i, gadget.i, text$, softWrapWidth.i, hardWrapWidth.i=-1, delimList$=" "+Chr(9), nl$=#LF$, liStart$="")
; ## Main function ##
; -- Word wrap in *one or more lines* in a window (can have a variable-width font)
; in : window : window number
; gadget : gadget number
; text$ : text which is to be wrapped;
; may contain #CRLF$ (Windows), or #LF$ (Linux and modern Mac systems) as line breaks
; softWrapWidth: the desired maximum width (pixels) of each resulting line
; if a delimiter was found (not counting the length of the inserted nl$);
; if no delimiter was found at a position <= softWrapWidth, a line might
; still be longer if hardWrapWidth = 0 or > softWrapWidth
; hardWrapWidth: guaranteed maximum width (pixels) of each resulting line
; (not counting the length of the inserted nl$);
; if hardWrapWidth <> 0, each line will be wrapped at the latest at
; hardWrapWidth, even if it doesn't contain a delimiter;
; default setting: hardWrapWidth = softWrapWidth
; delimList$ : list of characters which are used as delimiters;
; any delimiter in line$ denotes a position where a soft wrap is allowed
; nl$ : string to be used as line break (normally #CRLF$ or #LF$)
; liStart$ : string at the beginning of each list item
; (providing this information makes proper indentation possible)
;
; out: return value : text$ with given nl$ inserted at appropriate positions
;
; <http://www.purebasic.fr/english/viewtopic.php?f=12&t=53800>
Protected.i numLines, i, indentPixels, indentLen=-1
Protected line$, indent$, ret$=""
numLines = CountString(text$, #LF$) + 1
For i = 1 To numLines
line$ = RTrim(StringField(text$, i, #LF$), #CR$)
If FindString(line$, liStart$) = 1
If indentLen = -1
indentPixels = GetTextWidth(window, gadget, liStart$)
indentLen = GetTextLen(window, gadget, Space(Len(text$)), indentPixels)
EndIf
indent$ = Space(indentLen)
Else
indent$ = ""
EndIf
ret$ + LineWrapW(window, gadget, line$, softWrapWidth, hardWrapWidth, delimList$, nl$, indent$)
If i < numLines
ret$ + nl$
EndIf
Next
ProcedureReturn ret$
EndProcedure
EnableExplicit
;XIncludeFile "WordWrapW.pbi"
LoadFont(0, "Courier", 14)
Procedure ShowWindow (title$, text$, softWrapWidth.i, hardWrapWidth.i=-1, delimList$=" "+Chr(9), nl$=#LF$, liStart$="")
If OpenWindow(0, 0, 0, 450, 650, title$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
MessageRequester("Fatal error", "Program terminated.")
End
EndIf
TextGadget(0, 10, 10, 430, 330, "")
Protected text1$ = WordWrapW(0, 0, text$, softWrapWidth-12, hardWrapWidth, delimList$, nl$, liStart$)
SetGadgetText(0, ReplaceString(text1$, " ", "*"))
SetGadgetColor(0, #PB_Gadget_BackColor, $CCBFB4)
SetGadgetFont(0,FontID(0) )
EditorGadget(10, 10, 350, softWrapWidth, 200, #PB_Editor_WordWrap)
SetGadgetText(10, text$)
SetGadgetFont(10,FontID(0) )
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
CloseWindow(0)
EndProcedure
Define line$, text$
line$ = "Vertical & Horizontal" + #LF$ + " Centered Text in " + #LF$ + "Multiline StringGadget"
ShowWindow("Word wrap demo", line$, 104)
The result should be.
it was so obvious to me that I didn’t think okay excuse me that I wasted your time in vain.