MaxGui, Multiple canvas objects & Hooks

BlitzMax Forums/BlitzMax Beginners Area/MaxGui, Multiple canvas objects & Hooks

Hey everybody!

While doing an OOP exercise using multiple canvas objects, I ran into the following problem:

How do I get the event to identify in which canvas the event happened? (a MouseEnter event, for instance).

If you look at the code, you'll see that each Viewport object contains a canvas gadget, and has a "mouseover" field. But regardless of which canvas the mouse entered, the first created viewport always gets the event.

The biggest problem is that I don't want to use something like a timer to redraw all viewports, I only want to redraw the one that gets the event... but only the first Viewport is getting those events!

Maybe the problem is in the EventHook functions, which I re-used from the help and don't quite understand...

Any help is welcome!
Thanks,
Leo.


Strict

'************************************
'*********** " base" type ***********
'************************************

Type TMyGadget 

	Global MyWindow:TGadget
	Global MyGadgetList:TList = CreateList()
	
	Global PointerX:Int
	Global PointerY:Int
	
	Field x:Int
	Field y:Int
	Field width:Int
	Field height:Int
	
	Field Mouseover:Int = False
	
	Method OnEvent(event:TEvent) Abstract		
	Method Draw() Abstract
	Method Update() Abstract
	
	
	Method New()
		AddHook EmitEventHook,eventhook,Self
	End Method	

	Function eventhook:Object(id,data:Object,context:Object)
		Local event:TEvent
		Local app:TMyGadget
		event=TEvent(data)
		app=TMyGadget(context)
		app.OnEvent event	
	End Function		
	
	Function MakeMyWindow(name:String,x:Int,y:Int,width:Int,height:Int)
		If Not MyWindow
			MyWindow=CreateWindow(name,x,y,width,height)
			MyGadgetList.AddLast MyWindow			
		EndIf
	EndFunction	
	
	Function UpdateAll()
		For Local obj:TMyGadget = EachIn MyGadgetList
			Obj.Update					
		Next		
	End Function	
	
End Type


'****************************************
'*********** "Viewport"  type ***********
'****************************************


Type Tviewport Extends TMyGadget
	
	Field BgRed:Byte
	Field BgGreen:Byte
	Field BgBlue:Byte
	
	Field canvas:TGadget
	Field name:String
	
	Method Update()
		Self.Draw()
	End Method	
	
	Method Draw()
		SetGraphics CanvasGraphics(Self.canvas)
		SetViewport 0,0,GraphicsWidth(),GraphicsHeight()		
		SetClsColor BgRed,BgGreen,BgBlue						
		Cls
		
		SetColor 255,255,255		
		SetRotation MilliSecs()*.1
		DrawRect (GraphicsWidth()/2,GraphicsHeight()/2,60,10)
		SetRotation 0
		
		DrawText name, 10,10
		DrawText "Pointer:"+PointerX+","+PointerY,10,30
		DrawText "MouseOver:"+Mouseover,10,50			
		Flip		
	End Method		
	
	Method OnEvent(event:TEvent)	
		If event
			Select event.id			
				Case EVENT_WINDOWCLOSE
					End	
				Case EVENT_MOUSEMOVE
					RedrawGadget (Self.canvas)
					PointerX = event.x
					PointerY = event.y							
				Case EVENT_GADGETPAINT
					Update					
				Case EVENT_TIMERTICK
					UpdateAll					
				Case EVENT_MOUSEENTER
					Mouseover = True					
				Case EVENT_MOUSELEAVE
					Mouseover = False				     		
			End Select
		EndIf		
	End Method	
	
	Method Create:Tviewport(Title:String, x:Int, y:Int, width:Int, height:Int)	
		Self.canvas=CreateCanvas(x,y,width,height,MyWindow)
		Self.name = Title
		Self.canvas.SetLayout 2,2,2,2		
		MyGadgetList.AddLast Self		
		Return Self		
	End Method
	
	
End Type


'****************** main program *************************


Global MainTimer:TTimer = CreateTimer (60)
TMyGadget.MakeMyWindow("Main WIndow",100,100,400,500)

Local View01:Tviewport = New Tviewport.Create("View01", 0,0,200,200)
View01.BgRed = 255
View01.BgGreen = 0
View01.BgBlue = 0

Local View02:Tviewport = New Tviewport.Create("View02", 200,0,200,200)
View02.BgRed = 0
View02.BgGreen = 255
View02.BgBlue = 0

Local View03:Tviewport = New Tviewport.Create("View03", 0,200,200,200)
View03.BgRed = 0
View03.BgGreen = 0
View03.BgBlue = 255

Local View04:Tviewport = New Tviewport.Create("View04", 200,200,200,200)
View04.BgRed = 128
View04.BgGreen = 128
View04.BgBlue = 128


Repeat
	WaitEvent()			
Forever




Thanks for the help with the "codebox" thing, Rik!

(By the way, how do i post a code in a small textbox? Can I specify the number of lines here?)


You'll be wanting the <CODEBOX></CODEBOX> tag then (use '[' square brackets instead though).

Lots of useful info in the FAQ

and specifically for the forum codes in ..

What are the forum codes?

Method OnEvent(event:TEvent)	
  If event
    If event.source = Canvas
      Select event.id
        ...
        ...
      EndSelect
    EndIf
  EndIf
EndMethod


Hey Fred,

Selecting the Event Id didn't really fix all the problems, but it got me halfway there, and I was able to figure out the rest. (had to change the event hook stuff... at least now I understand it!). Thanks!!!

Now that I got over it, I'm building a map editor that, when in GUI mode, has several viewports with different functions, but when in FullScreen mode, only "plays" the contents of the main viewport (the game itself), which don't use MaxGUI at all. I'll post something I've done with it in the next days...or weeks...

Thanks again!