Textarea update

BlitzMax Forums/MaxGUI Module/Textarea update

zambani(Posted 2008) [#1]
I have recursive function in which I'm sending text to a textarea to be displayed. The problem is that the textarea won't update with the new data until the entire recursive function runs its course. Is there a way to run the recursive function and give temporary control back to the OS after each iteration so it can update the text area?


jsp(Posted 2008) [#2]
Try PollSystem() in your loop.

PollSystem returns control back to the operating system, allowing such events as keystrokes and gadget actions to be processed. Control is then returned back to your program.


zambani(Posted 2008) [#3]
Try PollSystem() in your loop.


Thanks. I just tried that and it dosen't work.


jsp(Posted 2008) [#4]
Put the PollSystem right after the command which alters the textarea text. Maybe another RedrawGadget can help as well.
Some code which shows the problem?


zambani(Posted 2008) [#5]
Some code which shows the problem?


Below is the code;
It comes to action wthen the bt_SYNC event fires.

backupFiles: is the main recursive function
addMonitorText: is where I send some text to the text area

Thanks a lot

Function mainHook:Object(id:Int, data:Object, context:Object) 

	Local Event:TEvent = TEvent(data)
'Print Event.ToString() 
	Select Event.id
		Case EVENT_WINDOWCLOSE
			End
			
		Case EVENT_GADGETPAINT
			refreshScreen() 
			
		Case EVENT_GADGETACTION
			Select Event.source
				Case btn_SELECT1
					txb_masterFolder.SetText(RequestDir("Master Folder"))
				Case btn_SELECT2
					txb_backupFolder.SetText(RequestDir("Backup Folder"))
				Case btn_SYNC
					master = txb_masterFolder.GetText()
					backup = txb_backupFolder.GetText()
					backupFiles() ;
					Print
					Print
					addMonitorText("COMPLETED!")
					Print
					Print
			EndSelect
	EndSelect
End Function

Function addMonitorText(t:String)
	Local bt:String
	For Local a:Int = MonitorTextArray.Length - 1 To 1 Step - 1
		MonitorTextArray[a] = MonitorTextArray[a - 1]
		bt:+MonitorTextArray[a] + "~n"
	Next
	monitor.SetText(bt + t)
	MonitorTextArray[0] = t
	PollSystem()
End Function


Function backupFiles(path:String = "")
	Local fn:String
	Local inputDir = ReadDir(master + path)
	
	fn = NextFile(inputDir) 'Get the filenames in folder
	While fn <> ""
		If fn <> "." And fn <> ".."
			If FileType(master + path + "\" + fn) = FILETYPE_DIR
				If FileType(backup + path + "\" + fn) = 0
					'Create new dir in backup if one does not exist in master
					If Not CreateDir(backup + path + "\" + fn)
						addMonitorText("Error trying to create dir - " + backup + path + "\" + fn)
						End
					End If
					addMonitorText("DIRECTORY ADDED - " + backup + path + "\" + fn)
				End If
'Print "PATH-" + path + "\" + fn
				backupFiles(path + "\" + fn)
			End If
			addNew(master, backup, path, fn)
		End If
		fn = NextFile(inputDir) 'Get the filenames in folder
	Wend

	inputDir = ReadDir(backup + path)
	fn = NextFile(inputDir) 'Get the filenames in folder
	While fn <> ""
		If fn <> "." And fn <> ".."
			If FileType(backup + path + "\" + fn) = FILETYPE_DIR
				If FileType(master + path + "\" + fn) = 0
					'Remove  entire dir in backup if one does not exist in master
					If Not DeleteDir(backup + path + "\" + fn, True)
						addMonitorText("Error trying to delete dir - " + backup + path + "\" + fn)
						End
					End If				
					addMonitorText("DIRECTORY REMOVED - " + backup + path + "\" + fn)
				End If
				backupFiles(path + "\" + fn)
			End If
			removeOrphan(master, backup, path, fn)
		End If
		fn = NextFile(inputDir) 'Get the filenames in folder
	Wend
	
End Function


Function removeOrphan(master:String, backup:String, path:String, file:String)
	If FileType(master + path + "\" + file) = 0
		'If file does not exist in master, then delete it.
		DeleteFile(backup + path + "\" + file)
		addMonitorText("Deleted - " + backup + path + "\" + file)
	End If
End Function




jsp(Posted 2008) [#6]
Try to move the PollSystem() one line up and see if that helps
Function addMonitorText(t:String)
	Local bt:String
	For Local a:Int = MonitorTextArray.Length - 1 To 1 Step - 1
		MonitorTextArray[a] = MonitorTextArray[a - 1]
		bt:+MonitorTextArray[a] + "~n"
	Next
	monitor.SetText(bt + t)
	PollSystem()
	MonitorTextArray[0] = t
End Function



zambani(Posted 2008) [#7]
Still doesn't work.


jsp(Posted 2008) [#8]
Hmm, difficult to say what else could be the problem, by just looking at the code.
I have seen sometimes, that more than one PollSystem() was needed and always bound to the gadget you wanna update, looks like its quite time critical.
One thing I noticed in your code is that you don't return the event in your hook function if you don't act on it. Is this what you wanted? And is there a special reason that you needed that hook function, as you mainly look for the buttons if they are pressed, except the refresh screen I can't imagine any time critical thing here.


zambani(Posted 2008) [#9]
The mainHook function I got from somewhere else, so I'm not sure if it's needed. Is there a better way to recieve the events for the buttons?


jsp(Posted 2008) [#10]
A 'better' way? No, I would say a different way.
For normal operations a standard WaitEvent() queue is quite sufficient. (But what is normal?:)
Hook functions are good for immediate reactions and for types which have self contained actions on events. Immediate reaction may required for drawing a canvas and a type could be something like the splitter gadget, where the content is adjusted while dragging the split. So, there is nothing wrong with using hooks, maybe just a bit too much for a basic gui, but of course it depends on the program and how the hooks are used.

An example of a WaitEvent() loop is here, just watch the debuglog:


The problem in your program comes more or less from the fact that there is no time left to the system to update the gui. So, if the PollSystem() doesn't work for you, you could also think about another way of doing it. You could for instance copy some bytes, pause – update your gadgets (progress bar, textarea) – resume and copy some more and so on. Every time you pause, you could check for new events as well. Takes a bit longer for the hole process but is maybe more comfortable.


William Drescher(Posted 2008) [#11]
Try this:

Function addMonitorText(t:String)
	Local bt:String
	For Local a:Int = MonitorTextArray.Length - 1 To 1 Step - 1
		MonitorTextArray[a] = MonitorTextArray[a - 1]
		bt:+MonitorTextArray[a] + "~n"
		monitor.SetText(bt + t)
		PollSystem()
	Next
	MonitorTextArray[0] = t
End Function


Is that the result you wanted?


zambani(Posted 2008) [#12]
jsp, Wilkua
Thanks for all the help. After carefully looking at both your suggestions, I was able to track the problem to the hook function. It was holding up the show. I replaced it with the straight forward currentEvent and call the PollSystem at the end of the addMoniTorText function.

One again thanks a million. That teaches me for just using code without knowing HOW it works.