← ST-Computer 12 / 1991

Extended Object Library (Pure C)

Programmierpraxis

Nachdem im letzten Heft Routinen vorgestellt wurden, um die Extended Rectangle Library des GEM/3 für IBM-kompatible PCs in Pure C auf dem Atari zu realisieren, soll es nun darum gehen, auch die Extended Object Library umzusetzen.

Diese Bibliothek ermöglicht eine vereinfachte Verwaltung von Dialogen und stellt darüber hinaus Funktionen zur Verfügung, um einzelne Objekt-Flags sowie den Objektstatus gezielt manipulieren zu können. Um welche Routinen es sich handelt? Nun, hier eine Auflistung:

void ob_dostate(OBJECT*tree, int index, int state);
Mit Hilfe von ob dostate ist es möglich, gezielt das Status-Flag state im Objekt index des Objektbaums tree zu setzen.

*void ob_undostate(OBJECT tree, int index, int state);
ob_undostate ist das Gegenstück zu ob_dostate. Es wird also ein bestimmtes Flag zurückgesetzt.

*int ob_isstate(OBJECT tree, int index, int state);
Dieser Aufruf ermöglicht die Abfrage eines Status-Bits. Das Ergebnis ist TRUE, wenn das angesprochene Bit state gesetzt ist, andernfalls erhält man FALSE.

*void obdoflaglOBJECT tree, index, int flag);
ob_doflag erlaubt das Setzen eines einzelnen Objekt-Flags.

*void ob_undoflag(OBJECT tree, index, int flag);
Um ein Flag selektiv zurückzusetzen, steht ob_undoflag zur Verfügung.

*int ob_isflag(OBJECT tree, index, int flag);
Mit ob_isflag kann getestet werden, ob ein Objekt-Flag gesetzt ist. In diesem Fall wird TRUE zurückgeliefert.

**int ob_xywh(OBJECT tree, int index, GRECT prect); ob_xywh liefert die Ausmaße eines Objekts in Form einer GRECT-Struktur, die bereits im letzten Heft in Verbindung mit der Extended Raster Library angesprochen wurde.

char ob_get_text(OBJECT tree, int index, int clear);
Diese Funktion liefert einen Pointer auf einen Text-String zurück, falls das angegebene Objekt einen solchen enthält. Es muß sich also um ein Objekt des Typs G_TEXT, G_FTEXT, G_BOXTEXT, G_FBOXTEXT, G_STRING, G_BUTTON oder G_TITLE handeln.

Ist das Flag clear TRUE, wird das erste Zeichen des Strings zusätzlich durch eine Null überschrieben, was sich ausgezeichnet dazu eignet, Eingabefelder vor einem Dialog zu löschen.

**char *ob_set_text(OBJECT tree, int index, char ptr);
Ein neuer Textzeiger kann mit ob_set_text gesetzt werden, ptr zeigt in diesem Fall auf den String, der Bestandteil der Objektstruktur werden soll.

*int ob_draw_dialog (OBJECT tree, int x, int y, int w, int h);
ob_draw_dialog übernimmt das komplette Zeichnen einer zentrierten Dialogbox. Sind die Parameter x,y,w,h ungleich Null, wird zusätzlich eine sich bis auf Dialoggröße ausbreitende growbox mit den entsprechenden Startkoordinaten gezeichnet.

*int ob undraw_dialog(OBJECT tree, int x, int y, int w, int h);
Die Funktion dieses Aufrufs liegt auf der Hand. Nach Beendigung eines Dialogs kann optional eine shrinkbox gezeichnet werden, wenn die Parameter x,y,w,h die Koordinaten hierzu enthalten.

Alle Funktionsprototypen sind noch einmal im Listing von OBLIB.H zusammengefaßt.

Den Quellcode für die Extended Object Library enthält OBLIB.S. Assembliert wurde dieser Text mit dem MAS-Assembler. Natürlich eignet sich hierzu auch ein anderer Assembler. Spezifisch für Pure C ist die Übergabe der Funktionsparameter.

Die Verwendung der neuen Library-Routinen wird im Listing DIALOG.C demonstriert. ob draw dialog ersetzt alle Aufrufe von form_center und form dial. Das Rücksetzen des SELECTED-Status beim Exit-Button eines Dialogs erfolgt der Einfachheit halber mittels ob_undostate.

/*****************************************/ /* OBLIB.H Allgemeine OBLIB Definitionen */ /*****************************************/ /* */ /* Autor: Uwe Seimet */ /* (C) 1991 MAXON Computer */ /*****************************************/ #ifnde£ __OBLIB__ #define __OBLIB__ void ob_dostate ( OBJECT *tree, int index, int state ) ; void ob_undostate ( OBJECT *tree, int index, int state ); int ob_isstate ( OBJECT *tree, int index, int state ); void ob_doflag ( OBJECT *tree, int index, int flag ) ; void ob_undoflag ( OBJECT *tree, int index,int flag ); int ob_isflag ( OBJECT *tree, int index, int flag ); void ob_xywh ( OBJECT *tree, int index, GRECT *rec ); char *ob_get_text ( OBJECT *tree, int index, int clear ); void ob_set_text ( OBJECT *tree, int index, char *p ); void ob_draw_dialog ( OBJECT *tree, int x1, int y1, int w1, int h1 ); void ob_undraw_dialog ( OBJECT *tree, int x1, int y1, int w1, int h1 ); #endif /* ___OBLIB__ */ ; OBLIB.S ; (c) 1991 MAXON Computer globl ob_dostate globl ob_undostate globl ob_isstate globl ob_doflag globl ob_undoflag globl ob_isflag globl ob_xywh globl ob_get_text globl ob_set_text globl ob_draw_dialog globl ob_undraw_dialog globl form_center globl form_dial globl objc_draw G_TEXT = 21 G_BOXTEXT= 22 G_BUTTON =26 G_STRING =28 G_FTEXT =29 G_FBOXTEXT= 30 G_TITLE = 32 ob_dostate: mulu #24,d0 or d1,10(a0,d0) ;Statusbit setzen rts ob_undostate: not d1 mulu #24,d0 ;Statusbit zurücksetzen and d1,10(a0,d0) rts ob_isstate: mulu #24,d0 and 10(a0,d0),d1 ;Statusbit testen bne sset clr d0 rts sset: moveq #1,d0 rts ob_doflag: mulu #24,d0 or d1,8(a0,d0) ;Objektflag setzen rts ob_undo£lag: not d1 mulu #24,d0 and d1,8(a0,d0) ;Objektflag setzen rts ob_isflag: mulu #24,d0 and 8(a0,d0),d1 ;Objektflag testen bne fset clr d0 rts fset: moveq #1,d0 rts ob_xywh: mulu #24,d0 move.l 16(a0),(a1)+ move.l 20 (a0),(a1) rts ob_get_text: bsr typetest ;auf Objekttyp testen move.l (a0),a0 tst d1 ;String initialisieren? beq noinit ;nein- clr.b (a0) noinit: rts ob_set_text: bsr typetest move.l a1,(a0) ;neuen Stringpointer setzen rts typetest: mulu #24,d0 move.b 7(a0,d0),d2 ;Objekttyp cmp.b #G_TEXT,d2 beq text cmp.b #G_FTEXT,d2 beq text cmp.b #G_FBOXTEXT, d2 beq text cmp.b #G_BOXTEXT,d2 beq string cmp.b #G_STRING,d2 beq string cmp.b #G_BUTTON,d2 beq string cmp.b #G_TITLE,d2 beq string sub.1 a0,a0 addq.l #4,sp ;Abbruch, falls kein Textobjekt rts text: move.l 12(a0,d0),a0 rts string: lea 12(a0,d0),a0 rts ob_draw_dialog: link a6,#-16 bsr center clr -2(a6) ;FMD_START bsr dial move -4(a6),d0 ;x or -6(a6),d0 ;y or -8(a6),d0 ;w or 8(a6),d0 ;h beq nogrow ;keine growbox zeichnen- move #1,-2(a6) ;FMD_GROW bsr dial nogrow: lea -16(a6),a1 ;Pointer auf zentrierte Koordinaten move (a1)+,-(sp) ;h move (a1)+,-(sp) ;w move (a1)+,-(sp) ;y move (a1),d2 ;x moveq #127,d1 ;alle Ebenen (127 sollten reichen) clr d0 ;ab Ebene 0 bsr objc_draw addq.1 #6,sp unlk a6 rts ob_undraw_dialog: link a6,#-16 bsr center move -4(a6),d0 ;x or -6(a6),d0 ;y or -8(a6),d0 ;w or 8(a6),d0 ;h beq noshrink ;keine shrinkbox zeichnen- move #2,-2(a6) ;FMD_SHRINK bsr dial noshrink:move #3,-2(a6) ;FMD__FINISH bsr dial unlk a6 rts center: move d2,-8(a6) ;fo_dilittlw move d1,-6(a6) ;fo_dilittly move d0,-4(a6) ;fo_dilittlx move.l a0,-(sp) lea -10(a6),a1 pea -16 (a6) pea -14 (a6) pea -12 (a6) bsr form_center lea 12(sp),sp move.l (sp)+,a0 rts dial: move.l a0,-(sp) ;Objektadresse merken lea -16(a6),a1 ;Pointer auf zentrierte Koordinaten move (a1)+,-(sp) ;fo_dibigh move (a1)+,-(sp) ;fo_dibigw move (a1)+,-(sp) ;fo_dibigy move (a1),-(sp) ;fo_dibigx move 8(a6),(sp) ;fo_dilittlh move -8(a6),-(sp) ;fo_dilittlw move -6(a6),d2 ;fo_dilittly move -4(a6),d1 ;fo_dilittlx move -2(a6),d0 ;fo_diflag bsr form_dial lea 12(sp),sp move.l (sp)+,a0 rts /* Dialog mittels ob draw dialog, ob_undraw_dialog und ob_undostate */ /* tree erhält die Adresse des Objektbaums */ /* index ist die Nummer des ersten Eingabefeldes */ void dialog(tree,index) OBJECT *tree; int index; { int exit_obj; ob_draw_dialog(tree,40,40,4,4); /* Dialog mit growbox zeichnen */ exit_obj=form_do(tree,index); /* Benutzereingaben abwarten */ ob_undraw_dialog(tree,40,40,4,4); /* Dialog entfernen, shrinkbox */ ob_undostate(tree,exitobj,SELECTED); /* Exit-Button zurücksetzen */ return; /* so einfach ist das */ }
Uwe Seimet