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?
Textarea update
BlitzMax Forums/BlitzMax GUI Programming/Textarea update 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.
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.
Try PollSystem() in your loop.
Thanks. I just tried that and it dosen't work.
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?
Some code which shows the problem?
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
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
Still doesn't work.
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.
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.
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?
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.
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:
SuperStrict Import MaxGui.Drivers Global TBackupFolder:TGadget Global TMasterFolder:TGadget Global TMonitor:TGadget Local Window1:TGadget = CreateWindow:TGadget("Window1",247,140,391,261,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_STATUS |WINDOW_CLIENTCOORDS ) Local LBackupFolder:TGadget = CreateLabel:TGadget("Backup Folder",15,59,80,15,Window1:TGadget,Null) Local LMasterFolder:TGadget = CreateLabel:TGadget("Master Folder",15,12,80,15,Window1:TGadget,Null) Local BMaster:TGadget = CreateButton:TGadget("Set",332,29,46,18,Window1:TGadget,BUTTON_PUSH) TBackupFolder:TGadget = CreateTextField:TGadget(15,76,299,18,Window1:TGadget,Null) SetGadgetText( TBackupFolder:TGadget,"") Local BBackup:TGadget = CreateButton:TGadget("Set",332,76,46,18,Window1:TGadget,BUTTON_PUSH) TMasterFolder:TGadget = CreateTextField:TGadget(15,29,299,18,Window1:TGadget,Null) SetGadgetText( TMasterFolder:TGadget,"") Local BSync:TGadget = CreateButton:TGadget("Sync",303,235,75,23,Window1:TGadget,BUTTON_PUSH) TMonitor:TGadget = CreateTextArea:TGadget(15,126,363,101,Window1:TGadget,Null) SetTextAreaText( TMonitor:TGadget , "" ) Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE Select EventSource() Case Window1 Window1_WC( Window1:TGadget ) End Select Case EVENT_GADGETACTION Select EventSource() Case BMaster BMaster_GA( BMaster:TGadget ) Case TBackupFolder TBackupFolder_GA( TBackupFolder:TGadget ) Case BBackup BBackup_GA( BBackup:TGadget ) Case TMasterFolder TMasterFolder_GA( TMasterFolder:TGadget ) Case BSync BSync_GA( BSync:TGadget ) End Select End Select Forever Function Window1_WC( Window:TGadget ) DebugLog "Window Window1 wants to be closed" End End Function Function BMaster_GA( Button:TGadget ) DebugLog "Button BMaster was pressed" SetGadgetText(TMasterFolder, RequestDir("Master Folder")) End Function Function TBackupFolder_GA( TextField:TGadget ) DebugLog "TextField TBackupFolder was modified" DebugLog "Text = "+ TextFieldText$( TextField:TGadget ) End Function Function BBackup_GA( Button:TGadget ) DebugLog "Button BBackup was pressed" SetGadgetText(TBackupFolder,RequestDir("Backup Folder")) End Function Function TMasterFolder_GA( TextField:TGadget ) DebugLog "TextField TMasterFolder was modified" DebugLog "Text = "+ TextFieldText$( TextField:TGadget ) End Function Function BSync_GA( Button:TGadget ) DebugLog "Button BSync was pressed" For Local i:Int = 1 To 10 AddTextAreaText( TMonitor:TGadget,"Syncing file"+Rand(1,1000)+"~n" ) Delay 50 Next End Function
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.
Try this:
Is that the result you wanted?
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?
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.
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.