WindowBox Scrolling Help.

BlitzMax Forums/BlitzMax Beginners Area/WindowBox Scrolling Help.

Shortwind(Posted 2010) [#1]
Ok. Below is the code for a basic windowbox that I'm working on. It's far from complete, but I've ran into a snag already. If you run the code as is, it will print in the windowbox fine, except it's not printing out the last line of the last command if the window is full.... I've been messing with this for three hours, so I think I've probably just over thunk the problem. If anyone can help, I'd appreciated it.

Strict
Graphics 800,600,0,60

Local mywindow:windowbox=WindowBox.Create()
mywindow.setwindowfont("c:\windows\fonts\consola.ttf",18)
mywindow.setpos(100,200)
mywindow.setsize(20,10)
'mywindow.settexture("text_texture.png")

Cls
SetColor 255,255,255
SetBlend AlphaBlend

mywindow.show()
mywindow.CurX=0
mywindow.CurY=0
mywindow.printwrap("Hello.")
Flip
Delay(100)
mywindow.printwrap("This is a test of something.")
Flip
Delay(100)
mywindow.printwrap("And something is nothing, but the nothing is something in the morning.")
Flip
Delay(100)
mywindow.printwrap("Then the mountains came crashing to the shore.")
Flip
Delay(100)
mywindow.printwrap("Sometimes when the clocks stop, the world stops with them.")
Flip
'Delay(100)
'mywindow.printwrap("Even more printing that is fun.")
'Flip
'Delay(100)
'mywindow.printwrap("And more printing.")
'Flip
'Delay(100)
'mywindow.printwrap("Things are not funny in the morning.")
'Flip

Repeat
Until KeyDown(KEY_ESCAPE) Or AppTerminate()

Type WindowBox
	'Global WindowBoxList:TList = New TList
	
	Field Font_Name:String
	Field Font_Size:Int
	Field FontMaxWidth:Int
	Field FontMaxHeight:Int
	Field ScreenWidth:Int
	Field ScreenHeight:Int
	Field WindowXPos:Int
	Field WindowYPos:Int
	Field WindowWidth:Int
	Field WindowHeight:Int
	Field TexturePath:String
	Field TextureImage:TImage = New TImage
	Field CurX:Int
	Field CurY:Int
	Field TextLines:String[100]
	Field CurTextLine:Int
	Field CurTopLine:Int
	
	Function Create:WindowBox()
		Local w:WindowBox = New WindowBox
		w.SetWindowFont(Null,8)
		w.ScreenWidth=GraphicsWidth()
		w.ScreenHeight=GraphicsHeight()
		w.SetPos(0,0)
		w.SetSize(10,10)
		w.CurX=0
		w.CurY=0
		For Local i:Int=0 To 99
			w.TextLines[i]=""
		Next
		w.CurTextLine=0
		w.CurTopLine=0
		
'		WindowBoxList.addlast(w:WindowBox)
		Return w:WindowBox
	End Function

	Method SetWindowFont(Font_Namex:String,Font_Sizex:Int)
		Local font:timagefont=LoadImageFont(font_namex,font_sizex,SMOOTHFONT)
		SetImageFont(font)
		Font_Name=Font_Namex
		Font_Size=Font_Sizex
		FontMaxWidth=TextWidth(Chr(0))
		FontMaxHeight=TextHeight(Chr(0))
		For Local i:Int=1 To 255
			If TextWidth(Chr(i))>FontMaxWidth Then FontMaxWidth=TextWidth(Chr(i))
			If TextHeight(Chr(i))>FontMaxHeight Then FontMaxHeight=TextWidth(Chr(i))
		Next
	End Method
	
	Method SetPos(xpos:Int, ypos:Int)
		WindowXPos=xpos
		windowYPos=ypos
	End Method
	
	Method SetSize(xsize:Int, ysize:Int)
		WindowWidth=xsize
		WindowHeight=ysize
	End Method
	
	Method DrawBorder()
		SetColor 255,255,255
		Local x:Int=WindowXPos
		Local x1:Int=WindowXPos+(WindowWidth*FontMaxWidth)+FontMaxWidth
		Local y:Int=WindowYPos
		Local y1:Int=WindowYPos+(WindowHeight*FontMaxHeight)
		
		DrawLine(x-5,y-5,x1+5,y-5)
		DrawLine(x-5,y-5,x-5,y1+5)
		DrawLine(x1+5,y-5,x1+5,y1+5)
		DrawLine(x-5,y1+5,x1+5,y1+5)
	End Method
			
	Method Show()
		Local x1:Int=(WindowWidth*(FontMaxWidth))
		Local y1:Int=(WindowHeight*(FontMaxHeight))
		DrawBorder()
		'DrawImageRect(TextureImage,WindowXPos,WindowYPos,x1,y1)
	End Method
	
	Method SetTexture(TexturePathx:String)
		TextureImage = LoadImage(TexturePathx)
	End Method
	
	Method PrintWrap(Text:String)
		Local words:String[]
		Local soffx:Int=WindowXPos
		Local soffy:Int=WindowYPos
		
		words=Text.split(Chr(32))
		For Local t:String=EachIn words
			If Len(t)<WindowWidth-CurX Then
				TextLines[CurTextLine]=TextLines[CurTextLine]+t
			Else
				CurX=0
				CurY=CurY+1
				If CurY > WindowHeight Then
					CurTopLine=CurTopLine+1
				EndIf
				CurTextLine=CurTextLine+1
				TextLines[CurTextLine]=TextLines[CurTextLine]+t
			End If
			If Instr(".?!",Right(t,1))<>0 Then
				CurX=CurX+Len(t)+2
				TextLines[CurTextLine]=TextLines[CurTextLine]+"  "
			Else
				CurX=CurX+Len(t)+1
				TextLines[CurTextLine]=TextLines[CurTextLine]+" "
			EndIf

			If CurX > WindowWidth Then
				CurX=0
				CurY=CurY+1
				If CurY > WindowHeight Then
					CurTopLine=CurTopLine+1
				EndIf
				CurTextLine=CurTextLine+1
			EndIf			
		Next
		SetColor 0,0,0
		DrawRect(WindowXPos,WindowYPos,WindowWidth*FontMaxWidth,(WindowHeight)*FontMaxHeight)
		SetColor 255,255,255
		For Local i:Int=CurTopLine To WindowHeight+CurTopLine-1
			DrawText(TextLines[i],soffx+FontMaxWidth,soffy+((i-CurTopLine)*FontMaxHeight))
		Next
	End Method
	 
End Type


Thanks :D


Jesse(Posted 2010) [#2]
you owe me five dollars for five minutes of my time.




Shortwind(Posted 2010) [#3]
Doh!

Thanks! I was sure I had been looking at that code for too long.

Your fix is perfect!

:D


Shortwind(Posted 2010) [#4]
Hmm... I have dug myself into a corner by sheer lack of planning. This routine works perfectly (Now with Jesse's help. I guess I still owe him that $5 bucks.) I even added the ability to add ~n (returns) to the output.

The problem: Because of the way I elected to do the actual printing, and scrolling of the text, I am now having a heck of a time adding color codes. Oops. The original method for printing was (I thought), slick and to the point.

Guess it's back to the drawing board. Ho, Hum. :(

I've only seen one actual module that does most of what I want to accomplish, libtcod, but even that didn't handle scrolling the text in the window when it filled up. I've seen no other code that allows for automatic scrolling when the text reaches the bottom of the window. I would have loved to use libtcod, but it is unfinished, and buggy as hell, and doesn't allow the use of standard fonts without jumping through hoops.

Any suggestions on doing this more effectively? Or has someone already written this type of windowbox routine for BMax, and I just didn't find it in the code archives?

Thanks. :D


Jesse(Posted 2010) [#5]
I hope you have enough money because this info will cost you $10,000.
you can easily do it by saving types to the line array instead of saving strings. I have it working. I was going to post it but I think you should try it first. The way I did it is by crating a word type that included a color type I also crated a line type that stores the words in a list. each type store its length in pixels and chars so make it easier to display. and the only type that displays is the the text is the word type. give it your best shot and if you can't figure it out I'll post what I got.

ROFL.......
just so there won't be any misunderstanding, this is about the first sentence.


Shortwind(Posted 2010) [#6]
Ok, I've changed this up, and it looks nicer, but still needs a lot of polish, and I need to change my actual print routine, it's bollocks and looks ugly if you slow it down. Plus the code handling is still a bit flaky, but works. :D

Again, here is the code I've come up with. Do NOT use this is a real project because it's crap! ha ha



Jesse, I'm sure yours has a lot more panash! :D


Shortwind(Posted 2010) [#7]
To go forward, I think I need to change the print routine to print character by character, insteal of full words. Then the user could set a print speed and have it print more realistically. Anyone have any comment on that?

(Ignore the fact that mine prints the same thing over and over again, as more lines are added... oops... :D I'm fixing that.)

As far as the functioning of the {} (codes), I'm really sure this can be better as well. Currently if you try to do {White}Hello.{Blue} (without a space before the {Blue} it will not work, my sucky parser is broken.

One last thing: I've not much experience in actual graphics, but I'm quite sure that when the window is displayed, then hidden, what ever was behind it should be redrawn. Is a simple image-rect-copy type thing the best approach? And I haven't even addressed the issue of window depth, it would be nice, I guess, to be able to have multiple windows open and move them around. hmm... I think I might be getting over my head. :D

Sorry, I can be a bit dense sometimes.

Well, back to work.


Jesse(Posted 2010) [#8]
actually a "word" in a sense could be a space or a character.

well, this is what I did. so you can get an idea:




Jesse(Posted 2010) [#9]
base on what you last post there are several steps you need to follow in order to produce in a kind of a time line effect.
I usually separate my code in to three and sometime four steps:
1. creation process
2. initialization process(this process sometimes integrated in the creation process)
3. update process
4. display process

that is how I do all of my code that is for games and is interactive.
anyway. All I had to do is separate the processes in your code and added the different function needed for it to work in a time line. I had a timer function which I did a while ago and was easy to incorporate. You can use it as you like, just don't share it as yours. It is not that big of a deal so don't need or expect to get credit for it and yes, use at your own risk.
anyway this is what I got:

I hope it helps


Shortwind(Posted 2010) [#10]
Jesse, very elegant approach. Thanks for posting the updated code. You have created very clean and easy to follow (understand) methods for exactly what I was attempting to produce in the first place. You've given me some clearer insight as to how BlitzMax TLists and TTimer should work. It is fully obvious that my shoddy second code post illustrates the following:

First, a incomplete understanding of the BlitzMax language and syntax.

Second, my reliance on "intelligent" IDE's. They have instilled a lazyness in me. I've gotten so used to typeing a command then the dot and getting a list of that types elements and procedures, and a wealth of documentation. I guess that I have neglected, and in a way, been "trained", to not memorize, and thus, fully understand the underlying fundamentals of some of the built in commands and types. (I use the standard IDE right now, precisely because I'm trying to retrain myself, and because it's a new language to me.)

Third, it shows how my brain works when approaching a new problem. My original post, though I thought it was pretty decent, did not come from a first, or second, or even third revision. As you can see from the second code I posted, it takes me some time to get a "working" set of procedures into a well formed, nice looking, and easy to use, "final", set. A good friend of mine was a professional programmer (database expert, among other things) for over thirty years. I have to laugh everytime I write some new code, because he would get so pissed at me for getting bogged down in always "trying" to produce the most perfect and efficient code. It almost never failed. I'd create a new procedure, work on it for a month, think it was perfect, then show it to him for approval. Of course you already can guess the result. :D

I guess what I'm trying to say is I really do appreciate your help and advice. Your approach is much the same as my friends. He would also give me some advice first, then make me work on the code to see what I can produce, before ripping me a new one for being silly. :D I guess I miss that. And it just caught me off guard when you approached this problem in the same manner. Maybe I'm too sentimental, sorry. I just miss my friend.

Anyway, I'm babbling.

Great work. I believe I'm going to reapproach my Codes type and procedures and take them out of the actual text input. Your approach seems, first, simpler, and second I can see greater potiental for my Codes type and procedures. I see where I can create greater control, in a more simplified manner, over how the text is presented.

Thanks again,
Laters! :D


Jesse(Posted 2010) [#11]
Thank you. I am glad I was able to help you out.
about Tlist, It has been only little over a year ago that I learned to use it somewhat efficiently and I have been programming in Bmax for years. I posted code in the code Archives in which I wrote a linked list from scratch not knowing that that's exactly what Tlist is. Funny thing is that sense we don't have a manual for Bmax, the best way to get information here is by posting our code here, good or bad, and sharing what we know and getting answers from someone that know something we don't.

One of the things I try to do when coding is to brake down what I am trying to do in to simpler more manageable pieces but one of the problems I run into from doing that is that sometimes the code becomes too inefficient as far as speed is concerned. The good thing is that once you have it working it is easy to optimize.

good luck with your project.