object help please

BlitzMax Forums/BlitzMax Beginners Area/object help please

im creating a little gui system

I have gadget types like:

type gui_element
field gadget_number
endtype

type button extends gui_element

endtype

type textbox extends gui_element

endtype

I want to gather the gadgets onto a window

so in my window class I have a list of gadgets that it contains

type window
field gadget_list:tlist

method add_gadget_to_window(o:object)
o.gadget_number=gadget_list.count()+1
endtype

endtype



but I cant access the field gadget_number from o:object
how do I do that?

Change

method add_gadget_to_window(o:object)

To

method add_gadget_to_window(e:gui_element)

it compiles now thanks

but throws an error:'trying to access field or method of null object'

here is the actual method:

Method add_gadget(o:gui_element)
gadget_list.addlast(o)

-this is the line that throws the error -
o.gadget_number=gadget_list.count()

EndMethod

im absolutely sure that gui_element has a field called gadget_number

dont know why it does this

Are you sure gadget_list isn't null?

pretty sure:
I changed the line
o.gadget_number=gadget_list.count()
to
o.gadget_number=1

and it still threw the error.

shall I show ALL the code? its 300 lines with spaces

I had a look at frygui,highgui and c64's GUI code

none of them do it like I am attempting

all of those other GUI systems have a list of children on the gui_element base type.

So maybe what I am attempting is impossible?

In that case, you're sending an object to that function which either does not exist or is not derived from gui_element.

But yeah, if you don't mind posting all the code, I don't mind taking a look.

Those GUI systems you mention might not work by deriving all their gui_elements from a base type, but mine does, so unless there's more to this than meets the eye, I'm sure it's possible.

thanks for taking a look


I can change the loadimage commands if you want to run the program for yourself

instead of creating a window, I tried to create a gadget scroller that had a list of gadgets - like a list of buttons and textboxes

Strict

SeedRnd(MilliSecs())

SetGraphicsDriver D3D7Max2DDriver () 

Graphics 640 , 480

Local checktime
Local fpscounter
Local curTime
Local curfps
Local time

gui_type.init_gui() 

Local t:textbox=textbox.Create() 
Local b:button=button.Create(150,50,100,40,"Request")
Local g:gadget_scroller=gadget_scroller.Create(0 , 0 , 120 , 200) 
g.add_gadget(b)

Global mouse_hit1
Global mouse_x
Global mouse_y

While Not KeyHit(KEY_ESCAPE) 

Delay(1)

SetViewport(0 , 0 , GraphicsWidth() , GraphicsHeight() )

Cls


time = MilliSecs() 


mouse_hit1=MouseHit(1)
mouse_x = MouseX() 
mouse_y=MouseY()

curtime=time
If curTime > checkTime Then
	 checkTime = curTime + 1000
	curFPS= fpscounter
 fpscounter = 0
Else
	fpscounter = fpscounter + 1
End If


Local argh$=String(curfps)

SetColor 255 , 255 , 255
DrawText "FPS: " + curfps, 10, 10

For Local t:gui_element = EachIn gui_element.list

t.update(mouse_hit1 , mouse_x , mouse_y) 
t.render() 
Next


Flip False

Wend




Type gui_type
Field up_arrow:Timage
Field down_arrow:Timage
Field window_img:Timage
Field button_img:Timage
Field button_over_img:Timage
Global gui_pointer:gui_type

Function init_gui()
gui_pointer:gui_type=New gui_type
gui_pointer.down_arrow=LoadImage("downarrow.png")
gui_pointer.window_img = LoadImage("window.png") 
gui_pointer.button_img = LoadImage("button.png") 
gui_pointer.button_over_img=LoadImage("buttonpressed.png")
EndFunction



EndType

Type gui_element
Field x
Field y
Field width:Float
Field height:Float
Field mouse_over

Field gadget_number 'for gadget scroller

Global list:TList = New TList

Method After:Object()
		Local link:TLink = list.FindLink(Self).NextLink()
		If link
			Return Object(link.Value())
		Else
			Return Null
		EndIf
EndMethod

	Method Before:Object()
		Local link:TLink = list.FindLink(Self).PrevLink()
		If link
			Return Object(link.Value())
		Else
			Return Null
		EndIf
	EndMethod

Method New()
list.addlast(Self) 
EndMethod

Method update(mouse_hit1,mouse_X,mouse_y) 
If detect_mouse_over(mouse_x,mouse_y) 
mouse_over = True
Else
mouse_over=False
EndIf
EndMethod

Method detect_mouse_over(mouse_X,Mouse_Y)
If Mouse_X > x
If Mouse_X < (x + width) 
If Mouse_Y > y
If Mouse_Y < (y + height) 
Return True
EndIf
EndIf
EndIf
EndIf
EndMethod

Method render() 

EndMethod

EndType


Type button Extends gui_element

Field text$
Global img:timage
Global img2:timage
Field pressed_timer

Function Create:button(x , y , width:Float , height:Float , text$)
Local t:button=New button
t.x = x
t.y = y
t.width = width
t.height = height
t.text = text

If img = Null
img=gui_type.gui_pointer.button_img
img2=gui_type.gui_pointer.button_over_img
EndIf

EndFunction

Method update(mouse_hit1,mouse_x,mouse_y) 
Super.update(mouse_hit1,mouse_x,mouse_y)
If mouse_hit1
If mouse_over = True
DebugLog Self.text
EndIf
EndIf
EndMethod

Method render()

SetColor(255,255,255) 
SetScale (Self.width / ImageWidth(img) , height / ImageHeight(img)) 


If mouse_over=True And mouse_hit1=True
pressed_timer=MilliSecs()
EndIf

If pressed_timer+300>MilliSecs()
DrawImage img2 , x , y
Else
DrawImage img,x,y
EndIf

SetScale(1 , 1) 

If mouse_over=False
SetColor (0 , 0 , 0) 
Else
SetColor (170,0,0)
EndIf

Local draw_x=(x+(width/2))-(TextWidth(text)/2)
Local draw_y=(y+(height/2))-(TextHeight(text)/2)
DrawText text,draw_x,draw_y
SetColor(255 , 255 , 255) 

EndMethod

EndType




Type textbox Extends gui_element

Field lines$[400]
Field current_line
Global img
Global list:TList=New TList

Function Create:textbox() 
Local t:textbox=New textbox 
t.x = 500
t.y = 0
t.width = 150
t.height = 150
t.lines[0] = "Help an ogre"
t.lines[1] = "Just hit me"
t.lines[2] = "over the head"
t.current_line=0
list.addlast(t)
Return t
End Function

Method render() 
SetColor 255,255,255
'SetViewport viewport_x , viewport_Y , viewport_width , viewport_height
SetScale (width/128,height/128)
'DrawRect viewport_x,viewport_y,viewport_width,viewport_height
DrawImage gui_type.gui_pointer.window_img,x,y 
SetScale(1,1)
SetColor 0 , 0 ,0

Local line_position=0
For Local iter = Self.current_line To lines.length-1
If lines[iter]<>""
DrawText lines[iter],x+5,y+(line_position*15)+5
line_position=line_position+1
EndIf
Next

SetColor 255,255,255
SetScale (0.5,0.5)
DrawImage gui_type.gui_pointer.down_arrow,x+width-29,y+height-58
SetRotation (180) 
DrawImage gui_type.gui_pointer.down_arrow,x+width,y+29
SetRotation (0) 
SetScale (1,1)
EndMethod

EndType

Type gadget_scroller Extends gui_element


Field current_gadget:Object
Field gadget_list:TList
Field virtual_height


Method add_gadget(o:gui_element)
gui_element.list.remove(o)
gadget_list.addlast(o)
o.gadget_number=gadget_list.count()
EndMethod

Function Create:gadget_scroller(x,y,width,height) 

Local o:gadget_scroller = New gadget_scroller
o.gadget_list = New TList
Return o

EndFunction

Method render() 
For Local o:gui_element = EachIn gadget_list
DebugLog "found gadget on list"
If o = Self.current_gadget
SetViewport (x , y , width , height)
DebugLog "arg"
o.render
Exit
EndIf
Next

SetViewport(0,0,GraphicsWidth(),GraphicsHeight())
EndMethod

Method update(mouse_hit1,mouse_X,mouse_y)

EndMethod

EndType



Your Create function within the Button type is not returning the object it creates, so you're passing a null object when you call g.addgadget(b)

Change the create function in Button to this:

Function Create:button(x , y , width:Float , height:Float , text$)
Local t:button=New button
t.x = x
t.y = y
t.width = width
t.height = height
t.text = text

If img = Null
img=gui_type.gui_pointer.button_img
img2=gui_type.gui_pointer.button_over_img
Return t
EndIf


And you should be fine.

oops,
it works now thanks!