[MAXGUI] TextArea manipulation possible?

BlitzMax Forums/BlitzMax Beginners Area/[MAXGUI] TextArea manipulation possible?

Grisu(Posted 2006) [#1]
Hi!

Is it possible that the first line of the textarea and the phrases "Sprecher:" & "Mitwirkung:" have a different color and use a bold (default) front?

This involves FormatTextAreaText I guess, but I could not figure out how... :/ Also the MaxGui source code was a bit too complex for me to adopt.

Example Code:
SuperStrict

Local MyWindow:TGadget=CreateWindow("TextArea Help Needed", 40,40,400,400)
Global MyText:TGadget=CreateTextArea(0,0,380,360,MyWindow, TEXTAREA_WORDWRAP|TEXTAREA_READONLY)

Local In:Tstream=ReadStream("text.txt")
While Not Eof(In)
    Local text:String=ReadLine(In)
    AddTextAreaText(MyText,Text+"~n")
Wend
CloseStream(In)

Repeat
  WaitEvent()
  Select EventID()
  Case EVENT_WINDOWCLOSE
     End
  End Select
Forever
End


Text.txt
5 ...und der Fluch des Rubins

Alfred Hitchcock und die drei Detektive (Firmenzeichen ???) haben es hier mit einem seltsamen Vermächtnis zu tun: Onkel Horatio hat seinem Neffen etwas Wertvolles hinterlassen - aber was? Und vor allem wo? Die jungen Kriminalisten Justus, Peter und Bob sehen sich hier mit viel zu vielen Gipsköpfen, geheimnisvollen Herren und dem Wort August in mindestens fünf Bedeutungen konfrontiert. Werden Justus und seine Freunde mit diesem Fall nicht überfordert?

Originaltitel: The Mystery Of The Fiery Eye

Sprecher:
Joe 			Buchholz, Peter
August August, genannt Gus 	Chresczinski, Stephan
Bob Andrews	 	Fröhlich, Andreas
Mr. Rhandur 		Kramer, Gottfried
Patrick Kenneth 		Kubach, Wolfgang
Tante Mathilda Jonas 	Lieneweg, Karin
Alfred Hitchcock 		Pasetti, Peter
Mutter 			Pichler, Renate
Justus Jonas	 	Rohrbeck, Oliver
Lisa 			Stolze, Madeleine
Peter Shaw	 	Wawrczeck, Jens
Mr. Dwiggins 		Wolff, Joachim

Mitwirkung: 	
Cover Design 		Schoedsack, Atelier
Produktion 		Körting, Heikedine
Effekte 			Europa, Tonstudio
Regie 			Körting, Heikedine
Autor 			Arthur, Robert
Musik (Titel) 		Conrad, Jan-Friedrich
Cover Illustration 		Rasch, Aiga



klepto2(Posted 2006) [#2]
This should work:

SuperStrict

Local MyWindow:TGadget=CreateWindow("TextArea Help Needed", 40,40,400,400)
Global MyText:TGadget=CreateTextArea(0,0,380,360,MyWindow, TEXTAREA_WORDWRAP|TEXTAREA_READONLY)

Local In:Tstream=ReadStream("text.txt")
While Not Eof(In)
 	Local text:String = ReadLine(In)  
 	AddTextAreaText(MyText , Text + "~n")
	If text.Trim() = "Sprecher:" Or text.Trim() = "Mitwirkung:" Then
		Local Line:Int = TextAreaCursor( mytext , TEXTAREA_LINES )
		FormatTextAreaText( mytext , 255 , 0 , 0 , 1 , line - 1 , 1 , TEXTAREA_LINES )
	EndIf
Wend
CloseStream(In)

Repeat
  WaitEvent()
  Select EventID()
  Case EVENT_WINDOWCLOSE
     End
  End Select
Forever
End



Grisu(Posted 2006) [#3]
Thanks a lot. Your code works.

My problem is that I have around 200 of these data files as above and I have to switch displaying them quite fast.

Thus this method loading them from HDD is too slow.
I have an array sturcture called MyArray$[0..max] that holds the text for each data file.

Is it possible to do the "high-lightning" of a text already in loaded into ram?

The only thing that might work is creating a separate textarea for each data file at startup when I load the files. And hide all but the one not visible. But that would blow memory usage.

Is there a way to get the text "linewise" from an existing textarea?


Grisu(Posted 2006) [#4]
YEHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA found a workaround.

I simply search my array contents for the words I need and change the Textareagadget where needed. Its a neat trick to find the positions inside the textarea. And much faster too.

pos=Instr(MyArray$[Current_Folge],"Anmerkung:",1 )
If pos <> 0 Then FormatTextAreaText( Mytext:TGadget , 0 , 0 , 0 , 1 , pos-1 , 10 )


Thanks again.

And again: BLITZMAX DOCS need more examples!


klepto2(Posted 2006) [#5]
It is not possible to store the highlighting in Ram. Thats the reason why the BMaxIDE Highlighter is so slow in the loading.

To get the Line : Take a closer look to my sample. There I use
a constant called 'TEXTAREA_LINES' the default one used by max is called 'TEXTAREA_CHARS' . So if a function uses a unit as a parameter, you could use one of these constants and then all returned date from the function is based on Lines or Chars (dependend from the constant)


Grisu(Posted 2006) [#6]
With my workaround posted above, you can load the whole text / source at start up and modify the highlightning afterwards.

If you put some more work into it, the highlighter could only change the text "viewable" at the moment.

If you like, I can e-mail you a preview of my current app where I use that technique mentioned in the post before.


klepto2(Posted 2006) [#7]

the highlighter could only change the text "viewable" at the moment



Thats the point. With the standard commands it is impossible to get the correct visible range. You have to implement some additional Functions to add these. I have done it, but it will only work on Win32.

With the loading in rem thingy, i think I've misunderstood you, because I was thinking of another Richedit tweak, which would mark the the text in ram and so the text wouldn't rendered in the default color before. Currently Richedit works this way:
--> Load Text
--> Display Text in Default
--> change colores and styles <-- the slowness issue

I have some good experience with highlighter code in Bmax and optimizing it. Maybe I could give you some hints to tweak your code a bit ;) so I would be pleased to test you app.


Grisu(Posted 2006) [#8]
1. I load all textfiles into rem, before the app starts and fill an array called MyArray$:

Function Load_DDF()

For Local i:Int=0 To MAXFOLGEN-1
	Local hFile:TStream = OpenFile("Incbin::./Data/"+i+".ddf", True, False)
    While Not Eof(hFile)
    		MyArray[i]=MyArray[i]+ReadLine(hFile)+"~n" 'put data string in array
    Wend  
    CloseFile hFile
Next 

End Function 


2. This is my whole update TextArea code:
      LockTextArea(MyText)
      FormatTextAreaText( Mytext:TGadget , 0 , 0 , 0 , 0 , 0 , TEXTAREA_ALL )
      SetTextAreaText(MyText,MyArray$[Current_Folge],0,TEXTAREA_ALL,TEXTAREA_CHARS)

      Local pos=Instr(MyArray$[Current_Folge],"~n",1 ) 
      FormatTextAreaText( Mytext:TGadget , 255 , 0 , 0 , 1 , 0 , pos )

      pos=Instr(MyArray$[Current_Folge],"Anmerkung:",pos ) 
      If pos <> 0 Then FormatTextAreaText( Mytext:TGadget , 0 , 0 , 0 , 1 , pos-1 , 10 )

      pos=Instr(MyArray$[Current_Folge],"Originaltitel:",pos ) 
      If pos <> 0 Then FormatTextAreaText( Mytext:TGadget , 0 , 0 , 0 , 1 , pos-1 , 14 )

      pos=Instr(MyArray$[Current_Folge],"Trailer:",pos ) 
      If pos <> 0 Then FormatTextAreaText( Mytext:TGadget , 0 , 0 , 0 , 1 , pos-1 , 8 )

      pos=Instr(MyArray$[Current_Folge],"Sprecher:",pos ) 
      If pos <> 0 Then FormatTextAreaText( Mytext:TGadget , 0 , 0 , 255 , 1 , pos-1 , 9 )

      pos=Instr(MyArray$[Current_Folge],"Mitwirkung:",pos ) 
      If pos <> 0 Then FormatTextAreaText( Mytext:TGadget , 0 , 0 , 255 , 1 , pos-1 , 11 )

      UnlockTextArea(MyText)
      SelectTextAreaText( Mytext , 0 , 0) 


I doubt one can make this faster.


klepto2(Posted 2006) [#9]
Your right, this is a good idea. I was thinking you're trying to write a more complex highlighter.
But the highlightspeed issue is the same.
It is the same as if you would load the file directly to the
textarea. the Array might be a bit faster, but that should be minimal ;) . In Fact you're doing the same as I described before. You load a file and set the textareatext and thats why the TextAreaFormat is so slow with great texts.

Sorry that I have misunderstood you so hard.


Grisu(Posted 2006) [#10]
No problem, I think we are both German and so it is only the language barrier that caused the misunderstanding.... :)

Is it normal that I have to call the line below each time I put new text into the textarea?

FormatTextAreaText( Mytext:TGadget , 0 , 0 , 0 , 0 , 0 , TEXTAREA_ALL )

Is there some kind of flag, that tells that textarea that it should delete all "formats" made before ( reset to default )?