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. |