Corso di AmigaOS

Torna all'elenco delle lezioniPer dubbi, consigli o richieste, potete mandare un'e-mail ad Andrea Carolfi.
Ringraziamo Amiga Transactor Mailing List per questo tangibile contributo!


Intuition (Quattordicesima lezione)

In questa lezione vedremo ulteriori funzioni che Intuition mette a disposizione per gestire finestre, schermi e requester.

Procedure e funzioni sulle finestre

Cominciamo a vedere quelle riguardanti alle finestre:

  • BOOL ModifyIDCMP( struct Window *window, unsigned long flags );
  • void SetWindowTitles( struct Window *window, UBYTE *windowTitle,UBYTE *screenTitle );
  • void MoveWindow( struct Window *window, long dx, long dy );
  • void SizeWindow( struct Window *window, long dx, long dy );
  • void WindowToBack( struct Window *window );
  • void WindowToFront( struct Window *window );
  • void ActivateWindow( struct Window *window );
  • void MoveWindowInFrontOf( struct Window *window,struct Window *behindWindow );
  • void ChangeWindowBox( struct Window *window, long left, long top, long width, long height );
  • void PrintIText( struct RastPort *rp, struct IntuiText *iText, long left, long top );

Quasi tutte queste funzioni, spiegano la loro funzione con il loro nome, ma vediamole nel dettaglio:
la ModifyIDCMP, serve per modificare gli IDMCP di una finestra. Alcune lezioni fa, avevo introdotto il discorso delle porte messaggi usate da Intuition per comunicare al processo che possiede una finestra, determinate situazioni.
Specificare quali situazioni farsi segnalare da Intuition, era compito del task impostando gli opportuni IDCMP nell'apertura della finestra. E' possibile comunque, che nel corso dell'esecuzione del programma, certi particolari messaggi non ci occorrano più o addirittura, non abbiamo più bisogno della porta messaggi. In questo caso, questa funzione si incarica di modificare i suddetti flag a seconda di quello specificato. La descrizione completa di tutti gli IDCMP, sono nella sezione degli autodoc che descrive questa funzione. Aggiungo che per chiudere la porta messaggi basta: ModifyIDCMP(win,0).

La SetWindowTitles, imposta il titolo della finestra e dello schermo, quando questa finestra è selezionata. Se vogliamo modificare solo uno dei due senza toccare l'altro è sufficente passare come parametro -1, cioè:
SetWindowTitles(win,"Pippo",(STRPTR)-1); e cambierà il titolo della finestra in Pippo, lasciando invariato quello dello schermo.

WindowToBack, WindowToFront e ActivateWindow, mi sembrano sufficentemente chiare e non credo necessitano di ulteriori spiegazioni.

Un discorso a parte, meritano MoveWindow, SizeWindow e ChangeWindowBox.
Come i nomi della prime due lasciano intendere, queste due procedure servono rispettivamente per muovere una finestra e per cambiarne la dimensione. La terza riassiume le prime due in un'unica procedura. Con la differenza che le sue coordinate e dimensioni sono assolute mentre quelle delle altre due procedure sono relative. Ossia, è possibile chiamare MoveWindow(win,-5,-10); che sposterà verso sinistra di cinque pixel e verso l'alto di dieci pixel la finestra. Lo stesso, è possibile fare SizeWindow(win,-5,10); che restringerà la larghezza della finestra di cinque pixel ed aumenterà l'altezza di dieci.

Invece, la ChangeWindowBox, deve essere chiamata in questo modo (ad esempio):
ChangeWindowBox(win,30,120,250,50) che posizionerà la finestra a trenta pixel dal bordo sinistro dello schermo a centoventi pixel dal bordo superiore con una dimensione di duecentocinquanta pixel per cinquanta. Ovviamente, queste funzioni compiono dei controlli sui parametri passati per assicurarsi che siano legali (la finestra non esca dallo schermo), ma se magari specifichiamo una dimensione che ci taglia via dei gadget, sarà solo colpa nostra.

La PrintIText, serve per visualizzare del testo su una finestra (una specie di printf() grafica). Specificando un font già aperto da usare (spiegheremo più avanti come fare per aprire un font) tramite la struttura IntuiText visualizzerà il testo specificato alla posizione specificata.
Ad esempio:

struct IntuiText testo2 = {2,0,JAM1,NULL,10,NULL,"Testo di prova2",NULL};
struct IntuiText testo1 = {1,0,JAM1,NULL,NULL,NULL,"Testo di prova1",&testo2};

[...]
PrintIText(win -> RPort,&testo1,10,30);

visualizzerà il primo testo con il colore 1, alla posizione 10, 30 ed il secondo testo con il colore 2, alla posizione 10, 40.
Da notare, che l'hotspot dei caratteri è in basso a sinistra e non in alto a sinistra. Cioè, se stampiamo un font alla posizione 0,0 questo esce fuori dalla finestra per tutta la sua altezza. Per stampare del testo, una riga dopo l'altra occorre quindi tener conto dell'altezza del font.

Infine, la MoveWindowInFrontOf è una versione un pò più flessibile di WindowToBack e WindowToFront. E' possibile posizionare la nostra finestra sopra un'altra avendo a disposizione il suo puntatore.

Procedure sugli schermi

Vediamo adesso alcune procedure aggiuntive sugli schermi:

  • BOOL WBenchToBack( void );
  • BOOL WBenchToFront( void );
  • void MoveScreen( struct Screen *screen, long dx, long dy );
  • void ScreenToBack( struct Screen *screen );
  • void ScreenToFront( struct Screen *screen );

Le varie ToBack e ToFront, servono per portare uno schermo o il Workbench in primo piano o sullo sfondo. Mentre la MoveScreen serve per posizionare lo schermo (dragging). A partire dalla versione 2.0 del SO, è possibile specificare anche l'ascissa, mentre le versioni precedenti richiedevano che il bordo sinistro dello schermo fosse sempre a zero. Anche quì, come nella MoveWindow le coordinate sono relative e non assolute.

Requester

Vediamo adesso come poter segnalare un errore o un messaggio all'utente tramite un requester.
Il modo più semplice è di usare la:

LONG EasyRequestArgs( struct Window *window, struct EasyStruct *easyStruct,
        ULONG *idcmpPtr, APTR args );
LONG EasyRequest( struct Window *window, struct EasyStruct *easyStruct,
        ULONG *idcmpPtr, ... );

struct EasyStruct {
         ULONG   es_StructSize; /* should be sizeof (struct EasyStruct )*/
         ULONG   es_Flags;   /* should be 0 for now        */
         UBYTE   *es_Title;  /* title of requester window     */
         UBYTE   *es_TextFormat;   /* 'printf' style formatting string */
         UBYTE   *es_GadgetFormat; /* 'printf' style formatting string */
};

Questa funzione, restituisce il numero di bottone che l'utente ha premuto. Questi sono numerati a partire da 0 (che è l'ultimo a destra considerato come risposta negativa) fino ad n.

Vediamo un esempio:

struct EasyStruct ES = {
        sizeof(struct EasyStruct),
        0,
        "Messaggio di errore"
        "Impossibile aprire il file %s!\n",
        "Ok"
};

[...]

EasyRequest(win,&ES,NULL,nomefile);

Oltre ad una chiamata così semplice, è possibile impostare degli IDCMP che possano far cancellare il requester (ad esempio sulla richesta di un disco) e specificare più di un parametro e più di un bottone (separandoli da un |, cioè "Ok|Riprova|Annulla"). Sempre negli autodoc c'è un listato di esempio più alcuni riferimenti ad altre funzioni che possono compiere lo stesso compito. Quale la BuiltEasyRequest. A tal proposito, merita di essere mostrato in questa sede un sorgente di esempio che mostra come visualizzare un requester che non blocca l'applicazione che l'ha chiamata, tramite l'uso della funzione SysReqHandler. Vediamolo:

window = BuildEasyRequest( ... ); // Rispetto alla EasyRequestArgs restituisce
                                                                                        // il ptr alla finestra del requester.

while((retval = SysReqHandler(window,idcmp_ptr,TRUE)) == -2)
{
        / * loop */
}
FreeSysRequest(window);

Lezione precedente Indice delle lezioni Lezione successiva
Copyright AMiWoRLD Ph0ton