Make the OpenGl Gadget the EventGadget() programmatically?

Windows specific forum
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Make the OpenGl Gadget the EventGadget() programmatically?

Post by IdeasVacuum »

If I'm viewing/updating info in a Tool Window, I'd like to just use the key shortcuts in the OGL Gadget (Main Window) without first having to click in it with the mouse. I have tried a fake mouse click:

Code: Select all

Macro Macro_MouseClick
;#--------------------
mouse_event_(#MOUSEEVENTF_LEFTDOWN,0,0,0,0)
mouse_event_(#MOUSEEVENTF_LEFTUP,0,0,0,0)
EndMacro
It, and my other poorly considered ideas, do not work because I have a chicken-and-egg situation:

Code: Select all

Select EventGadget()

         Case #OpenGlGadget

                         Select EventType()

                                   Case #PB_EventType_KeyDown

                                                   igKey = GetGadgetAttribute(#OpenGlGadget, #PB_OpenGL_Key)
                                            Select igKey

                                                            Case       #PB_Shortcut_Up: CameraIncrementRotationX(-2, 100)
                                                            Case     #PB_Shortcut_Down: CameraIncrementRotationX(2, 100)
                                                            Case     #PB_Shortcut_Left: CameraIncrementRotationY(2, 100)
                                                            Case    #PB_Shortcut_Right: CameraIncrementRotationY(-2, 100)
                                                            Case #PB_Shortcut_Subtract: CameraZooming(0)
                                                            Case      #PB_Shortcut_Add: CameraZooming(1)
                                            EndSelect
                         EndSelect
EndSelect
[/size]

........... but it must be possible?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4664
Joined: Sun Apr 12, 2009 6:27 am

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by RASHAD »

Hi IV
Try

Code: Select all

.
.
OpenWindow(0, 0, 0, 530, 320, "OpenGL Gadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

OpenGLGadget(0, 10, 10, 200, 200,#PB_OpenGL_Keyboard )
SetupGL()

OpenGLGadget(1, 220, 10, 300, 300 ,#PB_OpenGL_Keyboard)
SetupGL()

AddWindowTimer(0, 1, 16) ; about 60 fps

AddKeyboardShortcut(0,#PB_Shortcut_Up,10)
AddKeyboardShortcut(0,#PB_Shortcut_Down,20)
AddKeyboardShortcut(0,#PB_Shortcut_Left,30)
AddKeyboardShortcut(0,#PB_Shortcut_Right,40)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case 10
          If flag1 = 1
            Debug "1 up"
          ElseIf flag2 = 1
            Debug "2 up"
          EndIf
          
        Case 20
          If flag1 = 1
            Debug "1 down"
          ElseIf flag2 = 1
            Debug "2 down"
          EndIf
          
      EndSelect        
    
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_MouseEnter
              SetFocus_(GadgetID(0))
              flag1 = 1
              
            Case #PB_EventType_MouseLeave
              SetFocus_(0)
              flag1 = 0
          EndSelect
          
        Case 1
          Select EventType()
            Case #PB_EventType_MouseEnter
              SetFocus_(GadgetID(1))
              flag2 = 1
              
            Case #PB_EventType_MouseLeave
              SetFocus_(0)
              flag2 = 0
          EndSelect
      EndSelect
          
    Case #PB_Event_Timer
      If EventTimer() = 1
        DrawCube(0)
        DrawCube(1)
      EndIf
  EndSelect
  
Until Quit = 1
Egypt my love
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by IdeasVacuum »

... same result

If there is a Tool Window and that has the focus (is being used by the User) - key press only works after mouse click of either the Main Window or OpenGL Gadget first.

I was hoping that pre-sending an OpenGl message such as glClearColor, glClear would open the door but nooooooo
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by IdeasVacuum »

SetActiveWindow(#WinMain) : SetActiveGadget(#OpenGlGadget) does not work.

I was so surprised SetActiveWindow() doesn't work because if you just click on the Window title bar, everything does then work. In Windows 7 the title bar changes colour slightly to indicate it has the focus - shouldn't SetActiveWindow() trigger the same?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4664
Joined: Sun Apr 12, 2009 6:27 am

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by RASHAD »

Hi IV
Try

Code: Select all

SendMessage_(WindowID(#WinMain), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)

Code: Select all

OpenWindow(0,0,0,400,300,"Main",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindow(1,0,0,300,200,"child",#PB_Window_SystemMenu | #PB_Window_ScreenCentered,WindowID(0))
ButtonGadget(10,10,10,60,20,"RUN")
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 10
          SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
      EndSelect
  EndSelect
Until Quit = 1
Egypt my love
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by IdeasVacuum »

Hi Rashad, thanks for trying. No joy :cry:

Code: Select all

Case #PB_Event_Menu                                                                                                                                     
                                                                                                                                                        
               SendMessage_(WindowID(#WinMain), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)                                                                       
                                                                                                                                                        
               Select EventMenu()                                                                                                                       
                                                                                                                                                        
                              Case       #KeyUp: SendMessage_(WindowID(#WinMain), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) : CameraIncrementRotationX(-2, 100) 
                              Case     #KeyDown: SendMessage_(WindowID(#WinMain), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) : CameraIncrementRotationX(2, 100)  
                              Case     #KeyLeft: CameraIncrementRotationY(2, 100)                                                                       
                              Case    #KeyRight: CameraIncrementRotationY(-2, 100)                                                                      
                              Case #KeySubtract: CameraZooming(0)                                                                                       
                              Case      #KeyAdd: CameraZooming(1)                                                                                       
               EndSelect                                                                                                                                
[/size]
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
mestnyi
Addict
Addict
Posts: 1001
Joined: Mon Nov 25, 2013 6:41 am

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by mestnyi »

IdeasVacuum wrote:If I'm viewing/updating info in a Tool Window, I'd like to just use the key shortcuts in the OGL Gadget (Main Window) without first having to click in it with the mouse. I have tried a fake mouse click:
I think that not a click is important here, but the cursor over the gadget.

Code: Select all

Global RollAxisX.f
Global RollAxisY.f
Global RollAxisZ.f

Global RotateSpeedX.f = 1.0
Global RotateSpeedY.f
Global RotateSpeedZ.f = 1.0

Global ZoomFactor.f = 1.0 ; Distance of the camera. Negative value = zoom back

Procedure DrawCube(Gadget)
  SetGadgetAttribute(Gadget, #PB_OpenGL_SetContext, #True)
  
  glPushMatrix_()                  ; Save the original Matrix coordinates
  glMatrixMode_(#GL_MODELVIEW)

  glTranslatef_(0, 0, ZoomFactor)  ;  move it forward a bit

  glRotatef_ (RollAxisX, 1.0, 0, 0) ; rotate around X axis
  glRotatef_ (RollAxisY, 0, 1.0, 0) ; rotate around Y axis
  glRotatef_ (RollAxisZ, 0, 0, 1.0) ; rotate around Z axis
 
  RollAxisX + RotateSpeedX 
  RollAxisY + RotateSpeedY 
  RollAxisZ + RotateSpeedZ 

  ; clear framebuffer And depth-buffer

  glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

  ; draw the faces of a cube
  
  ; draw colored faces

  glDisable_(#GL_LIGHTING)
  glBegin_  (#GL_QUADS)
  
  ; Build a face, composed of 4 vertex ! 
  ; glBegin() specify how the vertexes are considered. Here a group of
  ; 4 vertexes (GL_QUADS) form a rectangular surface.

  ; Now, the color stuff: It's r,v,b but with float values which
  ; can go from 0.0 To 1.0 (0 is .. zero And 1.0 is full intensity) 
  
  glNormal3f_ (0,0,1.0)
  glColor3f_  (0,0,1.0)
  glVertex3f_ (0.5,0.5,0.5)   
  glColor3f_  (0,1.0,1.0)         
  glVertex3f_ (-0.5,0.5,0.5)
  glColor3f_  (1.0,1.0,1.0)
  glVertex3f_ (-0.5,-0.5,0.5)
  glColor3f_  (0,0,0)
  glVertex3f_ (0.5,-0.5,0.5) 

  ; The other face is the same than the previous one 
  ; except the colour which is nice blue To white gradiant

  glNormal3f_ (0,0,-1.0)
  glColor3f_  (0,0,1.0)
  glVertex3f_ (-0.5,-0.5,-0.5)
  glColor3f_  (0,0,1.0)
  glVertex3f_ (-0.5,0.5,-0.5)
  glColor3f_  (1.0,1.0,1.0)
  glVertex3f_ (0.5,0.5,-0.5)
  glColor3f_  (1.0,1.0,1.0)
  glVertex3f_ (0.5,-0.5,-0.5)
  
  glEnd_()
  
  ; draw shaded faces

  glEnable_(#GL_LIGHTING)
  glEnable_(#GL_LIGHT0)
  glBegin_ (#GL_QUADS)

  glNormal3f_ (   0, 1.0,   0)
  glVertex3f_ ( 0.5, 0.5, 0.5)
  glVertex3f_ ( 0.5, 0.5,-0.5)
  glVertex3f_ (-0.5, 0.5,-0.5)
  glVertex3f_ (-0.5, 0.5, 0.5)

  glNormal3f_ (0,-1.0,0)
  glVertex3f_ (-0.5,-0.5,-0.5)
  glVertex3f_ (0.5,-0.5,-0.5)
  glVertex3f_ (0.5,-0.5,0.5)
  glVertex3f_ (-0.5,-0.5,0.5)

  glNormal3f_ (1.0,0,0)
  glVertex3f_ (0.5,0.5,0.5)
  glVertex3f_ (0.5,-0.5,0.5)
  glVertex3f_ (0.5,-0.5,-0.5)
  glVertex3f_ (0.5,0.5,-0.5)

  glNormal3f_ (-1.0,   0,   0)
  glVertex3f_ (-0.5,-0.5,-0.5)
  glVertex3f_ (-0.5,-0.5, 0.5)
  glVertex3f_ (-0.5, 0.5, 0.5)
  glVertex3f_ (-0.5, 0.5,-0.5)

  glEnd_()

  glPopMatrix_()
  glFinish_()

  SetGadgetAttribute(Gadget, #PB_OpenGL_FlipBuffers, #True)
EndProcedure

Procedure SetupGL()
    
  glMatrixMode_(#GL_PROJECTION)
  gluPerspective_(30.0, 200/200, 1.0, 10.0) 
  
  ; position viewer
  glMatrixMode_(#GL_MODELVIEW)
  
  glTranslatef_(0, 0, -5.0)
  
  glEnable_(#GL_DEPTH_TEST)   ; Enabled, it slowdown a lot the rendering. It's to be sure than the
                              ; rendered objects are inside the z-buffer.
  
  glEnable_(#GL_CULL_FACE)    ; This will enhance the rendering speed as all the back face will be
                              ; ignored. This works only with CLOSED objects like a cube... Singles
                              ; planes surfaces will be visibles only on one side.
    
  glShadeModel_(#GL_SMOOTH)
EndProcedure

OpenWindow(0, 0, 0, 530, 320, "OpenGL Gadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

OpenGLGadget(0, 10, 10, 200, 200,#PB_OpenGL_Keyboard )
SetupGL()

OpenGLGadget(1, 220, 10, 300, 300 ,#PB_OpenGL_Keyboard)
SetupGL()

AddWindowTimer(0, 1, 16) ; about 60 fps

AddKeyboardShortcut(0,#PB_Shortcut_Up,10)
AddKeyboardShortcut(0,#PB_Shortcut_Down,20)
AddKeyboardShortcut(0,#PB_Shortcut_Left,30)
AddKeyboardShortcut(0,#PB_Shortcut_Right,40)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
     
    Case #PB_Event_Menu
      Select EventMenu()
        Case 10
          If flag1 = 1
            Debug "1 up"
          ElseIf flag2 = 1
            Debug "2 up"
          EndIf
         
        Case 20
          If flag1 = 1
            Debug "1 down"
          ElseIf flag2 = 1
            Debug "2 down"
          EndIf
         
      EndSelect       
   
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_MouseEnter
              SetActiveGadget(0)
              flag1 = 1
             
            Case #PB_EventType_MouseLeave
              SetActiveGadget(1)
              flag1 = 0
          EndSelect
         
        Case 1
          Select EventType()
            Case #PB_EventType_MouseEnter
              SetActiveGadget(1)
              flag2 = 1
             
            Case #PB_EventType_MouseLeave
              SetActiveGadget(0)
              flag2 = 0
          EndSelect
      EndSelect
         
    Case #PB_Event_Timer
      If EventTimer() = 1
        DrawCube(0)
        DrawCube(1)
      EndIf
  EndSelect
 
Until Quit = 1
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by IdeasVacuum »

Thanks for your input mestnyi, but it will always work when the app has only one Window. The OpenGL gadgets are also being kept "alive" by the looped displays. So not the same as the scenario I am battling with.

When I started this post, I thought the answer must be simple and someone would have a one-line solution. I have since found another post, similar scenario but with a Canvas.

Bottom line is, if you use SetActiveWindow(), that should happen. On Windows that is the same as SetFocus, with the same not-quite-there result :shock:

A third example where SetActiveWindow() dosn't work:
viewtopic.php?f=13&t=50296&start=0

Given that SetActiveWindow() is based on the API, it isn't going to get any better. So that takes me back into fake mouse click territory :mrgreen:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by IdeasVacuum »

So this demonstrates the issue that turns out to be more difficult than I thought it would be.

The Actual App Window is full screen.

Code: Select all

Enumeration
#MainWin
#OGL
#KeyUp
#KeyDown
#KeyLeft
#KeyRight
#KeySubtract
#KeyAdd
#ToolWin
#Button1
#Button2
EndEnumeration


Procedure ToolWin()
;#-----------------
Protected iX.i = WindowX(#MainWin) + 20
Protected iY.i = WindowY(#MainWin) + 40

               If OpenWindow(#ToolWin, iX, iY, 250, 100, "ToolWin", #PB_Window_SystemMenu | #PB_Window_Tool)

                       ButtonGadget(#Button1, 140, 10, 100, 25, "Button1", #PB_Button_Toggle)
                       ButtonGadget(#Button2, 140, 40, 100, 25, "Button2", #PB_Button_Toggle)
                       StickyWindow(#ToolWin, #True)
               EndIf
EndProcedure

Procedure MainWin()
;#-----------------

               If OpenWindow(#MainWin, 0, 0, 600, 400, "MainWin", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

                       OpenGLGadget(#OGL, 4, 4, 592, 392, #PB_OpenGL_Keyboard)

                         AddKeyboardShortcut(#MainWin, #PB_Shortcut_Up, #KeyUp)
                         AddKeyboardShortcut(#MainWin, #PB_Shortcut_Down, #KeyDown)
                         AddKeyboardShortcut(#MainWin, #PB_Shortcut_Left, #KeyLeft)
                         AddKeyboardShortcut(#MainWin, #PB_Shortcut_Right, #KeyRight)
                         AddKeyboardShortcut(#MainWin, #PB_Shortcut_Subtract, #KeySubtract)
                         AddKeyboardShortcut(#MainWin, #PB_Shortcut_Add, #KeyAdd)
               EndIf
EndProcedure

Procedure Activate()
;#------------------

         SetActiveWindow(#MainWin)
         SetActiveGadget(#OGL)
EndProcedure

Procedure WaitLoop()
;#------------------
Protected iQuit.i = #False


          Repeat
                  Select WaitWindowEvent(1)

                         Case #PB_Event_CloseWindow

                              Select EventWindow()

                                   Case #MainWin: iQuit = #True
                                   Case #ToolWin: ;do nothing

                              EndSelect

                         Case #PB_Event_Menu

                              Select EventMenu()

                                     Case       #KeyUp: Activate() : Debug "KeyUp"
                                     Case     #KeyDown: Activate() : Debug "KeyDown"
                                     Case     #KeyLeft: Activate() : Debug "KeyLeft"
                                     Case    #KeyRight: Activate() : Debug "KeyRight"
                                     Case #KeySubtract: Activate() : Debug "KeySubtract"
                                     Case      #KeyAdd: Activate() : Debug "KeyAdd"
                              EndSelect

                      Case #PB_Event_Gadget

                              Select EventWindow()

                                   Case #ToolWin

                                         Select EventGadget()

                                                Case #Button1: Debug "Button1"
                                                Case #Button2: Debug "Button2"
                                         EndSelect
                              EndSelect
                  EndSelect

          Until iQuit = #True

EndProcedure

MainWin()
ToolWin()
WaitLoop()
End
[/size]
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by Shardik »

IdeasVacuum wrote:So this demonstrates the issue that turns out to be more difficult than I thought it would be.
I have taken your example and modified it. It's now working on my Windows 10 x64 with PB 5.71 x86 and x64 and PB 5.46 x86 in ASCII and Unicode mode:

Code: Select all

Enumeration
  #MainWin
  #OGL
  #ToolWin
  #Button1
  #Button2
EndEnumeration


Procedure ToolWin()
  Protected iX.i = WindowX(#MainWin) + 20
  Protected iY.i = WindowY(#MainWin) + 40
  
  If OpenWindow(#ToolWin, iX, iY, 250, 100, "ToolWin", #PB_Window_SystemMenu | #PB_Window_Tool)
    ButtonGadget(#Button1, 140, 10, 100, 25, "Button1")
    ButtonGadget(#Button2, 140, 40, 100, 25, "Button2")
    StickyWindow(#ToolWin, #True)
  EndIf
EndProcedure

Procedure MainWin()
  If OpenWindow(#MainWin, 0, 0, 600, 400, "MainWin", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    OpenGLGadget(#OGL, 4, 4, 592, 392, #PB_OpenGL_Keyboard)
  EndIf
EndProcedure

Procedure WaitLoop()
  ;#------------------
  Protected iQuit.i = #False

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Select EventWindow()
          Case #MainWin: iQuit = #True
          Case #ToolWin: ;do nothing
        EndSelect
      Case #PB_Event_Gadget
        Select EventWindow()
          Case #ToolWin
            Select EventGadget()
              Case #Button1: Debug "Button1"
              Case #Button2: Debug "Button2"
            EndSelect
        EndSelect
      Case #WM_KEYUP
        Select EventWindow()
          Case #ToolWin
            Select EventwParam()
               Case #VK_UP, #VK_DOWN, #VK_LEFT, #VK_RIGHT, #VK_SUBTRACT, #VK_ADD
                 PostEvent(#PB_Event_FirstCustomValue, #MainWin, #OGL, 0, EventwParam())
            EndSelect
          Case #MainWin
            Select EventwParam()
              Case       #VK_UP: Debug "KeyUp"
              Case     #VK_DOWN: Debug "KeyDown"
              Case     #VK_LEFT: Debug "KeyLeft"
              Case    #VK_RIGHT: Debug "KeyRight"
              Case #VK_SUBTRACT: Debug "KeySubtract"
              Case      #VK_ADD: Debug "KeyAdd"
           EndSelect
        EndSelect
      Case #PB_Event_FirstCustomValue
        Select EventData()
          Case       #VK_UP: Debug "KeyUp"
          Case     #VK_DOWN: Debug "KeyDown"
          Case     #VK_LEFT: Debug "KeyLeft"
          Case    #VK_RIGHT: Debug "KeyRight"
          Case #VK_SUBTRACT: Debug "KeySubtract"
          Case      #VK_ADD: Debug "KeyAdd"
        EndSelect
    EndSelect
  Until iQuit = #True
EndProcedure

MainWin()
ToolWin()
WaitLoop()
End
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Make the OpenGl Gadget the EventGadget() programmaticall

Post by IdeasVacuum »

Hello Shardik

That does indeed work exactly as required. I was thinking Rashad might suggest something similar too. I'm sure Fred wrote somewhere, donkeys years ago, that #WM and #VK might not be supported in the future - but it's all still there for Win10 :)

Defining a custom event to catch the User's actual intent is a very good idea - it never crossed my mind (not far to cross, it's only little).

Many thanks for your help. I'm struggling a lot this year.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply