Page 1 of 1

cursor management

Posted: Tue Aug 15, 2023 10:44 am
by wawavoun
Hello,

I try to use the function setgadgetattribute(#canvas, #pb_canvas_cursor, #pb_cursor_busy) before a long calculation loop (and reverse to default cursor at the end of the loop).
The code run without error or warning.

But the cursor dont change (at least under linux) under normal situation.
But if the calculation loop is interrupted (by some application internal problem) and exit without setting the default cursor then the busy cursor come on the screen...

I assume the problem is linked to event management and because the calculation loop start immediately after the cursor change then window management system has no chance to do the operation.

How can I solve this ?

Thanks for the help.
Philippe

Re: cursor management

Posted: Tue Aug 15, 2023 11:03 am
by Gérard
Hello,

Maybe

Code: Select all

EnableExplicit

OnErrorGoto(?ErrorHandler)

; your program

ErrorHandler:

; release cursor

End

Re: cursor management

Posted: Tue Aug 15, 2023 11:44 am
by wawavoun
I apologize if I have been unclear.

My problem is not in the case of an interrupted calculation loop.

My question is : what to do just after the setgadgetattribute(#canvas...) and before the calculation loop start in order to have the new cursor on the screen ?

If I remember correctly under VB there is an instruction 'doevent' which do that...

Thanks again.
Philippe

Re: cursor management

Posted: Tue Aug 15, 2023 11:46 am
by BarryG
This is the equivalent of "DoEvents" of Visual Basic:

Code: Select all

While WindowEvent() : Wend

Re: cursor management

Posted: Tue Aug 15, 2023 12:19 pm
by wawavoun
Thanks but dont do the job I expect...

Re: cursor management

Posted: Tue Aug 15, 2023 12:58 pm
by Gérard
DoEvents() replacement

Code: Select all

Procedure.a doEvents(loop.a=255)
  Protected n.a 
  For n = 0 To loop
    WindowEvent()
    n + 1
  Next
EndProcedure
Usage: DoEvents(N) ; N between 1 and 255

Edit:
I tried with one of my applications, the busy cursor is only visible on the visible part of the canvas.
If the canvas is covered by another gadget, the busy cursor is not visible.

Re: cursor management

Posted: Tue Aug 15, 2023 1:24 pm
by wawavoun
During your test with the busy cursor did you use this dovents loop ?

Re: cursor management

Posted: Tue Aug 15, 2023 2:13 pm
by Gérard
Yes.

DoEvents(10)

Re: cursor management

Posted: Tue Aug 15, 2023 3:14 pm
by Gérard
DoEvents(1) is to be done in the working loop
An example that works.

Code: Select all

Declare.a doEvents(loop.a=255)
#bgcolor = 14474460 ; bgcolor = RGB(220,220,220) $00DCDCDC
#winMain=0
#canvas=0
#status=1
#button=2
#appWidth  = 550
#appHeight = 170
#Flags = #PB_Window_TitleBar|#PB_Window_ScreenCentered|#PB_Window_SystemMenu

If OpenWindow(#winMain, #PB_Any, #PB_Any , #appWidth, #appHeight, "Canvas test", #Flags)
  SetWindowColor(#winMain, #bgcolor)
  CreateStatusBar(#status, WindowID(#winMain))
  AddStatusBarField(#PB_Ignore)
  StatusBarText(#status, 0, "Testing...")
  CanvasGadget(#canvas, 0, 0, #appWidth, #appHeight-StatusBarHeight(#status), #PB_Canvas_Container)
  StartDrawing(CanvasOutput(#canvas))
    FillArea(0, 0, -1,#bgcolor)
  StopDrawing()
  ButtonGadget(#button,10,10,150,25,"Do a long job")
  CloseGadgetList()
  
  Repeat
    Event = WaitWindowEvent(20)
    Select Event
      Case #PB_Event_Menu
        indexMenu = EventMenu()
      Case #PB_Event_Gadget
        indexGadget     = EventGadget()
        indexGadgetType = EventType()
        Select indexGadget
          Case #button
            DisableGadget(#button,#True)
            SetGadgetAttribute(#canvas, #PB_Canvas_Cursor, #PB_Cursor_Busy)
            For N=0 To 10000
              doEvents(1)
              StatusBarText(#status, 0, "Testing..."+Str(N))
            Next
            SetGadgetAttribute(#canvas, #PB_Canvas_Cursor, #PB_Cursor_Default)
            DisableGadget(#button,#False)
        EndSelect
      Case #PB_Event_SysTray
        Select EventType()
        EndSelect
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_MinimizeWindow
      Case #PB_Event_MaximizeWindow
      Case #PB_Event_RestoreWindow
    EndSelect
  ForEver
EndIf

Procedure.a doEvents(loop.a=255)
  Protected n.a 
  For n = 0 To loop
    WindowEvent()
    n + 1
  Next
EndProcedure

Re: cursor management

Posted: Tue Aug 15, 2023 3:38 pm
by infratec
My standard sentence:

Only one event loop in a program.

If you have to run time consuming stuff, use a thread.
If you use a thread, don't access GUI elements directly. Use PostEvent() to do this in the main thread.