Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

11

06.12.2013, 12:09

Danke für die weiteren Vorschläge.

Zitat von »TrommlBomml«

Dann ist der WPF-Ansatz nicht der richtige sondern der von BlueCobold :)

Obwohl ich momentan nicht den Anspruch habe, mein GUI "fluid" zu machen, finde ich die Panel auch so ziemlich nützlich. Beispielsweise wenn es darum geht, einfach nur ein paar Buttons untereinander zu platzieren, ohne für jeden Button explizit die Position festzulegen. Es gibt aber natürlich auch einige Fälle, in denen ich eine relative Positionierung bevorzugen würde. Kommt auch sehr auf die Gestaltung des GUIs an, denke ich.


Zitat von »eXpl0it3r«

Ich persönlich finde SFGUI's Layouter recht praktisch, denn obwohl es empfohlen ist nur Layouters zu verwenden, so ist es jedoch auch kein Problem mal etwas zu fixieren. Wenn ich mich richtig erinnere, hat SFGUI vom Design her relative viel von GTK übernommen, kannst dir also auch mal GTK noch anschauen. ;)

Hier habe ich mich mal etwas in GTK (für Python) eingelesen und auf den ersten Blick würde ich sagen, dass der von GTK gewählte Ansatz (was die Container betrifft) dem von WPF entspricht. Unter anderem gibt auch einen Fixed-Container, in dem die Children relativ zum Parent positioniert werden können. Einen Hinweis darauf, dass einzelne Elemente in anderen Containern fix positioniert werden können, habe ich allerdings noch nicht gefunden. Ist aber auch nicht so wichtig; das bekomme ich schon hin. ;)


Zitat von »Thoran«

Klar kann ich die Positionierung von Anfang an einem Layoutmanager übertragen, der dann auf der Basis von Constraints oder sonstigen Konstrukten versucht das anzulegen, was der Entwickler evtl. gemeint hat. Ich bevorzuge, das Anlegen der GUI über einen GUI-Editor, es sei denn man betreibt einen data-driven approach, der auch die GUI-Elemente bestimmt.

In meinem Fall kann man von data-driven sprechen, denke ich. Jedenfalls habe ich vor, GUI-Elemente bzw. GUI-Templates mit XML zu definieren.


Zitat von »Thoran«

Auflösungsunabhängigkeit erreiche ich normalerweise damit, dass ich grunsätzlich im Interval [0;1] meine GUI-Widgets anlege. Während der Ausführung wird das dann mit der tatsächlich verfügbaren Auflösung entlang der Achsen multipliziert.

Ich hatte mir die Möglichkeit überlegt, die Größe eines Elements entweder in Pixeln oder in Prozent festlegen zu können (falls man sie festlegen möchte). Der Prozentwert würde sich dann auf die Größe des Parents beziehen. Aber darüber werde ich noch genauer nachdenken.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

12

06.12.2013, 12:23

Ich hatte mir die Möglichkeit überlegt, die Größe eines Elements entweder in Pixeln oder in Prozent festlegen zu können
Ich würde Dir zu beidem raten. Sonst hast Du keine Möglichkeit ein Element immer z.B. 30 Pixel vom rechten Rand zu positionieren. Das geht nämlich nur mit der Kombination aus 100% - 30 Pixel.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

13

08.12.2013, 01:59

Das ist wohl wahr. Ich bin mir allerdings noch nicht sicher, wie ich das in der API umsetzen werde.

So vielleicht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
widget.setPlacement(Placement::Relative);

// Setzt Abstand zwischen rechter Widgetkante und rechter Parentkante auf 30px.
widget.setRight(Unit::pixel(30));

// Setzt Abstand zwischen linker Widgetkante und rechter Parentkante auf 30px.
// setRight wird hierdurch wieder außer Kraft gesetzt.
widget.setLeft(Unit::percent(1.f) + Unit::pixel(30));

// Und so könnte man ein Widget im Parent zentrieren:
widget.setLeft(Unit::percent(.5f));
widget.alignHorizontal(Align::Center);

Aber das sind nur meine ersten Gedanken dazu.

Falls ich es so mache, bräuchte ich eine Unit-Klasse, die eine Kombination aus Prozent- und Pixelwerten abbilden kann. Diese könnte dann sehr einfach in den finalen Wert konvertiert werden:

C-/C++-Quelltext

1
2
// Als Argument wird das Objekt übergeben, auf das sich die Prozentwerte beziehen.
float finalx = widget.left.translate(widget.parent);

Könnte klappen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

14

08.12.2013, 09:11

Wozu brauchst Du linken und rechten Abstand? Du brauchst doch nur einen einzigen Offset für x und für y. Klar, Du kannst das mit Margins machen, so wie WPF. Finde ich aber überflüssig.
Wenn Du Horizontal Center hast, dann brauchst Du kein Left Percent 50. Center ist doch schon 50%. Bzw. 50%-0.5*WidgetWidth. Left ist 0% und Right ist 100%-WidgetWith.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

15

08.12.2013, 20:11

Ja, so gesehen hast du natürlich recht. Ich habe im obigen Code versucht, die Abstände einstellbar zu machen, ohne dass man WidgetWidth kennt. WidgetWidth ist ja womöglich noch nicht bekannt, wenn die Positionierung des Widgets am Anfang festgelegt wird und kann sich während der Laufzeit ändern. Wenn ich WidgetWidth in die Position einfließen lassen wollte, müsste ich daraus eine Variable machen, die sich auf das Widget bezieht, vergleichbar mit Unit::percent.

Anstatt eine solche Variable zu verwenden, habe ich in meinem Versuch mit setRight die Möglichkeit gegeben, das Widget am rechten statt am linken Rand des Parents auszurichten. Analog dazu würde es neben setTop auch ein setBottom geben (von CSS inspiriert). Mit setLeft(100%) würde der linke Rand des Widgets auf den rechten Rand des Parents gelegt werden. Das Widget würde sich dadurch also rechts neben dem Parent befinden. Mit setRight(100%) würde das Widget dementsprechend links neben dem Parent platziert werden.

alignHorizontal war so gedacht, dass relativ positionierte Widgets (im Gegensatz zu nichtrelativ positionierten Widgets) damit an dem von setLeft/setRight festgelegten Punkt ausgerichtet werden. Kombiniert man z.B. setLeft(100%) mit alignHorizontal(center), wird das Widget auf dem rechten Rand des Parents zentriert. setRight(100%) + alignHorizontal(right) macht dasselbe wie setLeft(0).

Nicht besonders intuitiv, wie ich zugeben muss.
Ich fände es besser, wenn sich alignHorizontal auf den Innenbereich des Parents beziehen würde, so wie bei nichtrelativ positionierten Widgets auch. Und eine WidgetWidth-Variable wäre ebenfalls ziemlich praktisch.

Also hier ein neuer Versuch:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
widget.setPlacement(Placement::Relative);

// Widget horizontal und vertikal im Parent zentrieren.
widget.alignHorizontal(Align::Center);
widget.alignVertical(Align::Center);

// Widget rechts innen am Parent platzieren.
widget.alignHorizontal(Align::Right);

// Widget rechts außen am Parent platzieren.
widget.alignHorizontal(Align::Right);
widget.setMarginLeft(Measure::self(1.f));

// Widget unter dem Parent platzieren, mit 30px Abstand. Measure::pixel ist optional.
widget.alignVertical(Align::Top);
widget.setMarginTop(Measure::parent(1.f) + Measure::pixel(30));
// Alternative:
widget.alignVertical(Align::Bottom);
widget.setMarginTop(Measure::self(1.f) + 30);

// Widget auf dem linken Rand des Parents zentrieren.
widget.alignHorizontal(Align::Left);
widget.setMarginRight(Measure::Self(.5f));

Besser?
Habe nun Margin anstatt left/right/... benutzt, weil damit auch die Abstände der nichtrelativ positionierten Widgets eingestellt werden. Dadurch ist es einheitlich.

In XML würde ich das dann etwa so abbilden:

XML

1
2
3
4
5
6
7
8
9
<parent>
    <!-- Widget wird auf rechtem Rand des Parents zentriert.
         100% bezieht sich auf die Breite des Parents.
         @50% bezieht sich auf die Breite des Widgets. -->
    <widget placement="relative" align="left" margin-left="100% - @50%"/>
    
    <!-- Widget wird 10px über dem unteren Rand des Parents platziert. -->
    <widget placement="relative" valign="bottom" margin-bottom="10px"/>
</parent>

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

16

08.12.2013, 20:16

<widget placement="relative" align="left" margin-left="100% - @50%"/>

Das halte ich für Unfug. Ich würde das schlicht align="right" nennen, denn das erwartet man als Ergebnis. Eine mathematische Operation als Wert für ein XML-Attribut halte ich auch für ganz schlecht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

17

08.12.2013, 22:54

Die Antwort kam ja wie aus der Pistole geschossen. ;)

Zitat von »BlueCobold«

Das halte ich für Unfug. Ich würde das schlicht align="right" nennen, denn das erwartet man als Ergebnis.

Ich denke nicht, dass man das als Ergebnis erwarten würde. Bei einem align="right" erwarte ich zumindest, dass die rechte Kante des Widgets am rechten Rand des Parents angelegt wird. Aber das passiert hier nicht: Stattdessen wird das Widget so ausgerichtet, dass sein Mittelpunkt auf dem rechten Rand des Parents liegt.

align="right" margin-left="@50%" hätte es hier natürlich auch getan, aber ich wollte in dem Beispiel die Unterscheidung zwischen den beiden Prozentwerten zeigen.


Zitat von »BlueCobold«

Eine mathematische Operation als Wert für ein XML-Attribut halte ich auch für ganz schlecht.

Warum? Letztendlich ist das nur ein String, der an den Konstruktor der Measure-Klasse übergeben wird.
Außerdem schreibe ich in XSLT fast jeden Tag Ausdrücke in Attribute. Aufrgund der großen Macht der schwarzen XSLT-Magie kann ich also gar nicht mehr anders. ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

18

09.12.2013, 06:40

Ich denke nicht, dass man das als Ergebnis erwarten würde.
Ich hätte es erwartet.
Aber das passiert hier nicht: Stattdessen wird das Widget so ausgerichtet, dass sein Mittelpunkt auf dem rechten Rand des Parents liegt.
Das wiederum hätte ich nicht erwartet.

Parsing von Ausdrücken und das am Ende noch im Konstruktor, das sollte man meiner Meinung nach immer vermeiden, weil man dem Entwickler da wieder eine neue (wenn auch einfache) Syntax aufbrummt, die eben nicht sein muss.
Letztlich ist es Dein Ding, Du kannst tun und lassen, was Du willst. Ich hätte es trotzdem über align="right" xoffset="50%" gemacht. Alignment bezieht sich auf das Parent-Widget, Offset ist relativ dazu in Pixeln, wobei die Größe des Widgets in % genutzt werden kann. Ich denke, dass das jeder versteht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Thoran

Alter Hase

Beiträge: 520

Wohnort: Stuttgart

Beruf: Senior Software Engineer

  • Private Nachricht senden

19

09.12.2013, 09:32

Ich würde Dir zu beidem raten. Sonst hast Du keine Möglichkeit ein Element immer z.B. 30 Pixel vom rechten Rand zu positionieren. Das geht nämlich nur mit der Kombination aus 100% - 30 Pixel.

Ich frage mich warum man das tun will, wenn man ein auflösungsunabhängiges GUI entwicklen will?
Mein Entwicklertagebuch
Aktuelles Projekt: Universum Espionage
Eingestellt:Spieleengine SilverCore
Organisator "Spieleentwickler Stammtisch Stuttgart"

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

20

09.12.2013, 10:02

Ich frage mich warum man das tun will, wenn man ein auflösungsunabhängiges GUI entwicklen will?

Vielleicht um "Randgrafiken" für Fenster, Buttons etc. nicht mitzuskalieren. Das sieht ggf. ziemlich hässlich aus.
Bei den meisten Betriebssystemoberflächen sind ja auch die Fensterrahmen und die Buttons zum Minimieren, Maximieren und Schließen eines Fensters immer gleich groß, egal welche Auflösung man einstellt.

Werbeanzeige