wtf GUI Frameworks... rant I guess

Everything else that doesn't fall into one of the other PB categories.
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: wtf GUI Frameworks... rant I guess

Post by TomS »

Yes. That's the beauty of a map (assoziative array) like list. You can put whatever you want as a key.
Well RTF is fairly complicated if you want to use its full power. And it's kinda stupid (the colortable thing). But it's been sued before. Like I said I got the idea from a chat programm (irc like) where all the formattign was done via rtf. There was even a section in the manual about some basic rtf styles that were not available through the program's buttons.
Anyway I think Scintilla suits most programmers better. With its callbacks and everything.
But RTF has one big advantage over Scintilla: It can display images :D
Which kinda makes it ideal for a chat.
But there's still a limitation about contentlenght in the EditorGadget. I think it was 65k Characters or something.
Many don't even know about the capabilities of the EditorGadget. They think it's just a multiline StringGadget.
Maybe some people consider using RTF instead of Scintilla, when I announce the alpha lib. Who knows ;)
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

edit: I am an idiot... I fixed the problem I posted about..
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

Ok!
I had some stupid n00b trials and tribulations.. like for some reason I thought it was smart to put a semicolon after my (RTF) R/G/B defines and that was fun to debug!
Remember: \redxxx\greenxxx\bluexxx; not \redxxx;\greenxxx;\bluexxx; !! :p
And then I forgot to assign the result of my ReplaceString() operations to an actual variable! (which lead to the above post I deleted) lulz..

It's not finished but I wanted to show my progress anyway... Here is my Color parsing! It uses opening and closing tags,
like so:

Code: Select all

<color=colorname>blahblah</color>
And now that I actually have it working, I will start adding in support for multiple fonts, and basic text styling such as bold & italics.. Perhaps underlined as well. I'm not sure yet.
The code below is a self contained Demo, so just copy and paste :)
I figured since I was working on a text game, I would Demo what my room descriptions will look like too. I haven't decided on the final colors for the default theme, but these are pretty close.

Code: Select all

;// Defining Structures to hold Font and Color data
;// that will be used to build the reference Tables
;// and RTF Header we will be using.
;//
Structure Color_RGB       ;//Hold RGB Color values in ColorTable.
  r.i
  g.i
  b.i
EndStructure

Structure ColorTable      ;// Main Structure for List of Colors.
  name.s
  color.Color_RGB
  colorID.i
EndStructure

Structure FontTable       ;// Main Structure for List of Fonts.
  name.s
  fontID.i
EndStructure





;// Creating Linked Lists to hold Color and Font data so we can
;// change the look of text on the fly, during Run Time.
NewList Color_Table.ColorTable()
NewList Font_Table.FontTable()





;// Variables to hold generated ID numbers for use in an RTF
;// Header that will be generated later on.
;//
Global ColorIndex.i
Global FontIndex.i
Global rtf_header.s




;// This Procedure assembles the Color Table from input passed to
;// it during Runtime.  Each entry in the Linked List has a color
;// name attached to it, as well as the HEX (*BGR) value of that
;// color, and a generated ID number which corresponds to it's
;// ID within the RTF header when it is generated later.
;//
Procedure Build_Color_Table(name.s, r.i, g.i, b.i)
  
  Shared Color_Table()
  
  ForEach Color_Table()
    If Color_Table()\name = name
      ProcedureReturn #False
    EndIf
  Next
  
  
  AddElement(Color_Table())
  Color_Table()\name = name
  Color_Table()\color\r = r
  Color_Table()\color\g = g
  Color_Table()\color\b = b
  Color_Table()\colorID = 0
  ProcedureReturn #True
  
EndProcedure





;// This Procedure will parse all text sent to the text box.
;// Its job is to parse each line for Color and Font tags
;// which will determine what the text looks like.  It will
;// build the proper RTF header and convert the formating
;// tags into RTF Formating Syntax.
;//
Procedure.s Format(input.s)
  Protected header.s, footer.s, ColorIndex.i
  Shared Color_Table()
  
  
  ;// Build our initial RTF Header
  SelectElement(Color_Table(), 0)
  header = "{\rtf {\colortbl;" + "\red" +Str(Color_Table()\color\r)+"\green"+Str(Color_Table()\color\g)+"\blue"+Str(Color_Table()\color\b)+";"
  
  
  ;// Copy current input string to a temporary working variable.
 
  ;// Make sure the index is reset to 1
  ColorIndex = 1

 ;// For some reason the default text color will not apply to the next line, if we post a line previously, whose only text is contained within color tags.
 ;// so we add a call for the default text color to each new line.
  input = "\cf1" + input
  
  
  ;// Repeat this task for every color in the table. Here we are
  ;// searching the input string for any occurence of a color tag
  ;// and matching it to the name of the color, within the Table.
  ;// Then we assign an Index ID which will also serve as its RTF
  ;//    \cf  ID.  If it works properly they should all match up
  ;// to the proper colors.  This will be used to include color
  ;// formats in the header ONLY for colors present in the input
  ;// string; saves time and memory.
  ResetList(Color_Table())
  ForEach Color_Table() 
    If FindString(input, "<color=" +Color_Table()\name +">",1) <> 0
      
      ;// Increment and assign an index number.
      ColorIndex +1
      Color_Table()\colorID = ColorIndex
      
      ;// Add color to the Color Table.
      header = header + "\red"+Str(Color_Table()\color\r)+"\green"+Str(Color_Table()\color\g)+"\blue"+Str(Color_Table()\color\b)+";"
    EndIf
  Next
  
  
  ;// Now we repeat the same task above, with a slightly different
  ;// command.  We will replace the color/font/styling tags with 
  ;// the proper RTF Syntax commands.
  
  ResetList(Color_Table())
  ForEach Color_Table()
    input = ReplaceString(input, "<color=" + Color_Table()\name + ">", "\cf" +Str(Color_Table()\colorID))
    
  Next
  
  ;// Look for closing tags to restore the default color, font, and styling.
  input = ReplaceString(input, "</color>", "\cf1 ")
  
  header = header + "}"
  footer = "}"
  ProcedureReturn header + input + footer
EndProcedure





;// Create the Color Table. Colors are stored as RGB
;// and will be parsed by name.
;//
Build_Color_Table("DefaultText",     119,  136,  153)
Build_Color_Table("RoomTitle",       255,  255,  255)
Build_Color_Table("RoomList",        255,  0,    0)
Build_Color_Table("RoomNPC",         43,   225,  0)
Build_Color_Table("RoomExits",       0,    116,  107)
Build_Color_Table("blue",            54,   0,    237)
Build_Color_Table("brightgreen",     0,    238,  0)
Build_Color_Table("brown",           153,  102,  0)
Build_Color_Table("darkred",         203,  32,   38)
Build_Color_Table("forestgreen",     34,   139,  34)
Build_Color_Table("gold",            254,  204,  0)
Build_Color_Table("green",           0,    204,  0)
Build_Color_Table("grey",            204,  204,  204)
Build_Color_Table("lightblue",       24,   116,  205)
Build_Color_Table("orange",          255,  140,  0)
Build_Color_Table("red",             255,  0,    0)
Build_Color_Table("slateblue",       0,    127,  255)
Build_Color_Table("teal",            0,    128,  128)
Build_Color_Table("white",           255,  255,  255)

Build_Color_Table("yellow",          255,  255,  0)

;///////////////////////////////
;///////////////////////////////
;Test Code Below
;///////////////////////////////
;///////////////////////////////

OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
EditorGadget(0, 0, 0, 600, 400,  #PB_Editor_ReadOnly)
SetGadgetColor(0, #PB_Gadget_BackColor, $000000)
SendMessage_(GadgetID(0), #EM_SETTARGETDEVICE, #Null, 0)
AddGadgetItem(0, -1, Format("<color=RoomTitle>[Kirkhill, Town Center]</color>"))
AddGadgetItem(0, -1, Format("You are standing in the center of Kirkhill.  A large Japanese Maple stands before you ominously, as if beckoning for you to climb it.  Beneath the tree, children are playing a game of tag, filling the air with their lighthearted laughter.  In the distance you can see the peak of Tarn Kolag which marks the territorial boundary between The Darkan Lordship and The Wastelands."))
AddGadgetItem(0, -1, Format("<color=RoomList>You also see:</color> A modest sized bronze statue of Eric and Neco Darkan."))
AddGadgetItem(0, -1, Format("<color=RoomNPC>Also here:</color> A wandering Street Merchant, Ovelia the Blacksmith, a pet dog."))
AddGadgetItem(0, -1, Format("<color=RoomExits>Obvious Exits:</color> Northeast, North, East, South, Southwest, West."))

Repeat
   event = WaitWindowEvent(20)   
Until event = #PB_Event_CloseWindow
Image
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: wtf GUI Frameworks... rant I guess

Post by TomS »

So in essence it's the same as my version? Just tidier :P
And with a default color other than black.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

Pretty much, yes.. Remember I said we pretty much had the same idea :P

I am pretty stubborn about trying to keep my code neat and readable, well commented 8)
I think the only real difference, is I store RGB values instead of convert them from Hex.

Once I get the font, and styling tag parsing put in, the only thing left for me to do with it would be to implement reading values in from a settings File.
Image
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: wtf GUI Frameworks... rant I guess

Post by TomS »

Well. You can find styles like bold, italic and underlined in my code.
There are certain "templates" for fonts. They are font families that have their own tag http://www.biblioscape.com/rtf15_spec.htm#Heading12
For any other fonts you have to use a font table.

The reading of a settings-file should be the easy part :lol:
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by IdeasVacuum »

TomS wrote:But the editorgadget doesn't support the new xml-format.
To display an existing rtf-file, you just have to get its contents and use SetGadgetText() on the editor gadget. Then you just need to change the path of the image(s) and you're done.
Hi TomS

I didn't realise that PB's Editor Gadget was so powerful. Can you expand upon how to display an rtf file? I don't get you re changing the path of the images.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

TomS wrote:Well. You can find styles like bold, italic and underlined in my code.
There are certain "templates" for fonts. They are font families that have their own tag http://www.biblioscape.com/rtf15_spec.htm#Heading12
For any other fonts you have to use a font table.

The reading of a settings-file should be the easy part :lol:
I'm familiar with most of the formatting commands I'll need to do, instead of refering to a big documentation from the start, I actually found it easier to follow a tutorial I found through google at http://www.pindari.com/
Image
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: wtf GUI Frameworks... rant I guess

Post by TomS »

IdeasVacuum:

Well I thought that images are linked instead of integrated in the file. Maybe there's an option for that. I will have to look into it.
But a quick test showed that the images are stored as text within the file and takes double the space because Microsoft doesn't use Hex to store the 3 colors per pixel in 3 bytes but uses plain text (000000 =black and FFFFFF=white) :? (Ok. Binary is possible, too).

Either wordpad has a better (more adapted to microsofts bullshit changes in each and every fileformat) RTF parser or I'm missing something.
My quick 'n' dirty example. But no image :|
Everything else (style, font, color etc) works as expected.

Code: Select all

OpenWindow(0,0,0,800,600,"",#PB_Window_SystemMenu)
EditorGadget(0,0,0,800,600)

file$="Dokument.rtf"
If file$
	If ReadFile(0, file$) 
		While Not Eof(0)
			string$ = string$ + ReadString(0) + #CRLF$
		Wend 
	EndIf
EndIf

SetGadgetText(0, string$)

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow 
@Zach: Nice find. Thanks. I was using this: http://www.biblioscape.com/rtf15_spec.htm
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

I'll probably consult your link and MSDN now that I am more familiar with RTF.. I can definitely see a lot of uses for other things like lists, and tables to keep certain data formatted nicely when printed..

I almost wonder if I shouldn't have just implemented RTF directly, but then I'd lose data portability :evil:
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

(preface: I have been away from coding for a few years and trying to get back into things, starting with this)

OK so, I can't figure out why this code is now broken. I'm not sure if its a Windows 10 / RTF spec thing, or something related to Purebasic. This code was written on a much older version, probably 5.21 LTS or somewhere around that point. TomS's original example in this thread also does not work.

It seems to be passing the text through without recognizing the RTF tags; and I'm just not sure why. Maybe a header format has changed? idk. But I did make an RTF file in Wordpad, save it, and load it into a purebasic editorgadget and it displayed just fine.


Can anyone provide any insight as to what is going on with this code? I am currently using PB x64 version 5.61 under Windows 10 LTSB.
Zach wrote:Ok!
I had some stupid n00b trials and tribulations.. like for some reason I thought it was smart to put a semicolon after my (RTF) R/G/B defines and that was fun to debug!
Remember: \redxxx\greenxxx\bluexxx; not \redxxx;\greenxxx;\bluexxx; !! :p
And then I forgot to assign the result of my ReplaceString() operations to an actual variable! (which lead to the above post I deleted) lulz..

It's not finished but I wanted to show my progress anyway... Here is my Color parsing! It uses opening and closing tags,
like so:

Code: Select all

<color=colorname>blahblah</color>
And now that I actually have it working, I will start adding in support for multiple fonts, and basic text styling such as bold & italics.. Perhaps underlined as well. I'm not sure yet.
The code below is a self contained Demo, so just copy and paste :)
I figured since I was working on a text game, I would Demo what my room descriptions will look like too. I haven't decided on the final colors for the default theme, but these are pretty close.

Code: Select all

;// Defining Structures to hold Font and Color data
;// that will be used to build the reference Tables
;// and RTF Header we will be using.
;//
Structure Color_RGB       ;//Hold RGB Color values in ColorTable.
  r.i
  g.i
  b.i
EndStructure

Structure ColorTable      ;// Main Structure for List of Colors.
  name.s
  color.Color_RGB
  colorID.i
EndStructure

Structure FontTable       ;// Main Structure for List of Fonts.
  name.s
  fontID.i
EndStructure





;// Creating Linked Lists to hold Color and Font data so we can
;// change the look of text on the fly, during Run Time.
NewList Color_Table.ColorTable()
NewList Font_Table.FontTable()





;// Variables to hold generated ID numbers for use in an RTF
;// Header that will be generated later on.
;//
Global ColorIndex.i
Global FontIndex.i
Global rtf_header.s




;// This Procedure assembles the Color Table from input passed to
;// it during Runtime.  Each entry in the Linked List has a color
;// name attached to it, as well as the HEX (*BGR) value of that
;// color, and a generated ID number which corresponds to it's
;// ID within the RTF header when it is generated later.
;//
Procedure Build_Color_Table(name.s, r.i, g.i, b.i)
  
  Shared Color_Table()
  
  ForEach Color_Table()
    If Color_Table()\name = name
      ProcedureReturn #False
    EndIf
  Next
  
  
  AddElement(Color_Table())
  Color_Table()\name = name
  Color_Table()\color\r = r
  Color_Table()\color\g = g
  Color_Table()\color\b = b
  Color_Table()\colorID = 0
  ProcedureReturn #True
  
EndProcedure





;// This Procedure will parse all text sent to the text box.
;// Its job is to parse each line for Color and Font tags
;// which will determine what the text looks like.  It will
;// build the proper RTF header and convert the formating
;// tags into RTF Formating Syntax.
;//
Procedure.s Format(input.s)
  Protected header.s, footer.s, ColorIndex.i
  Shared Color_Table()
  
  
  ;// Build our initial RTF Header
  SelectElement(Color_Table(), 0)
  header = "{\rtf {\colortbl;" + "\red" +Str(Color_Table()\color\r)+"\green"+Str(Color_Table()\color\g)+"\blue"+Str(Color_Table()\color\b)+";"
  
  
  ;// Copy current input string to a temporary working variable.
 
  ;// Make sure the index is reset to 1
  ColorIndex = 1

 ;// For some reason the default text color will not apply to the next line, if we post a line previously, whose only text is contained within color tags.
 ;// so we add a call for the default text color to each new line.
  input = "\cf1" + input
  
  
  ;// Repeat this task for every color in the table. Here we are
  ;// searching the input string for any occurence of a color tag
  ;// and matching it to the name of the color, within the Table.
  ;// Then we assign an Index ID which will also serve as its RTF
  ;//    \cf  ID.  If it works properly they should all match up
  ;// to the proper colors.  This will be used to include color
  ;// formats in the header ONLY for colors present in the input
  ;// string; saves time and memory.
  ResetList(Color_Table())
  ForEach Color_Table() 
    If FindString(input, "<color=" +Color_Table()\name +">",1) <> 0
      
      ;// Increment and assign an index number.
      ColorIndex +1
      Color_Table()\colorID = ColorIndex
      
      ;// Add color to the Color Table.
      header = header + "\red"+Str(Color_Table()\color\r)+"\green"+Str(Color_Table()\color\g)+"\blue"+Str(Color_Table()\color\b)+";"
    EndIf
  Next
  
  
  ;// Now we repeat the same task above, with a slightly different
  ;// command.  We will replace the color/font/styling tags with 
  ;// the proper RTF Syntax commands.
  
  ResetList(Color_Table())
  ForEach Color_Table()
    input = ReplaceString(input, "<color=" + Color_Table()\name + ">", "\cf" +Str(Color_Table()\colorID))
    
  Next
  
  ;// Look for closing tags to restore the default color, font, and styling.
  input = ReplaceString(input, "</color>", "\cf1 ")
  
  header = header + "}"
  footer = "}"
  ProcedureReturn header + input + footer
EndProcedure





;// Create the Color Table. Colors are stored as RGB
;// and will be parsed by name.
;//
Build_Color_Table("DefaultText",     119,  136,  153)
Build_Color_Table("RoomTitle",       255,  255,  255)
Build_Color_Table("RoomList",        255,  0,    0)
Build_Color_Table("RoomNPC",         43,   225,  0)
Build_Color_Table("RoomExits",       0,    116,  107)
Build_Color_Table("blue",            54,   0,    237)
Build_Color_Table("brightgreen",     0,    238,  0)
Build_Color_Table("brown",           153,  102,  0)
Build_Color_Table("darkred",         203,  32,   38)
Build_Color_Table("forestgreen",     34,   139,  34)
Build_Color_Table("gold",            254,  204,  0)
Build_Color_Table("green",           0,    204,  0)
Build_Color_Table("grey",            204,  204,  204)
Build_Color_Table("lightblue",       24,   116,  205)
Build_Color_Table("orange",          255,  140,  0)
Build_Color_Table("red",             255,  0,    0)
Build_Color_Table("slateblue",       0,    127,  255)
Build_Color_Table("teal",            0,    128,  128)
Build_Color_Table("white",           255,  255,  255)

Build_Color_Table("yellow",          255,  255,  0)

;///////////////////////////////
;///////////////////////////////
;Test Code Below
;///////////////////////////////
;///////////////////////////////

OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
EditorGadget(0, 0, 0, 600, 400,  #PB_Editor_ReadOnly)
SetGadgetColor(0, #PB_Gadget_BackColor, $000000)
SendMessage_(GadgetID(0), #EM_SETTARGETDEVICE, #Null, 0)
AddGadgetItem(0, -1, Format("<color=RoomTitle>[Kirkhill, Town Center]</color>"))
AddGadgetItem(0, -1, Format("You are standing in the center of Kirkhill.  A large Japanese Maple stands before you ominously, as if beckoning for you to climb it.  Beneath the tree, children are playing a game of tag, filling the air with their lighthearted laughter.  In the distance you can see the peak of Tarn Kolag which marks the territorial boundary between The Darkan Lordship and The Wastelands."))
AddGadgetItem(0, -1, Format("<color=RoomList>You also see:</color> A modest sized bronze statue of Eric and Neco Darkan."))
AddGadgetItem(0, -1, Format("<color=RoomNPC>Also here:</color> A wandering Street Merchant, Ovelia the Blacksmith, a pet dog."))
AddGadgetItem(0, -1, Format("<color=RoomExits>Obvious Exits:</color> Northeast, North, East, South, Southwest, West."))

Repeat
   event = WaitWindowEvent(20)   
Until event = #PB_Event_CloseWindow
Image
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

On a hunch I installed 5.21 LTS and the code examples work when you disable unicode compilation.

So I guess I need to solve the issue of how to use my RTF code, in unicode compiled mode. It's kind of confusing because I don't see anything specific when I view the RTF test file in a text editor, I couldn't seem to pinpoint any unicode specific stuff enabling things to work as intended.

:?
Image
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: wtf GUI Frameworks... rant I guess

Post by mk-soft »

I have a solution with API.
The EditorGadget (RichEdit) is still compatible with UTF8

Code: Select all

;-TOP

; *****************************************************************************
; AddTextRTF by mk-soft, v1.03, 25.03.2018

CompilerIf #PB_Compiler_Version < 550
  Procedure UTF8(Text.s)
    Protected *mem = AllocateMemory(StringByteLength(Text, #PB_UTF8) + 1)
    If *mem
      PokeS(*mem, Text, -1, #PB_UTF8)
    EndIf
    ProcedureReturn *mem
  EndProcedure
CompilerEndIf

Procedure AddTextRTF(Gadget, Text.s , NewLine=#True)
  If Left(Text, 5) <> "{\rtf "
    Text = "{\rtf " + Text + "}"
  EndIf
  CompilerIf #PB_Compiler_Unicode
    Protected hEdit = GadgetID(Gadget)
    Protected ndx = GetWindowTextLength_(hEdit)
    Protected *szBuffer = UTF8(Text)
    Protected hFocus = GetFocus_()
    If ndx And NewLine
      AddGadgetItem(Gadget, -1, "")
    EndIf
    SetFocus_(hEdit);
    SendMessage_(hEdit, #EM_SETSEL, ndx, ndx)
    SendMessage_(hEdit, #EM_REPLACESEL, 0, *szBuffer)
    SetFocus_(hFocus);
    FreeMemory(*szBuffer)
  CompilerElse
    AddGadgetItem(Gadget, -1 , Text)
  CompilerEndIf
EndProcedure

; *****************************************************************************

;// Defining Structures to hold Font and Color data
;// that will be used to build the reference Tables
;// and RTF Header we will be using.
;//
Structure Color_RGB       ;//Hold RGB Color values in ColorTable.
  r.i
  g.i
  b.i
EndStructure

Structure ColorTable      ;// Main Structure for List of Colors.
  name.s
  color.Color_RGB
  colorID.i
EndStructure

Structure FontTable       ;// Main Structure for List of Fonts.
  name.s
  fontID.i
EndStructure





;// Creating Linked Lists to hold Color and Font data so we can
;// change the look of text on the fly, during Run Time.
NewList Color_Table.ColorTable()
NewList Font_Table.FontTable()





;// Variables to hold generated ID numbers for use in an RTF
;// Header that will be generated later on.
;//
Global ColorIndex.i
Global FontIndex.i
Global rtf_header.s




;// This Procedure assembles the Color Table from input passed to
;// it during Runtime.  Each entry in the Linked List has a color
;// name attached to it, as well as the HEX (*BGR) value of that
;// color, and a generated ID number which corresponds to it's
;// ID within the RTF header when it is generated later.
;//
Procedure Build_Color_Table(name.s, r.i, g.i, b.i)
  
  Shared Color_Table()
  
  ForEach Color_Table()
    If Color_Table()\name = name
      ProcedureReturn #False
    EndIf
  Next
  
  
  AddElement(Color_Table())
  Color_Table()\name = name
  Color_Table()\color\r = r
  Color_Table()\color\g = g
  Color_Table()\color\b = b
  Color_Table()\colorID = 0
  ProcedureReturn #True
  
EndProcedure





;// This Procedure will parse all text sent to the text box.
;// Its job is to parse each line for Color and Font tags
;// which will determine what the text looks like.  It will
;// build the proper RTF header and convert the formating
;// tags into RTF Formating Syntax.
;//
Procedure.s Format(input.s)
  Protected header.s, footer.s, ColorIndex.i
  Shared Color_Table()
  
  
  ;// Build our initial RTF Header
  SelectElement(Color_Table(), 0)
  header = "{\rtf {\colortbl;" + "\red" +Str(Color_Table()\color\r)+"\green"+Str(Color_Table()\color\g)+"\blue"+Str(Color_Table()\color\b)+";"
  
  
  ;// Copy current input string to a temporary working variable.
 
  ;// Make sure the index is reset to 1
  ColorIndex = 1

 ;// For some reason the default text color will not apply to the next line, if we post a line previously, whose only text is contained within color tags.
 ;// so we add a call for the default text color to each new line.
  input = "\cf1" + input
  
  
  ;// Repeat this task for every color in the table. Here we are
  ;// searching the input string for any occurence of a color tag
  ;// and matching it to the name of the color, within the Table.
  ;// Then we assign an Index ID which will also serve as its RTF
  ;//    \cf  ID.  If it works properly they should all match up
  ;// to the proper colors.  This will be used to include color
  ;// formats in the header ONLY for colors present in the input
  ;// string; saves time and memory.
  ResetList(Color_Table())
  ForEach Color_Table() 
    If FindString(input, "<color=" +Color_Table()\name +">",1) <> 0
      
      ;// Increment and assign an index number.
      ColorIndex +1
      Color_Table()\colorID = ColorIndex
      
      ;// Add color to the Color Table.
      header = header + "\red"+Str(Color_Table()\color\r)+"\green"+Str(Color_Table()\color\g)+"\blue"+Str(Color_Table()\color\b)+";"
    EndIf
  Next
  
  
  ;// Now we repeat the same task above, with a slightly different
  ;// command.  We will replace the color/font/styling tags with 
  ;// the proper RTF Syntax commands.
  
  ResetList(Color_Table())
  ForEach Color_Table()
    input = ReplaceString(input, "<color=" + Color_Table()\name + ">", "\cf" +Str(Color_Table()\colorID))
    
  Next
  
  ;// Look for closing tags to restore the default color, font, and styling.
  input = ReplaceString(input, "</color>", "\cf1 ")
  
  header = header + "}"
  footer = "}"
  ProcedureReturn header + input + footer
EndProcedure





;// Create the Color Table. Colors are stored as RGB
;// and will be parsed by name.
;//
Build_Color_Table("DefaultText",     119,  136,  153)
Build_Color_Table("RoomTitle",       255,  255,  255)
Build_Color_Table("RoomList",        255,  0,    0)
Build_Color_Table("RoomNPC",         43,   225,  0)
Build_Color_Table("RoomExits",       0,    116,  107)
Build_Color_Table("blue",            54,   0,    237)
Build_Color_Table("brightgreen",     0,    238,  0)
Build_Color_Table("brown",           153,  102,  0)
Build_Color_Table("darkred",         203,  32,   38)
Build_Color_Table("forestgreen",     34,   139,  34)
Build_Color_Table("gold",            254,  204,  0)
Build_Color_Table("green",           0,    204,  0)
Build_Color_Table("grey",            204,  204,  204)
Build_Color_Table("lightblue",       24,   116,  205)
Build_Color_Table("orange",          255,  140,  0)
Build_Color_Table("red",             255,  0,    0)
Build_Color_Table("slateblue",       0,    127,  255)
Build_Color_Table("teal",            0,    128,  128)
Build_Color_Table("white",           255,  255,  255)

Build_Color_Table("yellow",          255,  255,  0)

;///////////////////////////////
;///////////////////////////////
;Test Code Below
;///////////////////////////////
;///////////////////////////////

OpenWindow(0, 0, 0, 600, 400, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
EditorGadget(0, 0, 0, 600, 400);,  #PB_Editor_ReadOnly)
SetGadgetColor(0, #PB_Gadget_BackColor, $000000)
SendMessage_(GadgetID(0), #EM_SETTARGETDEVICE, #Null, 0)

; AddGadgetItem(0, -1, Format("<color=RoomTitle>[Kirkhill, Town Center]</color>"))
; AddGadgetItem(0, -1, Format("You are standing in the center of Kirkhill.  A large Japanese Maple stands before you ominously, as if beckoning for you to climb it.  Beneath the tree, children are playing a game of tag, filling the air with their lighthearted laughter.  In the distance you can see the peak of Tarn Kolag which marks the territorial boundary between The Darkan Lordship and The Wastelands."))
; AddGadgetItem(0, -1, Format("<color=RoomList>You also see:</color> A modest sized bronze statue of Eric and Neco Darkan."))
; AddGadgetItem(0, -1, Format("<color=RoomNPC>Also here:</color> A wandering Street Merchant, Ovelia the Blacksmith, a pet dog."))
; AddGadgetItem(0, -1, Format("<color=RoomExits>Obvious Exits:</color> Northeast, North, East, South, Southwest, West."))

AddTextRTF(0, Format("<color=RoomTitle>[Kirkhill, Town Center]</color>"))
AddTextRTF(0, Format("You are standing in the center of Kirkhill.  A large Japanese Maple stands before you ominously, as if beckoning for you to climb it.  Beneath the tree, children are playing a game of tag, filling the air with their lighthearted laughter.  In the distance you can see the peak of Tarn Kolag which marks the territorial boundary between The Darkan Lordship and The Wastelands."))
AddTextRTF(0, Format("<color=RoomList>You also see:</color> A modest sized bronze statue of Eric and Neco Darkan."))
AddTextRTF(0, Format("<color=RoomNPC>Also here:</color> A wandering Street Merchant, Ovelia the Blacksmith, a pet dog."))
AddTextRTF(0, Format("<color=RoomExits>Obvious Exits:</color> Northeast, North, East, South, Southwest, West."))
AddTextRTF(0, "Hello World")

Repeat
   event = WaitWindowEvent(20)   
Until event = #PB_Event_CloseWindow
I think Purebasic internally converts the text to RTF and thus your control codes get lost
Last edited by mk-soft on Sun Mar 25, 2018 4:22 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: wtf GUI Frameworks... rant I guess

Post by Zach »

Thanks for showing a way to get it to work. I'll do my best to understand the new code.. (kind of have an idea, tho I don't like using API and pointers that much)
I had actually tried a couple times to use the UTF8() function but couldn't figure out the proper way to implement it. :oops:
Image
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: wtf GUI Frameworks... rant I guess

Post by mk-soft »

The RichEdit control has a check on the text "{\rtf".
If this text is recognized at the beginning, the text is interpreted as UTF8 and translated by Control.
Otherwise, the text is interpreted as Unicode text.

Update v1.04

Code: Select all

;-TOP

; *****************************************************************************
; AddTextRTF by mk-soft, v1.04, 25.03.2018

CompilerIf #PB_Compiler_Version < 550
  Procedure UTF8(Text.s)
    Protected *mem = AllocateMemory(StringByteLength(Text, #PB_UTF8) + 1)
    If *mem
      PokeS(*mem, Text, -1, #PB_UTF8)
    EndIf
    ProcedureReturn *mem
  EndProcedure
CompilerEndIf

Procedure AddTextRTF(Gadget, Text.s , NewLine=#True)
  If Left(Text, 5) <> "{\rtf"
    Text = "{\rtf " + Text + "}"
  EndIf
  CompilerIf #PB_Compiler_Unicode
    Protected hEdit = GadgetID(Gadget)
    Protected ndx = GetWindowTextLength_(hEdit)
    Protected *szBuffer = UTF8(Text)
    Protected hFocus = GetFocus_()
    If ndx And NewLine
      AddGadgetItem(Gadget, -1, "")
    EndIf
    SetFocus_(hEdit);
    SendMessage_(hEdit, #EM_SETSEL, ndx, ndx)
    SendMessage_(hEdit, #EM_REPLACESEL, 0, *szBuffer)
    SetFocus_(hFocus);
    FreeMemory(*szBuffer)
  CompilerElse
    AddGadgetItem(Gadget, -1 , Text)
  CompilerEndIf
EndProcedure

; *****************************************************************************
Last edited by mk-soft on Sun Mar 25, 2018 7:34 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply