ClearGadgetItems() doesn't clear first row in EditorGadget?

Just starting out? Need help? Post your questions and find answers here.
User avatar
mhs
Enthusiast
Enthusiast
Posts: 101
Joined: Thu Jul 02, 2015 4:53 pm
Location: Germany
Contact:

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

Post by mhs »

if you want to bypass the problem completely, you should outsource the timeconsumingcode in an extra thread.
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

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

Post 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
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

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

Post 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).
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mhs
Enthusiast
Enthusiast
Posts: 101
Joined: Thu Jul 02, 2015 4:53 pm
Location: Germany
Contact:

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

Post 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.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

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

Post 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
Egypt my love
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

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

Post 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
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

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

Post 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.
Image
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

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

Post 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
Egypt my love
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

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

Post 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)
Image
Post Reply