**************************************************************************** * * * Hier ist unser Modula-2_Kurs, für Fortgeschrittene. * * * ********h=Help************************************************************** Optische Aufwertung des Menüs: Dazu gibt es eine ganze Reihe von Möglichkeiten. 1. Änderung des verwendeten (ROM-) Zeichensatzes. 2. Verwendung von Zeichensätzen von der Diskette. 3. Mischung verschiedener Zeichensätze in einem Menü. 4. Verwendung verschiedener Hervorhebungsmethoden. 5. Verwendung verschiedenfarbiger Texte. 6. Einblendung eines alternativen Textes, wenn der MenuItem selektiert ist. 7. Verwendung von Bildern (=Images) anstelle von Text. 8. Einblendung alternativer Images. In unserem heutigen Demo-Programm habe ich a) in der Version für den Demo-Compiler (im Ordner 'Demos/DemoComp') von den Methoden 1., 3., und 7. gebrauch gemacht. b) in der Version für den kommerziellen Compiler (im Ordner 'Demos/Kommerz') die Methoden 2., 3. und 8. verwendet. Zusammenfassend kann man sagen, daß sich Menüs durch Änderung des Schriftbildes und den Einsatz von Images anstelle von Text optisch aufwerten lassen. Änderungen des Schriftbildes Durch Variationen innerhalb des Records 'IntuiText': Den Aufbau und die Bedeutung der Variablen des 'IntuiText'-Records hatte ich im letzten Kursteil unter Pos. 4.3.3 erklärt. Die Möglichkeiten zur Veränderung stecken in den Variablen: 1. 'frontPen': Haben wir in der Prozedur 'Farben()' vier Farben vorgesehen, dann bleiben uns (abgesehen von der Hintergrundfarbe) drei Farben zur freien Verwendung übrig, in denen die Schrift dargestellt werden kann; entsprechend den Farbnummern 0 ... 4. 2. 'backPen': Ist von der Variablen 'drawMode' abhängig, deshalb siehe dort! 3. 'drawMode': Wird in der Form 'drawMode := DrawModeSet{ ... }' verwendet. In die {} können die verschieden 'DrawModes' (=Darstellungsmodi) ein- gesetzt werden: 'DrawMode = (dm0,complement,inversvid)'. a) DrawModeSet{}: Dafür gibt es auch die Kurzschreibweise 'jam1'. Ist 'jam1' gesetzt, dann wird die Angabe der Variablen 'backPen' ignoriert (=nicht beachtet), und der Text überschreibt den Hinter- grund nur im Bereich der Zeichen. b) DrawModeSet{dm0}: Wird auch als 'jam2' bezeichnet. Ist 'jam2' ge- setzt, dann wird der Texthintergrund im Bereich der Zeichenmatrix mit der in 'backPen' angegebenen Farbe dargestellt. Beispiel: Unsere Farbeinteilung war: Farbe 0 = schwarz, Farbe 1 = rot, Farbe 2 = grün und Farbe 3 = blau. Setzen wir nun 'frontPen := 2', 'backPen := 1' und 'drawMode := jam2'; dann wird in grüner Schrift auf rotem Texthintergrund geschrieben. Der ursprüngliche (schwarze) Hintergrund bleibt außerhalb des Bereichs der Textmatrix davon unberührt. Anmerkung: 'jam1' bedeuted, daß in einer Farbe ('frontPen') geschrieben wird. 'jam2' bedeuted, daß in zwei Farben ('frontPen' und 'backPen') geschrieben wird. c) DrawModeSet{complement}: Veranlaßt, daß der Text in der Komple- mentfarbe in den Hintergrund geschrieben wird. Die Hintergrund- farbe bleibt dabei unverändert. Deshalb ist 'complement' nicht sinnvoll mit 'jam2' zu kombinieren. Die Komplementfarbe be- stimmt sich aus der Zahl der Bitplanes und der Farbnummer der gesetzten Farbe. Beispiel: Haben wir zwei Bitplanes und 'frontPen := 2', dann sind die Bits '10' gesetzt. 'complement' veranlaßt nun, daß mit den Bits '01' geschrieben wird, Das ist aber die Farbe 1. d) DrawModeSet{inversvid}: 'inversvid' steht für 'Inverse Video' und veranlaßt, daß der Text in der Hintergrundfarbe in ein Rechteck geschrieben wird, das mit der Farbe des 'frontPen' gefüllt wird. e) DrawModeSet{jam2,inversvid}: veranlaßt, daß die Farben von 'frontPen' und 'backPen' vertauscht werden. Anmerkungen: 1. Die Angabe 'DrawModeSet{complement,inversvid}' ist (vermutl.) nicht sinnvoll, da das Fehlen der Angabe 'jam2' den 'drawMode' 'jam1' impliziert. Bei 'jam1' haben aber 'complement' und 'inversvid' die gleiche Wirkung. 2. Denkbar wäre auch noch die Kombination 'DrawModeSet{jam2,complement, inversvid}. Ob das aber eine zusätzliche Textdarstellungsmög- lichkeit ergibt, kann ich so nicht sagen. In der Literatur taucht diese Kombination jedenfalls nicht auf. Aber vielleicht probiert das mal ein Kursteilnehmer aus und sagt es uns dann! Machen wir uns nun an weitere Änderungen des Schriftbildes durch zusätzliche Angaben im TextAttribut-Record: Im oben besprochenen 'IntuiText'-Record steckt die Variable 'iTextFont'. Mit diesem Zeiger auf einen 'TextAttr'-Record haben wir zusätzliche Möglichkeiten zur optischen Textveränderungen. Die Definition des 'TextAttr'-Records lautet: TYPE TextAttr = RECORD name :ADDRESS; ySize :CARDINAL; style :FontStyleSet; flags :FontFlagSet; END; mit FontStyles = (underlined,bold,italic,extended); FontStyleSet = SET OF FontStyles; FontFlags = (romFont,diskFont,revPath,tallDot, wideDot,proportional,designed,removed); FontFlagSet = SET OF FontFlags; Die Bedeutung der Variablen: name: Ist die Adresse des Namens eines Zeichensatzes. Benutzern der Demo-Version des M2Amiga fehlt das Modul 'DiskFont' mit der Prozedur 'OpenDiskFont()'. Deshalb können sie nur auf den im ROM vorliegenden Zeichensatz "topaz.font" zugreifen. Besitzer der kommerziellen Version des M2Amiga können dagegen auch auf Fonts zurück greifen, die auf Disketten vorliegen. Sehen Sie sich dazu das 'fonts'-Directory Ihrer Workbench-Dik an. Dort finden Sie die möglichen 'fonts' verzeichnet. Viele Textverarbeitungs- programme bieten darüber hinaus noch zusätzliche 'fonts' an. ySize: Da es den gleichen Zeichensatz (z.B. "topaz.font") in verschiedenen Größen (= Höhe in Pixel) gibt, muß noch die Größe des gewünschten Zeichensatzes in der Variablen 'ySize' angegeben werden. Beim Zeichensatz im ROM (auch ROM-Font genannt) stehen die Größen 8 (für 80 Zeichen pro Zeile) und 9 (für 60 Zeichen pro Zeile) zur Verfügung. Auf der Diskette gibt es aber für "topaz.font" auch noch die Größen 11 und 17. style: Erlaubt es, die oben angegebenen Zusätze (unterstrichen, fett, schräg und/oder extrabreit) für den Text anzugeben. flags: Die Möglichkeiten für 'flags' stehen ebenfalls oben im Text. Ich konnte aber bis jetzt kein Beisoielprogramm finden, in dem sie angewendet wurden. Wer Zeit und Interesse hat, der kann ja mal die 'flags' tallDot, wideDot oder proportional ausprobieren. Die anderen 'flags' erscheinen mir nicht so sinnvoll - aber man weiß ja nie! Vielleicht höre ich gelegent- lich davon. Anwendung des 'TextAttr'-Records im Demo-Programm: Im heutigen Demo-Programm 'MenuDemo' bin ich wider zwei verschiedene Wege gegangen. Grund: Bei der Verwendung von Zeichensätzen von der Diskette wird zum Laden des Zeichensatzes die Prozedur 'OpenDiskFont()' aus dem Modul 'DiskFont' benötigt. Dieses Modul gibt es aber nur zur kommerziellen Version des M2Amiga-Compilers. Deshalb habe ich Für Besitzer der Demo-Version des M2Amiga eine Anwendung (im Ordner 'Demos/DemoComp') gezeigt, bei der ich den ROM-Zeichensatz "topaz.fonts" verwende. 1. Im Modul 'DemoMenu.mod' (etwa in der Mitte des Listings) benutze ich die Größe 9 mit 'style := FontStyleSet{bold,extended}' für die Action-Items. 2. Für Screen- und Window-Titel verwende ich im Modul 'Fenster.mod' in der Prozedur 'Bildschirm()' die Größe 9 mit 'style := FontStyleSet{bold,extended}'. 3. Im Hauptprogramm (Modul 'MenuDemo.mod') verwende ich nur 'ySize := 8' ohne zusätzliche Angaben. Besitzer der kommerziellen Version des M2Amiga finden im Ordner 'Demos/Kommerz' im Modul 'Fenster.mod' in der Prozedur 'Bildschirm()' ein Beispiel für die Verwendung des DiskFonts "sapphire.font" in der Größe 'ySize := 19'. Damit werden dort Screen- und Fenster-Titel geschrieben. Im Modul 'DemoMenu.mod' habe ich dann, gleich zu Beginn der Initialisierung, noch eimal den gleichen Zeichensatz in der Größe 'ySize := 14' für die Action-Items benutzt. Im Hauptprogramm (Modul 'MenuDemo.mod') in der Prozedur 'ChangeFont' schalte ich dann auf den Standard-Zeichensatz "topaz.font" mit 'ySize := 8' zurück, da die Ausgabetexte der Infos-Items sonst zu groß für das Fenster werden. Damit haben wir die Variationsmöglichkeiten der Schrift entsprechend den Überlegungen aus dem obigen Abschnitt 4.7 behandelt. Bleibt noch die Verwendung von Bildern anstelle von Text in den 'MenuItem's. 7.2 Verwendung von Images anstelle von Texten: Wie Sie im letzten Kursteil gesehen haben, gibt es im Record 'MenuItem' die Variable 'flags := MenuItemFlagSet{ ...}'. Geben wir dort nicht das flag 'itemText' an, so erwartet Intuition in der Variablen 'MenuItem.itemFill' die Adresse eines Images (=Bildes). Ist zusätzlich das Flag 'highItem' gesetzt, dann muß auch noch die Adresse eines 2. Bildes bei 'MenuItem.selectFill' stehen. Doch zunächst einmal müssen wir klären 7.2.1 Was ist ein Image? Ein Bild wird in M2 natürlich wieder durch einen Record beschrieben. Seine Definition lautet: TYPE Image = RECORD leftEdge :INTEGER; topEdge :INTEGER; width :INTEGER; height :INTEGER; imageData :ADDRESS; planePick :Planes; ----> Planes = SET OF [0..7] lt. 'Graphics.def' planeOnOff :Planes; nextImage :ImagePtr; END; Bedeutung der Variablen: leftEdge, topEdge, width und height: haben die gleiche Bedeutung wie beim 'MenuItem'-Record; legen also die Lage des Bildes im Container fest. depth: bestimmt die Zahl der Bitplanes (max. 6) des Bildes. imageData: Hier steht die Adresse der Bilddaten, die aus 16-Bit-Wörtern bestehen. Dazu unten mehr. planePick: Gibt an in welche Bitplanes des Windows oder Screens das Bild eingesetzt wird. planeOnOff: Bestimmt was mit den Bitplanes des Windows oder Screens geschehen soll, die ensprechend 'planePick' nicht gesetzt wurden. nextImage: Zeigt auf den nächsten 'Image'-Record, falls mehrere Images miteinander verkettet werden sollen. Zusätzliche Erläuterungen zu den Variablen 'planePick' und 'planeOnOff' Beide Variablen enthalten Bitmuster, deren Bits die jeweilige Bitplane bezeichnen. Beispiel: Für einen Screen mit 3 Bitplanes (Plane 0, 1 und 2) sibd die folgenden Kombinationen möglich: Wert von planePick bzw. planeOnOff ----------------------------- dezimal | binär | ausgewählte | |Bit Nr. 2 1 0 | Bitplanes | Bemerkung ----------------------------------------------------------------------- 0 | 0 0 0 | keine | - 1 | 0 0 1 | 0 | Bit Nr. 0 gesetzt 2 | 0 1 0 | 1 | Bit Nr. 1 gesetzt ----------------------------------------------------------------------- 3 | 0 1 1 | 0 & 1 | Bit Nr. 0 & 1 gesetzt 4 | 1 0 0 | 2 | Bit Nr. 2 gesetzt 5 | 1 0 1 | 0 & 2 | Bit Nr. 0 & 2 gesetzt 6 | 1 1 0 | 1 & 2 | Bit Nr. 1 & 2 gesetzt 7 | 1 1 1 | 0 & 1 & 2 | Bit Nr. 0 & 1 & 2 gesetzt ----------------------------------------------------------------------- Hat Ihr Image nur eine Bitplane, dann können Sie mit 'planePick' angeben, in welche Bitplane des Screens oder Windows Ihr Image eingeschoben werden soll. Also mit 'planePick := 1' in Plane 0, mit 'planePick := 2' in Plane 1, etc. etc... Wenn Sie nun 'planePick := 1' und 'planeOnOff := 0' setzen, und anschließend in einer Schleife 'planeOnOff'in 2 und später in 4 ändern, dann wechseln Sie die Hintergrundfarben Ihres Bildes ohne das Bild selbst zu verändern. Diese beiden Variablen bieten damit ganz effiziente Variationsmöglichkeiten - probieren Sie das ruhig mal aus! Sie finden diese Variablen im Modul 'DemoMenu.mod' in der Prozedur 'InitImage()'. Doch nun zur Variablen imageData: In den diversen Büchern über die Programmierung unter Intuition in der Sprache C, sind Beispiele angegeben, wie diese 16-Bit-Wörter aufzubauen sind. Alle diese Beispiele laufen aber auf 'wilde' Bitmusterberechnungen (von Hand!) hinaus. Es geht aber auch eleganter: Mit dem Programm 'IFFtoCode' von Pit Burkhardt vom Stuttgarter Modula-2 Klub (=Amok), das auf der Disk 'Amok#3' (bzw. SIGMA.06) veröffentlicht wurde. Dieses Programm (incl. Dokumentation) habe ich Ihnen in den Ordner 'Demos' kopiert. Dort finden Sie auch eine genauere Beschreibung zur Anwendung dieses Programms. Mit einem Malprogramm (z.B. DPaint) erstellen Sie die Bilder, und saven sie als IFF-Brushes. Will man mehrere Bilder als Menüpunkte untereinander darstellen, dann müssen die Bilder alle gleich groß sein! Das Programm 'IFFtoCode' macht dann aus den Brushes ein M2-Hilfsmodul, aus dem die Imagedaten direkt übernommen werden können. Das Hilfsmodul enthält allerdings Definitions- und Implementations-Modul gleichzeitig. Sie müssen dann noch 'von Hand' getrennt werden. Zur genaueren Information lesen Sie bitte Pit Burkhardts Doumentationsfile. 7.2.2 Beispiele für Images im Demo-Programm: In der Schublade 'Demos/Kommerz' für Besitzer der kommerziellen Version des M2Amiga-Compilershabe ich quasi eine 'Deluxe-Ausgabe' des Menü-Programms erstellt. Aber auch die Besitzer der Demo-Version sollten sich die Wirkung der großen Images im Programm 'MenuDemo' nicht entgehen lassen. Die Methode von Pit Burkhardt, die Imagedaten einzeln in ARRAY-Elemente einzusetzen, ist allerdings etwas platzaufwendig. Das äußert sich in meinem Beispiel-Programm darin, daß die 3 Bilder (mit je 1 alternativen Bild) und dem Modulkopf, das Modul 'Images.mod' auf ca. 72 kBytes anschwellen lassen. Da wir ein so langes Modul nicht durch den Demo-Compiler bekommen, habe ich für die Demo-Version ein Modul 'SimpleImg.mod' mit einfacheren Bildern erstellt. Entsprechend bescheiden sehen allerdings auch die Infos-Items dann aus. 4.8 Probleme mit dem Demo-Programm: Bei der Kompilation des Moduls 'DemoMenu.mod' aus dem Ordner 'Demos/Kommerz' hatte ich einige Probleme. Bei der Einbindung verschiedener Diskfonts mit dem Programmstück: BEGIN (* Beginn der Initialisierung des Moduls. *) tfp := NIL; WITH ta DO name := ADR("sapphire.font"); ySize := 14; style := FontStyleSet{}; flags := FontFlagSet{}; END; ht := ta.ySize+4; tap := ADR(ta); tfp := OpenDiskFont(tap); IF tfp=NIL THEN (* BreakPoint(ADR("sapphire.font nicht gefunden!")); Hier überflüssig, da in 'Fenster.mod nochmal gecheckt! *) ht := 8+2; END; (* IF *) stürzte der Compiler manchmal ab und brachte nur die sehr ungenauen Fehlermeldungen "Address Error - abort" und "9000: Compiler-Absturz". Gelegentlich ließ sich das Modul aber auch kompilieren. Da ist also vermutlich noch 'irgendwo der Wurm drin'?! Ich verstehe z.B. nicht, wozu der 'TextFontPtr' tfp benötigt wird, wenn ich ihn doch garnicht weiter verwende?! Im 'IntuiText'-Record wird ja nur der 'TextAttrPtr' tap übergeben? Irgendwo hakt es da noch - aber vielleicht kann mir das ja ein Kursteilnehmer verraten??!! 4.9 Aufgaben: * Ich habe in der kommerziellen Version alternative Images im Menü ver- wendet - probieren Sie doch mal die Verwendung alternativer Texte! * Spielen Sie verschiedene Möglichkeiten bei der Darstellung der Fonts durch (Änderung des FontFlagSet{}). * Erzeugen Sie verschiedenfarbige Texte in den MenuItems. * Falls Sie die kommerzielle Version des M2Amiga besitzen - probieren Sie die Verwendung anderer DiskFonts. Damit haben wir die Menüs so ziemlich abgehandelt - natürlich gibt es noch eine ganze Menge Feinheiten. Auf die will ich aber erst zu einem späteren Zeitpunkt zurück kommen. Wenn alles klappt, werden wir und im nächsten Kursteil mit der Erzeugung und Verwendung eigener Gadgets beschäftigen. Das wird sicher interessant - aber nicht ganz einfach. Ich habe bis jetzt jedenfalls nur eine ungefähre Vorstellung von dem, was da auf uns zukommt. Aber ich bin sicher, irgendwie kriegen wir das schon hin! Viel Spaß!