Parent/Child Type Structuring

Blitz3D Forums/Blitz3D Programming/Parent/Child Type Structuring

spriteman(Posted 2006) [#1]
Hi,

I am starting to get the hang of types and have had partial success in using them.

My question is probably something that has been mentioned again and again but, what is the best way of specifying an unspecified number of a particular type within a type structure.

I am making a kind of GUI and have declared a parent type structure as below.

;----Type declerations----------
Type GADGET
Field GID% ; Gadget ID
Field GIMAGE$ ; Image
Field GX% ; X Pos
Field GY% ; Y Pos
Field GW% ; Gadget Width
Field GH% ; Gadget Height
End Type

I then pass values to this parent type structure using the function and function call as below,

;CreateGadget(0,"mp3player1.bmp",100,100,300,200)

;Function CreateGadget(GID%,GIMAGE$,GX%,GY%,GW%,GH%) ;Create a Gadget

;G.GADGET = New GADGET
; G\GID% = GID%
; G\GIMAGE = LoadImage(GIMAGE$)
; G\GX% = GX%
; G\GY% = GY%
; G\GW% = GW%
; G\GH% = GH%

;Return True

;End Function

What I would now like to do is create an unspecified number of child types within the parent type above and be able to pass values to it using a similar function. The child types would have to be an unspecified number of.

Sorry if this is unclear as sometimes I find it difficult to state the details...


(tu) sinu(Posted 2006) [#2]
Do you mean like this?


;Function CreateGadget(GID%,GIMAGE$,GX%,GY%,GW%,GH%) ;Create a Gadget

;G.GADGET = New GADGET
; G\GID% = GID%
; G\GIMAGE = LoadImage(GIMAGE$)
; G\GX% = GX%
; G\GY% = GY%
; G\GW% = GW%
; G\GH% = GH%

;Return handle(g)

;End Function

function DoStuff(id%,x#,y#)

 g.GADGET = object.GADGET(id)
 if GADGET = null return
 
 ;dostuff to this gadget here
end function




spriteman(Posted 2006) [#3]
Hi tu,

Its a funny one to explain so I will tell you what I am doing.

I am creating gadgets which contains a G\GIMAGE field as above to store a background picture for the gadget and other criteria. Within that gadget there will be buttons and sliders. I am looking to specify the buttons and sliders as child type structures which would have a direct relationship with the parent gadget type.

Hope this helps the explanation.

Thanks,


Stevie G(Posted 2006) [#4]
I think this is the kind of thing you mean. I use this type of thing for GUI stuff where I make a menu and add button types to it .... Basically, each button holds it's parent gadget so that they can be grouped together. It's not really necessary to store a GID% if you hold the gadget globally.

Simple non working example

Type GADGET
	Field GID% ; Gadget ID
	Field GIMAGE$ ; Image
	Field GX% ; X Pos
	Field GY% ; Y Pos
	Field GW% ; Gadget Width
	Field GH% ; Gadget Height
End Type

Type BUTTON
	Field Parent.GADGET
	Field Blah1
	Field Blah2
End Type

Global MENU1.GADGET = CreateGadget( 0, "mp3player1.bmp",100,100,300,200)
CreateButton( MENU1, 5, 5 )
CreateButton( MENU1, 2, 2 )

Global MENU2.GADGET = CreateGadget( 1, "Anotherbitmap.bmp",250,100,300,200)
CreateButton( MENU2, 5, 5 )
CreateButton( MENU2, 2, 2 )

;===========================================================
;===========================================================
;===========================================================

Function CreateButton( G.GADGET , Blah1, Blah2 )

	b.Button = New button
	b\Parent = G
	b\Blah1 = Blah1
	b\Blah2 = Blah2
	
End Function

;===========================================================
;===========================================================
;===========================================================

Function CreateGadget.Gadget(GID%,GIMAGE$,GX%,GY%,GW%,GH%) ;Create a Gadget

	G.GADGET = New GADGET
	G\GID% = GID%
	G\GIMAGE = LoadImage(GIMAGE$)
	G\GX% = GX%
	G\GY% = GY%
	G\GW% = GW%
	G\GH% = GH%

	Return G

End Function

;===========================================================
;===========================================================
;===========================================================



Beaker(Posted 2006) [#5]
Use Stevie Gs method or there are a couple of other ways to go:

Manage the type list yourself using sibling and child links.
Type GADGET
	Field GID% ; Gadget ID
	Field GIMAGE$ ; Image
	Field GX% ; X Pos
	Field GY% ; Y Pos
	Field GW% ; Gadget Width
	Field GH% ; Gadget Height

	Field firstchild.GADGET	;link to first child of this gadget
	Field prv.GADGET	;link to previous sibling
	Field nxt.GADGET	;link to next sibling
	;Field parent.GADGET	;optional link to parent of this GADGET
End Type
This method is very good, but can be a little fiddly.

Next method is to allow a maximum number of children using a Constant, and store the children in a Blitz array:
Const MAXGADGETCHILDREN = 20
Type GADGET
	Field GID% ; Gadget ID
	Field GIMAGE$ ; Image
	Field GX% ; X Pos
	Field GY% ; Y Pos
	Field GW% ; Gadget Width
	Field GH% ; Gadget Height

	Field child.GADGET[MAXGADGETCHILDREN]
End Type


Another way is to store the Handle of the childrens Type objects in a bank (with an offset of 4 bytes between each).
Type GADGET
	Field GID% ; Gadget ID
	Field GIMAGE$ ; Image
	Field GX% ; X Pos
	Field GY% ; Y Pos
	Field GW% ; Gadget Width
	Field GH% ; Gadget Height

	Field childbank	;created using CreateBank()
End Type
For this one look up CreateBank(), and then Object() and Handle() on this forum.
Object/Handle primer
Interesting use of Object/Handle


spriteman(Posted 2006) [#6]
Hi,

I have used Stevie G's method as its the kind of structure I have been looking to addopt. Below is a little code which contains a Gadget Type and 2 slider types as children. Can anyone show me how to display image the gadget and the sliders in the main program loop using a global reference to the type structure PLAYER1. Thanks,

Graphics 800,600,0,2

SeedRnd MilliSecs()

;----Type declerations----------

Type GADGET
Field GID% ; Gadget ID
Field GIMAGE$ ; Image
Field GX% ; X Pos
Field GY% ; Y Pos
Field GW% ; Gadget Width
Field GH% ; Gadget Height
End Type

Type SLIDER
Field Parent.GADGET ; The sliders parent is the gadget
Field SID% ; Slider ID
Field SIMAGE$ ; Image
Field SX% ; X Pos
Field SY% ; Y Pos
Field SW% ; Slider Width
Field SH% ; Slider Height
Field SMAX% ; Slider Max value
Field SMIN% ; Slider Min value
End Type

;-------------------------------

Global PLAYER1.GADGET = CreateGadget( 0,"mp3player1.bmp",100,100,300,200)
CreateSlider(PLAYER1,0,0,12,67,"slider.bmp",40,10,100,0)
CreateSlider(PLAYER1,0,0,60,67,"slider.bmp",40,10,100,0)

;-------------------------------



SetBuffer BackBuffer()

While Not KeyHit(1)


Flip
Wend

End

;-------------------------------

Function CreateGadget.gadget(GID%,GIMAGE$,GX%,GY%,GW%,GH%) ;Create a Gadget

G.GADGET = New GADGET
G\GID% = GID%
G\GIMAGE = LoadImage(GIMAGE$)
G\GX% = GX%
G\GY% = GY%
G\GW% = GW%
G\GH% = GH%

Return G
End Function

Function CreateSlider(G.GADGET,SID%,SPTID%,SX%,SY%,SIMAGE$,SW%,SH%,SMAX%,SMIN%) ;Create a Slider

S.SLIDER = New SLIDER
S\PARENT = G
S\SID% = SID%
S\SX% = SX%
S\SY% = SY%
S\SIMAGE = LoadImage(SIMAGE$)
S\SW% = SW%
S\SH% = SH%
S\SMAX% = SMAX%
S\SMIN% = SMIN%

Return True

End Function


Stevie G(Posted 2006) [#7]
I would tend to stick with a single button type which has an ID to tell whether it's a text box , input box ,horizontal or verticle slider etc... for interaction. This means you have some redundant fields for some of the button types but not much of an overhead.

As you have it now, for just the sliders ... this should work :

function DisplayGaget( g.gadget )

    drawimage g\GIMAGE, g\gx, g\gy 
    for s.slider = each slider
       if s\Parent = g
           drawimage s\SIMAGE, s\SX, s\SY
       endif
     next
    
end function



spriteman(Posted 2006) [#8]
Stevie G

This is very tidy and a great way to build up a GUI using propper structured Types. It took me a while to think about how to structure a type within a type so to speak. Well the next thing I will do is add some more sliders, then some buttons eventually. I guess its fairly fast as well. My Gui will consist of windows that are draggable. It will also use a great windows priority system that big10 helped me with. Great people on a great forum. Thanks again.


spriteman(Posted 2006) [#9]
Steve G,

Just to add and sorry again for borrowing your brain, I will be wanting to relate to the child types i.e the sliders so that when the mouse is over the slider knob image (Of the chosen gadget) so to speak then the mouse pointer turns into a hand pointer. This denotes that the user has hit a hotspot.

Now, I wish to use RectsOverlap to identify that the mouse is over the slider knob. Bearing in mind I am also using a priority method to select and store the top priority gadget and giving it a type global pointer of ACTIVE_G

If RectsOverlap(ACTIVE_G\GX%,ACTIVE_G\GY%,ACTIVE_G\GW%,15,mx,my,1,1) Then

How would I refer to the child slider in rectsoverlap,?

regds


spriteman(Posted 2006) [#10]
Well I actually managed to do this myself....Just need to address my type pointers correctly..:-)

For S.SLIDER = Each SLIDER
If S\PARENT = ACTIVE_G ; Check hotspots on active gadget only
If RectsOverlap((ACTIVE_G\GX%+S\SX),(ACTIVE_G\GY%+S\SY),S\SW,S\SH,mx,my,1,1) Then
DrawImage hand,mx,my
pointeroff=1
End If
EndIf
Next