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

1

19.03.2011, 18:02

[gelöst] Textposition bei GUI-Element berechnen

Hallo Zusammen,

Da ich in meinem aktuellen Projekt nur sehr grundlegende GUI-Elemente wie z.B. Buttons brauche, habe ich mir gedacht, dass ich die auch gut selbst machen kann.
Mein Problem ist jetzt, wie rechne ich die Textposition auf z.B. einem Button aus?
Bis jetzt hatte ich das so probiert: (unter der Annahme dass z.B. ein Buchstabe der Schriftgröße 14 auch 14 Pixel groß ist^^)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
float Temp = static_cast<float>(LabelText.GetNumChars());
Temp /= 2;
LabelText.SetPosition ((PosX+Width/2) - Temp*LabelText.GetCharacterSize(), (PosY+Height/2) - LabelText.GetCharacterSize()/2); 
/*- LabelText.GetCharacterSize()/2 weil das "Center" des Texts links oben liegt.
Label Text: Der Text, Center liegt links oben 
Temp: Anzahl der Zeichen im Text (Temp/=2, weil ich dachte, dass ich einfach die Hälfte der Zeichen * Zeichengröße von der Mitte des Buttons aus nach links verschiebe
PosX/PosY: Position des Buttons, liegt auch links oben
Width/height: Breite bzw. Höhe des Buttons */


Die Bestimmung der Y-Koordinate des Textes funktioniert ganz gut, aber bei der X-Koordinate komme ich nicht weiter. Bei kleinen Texten kommt es noch etwa hin, aber bei z.B. "ABC hallo bla bla", liegt der Text viel zu weit links und beginnt sogar schon außerhalb des Buttons.

Zusammengefasst: Wie berechne ich die Position eines Textes, sodass er mittig liegt? Oder wie bekomme ich anhand der Zeichengröße die Größe eines Zeichens in Pixeln?

lg chaia

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Chaia*« (21.03.2011, 14:25)


Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

2

19.03.2011, 18:47

Also soweit ich das sehe, hast du bei der Berechnung alles richtig gemacht! Aber nur, wenn wirklich alle Zeichen gleich breit sind!
Ich weiß jetzt nicht ob du mit Bitmap-Font oder TrueType arbeitest, aber es ist meisten so, dass ein "l" nicht so breit ist, wie ein "b". Das würde auch erklären warum es umso mehr abweicht, desto länger der Text ist. Umso länger dieser nämlich ist, desto mehr Zeichen mit unterschiedlicher Breite kommen zusammen, womit die wahrscheinlichkeit einer Abweichung größer ist. ;)

Also mein Tipp:
Überprufe nochmal, ob wirklich alle Zeichen gleich breit sind.
Und wenn sie es nicht sind, musst du alle Buchstaben einzeln durchlaufen, dann für jeden die entsprechende Länge zur Gesamtlänge addieren und das Ergebnis dann als Gesamtlänge in deine Berechnung einbauen. :thumbup:

Mfg Harry222

3

20.03.2011, 10:14

Ups, das hatte ich gar nicht beachtet^^
Ich arbeite mit der SFML, ich denke da wird TrueType verwendet.
Wie kann ich die Breite eines Buchstaben berechnen, ohne jetzt alle Werte irgendwo nachzuschauen und ein episches switch-case aufzubauen und zwischen jedem Buchstaben zu unterscheiden?

lg chaia

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

4

20.03.2011, 13:42

Ich würde es schon mit switch-case machen! Die meisten Zeichen, wie z.B. "b", "a", "z", "#", u.s.w., sind ja meistens gleich groß und es gibt nur ein paar Ausnahmen, wie z.B. "l", "t", und noch ein paar. (Großbuchstaben sind meistens alle gleich breit! ;) )
Das heißt du müsstest nur alle Zeichen raussuchen, die du verwenden möchtest und die von der Normalgröße abweichen. Alle, die nicht abweichen werden dann in der switch-Anweisung per default addiert, alle anderen haben ein extra case!

Mfg Harry222

5

20.03.2011, 23:10

? sf::String liefert dir doch ein sf::FloatRect, mitdem du dir die breite des Strings usw. holen kannst ... damit zu zentrieren sollte nunwirklich nicht schwer sein ;)
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Bügeleisen

Frischling

Beiträge: 11

Wohnort: Köln

Beruf: Schüler

  • Private Nachricht senden

6

21.03.2011, 10:47

Ich habe das mal so gelöst:

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
24
25
26
27
28
29
sf::String MainWindow::alignText(std::string const& text, TextAlign align, float top, float margin)
{
    sf::String txt(text);
    float txtWidth = txt.GetRect().GetWidth();

    switch(align)
    {
    case CENTER:
        {
            float x = (app->GetWidth() - txtWidth) / 2 + margin;
            txt.SetPosition(x, top);
        } break;
    case LEFT:
        {
            txt.SetPosition(margin, top);
        } break;
    case RIGHT:
        {
            float x = app->GetWidth() - txtWidth - margin;
            txt.SetPosition(x, top);
        } break;
    default:
        {
            txt.SetPosition(margin, top);
        } break;
    }

    return txt;
}


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
enum TextAlign
{
    CENTER = 1,
    LEFT,
    RIGHT,
};

class MainWindow
{
//...
sf::String alignText(std::string const& text, TextAlign align, float top = 0.f, float margin = 0.f);
//...
}
Das bügeln wir schon aus :thumbsup:

7

21.03.2011, 14:24

? sf::String liefert dir doch ein sf::FloatRect, mitdem du dir die breite des Strings usw. holen kannst ... damit zu zentrieren sollte nunwirklich nicht schwer sein ;)


Ups, das hab ich übersehen^^
Dann ist das wohl hier gelöst.
Ansonsten hätte ich es eben auch mit einem switch gelöst.

lg chaia

Werbeanzeige