Fehler in OOP Konstrukt...

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

DamienX

Betreff: Fehler in OOP Konstrukt...

BeitragFr, Jul 20, 2007 8:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo!

Ich habe um mich in die OOP einzuarbeiten ein sehr kleines Gui Programm geschrieben. Kam eigentlich ganz gut klar (zumindest dachte ich das) bis ich auf die (längst überfällige) idee kam ein zweites Fenster zu erstellen um zu testen ob sich das Programm so verhält wie ich mir das vorgestellt hatte. Pustekuchen!

Das Problem ist das ich in einer statischen Methode "MouseOnObject()" ermitteln will ob sich die Maus über einem Object befindet damit ich danach mit "ObjectClicked()" auch prüfen kann ob ein "Object" gedrückt wurde.

Tja an sich dachte ich dass das kein Problem sein müsste nur... fragt die Funktion komischerweise genau dies nur bei den ersten erstellten Unterobject von "Object" ab was in diesem Fall das erste Fenster und die erste Guigrafik ist.

Ich gehe eigentlich die komplette Liste (ObjList) mit Objekten durch und hab da mal wieder n Brett vorm Kopf!

Muss euch leider den kompletten Code posten weil ich nicht weiß wo der fehler sein könnte und ihr braucht ihr 2 Grafiken um das Programm zu testen aber vllt schaut sich das ja trotzdem mal wer an.

Hier der Code:
Code: [AUSKLAPPEN]

SuperStrict
Const WIDTH:Int = 800, HEIGHT:Int  = 600, DEPTH:Int  = 0
Graphics WIDTH,HEIGHT,DEPTH
SetMaskColor (255,0,255)




'Test
'Local a:Window = Window.CreateWindow(100,20,100,100)
'Local b:Window = Window.CreateWindow(250,20,100,100)
'Local c:Window = Window.CreateWindow(100,250,100,100)

Local d:GuiGraphic = GuiGraphic.InsertGuiGraphic(0, 0, 100, 25,"media\skin1\top.bmp","SCALED","TOP")
Local e:GuiGraphic = GuiGraphic.InsertGuiGraphic(0 ,30 ,13 ,16 , "media\skin1\scale.bmp", "NONSCALED","SCALEBUTTON")


'************************** BASETYPE *********************************
Type Objects
Global ObjList:TList = New TList      'Liste für alle Objekt
Global mx:Int, my:Int               'Maus Koordinaten
Global Counter:Int                   'Counter (für späteres ID System)

   Field x : Int                  'Objekt Koordinaten
   Field y : Int
   
   Field width : Int               'Höhe Breite
   Field height :Int
   
   Field id:Int                  'Id variable


   '.Mausposition abfragen   
   Function MouseUpdate:Byte()
      mx = MouseX()
      my = MouseY()
   End Function


   '.Abfrage ob Maus auf Objects steht (!!!sollte alle Objects durchlaufen!!!)
   Function MouseOnObject:Int()
      For Local f:Objects = EachIn ObjList:TList
         If mx < f.x Return False
         If mx > f.x + f.width Return False
         If my > f.y + f.height Return False
         If my < f.y Return False
            Return True
      Next
   End Function

   'Abfrage ob Object geklickt wurde
   Function ObjectClicked:Int()
      If MouseOnObject:Int() = True
         If MouseHit (1) Or MouseDown (1)
            Return True
         Else
            Return False
         EndIf
      EndIf
   End Function
   
   
   
   '.Update Funktion    (Verbessrungswürdig aber funktioniert imo ^^)
   Function DrawObjects()
      For Local f:Window = EachIn ObjList:TList
         DrawRect (f.x:Int, f.y:Int, f.width:Int, f.height:Int)
      Next
      
      For Local f:GuiGraphic = EachIn ObjList:TList
         Select f.mode
            Case "NONSCALED"
            DrawImage (f.image:Timage, f.x, f.y)
            Case "SCALED"
            DrawImageRect (f.image:Timage, f.x:Int, f.y:Int, f.width:Int, f.height:Int)
         End Select      
      Next
   End Function
   
   
   'Ne kleine funktion zum Überprüfen der funktionen
   Function Debug()
      DrawRect 0,500,200,100
      SetColor 0,0,0
      DrawRect 1,501,198,98
      SetColor 255,255,255
      
      DrawText "Objekte: "+CountList(Objects.ObjList),10,510
      DrawText "Mouseposition: "+mx+","+my,10,520
      
      For Local f:Objects = EachIn ObjList:TList
         If MouseOnObject() = True
            DrawText "Maus auf Objekt!!",10,580
         
         EndIf
      Next
   End Function
   
End Type



'********************** Windowtype ***********************************
Type Window Extends Objects 'Fensterklasse
   Function CreateWindow:Window(x:Int, y:Int ,width:Int ,height:Int)
      Local a:Window = New Window
         a.x = x
         a.y = y
         a.width = width
         a.height = height
         
      ObjList.addlast(a)
      
      GuiGraphic.InsertGuiGraphic(a.x, a.y, a.width, 25,"media\skin1\top.bmp","SCALED","TOP") 'Fügt schon mal 2 Gui Grafiken ein
      GuiGraphic.InsertGuiGraphic(a.x+a.width-13 ,a.y+a.height-16 ,13 ,16 , "media\skin1\scale.bmp", "NONSCALED","SCALEBUTTON")
      
      Return a
   End Function
End Type



'********************* GUI-Graphics Type *************************
Type GuiGraphic Extends Objects
   Field image:Timage
   Field path:String
   
   Field mode:String
   Field func:String

   
   Function InsertGuiGraphic:GuiGraphic (x:Int, y:Int, width:Int, height:Int, path:String, mode:String, func:String)
      Local a:GuiGraphic = New GuiGraphic
         a.image = LoadImage(path:String)
         a.path = path
            If a.Image
               a.x = x
               a.y = y         
               a.width = width
               a.height = height
               a.mode = mode
               a.func = func
               
               ObjList.addlast(a)
            Else
               RuntimeError (" Konnte Grafik "+a.path+" nicht finden!")
            EndIf
      Return a
   End Function
End Type








'***************************** MAIN LOOP **********************************************************
While Not KeyDown (key_escape)
Objects.DrawObjects()
Objects.MouseUpdate()
Objects.MouseOnObject()

'*****************************
Objects.Debug()
Flip
Cls
Wend


Bin für jeden Tipp dankbar
Grüße Dx
Lets make things better...
 

Dreamora

BeitragFr, Jul 20, 2007 9:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem ist dein Konstrukt

Du gibst schon beim ersten Objekt zwingend true oder false zurück.

Was du machen müsstest ist durchgehen und innerhalb der Loop nur dann True zurück geben, wenn es über einem Objekt ist, sonst nichts.

Das Return False darfst du erst nach der For - Next nutzen.

Du hast da den Code genommen, den man normalerweise nutzt um zu prüfen ob man innerhalb eines bestimmten Rechteckes ist, nicht ob man über / in irgend einem ist, daher kommt das problem.


Oder ich sollte anders sagen: Was du da versuchst ist eigentlich falsch, denn bei MouseClicked willst du ja bestimmt wissen ob ein bestimmtes Objekt geklickt wird oder? nicht einfach irgend eines, denn das ist recht sinnfrei wenn du 20 hast ... weils eigentlich immer true sein dürfte und dir 0 funktionalität für ein bestimmtes Objekt erlaubt.


Beschäftige dich am besten noch ein wenig mehr mit OO und vor allem mit Method. Das sind sowas ähnliches wie Funktionen, der Unterschied ist, dass sie auf dem Objekt selbst ausgeführt werden, nicht auf der Klasse.

Damit könntest du eine Over:int() Methode machen, die sagt ob die Maus über diesem Objekt ist
Wenn du deine jetzige mit der Loop immer noch willst, kannst du dann einfach deine jetzige Loop nehmen und in die loop nur "if f.over() return true" packen und nach der loop ein return false.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragFr, Jul 20, 2007 13:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:

Du hast da den Code genommen, den man normalerweise nutzt um zu prüfen ob man innerhalb eines bestimmten Rechteckes ist, nicht ob man über / in irgend einem ist, daher kommt das problem.

Ich glaube das ist was ich im Moment nicht verstehe. Ich habe für die Funktion bewusst Function verwendet statt Method... weil ich ja eigentlich nicht wissen will ob ich auf ein bestimmtes Object zeige sondern eben bei alle relevanten Objekten abfragen will!

Zitat:

Oder ich sollte anders sagen: Was du da versuchst ist eigentlich falsch, denn bei MouseClicked willst du ja bestimmt wissen ob ein bestimmtes Objekt geklickt wird oder? nicht einfach irgend eines, denn das ist recht sinnfrei wenn du 20 hast ... weils eigentlich immer true sein dürfte und dir 0 funktionalität für ein bestimmtes Objekt erlaubt.

Meine Idee dahinter ist simpel ausgedrückt dass ich wissen will ob ein Object "geklickt" wird um danach die Funktion erweitern zu können und sie mir zurückgibt was gedrückt wurde. Dies ermittle ich über die Eigenschaft 'func' in welcher die Funktion des Objectes festgehalten wird um mit einem einfachen select..case Befehl diese dann umszusetzen. In diesem Beispiel ob es sich um ein Object der Klasse 'GuiGraphic' handelt und speziel welche Aufgabe diese Übernimmt.

Hier ein halbherziger Pseudocode der eigentlich die Steuerung der GuiGraphic Objecte übernehmen soll.
In diesem Fall Skalierung, Verschiebung etc. :
Code: [AUSKLAPPEN]

'Function zur Kontrolle der GUI Funktionen
Function Control:Int()
   For Local f:GuiGraphic = EachIn ObjList:TList   
      If ObjectClicked() = True
         Select f.func:String
            Case "TOP"
                        
            Case "SCALEBUTTON"
               
            Case "LEFTBORDER"
            
            Case "RIGHTBORDER"
         
            Case "LOWBORDER"
               
            Case "SYMBOL"
         End Select
      EndIf
   Next
End Function


Zitat:

Beschäftige dich am besten noch ein wenig mehr mit OO und vor allem mit Method. Das sind sowas ähnliches wie Funktionen, der Unterschied ist, dass sie auf dem Objekt selbst ausgeführt werden, nicht auf der Klasse.

Habe Jolinahs Tutorial durchgearbeitet (bevor die Frage kommt... ja wirklich durchgearbeitet sonst wär ich vermutlich nicht soweit gekommen Very Happy) und schon soweit verstanden was der unterschied zwischen statischen und nicht statischen Methoden ist. Anscheinend setze ich sie in diesem Beispiel nur falsch ein was übrigens auch schon mein Gedanke war.

Zitat:

Damit könntest du eine Over:int() Methode machen, die sagt ob die Maus über diesem Objekt ist
Wenn du deine jetzige mit der Loop immer noch willst, kannst du dann einfach deine jetzige Loop nehmen und in die loop nur "if f.over() return true" packen und nach der loop ein return false.

Ok aber wie ermittle ich in dieser Methode Over:Int() ob der mauszeiger auf einem Objekt steht ohne True oder False (Darf man in BMax von Bool sprechen?) zurückzugeben?

Nebenbei: Sollte man Funktionen die keinen wert zurückliefern bzw. nur einen Bool diese als Byte deklarieren oder sind Integer intern schneller?

Schon mal danke im vorraus!
Mit freundlichen Grüßen Dx

EDIT: Habs glaub ich hingekriegt... hab MouseOnObject zu ner Methode umgeschrieben und True oder false erst beim Klick zurückgeben lassen... aber du hast recht... muss mir den Ablauf nochmal durch den Kopf gehen lassen weil ich doch noch nicht ganz verstanden hab warum das so einen Unterschied macht!
Lets make things better...
 

Dreamora

BeitragFr, Jul 20, 2007 13:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Blitz hat keine Booleans, es gibt einfach Int zurück.

Wenn du jedoch True / False zurück gibst kannst du einfach mit If blabla.over() abfragen, das wird dann gleich behandelt als ob du "if blabla.over() = true" gemacht hättest.

Ich habe jetz aber Mal deinen Code genommen und so umstrukturiert, das er OO technisch dann auch genutzt werden kann, denn aktuell ist er ziemlich non-OO eigentlich und könnte in BlitzPlus umgesetzt werden.
Allerdings muss ich drauf hinweisen, dass die aktuelle Struktur sehr ineffizient ist weil sie immer alle Gadgets anspringt. Am besten baust du eine Hierarchie auf. Das heisst jedes Window speichert sich in einer Liste die Objekte die drin sind und zeichnet sie im eigenen zeichnungsaufruf anstatt das global zu machen.

Code: [AUSKLAPPEN]

Type Objects
   Global ObjList:TList = New TList      'Liste für alle Objekt
   Global mx:Int, my:Int               'Maus Koordinaten
   Global Counter:Int                   'Counter (für späteres ID System)

   Field x : Int                  'Objekt Koordinaten
   Field y : Int
   
   Field width : Int               'Höhe Breite
   Field height :Int
   
   Field id:Int                  'Id variable


   '.Mausposition abfragen
   ' Was nix zurück gibt braucht auch keinen Returntype :)
   Function MouseUpdate()
      mx = MouseX()
      my = MouseY()
   End Function

   Function MouseOnObject:Int()
      For Local f:Objects= EachIn ObjList:TList
         if f.Over()      return true
      Next
      return false
   End Function

   rem
      Gibt zurück, ob die Maus über diesem Objekt ist
   end rem
   Method Over:Int()
      If mx < x Return False
      If mx > x + f.width Return False
      If my > y + f.height Return False
      If my < y Return False
         
      Return True

   End Method

   'Abfrage ob Object geklickt wurde
   Method ObjectClicked:Int()
      If Over()
         If MouseDown (1)
            Return True
         Else
            Return False
         EndIf
      EndIf
   End Method
   
   
   
   '.Update Funktion    (Verbessrungswürdig aber funktioniert imo ^^)
   Function DrawObjects()
      For Local f:Objects= EachIn ObjList:TList
         f.draw()
      Next
   End Function
   
   ' Implementation davon in den abgeleiteten Klassen
   method Draw() abstract
   
   'Ne kleine funktion zum Überprüfen der funktionen
   Function Debug()
      DrawRect 0,500,200,100
      SetColor 0,0,0
      DrawRect 1,501,198,98
      SetColor 255,255,255
     
      DrawText "Objekte: "+CountList(Objects.ObjList),10,510
      DrawText "Mouseposition: "+mx+","+my,10,520
     
      rem
      Das macht so wenig sinn das du für alle objekte prüfst ob du über irgend einem objekt bist :)
      For Local f:Objects = EachIn ObjList:TList
         If MouseOnObject() = True
            DrawText "Maus auf Objekt!!",10,580
         
         EndIf
      Next
      end rem
     
      If MouseOnObject()
         DrawText "Maus auf Objekt!!",10,580
      EndIf
   End Function
   
End Type


'********************** Windowtype ***********************************
Type Window Extends Objects 'Fensterklasse
   Function CreateWindow:Window(x:Int, y:Int ,width:Int ,height:Int)
      Local a:Window = New Window
         a.x = x
         a.y = y
         a.width = width
         a.height = height
         
      ObjList.addlast(a)
     
      GuiGraphic.InsertGuiGraphic(a.x, a.y, a.width, 25,"media\skin1\top.bmp","SCALED","TOP") 'Fügt schon mal 2 Gui Grafiken ein
      GuiGraphic.InsertGuiGraphic(a.x+a.width-13 ,a.y+a.height-16 ,13 ,16 , "media\skin1\scale.bmp", "NONSCALED","SCALEBUTTON")
     
      Return a
   End Function

   Method Draw()
      DrawRect (x, y, width, height)
   End Method
End Type



'********************* GUI-Graphics Type *************************
Type GuiGraphic Extends Objects
   Field image:Timage
   Field path:String
   
   Field mode:String
   Field func:String

   
   Function InsertGuiGraphic:GuiGraphic (x:Int, y:Int, width:Int, height:Int, path:String, mode:String, func:String)
      Local a:GuiGraphic = New GuiGraphic
         a.image = LoadImage(path:String)
         a.path = path
            If a.Image
               a.x = x
               a.y = y         
               a.width = width
               a.height = height
               a.mode = mode
               a.func = func
               
               ObjList.addlast(a)
            Else
               RuntimeError (" Konnte Grafik "+a.path+" nicht finden!")
            EndIf
      Return a
   End Function

   Method Draw()
      Select mode
         Case "NONSCALED"
            DrawImage (image, x, y)

         Case "SCALED"
            DrawImageRect (image, x, y, width, height)
       End Select   
   End Method
End Type 
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragFr, Jul 20, 2007 14:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:

Am besten baust du eine Hierarchie auf. Das heisst jedes Window speichert sich in einer Liste die Objekte die drin sind und zeichnet sie im eigenen zeichnungsaufruf anstatt das global zu machen.


Du meinst für jedes Fenster eine eigene Liste wo das Fenster und die Grafiken drin liegen? Hört sich gut an.
Ich werd nochmal von vorne beginnen... Aber auf jedenfall vielen dank für deine Denkanstöße!
Lets make things better...
 

Dreamora

BeitragFr, Jul 20, 2007 15:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Was ich meinte, ist das sich jedes Fenster eine Liste speichert mit "Grafiken" etc die zu diesem Fenster gehören (buttons etc später nehm an)
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragSa, Jul 21, 2007 19:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok ich glaube ich habe verstanden worauf du raus willst... zumindest weitgehend!

Jetzt stellt sich mir ein neues Problem das ich in meinem andern Konstrukt auch schon versucht habe zu umgehen! Hab der Windowklasse nun eine Eigenschaft hinzugefügt "GagdetList" in der alle Grafiken usw. für dieses Window abgelegt werden sollen... Nur kann ich natürlich auf diese Liste nicht aus einer anderen Klasse zugreifen und nun frage ich wie das geht bzw. ob das überhaupt geht. Eigentlich kennt in dem Fall "Gfx" die Eigenschaft einer abgeleiteten Klasse ja nicht... oder is mein Konstrukt wieder nich optimal Very Happy ?

Hier wieder der Codeausschnitt:
Code: [AUSKLAPPEN]
Type Objects
Global WindowList:TList = New TList

   Field x:Int
   Field y:Int
   Field width:Int
   Field height:Int
   
   Method Draw() Abstract
   
   Function Control()
      For Local f:Objects = EachIn WindowList:TList
         f.Draw()
      Next
   End Function
End Type


Type Window Extends Objects
   Field GadgetList:TList

   Function CreateWindow:window(x:Int ,y:Int ,width:Int ,height:Int)
      Local w:window = New window
      Local GadgetList:TList = New TList
      w.x = x
      w.y = y
      w.width = width
      w.height = height   
      
      WindowList.addlast(w)
      
      
      
      Return w
   End Function

   Method Draw()
      DrawRect(x,y,width,height)
   End Method
End Type




Type Gfx Extends Objects
   Field image:Timage
   Field path:String
   
   Function InsertGfx:Gfx(x:Int ,y:Int ,width:Int ,height:Int ,path:String)
      Local a:gfx = New gfx
      a.path = path
      a.image:Timage = LoadImage (a.path)
      
      If a.image      
         a.x = x
         a.y = y
         a.width = width
         a.height = height
         
         'Test
         Window.GadgetList.addlast(a) 'Funktioniert nicht (wie kann ich eine Eigenschaft einer anderen Klasse ansprechen???)
      Return a
         
         
      Else
         RuntimeError(" Konnte Grafik "+a.path+" nicht finden")
      EndIf
   End Function
   
   
   Method Draw()   
      DrawImageRect(image, x, y, width, height)         
   End Method
End Type



'Testscript
Local a:Window = Window.CreateWindow(10,10,100,100)


Gibts ne Möglichkeit oder muss ich die Klassen Window und Gfx veschachteln?
Danke schon mal im vorraus!
Lets make things better...
 

Dreamora

BeitragSo, Jul 22, 2007 19:42
Antworten mit Zitat
Benutzer-Profile anzeigen
1. Globals existieren in allen klassen und abgeleiteten klassen
2. Du kannst auch von aussen auf globals in Types zugreifen. Typename.Globalname Smile
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragMo, Jul 23, 2007 16:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Wow so einfach.. danke Very Happy
Lets make things better...
 

Dreamora

BeitragMo, Jul 23, 2007 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Kein Problem

Und da ich wegen deiner Fragen vermute, dass du nicht weisst wie du auf Methoden einer übergeordneten Klasse zugreifen kannst:

Mit Self. greifst du auf fields / methoden des aktuellen Objektes zu
Mit Super. greifst du auf fields / methoden der übergeordneten klasse zu von welcher du extended hast.

speziell bei field wichtig! denn wenn du in einer extended klass ein field mit dem gleichen namen hast wie in der original, dann hast du danach 2 mal dieses field! einmal bei der original und einmal bei der extended ...
ist ein mächtiges, aber anfangs meist höchst verwirrendes feature!
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragFr, Jul 27, 2007 1:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Gut das ist schon mal sehr hilfreich Smile

Aber zum Thema 2 gleiche Fields in nem OOP Konstrukt:
Im Optimalfall sollte so etwas nicht passieren oder? Wenn ich ein Programm OO programmieren will, will ich doch die eigenschaften weiter vererben und nicht doppelt belegen oder liege ich da falsch?
Lets make things better...
  • Zuletzt bearbeitet von DamienX am Fr, Jul 27, 2007 3:53, insgesamt einmal bearbeitet

mahe

BeitragFr, Jul 27, 2007 2:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Es kann Sinn machen einzelne Methoden zu ersetzen wenn ein Konstrukt als "Vorlage" für verschiedene andere verwendet wird.
Für doppelte Fields fällt mir jetzt allerdings keine Verwendung ein ...
ʇɹǝıdɯnɹɹoʞ ɹnʇɐuƃıs - ǝpoɥʇǝɯ-ɹoɹɹıɯ ɹǝp uı ,ɹoɹɹǝ,
 

Dreamora

BeitragFr, Jul 27, 2007 9:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei Methoden gibt es keine doppelten, die werden ersetzt beim extended Objekt.


Bei den Fields kann es Sinn machen, wenn man:

1. aus irgend einem Grund den Type ändern muss
2. Aus irgend einem Grund in der aktuellen Klasse eine eigenständige Form des Fields braucht.


Das schöne daran ist, dass man auch in der erweiterten Klasse auf beide Fields zugreifen kann via Super.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragFr, Jul 27, 2007 10:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Am meisten Kopfzerbrechen bereitet mir das Zuordnen der Steuerelemente (also Skalierbutton etc.) zu den richtigen Windows. Versuche gerade mir mein eigenes id-System zusammenzuschustern aber so recht will das noch nicht klappen. Mein Hauptproblem liegt leider Gottes am Zugriff auf diverse Eigenschaften die in einer Klasse nicht spezifisch definiert sind.

Hab mein Konstrukt mitlerweile 3 mal umgeworfen und neu begonnen. Zwar immer mit kleinen Schönheitskorrekturen aber letztlich scheitert es immer an der Zuweisung (ich glaube in der GUI-Programmierung nennt man es Parent-Gadget Beziehung) wie oben genannt.

Ich würd mir zutrauen die sache einfach non OOP zu meistern (zumindest für meine Anforderungen) aber das ist nicht mein Ziel. Mein Ziel ist es die Klassen so aufzuteilen dass sie einfach zu überarbeiten und zu erweitern sind.

Ich will mal versuchen zu erklären was ich nun eigentlich vor habe....

Ich gehe bei allen was ich in dem GUI haben will vom Basetype TObject aus. Das heisst alles was irgendwie
eine Funktion haben soll wird vom Basetype abgeleitet und ich definiere in diesem schon mal Eigenschaften wie Koordinaten,Höhe und Breite.
Im Moment will ich genau 2 Elementare Sachen realiesieren um das Grundgerüst aufstellen zu können:

1. Ein Klasse für die Fenster (TWindow) und
2. Ein Klasse für die Grafiken oder auch "Steuerelemente" die das Fenster Skalieren bzw verschieben.

Meine erste Hierarchie war folgende:
-----------------------------------------------
TObject
-> TWindow extends TObject
-> TGfx extends TObject
-----------------------------------------------

Dann hatte ich aber das Problem dass ich von TGfx Methoden/Funktionen eigentlich gar nicht auf TWindow Eigenschaften zugreifen konnte also hab ichs mal anders versucht....
-----------------------------------------------
TObject
-> TWindow extends TObject
---> TGfx extends TWindow
-----------------------------------------------
wobei ich aber auf fast exakt die gleichen Probleme gestoßen bin und bemerkt habe dass ich so Eigenschaften weiter vererbe die im abgeleiteten Type völlig nutzlos sind.

Also komme ich zu der Annahme das erstgenanntes Konstrukt die bessere Lösung ist.

Nun wenn ich also im Konstrukt 1 ein Steuerelement zum verschieben des Fensters erstellen will muss erstens wissen zu welchem Fenster dieses gehört und zweitens genau die Koordinaten dieses Fensters ansprechen können.

Genau daran scheiterts leider immer noch. Ich weiss dass ein GUI vllt. nicht optimal für den Beginn in OOP ist aber sie zeigt schnell auf wo Unklarheiten sind.

Schon mal Danke fürs zurechtstutzen Wink
Lets make things better...
 

Dreamora

BeitragFr, Jul 27, 2007 10:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Neue File

UISystem.bmx

mit

include "twindow.bmx"
include "tgfx.bmx"


jetz können sie gegenseitig auf die Daten zugreifen, vorausgesetzt TGfx weiss überhaupt dass es auf einem "TWindow" ist.
Ansonsten musst du ihm das beibringen Smile (und bei der Zerstörungsmethode auch diese Referenz wieder nullen!)

Ich würde überdies eine Grundklasse TGadget machen, von welcher TWindow und später auch TButton oder was du noch so machen willst, ableitet.

In TGadget sind alle Methoden abstrakt definiert die irgend ein Gadget haben muss.

danach kannst du nämlich dann einfach TGadget(irgendEinGadget).irgendEineMethode nutzen was so mächtig wie wichtig ist, wenn du eine gescheite Struktur willst.

Frage mich aktuell ob TGFX nicht auch ein Fall für so ein Gadget wäre, da es ja scheinbar mehr macht als nur etwas zu zeichnen.
Oder falls damit Teile der Fensterdekoration gemeint sind wie der Balken oben und so: Würde ich nicht empfehlen eine eigene Klasse draus zu machen, könnte die Event Handling Struktur drastisch viel komplexer machen.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragFr, Jul 27, 2007 11:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ungefähr so?

Code: [AUSKLAPPEN]
Type TGadget
   Global mx:Int, my:Int
   
   Field x:Int ,y:Int
   Field w:Int ,h:Int
   
   
   Method Create() Abstract
   
   Method Draw() Abstract
End Type


Type TWindow Extends TGadget
   Function Create:TWindow(x:Int ,y:Int ,w:Int ,h:Int)
      Local w:TWindow = New TWindow
         

   End Function
   
   Method Draw()
   
   End Method
   
End Type


Type TButton Extends TGadget
   Function Create:TButton(x:Int, y:Int ,w:Int ,h:Int)
      Local b:TButton = New TButton
   End Function
   
   Method Draw()
   
   End Method
End Type


Die Method nur abstract im Basetype aufsetzen und im "Untertype" dann definieren?
Lets make things better...
 

Dreamora

BeitragFr, Jul 27, 2007 11:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Create darfst du nicht definieren. BM hat kein Function Overloading, das heisst, Create müsste immer den gleichen Typ zurück geben.

Aber den Rest würde ich so machen, ja.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DamienX

BeitragFr, Jul 27, 2007 12:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Schade das nimmt einiges an Spielraum raus... in C++ ging das ohne Probleme! Confused
Werd jetz mal versuchen den Windows die Gadgets zuzuweisen!
Lets make things better...

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group