Extended Object Library (Pure C)

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
Aus:ST-Computer 12 /1991, Seite

Links

Copyright-Bestimmungen: siehe Über diese Seite