(******************************************************************************) (* This MODULE is Public Domain. Copy me like a beast! *) (* Christian Ledermann *) (* W”lfelkofen 2 *) (* 84166 Adlkofen *) (******************************************************************************) (* *) (* Started: 20.12.92 03:54:30 *) (* Version: 20.12.89 00:404:12:54 *) (* *) (******************************************************************************) (* *) (* Diese Software ist ohne jede Garantie. Ich verspreche *) (* keinerlei Wartung und bernehme keine Verantwortung fr Sch„den die *) (* durch die Benutzung dieses Programmes entstehen. *) (* Jegliche Ersatzansprche lehne ich ab. *) (* *) (******************************************************************************) DEFINITION MODULE EasyWindow; (* NeuImplementation und Anpassung von : *) (* MODULE WindowBase; *) (* Hans Endl 25. 09. 1986 *) (* 02. 06. 1987 *) (* 01. 10. 1987 *) (**************************************************************************) (* Mit der Einfhrung von WinX und MultiGEM stehen nun mehr als 8 Fenster *) (* unter GEM zur Verfgung. *) (* Die Tricksereien mit Aktivate und Deaktivate zur Verwaltung von 12 *) (* Fenstern sind also hinf„llig geworden. *) (* Zudem sind hier nun auch die Interna des Modules zug„nglich. *) (* BugFixes und Verbesserungen lassen sich also ohne weiteres vornehmen. *) (**************************************************************************) FROM SYSTEM IMPORT ADDRESS,BYTE; FROM GEMVDIbase IMPORT PxyArrayType; (* Dieses Modul stellt eine Zwischenschicht zur Fensterprogrammierung zur Verfgung, die etwas komfortablere Funktionen als die reinen AES-Aufrufe enth„lt, aber nicht so sehr einschr„nkt wie die auf MEDOS basierenden Moduln "Windows", "TextWindows" und "Graphic- "Windows". Wichtige Bestandteile von "WindowBase" sind - die Struktur "windowtype", die die unter AES am h„ufigsten ben”tigten Fensterdaten enth„lt - Prozeduren zum Setzen der Schieber - die automatische Abarbeitung der Rechteckliste bei Redraw- Aufrufen *) CONST (* ehemals : *) (* maxwindow = 12; (* 7 Fenster in GEM-AES m”glich + 5 fr Debugger *) *) (* *) (*neu*) maxwindow = 127; (* ge„ndert fr WinX und MultiTOS ... *) deskhandle = 0; (*neu*) (* Window-Arrowed Ergebnisse *) WindowUpPage=0; WindowDownPage=1; WindowUpLine=2; WindowDownLine=3; WindowLeftPage=4; WindowRightPage=5; WindowLeftLine=6; WindowRightLine=7; (* eigentlich sollten diese ereignisse in GEMAESBase definiert sein *) TYPE window = INTEGER; (* Aus Grnden der Kompatibilit„t zu AES und MEDOS wird zur Iden- tifikation eines Fensters nicht ein Zeiger auf den unten defi- nierten Window-Record benutzt, sondern eine Integer-Zahl, die mit dem AES-Window-Handle identisch ist und als Index eines Feldes von ((*neu*)POINTER TO) Window-Records fungiert. *) rectangle = RECORD x: INTEGER; (* x-Koordinate der linken oberen Ecke *) y: INTEGER; (* y-Koordinate der linken oberen Ecke *) w: INTEGER; (* Breite *) h: INTEGER (* H”he *) END; (* Definition eines Rechtecks in AES-spezifischer Form mit linker oberer Ecke und Breite und H”he in Pixeln, im Gegensatz zu der vom VDI meist benutzten Form des PxyArrays, das durch zwei dia- gonal gegenberliegende Ecken definiert wird. *) WindowElement = (Title, CloseButton, FullButton, Moveable, InfoLine, SizeButton, UpArrow, DownArrow, VertSlider, LeftArrow, RightArrow, HorizSlider); WindowElements = SET OF WindowElement; (*neu*) Effects = (Bold,Light,Italic,Underlined,Outlined,Shaded); (*neu*) TextEffects = SET OF Effects; CONST AllElements = WindowElements {Title..HorizSlider}; NoElements = WindowElements{}; (*neu*) NoEffects = TextEffects{}; TYPE wstring = ARRAY [0..79] OF CHAR; (* String fr Titel und Info *) RedrawProcType = PROCEDURE (window, rectangle); windowtype = RECORD handle: INTEGER; (* AES-Fensternummer *) max: rectangle; (* Maximale Fenstergr”že *) total: rectangle; (* Aussenmasse des Fensters *) work: rectangle; (* Innenmasse des Fensters *) (*neu*) min: rectangle; (* Minimale Fenstergr”že *) elements: WindowElements; (* Menge der Fensterelemente*) fulled: BOOLEAN; (* Fenster auf max gesetzt *) opened: BOOLEAN; (* Fenster ge”ffnet *) ontop: BOOLEAN; (* TRUE, falls oberstes F. *) text: BOOLEAN; (* TRUE, falls Textfenster *) (*neu*) grow: BOOLEAN; (* Wenn diese Variable auf TRUE gesetzt ist, w„chst bzw. schrumpft das Fenster beim ™ffnen bzw. Schliessen *) (*neu*) snap: BOOLEAN; (* Fenster Snappen *) (*neu*) allignX, (*neu*) allignY : INTEGER; (* horizontale /vertikale Ausrichtung *) (*neu*) scrollX, (*neu*) scrollY : INTEGER; (* Scrollwert : um diesen Betrag wird der Fensterinhalt bei Bet„tigen der Schieber gerollt *) row, col: INTEGER; (* Zeile und Spalte bei Text Pixel bei Grafik *) maxrow: INTEGER; (* letzte Zeile *) maxcol: INTEGER; (* letzte Spalte *) colour: INTEGER; (* Hintergrundfarbe *) CASE :BOOLEAN OF TRUE: style: INTEGER; (* Flltyp fr Hintergrund *) |FALSE: (*neu*) InteriorStyle : BYTE; (*neu*) FillStyle : BYTE; (* so ist es einfacher den Flltyp einzustellen*) END(*CASE*); textcolour: INTEGER; (* Farbe des Textes *) (*neu*) texteffects:TextEffects; (* Text-Effekte *) redrawproc: RedrawProcType; (* Redraw-Procedure *) title: wstring; (* Titelzeile *) info: wstring; (* Informationszeile *) reference: ADDRESS; (* frei fr Anwender *) END; TYPE windowptr = POINTER TO windowtype; VAR (*neu*) windowlist: ARRAY [-1..maxwindow] OF windowptr; (* In WindowBase war es noch : windowlist: ARRAY [0..maxwindow] OF windowtype; aber mit der gr”žeren Anzahl von Fenstern ist es gnstiger hier ein speicherplatzsparenderes ARRAY zu benutzen. Nicht vorhandene ( mit createWindow erzeugte )Fenster belegen hier nur den Speicherplatz eines POINTERs (4 BYTE) und nicht den eines ganzen WindowTypes *) (* Default Werte *) growbox: BOOLEAN; (* Wenn diese Variable auf TRUE gesetzt ist, wachsen bzw. schrumpfen die Fenster beim ™ffnen bzw. Schliessen, default = TRUE *) (*neu*) Snap: BOOLEAN; (* Fenster Snappen Ja/Nein,default = FALSE *) (*neu*) AllignX, (*neu*) AllignY : INTEGER; (* horizontale /vertikale Ausrichtung Default = 1/1 *) (*neu*) PROCEDURE TerminateWindows;(* Alle Fenster schliežen (AES.CloseWindow), ihre handles freigeben (AES.DeleteWindow) und den Speicherplatz fr die MODULE-interne Verwaltung freigeben (STORAGE.DEALLOCATE). !!!!! ACHTUNG !!!!!! Unbedingt vor Verlassen des Programmes aufrufen !! *) PROCEDURE createWindow (VAR u: window; x, y, w, h: INTEGER; parts: WindowElements; title: ARRAY OF CHAR; textwindow: BOOLEAN; rdp: RedrawProcType); (* Erzeugt die im AES und in diesem Modul notwendigen Datenstrukturen zur Verwaltung eines Fensters, das jedoch noch nicht gezeichnet wird. x, y, w und h beschreiben die maximale Gr”sse des „usseren Fenster- randes. Sind w und h gleich 0, so wird die Gr”sse des Desktops ohne Menleiste bernommen. "parts" ist ein Set aus den gewnschten Fensterelementen. "title" ist der Fenstertitel. "textwindow" soll bei Textfenstern auf TRUE gesetzt werden, der Fensterursprung wird dann an das Textraster angepažt. "rdp" ist die Redraw-Prozedur, also die Prozedur, die den Inhalt des Fensters zeichnet. Sie wird beim Aufruf der Prozedur "DoRedraw" (siehe unten) so oft aufgerufen wird, bis die Rechteckliste, die die sichtbaren Teile des Fensters angibt, abgearbeitet worden ist. An "rdp" wird beim Aufruf ein Rechteck bergeben, das die neu zu zeichnende Fl„che angibt. Wurde beim Aufruf von "DoRedraw" der Paramter "clip" auf FALSE gesetzt, muss "rdp" alle Ausgaben selbst auf diese Fl„che begrenzen, was die Ausgabe vor allem bei Text stark beschleunigen kann, aber bei teilweise verdeckten Fen- stern kaum durchfhrbar ist. Beim Zeichnen von Objektb„umen wird das Begrenzungsrechteck direkt beim "ObjectDraw"-Aufruf angegeben. *) (*neu*) (* ersatzlos getrichen : *) (* PROCEDURE activate (u: window); *) (* PROCEDURE deactivate (u: window); *) (* wird nicht mehr ben”tigt da nun gengend Fenster zur Verfgung stehen *) PROCEDURE clearWindow (u: window ); PROCEDURE closeWindow (u: window ); PROCEDURE deleteWindow (VAR u: window ); (* window wird auf -1 gesetzt! *) PROCEDURE fullWindow (u: window ); PROCEDURE openWindow (u: window ; x, y, w, h: INTEGER); (* falls x,y,w,h =0 wird die vorige Gr”sse des Fensters wiederhergestellt *) PROCEDURE setWindow (u: window ; x, y, w, h: INTEGER); PROCEDURE topWindow (u: window); PROCEDURE MouseOn; PROCEDURE MouseOff; (* Vor Ausgaben auf den Bildschirm muss die Maus ausgeschaltet werden, da sonst das Maussymbol berschrieben wird und bei der n„chsten Bewegung der Maus der alte, zuvor von der Maus verdeckte Bildschirm- inhalt wieder restauriert wird. Alle Prozeduren in diesem Modul, die den Bildschirm ver„ndern, schalten die Maus w„hrend der Ausgabe aus. W„hrend des Aufrufs der vom Benutzer bereitgestellten Redraw-Prozedur beim Abarbeiten der Rechteckliste in "DoRedraw" wird die Maus eben- falls ausgeschaltet, ruft der Benutzer dagegen selbst seine Redraw- Prozedur auf oder benutzt er die weiter unten beschriebenen Textaus- gabeprozeduren, muss er sich selbst um die Maus kmmern. Achtung: Ein- und Ausschalten der Maus wird vom Betriebssystem mitgez„hlt. Wird die Maus mehrmals ausgeschaltet, muž sie genausooft wieder eingeschaltet werden, damit sie sichtbar wird. Wird die Maus zu oft eingeschaltet, dann entstehen beim Bewegen von Fenstern und Schiebern Schmutz- effekte. *) PROCEDURE SetHorSlider (u: window ; wpos, wsize, total: INTEGER); (* siehe "SetVertSlider", setzt den horizontalen Schieber entsprechend der horizontalen Position des Fensters im Gesamtdokument. *) PROCEDURE SetInfo (u: window ; s: ARRAY OF CHAR); (* Schreibt einen Text in die Info-Zeile des Fensters *) PROCEDURE SetTitle (u: window ; s:ARRAY OF CHAR); (* Schreibt einen Text in die Titel-Zeile des Fensters. Der Text bleibt beim Schliessen erhalten und wird beim ™ffnen wieder angezeigt *) PROCEDURE SetVertSlider (u: window ; wpos, wsize, total: INTEGER); (* Berechnet die korrekte Position und -gr”sse des vertikalen Schiebers aus den Parametern, die die vertikale Position des Fensters im Gesamtdokument beschreiben, und setzt den Schieber. Die Schieber mssen, falls vorhanden, nach jeder Ver„nderung der Fenstergr”sse oder des Fensterinhalts neu gesetzt werden. Bedeutung der Parameter: wpos: Anfangsposition des Fensters im Gesamtdokument wsize: Gr”sse des im Fenster dargestellten Teils des Gesamtdokuments total: Gr”sse des Gesamtdokuments *) PROCEDURE clearrect (u: window ; rect: rectangle); (* L”scht einen Rechteckbereich innerhalb des Fensters "u" in Fensterkoordinaten *) PROCEDURE copyrect (u: window ; source, dest: rectangle); (* Kopiert innerhalb eines Fensters den Rechteckbereich "source" in den Rechteckbereich "dest" (Koordinaten relativ zum Fensterursprung links oben). Der freiwerdende Bereich von "source" muss bei Bedarf gel”scht werden. Mit dieser Prozedur lassen sich Scroll-, Insert- und Deletefunktionen in Textfenstern realisieren *) (* Achtung ! Dies funktioniert nur bei Fenstern die nicht verdeckt liegen. Vor Aufruf dieser Routine sollte berprft werden ob das Fenster das TopWindow ist *) PROCEDURE scrollup (u: window ); (* Schiebt den Inhalt eines Textfensters eine Zeile nach oben, die oberste Zeile verschwindet, die unterste wird gel”scht. "row" wird auf "maxrow", "col" auf 0 gesetzt *) (* Benutzt copyrect => berprfen ob Fenster ontop ist *) PROCEDURE scrolldown (u: window ); (* Schiebt den Inhalt eines Textfenster eine Zeile nach unten, die unterste Zeile verschwindet, die oberste wird gel”scht. "row" und "col" werden auf 0 gesetzt *) (* Benutzt copyrect => berprfen ob Fenster ontop ist *) PROCEDURE DrawCursor (u: window ; row, col: INTEGER); (* Zeichnet ein Rechteck in der Gr”sse eines Zeichenfeldes an die angegebene Stelle innerhalb des Fensters. Da alle Pixel inver- tiert werden, nimmt ein zweiter Aufruf mit denselben Parametern den Cursor wieder weg. *) (* noch nicht implementiert *) PROCEDURE WriteStr (u: window ; row, col: INTEGER; s: ARRAY OF CHAR); (* Gibt einen String ab der durch "row" (Zeile) und "col" (Spalte) angegebenen Stelle aus. Zeile und Spalte beziehen sich auf den Arbeitsbereich des Fensters. Das Zeichen in der linken oberen Ecke hat die Koordinaten (0,0). *) (* noch nicht implementiert *) PROCEDURE WriteTextBlock (u: window ; row, col: INTEGER; adr: ADDRESS; count: INTEGER); (* Wie "WriteStr", nur wird der auszugebende String durch die Adresse des ersten Zeichens und die L„nge angegeben *) (* noch nicht implementiert *) PROCEDURE WriteTextBuffer (u: window ; adr: ADDRESS; count, offset: INTEGER); (* Gibt den ab der Adresse "adr" liegenden Text ins Fenster "u" ab der Position (0,0) aus, bis entweder 0C im Text auftritt, "count" erreicht wird oder das Fenster voll ist. Als Zeilenende wird lf erkannt, cr wird ignoriert. Falls "offset" > 0, werden die ersten "offset" Zeichen in jeder Zeile bersprungen, so dass sich hori- zontale Fensterverschiebungen realisieren lassen. Diese Prozedur eignet sich gut fr das Redrawing von Textfensterpuffern. *) (* noch nicht implementiert *) PROCEDURE RectToPxy (VAR rect: rectangle; VAR pxy: PxyArrayType); (* Wandelt die Koordinaten eines Rechtecks von der "rectangle"-Form "PxyArray"-Form um (siehe obige Definition) *) PROCEDURE DoRedraw (u: window ; x, y, w, h: INTEGER; clip: BOOLEAN); (* Holt sich von AES die Rechteckliste des Fensters w, schneidet die erhaltenen Rechtecke mit dem Desktop und der als Parameter ber- gebenen Fl„che und fhrt dann die erforderliche Anzahl von Auf- rufen der Redraw-Prozedur, die beim Create-Aufruf angegeben wurde, aus. "DoRedraw" ist somit die Aktion auf eine Redraw-Message. Mit "clip" kann angegeben werden, ob "DoRedraw" selbst den Clipping- Aufruf fr VDI-Funktionen durchfhren soll. In jedem Fall wird w„hrend des Ablaufs von "DoRedraw" das Window-Update-Flag gesetzt und die Maus ausgeschaltet. *) (*neu*) (* ersatzlos getrichen : *) (* PROCEDURE wd (handle: INTEGER): window; *) (* wird nicht mehr ben”tigt da nun gengend Fenster zur Verfgung stehen *) PROCEDURE wp (u: window): windowptr; END EasyWindow.