your own gadgets! (Blitzplus, average skills)
BlitzPlus Forums/BlitzPlus Tutorials/your own gadgets! (Blitzplus, average skills)
| ||
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. ; ; 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 |
| ||
Very interesting |
| ||
LOoks a good way to make up for the lack of gadjets |
| ||
here's another example.. a scroll-panel Notice that found a dumb thingy while preparing this post.. I'm too lazy to fix it however.. :) For obvious reasons the scrollpanel needs to be as wide as the parent-panel.. so having an arguement stating the width of you scrollpanel would'n much useful when you can get the gadgetwidth of the parent panel to get that width ;) anyway (it's just an example, soon enough you should be making your own gadgets anyway), enjoy.. app=CreateWindow("",0,0,640,480) ; create 2 parent panels panel1=CreatePanel(20,20,256,256,app) panel2=CreatePanel(320,20,256,256,app) ; create the scrollpanels scrollpanel1=CreateVScrollpanel(256,768,panel1,32,160,160,160) scrollpanel2=CreateVScrollpanel(256,512,panel2,32,160,160,160) ; put some example crap on the scrollpanels For t=0 To 10 CreateButton(t,32,20+t*64,64,24,VScrollpanelPanel(scrollpanel1)) CreateButton(t,32+t*5,20+t*32,64,24,VScrollpanelPanel(scrollpanel2)) Next ; main loop quit=False Repeat WaitEvent() If EventID()=$803 quit=True ; if you don't include these, you can't scroll! VScrollpanelEvents (scrollpanel1) VScrollpanelEvents (scrollpanel2) Until quit ; clean-up FreeBank scrollpanel1 FreeBank scrollpanel2 ; bye! End ; returns the actual panelhandle of the scrollpanel.. Function VScrollpanelPanel(bank) Return PeekInt(bank,4) End Function Function VScrollpanelEvents(bank) canvas=PeekInt(bank,8) If EventSource()=canvas If EventID()=$201 PokeByte bank,19,1 ; drag=true PokeShort bank,20,MouseY() ; start coord. EndIf If EventID()=$202 PokeByte bank,19,0 ; drag=false EndIf If PeekByte(bank,19) ; drag ? If EventID()=$203 y=MouseY() panel=PeekInt(bank,4) oldy=PeekShort(bank,20) ycoord=GadgetY(panel)+y-oldy ycoord=Limit(ycoord,-PeekShort(bank,14)+PeekShort(bank,22),0) SetGadgetShape panel,GadgetX(panel),ycoord,GadgetWidth(panel),GadgetHeight(panel) PokeShort bank,20,y EndIf EndIf EndIf End Function Function CreateVScrollpanel(width,height,parent,dragwidth,r,g,b) If width*height=0 Break"Incorrect dimensions!" If height<GadgetHeight(parent) Break"Panel height-bigger than parent-height!" If Not parent Break"Parent missing" If Not dragwidth Break"Dragbar zero" r=Limit(r,0,255) g=Limit(g,0,255) b=Limit(b,0,255) ; adr name size ; 00 ID 4 bytes <- reserved for an optional 4-chars ID check! not used right now.. ; 04 panel 1 int (4 bytes) ; 08 dragcanvas 1 Int (4 bytes) ; 12 width 1 short (2 bytes) ; 14 height 1 short (2 bytes) ; 16 r 1 byte ; 17 g 1 byte ; 18 b 1 byte ; 19 dragstatus 1 byte ; 20 dragY 1 short (2 bytes) ; 22 parntheight 1 short (2 bytes) bank=CreateBank(24) panel=CreatePanel(0,0,width,height,parent) SetPanelColor panel,r,g,b canvas=CreateCanvas(width-dragwidth,0,dragwidth,height,panel) SetCanvas canvas ClsColor r,g,b:Cls For y=2 To height-1 Step 4 For x=2 To dragwidth-1 Step 4 xo=(y Mod 8)/4 Bcolor r*1.3,g*1.3,b*1.3 Plot x+xo,y Bcolor r*0.7,g*0.7,b*0.7 Plot x+xo+1,y+1 Next Next Bcolor r*1.3,g*1.3,b*1.3 Line 0,0,0,height-2 Line 0,0,dragwidth-2,0 Bcolor r*0.7,g*0.7,b*0.7 Line dragwidth-1,1,dragwidth-1,height-2 Line 1,height-1,dragwidth-2,height-1 FlipCanvas canvas PokeInt bank,4,panel PokeInt bank,8,canvas PokeShort bank,12,width PokeShort bank,14,height PokeByte bank,16,r PokeByte bank,17,g PokeByte bank,18,b PokeShort bank,22,GadgetHeight (parent) Return bank End Function ; misc. needed global functions.. some useful, some just for the lazy coder (SetCanvas) :) Function Limit(value,minvalue,maxvalue) If value<minvalue Return minvalue If value>maxvalue Return maxvalue Return value End Function Function Break(s$) Notify s$ End End Function Function Bcolor(r,g,b) r=Limit(r,0,255) g=Limit(g,0,255) b=Limit(b,0,255) Color r,g,b End Function Function SetCanvas(bla) SetBuffer CanvasBuffer(bla) End Function |
| ||
That's really very useful. |