events
BlitzMax Forums/BlitzMax Beginners Area/events
| ||
| I'm trying to figure out things like eventhooks 'n stuff.. can someone explain it a bit, for example by adding such a mechanism to the small example-source below? So, the idea is that I don't need that t.ev in the mainloop anymore, everything should become transparent, just like the standard built-in GUI objects.. It should also emit some new events I could read out with EventSource().. MaxGUI really needs more examples.., as good as B+ was, as minimalistic/sober MaxGUI is .. ._. |
| ||
Try this...
Strict
Type test
Field canvas:TGadget
Method ev(event:TEvent)
Select event.ID
Case EVENT_MOUSEENTER
update 1
Case EVENT_MOUSELEAVE,EVENT_GADGETPAINT
update
End Select
End Method
Method update(state:Byte=0)
SetGraphics CanvasGraphics(canvas)
SetClsColor 128+state*127,128+state*127,128+state*127
Cls
Flip
End Method
Function create:test(parent:tgadget)
Local a:test=New test
a.canvas=CreateCanvas(10,10,20,20,parent)
Return a
End Function
End Type
Local win:TGadget=CreateWindow("o_O",0,0,400,120)
Global t:test=test.create(win)
AddHook EmitEventHook,EventHook
Repeat
WaitEvent()
't.ev
If EventID()=EVENT_WINDOWCLOSE End
Forever
Function EventHook:Object(iId,tData:Object,tContext:Object)
'event is in TDATA
'source --> event.Source (method)
'event ID (EVENT_MOUSEENTER...) --> event.ID
Local Event:TEvent=TEvent(tData)
Print "Event : "+event.tostring()
Print "Source: "+String(event.source)
Select Event.Source
Case t.canvas
t.ev(event)
Print "event catched..."
Return Null
Default
Print "No event..."
End Select
Return Event 'Event pass through (nothing thats been captured)
End Function
I modified some thing to reach the goal...I extended your TEST type to catch the event, the EventHook function is from this forum - I don't remember who wrote it. |
| ||
Strict
Type test
Field canvas:TGadget
Method ev(event:TEvent)
Select event.ID
Case EVENT_MOUSEENTER
update 1
Case EVENT_MOUSELEAVE,EVENT_GADGETPAINT
update
End Select
End Method
Method update(state:Byte=0)
SetGraphics CanvasGraphics(canvas)
SetClsColor 128+state*127,128+state*127,128+state*127
Cls
Flip
End Method
Function create:test(parent:tgadget)
Local a:test=New test
a.canvas=CreateCanvas(10,10,20,20,parent)
AddHook EmitEventHook,a.EventHook
Return a
End Function
Function EventHook:Object(iId,tData:Object,tContext:Object)
'event is in TDATA
'source --> event.Source (method)
Local Event:TEvent=TEvent(tData)
Print "Event : "+event.tostring()
Print "Source: "+String(event.source)
Select Event.Source
Case t.canvas
t.ev(event)
Print "event catched..."
Return Null
Default
Print "No event..."
End Select
Return Event 'Event pass through (nothing thats been captured)
End Function
End Type
Local win:TGadget=CreateWindow("o_O",0,0,400,120)
Global t:test=test.create(win)
'AddHook EmitEventHook,t.EventHook
Repeat
WaitEvent()
't.ev
If EventID()=EVENT_WINDOWCLOSE End
Forever
Just now I realized that I can 'inglobe' all the function - even EventHook - in the type... [edit]: modified again: now when you create a TEST type you add the eventhook |
| ||
| That example is not that useful to me.. Globals are evil and should be avoided.. :( it should be like this: Local t:test=test.create(win) And obviously in the EventHook function there can't be a reference to that global t .. |
| ||
Strict
Type Test
Global test_List:TList = New TList
Global Act_Can:Test = Null
Field canvas:TGadget
Function Hook:Object(id,data:Object,context:Object)
Local ev:TEvent=TEvent(data)
If Not ev Return data
'Print ev.toString()
Select ev.id
Case Event_MouseEnter
Act_Can = GetSelectedCanvas(Ev)
If Act_Can <> Null Then
Act_Can.Update(1)
EndIf
Case Event_MouseLeave
If Act_Can <> Null
Act_Can.Update(0)
Act_Can = Null
EndIf
Case Event_TimerTick
For Local T:Test = EachIn Test.Test_List
RedrawGadget T.Canvas
Next
End Select
Return data
End Function
Function GetSelectedCanvas:Test(Event:TEvent)
For Local T:Test = EachIn Test.Test_List
If T.Canvas = Event.Source Then
Return T
End If
Next
Return Null
End Function
Method update(state:Byte=0)
SetGraphics CanvasGraphics(canvas)
SetClsColor 128+state*127,128+state*127,128+state*127
Cls
Flip
End Method
Function create:Test(x,y,w,h,parent:TGadget)
Local a:Test=New Test
a.canvas=CreateCanvas(x,y,w,h,parent)
a.Update(0)
Test.Test_List.Addlast(A)
AddHook EmitEventHook,Test.Hook,A,0
Return a
End Function
End Type
Function createtest:Test(x,y,w,h,parent:TGadget)
Return Test.Create(x,y,w,h,parent)
End Function
Local win:TGadget=CreateWindow("o_O",0,0,640,480)
Local t:Test=createtest(32,32,48,24,win)
t:Test=createtest(32,60,48,24,win)
t:Test=createtest(32,88,48,24,win)
Repeat
WaitEvent()
If EventID()=EVENT_WINDOWCLOSE End
Forever
This is a small workaround, I hope this helps you |
| ||
| Also not what I mean .. sorry .. It may even all work, but I really wonder why it isn't possible to have it all a bit more transparent like the rest. A hook for each instance, without instances even knowing other instances.. like it is now.. since they're in the same list. So create them like this: local t:createtest(10,20,30,40,win) local t2:createtest(30,40,50,60,win) local doggy:createtest(50,60,70,80,win) local helloworld:createtest(150,160,170,180,win) local bratwurst:createtest(150,160,170,180,win) .. and each one should work indepentently.. All these, not being in any list, and each with its own private hook. No globals, no type-globals, no lists.. It should look/feel just like the first sample I posted, but then automated with hooks.. With degac's last one I'd be done, except for the global.. Yes, sorry for my anti-globalism-campaign, but uhm.. I hate them.. :D Any new suggestions? :P |
| ||
Strict
Type Test
Field canvas:TGadget
Function Hook:Object(id,data:Object,context:Object)
Local ev:TEvent=TEvent(data)
If Not ev Return data
'Print ev.toString()
Local Act_Can:Test = Test(TGadget(ev.source).Context)
If Act_Can <> Null Then
Select ev.id
Case Event_MouseEnter
Act_Can.Update(1)
Case Event_MouseLeave
Act_Can.Update(0)
Case Event_TimerTick
RedrawGadget Act_Can.Canvas
End Select
EndIf
Return data
End Function
Method update(state:Byte=0)
SetGraphics CanvasGraphics(canvas)
SetClsColor 128+state*127,128+state*127,128+state*127
Cls
Flip
End Method
Function create:Test(x,y,w,h,parent:TGadget)
Local a:Test=New Test
a.canvas=CreateCanvas(x,y,w,h,parent)
a.canvas.Context = a
a.Update(0)
AddHook EmitEventHook,Test.Hook,Null,0
Return a
End Function
End Type
Function createtest:Test(x,y,w,h,parent:TGadget)
Return Test.Create(x,y,w,h,parent)
End Function
Local win:TGadget=CreateWindow("o_O",0,0,640,480)
Local t:Test=createtest(32,32,48,24,win)
t:Test=createtest(32,60,48,24,win)
t:Test=createtest(32,88,48,24,win)
Repeat
WaitEvent()
If EventID()=EVENT_WINDOWCLOSE End
Forever
This is my new suggestion, as you can add context objects to each Gadget you could attach the actual Test Type to the cnavas. With Local Act_Can:Test = Test(TGadget(ev.source).Context) you can receive the Test Type attached with the event.source. and use this to update your things. |
| ||
| almost .. ..but not yet :D I think there should simply be an events-method. And the only thing the hook should do is call that events-method. The hook function shouldn't do the actual events itself. This event function would look like this:
Method Events()
If EventSource()=gadget1
If EventID()=id1
EndIf
If EventID()=id2
EndIf
Endif
If EventID()=id3 ; just for this order-swapping I'm not much a fan of Select-Case constructions..
If EventSource()=gadget2
EndIf
If EventSource()=gadget3
EndIf
Endif
; And yes, you can assume there's more than 1 gadget for an object like this..
End Method
Actually I'm surprised this baby takes so long to deliver :P The idea isn't that strange I'd say. - create independent unlisted local object - create event-function for object - create eventhook that calls that event-function - and next step: emit new unique events so I can use this object everywhere The endgoal is that there's a means to create new GUI gadgets and other self-contained objects that look 100% transparent with the rest of the gadgets. So it must work in a 100% similar way. |