Indeed there is no easy cross-platform way. But already 5 years ago I have posted
cross-platform code example in the German forum which allows to use text tags to convert marked text into bold, italic and underlined text. In MacOS and Windows the text is transformed into the RTF text format. Since Linux doesn't support the RTF format, the marked text is converted using GTK tags. Therefore you currently have to exchange marked text between the different operating systems before displaying it in the EditorGadget because the text in Linux - as mentioned - doesn't use the RTF format. But my special format
displaying it in the EditorGadget is cross-platform.
I have modified the source code to also support strikethrough text by extending the tag definitions in the data section. I have successfully tested the modified source code on these operating systems:
Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC ""
gtk_text_buffer_create_tag(*Buffer.GtkTextBuffer, TagCharacter.P-UTF8,
PropertyName.P-UTF8, PropertyValue.I, Terminator.I = 0)
EndImport
CompilerEndIf
Structure TagEntry
Character.S
AttributeName.S
StartOffset.I
EndOffset.I
EndStructure
Procedure AddTextWithAttributes(EditorGadgetID.I, AttributeText.S)
Static NewList Tag.TagEntry()
Protected Offset.I
Protected RTFTag.S
Protected TagCharacter.S
Protected TagList.S
Protected TagOffset.I
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
Static TagTable.I
Protected AttributeValue.S
Protected EndIter.GtkTextIter
Protected NewTextOffset.I
Protected StartIter.GtkTextIter
Protected *TextBuffer = gtk_text_view_get_buffer_(0 +
GadgetID(EditorGadgetID))
CompilerCase #PB_OS_MacOS
Protected AttributeString.I
Protected AttributeTextASCII.S
Protected DataObject.I
Protected TextStorage.I
CompilerCase #PB_OS_Windows
Protected AttributeTextASCII.S
CompilerEndSelect
; ----- On first call create new tag table and define RTF tags (for MacOS and
; and Windows) or the Linux-specific tags
If ListSize(Tag()) = 0
Repeat
Read.S TagCharacter
If TagCharacter = ""
Break
Else
AddElement(Tag())
Tag()\Character = TagCharacter
Read.S Tag()\AttributeName
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Read.S AttributeValue
gtk_text_buffer_create_tag(*TextBuffer, Tag()\Character,
Tag()\AttributeName, Val(AttributeValue))
CompilerEndIf
EndIf
ForEver
Else
ForEach Tag()
Tag()\StartOffset = 0
Tag()\EndOffset = 0
Next
EndIf
; ----- Find all tags and fill in tag character, attribute name, start-
; and stop offset in LinkedList Tag()
Repeat
Offset = FindString(AttributeText, "[")
If Offset = 0
Break
Else
TagList = ""
TagOffset = Offset + 1
RTFTag = "{"
Repeat
TagCharacter = Mid(AttributeText, TagOffset, 1)
If TagCharacter = "]"
Break
Else
If FindString(TagList, TagCharacter) = 0
TagList + TagCharacter
EndIf
ForEach Tag()
If Tag()\Character = TagCharacter
If Tag()\StartOffset = 0
Tag()\StartOffset = Offset
RTFTag + "\" + Tag()\AttributeName + " "
Else
Tag()\EndOffset = Offset
RTFTag = "}"
EndIf
Break
EndIf
Next
EndIf
TagOffset + 1
ForEver
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
AttributeText = ReplaceString(AttributeText, "[" + TagList + "]", "",
#PB_String_NoCase, Offset, 1)
CompilerElse
AttributeText = ReplaceString(AttributeText, "[" + TagList + "]",
RTFTag, #PB_String_NoCase, Offset, 1)
AttributeText = ReplaceString(AttributeText, #CR$, "\line")
CompilerEndIf
TagList = ""
EndIf
ForEver
; ----- Append new text with attributes at already existing text
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
NewTextOffset = gtk_text_buffer_get_char_count_(*TextBuffer)
gtk_text_buffer_get_end_iter_(*TextBuffer, @EndIter)
gtk_text_buffer_insert_(*TextBuffer, @EndIter, AttributeText, -1)
If ListSize(Tag()) > 0
; ----- Fill in all tags from list in *TextBuffer
ForEach Tag()
gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @StartIter,
NewTextOffset + Tag()\StartOffset - 1)
gtk_text_buffer_get_iter_at_offset_(*TextBuffer, @EndIter,
NewTextOffset + Tag()\EndOffset - 1)
gtk_text_buffer_apply_tag_by_name_(*TextBuffer, Tag()\Character,
@StartIter, @EndIter)
Next
EndIf
CompilerCase #PB_OS_MacOS
AttributeText = "{\rtf1" + AttributeText + "}"
AttributeTextASCII = Space(StringByteLength(AttributeText, #PB_Ascii))
PokeS(@AttributeTextASCII, AttributeText, -1, #PB_Ascii)
DataObject = CocoaMessage(0, 0,
"NSData dataWithBytes:", @AttributeTextASCII,
"length:", Len(AttributeText))
If DataObject
AttributeString = CocoaMessage(0, 0, "NSAttributedString alloc")
CocoaMessage(@AttributeString, AttributeString,
"initWithRTF:@", @DataObject,
"documentAttributes:", 0)
If AttributeString
TextStorage = CocoaMessage(0, GadgetID(0), "textStorage")
CocoaMessage(0, TextStorage, "appendAttributedString:",
AttributeString)
CocoaMessage(0, AttributeString, "release")
EndIf
; ----- Automatically set correct text color in light and dark mode
CocoaMessage(0, GadgetID(EditorGadgetID),
"setTextColor:", CocoaMessage(0, 0, "NSColor textColor"))
EndIf
CompilerCase #PB_OS_Windows
AttributeText = "{\rtf1" + AttributeText + "}"
AttributeTextASCII = Space(StringByteLength(AttributeText, #PB_Ascii))
PokeS(@AttributeTextASCII, AttributeText, -1, #PB_Ascii)
SendMessage_(GadgetID(EditorGadgetID), #EM_SETSEL, -1, -1)
SendMessage_(GadgetID(EditorGadgetID), #EM_REPLACESEL, 0,
AttributeTextASCII)
CompilerEndSelect
EndProcedure
OpenWindow(0, 100, 100, 400, 100, "EditorGadget with text attributes")
EditorGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
AddTextWithAttributes(0,
"This is [b]bold text[b] and the following is [u]underlined[u]." + #CR$)
AddTextWithAttributes(0, "Now follows [i]italic[i] and [s]strikethrough[s]." +
#CR$)
AddTextWithAttributes(0,
"And combined [biu]bold, italic and underlined[biu].")
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
End
; ----- Tag definitions
DataSection
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Data.S "b", "weight", "700"
Data.S "i", "style", "2"
Data.S "s", "strikethrough", "1"
Data.S "u", "underline", "1"
CompilerElse
Data.S "b", "b"
Data.S "i", "i"
Data.S "s", "strike"
Data.S "u", "ul"
CompilerEndIf
Data.S ""
EndDataSection