Per dubbi, consigli o richieste, potete mandare un'e-mail ad Andrea Carolfi.
Ringraziamo Amiga Transactor Mailing List per questo tangibile contributo!
Ma vediamo quello che mette a disposizione Intuition che sono comunque molto utili per la completezza di un programma di una certa dimensione. Struttura Menu e MenuItem Prima di introdurre le funzioni della Gadtools che permettono di definire una intera 'menustrip', vediamo nello specifico come sono formate le strutture Menu e MenuItem dichiarate nel file intuition/intuition.h: /* ======================================================================== */ /* === Menu =============================================================== */ /* ======================================================================== */ struct Menu { struct Menu *NextMenu; /* Puntatore al prossimo */ WORD LeftEdge, TopEdge; /* Posizione del box di selezione */ WORD Width, Height; /* Dimensione del box di selezione */ UWORD Flags; /* Flags tra quelli definiti sotto */ BYTE *MenuName; /* Testo per questo menù */ struct MenuItem *FirstItem; /* Puntatore alla prima opzione */ /* Queste variabili dal nome misterioso sono solo per uso interno */ WORD JazzX, JazzY, BeatX, BeatY; }; /* FLAGS IMPOSTATI SIA DALL'APPLICAZIONE CHE DA INTUITION */ #define MENUENABLED 0x0001 /* Questo menù è o no abilitato */ Vediamo adesso la struttura MenuItem: /* ======================================================================== */ /* === MenuItem =========================================================== */ /* ======================================================================== */ struct MenuItem { struct MenuItem *NextItem; /* Puntatore alla prossima opzione */ WORD LeftEdge, TopEdge; /* Position del box di selezione */ WORD Width, Height; /* Dimensione del box di selezione */ UWORD Flags; /* Flags definiti più in basso */ LONG MutualExclude; /* Bits per la mutua exclusione con altre opz */ APTR ItemFill; /* Puntatore a Image, IntuiText, o NULL */ /* Quando questa opzione è puntata dal cursore e la modalità di evidenziazione * HIGHIMAGE è selezionata, sarà visualizzata questa immagine alternativa */ APTR SelectFill; /* Puntatore a Image, IntuiText, o NULL */ BYTE Command; /* Solo se l'applic imposta il flag COMMSEQ */ struct MenuItem *SubItem; /* Se non-zero, punta ad un sotto menù */ /* Il campo NextSelect rappresenta il numero di menù della opzione successiva * selezionata (quando l'utente ha selezionato più cose) */ UWORD NextSelect; }; /* FLAGS IMPOSTATI DALL'APPLICAZIONE */ #define CHECKIT 0x0001 /* L'opzione potrà avre un checkmark */ #define ITEMTEXT 0x0002 /* Se impostato l'opzione è testuale, altrimenti è grafica */ #define COMMSEQ 0x0004 /* Se esiste una short-cut */ #define MENUTOGGLE 0x0008 /* Per la mutua esclusione */ #define ITEMENABLED 0x0010 /* Opzione abilitata */ /* questi sono i significati dei SPECIAL HIGHLIGHT FLAG */ #define HIGHFLAGS 0x00C0 /* see definitions below for these bits */ #define HIGHIMAGE 0x0000 /* Usa l'immagine dell'utente */ #define HIGHCOMP 0x0040 /* Evidenzia complementando il box di selezione */ #define HIGHBOX 0x0080 /* Evidenzia riquadrando il box di selezione */ #define HIGHNONE 0x00C0 /* Non evidenziare */ /* FLAGS IMPOSTATI SIA DALL'APPLICAZIONE CHE DA INTUITION */ #define CHECKED 0x0100 /* Stato del checkmark */Ora, come potete vedere, definire un certo numero di menù con una certa serie di opzioni, sarebbe un lavoro (e lo era prima di GadTools) davvero oneroso, dovendo valorizzare per ogni singolo menù una struttura Menu e per ogni opzione di ogni menù una struttura MenuItem. La difficoltà maggiore, però la si riscontrava principalmente nella definizione della 'selectbox' (letteralmente la scatola di selezione) che dovrebbe contenere il testo o l'immagine del menù. Infatti il problema principale era che bisognava calcolarsi l'occupazione del testo con il font utilizzato (guai se cambiava, allora sballava tutto) poi lasciare un po di margine sennò tutto veniva appiccicato, ecc. Per non parlare del fatto che il sorgente si allungava parecchio. Fortunatamente con l'introduzione della gadtools.library le cose sono state di molto facilitate ed automatizzate. Vediamo come. Struttura NewMenu Nel file libraries/gadtools.h è dichiarata una struttura NewMenu che serve per la definizione di un'intera 'menustrip'. Come dice il commento: /* Fill out an array of these and pass that to CreateMenus(): */ basta definire un array di queste e passarla alla CreateMenus. struct NewMenu { UBYTE nm_Type; /* Vedi sotto */ /* Il compilatore inserisce un byte PAD quì */ STRPTR nm_Label; /* Etichetta del menù */ STRPTR nm_CommKey; /* Scorciatoia da tastiera */ UWORD nm_Flags; /* Flags della struttura Menu o MenuItem (vedi note) */ LONG nm_MutualExclude; /* MenuItem MutualExclude word */ APTR nm_UserData; /* Per uso personale, vedi note */ }; /* Necessario solo dentro la definizione di IM_ */ #define MENU_IMAGE 128 /* nm_Type determina a cosa ogni struttura NewMenu corrisponde. * Per i valori NM_TITLE, NM_ITEM e NM_SUB, nm_Label dovrebbe essere una * stringa di testo da usare per quel titolo di menù, opzione o sotto-opzione. * Per IM_ITEM o IM_SUB, imposta nm_Label a puntare ad una struttura Image * che desideri usare per questa opzione o sotto-opzione. * NOTA: Al presente, puoi solo usare immagini convenzionali. * Immagini custom create dalle classi image di Intuition non funzionano. */ #define NM_TITLE 1 /* Titolo menù */ #define NM_ITEM 2 /* Opzione menù testuale */ #define NM_SUB 3 /* Sotto-opzione menù testuale */ #define IM_ITEM (NM_ITEM|MENU_IMAGE) /* Opzione menù grafica */ #define IM_SUB (NM_SUB|MENU_IMAGE) /* Sotto-opzione menù grafica */ /* L'array di NewMenu dovrebbe essere terminato con un NewMenu dove * nm_Type è uguale a NM_END. */ #define NM_END 0 /* Fine dell'array di NewMenu */ /* A partire con la V39, GadTools salterà ogni NewMenu dove il campo * nm_Type ha il bit NM_IGNORE impostato. */ #define NM_IGNORE 64 /* nm_Label dovrebbe essere una stringa di testo per le opzioni testuali, un * puntatore ad una struttura Image per le opzioni di menù grafiche o la * costante speciale NM_BARLABEL, per ottenere una barra separatrice. */ #define NM_BARLABEL ((STRPTR)-1) /* Il campo nm_Flags è usato per riempire o il campo Menu->Flags o * MenuItem->Flags. Notare che il senso dei bit MENUENABLED o * ITEMENABLED è invertito tra questo uso e quello di Intuition, * in altre parole, i NewMenus sono abilitati per default. Le etichette * seguenti sono provviste per disabilitarli: */ #define NM_MENUDISABLED MENUENABLED #define NM_ITEMDISABLED ITEMENABLED /* Nuovo per la V39: NM_COMMANDSTRING. Per una opzione o sotto-opz testuale, * fai puntare nm_CommKey ad una stringa arbitraria ed imposta il flag * NM_COMMANDSTRING. */ #define NM_COMMANDSTRING COMMSEQ /* Un puntatore UserData può essere associato ad ogni struttura Menu e MenuItem. * La CreateMenus() alloca spazio per un UserData dopo ogni Menu o MenuItem * (titolo, opzione o sotto opzione). Dovresti usare le macro * GTMENU_USERDATA() o GTMENUITEM_USERDATA() per estrarlo. */ #define GTMENU_USERDATA(menu) (* ( (APTR *)(((struct Menu *)menu)+1) ) ) #define GTMENUITEM_USERDATA(menuitem) (* ( (APTR *)(((struct MenuItem *)menuitem)+1) ) ) Procedure GadTools sui menù Abbiamo quindi visto la struttura che ci mette a disposizione Gadtools e più o meno dovrebbe essere chiaro come inizializzarla (spero! :-) ). Vediamo adesso quali procedure dobbiamo usare per vedere apparire i nostri menù:
Visto che ormai dovreste aver imparato che differenza c'è tra la
versione di funzione con la struct TagItem * e quella con Tag,
vediamo a cosa servono.
Dopo ciò se abbiamo un solo menù possiamo usare la 3 che serve proprio per creare un solo menù, altrimenti se abbiamo una serie di menù dobbiamo usare la 4. I tag che hanno in comune queste due funzioni sono:
Apro una parentesi, non mi do del noi (come il mago Otelma), ho solo tradotto dall'inglese la documentazione della gadtools, dove parla dei tag. :-) Chiusa parentesi. Il tag che la 3 ha in più rispetto alla 4 è:
Infine, quando non avremo più bisogno dei menù li potremo liberare in una botta con la 2. Il discorso è lungi dall'essere finito, infatti occorre sapere come
collegare un menù ad una finestra, come toglierlo, come dis/abilitare
le opzioni e come ottenere i menù selezionati dall'utente.
che mi pare non abbiano bisogno di ulteriori spiegazioni. Per dis/abilitare un'opzione di menù, una sotto-opzione, un menù intero ecco le:
per quanto riguarda il discorso sul secondo paramero conviene rifarsi alla lezione nove, quando ho descritto come vengono identificati i menù in un numero a sedici bit. Nel sorgente allegato (non è più parte integrante della lezione, visto che è sempre lo stesso che cresce), le funzioni spiegate fanno bella mostra di sè creando un menù per il momento fittizio. Più in là, con le prossime lezioni, contribuiremo a renderlo più "vivo".
|