Obligement - L'Amiga au maximum

Jeudi 25 avril 2024 - 08:07  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in english


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : MUI - communication, notification
(Article écrit par Mathias Parnaudeau - juillet 2004)


Chapitre 2

Ce chapitre réutilise bien sûr les bases du chapitre 1 et porte plus précisément sur l'interaction entre les composants. Toujours dans l'optique de notre lecteur de CD, nous lui attribuerons un bouton "Play" et un autre "Stop", les deux agissant sur un objet graphique Busy appartenant à une classe externe. Cet objet dynamique symbolisera la lecture d'un morceau en cours ; il se figera lors d'un clic sur "Stop".

La bibliothèque Busy.mcc, et ses includes, peut être récupérée sur : mui.zerohero.se/mcc/MCC_Busy.lha.

Complément

L'organisation du programme a légèrement changé. Les bibliothèques sont cette fois-ci ouvertes et fermées dans la fonction main. Mais l'intérêt porte sur la fonction CreateGui qui nous intéresse ; elle a changé en plusieurs points :

1. Les boutons sont créés différemment, avec l'appellation KeyButton ici, qui spécifie un raccourci clavier. D'autre part, ils sont affectés à une variable de type "Object *", c'est-à-dire un pointeur sur un composant MUI (objet BOOPSI en fait) alloué dynamiquement. On trouve parfois la notation "APTR" à la place, ce qui n'est pas une faute mais se trouve moins appropriée. La variable ainsi renseignée va permettre de communiquer avec le composant associé, comme c'était déjà le cas de la fenêtre (DoMethod() sur la variable window).

2. La description de l'interface présente une autre nouveauté : l'attribut MUIA_Application_UsedClasses. Mentionné dans le fichier MUIUndoc (voir sur Aminet), il n'est utilisé qu'à partir de MUI 3.9 : chaque classe externe est indiquée dans une liste de chaînes de caractères et fera que l'application ne fournira le panel des préférences que pour ces classes référencées. Voilà donc une bonne habitude à prendre. Comme cet attribut n'est pas défini dans les includes de bases, il doit être ajouté à la main au début du source (#define MUIA_Application_UsedClasses, etc.).

3. La classe Busy a l'avantage d'être vraiment simple ! On la construit de façon à ce qu'elle soit inactive au démarrage puis on change sa vitesse de défilement :
  • 20 (valeur arbitraire, vous pouvez en tester d'autres) lorsque l'on clique sur Play.
  • 0 (avec la valeur particulière MUIV_Busy_Speed_Off) quand on arrête.
4. Il est possible d'associer une bulle d'aide à un composant grâce au simple attribut MUIA_ShortHelp, suivi de la chaîne de caractères à afficher après quelques secondes. Pour les boutons, à cause de la notation choisie, on ne peut leur ajouter un attribut. Nous verrons par la suite un nouveau moyen pour décrire un bouton de manière plus expansée.

5. Un dernier détail concerne la mise en forme du texte : pour montrer que ça existe, on utilise les defines MUIX_U et MUIX_N dans le TextObjet au lieu des codes \33u et \33n équivalents.

6. Après la construction de l'interface, nous nous trouvons en présence de la fonction SetAttrs(). Cette dernière agit comme la fonction set du chapitre 1 mais permet de passer plusieurs paramètres, donc de modifier plusieurs attributs d'un objet, avec l'appel d'une seule fonction.

Voilà à quoi ressemble désormais notre programme :

/*
 * DisKo2.c (05/06/04)
 *
 */

#include <stdio.h>
#include <libraries/mui.h>
#include <proto/intuition.h>
#include <proto/muimaster.h>
#include <proto/exec.h>
#include <clib/alib_protos.h>

#include <mui/Busy_mcc.h>

#define MAKE_ID(a,b,c,d)  ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))

struct Library *MUIMasterBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;

#ifdef __amigaos4__
struct IntuitionIFace *IIntuition;
struct MUIMasterIFace *IMUIMaster;
#endif

#define	MUIA_Application_UsedClasses	0x8042e9a7	/* V20 STRPTR *	i..	*/

static STRPTR ClassList[] =
{
      "Busy.mcc",
      NULL
};

void CreateGui(void)
{
      Object *app = NULL;
      Object *window = NULL;
      Object *bt_play, *bt_stop;
      Object *busy;

      /* Description de l'interface et de ses propriétés */	

      app = (Object *)ApplicationObject,
            MUIA_Application_Author, "corto@guru-meditation.net",
            MUIA_Application_Base, "DISKO",
            MUIA_Application_Title, "MUI - Exemple 2",
            MUIA_Application_Version, "$VER: Exemple2 1.00 (21/01/03)",
            MUIA_Application_Copyright, "Mathias PARNAUDEAU",
            MUIA_Application_Description, "Interface MUI avec texte et boutons",
            MUIA_Application_HelpFile, NULL,
            MUIA_Application_UsedClasses, ClassList,

        SubWindow, window = WindowObject,
                        MUIA_Window_Title, "Exemple 2",
            MUIA_Window_ID, MAKE_ID('W', 'I', 'N', '1'),
            WindowContents, VGroup,

                              Child, TextObject,
                                    TextFrame,
                                    MUIA_Background, MUII_TextBack,
                                    MUIA_Text_Contents, "\33c A nouveau notre composant texte qui nous revient de l'exemple précédent\n" \
"Et ci-dessous le nouveau composant de "MUIX_U"classe Busy"MUIX_N" dont on va tester la dynamique",
                                    MUIA_ShortHelp, "Texte explicatif, montre le fonctionnement d'une bulle d'aide",
                              End,

                              /* Utilisation d'un groupe horizontal pourvu de boutons */
                              Child, HGroup,
                                    Child, bt_play = KeyButton("Play", 'p'),
                                    Child, bt_stop = KeyButton("Stop", 's'),
                              End,

                              Child, busy = BusyObject,
                                    MUIA_Busy_Speed, MUIV_Busy_Speed_Off,
                              End,
                        End,
        End,
    End;

      /* On fixe quelques valeurs et notifications */
      
      DoMethod(window,
            MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
            app, 2,
            MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

      set(bt_stop, MUIA_Disabled, TRUE);

      DoMethod(busy, MUIM_Busy_Move, FALSE);

      DoMethod(bt_play, MUIM_Notify, MUIA_Pressed, FALSE,
         bt_stop, 3, MUIM_Set, MUIA_Disabled, FALSE);
      DoMethod(bt_play, MUIM_Notify, MUIA_Pressed, FALSE,
         bt_play, 3, MUIM_Set, MUIA_Disabled, TRUE);

      DoMethod(bt_stop, MUIM_Notify, MUIA_Pressed, FALSE,
         bt_play, 3, MUIM_Set, MUIA_Disabled, FALSE);
      DoMethod(bt_stop, MUIM_Notify, MUIA_Pressed, FALSE,
         bt_stop, 3, MUIM_Set, MUIA_Disabled, TRUE);

      /* MUIV_ représente une valeur spéciale d'un attribut, ici il annule la vitesse */

      DoMethod(bt_play, MUIM_Notify, MUIA_Pressed, FALSE,
                              busy, 3, MUIM_Set, MUIA_Busy_Speed, 20);
      DoMethod(bt_stop, MUIM_Notify, MUIA_Pressed, FALSE,
                              busy, 3, MUIM_Set, MUIA_Busy_Speed, MUIV_Busy_Speed_Off);

      SetAttrs(window, MUIA_Window_Open, TRUE, TAG_END);

      /* Boucle de gestion des événements, toujours la même */
      {
            ULONG sigs = 0;

            while (DoMethod(app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit)
            {
                  if (sigs)
                  {
                        sigs = Wait(sigs | SIGBREAKF_CTRL_C);
                        if (sigs & SIGBREAKF_CTRL_C) break;
                  }
            }
      }

      set(window, MUIA_Window_Open, FALSE);

      /* Libération des ressources et fermeture */
      MUI_DisposeObject(app);
}

/*
 * Initialisation et vérification de tout ce qui est nécessaire à la bonne exécution
 * de l'application : ouverture des bibliothèques, test de présence des classes MCC, ...
 */
int Initialize(void)
{
      int res = 1;
      Object *busy = NULL;

      IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39L);
      MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN);

      if (IntuitionBase == NULL){
            printf("Impossible d'ouvrir 'intuition.library' V39\n");
            res = 0;
      }
      if (MUIMasterBase == NULL){
            printf("Impossible d'ouvrir '%s' V%d\n", MUIMASTER_NAME, MUIMASTER_VMIN);
            res = 0;
      }

#ifdef __amigaos4__
      IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL);
      if (!IIntuition){
            printf("Impossible d'obtenir l'interface IIntuition\n");
            res = 0;
      }

      IMUIMaster = (struct MUIMasterIFace *)GetInterface(MUIMasterBase, "main", 1, NULL);
      if (!IMUIMaster){
            printf("Impossible d'obtenir l'interface IMUIMaster\n");
            res = 0;
      }
#endif

      busy = BusyObject, End;
      if (busy == NULL){
            printf("Classe Busy manquante\n");
            res = 0;
      }
      MUI_DisposeObject(busy);

      return res;
}


/*
 * Fermeture et libération de tout ce qui a été initialisé au démarrage.
 */
void DeInitialize(void)
{
#ifdef __amigaos4__
      if (IMUIMaster) {
            DropInterface((struct Interface *)IMUIMaster);
      }
      if (IIntuition) {
            DropInterface((struct Interface *)IIntuition);
      }
#endif
      CloseLibrary(MUIMasterBase);
      CloseLibrary((struct Library *)IntuitionBase);
}


int main(int argc, char **argv)
{

      if(Initialize()){
            CreateGui();
      }
      DeInitialize();

      return 0;
}

Les notifications

Une notification permet d'indiquer à un objet quoi faire quand il lui arrive quelque chose, c'est aussi simple que ça ! Par exemple, pour que l'application reçoive un événement de fin lorsque l'on clique sur le bouton de fermeture de la fenêtre, on utilise la fonction à tout faire DoMethod() comme ceci :

DoMethod(window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
app, 2, MUIM_Application_ReturnID, UIV_Application_ReturnID_Quit);

Voici l'explication de chaque paramètre, dans l'ordre :
  • L'objet sur lequel on veut appeler une méthode, ici la fenêtre.
  • Le nom de la méthode, MUIM_Notify.
  • L'attribut qui déclenchera la notification lors du changement de sa valeur.
  • La valeur : ici on veut déclencher l'action lorsque l'attribut MUIA_Window_CloseRequest passe à TRUE, c'est-à-dire quand on clique sur le gadget de fermeture ou qu'on appuie sur la touche Escape.
  • L'objet cible sur lequel porte la notification.
  • Le nombre de paramètres qui restent à suivre.
  • La méthode que l'objet cible doit exécuter, ici l'affectation d'une valeur de retour à l'application.
  • Le paramètre passée à cette méthode.
Pour plus d'informations, réferrez-vous au fichier MUI_Notify.doc dans les autodocs de MUI. Mais le principe est là, applicable à nos composants :

DoMethod(bt_play, MUIM_Notify, MUIA_Pressed, FALSE,
bt_stop, 3, MUIM_Set, MUIA_Disabled, FALSE);

Dans ce cas, on indique au bouton "Play", quand il est sélectionné (plus précisément au moment où il est relâché) de griser le bouton "Stop". On remarque toute la puissance des notifications ici. Il est ensuite inutile de gérer les événements dans un boucle. Les actions sont définies ainsi et il n'y a plus rien à faire !

Notions acquises dans ce chapitre
  • Notion de notification.
  • Interactions entre composants avec set()/SetAttrs() et DoMethod().
  • Utilisation d'une classe externe, à opposer aux classes de base dites "builtin".
  • Ajout de bulles d'aide.
  • Imbrication de groupes : un horizontal dans le groupe vertical principal.
  • Raccourcis clavier avec KeyButton.
  • Attribut MUIA_Application_UsedClasses.


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]