SetProxy()

BlitzMax Forums/BlitzMax GUI Programming/SetProxy()

I have some problems to understand how SetProxy() exactly works.
With SetProxy you can setup what is the 'main gadget' in your own-gadget.
But...

I have an user-gadget (like in the following example) that is composed by 2 (or more) sub-gadgets; I have problems to extends the standard gadget commands to work with my user-gadget.
In this case DISABLEGADGET what it really does? It disable the panel gadget? And the others?

I think I'm a little lost....

Import maxgui.drivers
Import maxgui.proxygadgets

Global wndMain:TGadget = CreateWindow( AppTitle, 100, 100, 300, 200, Null, WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_STATUS )

Global temp:tgadget = CreateMultiGadget("Hello" , 10 , 10 , 100 , 100 , wndMain) 
DisableGadget temp 'it disables the gadgets(panel) but all the rest is not greyed-out

Repeat
	WaitEvent()
	SetStatusText wndMain, CurrentEvent.ToString()
	Select EventID()
		Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End
	EndSelect
Forever

Function CreateMultiGadget:TGadget( url$,x:Int,y:Int,w:Int,h:Int,group:TGadget,style=0,customtext$ = "" )
		Return New Tmulti.Create(url,x,y,w,h,group,style,customtext)
EndFunction

Type tmulti Extends  TProxyGadget

	Global multi_list:TList
	
	Field panel:tgadget
	Field button:tgadget

	Method New()
		If multi_list=Null Initialize()
	End Method
	
	Method Create:tmulti(tit$ , x:Int , y:Int , w:Int , h:Int , group:tgadget , style:Int = 0 , ct$ = "")
		panel:tgadget = CreatePanel(x , y , w , h , group , PANEL_ACTIVE) 
		button:tgadget = CreateButton(tit , 4,1 , w , 18, panel , BUTTON_CHECKBOX) 
	
		SetProxy(panel ) 
		SetGadgetColor panel,188,188,188
		multi_list.AddLast Self

		Return Self
	End Method
	
	Method EventHook:TEvent( pEvent:TEvent )
		
		Select pEvent.id
		
			Case EVENT_MOUSEENTER
				button.settextcolor(255,0,0)
				SetPointer(POINTER_HAND)
			Case EVENT_MOUSELEAVE
				button.settextcolor(0,0,0)
				SetPointer(POINTER_DEFAULT)
			Case EVENT_MOUSEDOWN
				
		EndSelect
		
		Return Null
	
	EndMethod
	

	Method SetTextColor(r,g,b)
		Super.SetTextColor(r,g,b)
	EndMethod
	
	Method Free()
		multi_list.Remove(Self)
		Super.Free()
	EndMethod
	
	Function Initialize()
		multi_list = New TList
		AddHook EmitEventHook, eventHandler, Null, 1
		
	EndFunction
	
	Function eventHandler:Object( pID%, pData:Object, pContext:Object )
		Local pEvent:TEvent = TEvent(pData)
		
		If pEvent Then
			For Local tmp:Tmulti = EachIn multi_list
				If tmp.proxy = pEvent.source
					Return tmp.EventHook( pEvent ) 
				End If
			Next
		EndIf
	Return pData
	EndFunction
End Type


The TProxyGadget simply allows you to set-up custom gadgets so that they can be used with the standard set of MaxGUI commands, such as DisableGadget(), SetGadgetColor() etc.

This is done by setting a real gadget as the proxy gadget, which in your case appears to be panel, to which all commands are forwarded on to. Therefore, any time you call a MaxGUI command (such as DisableGadget()) on your TMulti custom gadget, it is effectively the same as calling it on TMulti.panel.

The behaviour you are experiencing is as expected - the panel is disabled which on Windows means that the panel becomes greyed out, and the children are also disabled (but don't appear so, this is just the OS standard - only the parent appears greyed out, although the children become desensitized).

If you really want the button to be greyed out too, then you'll need to override the SetEnabled(bool) by adding a new method somewhere in TMulti so that is passes the message onto both the panel and the button. For example,

Import maxgui.drivers
'Import maxgui.proxygadgets

Global wndMain:TGadget = CreateWindow( AppTitle, 100, 100, 300, 200, Null, WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_STATUS )

Global temp:tgadget = CreateMultiGadget("Hello" , 10 , 10 , 100 , 100 , wndMain) 
DisableGadget temp 'it disables the gadgets(panel) but all the rest is not greyed-out

Repeat
	WaitEvent()
	SetStatusText wndMain, CurrentEvent.ToString()
	Select EventID()
		Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE;End
	EndSelect
Forever

Function CreateMultiGadget:TGadget( url$,x:Int,y:Int,w:Int,h:Int,group:TGadget,style=0,customtext$ = "" )
		Return New Tmulti.Create(url,x,y,w,h,group,style,customtext)
EndFunction

Type tmulti Extends  TProxyGadget

	Global multi_list:TList
	
	Field panel:tgadget
	Field button:tgadget

	Method New()
		If multi_list=Null Initialize()
	End Method
	
	Method Create:tmulti(tit$ , x:Int , y:Int , w:Int , h:Int , group:tgadget , style:Int = 0 , ct$ = "")
		panel:tgadget = CreatePanel(x , y , w , h , group , PANEL_ACTIVE) 
		button:tgadget = CreateButton(tit , 4,1 , w , 18, panel , BUTTON_CHECKBOX) 
	
		SetProxy(panel ) 
		SetGadgetColor panel,188,188,188
		multi_list.AddLast Self

		Return Self
	End Method
	
	Method EventHook:TEvent( pEvent:TEvent )
		
		Select pEvent.id
		
			Case EVENT_MOUSEENTER
				button.settextcolor(255,0,0)
				SetPointer(POINTER_HAND)
			Case EVENT_MOUSELEAVE
				button.settextcolor(0,0,0)
				SetPointer(POINTER_DEFAULT)
			Case EVENT_MOUSEDOWN
				
		EndSelect
		
		Return Null
	
	EndMethod
	
	Method SetEnabled(bool)
		button.SetEnabled(bool)
		Super.SetEnabled(bool)	'This will forward the command onto the proxy gadget (i.e. the panel)
	EndMethod
	
	'You shouldn't need this
	'Method SetTextColor(r,g,b)
	'	Super.SetTextColor(r,g,b)
	'EndMethod
	
	Method Free()
		multi_list.Remove(Self)
		Super.Free()
	EndMethod
	
	Function Initialize()
		multi_list = New TList
		AddHook EmitEventHook, eventHandler, Null, 1
		
	EndFunction
	
	Function eventHandler:Object( pID%, pData:Object, pContext:Object )
		Local pEvent:TEvent = TEvent(pData)
		
		If pEvent Then
			For Local tmp:Tmulti = EachIn multi_list
				If tmp.proxy = pEvent.source
					Return tmp.EventHook( pEvent ) 
				End If
			Next
		EndIf
	Return pData
	EndFunction
End Type


Finally, I perhaps should also mention that you don't need to import MaxGUI.ProxyGadgets to make your own custom TProxyGadgets - all this is defined in MaxGUI.MaxGUI which is imported by MaxGUI.Drivers. MaxGUI.ProxyGadgets simply contains standard MaxGUI custom gadgets such as the hyperlink control (which wraps a label). If you aren't using the hyperlink control, you don't need to import it.

Edit: However, you might want to take a look into MaxGUI.ProxyGadget's source, as you will see how I do proxy gadgets.

Oh many thanks. Now it's more clear.
I think I will checkout better the gadget.bmx+magui.bmx type structure to know what methods are used.
Thank you very much.

PS:as for import Maxgui.Proxygadgets I made a copy&paste of the hyperlink gadget example: this means that this example must be changed...

PS:as for import Maxgui.Proxygadgets I made a copy&paste of the hyperlink gadget example: this means that this example must be changed...

Well that's not quite right - the hyperlink example needs to import MaxGUI.ProxyGadgets as it is using the hyperlink proxy gadget control. ;-) For your own proxy gadgets however, you do not need to import it.

(Homer Simpson's voice)Doh!
I'm very stupid...sorry :D