Page 2 of 2

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Mon Apr 04, 2016 2:23 pm
by mhs
if you want to bypass the problem completely, you should outsource the timeconsumingcode in an extra thread.

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Mon Apr 04, 2016 2:29 pm
by collectordave
Hi mhs

The thread solution posted earlier but it does not allow lord to set the text from the timeconsuming code as it is in a thread.

Regards

CD

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Mon Apr 04, 2016 2:56 pm
by wilbert
collectordave wrote:The thread solution posted earlier but it does not allow lord to set the text from the timeconsuming code as it is in a thread.
What I did for my own app LumaTone, is to let the time consuming thread allocate some new memory for every text message using AllocateMemory, fill it with the text message and post en event using PostEvent with the pointer that AllocateMemory returned as data.
The main thread processes this event in the event loop by adding the text to the EditorGadget and freeing the allocated memory.
This way PureBasic doesn't free the memory itself like with local variables and the memory is never accessed at the same time by multiple threads.
So far I can tell it works stable on all three platforms (Windows, OSX and Linux).

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Mon Apr 04, 2016 3:02 pm
by mhs
My solution would be something like wilberts. I would just use a global list as a queue instead of allocation memory manual, but that is a matter of taste.

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Mon Apr 04, 2016 5:45 pm
by RASHAD
I think it is related to the Gadget Device Context
Specially when the gadget is MultiLine

Windows workaround

Code: Select all

Procedure SetSomeText()
  Static x
  ClearGadgetItems(2)  
  UpdateWindow_(GadgetID(2))
  x=1-x
  If x
    SetGadgetText(2, "1111111111111111111"+#CRLF$+"1111111111111111111")
    Delay(500)
  Else
    SetGadgetText(2, "2222222222222222222"+#CRLF$+"2222222222222222222")
    Delay(500)
  EndIf
EndProcedure

OpenWindow(1, 10, 10, 640, 480, "")
StringGadget(1, 55, 5, 580, 20, "")
EditorGadget(2, 5, 30, 630, 445, #PB_Editor_WordWrap)
AddKeyboardShortcut(1, #PB_Shortcut_Return, 10)
BindEvent(#PB_Event_Menu, @SetSomeText(), 1)
Quit=#False
Repeat
  Event=WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit=#True
      
  EndSelect
Until Quit=#True
Cross platform workaround

Code: Select all

Procedure SetSomeText()
  Static x
  FreeGadget(2)
  EditorGadget(2, 5, 30, 630, 445, #PB_Editor_WordWrap) 
 x=1-x
  If x
    SetGadgetText(2, "1111111111111111111"+#CRLF$+"1111111111111111111")
    Delay(500)
  Else
    SetGadgetText(2, "2222222222222222222"+#CRLF$+"2222222222222222222")
    Delay(500)
  EndIf
EndProcedure

OpenWindow(1, 10, 10, 640, 480, "")
StringGadget(1, 55, 5, 580, 20, "")
EditorGadget(2, 5, 30, 630, 445, #PB_Editor_WordWrap)
AddKeyboardShortcut(1, #PB_Shortcut_Return, 10)
BindEvent(#PB_Event_Menu, @SetSomeText(), 1)
Quit=#False
Repeat
  Event=WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit=#True
      
  EndSelect
Until Quit=#True

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Mon Apr 04, 2016 7:26 pm
by collectordave
I think the most important message here is to see that when there is some time comsuming code that just has to be run then it is the programmers responsibility to ensure that the messages sent to the application by the OS are still processed.

I have rewritten my example earlier using RASHAD's solution. the updates are immediate but the messages are still not processed. The example here uses the windowevent() and runs fine. If you comment out the While WindowEvent() : Wend lines and decomment the ;UpdateWindow_(GadgetID(2)) lines the first thing to notice is that the button is not displayed and then after some time the programme crashes, however this is not a crash the programme has just not processed it's messages so the OS thinks it has crashed. As infratec pointed out
It is a windows program, which is event driven.
A call to something which modifies the GUI is not handled immediately.
At least one round through the event loop is needed.
All things on the GUI stop when running code that does not process the event loop at least occasionally.

Code: Select all

Global Text.s

Procedure SetSomeText()

  Static x
 
  Select x
      
    Case 0
      ClearGadgetItems(2)
      Text = ""
     
    Case 1
     
      For i=1 To 25
        Text = Text +"11111111111111111111111111111111"+#CRLF$
      Next
      SetGadgetText(2, Text)
      Text = ""
   
    Case 2
     
      For i=1 To 25
        Text = Text +"22222222222222222222222222222222"+#CRLF$
      Next
      SetGadgetText(2, Text)   
      text = ""
   
 EndSelect
  x = x + 1
  If x > 2
    x = 0
  EndIf
 
EndProcedure

Procedure TimeConsumingCode()
 
  For i=1 To 5000000
    
    ;Some time consuming Code
    StartTime = ElapsedMilliseconds() 
    While   endtime < 5000                     
      EndTime = ElapsedMilliseconds()-StartTime 
    Wend
    
    Select i
       
      Case 1000000
        text = "Just testing after first 1000000"
        SetGadgetText(2, Text)
        ;UpdateWindow_(GadgetID(2))
        While WindowEvent() : Wend   
        ;More time consuming Code
        StartTime = ElapsedMilliseconds() 
        While   endtime < 5000                     
          EndTime = ElapsedMilliseconds()-StartTime 
        Wend       
        
      Case 2000000
        
        SetSomeText()
        ;UpdateWindow_(GadgetID(2))
        While WindowEvent() : Wend      
        ;More time consuming Code
        StartTime = ElapsedMilliseconds() 
        While   endtime < 5000                     
          EndTime = ElapsedMilliseconds()-StartTime 
        Wend         
      Case 3000000
       
        SetSomeText()
        While WindowEvent() : Wend
        ;UpdateWindow_(GadgetID(2))        
        ;More time consuming Code
        StartTime = ElapsedMilliseconds() 
        While   endtime < 5000                     
          EndTime = ElapsedMilliseconds()-StartTime 
        Wend         
      Case 4000000
       
        SetSomeText()
        
        ;More time consuming Code
        StartTime = ElapsedMilliseconds() 
        While   endtime < 5000                     
          EndTime = ElapsedMilliseconds()-StartTime 
        Wend         
        While WindowEvent() : Wend 
        ;UpdateWindow_(GadgetID(2))
    EndSelect     
   
    While WindowEvent() : Wend
    ;More time consuming Code
    StartTime = ElapsedMilliseconds() 
    While   endtime < 5000                     
      EndTime = ElapsedMilliseconds()-StartTime 
    Wend   
    y=Pow(2, i)
   
  Next

  Debug "Time Consuming Code Finished"
 
EndProcedure

OpenWindow(1, 10, 10, 640, 480, "")
ButtonGadget(1, 5, 5, 100, 20, "")
EditorGadget(2, 5, 30, 630, 445, #PB_Editor_WordWrap)
AddKeyboardShortcut(1, #PB_Shortcut_Return, 10)
BindEvent(#PB_Event_Menu, @SetSomeText(), 1)
Quit=#False

Text = ""

TimeConsumingCode()

Repeat
  Event=WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit=#True
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          Debug "Time Consuming Code Started"
          TimeConsumingCode()
      EndSelect
  EndSelect
Until Quit=#True
Regards

CD

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Tue Apr 05, 2016 7:51 am
by Lord
@all:
Thank you for all your very valuable inputs.

I think Rashad's way is the way I will go by just adding

Code: Select all

UpdateWindow_(GadgetID(2))
right after ClearGadgetItems().
It prevents from displaying a misleading residue in line one.
(At least in this specific case)

Thank you @Rashad for this nice little tip!
Your code pieces are always a source for inspiration.

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Tue Apr 05, 2016 9:37 am
by RASHAD
Hi Lord
Thanks mate

Another workarounds

# 1:

Code: Select all

Procedure SetSomeText()
  Static x
  r = CountGadgetItems(2)
  For row = r To 0 Step -1
    RemoveGadgetItem(2,row)  
  Next
  x=1-x
  If x
    SetGadgetText(2, "1111111111111111111"+#CRLF$+"1111111111111111111")
    Delay(500)
  Else
    SetGadgetText(2, "2222222222222222222"+#CRLF$+"2222222222222222222")
    Delay(500)
  EndIf
EndProcedure

OpenWindow(1, 10, 10, 640, 480, "")
StringGadget(1, 55, 5, 580, 20, "")
EditorGadget(2, 5, 30, 630, 445, #PB_Editor_WordWrap)
AddKeyboardShortcut(1, #PB_Shortcut_Return, 10)
BindEvent(#PB_Event_Menu, @SetSomeText(), 1)
Quit=#False
Repeat
  Event=WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit=#True
     
  EndSelect
Until Quit=#True
# 2:

Code: Select all

Procedure SetSomeText()
  Static x
  r = CountGadgetItems(2)
  RemoveGadgetItem(2,r)
  ClearGadgetItems(2)
  
  x=1-x
  If x
    SetGadgetText(2, "1111111111111111111"+#CRLF$+"1111111111111111111")
    Delay(500)
  Else
    SetGadgetText(2, "2222222222222222222"+#CRLF$+"2222222222222222222")
    Delay(500)
  EndIf
EndProcedure

OpenWindow(1, 10, 10, 640, 480, "")
StringGadget(1, 55, 5, 580, 20, "")
EditorGadget(2, 5, 30, 630, 445, #PB_Editor_WordWrap)
AddKeyboardShortcut(1, #PB_Shortcut_Return, 10)
BindEvent(#PB_Event_Menu, @SetSomeText(), 1)
Quit=#False
Repeat
  Event=WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Quit=#True
     
  EndSelect
Until Quit=#True

Re: ClearGadgetItems() doesn't clear first row in EditorGadg

Posted: Tue Apr 05, 2016 4:11 pm
by Lord
Hi Rashad!

Thank you for trying to give me some more options to choose from.

I Think, I will stick to your first "workaround" because:

1. "workaround" (both versions)
Gadget is cleared at once, no residue
2. "Another workaround #1"
Gadget is not cleared at once, you can't tell wether there is a residue or not
3. "Another workaround #2"
Gadget cleared, but first row stays (residue, not really an improvement)