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