Jump to content

Drawing chat window...need some ideas on how to do the text.


Recoil

Recommended Posts

Right now I am drawing the text from the rtbChat and txtMeChat on my generic image during each render method.  When the picScreen has focus you press "t" to start talking which enables the txtMeChat...of course this disables the movement so that text can be entered without messing it up with other key presses.  The square at the end of each line is from the font's CRLF character, which can be fixed by changing the font.  Here is what I currently have:

11brek4.png

Dim tmpChat As String = ""

        For Each line In frmMainGame.rtbChat.Lines

            tmpChat += line & vbCrLf

        Next

First I need to figure out how to limit the text to a certain number of lines.  Since I am going to delete the txtMeChat and rtbChat once this is done I really don't want to use either of those...but still I have been unable to get the last 9 lines of the rtbChat so only they display.

Second I need to limit the line length to about 50 characters so it will not draw off screen.

Third I need to poll the keys being pressed during the keydown event (I know how to do this), but something like backspace I am lost on how I would delete that from a string.

Fourth when text is being entered into the chat portion at the bottom I need to shift the view area to the right and clip off the left so the rest of the string can be viewed...either that or limit the text to only 50 characters.

Last I need to figure how to make this act like an actual rtb that can scroll up and down so many lines.  I can create a generic scrollbar graphics to handle this on mouse up later...

ALL that being said, I have looked through the vb6 sources to get an idea of how this is done on there, but I don't have vb6 installed and am using notepad++.  With what is there it is in no way compatible with the current setup.  I'm hoping to get a straight forward idea of what does need to be done in order to do this in the most efficient manner.  Any help is much appreciated!

Link to comment
Share on other sites

Almost nearly there...somewhat.

I have no idea about txtMeChat yet, but for the rtb I am writing the lines to a file and clearing it out on dispose.  Here I am reading the first 9 lines great, but when it goes over the 9 lines I only want to show the last 9.  So close...

Dim tmpChat As String = ""

        Dim lines() As String = File.ReadAllLines(Application.StartupPath & "tmpChat.txt") '.Length
        Dim line As String
        If lines.Count <= 9 Then
            Using sr As New StreamReader(Application.StartupPath & "tmpChat.txt")
                line = sr.ReadToEnd()
                tmpChat += line
            End Using
        Else
            Using sr As New StreamReader(Application.StartupPath & "tmpChat.txt")
                
                For i As Integer = (lines.Count - 9) To lines.Count
                    line = sr.ReadLine(lines(i)) '.ReadToEnd()
                    tmpChat += line
                Next

            End Using
        End If[code]

Link to comment
Share on other sites

First off, don't store the strings into a file. If anything use a List. Check this out.

 Dim ChatLines As New List(Of String)

        'Every time you receive a message, add it to the list.
        ChatLines.Add("jcsnider: hi")
        ChatLines.Add("jcsnider: hi2")
        ChatLines.Add("jcsnider: hi3")
        ChatLines.Add("jcsnider: hi4")
        ChatLines.Add("jcsnider: hi5")
        ChatLines.Add("jcsnider: hi6")
        ChatLines.Add("jcsnider: hi7")

        Dim renderblock As String = ""

        Dim i As Integer = ChatLines.Count - 9
        If i < 0 Then i = 0
        For x = i To ChatLines.Count - 1
            renderblock = renderblock & ChatLines(x) & vbNewLine
        Next

        MsgBox("Here is the first 7 inputs: " & renderblock)

        ChatLines.Add("jcsnider: hi8")
        ChatLines.Add("jcsnider: hi9")
        ChatLines.Add("jcsnider: hi10")
        ChatLines.Add("jcsnider: hi11")

        'Notice how this is the same thing as above
        renderblock = ""
        i = ChatLines.Count - 9
        If i < 0 Then i = 0
        For x = i To ChatLines.Count - 1
            renderblock = renderblock & ChatLines(x) & vbNewLine
        Next

        MsgBox("Here are the last 9 inputs: " & renderblock)

In reality you would just render off of the list instead of storing into the renderblock/tmpchat variable.

Link to comment
Share on other sites

When use that method I have text that will run below the chat window.  To keep my text from running off the screen I found a way to make it wrap, this is in modText:

Dim splitChars As Char() = New Char() {" "c, "-"c, ControlChars.Tab}

    Private Function WordWrap(str As String, width As Integer) As String
        Dim words As String() = Explode(str, splitChars)

        Dim curLineLength As Integer = 0
        Dim strBuilder As New StringBuilder()
        Dim i As Integer = 0
        While i < words.Length
            Dim word As String = words(i)
            ' If adding the new word to the current line would be too long,
            ' then put it on a new line (and split it up if it's too long).
            If curLineLength + word.Length > width Then
                ' Only move down to a new line if we have text on the current line.
                ' Avoids situation where wrapped whitespace causes emptylines in text.
                If curLineLength > 0 Then
                    strBuilder.Append(Environment.NewLine)
                    curLineLength = 0
                End If

                ' If the current word is too long to fit on a line even on it's own then
                ' split the word up.
                While word.Length > width
                    strBuilder.Append(word.Substring(0, width - 1) + "-")
                    word = word.Substring(width - 1)

                    strBuilder.Append(Environment.NewLine)
                End While

                ' Remove leading whitespace from the word so the new line starts flush to the left.
                word = word.TrimStart()
            End If
            strBuilder.Append(word)
            curLineLength += word.Length
            i += 1
        End While

        Return strBuilder.ToString()
    End Function

    Private Function Explode(str As String, splitChars As Char()) As String()
        Dim parts As New List(Of String)()
        Dim startIndex As Integer = 0
        Explode = Nothing
        While True
            Dim index As Integer = str.IndexOfAny(splitChars, startIndex)

            If index = -1 Then
                parts.Add(str.Substring(startIndex))
                Return parts.ToArray()
            End If

            Dim word As String = str.Substring(startIndex, index - startIndex)
            Dim nextChar As Char = str.Substring(index, 1)(0)
            ' Dashes and the likes should stick to the word occuring before it. Whitespace doesn't have to.
            If Char.IsWhiteSpace(nextChar) Then
                parts.Add(word)
                parts.Add(nextChar.ToString())
            Else
                parts.Add(word + nextChar)
            End If

            startIndex = index + 1
        End While
    End Function

And here is my modified AddText sub:

Public Sub AddText(ByVal Msg As String)
        txtChatAdd += WordWrap(Msg, 70)

    End Sub

And in modGameLogic when all the text is being added:

If Not txtChatAdd = Nothing Then

            txtChatAdd += vbCrLf
            ChatLines.Add(txtChatAdd)

            frmMainGame.rtbChat.AppendText(txtChatAdd)
            txtChatAdd = Nothing

        End If

Is there a more efficient way that you know of in order to achieve this?  It is drawing to the screen, but on a test if the test is very long then it adds more than the chat height.

Link to comment
Share on other sites

Yeah, after you run your word wrap function, split the output by new line characters and one at a time add it to the ChatLine list. That way instead of showing 9 long responses, it shows 9 lines, period.

Link to comment
Share on other sites

It took me about 3 hours to figure out to remove vbCrLf and replace it with "|" pipe key instead...otherwise it would just split at the vbCrLf but it would not delete it and would still throw in an extra new line...

-_-

Link to comment
Share on other sites

Use Calibri font to fix the Square on jump line :P.

I needed to have a fixed-width font for the text wrapping on the chat area.  It has to be a true-type font, which calibri is, but it's not fixed-width.  I am looking around for an alternative though ;)

Link to comment
Share on other sites

Render each line separately, replace the new line arguments with a space or a blank and it will work on every font.

I so tried doing this, I swear...it just did not work out too well whenever I tried to create a new line and using vbCrLf anywhere.  The good news is until I come back to fix this problem I found http://www.1001fonts.com/share-tech-mono-font.html which is a fixed-width, true-type font.  I had to increase the size to 12, and cut down the number of lines being drawn to 9, but it looks good for now.

I may try to fix this tomorrow.  Right now I am adding the text to be rendered for each string through my word wrap sub (used to be a function).

Link to comment
Share on other sites

So yeah, I'm an idiot...

I was still using the renderblock to compile a list of the ChatLines, then write them to the screen.  That is why I needed to add vbCrLf to every line segment.

It did not dawn on me until nearly 2 hours this morning of trying to tweak it to instead loop through the ChatLines, draw them, then add to the position that the next line was being drawn.  Now this works with any font, but I still like the one I found for right now.

The ONLY issues that someone may run into is:

If their font is too wide, then the word wrap length will have to be changed. 

If their font height is too tall, then the number of rendered lines will have to be reduced.

Link to comment
Share on other sites

SFML should have built in measurements for the font based on your own input strings. You can dynamically split them up and stuff based on that. Little more work but it removes the issues you discussed in your previous post.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...