Textstellen farbig hervorheben

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Cardonic

Betreff: Textstellen farbig hervorheben

BeitragMi, Aug 23, 2006 17:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi

Ich brauche für mein Projekt eine Methode, mit der sich gewisse Stellen oder Wörters eines Textes farblich hervorheben lassen.

Ich hab mich mal hinter meine Kiste gesetzt und einen kleinen Test gecoded. Ich bin aber noch nicht so ganz mit dem Ergebnis zufrieden.

Vielleich fällt euch ja noch eine elegantere, schnellere, bessere Methode ein. Ich wäre auch über Verbesserungen meines Codes aufs höchste erfreut.

Hier mal mein Code: [AUSKLAPPEN]
SuperStrict

Local TestString:String = "File:TStream = OpenFile("+Chr(34)+"C:\file.txt"+Chr(34)+")"

Global Colors:TList = CreateList()

Type Color
   Field Start:Int
   Field Length:Int
   Field Red:Byte
   Field Green:Byte
   Field Blue:Byte
End Type

Function AddColor(S:Int,L:Int,R:Byte,G:Byte,B:Byte)
   Local NewColor:Color = New Color
   NewColor.Start = S
   NewColor.Length = L
   NewColor.Red = R
   NewColor.Green = G
   NewColor.Blue = B
   ListAddLast(Colors,NewColor)
End Function

AddColor(6,7,255,255,0)
AddColor(16,8,255,255,0)
AddColor(25,13,0,255,102)

Graphics(800,600)

' main loop

While Not KeyHit(KEY_ESCAPE)

   Cls

   For Local I:Int = 1 To Len(TestString)
      SetColor(255,255,255)
      For Local CurrentColor:Color = EachIn Colors
         If I >= CurrentColor.Start And I < CurrentColor.Start+CurrentColor.Length Then
            SetColor(CurrentColor.Red,CurrentColor.Green,CurrentColor.Blue)
         EndIf
      Next
      DrawText(Mid(TestString,I,1),I*8,10)
   Next

   Flip

Wend


mfg Cardonic
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.

Cardonic

BeitragMi, Aug 23, 2006 22:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab noch eine zweite Variante geschrieben.

Das Ergebnis ist diesmal etwas besser ausgefallen.
Vorteile dieses Codes sind:
- Schneller
- Texte lassen sich einfacher erstellen (finde ich)
- Auch für OOP geeignet

Und hier noch der Code: [AUSKLAPPEN]
SuperStrict

' types

Type TLine

   Field Parts:TList = CreateList()

   Method Draw()
      Local Chars:Int = 1
      For Local CurrentPart:TPart = EachIn Self.Parts
         SetColor(CurrentPart.Red,CurrentPart.Green,CurrentPart.Blue)
         DrawText(CurrentPart.Text,Chars*8,10)
         Chars :+ Len(CurrentPart.Text)
      Next
   End Method

   Method AddText(T:String,R:Int=255,G:Int=255,B:Int=255)
      Local NewPart:TPart = New TPart
      NewPart.Text = T
      NewPart.Red = R
      NewPart.Green = G
      NewPart.Blue = B
      ListAddLast(Self.Parts,NewPart)
   End Method
   
End Type

Type TPart

   Field Text:String
   Field Red:Byte
   Field Green:Byte
   Field Blue:Byte

End Type

' create line

Local TestLine:TLine = New TLine

TestLine.AddText("File:")
TestLine.AddText("TStream",255,255,0)
TestLine.AddText(" = ")
TestLine.AddText("OpenFile",255,255,0)
TestLine.AddText("(")
TestLine.AddText(Chr(34)+"C:file.txt"+Chr(34),0,255,102)
TestLine.AddText(")")

' graphics

Graphics(800,600)

' main loop

While Not KeyHit(KEY_ESCAPE)

   Cls

   TestLine.Draw()

   Flip

Wend


Ich wäre aber froh, wenn ich hier nicht weiterhin einen Dialog führen muss.

mfg Cardonic
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.

Vertex

BeitragDo, Aug 24, 2006 1:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja, naja. TList ist sicherlich eine feine Sache, leider aber nicht gerade sehr schnell. Arrays wären hier angesagter. Also ein statisches(^= feste Größe) Array, wo du deine Parts reinknallst ist etwas schneller und ressourcenschonender. TPart wegzulassen wäre natürlich das idealste.

Code: [AUSKLAPPEN]
SuperStrict

Framework BRL.Max2D
Import BRL.GLMax2D
Import BRL.PolledInput

Type TLine
   Field PartContents : String[255]
   Field PartColors   : Byte[255, 3]
   Field Count        : Byte

   Method AddText(Text:String, Red:Byte=255, Green:Byte=255, Blue:Byte=255)
      Self.PartContents[Self.Count] = Text
      Self.PartColors[Self.Count, 0] = Red
      Self.PartColors[Self.Count, 1] = Green
      Self.PartColors[Self.Count, 2] = Blue
      Self.Count :+ 1
   End Method

   Method Clear()
      Self.Count = 0
   End Method

   Method Draw(X:Float, Y:Float)
      Local Index:Int, Position:Int

      For Index = 0 Until Self.Count
         SetColor(Self.PartColors[Index, 0], ..
                  Self.PartColors[Index, 1], ..
                  Self.PartColors[Index, 2])
         DrawText(Self.PartContents[Index], X + Position*8, Y)
         Position :+ Self.PartContents[Index].Length
      Next
   End Method
End Type

Global TextLine : TLine

Graphics(640, 480)

TextLine = New TLine
TextLine.AddText("File:")
TextLine.AddText("TStream", 255, 255, 0)
TextLine.AddText(" = ")
TextLine.AddText("OpenFile", 255, 255, 0)
TextLine.AddText("(")
TextLine.AddText("~qC:file.txt~q", 0, 255, 102)
TextLine.AddText(")")
TextLine.Draw(10, 10)

TextLine.Clear()
TextLine.AddText("File.Close()")
TextLine.Draw(10, 25)

Flip()
WaitKey()
End


Im Übrigen ist ein Selbstgespräch ein Monolog und kein Dialog Wink
mfg olli

Justus

BeitragDo, Aug 24, 2006 9:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Für alle, die Highlighting/Textformatierung gerne mit MaxGUI in einer Textarea wollen, habe ich diese kleine Funktion geschrieben.

Code: [AUSKLAPPEN]
'WRITE TO TEXTAREA
'Adds Text to a textarea and formats it with the given color and
'text style settings.
'flags: 1 = bold ; 2 = italic ; 1 | 2 = bold and italic
'--------------------------------------------------------------------
Function WriteToTextarea(textarea:TGadget,str:String,r:Int=0,g:Int=0,b:Int=0,flags:Int=0,newline:Int=True)
   Local pos:Int
   Local length:Int
   
   AddTextAreaText textarea,str

   Select newline
      Case True
         AddTextAreaText textarea,Chr(13)
         length = Len(str+Chr(13))
      Case False
         length = Len(str)
   EndSelect
   pos = TextAreaLen(textarea)-length
   FormatTextAreaText(textarea,r,g,b,flags,pos,length)
EndFunction

Cardonic

BeitragDo, Aug 24, 2006 13:37
Antworten mit Zitat
Benutzer-Profile anzeigen
@Vertex: Du hast recht, dein Code ist bei mir fast doppelt so schnell. Ich denke, dass ich sowas in der Richtung für mein Projekt verwenden werde.

@Justus: Deine Funktion ist wirklich gut zu gebrauchen und erspart viel Mühe beim formatieren eines Textes. Da ich aber keine GUI in meinem Projekt verwenden werde, werde ich erst bei zukünftigen Projekten darauf zurückgreifen.

mfg Cardonic

PS: Spielt ja keine Rolle, ob ich Monolog oder Dialog schreibe; sind ja nur Gegensätze Rolling Eyes

~Edit~
Wie unanständig von mir, mich nicht für eure Beiträge zu bedanken.

Cardonic

BeitragDo, Aug 24, 2006 18:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier noch eine dritte Variante von mir.
Ich habe mich sehr stark an Vertex's Code orientiert und noch ein bisschen ausgebaut.
Man kann nun angeben, an welcher Stelle ein neuer "Textblock" eingefügt werden soll.
Zudem lassen sich jetzt auch einzelne "Textblöcke" entfernen.

Code: [AUSKLAPPEN]
SuperStrict

Type TLine

   Field PartStrings:String[256]
   Field PartColors:Byte[256,3]
   Field Count:Byte

   Method Draw(X:Float,Y:Float)
      Local Index:Byte, Position:Byte
      For Index = 0 Until Self.Count
         SetColor(Self.PartColors[Index,0],Self.PartColors[Index,1],Self.PartColors[Index,2])
         DrawText(Self.PartStrings[Index],X+Position*8,Y)
         Position :+ Self.PartStrings[Index].Length
      Next
   End Method

   Method AddText(Text:String,Red:Byte=255,Green:Byte=255,Blue:Byte=255,Index:Byte=255)
      If Self.Count = 256 Then Return
      If Index >= Self.Count Then
         Index = Self.Count
      Else
         Local CurrentIndex:Byte = Self.Count
         While CurrentIndex > Index
            PartStrings[CurrentIndex]  = PartStrings[CurrentIndex-1]
            PartColors[CurrentIndex,0] = PartColors[CurrentIndex-1,0]
            PartColors[CurrentIndex,1] = PartColors[CurrentIndex-1,1]
            PartColors[CurrentIndex,2] = PartColors[CurrentIndex-1,2]
            CurrentIndex :- 1
         Wend
      EndIf
      PartStrings[Index]  = Text
      PartColors[Index,0] = Red
      PartColors[Index,1] = Green
      PartColors[Index,2] = Blue
      Self.Count :+ 1
   End Method

   Method RemoveText(Index:Byte=255)
      If Self.Count = 0 Then Return
      Self.Count :- 1
      While Index < Self.Count
         PartStrings[Index]  = PartStrings[Index+1]
         PartColors[Index,0] = PartColors[Index+1,0]
         PartColors[Index,1] = PartColors[Index+1,1]
         PartColors[Index,2] = PartColors[Index+1,2]
         Index :+ 1
      Wend
   End Method

   Method Clear()
      Self.Count = 0
   End Method

End Type

Local TestLine:TLine = New TLine

Graphics(800,600)

TestLine.AddText("DrawText",255,255,0)
TestLine.AddText("(")
TestLine.AddText("~qHello World !~q",0,255,102)
TestLine.AddText(",10,10)")
TestLine.Draw(10,10)

TestLine.AddText("Naughty Text ",255,0,0,0)
TestLine.Draw(10,25)

TestLine.RemoveText(0)
TestLine.Draw(10,40)

TestLine.Clear()
TestLine.Draw(10,55)

TestLine.AddText("The End",127,127,127)
TestLine.Draw(10,70)

Flip
WaitKey()


mfg Cardonic
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.

Markus2

BeitragMi, Sep 20, 2006 12:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,

ich hatte das immer so gelößt .

z.B. *CFF00FFDieser Text ist Rot *C00FF00und nun Grün.

parsen und bei *C die Farbe dahinter einstellen und den Textblock überspringen .
In der Art kann man noch mehr Kürzel einbauen z.B. für
Hintergrundfarbe, Linien, Boxen oder Icons im Text zeigen und so weiter .

Cardonic

BeitragMi, Sep 20, 2006 16:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Scheint mir eine vernünftige Lösung zu seine. Speicherschonender ist es bestimmt, aber ob es auch schneller ist, das kann ich nicht ohne es auszuprobieren sagen.

Könntest du vielleicht kleines Beispiel aus deiner Codesammlung zeigen ?

mfg Cardonic
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.

d-bug

BeitragMi, Sep 20, 2006 18:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Also richtig schnell wirst du es nicht bekommen. Aber kleiner Tip... bersorge
dir eine RenderToTexture Lib (von Indiepath oder Diablo) und schreibe den
Text dann auf ein Image. So bekam ich meinen Textparser schnell genug.
Vorher machte ich 20 Neuauflagen mit 20 verschiedenen Lösungsansätzen
und keiner war am Ende schnell genug für Realtime. Jetzt stelle ich nurnoch
ein TImage dar und das geht recht flott, wie wir alle wissen. Wink

BTW, ich benutze dafür eine Art BB-Code Tags...

cheers

Cardonic

BeitragMi, Sep 20, 2006 19:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Klingt interessant, da ich diese farbigen Texte in meinem Spiel für Missionsinformationen einsetzen will (sprich in Realtime).

Weisst du gerade, woher ich diese RenderToTexture Lib bekomme ?

mfg Cardonic
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.
 

Dreamora

BeitragMi, Sep 20, 2006 19:27
Antworten mit Zitat
Benutzer-Profile anzeigen
http://modules.indiepath.com/forum
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Justus

BeitragMi, Sep 20, 2006 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
http://modules.indiepath.com/f...906028e7b2


user posted image
Google hilft.

Markus2

BeitragMi, Sep 20, 2006 19:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Bunter Text , vieleicht kann man das mit in Texture schreiben kombinieren
Code: [AUSKLAPPEN]

'MR
Strict
Graphics 800,600,16

SetClsColor 64,64,64
Cls
Flip
Cls

Local y:Float
For y=-100 To 240 Step 1
 SetColor 32,32,32
 DrawRect 10,10,320,240
 ColorText "*FTFF0000Das ist Rot *FT00FF00und das ist Gruen*R*FT0000FFUnd jetzt kommt Blau*R*FTFF8030Orange habe ich auch :)",0,y,10,10,320,240
 Flip
Next
ColorText "*FT00FF00Press any Key*R*FTFFFF00Ready.*R_",0,0,10,10,320,240
Flip

WaitKey
End

Function ColorText(Text:String,X_Scroll:Int,Y_Scroll:Int,X_Left:Int,Y_Top:Int,X_Width:Int,Y_Height:Int)

 Local i:Int   
 Local x:Int,y:Int 
 Local cx:Int,cy:Int 
 Local xx:String,f:String
 
 x = X_Scroll
 y = Y_Scroll
 
 cx = 0
 cy = 0
           
 Local ydown:Int
 ydown = TextHeight(Text)

 SetColor 255, 255, 255 'standart Farbe
   
 i = 1
 Repeat
  If i > Len(Text) Then Exit
   
  xx = Mid(Text, i, 1)
   
  '-------------------------------------------------------------------
   
  'Sonderzeichen Grafik *
   
  If xx = "*" Then
   
  '-------------------------------------------------------------------
 
  Select Mid(Text, i + 1, 1) 'Zeichen nach *
           
   '-------------------------------------------------------------------
           
   Case "F" 'Farbe
   
    Local ffa:Int, ffb:Int,ffc:Int

    If Mid(Text, i + 2, 1) = "T" Then 'Text Farbe
     f = Mid(Text, i + 3, 6)
     If Len(f) = 6 Then
      ffa =Int("$" + Left(f, 2))
      ffb =Int("$" + Mid(f, 3, 2))
      ffc =Int("$" + Right(f, 2))
      SetColor ffa,ffb,ffc
      i = i + 8
     End If
    End If

   '-------------------------------------------------------------------
           
   Case "R" 'Return
    x = X_Scroll
    y = y + ydown
    i=i+1
   
   '-------------------------------------------------------------------
           
   End Select 'Zeichen nach *
           
   '-------------------------------------------------------------------
   
  Else
   'bei Return eine Zeile runter wenn größer als Startposition
   If xx = Chr(13) Then
    x = X_Scroll
    y = y + ydown
   ElseIf xx = Chr(10) Then
   Else
    'Zeichen anzeigen
     If x >= 0 And x+TextWidth(xx) < X_Width And y >= 0 And y+ydown < Y_Height Then
      cx = x + X_Left
      cy = y + Y_Top
      DrawText xx, cx, cy
     End If
     x = x + TextWidth(xx)
   End If
  End If '* ?
   
  '-------------------------------------------------------------------
     
  If y > Y_Height Then Exit
     
  i = i + 1
 Forever
       
End Function

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group