Frage zur GUI Programmierung (Basics)



  • Hallo zusammen ich habe ein kleines Problem bei der GUI Programmierung, verwendet wird FLTK und das Framework von Stroustrup aus dem Buch PPPC++.

    Basisklasse: Shape
    Ich habe zwei neue Klassen geschrieben welche von Shape erben: Arc und Box.

    Konstruktoren:

    Arc(Point p, int radius, Quadrant q);
    Box(Point p, int width, int height, int radius);
    

    Hilfskonstruktionen

    Struct Point {
    int x, y;
    }
    
    enum class Quadrant {
    upper_right, upper_left, lower_right, lower_left
    }
    

    Arc zeichnet nur Viertelkreise in einen der vier möglichen Quadranten .

    Box soll ein Rechteck mit abgerundeten Ecken zeichnen und hier beginnt mein Problem. Die linien des Rechtecks zeichne ich mit der FLTK Funktion fl_line, die abgerundeten Ecken könnte ich ebenfalls mit der FLTK Funktion fl_arc zeichnen, da ich aber schon die Klasse Arc habe die dasselbe leistet, könnte ich doch diese dafür verwenden? Dafür müsste ich in meiner Box Klasse vier Objekte meiner Arc Klasse einbauen, macht man das denn so? Wie würdet ihr das Problem lösen?



  • @sirEgbert sagte in Frage zur GUI Programmierung (Basics):

    Dafür müsste ich in meiner Box Klasse vier Objekte meiner Arc Klasse einbauen, macht man das denn so? Wie würdet ihr das Problem lösen?

    Ja, kann man so machen. 4 Line und 4 Arc als Member-Objekte in der Box. Wenn das Ganze gezeichnet werden soll - ich vermute jede Klasse hat so etwas wie eine virtuelle draw()-Funktion müsste man für die Box eben die draw()-Funktionen der Member aufrufen.

    Ein Problem das dabei allerdings auftaucht ist, wie die Positionen der Objekte zu interpretieren sind. Es macht Sinn, wenn die Positionen solcher Member nicht absolut, sondern relativ zum Elternobjekt sind - schliesslich will man z.B. beim Verschieben eines Objektes nicht auch die Positionen aller Kindobjekte umständlich anpassen müssen.

    Eine Möglichkeit wäre da, den draw-Funktionen einen Ursprung mitzugeben, auf den sich die Koordinaten des Objekts beziehen, z.B. sowas:

    Arc::draw(Point origin);
    Box::draw(Point origin)
    {
        upper_left_arc.draw(origin + Box::origin)
        ...
    }
    

    Eine Alternative ist, die Box so zu lassen und die Line und Arc-Objekte "on-the-fly" zu erzeugen, wenn sie (z.B. innerhalb von draw benötigt werden. Dann könnte man die Positionen der Lines und Arcs jedes mal relativ zur Eltern-Box berechnen.

    Oder man verwendet separate draw-Funktionen für grafische Primitive, die unabhängig von den Objekten sind und nur Parameter entgegennehmen, die für das Zeichnen relevant sind. Z.B. sowas wie

    draw_line(Point p0, Point p1);
    draw_arc(Point p, int radius, Quadrant q)
    {
        for(...)
           draw_line(...)
    }
    
    Arc::draw()
    {
        draw_arc(...)
    }
    
    Box::draw()
    {
        draw_line(...)
        ...
        draw_arc(...)
    }
    

    In dem Fall könnte man sich die Line und Arc Member-Objekte in Box sparen.

    Gibts da bei dem Framework vielleicht bereits einen Ansatz zu? Vielleicht orientierst du dich an dem. Zusammengesetzte Objekte sind ja durchaus ein naheliegendes Problem das dort vermutlich bereits auf die eine oder andere Weise gelöst wurde (vielleicht in einem späteren Kapitel?)



  • Erstmal danke für deine Hilfe, sorry bin nicht mehr dazu gekommen zu antworten, man soll ja nichts aufschieben 🙂

    Jeweils vier Member des Typs Line und Arc hat nicht geklappt, weil die (virtuelle) draw Methode in einer Basisklasse namens Shape steckt, unter protected, daher kann man die wohl nur aufrufen wenn meine Box Klasse von Line oder Arc erben würde. Eine Box ist aber eine Art von Shape, es wäre irgendwie nicht logisch diese von etwas anderem als Shape abzuleiten.

    Den Ansatz Line und Shape on the fly, also temporär, zu erzeugen hat mir super gefallen, aber selbiges Problem, man kann die draw Methode nicht aufrufen.

    Was aber geht ist einen Startpunkt mit dem Box Konstruktor zu erzeugen, dadurch habe ich immer einen Bezugspunkt. Die übrigen Punkte werden dann on the fly in der draw Methode der Box Klasse erzeugt und dann mittels den FLTK Funktionen fl_line und fl_arc gleich alles gezeichnet.

    Zusammengesetzte Typen gibt es in dem Framework tatsächlich nicht, das ist scheinbar den Übungsaufgaben vorenthalten 🙂


Anmelden zum Antworten