When the B+ gadgets don't satisfy your needs anymore, and you fear that BlitzMax will still take a while, then read on!
Using banks, you can do your own gadgets, which can be way more advanced than any 'internal' gadget. The basic idea is that you store all your gadget-properties in a bank, and use the bankhandle for everything gadget-related (drawing, modifying etc.)
Compare:
window=CreateWindow("title",0,0,640,480)
with
bla=CreateSomething(32,32,64,24,window)
From this perspective, working with banks is the most clean method to do your own gadgets. And after adding "CreateSomething(x,y,width,height,parent)" to a .decl file to make it highlight in your code, it feels like you're working with an internal gadget!
The only 2 downsides are that you need your own events-checks and that the normal gadget modifers (SetGadgetShape etc. etc.) won't work on these new gadgets). But personally I'd say these downsides are really no match for all the possible goodies that are in store for you!
Basically there're several functions that you always need:
- a create function
- an update function
and if the function should react to events then you need another one:
- an event function
additionally, if you wish to read or write properties of your gadget then you need these 2 functions aswell:
- get functions
- set functions
A create function creates a bank for you in which to store all your properties.
An update function draws your gadget.
An event function does all the event handling and can modify your gadget properties.
And set & get functions write or read properties.
Note that once you created your own gadget, the gadget handle is the only variable you'll ever need in your source. You don't need globals or other vars, for the simple reason that all vars are stored inside the gadget-bank.
Another example of custom gadget I already made is a window. This window has a border based on a bitmap and with a get function you get back the panel of that custom window. On this panel you can place blitz gadgets or your own gadgets. With a little effort you can make a gadget that contains even more gadgets. In this case the sub-gadget event-checks are inside the parent event-checks. In short, a scrollbar would be made out of 1 main gadget with 3 subgadgets (an up-button, a down-button and the scrollbar itself). This works perfectly! And you need only one event function call in your mainloop.
With a little more creativity you can load images inside a create-function, and store the image-handles inside the bank. A primitive image-button is within everyone's reach then.
There are more ways to enhance the whole gadget system. You could for example use the first 4 bytes of each bank to store some ID. By checking on the ID you can make sure that you don't accidentaly send the wrong bankhandle to an eventchecker, updater or get/set.
Gadgets can be complete large objects, one of my own gadgets is a complete zoom window (to draw tiles/sprites). Once I created it, and once I put an events checker in my mainloop I can draw in it with 2 colors! This way, building apps is a piece o' cake!
The source below is as small as possible, without all the comfy extras, to make it a bit more readable. The color-system could be somewhat more advanced as well (didn't want to spend more than a few seconds to it :), but the whole idea is clear.
Using banks, you can do your own gadgets, which can be way more advanced than any 'internal' gadget. The basic idea is that you store all your gadget-properties in a bank, and use the bankhandle for everything gadget-related (drawing, modifying etc.)
Compare:
window=CreateWindow("title",0,0,640,480)
with
bla=CreateSomething(32,32,64,24,window)
From this perspective, working with banks is the most clean method to do your own gadgets. And after adding "CreateSomething(x,y,width,height,parent)" to a .decl file to make it highlight in your code, it feels like you're working with an internal gadget!
The only 2 downsides are that you need your own events-checks and that the normal gadget modifers (SetGadgetShape etc. etc.) won't work on these new gadgets). But personally I'd say these downsides are really no match for all the possible goodies that are in store for you!
Basically there're several functions that you always need:
- a create function
- an update function
and if the function should react to events then you need another one:
- an event function
additionally, if you wish to read or write properties of your gadget then you need these 2 functions aswell:
- get functions
- set functions
A create function creates a bank for you in which to store all your properties.
An update function draws your gadget.
An event function does all the event handling and can modify your gadget properties.
And set & get functions write or read properties.
Note that once you created your own gadget, the gadget handle is the only variable you'll ever need in your source. You don't need globals or other vars, for the simple reason that all vars are stored inside the gadget-bank.
Another example of custom gadget I already made is a window. This window has a border based on a bitmap and with a get function you get back the panel of that custom window. On this panel you can place blitz gadgets or your own gadgets. With a little effort you can make a gadget that contains even more gadgets. In this case the sub-gadget event-checks are inside the parent event-checks. In short, a scrollbar would be made out of 1 main gadget with 3 subgadgets (an up-button, a down-button and the scrollbar itself). This works perfectly! And you need only one event function call in your mainloop.
With a little more creativity you can load images inside a create-function, and store the image-handles inside the bank. A primitive image-button is within everyone's reach then.
There are more ways to enhance the whole gadget system. You could for example use the first 4 bytes of each bank to store some ID. By checking on the ID you can make sure that you don't accidentaly send the wrong bankhandle to an eventchecker, updater or get/set.
Gadgets can be complete large objects, one of my own gadgets is a complete zoom window (to draw tiles/sprites). Once I created it, and once I put an events checker in my mainloop I can draw in it with 2 colors! This way, building apps is a piece o' cake!
The source below is as small as possible, without all the comfy extras, to make it a bit more readable. The color-system could be somewhat more advanced as well (didn't want to spend more than a few seconds to it :), but the whole idea is clear.
; ; your own gadgets in Blitzplus using banks ; ; tutorial by CS^TBL - 2004 ; app=CreateWindow("gadget example",0,0,640,480) ; a single something something=CreateSomething(32,32,64,24,app,80,120,160) ; an array of somethings (nice way to do a virtual drumcomputer this way ^^;) Dim bla(31) For t=0 To 31 bla(t)=CreateSomething(32+(t*16),128,16,32,app,192,0,0) ; create a row of somethings If Rnd(1,5)<2 SetSomethingState(bla(t),True) ; switch on a few Next ;---------------------------------------------------------------------------------------------------- ; ----- MAIN loop ----------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------- quit=False Repeat WaitEvent() If EventID()=$803 quit=True ; check on events SomethingEvents(something) For t=0 To 31 SomethingEvents(bla(t)) Next Until quit ;---------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------- ; and free all the somethings again FreeBank something For t=0 To 31 FreeBank bla(t) Next End ; bye! ;---------------------------------------------------------------------------------------------------- Function GetSomethingState(bank) If BankSize(bank)<8 End Return PeekByte(bank,4) End Function ;---------------------------------------------------------------------------------------------------- Function SetSomethingState(bank,state) If BankSize(bank)<8 End PokeByte bank,4,state UpdateSomething(bank) End Function ;---------------------------------------------------------------------------------------------------- Function SomethingEvents(bank) If BankSize(bank)<8 End canvas=PeekInt(bank,0) status=PeekByte(bank,4) If EventSource()=canvas If EventID()=$201 If EventData()=1 status=(status+1) Mod 2 PokeByte bank,4,status UpdateSomething(bank) EndIf EndIf EndIf End Function ;---------------------------------------------------------------------------------------------------- Function UpdateSomething(bank) If BankSize(bank)<8 End canvas=PeekInt(bank,0) status=PeekByte(bank,4) r=PeekByte(bank,5) g=PeekByte(bank,6) b=PeekByte(bank,7) width=GadgetWidth(canvas) height=GadgetHeight(canvas) SetBuffer CanvasBuffer(canvas) Color 0,0,0:Rect 0,0,width,height,False Color 255,255,255:Rect 1,1,width-2,height-2,False r=Limit(r+(status*64),0,255) g=Limit(g+(status*64),0,255) b=Limit(b+(status*64),0,255) Color r,g,b Rect 2,2,width-4,height-4,True FlipCanvas canvas End Function ;---------------------------------------------------------------------------------------------------- Function CreateSomething(x,y,width,height,parent,r,g,b) ; adr name size ; -------------------------------------- ; 00 canvas 1 int ( 4 bytes) ; 04 status 1 byte ; 05 red 1 byte ; 06 greens 1 byte ; 07 blue 1 byte ; ; total: 8 bytes bank=CreateBank(8) canvas=CreateCanvas(x,y,width,height,parent) PokeInt bank,0,canvas PokeByte bank,4,status PokeByte bank,5,r PokeByte bank,6,g PokeByte bank,7,b UpdateSomething(bank) Return bank End Function ;---------------------------------------------------------------------------------------------------- ;-- just a handy global function -------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------- Function Limit(value,minvalue,maxvalue) If value<minvalue Return minvalue If value>maxvalue Return maxvalue Return value End Function