imagegadget / eventloop problem

Just starting out? Need help? Post your questions and find answers here.
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

imagegadget / eventloop problem

Post by kepu »

Hi!
I have a little problem with differences Windows and lLnux ,
I put these two codes to here if somebody can explain what i have done wrong
I am a newbie in Purebasic

Problem is in repeat-until loop, straight once/cycle command 'gosub crosshair' , it works in Windows fine, but in Linux it worked only when I coded it inside the loop but same code (similar outside the loop in sub 'crosshair') needed imagegadget(.. in addition of setgadgetstate(.. to work.
but other similar calls later didn't need that
Here are both codes (working ones )

This code works fine in Windows but not in Linux

Code: Select all

   Procedure WindowMouseButton(Wnd, ButtonNr)
    If Wnd And GetForegroundWindow_() = Wnd
    Select ButtonNr
      Case 0
        If GetAsyncKeyState_(#VK_LBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 1
        If GetAsyncKeyState_(#VK_RBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 2
        If GetAsyncKeyState_(#VK_MBUTTON) > 0
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf
  ProcedureReturn 0
EndProcedure
;********************************************************************

    WindowWidth = 1000  
     WindowHeight = 700
If OpenWindow(0, 10, 10, WindowWidth, WindowHeight, "PureQCad.018 ")

 hWnd = WindowID(0)
If hWnd <> 0

If CreateMenu(0, WindowID(0))
    MenuTitle("File")
      MenuItem( 1, "&Load...")
      MenuItem( 2, "Save")
       MenuBar()
      MenuItem( 5, "Exit")
 
    MenuTitle("Edit")
    MenuTitle("Draw")
      MenuItem( 18, "Line")
    MenuTitle("Mode")
    MenuTitle("Help")
      MenuItem( 44, "Help")
      MenuItem( 45, "About")
       
    EndIf  
        
 If CreateStatusBar(0, WindowID(0))
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100) 
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100) 
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100)

    EndIf
    
   StatusBarText(0, 0, "prog_name")
   StatusBarText(0, 1, " xx= ")
   StatusBarText(0, 2, " yy= ")  
   StatusBarText(0, 3, " orx= ")
   StatusBarText(0, 4, " ory= ")
   StatusBarText(0, 5, " DrawC ")
   StatusBarText(0, 6, " x= " )
   StatusBarText(0, 7, " y= " )
   StatusBarText(0, 8, "     ")
   StatusBarText(0, 9, "     ")
   StatusBarText(0, 10, "     ")
   
;********  init imagegadget ***********************************************
   bitmap1_n = 1                                                             ; image number 1
   bitmap1_h = CreateImage(bitmap1_n,800,550)      ; create the image and store the handle
   gadget1_n = 1
 ImageGadget(gadget1_n,0,0,800,500,bitmap1_h)  

; ******** init cross hair ***************************************************
 StartDrawing(ImageOutput(bitmap1_n))
     FillArea(10,10,-1,$ffffff) 
   DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
      ox=10
      oy=10
       oox=ox
       ooy=oy
        hwidth=WindowWidth-40
        hheight=WindowHeight-45
          Line(ox,10, 0, hheight , RGB(55,55,55)) 
          Line(10,oy, hwidth , 0, RGB(55,55,55)) 
 StopDrawing() 
 SetGadgetState(gadget1_n,bitmap1_h)

   For iii=0 To 100000: Next
   
 ;********* menuloop ****************************************************************************** 
Repeat
 event= WaitWindowEvent()
 Select event
   Case #PB_Event_Menu
      Select EventMenu()  
         Case 18     ;Line
             Gosub setLine
         Case 45 ; About
             MessageRequester("About", "image_gadget_test", 0)
         Case 5 ; exit
             Quit=#True     ;  End
         Default
             MessageRequester("Info", "MenuItem: "+Str(EventMenu()), 0)
      EndSelect
      
   Case #PB_Event_CloseWindow
        Quit=#True
 EndSelect
  
  Gosub crosshair    ;this does not work properly  in Linux if :SetGadgetState).... is used incrosshair sub

Until  Quit = #True
EndIf
End

;'****** end of menuloop ****************************************

crosshair:

    StartDrawing(ImageOutput(bitmap1_n))              
     DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
      ox=WindowMouseX(0)
      oy=WindowMouseY(0)         
       Line ( oox,  10, 0,  hheight, RGB(55,55,55))
       Line (10, ooy, hwidth, 0, RGB(55,55,55))
       Line ( ox, 10, 0, hheight, RGB(55,55,55))
       Line ( 10, oy, hwidth,0 , RGB(55,55,55))
    StopDrawing()   
  SetGadgetState(gadget1_n,bitmap1_h)   
   oox=ox
   ooy=oy
 StatusBarText(0, 1, " xx= "+Str(ox))
   StatusBarText(0, 2, " yy= "+Str(oy))  
   StatusBarText(0, 3, " orx= "+Str(oox))
   StatusBarText(0, 4, " ory= "+Str(ooy))
Return
  
setLine:
     StatusBarText(0, 0, "Line")  
      iii=WindowMouseButton(hWnd, 0)
    For  iii=0 To 10000:Next
     If WindowMouseButton(hWnd, 0)=1
        Goto startLine
     EndIf
   Gosub crosshair
   Goto setline
   
 startLine:
     startX =ox  
     startY = oy   
     Gosub crosshair
          StartDrawing(ImageOutput(bitmap1_n))              
              DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
                          mousX = WindowMouseX(0)
                          mousY = WindowMouseY(0)
                    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))  
                   omousX=mousX
                   omousY=mousY 
                StatusBarText(0, 6, Str(startX) )  
                StatusBarText(0, 7, Str(startY))  
         StopDrawing()
       SetGadgetState(gadget1_n,bitmap1_h)
     For iii=0 To 10000:Next
    
 drawLine:
   If WindowMouseButton(hWnd, 0)=0
    Goto finishLine
  EndIf
   Gosub crosshair
      mousX =ox    ; WindowMouseX(0)
      mousY = oy    ;WindowMouseY(0)
      StartDrawing(ImageOutput(bitmap1_n))              
                 DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
                    Line(startX,startY,omousX-startX, omousY-startY,RGB(5,5,200))  
                    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))  
                      omousX=mousX
                      omousY=mousY  
                StatusBarText(0, 8, Str(mousX-startX))  
                StatusBarText(0, 9, Str(mousY-startY))  
       StopDrawing()
     SetGadgetState(gadget1_n,bitmap1_h)
   Goto drawline
 finishLine:
      mousX =ox    ; WindowMouseX(0)
      mousY = oy    ;WindowMouseY(0)
      StartDrawing(ImageOutput(bitmap1_n))              
                 DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
                    Line(startX,startY,omousX-startX, omousY-startY,RGB(5,5,200))  
                    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))
                StatusBarText(0, 8, Str(mousX-startX))  
                StatusBarText(0, 9, Str(mousY-startY))  
                StatusBarText(0, 0, "         ")     
      StopDrawing()
    SetGadgetState(gadget1_n,bitmap1_h)
 
   Return
EndIf
and this next code works fine in Linux , so it seems that there is somekind of difference in Windows and Linux version .
In linux : gosub from repeat/until loop(but outside of case command) or imagedget / setgadget in some point in my prog.
I hope someone has time to check these. I have been really stuck with this couple weeks .

Code: Select all


  Procedure WindowMouseButton(Wnd, ButtonNr)
  Protected gdkWnd.l, x.l, y.l, mask.l
 
  If Wnd
    *Window.GTKWindow = Wnd
    gdkWnd = *Window\bin\child\window
    gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
   
    Select ButtonNr
      Case 0
        If (mask & #GDK_BUTTON1_MASK)
          ProcedureReturn 1
        EndIf
      Case 1
        If (mask & #GDK_BUTTON3_MASK)
          ProcedureReturn 1
        EndIf
      Case 2
        If (mask & #GDK_BUTTON2_MASK)
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf
   ProcedureReturn 0
EndProcedure
;***************************************************************************

    WindowWidth = 1000  
     WindowHeight = 700
If OpenWindow(0, 10, 10, WindowWidth, WindowHeight, "PureQCad.018 ")

 hWnd = WindowID(0)
If hWnd <> 0

If CreateMenu(0, WindowID(0))
    MenuTitle("File")
      MenuItem( 1, "&Load...")
      MenuItem( 2, "Save")
       MenuBar()
      MenuItem( 5, "Exit")
 
    MenuTitle("Edit")
    MenuTitle("Draw")
      MenuItem( 18, "Line")
    MenuTitle("Mode")
    MenuTitle("Help")
      MenuItem( 44, "Help")
      MenuItem( 45, "About")
       
    EndIf  
       
 If CreateStatusBar(0, WindowID(0))
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100) 
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100) 
      AddStatusBarField(100)
      AddStatusBarField(100)
      AddStatusBarField(100)

    EndIf
    
   StatusBarText(0, 0, "prog_name")
   StatusBarText(0, 1, " xx= ")
   StatusBarText(0, 2, " yy= ")  
   StatusBarText(0, 3, " orx= ")
   StatusBarText(0, 4, " ory= ")
   StatusBarText(0, 5, " DrawC ")
   StatusBarText(0, 6, " x= " )
   StatusBarText(0, 7, " y= " )
   StatusBarText(0, 8, "     ")
   StatusBarText(0, 9, "     ")
   StatusBarText(0, 10, "     ")
   
;********  init imagegadget ***********************************************
bitmap1_n = 1                                   ; empty image  1
bitmap1_h = CreateImage(bitmap1_n,800,550)      ; create /store the handle
gadget1_n = 1
ImageGadget(gadget1_n,0,0,800,500,bitmap1_h)  

; ******** init cross hair ************************************************
StartDrawing(ImageOutput(bitmap1_n))
FillArea(10,10,-1,$ffffff) 
DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
      ox=10
      oy=10
     oox=ox
      ooy=oy
      hwidth=WindowWidth-40
       hheight=WindowHeight-45
      Line(ox,10, 0, hheight , RGB(55,55,55)) 
      Line(10,oy, hwidth , 0, RGB(55,55,55)) 
 StopDrawing() 
 SetGadgetState(gadget1_n,bitmap1_h)
   For iii=0 To 100000: Next
   
 ;********* menuloop ******************************************************
Repeat
event= WaitWindowEvent()
Select event
   Case #PB_Event_Menu
         Select EventMenu()  
                 Case 18     ;Line
                          Gosub setLine
                 Case 45 ; About
                           MessageRequester("About", "image_gadget_test", 0)
                 Case 5 ; exit
                          Quit=#True    ;End
                 Default
                          MessageRequester("Info", "MenuItem: "+Str(EventMenu()), 0)
         EndSelect
    Case #PB_Event_CloseWindow
        Quit=#True
 EndSelect
    
  ; **** continous cross hair outside case's / this works here inside the 'eventloop' 
  ;****  if this bloc is used outside  'eventloop' 
  ; ie. by : 'Gosub crosshair'  then loop get slower at every event
   StartDrawing(ImageOutput(bitmap1_n))              
      DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
         ox=WindowMouseX(0)
         oy=WindowMouseY(0)         
           Line ( oox,  10, 0,  hheight, RGB(55,55,55))
           Line (10, ooy, hwidth, 0, RGB(55,55,55))
           Line ( ox, 10, 0, hheight, RGB(55,55,55))
          Line ( 10, oy, hwidth,0 , RGB(55,55,55))
      StopDrawing() 
   SetGadgetState(gadget1_n,bitmap1_h)
       oox=ox
       ooy=oy
          StatusBarText(0, 1, " xx= "+Str(ox))
          StatusBarText(0, 2, " yy= "+Str(oy))  
          StatusBarText(0, 3, " orx= "+Str(oox))
;**************************************
Until  Quit = #True
EndIf
End

;'****** end of menuloop ****************************************
crosshair:

   StartDrawing(ImageOutput(bitmap1_n))              
      DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
          ox=WindowMouseX(0)
          oy=WindowMouseY(0)         
             Line ( oox,  10, 0,  hheight, RGB(55,55,55))
             Line (10, ooy, hwidth, 0, RGB(55,55,55))
             Line ( ox, 10, 0, hheight, RGB(55,55,55))
             Line ( 10, oy, hwidth,0 , RGB(55,55,55))
   StopDrawing() 
   ImageGadget(gadget1_n,0,0,800,500,bitmap1_h)   ; but now this is needed in Linux ...not in Windows
    SetGadgetState(gadget1_n,bitmap1_h)                    
       oox=ox
       ooy=oy
          StatusBarText(0, 1, " xx= "+Str(ox))
          StatusBarText(0, 2, " yy= "+Str(oy))  
          StatusBarText(0, 3, " orx= "+Str(oox))
          StatusBarText(0, 4, " ory= "+Str(ooy))

Return
  
  setLine:
  StatusBarText(0, 0, "Line")  
  iii=WindowMouseButton(hWnd, 0)
  For  iii=0 To 10000:Next
   If WindowMouseButton(hWnd, 0)=1
    Goto startLine
  EndIf
  Gosub crosshair
   Goto setline
   
  startLine:
     startX =ox    
     startY = oy 
     Gosub crosshair
          StartDrawing(ImageOutput(bitmap1_n))              
                 DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
                          mousX = WindowMouseX(0)
                          mousY = WindowMouseY(0)
                    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))  
                   omousX=mousX
                   omousY=mousY 
                StatusBarText(0, 6, Str(startX) )  
                StatusBarText(0, 7, Str(startY))  
         StopDrawing()
         SetGadgetState(gadget1_n,bitmap1_h) 
             ; but here and after these lines it does not need imagegadget)..  why?
    For iii=0 To 10000:Next
    
   drawLine:
   
   If WindowMouseButton(hWnd, 0)=0
    Goto finishLine
  EndIf
   Gosub crosshair
     mousX =ox    ; WindowMouseX(0)
     mousY = oy    ;WindowMouseY(0)
   StartDrawing(ImageOutput(bitmap1_n))              
                 DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
                    Line(startX,startY,omousX-startX, omousY-startY,RGB(5,5,200))  
                    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))  
                    omousX=mousX
                   omousY=mousY  
                StatusBarText(0, 8, Str(mousX-startX))  
                StatusBarText(0, 9, Str(mousY-startY))  
         StopDrawing()
         SetGadgetState(gadget1_n,bitmap1_h)
     Goto drawline
    
     finishLine:
       mousX =ox   
      mousY = oy  
   StartDrawing(ImageOutput(bitmap1_n))              
                 DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
                    Line(startX,startY,omousX-startX, omousY-startY,RGB(5,5,200))  
                    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))
                StatusBarText(0, 8, Str(mousX-startX))  
                StatusBarText(0, 9, Str(mousY-startY))  
                StatusBarText(0, 0, "         ")     
         StopDrawing()
         SetGadgetState(gadget1_n,bitmap1_h)
     Return
     EndIf

:(
Last edited by kepu on Mon Aug 03, 2009 1:43 am, edited 1 time in total.
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Post by citystate »

at a glance, the first thing that stood out to me in your first code is that you are using Windows API calls (GetForegroundWindow_, GetAsyncKeyState_, etc) so it's not surprising that it only runs on the x86 version of PB. In general, you'll find that by limiting yourself to native PB functions, your code will be crossplatform
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

api-calls''''

Post by kepu »

Hi! :)
Those procedures works fine , sorry I didn't quote codes clearly, the first code is only for windows because its first procedure and the second is only for Linux because it's first procedure, I was talking only about code after of that first procedure. ( Sorry bad idea, I just tried to cut out samples for forum)
They are placed only to find which mousebutton is pressed,
And as you can notice , those procedures are different in both codes for Windows and for Linux version.
And I didn't find any ' WindowMouseButton()' like commands , not from help or in forums , if there is some let me know,but I don't like to use double buffering in this prog.
And I thing the help and examples are a little bit behind and they need some improvement to cover new PB inventions.


:?
Last edited by kepu on Mon Aug 03, 2009 3:08 am, edited 4 times in total.
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

Post by kepu »

Hi! Me again :D
If it helps ,You can replace that starting procedure in both codes with this one
then you can try them both in Windows or in Linux
because this procedure works in both in Linux and Windows

Code: Select all

Procedure WindowMouseButton(Wnd, ButtonNr)
 
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ;Linux Version
 
  Protected gdkWnd.l, x.l, y.l, mask.l
 
  If Wnd
    *Window.GTKWindow = Wnd
    gdkWnd = *Window\bin\child\window
    gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
   
    Select ButtonNr
      Case 0
        If (mask & #GDK_BUTTON1_MASK)
          ProcedureReturn 1
        EndIf
      Case 1
        If (mask & #GDK_BUTTON3_MASK)
          ProcedureReturn 1
        EndIf
      Case 2
        If (mask & #GDK_BUTTON2_MASK)
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf
 
  CompilerElse
  ;Windows Version
 
  If Wnd And GetForegroundWindow_() = Wnd
    Select ButtonNr
      Case 0
        If GetAsyncKeyState_(#VK_LBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 1
        If GetAsyncKeyState_(#VK_RBUTTON) > 0
          ProcedureReturn 1
        EndIf
      Case 2
        If GetAsyncKeyState_(#VK_MBUTTON) > 0
          ProcedureReturn 1
        EndIf
    EndSelect
  EndIf
 
  CompilerEndIf
 
  ProcedureReturn 0
EndProcedure

This procedure is slightly changed from DarkDragon message in this forum ;
viewtopic.php?t=29950

Yours Kepu
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

if I understood you correctly, the eventhandling of the refresh of the gadget creates problems.

when setting the contents of a gadget, the gadget needs refreshing, which can create one to three new events that need processing.
so, only after the eventloop of you programm passed (Wait)WindowEvent() up to three times successfully, the update is performed correctly.

for purposes like this where you want some steadily updating of content,
it's better to use WaitWindowEvent(timeout), and only update the content when the current event is #Null, means timeout has occurred.
this prevents filling up the eventqueue.

example for an image animation using this technique:
http://www.purebasic.fr/german/viewtopic.php?t=19394
oh... and have a nice day.
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

WaitWindowEvent()

Post by kepu »

As you can see, I have used WaitWindowEvent() and I have tried hundred different timeouts (0 to 450), because that was my first though, ( note that crosshair code is outside of eventloop it is only inside the repeat-until loop.)
The timeouts had no effect so far, in these samples I cut to forum,I omitted those.
You can try put some numbers there, but when you take imagegadget(.. out from the first sub (crosshair) and leave only that setgadgetstate(.. , it does not work.
and this is the only problem that I am talking about (note this happen only in Linux) , those other subs after that first don't need that (imagegadget(..)
And these my both samples are working fine, except I don't understand why in Linux setgadgetstate:.. command is not enough to update gadget (and only in the first sub, in other subs it is not needed )
What I have understand is that after once createimage() and imagegadget() have used then for same gadget only setgadgetstate() is needed.
You show sample of that image animation, in that sample everything happen inside the evenloop code meaning no jump out of that loop, ..
All samples in help section are made same way ...no actual jumps out from eventloop... I tried some like that , seems to work at least in small sizes, does that mean that I have to stretch eventloop over the full code?
In Windows, jumps out from eventloop seems to work fine , in Linux there seems to some problem , hard to believe, there has to be something else.
I am total newbie in PB
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

shorter?
hard to decipher your text.

I didn't took too much look into your code because you jump wildly back and forth, completely ineffectivce.
I recommend not to use GOSUB stuff at all.

call your crosshair only when the Event is #Null
a setgadgetstate will produce events. maybe on linux it produces five and on windows one.
so, when you not properly process events BEFORE creating new, you will mess it up and get a problem.
oh... and have a nice day.
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

Post by kepu »

So?

Sorry, can you be more specific , "not properly process events BEFORE creating new"?
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I already gave you an example.

in the code it sais

Code: Select all

;....
Repeat
  Event = WaitWindowEvent(10)
  Select Event
    ;**** Timer
    Case #Null
        SetGadgetState(0, ImageID(2)) 

    ;...

  EndSelect
Until EXIT 
as I said, only create new events when none is actual, when the timeout occurred.
oh... and have a nice day.
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

Post by kepu »

Yep, that I was quessing, your example is inside the eventloop, but Case #NULL seems not to have effect if I am outside of eventloop in sub, it means program should to return to eventloop for refresh, quite heavy jumping?
So, you are actually saying that all gadget handling should happen in eventloop trough case ,not in sub pointed from case
And when I am in sub, drawing for example line from starting point by keeping left button down , program has to return to eventloop / case #NULL for refresh (meaning it can't happen direct with setgadgetstate () in sub)
So, actually I should move all my code inside the eventloop, is that what you are saying?
That is not a case in other programming languages,
Sorry, I am bothering , my first language is not english, so my text might not be correct or polite, I am just asking help,I am feeling myself quite stupid.

And , once more those codes (actually they are only about 5% of full code) are working fine as they are , only problem is that I was confused, to use imagegadget() once again in the code,(and it is only in one point of code and only in Linux))
That didn't seem to be right,so I was asking help.
PS. Did you try that code for Linux, as it was and then without imagegadget() in crosshair sub.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

the point is, I do not even have linux so I could not test it.

and it was even only a guess what could be the reason for the problems here.

I only SAW that you are provoking problems producing Events when the Queue is not empty.
this is a problem I see quite often and the results are sometimes funny.


if does not matter if you GOSUB somewhere from within a CASE
it's almost the same as if the code would just continue.
GOSUB is no SUB in PureBasic, it's just an uncapsuled JSR.
if you want a real subroutine, write a Procedure.

PureBasic is a procedural programming language, so you need to keep an eye on some rules
when dealing with ObjectOriented things like the Windows EventQueue.
oh... and have a nice day.
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

Maybe ..this should be in Linux section

Post by kepu »

I don't know ,
maybe this topic should be in OS specific / Linux, because it seems to be more Linux problem?
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

Post by kepu »

I can use procedures instead of those 'subs' , thus , I don't really know how it will solve this problem, because it is totally something else.
I know how to do it either way, but if you don't have pants ,choosing between running or walking does not create pants, ...already creator of Pascal says that gosub /goto is not proper way to program...I agree.
Still looking for answer?
:?
kepu
User
User
Posts: 20
Joined: Mon Jul 13, 2009 8:00 am

Post by kepu »

Ok.
I changed crosshair to procedure, works exactly same way, it does not work without imagegadget(.. in the procedure
(in Linux)
:?
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

@kepu: I don't have linux to try out this modified code. Please try it out and let me know if there is any improvement. Only one of the changes is really needed, the others I did in the process of figuring out what may be wrong. I tried to change it as little as possible. :wink:

Here's a summary of the changes:
  • I made a minor change to process the results of initializing OpenWindow(), and others, in a procedure to handle errors and terminate the program if necessary (this prevents placing the majority of the program in an If/EndIf statement and keeps the indent level lower).

    Even though I know this is just a test snippett I added a flag to verify that the StatusBar was created successfully. This can be checked so that addition using commands with the StatusBar won't cause a problem (they'll be side-stepped) and allow the program to execute even if the StatusBar wasn't set up.

    I replaced the empty For/Next loops that were used as delays with an actual Delay(1).

    I have made slight changes to place the subroutines of the eventloop into procedures. This was done just for neatness (structuring it so I didn't overlook something), it would work the same without it I'm sure.

    I made a small change to the event loop so that it will continue to loop until all events have been handled, in case more than one is generated by changes in the loop itself or by executing the code for the crosshair after the event loop. This hopefully will cure your problem.

Code: Select all

;kepu's code sample modified by Demivec (8/3/2009)
; simplified to remove For-Next Delay loops, Goto's, Gosub's, and using a slightly changed eventloop

Declare crosshair()
Declare doLine()

Procedure handleError(p_result.l, p_text.s) ;display error message if result=0 and then END program.
  ;sample use HandleError(OpenWindow(#WINDOW_ROOT,0,0,120,120,#APP_NAME,#PB_Window_SystemMenu),"Main window could not be created.")
  ;Procedure borrowed from "Kale" in PureBasic forum
If p_result = 0
  MessageRequester("Error", p_text, #PB_MessageRequester_Ok)
  End
EndIf
EndProcedure

Procedure WindowMouseButton(Wnd, ButtonNr)
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    ;Linux Version
    
    Protected gdkWnd.l, x.l, y.l, mask.l
    
    If Wnd
      *Window.GTKWindow = Wnd
      gdkWnd = *Window\bin\child\Window
      gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
      
      Select ButtonNr
        Case 0
          If (mask & #GDK_BUTTON1_MASK)
            ProcedureReturn 1
          EndIf
        Case 1
          If (mask & #GDK_BUTTON3_MASK)
            ProcedureReturn 1
          EndIf
        Case 2
          If (mask & #GDK_BUTTON2_MASK)
            ProcedureReturn 1
          EndIf
      EndSelect
    EndIf
    
  CompilerElse
    ;Windows Version
    
    If Wnd And GetForegroundWindow_() = Wnd
      Select ButtonNr
        Case 0
          If GetAsyncKeyState_(#VK_LBUTTON) > 0
            ProcedureReturn 1
          EndIf
        Case 1
          If GetAsyncKeyState_(#VK_RBUTTON) > 0
            ProcedureReturn 1
          EndIf
        Case 2
          If GetAsyncKeyState_(#VK_MBUTTON) > 0
            ProcedureReturn 1
          EndIf
      EndSelect
    EndIf
    
  CompilerEndIf
  
  ProcedureReturn 0
EndProcedure

;********************************************************************
Define WindowWidth = 1000 
Define WindowHeight = 700
handleError(OpenWindow(0, 10, 10, WindowWidth, WindowHeight, "PureQCad.018 "),"Couldn't setup main Window")
  
Define hwnd = WindowID(0)
handleError(hwnd,"Couldn't obtain window handle")
  
If CreateMenu(0, WindowID(0))
  MenuTitle("File")
  MenuItem( 1, "&Load...")
  MenuItem( 2, "Save")
  MenuBar()
  MenuItem( 5, "Exit")
  
  MenuTitle("Edit")
  MenuTitle("Draw")
  MenuItem( 18, "Line")
  MenuTitle("Mode")
  MenuTitle("Help")
  MenuItem( 44, "Help")
  MenuItem( 45, "About")
  
EndIf 

If CreateStatusBar(0, WindowID(0))
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  AddStatusBarField(100)
  StatusBarText(0, 0, "prog_name")
  StatusBarText(0, 1, " xx= ")
  StatusBarText(0, 2, " yy= ") 
  StatusBarText(0, 3, " orx= ")
  StatusBarText(0, 4, " ory= ")
  StatusBarText(0, 5, " DrawC ")
  StatusBarText(0, 6, " x= " )
  StatusBarText(0, 7, " y= " )
  StatusBarText(0, 8, "     ")
  StatusBarText(0, 9, "     ")
  StatusBarText(0, 10, "     ")
  Define statusbarCreated = #True
EndIf

;********  init imagegadget ***********************************************
Define bitmap1_n = 1                                                             ; image number 1
Define bitmap1_h = CreateImage(bitmap1_n,800,550)      ; create the image and store the handle
Define gadget1_n = 1
ImageGadget(gadget1_n,0,0,800,500,bitmap1_h) 

; ******** init cross hair ***************************************************
StartDrawing(ImageOutput(bitmap1_n))
  FillArea(10,10,-1,$FFFFFF)
  DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
  Define ox=10
  Define oy=10
  Define oox=ox
  Define ooy=oy
  Define hwidth=WindowWidth-40
  Define hheight=WindowHeight-45
  Line(ox,10, 0, hheight , RGB(55,55,55))
  Line(10,oy, hwidth , 0, RGB(55,55,55))
StopDrawing()
SetGadgetState(gadget1_n,bitmap1_h)

Delay(1)
;********* menuloop ******************************************************************************
Repeat
  Repeat
    Define event= WaitWindowEvent(5)
    Select event
      Case #PB_Event_Menu
        Select EventMenu() 
          Case 18     ;Line
            doLine()
          Case 45 ; About
            MessageRequester("About", "image_gadget_test", 0)
          Case 5 ; exit
            Define Quit=#True     ;  End
          Default
            MessageRequester("Info", "MenuItem: "+Str(EventMenu()), 0)
        EndSelect
        
      Case #PB_Event_CloseWindow
        Quit=#True
    EndSelect
    
  Until event = 0 Or Quit = #True
  
  crosshair()    ;this does not work properly  in Linux if :SetGadgetState).... is used incrosshair sub
Until  Quit = #True
End

;'****** end of menuloop ****************************************
Procedure crosshair()
  Shared statusbarCreated, bitmap1_h, bitmap1_n, gadget1_n, hheight, hwidth, ox, oy, oox, ooy
  StartDrawing(ImageOutput(bitmap1_n))             
    DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
    ox=WindowMouseX(0)
    oy=WindowMouseY(0)         
    Line ( oox,  10, 0,  hheight, RGB(55,55,55))
    Line (10, ooy, hwidth, 0, RGB(55,55,55))
    Line ( ox, 10, 0, hheight, RGB(55,55,55))
    Line ( 10, oy, hwidth,0 , RGB(55,55,55))
  StopDrawing()   
  SetGadgetState(gadget1_n,bitmap1_h)   
  oox=ox
  ooy=oy
  If statusbarCreated
    StatusBarText(0, 1, " xx= "+Str(ox))
    StatusBarText(0, 2, " yy= "+Str(oy)) 
    StatusBarText(0, 3, " orx= "+Str(oox))
    StatusBarText(0, 4, " ory= "+Str(ooy))
  EndIf 
EndProcedure

Procedure doLine()
  Shared statusbarCreated, bitmap1_h, bitmap1_n, gadget1_n, hwnd, ox, oy
  ;setLine
  Repeat
    crosshair()
    If statusbarCreated
      StatusBarText(0, 0, "Line") 
    EndIf 
    WindowMouseButton(hwnd, 0) 
    Delay(1)
  Until WindowMouseButton(hwnd, 0)=1

  ;startLine
  Protected startX = ox 
  Protected startY = oy   
  crosshair()
  StartDrawing(ImageOutput(bitmap1_n))             
    DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
    Protected mousX = WindowMouseX(0)
    Protected mousY = WindowMouseY(0)
    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200)) 
    Protected omousX=mousX
    Protected omousY=mousY
    If statusbarCreated
      StatusBarText(0, 6, Str(startX) ) 
      StatusBarText(0, 7, Str(startY)) 
    EndIf 
  StopDrawing()
  SetGadgetState(gadget1_n,bitmap1_h)
  Delay(1)

  ;drawLine
  While WindowMouseButton(hwnd, 0) <> 0
    crosshair()
    mousX =ox    ; WindowMouseX(0)
    mousY = oy    ;WindowMouseY(0)
    StartDrawing(ImageOutput(bitmap1_n))             
      DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
      Line(startX,startY,omousX-startX, omousY-startY,RGB(5,5,200)) 
      Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200)) 
      omousX=mousX
      omousY=mousY 
      If statusbarCreated
        StatusBarText(0, 8, Str(mousX-startX)) 
        StatusBarText(0, 9, Str(mousY-startY)) 
      EndIf 
    StopDrawing()
    SetGadgetState(gadget1_n,bitmap1_h)
  Wend
  
  ;finishLine
  mousX =ox    ; WindowMouseX(0)
  mousY = oy    ;WindowMouseY(0)
  StartDrawing(ImageOutput(bitmap1_n))             
    DrawingMode(#PB_2DDrawing_Outlined | #PB_2DDrawing_XOr)
    Line(startX,startY,omousX-startX, omousY-startY,RGB(5,5,200)) 
    Line(startX,startY,mousX-startX,mousY-startY,RGB(5,5,200))
    If statusbarCreated
      StatusBarText(0, 8, Str(mousX-startX)) 
      StatusBarText(0, 9, Str(mousY-startY)) 
      StatusBarText(0, 0, "         ")     
    EndIf 
  StopDrawing()
  SetGadgetState(gadget1_n,bitmap1_h)

EndProcedure
Post Reply