Programmieren

Wie erzeugt man ein Proportionalgadget mit BOOPSI ? Teil 2

Sven Drieling

Im AmigaGadget #27 hatte Jürgen Klawitter beschrieben, wie man ein Proportionalgadget in einen Windowrand legt. Allerdings konnte ich auf der Disk keine Beispielprogramme finden. PropBorder auf dieser Disk ist nun eine direkte Umsetzung des Artikels in ein Programm und PropBorderTxt eine Erweiterung des Programms, das einen ASCII-Text lädt und ihn abhängig von der Position des Proportionalgadgets anzeigt. Beide Programme liegen als Ansi-C und Oberon-2 Source vor und laufen ab OS 2.04. Die beiliegende compilierte Version ist die Oberon-2 Version, da das Laufzeitsystem meines Oberon Compilers automatisch das Starten von der WB unterstützt.

[ Die Programme befinden sich im Verzeichnis "PropBorder". Im WWW können sie leider nicht abgerufen werden. (an) ]

Noch eine Anmerkung zum Artikel in der #27 und ein paar Sätze zu den beiden Sourcen.

PropBorder

    JK> Eine kleine Schwierigkeit stellt die Berechnung von GA_RelHeight dar,
    JK> weil die Höhe des sizing gadgets nicht bekannt ist, wenn es nur in den
    JK> rechten Fensterrand eingebunden ist. Man kann sich hier mit einem Wert
    JK> von 10 behelfen oder man geht die Gadgetliste durch und holt sich dort
    JK> den Wert.
   

Das sicherste dürfte es sein, das Gadget im linken und unteren Windowrand unterzubringen

    WA_SizeBRight, TRUE,
WA_SizeBBottom, TRUE,

dann kann man sicher die Größen der Ränder aus der Window-Struktur über win-&62;BorderRight, win-&62;BorderBottom auslesen.

Wenn man den unteren Fensterrand aber lieber für Ausgaben benutzt, sollte man, wie oben geschrieben, besser die Größe des Sizinggadgets ermitteln und keine festen Werte benutzen. Schon unter OS 2.04 hat das Sizinggadget in der Lowres-Auflösung eine andere Größe als in den höheren Auflösungen. PropBorder und PropBorderTxt ermitteln deshalb die Höhe des Sizinggadget, indem sie in der Funktion

    struct Gadget* FindSysGadget(struct Window *w, UWORD gadType)
   

die Gadgetliste des Windows nach dem Sizinggadget durchsuchen und dann die Höhe des Gadgets seiner Struktur entnehmen.

PropBorder

Arbeitet so wie im Artikel beschrieben. Es empfängt Änderung des Proportionalgadgets über IDCMP_IDCMPUPDATE und liest die aktuelle Position des Gadgets mit GetAttr() aus, um sie dann in der Shell auszugeben.

PropBorderTxt

Lädt zunächst den als zweiten Paramter angegebenen Text in eine Exec-Liste. Dabei entspricht jede Node einer Textzeile. Damit die C-Version nicht noch unübersichtlicher wird, ist die Zeilenlänge auf 1024 Zeichen beschränkt. Die Zeilen in der Liste werden zwar vollkommen dynamisch verwaltet, aber mit dieser Einschränkung ist das Einlesen der Zeilen mit der Ansi-C Funktion fgets() leichter. Die Oberon-2 Version benutzt statt der Exec-Liste das Module LinkedLists.mod und durch die Verwendung des dynamischen Strings aus STRING.mod entfällt auch die Längenbeschränkung der Zeilen. Dafür wird bei Speichermangel allerdings das Programm vom Laufzeitsystem abgebrochen. Für ein richtiges Programm empfiehlt sich die Verwendung von ALLOCATE() statt NEW(), allerdings muß man dann selbst überprüfen, ob der Speicher auch reserviert werden konnte.

Neu sind noch GetInnerWindow() und PrintPage(). GetInnerWindow() liefert die Ausmaße des inneren Windows(des Windows mit weggedachten Rand). Anhand dieser Werte wird ermittelt, wieviel Zeilen des Textes im Window angezeigt werden können, und PGA_Visible entsprechend gesetzt.

PrintPage() gibt den Text im Window ab der Zeile PGA_Top aus. Um diese Routine einfach zu halten, beginnt die Routine immer mit der ersten Zeile des Textes und überspringt die ersten PGA_Top - 1 Zeilen. Dann wird der Inhalt des Windows gelöscht und PGA_Visible Zeilen mittels graphics.Text() im Window ausgegeben. Wieviel Zeichen in eine Zeile des Windows passen wird mit graphics.TextFit() ermitteln. Das flackert zwar grauenhaft, aber es ist einfach und gut lesbar. Eine einfache Optimierung wäre, nicht auf einmal den gesamten Window-Inhalt zu löschen, sondern immer nur den Bereich der aktuellen Zeile. Damit entfällt das Flackern. Für mehr Effizienz müßte man sich innerhalb der Liste relativ zur letzten obersten Zeile bewegen und den schon mal ausgegeben Text im Window mittels Scrollraster scrollen. Aber dafür braucht man schon einige Zeilen und eine Reihe von Fallunterscheidungen.

Als Erweiterungen könnte man noch einen horizontalen Scroller im unteren Windowrand einbauen, um den Text auch in der horizontalen verschieben zu können. Schlußendlich könnte man noch die von der WB bekannten hoch/runter Pfeile einsetzen, um den Text auch Zeilen bzw. Spaltenweise scrollen zu können.

tschuess
[|8:)

Zurück