Page 1 of 2

2 CanvasGadgets with 2 BindGadgets

Posted: Thu Nov 05, 2015 2:11 pm
by HanPBF
Hello!

Using this code:

Code: Select all

EnableExplicit

Procedure onCallback_Canvas1()
	debug "onCallback_Canvas1"
EndProcedure

Procedure onCallback_Canvas2()
	debug "onCallback_Canvas2"
EndProcedure

if OpenWindow(0, 0, 0, 512, 512, "Test")
	CanvasGadget(1, 8, 8, 128, 64, #PB_Canvas_Border)	
	BindGadgetEvent(1, @onCallback_Canvas1())
	
	CanvasGadget(2, 32, 16, 64, 24, #PB_Canvas_Border)	
	BindGadgetEvent(2, @onCallback_Canvas2())
endif	

repeat 
	define E = WaitWindowEvent()
until E=#PB_Event_CloseWindow
How can I make event 2 being triggered?
Only debug output is "onCallback_Canvas1".
Overlapping of canvasGadget is by intention...



Thanks a lot!

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Thu Nov 05, 2015 2:41 pm
by HanPBF
O.k. got another error in my original code.

The silly SetWindowLongPtr_-method to mimick z-index works as needed....

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Sat Nov 07, 2015 7:29 am
by mestnyi

Code: Select all

EnableExplicit

Procedure GadgetsClip( WindowID = #False ) ;
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Protected Dim EnumerateList.I(0)
    If WindowID = #False : WindowID = UseGadgetList(0) : EndIf
    Protected GadgetID = FindWindowEx_( WindowID, 0,0,0 )
    
    While GadgetID
      If GadgetID
        If GetWindowLongPtr_( GadgetID, #GWL_STYLE ) & #WS_CLIPSIBLINGS = #False 
          Protected Gadget = GetProp_( GadgetID, "PB_ID" ) ; IDGadget( GadgetID )
          If ( IsGadget( Gadget ) And 
               GadgetID( Gadget ) = GadgetID )
            Protected Height = GadgetHeight( Gadget ) 
            SetWindowLongPtr_( GadgetID, #GWL_STYLE, GetWindowLongPtr_( GadgetID, #GWL_STYLE )|#WS_CLIPSIBLINGS )
            ResizeGadget( Gadget, #PB_Ignore, #PB_Ignore, #PB_Ignore, Height )
          EndIf
        EndIf
        ReDim EnumerateList( ArraySize( EnumerateList() ) + (1) ) : EnumerateList( ArraySize( EnumerateList() ) ) = GadgetID
      EndIf
      GadgetID = GetWindow_( GadgetID, #GW_HWNDNEXT )  
    Wend
    
    While ArraySize( EnumerateList() ) 
      If ArraySize( EnumerateList() )
        GadgetID = EnumerateList( ArraySize( EnumerateList() ) ) : ReDim EnumerateList( ArraySize( EnumerateList() ) - (1) )
        SetWindowPos_( GadgetID, #GW_HWNDLAST, 0,0,0,0, #SWP_NOMOVE|#SWP_NOSIZE )
      EndIf 
    Wend
    
    FreeArray( EnumerateList() )
  CompilerEndIf
EndProcedure

Procedure onCallback_Canvas()
  Debug "onCallback_Canvas " + EventGadget()
EndProcedure

If OpenWindow(0, 0, 0, 200, 100, "Test")
  CanvasGadget(1, 8, 8, 128, 64, #PB_Canvas_Border)   
  BindGadgetEvent(1, @onCallback_Canvas())
  
  CanvasGadget(2, 32, 16, 64, 24, #PB_Canvas_Border)  
  If StartDrawing(CanvasOutput(2))
    Box(0,0,OutputWidth(),OutputHeight(),0)
    StopDrawing()
  EndIf
  BindGadgetEvent(2, @onCallback_Canvas())
  
  
  GadgetsClip( )
EndIf   

If OpenWindow(10, 350, 0, 200, 100, "Test")
  CanvasGadget(11, 8, 8, 128, 64, #PB_Canvas_Border)   
  BindGadgetEvent(11, @onCallback_Canvas())
  
  CanvasGadget(12, 32, 16, 64, 24, #PB_Canvas_Border)  
  If StartDrawing(CanvasOutput(12))
    Box(0,0,OutputWidth(),OutputHeight(),0)
    StopDrawing()
  EndIf
  BindGadgetEvent(12, @onCallback_Canvas())
  
  
  GadgetsClip( )
EndIf   

Repeat 
  Define E = WaitWindowEvent()
Until E=#PB_Event_CloseWindow

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Wed Nov 11, 2015 5:41 pm
by netmaestro
PureBasic doesn't support overlapped gadgets, unfortunately. If you want to get a layout like that working, you have to separate the events received by the contained canvas from those for the canvas it's sitting on. How to do that?

The key is to ask the OS to treat the containing canvas as though the smaller canvas were not there. Or, more precisely, that the clipping region occupied by the smaller canvas were not there. A "clipping region" defines an area of screen real estate that a given window (in this case canvas gadget) must maintain for:

a) drawing upkeep
b) mouse/keyboard events processing

When a window is first created, it is assigned a clipping region that covers its full rectangle, including both client and frame areas of the window. In order to separate events from an overlapping window, the original region must be modified to remove from it the real estate occupied by the usurping smaller window.

Mestnyi shows one way, a good one, that uses window style modifications to specify clipping details. There is a second way: Create a region the size of canvas 1, punch a hole in it the size and position of canvas 2, then apply the region to the larger canvas. Now canvas 1 has been told that the area occupied by canvas 2 does not fall within its drawing region and so it is excluded from all event processing and drawing. The smaller area is now free to host a second gadget, a gadget whose events will flow freely and, more importantly, readably.

My guess is that Mestnyi's approach and the one I've just described are identical in the end because when Windows reads the style changes being applied to the canvas, it makes the same region modifications "under the hood".

Code: Select all

EnableExplicit

Define.i one, two

Procedure onCallback_Canvas1()
  Debug "onCallback_Canvas1"
EndProcedure

Procedure onCallback_Canvas2()
  Debug "onCallback_Canvas2"
EndProcedure

one = CreateRectRgn_(0,0,128,64)
two = CreateRectRgn_(24,8,88,32)
CombineRgn_(one, one, two, #RGN_XOR)

If OpenWindow(0, 0, 0, 512, 512, "Test")
  CanvasGadget(1, 8, 8, 128, 64, #PB_Canvas_Border)   
  SetWindowRgn_(GadgetID(1), one, #True)
  BindGadgetEvent(1, @onCallback_Canvas1())
  
  CanvasGadget(2, 32, 16, 64, 24, #PB_Canvas_Border)   
  BindGadgetEvent(2, @onCallback_Canvas2())
EndIf   

Repeat 
  Define E = WaitWindowEvent()
Until E=#PB_Event_CloseWindow

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Wed Nov 11, 2015 6:18 pm
by HanPBF
Well, at the moment I can see no disavantage in using combinergn_.

So, event is extinguished due to xor with top-more gadget, right?

This should work for many gadgets.
A general solution would be to set z-index for the gadgets storing them in their partner structure (setGadgetData) and lookup the overlapping regions and clip them away.

The way with setWindowLongPtr_/SetWindowPos_ does not mean one gadget is put in front of the other?
At the moment the setWindowLongPtr approach seems easier to handle.
The combinergn_ approach seems technical better/cleaner.

I had this problem first when I rebuilt a data grid (as MS Access like endless form) a few months ago.

I can remember that I needed to reset the setwindowlongptr_ after some events like mousewheel or click.
Will check this next week with combinergn_.


Anyway, great idea!
Thanks a lot!
Both of You!

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Wed Nov 11, 2015 6:20 pm
by RASHAD
Hi NM
That is a new tech. added to my archive
Thanks
Any news about luis you can share ?

Another shot
# 1:

Code: Select all

EnableExplicit

Procedure onCallback_Canvas1()
   Debug "onCallback_Canvas1"
EndProcedure

Procedure onCallback_Canvas2()
   Debug "onCallback_Canvas2"
EndProcedure

If OpenWindow(0, 0, 0, 512, 512, "Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
   CanvasGadget(1, 8, 8, 128, 64, #PB_Canvas_Border)   
   CanvasGadget(2, 32, 16, 64, 24, #PB_Canvas_Border)
   SetWindowLongPtr_( GadgetID(2), #GWL_HWNDPARENT,GadgetID(1))
   BindGadgetEvent(1, @onCallback_Canvas1())   
   BindGadgetEvent(2, @onCallback_Canvas2())
EndIf   

Repeat 
   Define E = WaitWindowEvent()
Until E=#PB_Event_CloseWindow
#2 :

Code: Select all

EnableExplicit

Procedure onCallback_Canvas1()
   Debug "onCallback_Canvas1"
EndProcedure

Procedure onCallback_Canvas2()
   Debug "onCallback_Canvas2"
EndProcedure

If OpenWindow(0, 0, 0, 512, 512, "Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
   CanvasGadget(1, 8, 8, 128, 64, #PB_Canvas_Border)   
   CanvasGadget(2, 32, 16, 64, 24, #PB_Canvas_Border)
   SetParent_(GadgetID(2),GadgetID(1))
   BindGadgetEvent(1, @onCallback_Canvas1())   
   BindGadgetEvent(2, @onCallback_Canvas2())
EndIf   

Repeat 
   Define E = WaitWindowEvent()
Until E=#PB_Event_CloseWindow

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Wed Nov 11, 2015 6:24 pm
by netmaestro
Is there a reason to fear something has happend to luis? I haven't heard anything.

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Wed Nov 11, 2015 6:30 pm
by RASHAD
No
Just I miss him for long

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Thu Nov 12, 2015 12:59 pm
by HanPBF
Hi Rashad!

"That is a new tech. added to my archive"

Where is that archive?
Partly private/public?
Online?


Thanks!

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Fri Nov 13, 2015 7:25 pm
by RASHAD
Hi HanPBF
Sorry it is a private archive

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Sat Feb 06, 2016 5:40 pm
by HanPBF
Hello RASHAD,

after migration of some servers last year I am currently again dev'ing with PB.

So, Your little trick helped a lot!!!

The problem without z-index is always You have to draw the things site by site which works also.
But You need 4 additional border gadgets / 'background' gadgets for one gadget.

Had to do so with containergadget; no drawing directly in containergadget and no color of border can be set; annoying.
So, did put one containergadget into another which works seamless.

Thanks2all!

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Sat Feb 06, 2016 8:03 pm
by davido
Hi RASHAD,
Regarding luis; perhaps his last post (no pun intended) might give a clue:
http://www.purebasic.fr/english/viewtop ... 78#p465678

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Tue Feb 09, 2016 4:36 pm
by RASHAD
Hi davido
Thanks for the info
Loosing good programmers like Sparkie,Fluid Byte,srod,luis,Trond and ......
NM and Danilo abandoned to Mac environment
It is a big loss to Windows forum

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Tue Feb 09, 2016 8:16 pm
by davido
Hi RASHAD,
I, too will miss luis, like you he has helped me on many occasions.

Regarding srod, he has been posting recently. He provided me with some very useful information.

Re: 2 CanvasGadgets with 2 BindGadgets

Posted: Wed Feb 10, 2016 7:59 pm
by mestnyi
PureBasic doesn't support overlapped gadgets

Is not it?
http://www.purebasic.fr/english/viewtop ... 15#p475798