Ich hab grad ein Brett vor Kopf.
In anderen Sprachen gibt es Listen wo ich Objekte rein tun kann, wie kann man das in GLBasic lösen?
TYPE TGui
x1
y1
x2
y2
text$
valuei
valuef#
enabled
visible
focus
SubList[] //AS TGui <<< ???
FUNCTION Add: x1,y1,x2,y2,text$
LOCAL G AS TGui
//G_ProcentToReal( x1,y1 , x1,y1 )
//G_ProcentToReal( x2,y2 , x2,y2 )
G.x1=x1
G.y1=y1
G.x2=x2
G.y2=y2
G.text$=text$
G.valuei=0
G.valuef#=0.0
G.enabled=TRUE
G.visible=TRUE
G.focus=FALSE
DIMPUSH SubList[], G //hier ist das nun der falsche Typ
ENDFUNCTION
//...
ENDTYPE //Gui
So sollte es gehen...
Quote from: Markus on 2012-Apr-19
Ich hab grad ein Brett vor Kopf.
In anderen Sprachen gibt es Listen wo ich Objekte rein tun kann, wie kann man das in GLBasic lösen?
TYPE TGui
x1
y1
x2
y2
text$
valuei
valuef#
enabled
visible
focus
SubList[] AS TGui //<<< War schon richtig so
FUNCTION Add: x1,y1,x2,y2,text$
LOCAL G AS TGui
//G_ProcentToReal( x1,y1 , x1,y1 )
//G_ProcentToReal( x2,y2 , x2,y2 )
G.x1=x1
G.y1=y1
G.x2=x2
G.y2=y2
G.text$=text$
G.valuei=0
G.valuef#=0.0
G.enabled=TRUE
G.visible=TRUE
G.focus=FALSE
DIMPUSH self.SubList[], G //Type-eigene Variablen immer mit self.xxx aufrufen
ENDFUNCTION
//...
ENDTYPE //Gui
Näh , hab ich auch gedacht .
Der Compiler sagt "type member is defined recursively : SubList"
Hier mal das ganze:
Die Anwendung
// --------------------------------- //
// Project: MRGUI
// Start: Thursday, April 19, 2012
// IDE Version: 10.283
GLOBAL Gui AS TGui
MainLoop()
END
FUNCTION MainLoop:
SYSTEMPOINTER TRUE
Gui.CreateWindow (0, 00,100,100,"Window")
Gui.CreateLabel (1, 10, 99, 20,"Label")
Gui.CreateButton (1, 20, 99, 30,"Button")
Gui.CreateSlider (1, 30, 99, 40,"Slider")
Gui.CreateList (1, 40, 99, 60,"List")
Gui.CreateCheckbox(1, 60, 99, 70,"Checkbox")
Gui.CreateOption (1, 70, 99, 80,"Option")
Gui.CreateFrame (1, 80, 99, 90,"Frame")
//Gui.CreateItem()
REPEAT
//0=X - Geschwindigkeit
//1=Y - Geschwindigkeit
//2=Rad (1 auf, -1 ab)
//3=linke Maustaste
//4=rechte Maustaste
//5=mittlere Maustaste
LOCAL wheel=MOUSEAXIS(2)
LOCAL bm=MOUSEAXIS(5)
LOCAL mx,my,b1,b2
MOUSESTATE mx,my,b1,b2
LOCAL keyasc$ = INKEY$( )
LOCAL keycode = KEY(1) //ESC
Gui.Update(mx,my,b1,b2,bm,wheel,keyasc$) //Keys & Mouse
Gui.Draw()
SHOWSCREEN
UNTIL FALSE
ENDFUNCTION
Und das GUI Modul wo ich grad dran bin
// --------------------------------- //
// Project: MRGUI
// Start: Thursday, April 19, 2012
// IDE Version: 10.283
TYPE TGui
x1
y1
x2
y2
text$
valuei
valuef#
enabled
visible
focus
SubList[] AS TGui
FUNCTION Add: x1,y1,x2,y2,text$
LOCAL G AS TGui
G_ProcentToReal( x1,y1 , x1,y1 )
G_ProcentToReal( x2,y2 , x2,y2 )
G.x1=x1
G.y1=y1
G.x2=x2
G.y2=y2
G.text$=text$
G.valuei=0
G.valuef#=0.0
G.enabled=TRUE
G.visible=TRUE
G.focus=FALSE
DIMPUSH self.SubList[], G
ENDFUNCTION
FUNCTION Draw:
IF self.visible=TRUE
LOCAL w,h
w=(self.x2-self.x1)+1
h=(self.y2-self.y1)+1
LOCAL vx,vy,width,height
GETVIEWPORT vx,vy,width,height //merken
VIEWPORT self.x1,self.y1,w,h
DRAWRECT 0,0,w,h,RGB(0,0,64) //Hintergrund
//Rahmen
DRAWLINE 0,0,w-1,0,RGB(255,255,255) //Oben
DRAWLINE 0,0,0,h-1,RGB(255,255,255) //Links
DRAWLINE 0,h-1,w-1,h-1,RGB(128,128,128) //Unten
DRAWLINE w-1,0,w-1,h-1,RGB(255,255,255) //Rechts
PRINT self.text$,0,0 //BitmapFont
VIEWPORT vx,vy,width,height //wieder herstellen
//----------------------------------------------- Unterliste
LOCAL G AS TGui
FOREACH G IN SubList[]
G.Draw()
NEXT
ENDIF
ENDFUNCTION //Draw
FUNCTION Update: mx,my,b1,b2,bm,wheel,keyasc$
//...
//Wenn sichtbar und enabled und Focus bei Textbox den Text verändern
//untere aufrufen
LOCAL G AS TGui
FOREACH G IN SubList[]
G.Update(mx,my,b1,b2,bm,wheel,keyasc$)
NEXT
ENDFUNCTION //Uodate
FUNCTION CreateWindow: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateLabel: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateButton: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateSlider: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateList: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION G_CreateCheckbox: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateOption: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateFrame: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
FUNCTION CreateItem: x1,y1,x2,y2,text$
Add(x1,y1,x2,y2,text$)
ENDFUNCTION
ENDTYPE //Gui
FUNCTION G_ProcentToReal: px#,py#,BYREF x,BYREF y
LOCAL vx,vy,width,height
GETVIEWPORT vx,vy,width,height
px=px/100.0
py=py/100.0
x=px*width
y=py*height
//DEBUG "px " + px + " py " +py +" x " + x + " y " +y +"\n"
ENDFUNCTION
Huh?
Ich bin mir sicher, dass das mal ging! Oo
EDIT: Der Fehler liegt auf jeden Fall nicht an der Deklaration...
Also das hier geht bei mir ... Ich verstehs auch gerad nicht :D
TYPE TTest
test AS TTest
tests[] AS TTest
ENDTYPE
Bei mir kommt mit deinem Beispiel beim compilieren
*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.9.829 SN:471f0175 - 2D, WIN32
"Test.gbas"(1) error : type member is defined recursively : test
Haste auch den gleichen gcc Compiler ???
GLBasic IDE, Version: 10.283
GLBasic SDK - Editor
Copyright ©2011 Dream Design Entertainment Software
Webpage: www.glbasic.com
Contains gcc versions: 3.4.2, 3.3.3, 4.0.1, 4.0.2 which are Copyright ©2007 Free Software Foundation, and licensed under the GPL.
See www.glbasic.com/main.php?site=gcc for more info.
Jo habe denselben... Ich glaube eher das lag daran, dass ich deinen Type darunter hatte...
Gernot?
Edit:
Hm ,für Windows gibt es wohl nur MinGW und da hab ich nur die gefunden
mingw-get-inst-20111118.exe
Aber an den GLBasic\Compiler Unterordner möchte ich nicht dran rumfummeln.
Der scheint dort von 2008 zu sein.
:help:
Würde ich dir auch raten, das nicht zu tun. :P
Plan B geht auch nicht , kommt auch ...
*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.9.829 SN:471f0175 - 2D, WIN32
"Test.gbas"(2) error : type member is defined recursively : Listx
TYPE TList
a=0
Listx[] AS TTest
b=0
FUNCTION Add:A AS TTest
DIMPUSH self.Listx[],A
ENDFUNCTION
ENDTYPE
TYPE TTest
x
y
Listy AS TList
FUNCTION Add: a AS TTest
self.Listy.Add(a)
ENDFUNCTION
ENDTYPE
TYPE Bla
X;Y;Z
ID
//usw
FUNCTION Add:
DIMPUSH Blub[], self
ENDFUNCTION
ENDTYPE
GLOBAL Blub[] AS Bla
So würde ich es machen... Ausm Bauch raus!
Ich brauche aber eine Struktur mit einer Liste welche die gleiche Struktur merken kann.
Ist wichtig für das GUI was ich grad mache.
Als Beispiel, wenn das Fenster unsichtbar ist braucht man den rest drunter nicht malen.
Wäre eine Liste unsichtbar,braucht mal die Items nicht malen.
Wenn ich das Fenster verschiebe kann ich alle Unterdinger mit verschieben.
Wenn eine Liste aus geschaltet ist sind es die unter Items quasi auch.
Vieleicht macht der Vorkompiler aus dem Basic komischen C Quelltext das der dann nicht verstanden wird oder der Compiler hat ein Bug.
EDIT: Ich nehme jetzt eine gesamt Liste das ich weiter komme
Habe die Hirachie über eine Connect Liste gemacht.
Ich weiß es sieht noch häßlich aus aber es wird :-)
Das mit dem Viewport im Viewport wird noch ein gezauber aber ich weiß was ich will 8)
Die Pos. der Steuerelemente habe ich in % angegeben und umgerechnet, damit kann man viel einfacher eine Maske aufbauen.
[attachment deleted by admin]
Rekursive Typedeklaration geht nicht und ging nach meiner Kenntnis auch nie. Backsliders Beispiel geht bei mir auch nicht, kA, warum es bei ihm gehen soll...
Connected Liste ist der beste Weg zum das zu erledigen.
Kurze Erklärung, warum es gar nicht gehen kann:
In BB z.B. geht es, jedoch müssen neue Instanzen eines Types dort immer mir einem NEW Operator deklariert werden, bevor man sie nutzen kann, Beispiel in Pseudo-Code, Übertragung von BB auf GLB:
TYPE Ta
t as Ta
i
ENDTYPE
b as Ta
NEW b
b.i=3
// zum nutzen von b.t wird ein weiteres NEW benötigt:
NEW b.t
// für jede weitere Instanz ebenfalls...
NEW b.t.t...
In GLB wird ein solcher NEW Operator nicht benötigt (genauer: existiert nicht), da hier ein Type immer vollständig deklariert wird, sobald eine Variable deklariert wird:
TYPE Ta
i
ENDTYPE
b as Ta
b.i=3
Ein Type wird immer vollständig deklariert, inklusive aller Untertypes!:
TYPE Tb
i
a as Ta
ENDTYPE
c AS Tb
c.i=3
c.a.i=5
Hatte man jetzt einen rekursiven Type, dann hätte man automatisch unendlich viele Types dieses Types, schließlich führt die Deklaration dieses Types dazu, dass eine weitere Instanz deklariert werden muss, dies führt dazu, dass eine weitere Instanz deklariert werden muss, dies führt dazu, dass eine weitere Instanz deklariert werden muss, dies...
Ich denke, du siehst das Problem. ;)
Für sowas nimmt man sich normalerweise eine Manager-Klasse oder sowa in der Art.
Angenommen es gibt etliche GUI-Komponenten wie Textfeld, Eingabefeld, Listbox etc.
Diese könnte man in einen eigenen Typ (oder mehrere nach Bedarf) stecken
TYPE TGuiElement
name$
...
ENDTYPE
Ein Dialog wiederum kann 1..n Gui-Komponenten enthalten also z.B. so
TYPE TDialog
....
GuiElements as TGuiElement[]
....
ENDTYPE
im ganzen Programm kann man ja 1..n Dialog nutzen, wo man z.B. auch das Hauptfenster als Dialog betrachten könnte. Alle Dialog könnte man in einem GUI-Manager verwalten
z.B.
TYPE TGuiManager
...
dialogs as TDialog[]
....
ENDTYPE
Richtiges OOP haben wir ja leider/Gott sei Dank (je nach Standpunkt) in GLBasic nicht, aber mit dieser Art der Komposition könnte man es ggfs. auch lösen, denke ich.
Außer dass du vielleicht:
//statt
GuiElements as TGuiElement[]
//lieber
GuiElements[] as TGuiElement
schreiben solltest. :)
Oder geht's auch andersrum? :blink:
ups ja, hast recht, habs nur einfach so hingeschrieben ohne Editor :)
Was ich wollte war doch nur eine Struktur mit einem leeren Array was dann Pointer sammelt.
Beim erzeugen einer Variable mit diesem Typ passiert doch sonst weiter gar nix.
Da gibt es doch noch gar keine Rekursion.
Vieleicht hab ich auch grad nur ein Pin im Kopf aber ich bin überzeugt das ich das nicht falsch gemacht habe.
@Quentin
TGuiElement möchte aber TGuiElemente haben
Dein Beispiel hat ja nur 3 Ebenen.
so ganz kann ich dir nicht folgen. Worauf genau willst du hinaus.
In deinem Beispiel hast du eine rekursive Definition. Dem könnte man in deinem Beispiel nur dadurch entgehen, wenn man das Array mit den GUI-Elementen als statisch im Sinne von statischen C++-Klassenmembern definiert, was so in GLBasic imho nicht möglich ist.
Ausserdem bezweifle ich, dass der Eierlegende-Woll-Milch-Sau-TYPE wirklich sinnvoll ist.
@Quentin
irgendwie fehlt mir dann eine Listen Klasse die alles aufnehmen kann.
Type TName
A=0
S as List
EndType
Local A as TName
Local B as TName
A.S.Add(B)
[attachment deleted by admin]
ähh genau das kannst du doch damit machen?
Hier mal ein Beispiel:
// GUI-Elemente, z.B. Label, Eingabefeld, pushbutton
TYPE TGuiElement
x%
y%
name$
content$
ENDTYPE
// Ein Dialog kann 1..n Gui-Elemente enthalten
TYPE TDialog
x%
y%
name$
items[] AS TGuiElement
ENDTYPE
// für das Hauptprogram benötigt man einen "GUI-Manager"
TYPE TGuiManager
dialogs[] AS TDialog
ENDTYPE
// jetzt mal ein paar GUI-Elemnte anlegne
LOCAL label AS TGuiElement
LOCAL inputfield AS TGuiElement
LOCAL checkbox AS TGuiElement
label.x = 0
label.y = 0
label.name$ = "LABEL"
label.content$ = "Eingabe:"
inputfield.x = 10
inputfield.y = 0
inputfield.name$ = "INPUTFIELD"
inputfield.content$ = ""
checkbox.x = 0
checkbox.y = 10
checkbox.name$ = "CHECKBOX"
checkbox.content$ = "X"
// diese packen wir in einen Dialog
LOCAL dialog AS TDialog
dialog.x = 0
dialog.y = 0
dialog.name$ = "DIALOG"
DIMPUSH dialog.items[], label
DIMPUSH dialog.items[], inputfield
DIMPUSH dialog.items[], checkbox
//... ggfs. weitere Dialog
// alle Dialog packen wir in unseren "Gui-Manager"
LOCAL guimgr AS TGuiManager
DIMPUSH guimgr.dialogs[], dialog
LOCAL y
WHILE TRUE
FOREACH dia IN guimgr.dialogs[]
y = 0
FOREACH item IN dia.items[]
PRINT item.name$, 0, y
PRINT item.content$, 100, y
INC y, 20
NEXT
NEXT
SHOWSCREEN
WEND
Nein. Ein Member eines Types darf keinen Member seines Parents haben. Das wäre rekursiv und geht nicht.
Mach eine Liste von Ta in Tb und pack die da rein. Baumstruktur geht nur über den Umweg einer Indexliste.
@Quentin
also so meinte ich das,das es eine Hirachie gibt. Also ich kann ein Fenster auch in eine Textbox tun wenn ich möchte.
Was ich gemacht habe ist ein Universal Element was sich nur anders malt/darstellt.
Type TElement
A=0
L as List
EndType
Local A as TElement
Local B as TElement
Local C as TElement
Local D as TElement
Local E as TElement
A.L.Add(B)
B.L.Add(C)
C.L.Add(D)
D.L.Add(E)
[attachment deleted by admin]
Great point 'kanonet' about the 'New' keyword missing from GLBasic, therefore recursive TYPEs can never be allowed!
Never thought about it that way!
This is a problem as long as a TYPE instance automatically reserves memory for each of its members.
But, as others have been mentioning, you don't need recursive TYPEs.
Use the 'id', 'id_parent' concept, and you are good to go.
TYPE TGui
id%
id_parent%
x%, y%
frames[] AS TGuiFrame
buttons[] AS TGuiButton
FUNCTION Set: x, y, parent_id%=-1
self.id = GetNextId()
self.id_parent = parent_id
self.x = x
self.y = y
DIM self.frames[0]
DIM self.buttons[0]
ENDFUNCTION
FUNCTION AddFrame%: x, y
LOCAL frame AS TGuiFrame
frame.Set(x, y, self.id)
DIMPUSH self.frames[], frame
RETURN frame.id
ENDFUNCTION
FUNCTION AddButton%: x, y
LOCAL button AS TGuiButton
buttonSet(x, y, self.id)
DIMPUSH self.buttons[], button
RETURN button.id
ENDFUNCTION
ENDTYPE
TYPE TGuiFrame
id%
id_parent%
x%, y%
FUNCTION Set: x, y, parent_id%=-1
self.id = GetNextId()
self.id_parent = parent_id
self.x = x
self.y = y
ENDFUNCTION
ENDTYPE
TYPE TGuiButton
id%
id_parent%
x%, y%
FUNCTION Set: x, y, parent_id%=-1
self.id = GetNextId()
self.id_parent = parent_id
self.x = x
self.y = y
ENDFUNCTION
ENDTYPE
FUNCTION GetNextId%: is_reset%=FALSE
STATIC id%=0
IF is_reset THEN id=0
INC id
RETURN id
ENDFUNCTION
This way you can have window hierarchies too.
One window can be the parent of another window.
One control can have a parent that is NOT a window, but another control.
LOCAL gui1 AS TGui
LOCAL gui2 AS TGui
gui1.Set(10, 10) // id=1 (from GetNextId), id_parent=-1 since not specified - Top Level
gui2.Set(20, 20, gui1.id) // id=2, id_parent=1 - Child of gui1
frame_id = gui1.AddFrame(30, 30) // id=3
gui1.AddButton(10, 10, frame_id) // id=4, id_parent=3 - Button is a child of a Frame
Not exactly as written, but the concept is there.
@Kitty Hello
ja, hab das anders gelöst, mir fehlt einfach eine Liste wo ich alles rein werfen kann und die ich eben so mir ForEach durch laufen kann.
BlitzMax hat sowas.
@Slydog
yes i used a parend/child list now (but without id^^)
Main Test
// --------------------------------- //
// Project: MRGUI
// Start: Thursday, April 19, 2012
// MR 19.04.2012
// IDE Version: 10.283
MainLoop()
END
FUNCTION MainLoop:
SYSTEMPOINTER TRUE
LOCAL Gui AS TConnect
LOCAL G AS TGui
LOCAL sp=1
LOCAL y=0
G_CreateBG()
LOCAL Begin AS TGui
LOCAL Window AS TGui=G.CreateWindow (0, 0,100,100,"Dialog");y=y+5+sp
Gui.Add(Begin,Window)
G=G.CreateLabel(1, y, 99, y+5,"Spielstände");y=y+5+sp
Gui.Add(Window,G)
LOCAL List1 AS TGui=G.CreateList (1, y, 93, y+5*4,"List")
Gui.Add(Window,List1)
LOCAL Slider2 AS TGui=G.CreateSlider (94, y, 99, y+5*4,"SliderY")
Gui.Add(Window,Slider2)
y=y+5*4+sp
LOCAL Slider1 AS TGui=G.CreateSlider (1, y, 93, y+5,"SliderX");y=y+5+sp
Gui.Add(Window,Slider1)
LOCAL i
LOCAL ty=List1.py1-2.5
FOR i=0 TO 5
G=G.CreateOption(List1.px1+1 ,ty ,List1.px1+ 19,ty+5,i)
IF i=1 THEN G.valuei=1
Gui.Add(List1,G)
G=G.CreateLabel(List1.px1+20 ,ty ,List1.px1+ 79,ty+5,"Level "+i+" - 19.04.12 1"+i+":15")
Gui.Add(List1,G)
G=G.CreateButton(List1.px1+80 ,ty ,List1.px1+ 90,ty+5,"X")
Gui.Add(List1,G)
ty=ty+6
NEXT
LOCAL Button2 AS TGui=G.CreateButton (1, y, 50, y+5,"Laden")
Gui.Add(Window,Button2)
LOCAL Button1 AS TGui=G.CreateButton (51, y, 99, y+5,"Speichern als");y=y+5+sp
Gui.Add(Window,Button1)
G=G.CreateTextbox (51, y, 99, y+5,"Level 3 - 21.04.2012 15:35");y=y+5+sp
G.focus=1
Gui.Add(Window,G)
;y=y+5+sp
G=G.CreateLabel(1, y, 99, y+5,"Einstellungen");y=y+5+sp
Gui.Add(Window,G)
LOCAL Frame1 AS TGui=G.CreateFrame (1, y, 50, y+5*5,"Schwierigkeitsgrad")
Gui.Add(Window,Frame1)
G=G.CreateOption (1+1,y+ 5, 49,y+ 5+5,"Einfach")
G.valuei=1
Gui.Add(Frame1,G)
G=G.CreateOption (1+1,y+ 5+5+1, 49,y+ 5+5+1+5,"Normal")
Gui.Add(Frame1,G)
G=G.CreateOption (1+1,y+ 5+5+1+5+1, 49,y+ 5+5+1+5+5+1,"Schwer")
G.enabled=FALSE
Gui.Add(Frame1,G)
LOCAL Frame2 AS TGui=G.CreateFrame (51, y, 99, y+5*5,"Akustik")
Gui.Add(Window,Frame2)
G=G.CreateCheckbox(51+1, y+5, 99-1, y+5+5,"Töne")
G.valuei=1
Gui.Add(Frame2,G)
G=G.CreateCheckbox(51+1, y+5+5+1, 99-1, y+5+5+5+1,"Musik")
G.valuei=1
Gui.Add(Frame2,G)
y=y+5*5+sp
DEBUG "Connect Einträge=" + BOUNDS(G_HierarchyList[],0) +"\n"
REPEAT
//0=X - Geschwindigkeit
//1=Y - Geschwindigkeit
//2=Rad (1 auf, -1 ab)
//3=linke Maustaste
//4=rechte Maustaste
//5=mittlere Maustaste
LOCAL wheel=MOUSEAXIS(2)
LOCAL bm=MOUSEAXIS(5)
LOCAL mx,my,b1,b2
MOUSESTATE mx,my,b1,b2
LOCAL keyasc$ = INKEY$( )
LOCAL keycode = KEY(1) //ESC
LOCAL vx,vy,width,height
Gui.Draw(Begin)
//Gui.Update(mx,my,b1,b2,bm,wheel,keyasc$) //Keys & Mouse
SHOWSCREEN
UNTIL FALSE
ENDFUNCTION
GUI
// --------------------------------- //
// Project: MRGUI
// Start: Thursday, April 19, 2012
// MR 19.04.2012
// IDE Version: 10.283
//For a Combobox use a Button and a List
CONSTANT G_Window =1
CONSTANT G_Label =2
CONSTANT G_Button =3
CONSTANT G_Slider =4
CONSTANT G_List =5
CONSTANT G_Checkbox =6
CONSTANT G_Option =7
CONSTANT G_Frame =8
CONSTANT G_Textbox =9
CONSTANT bgsprite1=101
CONSTANT bgsprite2=102
CONSTANT bgsprite3=103
TYPE TConnect
Parent AS TGui
Child AS TGui
FUNCTION Add:ParentX AS TGui,ChildX AS TGui
self.Parent=ParentX
self.Child=ChildX
DIMPUSH G_HierarchyList[],self
ENDFUNCTION
FUNCTION Draw:Parent AS TGui
//DEBUG Parent.text$ + "\n"
LOCAL vx,vy,width,height
GETVIEWPORT vx,vy,width,height //merken
Parent.Draw()
LOCAL w,h
LOCAL C AS TConnect
FOREACH C IN G_HierarchyList[]
IF C.Parent = Parent
Parent.ChangeViewPort(w,h)
C.Draw(C.Child)
ENDIF
NEXT
VIEWPORT vx,vy,width,height //wieder herstellen
ENDFUNCTION
ENDTYPE
GLOBAL G_HierarchyList[] AS TConnect
TYPE TGui
typ //label,textbox,...
px1 // % 0 bis 100 = breite
py1
px2
py2
x1
y1
x2
y2
text$
valuei //bei Textbox Cursor Pos.
valuefx# //bei Slider -1 bis 1
valuefy#
enabled
visible
focus //bei Eingabe
//SubList[] AS TGui <<< geht nicht ^^
FUNCTION Init: typ , x1 , y1 , x2 , y2 , text$
self.px1=x1
self.py1=y1
self.px2=x2
self.py2=y2
G_ProcentToReal( x1,y1 , x1,y1 )
G_ProcentToReal( x2,y2 , x2,y2 )
self.typ=typ
self.x1=x1
self.y1=y1
self.x2=x2
self.y2=y2
self.text$=text$
self.valuei=0
self.valuefx#=0.0
self.valuefy#=0.0
self.enabled=TRUE
self.visible=TRUE
self.focus=FALSE
ENDFUNCTION
FUNCTION ChangeViewPort: BYREF w,BYREF h
LOCAL x,y
x=self.x1
y=self.y1
w=(self.x2-self.x1)+1
h=(self.y2-self.y1)+1
IF self.y1=0 AND self.y2=0
VIEWPORT 0,0,-1,-1
ELSE
VIEWPORT x,y,w,h
ENDIF
ENDFUNCTION
FUNCTION TextWidth: tx$
LOCAL sx,sy
GETFONTSIZE sx,sy
RETURN sx*LEN(tx$)
ENDFUNCTION
FUNCTION TextHeight:
LOCAL sx,sy
GETFONTSIZE sx,sy
RETURN sy
ENDFUNCTION
FUNCTION Draw:
IF self.visible=TRUE
LOCAL vx,vy,width,height
GETVIEWPORT vx,vy,width,height //merken Element drüber
IF self.x1<vx THEN RETURN
IF self.x2>vx+width THEN RETURN
IF self.y1<vy THEN RETURN
IF self.y2>vy+height THEN RETURN
LOCAL w,h
ChangeViewPort(w,h)
LOCAL bgcolor=RGB(0,0,64)
IF self.enabled=FALSE
STRETCHSPRITE bgsprite3, 0, 0, w, h //AUS
ELSEIF self.focus<>0
STRETCHSPRITE bgsprite2, 0, 0, w, h //AN mit Focus
ELSE
STRETCHSPRITE bgsprite1, 0, 0, w, h //AN Normal
ENDIF
//Rahmen
LOCAL ColorL
LOCAL ColorD
IF self.focus
ColorL=RGB(0,0,64)
ColorD=RGB(255,255,255)
ELSE
ColorL=RGB(255,255,255)
ColorD=RGB(0,0,64)
ENDIF
IF self.typ=G_Label
ELSE
DRAWLINE 0,0,w-1,0,ColorL //Oben
DRAWLINE 0,0,0,h-1,ColorL //Links
DRAWLINE 0,h-1,w-1,h-1,ColorD //Unten
DRAWLINE w-1,0,w-1,h-1,ColorD //Rechts
ENDIF
LOCAL tx=0
LOCAL ty=0
IF self.typ=G_Window OR self.typ=G_Frame OR self.typ=G_Label OR self.typ=G_Checkbox OR self.typ=G_Option OR self.typ=G_Button OR self.typ=G_Textbox
tx=w/2-TextWidth(self.text$)/2 //Mitte
ENDIF
IF self.typ=G_Window OR self.typ=G_Frame
//die nicht
ELSE
ty=h/2-TextHeight()/2
ENDIF
IF self.typ=G_Slider
//dient nur zum rumgeklicke
//Kugel Malen
//x = -1 bis 1
//y = -1 bis 1
//valuefx#
//valuefy#
PRINT "+",w/2-TextWidth("+")/2,h/2-TextHeight()/2
ELSEIF self.typ=G_List
//Liste hat kein Text , nur Inhalt
ELSE
PRINT self.text$,tx,ty //BitmapFont
ENDIF
IF self.typ=G_Checkbox AND self.valuei<>0 THEN PRINT " +",0,ty //BitmapFont
IF self.typ=G_Option AND self.valuei<>0 THEN PRINT " +",0,ty //BitmapFont
IF self.typ=G_Textbox AND self.valuei<>0 THEN PRINT " +",0,ty //BitmapFont
ENDIF //Sichtbar
ENDFUNCTION //Draw
FUNCTION Update: mx,my,b1,b2,bm,wheel,keyasc$
//...
//Wenn sichtbar und enabled und Focus bei Textbox den Text verändern
ENDFUNCTION //Uodate
FUNCTION CreateWindow AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Window,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateLabel AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Label,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateTextbox AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Textbox,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateButton AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Button,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateSlider AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Slider,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateList AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_List,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateCheckbox AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Checkbox,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateOption AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Option,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
FUNCTION CreateFrame AS TGui: x1,y1,x2,y2,text$
LOCAL G AS TGui
G.Init(G_Frame,x1,y1,x2,y2,text$)
RETURN G
ENDFUNCTION
ENDTYPE //Gui
FUNCTION G_ProcentToReal: px#,py#,BYREF x,BYREF y
LOCAL vx,vy,width,height
GETVIEWPORT vx,vy,width,height
px=px/100.0
py=py/100.0
LOCAL m = MIN(width,height)
x=px*width //m
y=py*height //m
//DEBUG "px " + px + " py " +py +" x " + x + " y " +y +"\n"
ENDFUNCTION
FUNCTION G_CreateBG:
LOCAL vx,vy,width,height
GETVIEWPORT vx,vy,width,height //merken Element drüber
LOCAL width=32,h=32
CREATESCREEN 0, bgsprite1, width, h
USESCREEN 0
LOCAL ly#,mu#,r,g,b
FOR ly=0 TO h-1
mu#=ly / (h-1)
r=Intp( 64.0 , 255.0 ,mu)
g=Intp( 64.0 , 255.0 ,mu)
b=Intp(128.0 ,255.0 ,mu)
DRAWLINE 0,ly,width-1,ly,RGB(r,g,b)
NEXT
CREATESCREEN 0, bgsprite2, width, h
USESCREEN 0
FOR ly=0 TO h-1
mu#=ly / (h-1)
r=Intp(255.0 , 64.0 ,mu)
g=Intp(255.0 , 64.0 ,mu)
b=Intp(255.0 ,128.0 ,mu)
DRAWLINE 0,ly,width-1,ly,RGB(r,g,b)
NEXT
CREATESCREEN 0, bgsprite3, width, h
USESCREEN 0
LOCAL ly#,mu#,r,g,b
FOR ly=0 TO h-1
mu#=ly / (h-1)
r=Intp( 0.0 , 128.0 ,mu)
g=Intp( 0.0 , 128.0 ,mu)
b=Intp( 0.0 , 128.0 ,mu)
DRAWLINE 0,ly,width-1,ly,RGB(r,g,b)
NEXT
USESCREEN -1
ENDFUNCTION
//Interpolation A to B
FUNCTION Intp#: a#,b#,mu# //mu = 0.0 bis 1.0
RETURN a+(b-a)*mu
ENDFUNCTION