Obligement - L'Amiga au maximum

Vendredi 17 mai 2024 - 11:48  

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 - plus loin dans les classes
(Article écrit par Mathias Parnaudeau - juillet 2004)


Chapitre 3

Allez, il est temps que notre application ressemble un peu à un lecteur de CD ! Après avoir passé en revue les éléments nécessaires à l'élaboration basique de l'interface, nous passerons à leur mise en place dans le source, en nous basant sur celui du chapitre 2. Ceci fera intervenir les groupes de manière un peu plus poussée.

Cahier des charges

En regardant sur une platine CD de salon classique, on remarque les éléments suivants :
  • Les boutons Précédent, Suivant, Jouer, Pause, Arrêter.
  • Le bouton de volume qui peut être représenté par une réglette.
  • L'affichage du numéro de la piste courante (et éventuellement de la position en minutes et secondes).
  • Un voyant lumineux indiquant que la lecture est en cours (admettons que ça soit le cas, histoire de réutiliser notre objet de classe Busy :)).
Après avoir décidé de ce qui serait présent, il faut agencer tout cela puisque cette décision déterminera l'arborescence des objets : souvenez-vous des couples Child/End. On fixera la liste des pistes en premier, c'est-à-dire en haut et occupant presque toute la largeur. En effet, sur la droite, nous mettrons une glissière verticale, surmontée de l'annotation "Volume". En dessous, on placera les boutons alignés horizontalement avec au bout un champ de texte (en lecture seule) indiquant la piste courante. Puis tout en bas un objet Busy de faible épaisseur.

Concrètement

On remarque donc que nous avons à faire à trois groupes horizontaux superposés :
  • Affichage de la liste des pistes et volume.
  • Boutons et indicateur de la piste courante.
  • Voyant lumineux Busy comme témoin de lecture.
Voici comme on dit le pseudo-code équivalent :
 Window

        VGroup

                HGroup

                        Liste

                        VGroup

                                Label Volume

                                Glissière (Slider)

                HGroup

                        Bouton Précédent

                        Bouton Suivant

                        Bouton Jouer

                        Bouton Pause

                        Bouton Stop

                        Texte avec numéro de piste

                Busy
J'espère que tout cela est clair et que vous visualisez l'aspect que le lecteur va revêtir. Cette imbrication de groupes horizontaux et verticaux représente une première difficulté. L'autre réside dans les trois nouvelles classes utilisées pour les composants suivants :
  • Le label qui contient le mot "Volume", son usage est on ne peut plus simple !
  • Le volume.
  • La liste des chansons.
Le volume utilise la classe interne Slider (glisseur) dont l'autodoc est très accessible. Ses attributs sont : sa représentation verticale ou horizontale, sa valeur minimum et maximum, sa valeur de départ, etc. Pour notre exemple, on a choisi arbitrairement les limites 0 et 100, avec 38 comme valeur initiale. On fixe l'attribut MUIA_Lister_Reverse à TRUE pour obtenir le 0 en bas. Lorsqu'on regarde dans la documentation (ce qu'il faut toujours faire :)) on s'aperçoit que la plupart des attributs sont indiqués comme obsolètes. En fait, puisque l'on utilise des valeurs numériques, les attributs recommandés sont les équivalents de la classe builtin Numeric : MUIA_Numeric_Max au lieu de MUIA_Slider_Max, etc. Cela ne change rien dans le fonctionnement mais c'est plus correct au niveau de la conception. Et logique, tout simplement !

Pour visualiser toutes ces nouvelles notions, voici le source :

/*
 * DisKo3.c (08/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, *bt_previous, *bt_next, *bt_pause, *bt_eject;
	Object *busy;
	Object *sl_volume;
	Object *lv_pistes;
	Object *list;

	/* 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, "DisKo - Exemple 3",
		MUIA_Application_Version, "$VER: DisKo 1.03 (08/06/04)",
		MUIA_Application_Copyright, "Mathias PARNAUDEAU",
		MUIA_Application_Description, "Player de CD audio minimaliste",
		MUIA_Application_HelpFile, NULL,
		MUIA_Application_UsedClasses, ClassList,

        SubWindow, window = WindowObject,
				MUIA_Window_Title, "DisKo - release 3",
            MUIA_Window_ID, MAKE_ID('W', 'I', 'N', '1'),
            WindowContents, VGroup,

					Child, HGroup,
						Child, lv_pistes = ListviewObject,
							MUIA_Listview_Input, FALSE,
							MUIA_Listview_List, list = ListObject,
								ReadListFrame,
								MUIA_List_Format, "P=\33r",
							End,
						End,

						Child, VGroup,
							Child, Label("Volume"),
							Child, sl_volume = SliderObject,
								MUIA_Group_Horiz, FALSE,
								MUIA_Numeric_Min, 0,
								MUIA_Numeric_Max, 100,
								MUIA_Numeric_Value, 38,
								MUIA_Numeric_Reverse, TRUE,
							End,
						End,
					End,

					/* Utilisation d'un groupe horizontal pourvu de boutons */
					Child, HGroup,
						Child, bt_previous = KeyButton("Précédent", 'p'),
						Child, bt_next = KeyButton("Suivant", 'v'),
						Child, bt_play = KeyButton("Jouer", 'j'),
						Child, bt_pause = KeyButton("Pause", 'a'),
						Child, bt_stop = KeyButton("Arrêter", 's'),
						Child, bt_eject = KeyButton("Ejecter", 'e'),
					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);

	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);

	DoMethod(list, MUIM_List_InsertSingle, "1 - Première piste", MUIV_List_Insert_Bottom);
	DoMethod(list, MUIM_List_InsertSingle, "2 - Deuxième piste", MUIV_List_Insert_Bottom);

	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;
}

Sur la liste

En prévision de l'affichage des titres des chansons, un composant de type liste a été ajouté. La construction d'une liste repose en réalité sur deux classes, List et Listview, qui gèrent respectivement la gestion de la liste (manipulation de ses éléments) et sa représentation. La listview ne propose que peu d'options, les efforts devront être portés sur la richesse de la classe List, qui se trouve alors "embarquée" dans la listview.

Il a été choisi d'employer les classes List et Listview d'origine même si de nombreuses applications utilisent les classes NList et NListView, plus complètes et compatibles. Nos besoins n'étant pas très étendus, nous privilégions la simplicité. Nous ne perdrons rien dans les fonctionnalités liées aux listes que nous aborderons. Par contre, attention à ne pas mélanger ces deux groupes ! Leur compatibilité autoriserait une compilation sans soucis mais des surprises (mauvaises !) sont à prévoir dans le comportement de la liste produite.

Le contenu de la liste est géré par un objet List que l'on doit affecté à la Listview via l'attribut MUIA_Listview_List. La List interne contient ses propres attributs comme MUIA_List_Format pour déterminer comment cela sera affiché par la listview : définition de plusieurs colonnes, justification du texte (ici à droite pour que ça soit marquant, avec \33r), etc. L'incontournable DoMethod() est utilisée par deux fois avant l'ouverture de la fenêtre pour ajouter une ligne de texte avec MUIM_List_InsertSingle, soit deux lignes au total. On simule ainsi la lecture des titres des pistes d'un hypothétique CD. A noter qu'il est possible d'ajouter plusieurs lignes en même temps avec MUIM_List_Insert.

Notions acquises dans ce chapitre
  • Conception d'une interface, agencement des groupes.
  • Introduction aux importantes classes List et Listview.


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