Per dubbi, consigli o richieste, potete mandare un'e-mail ad Andrea Carolfi.
Ringraziamo Amiga Transactor Mailing List per questo tangibile contributo!
Bordi e Bottoni Intuition, fin dalle prime versioni, ha sempre permesso al programmatore di
creare le proprie interfaccie mettendo a disposizione solo le primitive minime
necessarie ed alcune strutture da inizializzare nel modo opportuno.
In questo modo però, da una parte il programmatore poteva esprimere
tutta la sua creatività in una interfaccia magari di dubbio gusto,
dall'altra l'utente si ritrovava innumerevoli interfaccie senza niente in
comune o quasi. Infatti, a partire dalla versione 2.0 del SO, con
l'introduzione della gadtools.library, la Commodore pose delle direttive
(ovviamente prese sotto gamba) per la realizzazione di interfaccie grafiche
"standard". Di fatto, la gadtools.library mette a disposizione alcune nuove
strutture e procedure, fatte a posta per creare in maniera più
intuitiva gadget, bordi e menù; anche perchè le vecchie
strutture di fatto erano poco intuitive e per creare anche un solo bottone
era necessario stendere decine di righe di codice di inizializzazione prima
di vedere comparire il bottone voluto (come vedremo infatti nel sorgente
di esempio). Bordi /* ======================================================================== */ /* === Border ============================================================= */ /* ======================================================================== */ /* Data type Border, used for drawing a series of lines which is intended for * use as a border drawing, but which may, in fact, be used to render any * arbitrary vector shape. * The routine DrawBorder sets up the RastPort with the appropriate * variables, then does a Move to the first coordinate, then does Draws * to the subsequent coordinates. * After all the Draws are done, if NextBorder is non-zero we call DrawBorder * on NextBorder */ struct Border { WORD LeftEdge, TopEdge; /* initial offsets from the origin */ UBYTE FrontPen, BackPen; /* pens numbers for rendering */ UBYTE DrawMode; /* mode for rendering */ BYTE Count; /* number of XY pairs */ WORD *XY; /* vector coordinate pairs rel to LeftTop */ struct Border *NextBorder; /* pointer to any other Border too */ };
Questa struttura, permette di disegnare un bordo di qualsiasi forma e di un
qualsiasi colore presente nella palette dello schermo utilizzato. Nel listato
di esempio vedremo un esempio di inizializzazione. void DrawBorder( struct RastPort *rp, struct Border *border, long leftOffset, long topOffset ); A partire con la versione 2.0 del SO, se vogliamo disegnare una cornice in "3D" (ovvero con il bordo sinistro e superiore bianchi e destro ed inferiore neri o viceversa) possiamo, invece di dichiarare due strutture Border e relativi array di coordinate (che sono anche difficili da gestire nel caso di eventuale finestra ridimensionabile o font-sensitive), utilizzare la procedura: void DrawBevelBoxA( struct RastPort *rport, long left, long top, long width, long height, struct TagItem *taglist ); void DrawBevelBox( struct RastPort *rport, long left, long top, long width, long height, Tag tag1, ... );
che vedremo nel dettaglio successivamente quando tratteremo la
gadtools.library. Bottoni /* ======================================================================== */ /* === Gadget ============================================================= */ /* ======================================================================== */ struct Gadget { struct Gadget *NextGadget; /* next gadget in the list */ WORD LeftEdge, TopEdge; /* "hit box" of gadget */ WORD Width, Height; /* "hit box" of gadget */ UWORD Flags; /* see below for list of defines */ UWORD Activation; /* see below for list of defines */ UWORD GadgetType; /* see below for defines */ /* appliprog can specify that the Gadget be rendered as either as Border * or an Image. This variable points to which (or equals NULL if there's * nothing to be rendered about this Gadget) */ APTR GadgetRender; /* appliprog can specify "highlighted" imagery rather than algorithmic * this can point to either Border or Image data */ APTR SelectRender; struct IntuiText *GadgetText; /* text for this gadget */ /* MutualExclude, never implemented, is now declared obsolete. * There are published examples of implementing a more general * and practical exclusion in your applications. * * Starting with V36, this field is used to point to a hook * for a custom gadget. * * Programs using this field for their own processing will * continue to work, as long as they don't try the * trick with custom gadgets. */ LONG MutualExclude; /* obsolete */ /* pointer to a structure of special data required by Proportional, * String and Integer Gadgets */ APTR SpecialInfo; UWORD GadgetID; /* user-definable ID field */ APTR UserData; /* ptr to general purpose User data (ignored by In) */ };
Ogni bottone creato, ha una struttura di questo tipo che lo descrive e che il
programmatore può modificare in alcune sue parti anche dopo la
creazione. Come si può capire dai puntatori GadgetRender e SelectRender, Intuition lascia molta libertà di scelta sull'aspetto esteriore del bottone che può essere un bordo o un'immagine. L'unica limitazione è dovuta dal fatto che Intuition gestisce solo bottoni rettangolari. Quindi è possibile, tramite una struttura Border o un'immagine disegnare un gadget rotondo o magari elissodale, ma Intuition utilizzera i campi LeftEdge, TopEdge, Width e Height per l'attivazione del bottone e non la sagoma dell'immagine. Se però si considera che mediamente l'utente preme il gadget in un "intorno" del suo centro, è possibile ottenere lo stesso l'effetto voluto che però non funzionerà nel 100% dei casi. Flag per la struttura Gadget Vediamo adesso come devono essere inizializzati i vari campi. /* --- Valori per il campo Gadget.Flags --- */ /* Le combinazioni di questi bit descrivono la tecnica di illuminazione usata */ /* per evidenziare un bottone selezionato */ #define GFLG_GADGHCOMP 0x0000 /* Complement the select box */ #define GFLG_GADGHBOX 0x0001 /* Draw a box around the image */ #define GFLG_GADGHIMAGE 0x0002 /* Blast in this alternate image */ #define GFLG_GADGHNONE 0x0003 /* don't highlight */ #define GFLG_GADGIMAGE 0x0004 /* set if GadgetRender and SelectRender * point to an Image structure, clear * if they point to Border structures */ #define GFLG_SELECTED 0x0080 /* you may initialize and look at this */ /* the GFLG_DISABLED flag is initialized by you and later set by Intuition * according to your calls to On/OffGadget(). It specifies whether or not * this Gadget is currently disabled from being selected */ #define GFLG_DISABLED 0x0100 /* These flags specify the type of text field that Gadget.GadgetText * points to. In all normal (pre-V36) gadgets which you initialize * this field should always be zero. Some types of gadget objects * created from classes will use these fields to keep track of * types of labels/contents that different from IntuiText, but are * stashed in GadgetText. */ #define GFLG_LABELITEXT 0x0000 /* GadgetText points to IntuiText */ #define GFLG_LABELSTRING 0x1000 /* GadgetText points to (UBYTE *) */ #define GFLG_LABELIMAGE 0x2000 /* GadgetText points to Image (object) */ /* New for V39: If set, this bit means that the Gadget is actually * a struct ExtGadget, with new fields and flags. All V39 boopsi * gadgets are ExtGadgets. Never ever attempt to read the extended * fields of a gadget if this flag is not set. */ #define GFLG_EXTENDED 0x8000 /* Gadget is extended */ /* --- Valori per il campo Gadget.Activation --- */ /* Set GACT_RELVERIFY if you want to verify that the pointer was still over * the gadget when the select button was released. Will cause * an IDCMP_GADGETUP message to be sent if so. */ #define GACT_RELVERIFY 0x0001 /* the flag GACT_IMMEDIATE, when set, informs the caller that the gadget * was activated when it was activated. This flag works in conjunction with * the GACT_RELVERIFY flag */ #define GACT_IMMEDIATE 0x0002 /* --- Valori per il campo Gadget.GadgetType --- */ #define GTYP_BOOLGADGET 0x0001 #define GTYP_GADGET0002 0x0002 #define GTYP_PROPGADGET 0x0003 #define GTYP_STRGADGET 0x0004 #define GTYP_CUSTOMGADGET 0x0005 |
![]() |
![]() |