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 4Arc
als Member-Objekte in derBox
. Wenn das Ganze gezeichnet werden soll - ich vermute jede Klasse hat so etwas wie eine virtuelledraw()
-Funktion müsste man für dieBox
eben diedraw()
-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 dieLine
undArc
-Objekte "on-the-fly" zu erzeugen, wenn sie (z.B. innerhalb vondraw
benötigt werden. Dann könnte man die Positionen derLine
s undArc
s 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 wiedraw_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
undArc
Member-Objekte inBox
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