TextArea problem..

BlitzMax Forums/MaxGUI Module/TextArea problem..

Dabhand(Posted 2008) [#1]
Import MaxGui.Drivers

Strict 

Local window:TGadget
Local textarea:TGadget
Local index:TGadget 

window=CreateWindow("My Window",130,20,400,300,,15|WINDOW_ACCEPTFILES)

textarea=CreateTextArea(50,0,ClientWidth(window)-70,200,window)
index = CreateTextArea(10,0,30,200,window,TEXTAREA_READONLY)
DisableGadget index
Local hWnd = QueryGadget(index, QUERY_HWND)
SendMessageA(hWnd, EM_SHOWSCROLLBAR, SB_VERT, False)

While WaitEvent()
	Select EventID()
		Case EVENT_GADGETSELECT
			Select EventSource()
				Case textarea
					SetTextAreaText(index,"")
					For Local loop:Int = 0 To TextAreaLine(textarea,TextAreaLen(textArea))
						AddTextAreaText index, ""+loop
						If loop = TextAreaLine(textarea,TextAreaLen(textArea)) Then Exit 
						AddTextAreaText index,"~n"
					Next
					Local selectedLine:Int = TextAreaCursor(textarea,TEXTAREA_LINES)
					SelectTextAreaText(index,selectedLine,1,TEXTAREA_LINES)		
			End Select 
	
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_APPTERMINATE
			End
	End Select
Wend


Hard one to explain whats wrong, but will show you the steps so you can see my problem, basically, run the program above...

Then, on each line, type a number (incremently) on each line of the big text area like so...


0
1
2
3
4
..


0 to 15 should be sufficent.

You'll probably see that on the left that the number is copied, this is a line counter. When you reach 15, navigate back up the large text area using the cursor keys and you'll see that the cursor is followed on the left.

When you get back up to 0, navigate back down and you should see something very odd happening...

This should pretty much be enough to realise what I'm after... I need the highlighted line number on the left to match the same line position of the cursor in the large text area.

Anyone lend a hand getting this to work, as I havent really got a clue why its jumping like it is! :|

Much appreciated

Dabz


SebHoll(Posted 2008) [#2]
The unexpected behaviour is because of the way that the RichEdit control scrolls to character positions. Try the following:

Import MaxGui.Drivers

Strict 

Local window:TGadget
Local textarea:TGadget
Local index:TGadget 

window=CreateWindow("My Window",130,20,400,300,,15|WINDOW_ACCEPTFILES)

textarea=CreateTextArea(50,0,ClientWidth(window)-70,200,window)
index = CreateTextArea(10,0,30,200,window,TEXTAREA_READONLY)
DisableGadget index
Local hWnd = QueryGadget(index, QUERY_HWND)
SendMessageA(hWnd, EM_SHOWSCROLLBAR, SB_VERT, False)

While WaitEvent()
	Select EventID()
		Case EVENT_GADGETSELECT
			Select EventSource()
				Case textarea
					LockTextArea index
					SetTextAreaText(index,"")
					For Local loop:Int = 0 To TextAreaLine(textarea,TextAreaLen(textArea))
						AddTextAreaText index, ""+loop
						If loop = TextAreaLine(textarea,TextAreaLen(textArea)) Then Exit 
						AddTextAreaText index,"~n"
					Next
					UnlockTextArea index
					Local selectedLine:Int = TextAreaCursor(textarea,TEXTAREA_LINES)
					SelectTextAreaText(index,selectedLine,0,TEXTAREA_LINES)
					SelectTextAreaText(index,selectedLine,1,TEXTAREA_LINES)		
			End Select 
	
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_APPTERMINATE
			End
	End Select
Wend
Notice the use of the second call to SelectTextAreaText(). The first positions the cursor at the start of the line - the text area control scrolls so that the start of the concerned line is visible. The second call then selects the entire line.

As you had it before, the SelectTextAreaText() command highlights the whole line straight away. The text area controls scrolls to first point where the selection is visible - to the text area, this is right at the start of the following line.

LockTextAreaText() may improve text area performance on some platforms but isn't necessary. Just added it for good measure.

I know the explanation isn't fantastic, but there is a reason why Microsoft's Rich Text control has that behaviour, and the workaround is to select the beginning of the line first.

Hope this helps,

Seb


Dabhand(Posted 2008) [#3]
Thanks Seb, that bit works a treat! :)

But I'm still getting weird results when I move the cursor up and down in the large text area, as in, it loses sync with the smaller index text area... Any pointers, or a suggestion on what you would think would be the best way to handle this little problem... Its a bugger! ;)

Dabz


Dabhand(Posted 2008) [#4]
Found this:-

SendMessageA(QueryGadget(textarea,QUERY_HWND), EM_GETFIRSTVISIBLELINE, 0, 0)


Hopefully, this will help me stop losing sync if I know the first visible line number... Will test tomorrow, sick as a parrot mucking about now! ;)

Dabz


Dabhand(Posted 2008) [#5]
I had a quick go and cracked it:-

Import MaxGui.Drivers

Strict 

Local window:TGadget
Local textarea:TGadget
Local index:TGadget 

window=CreateWindow("My Window",130,20,400,300,,15|WINDOW_ACCEPTFILES)

textarea=CreateTextArea(50,0,ClientWidth(window)-70,200,window)
index = CreateTextArea(10,0,30,200,window,TEXTAREA_READONLY)
DisableGadget index
Local hWnd = QueryGadget(index, QUERY_HWND)
SendMessageA(hWnd, EM_SHOWSCROLLBAR, SB_VERT, False)

While WaitEvent()
	Select EventID() 
		Case EVENT_GADGETSELECT
			Select EventSource()
				Case textarea
					LockTextArea index
					SetTextAreaText(index,"")
					For Local loop:Int = 0 To TextAreaLine(textarea,TextAreaLen(textArea))
						AddTextAreaText index, ""+loop
						If loop = TextAreaLine(textarea,TextAreaLen(textArea)) Then Exit 
						AddTextAreaText index,"~n"
					Next
					UnlockTextArea index
					Local selectedLine:Int = TextAreaCursor(textarea,TEXTAREA_LINES)
					SelectTextAreaText(index,SendMessageA(QueryGadget(textarea,QUERY_HWND), EM_GETFIRSTVISIBLELINE, 0, 0),0,TEXTAREA_LINES)
					SelectTextAreaText(index,selectedLine,1,TEXTAREA_LINES)	
					Print SendMessageA(QueryGadget(textarea,QUERY_HWND), EM_GETFIRSTVISIBLELINE, 0, 0)
			End Select 
	
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_APPTERMINATE
			End
	End Select
Wend


Lovely!!! :D

Thanks again Seb! ;)

Dabz