home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
580a.lha
/
AM
/
AMwindow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-21
|
14KB
|
624 lines
/*
* AMwindow.c: Subtask für Parameterfenster
*
* Auto: make AMwindow.o
*
*/
#include "AM.h"
#include <exec/execbase.h>
#include <exec/tasks.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfxmacros.h>
#include <utility/tagitem.h>
#include <libraries/gadtools.h>
#if 0
# define D(debug) debug
#else
# define D(debug)
#endif
#define abbruch SIGBREAKF_CTRL_C
#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
/*------------------------- Daten anderer Module...*/
extern struct ExecBase *SysBase;
extern struct Library *DOSBase;
extern long channel, instr,
freqmitte, freqabw,
volmitte, volabw;
extern double pausen, tonaus;
extern char skala[13], cskala[12][13];
/*------------------------- Daten dieses Moduls...*/
static struct TextAttr Topaz80 =
{
"topaz.font", /* Name */
8, /* YSize */
0, /* Style */
0, /* Flags */
};
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *GadToolsBase = NULL;
struct TextFont *font = NULL;
struct Screen *mysc = NULL;
struct Gadget *glist = NULL;
struct Window *mywin = NULL;
void *vi = NULL;
static struct Task *windowtask = NULL,
*maintask = NULL;
static ULONG topborder = 0,
bottomEdge = 0;
enum {
GAD_KANAL = 0, GAD_INSTR, GAD_FREQMITTE, GAD_FREQABW,
GAD_VOLMITTE, GAD_VOLABW, GAD_PAUSEN, GAD_TONAUS, GAD_SKALA,
GAD_CSKALA_LIST, GAD_CSKALA_STRING,
GAD_ANZAHL
};
struct Gadget *mgg[ GAD_ANZAHL ];
char lt_skala[12][16]; /* Texte für ListView */
struct List lh_skala; /* ListHeader */
struct Node nd_skala[12]; /* Knoten für Liste */
/*------------------------- Code-Deklarationen...*/
extern void ProgChange( int );
extern void AllNotesOff( void );
extern LONG Printf( UBYTE *, ... );
BOOL subinit( void );
void subclosedown( void );
void handlewindowmsg( void );
struct Gadget *CreateAllGadgets(struct Gadget **, void *, UWORD);
void closewindow( void );
/*------------------------- Stub-Code...*/
struct Gadget *CreateGadget( unsigned long kind, struct Gadget *gad,
struct NewGadget *ng, Tag tag1, ... )
{
return CreateGadgetA( kind, gad, ng, (struct TagItem *)&tag1 );
}
APTR GetVisualInfo( struct Screen *screen, Tag tag1, ... )
{
return GetVisualInfoA( screen, (struct TagItem *)&tag1 );
}
struct Window *OpenWindowTags( struct NewWindow *newWindow,
unsigned long tag1Type, ... )
{
return OpenWindowTagList( newWindow, (struct TagItem *)&tag1Type );
}
void GT_SetGadgetAttrs( struct Gadget *gad, struct Window *win,
struct Requester *req, Tag tag1, ... )
{
GT_SetGadgetAttrsA( gad, win, req, (struct TagItem *)&tag1 );
}
/*------------------------- Code-Definitionen...*/
static void windowtaskcode( void )
{
long wmsg=0, sgns;
geta4();
if( !subinit() ) return;
wmsg = 1 << mywin->UserPort->mp_SigBit;
while(1)
{
sgns = Wait( wmsg | abbruch );
if( sgns & wmsg )
{
handlewindowmsg();
SetSignal( 0, wmsg );
}
if( sgns & abbruch )
{
subclosedown();
mywin = 0;
return;
}
}
}
/* CreateAllGadgets()
*
* Diese Routine führt alle Gadget-Initialisierungen aus.
* glistptr ist ein auf NULL initialisierter GadgetList-Zeiger
* Rückgabe ist ein Zeiger auf das zuletzt erzeugte Gadget (also
* NULL bei Fehler)
*
*/
static struct Gadget *CreateAllGadgets(
struct Gadget **glistptr,
void *vi,
UWORD topborder )
{
struct NewGadget ng;
struct Gadget *gad;
int i;
/* All the gadget creation calls accept a pointer to the previous
gadget, and link the new gadget to that gadget's NextGadget field.
Also, they exit gracefully, returning NULL, if any previous gadget
was NULL. This limits the amount of checking for failure that
is needed. You only need to check before you tweak any gadget
structure or use any of its fields, and finally once at the end,
before you add the gadgets. */
/* We obligingly perform the following operation, required of
any program that uses the toolkit. It gives the toolkit a
place to stuff context data: */
gad = CreateContext(glistptr);
/* Since the NewGadget structure is unmodified by any of the
CreateGadget() calls, we need only change those fields which
are different. */
ng.ng_LeftEdge = 72;
ng.ng_TextAttr = &Topaz80;
ng.ng_VisualInfo = vi;
ng.ng_Width = 120;
ng.ng_Height = 12;
ng.ng_Flags = 0;
ng.ng_TopEdge = topborder + INTERHEIGHT;
ng.ng_GadgetText = "Kanal:";
ng.ng_GadgetID = GAD_KANAL;
mgg[GAD_KANAL] = gad = CreateGadget(SLIDER_KIND, gad, &ng,
GTSL_Min, 1,
GTSL_Max, 16,
GTSL_Level, channel+1,
GTSL_LevelFormat, "%2ld",
GTSL_LevelPlace, PLACETEXT_RIGHT,
GTSL_MaxLevelLen, 2,
GA_IMMEDIATE, TRUE,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+INTERHEIGHT;
ng.ng_GadgetText = "Instr:";
ng.ng_GadgetID = GAD_INSTR;
mgg[GAD_INSTR] = gad = CreateGadget(SLIDER_KIND, gad, &ng,
GTSL_Min, 0,
GTSL_Max, 64,
GTSL_Level, instr+1,
GTSL_LevelFormat, "%2ld",
GTSL_LevelPlace, PLACETEXT_RIGHT,
GTSL_MaxLevelLen, 2,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+2*INTERHEIGHT;
ng.ng_GadgetText = "F-Ber:";
ng.ng_GadgetID = GAD_FREQMITTE;
mgg[GAD_FREQMITTE] = gad = CreateGadget(SCROLLER_KIND, gad, &ng,
GTSC_Top, freqmitte-freqabw,
GTSC_Total, 128,
GTSC_Visible, freqabw*2,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+INTERHEIGHT;
ng.ng_GadgetText = "F-Abw:";
ng.ng_GadgetID = GAD_FREQABW;
mgg[GAD_FREQABW] = gad = CreateGadget(SLIDER_KIND, gad, &ng,
GTSL_Min, 0,
GTSL_Max, 63,
GTSL_Level, freqabw,
GTSL_LevelFormat, "±%3ld½",
GTSL_LevelPlace, PLACETEXT_RIGHT,
GTSL_MaxLevelLen, 5,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+2*INTERHEIGHT;
ng.ng_GadgetText = "V-Ber:";
ng.ng_GadgetID = GAD_VOLMITTE;
mgg[GAD_VOLMITTE] = gad = CreateGadget(SCROLLER_KIND, gad, &ng,
GTSC_Top, volmitte-volabw,
GTSC_Total, 128,
GTSC_Visible, volabw*2,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+INTERHEIGHT;
ng.ng_GadgetText = "V-Abw:";
ng.ng_GadgetID = GAD_VOLABW;
mgg[GAD_VOLABW] = gad = CreateGadget(SLIDER_KIND, gad, &ng,
GTSL_Min, 0,
GTSL_Max, 63,
GTSL_Level, volabw,
GTSL_LevelFormat, "±%3ld½",
GTSL_LevelPlace, PLACETEXT_RIGHT,
GTSL_MaxLevelLen, 5,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+2*INTERHEIGHT;
ng.ng_GadgetText = "Pausen:";
ng.ng_GadgetID = GAD_PAUSEN;
mgg[GAD_PAUSEN] = gad = CreateGadget(SLIDER_KIND, gad, &ng,
GTSL_Min, 0,
GTSL_Max, 100,
GTSL_Level, (long)(pausen*100),
GTSL_LevelFormat, "%3ld %%",
GTSL_LevelPlace, PLACETEXT_RIGHT,
GTSL_MaxLevelLen, 5,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+INTERHEIGHT;
ng.ng_GadgetText = "TonAus:";
ng.ng_GadgetID = GAD_TONAUS;
mgg[GAD_PAUSEN] = gad = CreateGadget(SLIDER_KIND, gad, &ng,
GTSL_Min, 0,
GTSL_Max, 100,
GTSL_Level, (long)(tonaus*100),
GTSL_LevelFormat, "%3ld %%",
GTSL_LevelPlace, PLACETEXT_RIGHT,
GTSL_MaxLevelLen, 5,
GA_RELVERIFY, TRUE,
TAG_DONE);
ng.ng_TopEdge += 12+INTERHEIGHT;
ng.ng_GadgetText = "Skala:";
ng.ng_GadgetID = GAD_SKALA;
ng.ng_Height = 14;
mgg[GAD_SKALA] = gad = CreateGadget(STRING_KIND, gad, &ng,
GTST_MaxChars, 12,
GTST_String, skala,
STRINGA_ReplaceMode, TRUE,
TAG_DONE);
/* String-Gadget für ListView: */
ng.ng_GadgetText = NULL;
ng.ng_GadgetID = GAD_CSKALA_STRING;
ng.ng_Height = 14;
ng.ng_Width += 40;
mgg[GAD_CSKALA_STRING] = gad = CreateGadget(STRING_KIND, gad, &ng,
GTST_MaxChars, 15,
STRINGA_ReplaceMode, TRUE,
TAG_DONE);
/* Liste der Continue-Skalen */
ng.ng_TopEdge += 12+2*INTERHEIGHT;
ng.ng_GadgetText = "CSkala:";
ng.ng_Flags = PLACETEXT_LEFT;
ng.ng_GadgetID = GAD_CSKALA_LIST;
ng.ng_Height = 4 + 8 * 9 + 14;
mgg[GAD_CSKALA_LIST] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng,
LAYOUTA_SPACING, 1,
GTLV_Labels, &lh_skala,
GTLV_ShowSelected, mgg[GAD_CSKALA_STRING],
TAG_DONE);
i = GAD_CSKALA_STRING;
bottomEdge = mgg[i]->TopEdge + mgg[i]->Height + 2*INTERHEIGHT;
return(gad);
}
static BOOL subinit( void )
// Fenster öffnen etc.
{
// zunächst mal probieren, ob wir ein Fenster kriegen können...
mywin = OpenWindowTags(NULL,
WA_Title, "AM Parameter",
WA_Width, 250,
WA_Height, bottomEdge,
WA_MinWidth, 50,
WA_MinHeight, 50,
WA_MaxWidth, 250,
WA_MaxHeight, bottomEdge,
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_SimpleRefresh, TRUE,
WA_IDCMP, CLOSEWINDOW | REFRESHWINDOW | \
SLIDERIDCMP | SCROLLERIDCMP | STRINGIDCMP | \
LISTVIEWIDCMP,
TAG_DONE);
// Na? Haben wir's?
if( !mywin )
return FALSE;
// Ja! Nun Gadgets anhängen und refreshen...
AddGList( mywin, glist, 0, -1, NULL );
RefreshGList( glist, mywin, NULL, -1 );
GT_RefreshWindow( mywin, NULL );
return TRUE;
}
static void subclosedown( void )
{
if(mywin) CloseWindow(mywin); mywin=0;
}
static BOOL HandleGadgetEvent(
struct Gadget *gad,
UWORD code )
{
char *s;
long i;
switch (gad->GadgetID)
{
case GAD_KANAL:
// unkritisch
AllNotesOff();
channel = (WORD) code - 1;
break;
case GAD_INSTR:
instr = (WORD) code - 1;
if( instr>=0 ) ProgChange( instr );
break;
case GAD_FREQMITTE:
// unkritisch
freqmitte = (WORD) code + freqabw;
break;
case GAD_FREQABW:
freqabw = (WORD) code;
// Grenzen neu checken
if( freqmitte+freqabw > 127 )
freqmitte = 127 - freqabw;
else if( freqmitte-freqabw < 0 )
freqmitte = freqabw;
// Scroller ändern
GT_SetGadgetAttrs( mgg[GAD_FREQMITTE], mywin, NULL,
GTSC_Top, freqmitte-freqabw,
GTSC_Visible, freqabw*2,
TAG_DONE );
break;
case GAD_VOLMITTE:
// unkritisch
volmitte = (WORD) code + volabw;
break;
case GAD_VOLABW:
volabw = (WORD) code;
// Grenzen neu checken
if( volmitte+volabw > 127 )
volmitte = 127 - volabw;
else if( volmitte-volabw < 0 )
volmitte = volabw;
// Scroller ändern
GT_SetGadgetAttrs( mgg[GAD_VOLMITTE], mywin, NULL,
GTSC_Top, volmitte-volabw,
GTSC_Visible, volabw*2,
TAG_DONE );
break;
case GAD_PAUSEN:
// unkritisch
pausen = (WORD) code / 100.0;
break;
case GAD_TONAUS:
// unkritisch
tonaus = (WORD) code / 100.0;
break;
case GAD_SKALA:
s = ((struct StringInfo *)gad->SpecialInfo)->Buffer;
// 12 Zeichen?
if( strlen(s)==12 )
strcpy( skala, s );
else
GT_SetGadgetAttrs( gad, mywin, NULL,
GTST_String, skala,
TAG_DONE );
break;
case GAD_CSKALA_LIST:
ActivateGadget( mgg[GAD_CSKALA_STRING], mywin, NULL );
break;
case GAD_CSKALA_STRING:
s = ((struct StringInfo *)gad->SpecialInfo)->Buffer;
i = atol(s);
if( s[2]==':' && i>=0 && i<=11 )
{
if( strlen(s)==15 )
{
// komplett -> einbauen bzw. ersetzen
strcpy( cskala[i], s+3 );
strcpy( lt_skala[i], s );
GT_SetGadgetAttrs( mgg[GAD_CSKALA_LIST], mywin, NULL,
GTLV_Labels, &lh_skala,
TAG_DONE );
RefreshGList( mgg[GAD_CSKALA_LIST], mywin, NULL, 1 );
}
else if( s[3] == 0 )
{
// nur noch Index -> löschen
cskala[i][0] = 0;
lt_skala[i][3] = 0;
GT_SetGadgetAttrs( mgg[GAD_CSKALA_LIST], mywin, NULL,
GTLV_Labels, &lh_skala,
TAG_DONE );
RefreshGList( mgg[GAD_CSKALA_LIST], mywin, NULL, 1 );
}
}
break;
}
}
static void handlewindowmsg( void )
{
struct IntuiMessage *imsg;
struct Gadget *gad;
ULONG imsgClass;
UWORD imsgCode;
while( imsg = GT_GetIMsg(mywin->UserPort) )
{
imsgClass = imsg->Class;
imsgCode = imsg->Code;
gad = (struct Gadget *)imsg->IAddress;
// ^^^ natürlich nur bei Gadgets gültig
GT_ReplyIMsg(imsg);
switch (imsgClass)
{
case MOUSEMOVE:
case GADGETUP:
HandleGadgetEvent(gad, imsgCode);
break;
case CLOSEWINDOW:
// Nur HauptTask signalisieren
Signal( maintask, SIGBREAKF_CTRL_C );
break;
case REFRESHWINDOW:
GT_BeginRefresh(mywin);
GT_EndRefresh(mywin, TRUE);
break;
}
}
}
//---------------------- Nach außen sichtbare Funktionen:
BOOL startwindow( void )
// Libs öffnen, etc., Task starten
{
int i;
if( !(GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 36L)))
return( FALSE );
if( !(IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 36L))) {
closewindow();
return( FALSE ); }
if( !(GadToolsBase = OpenLibrary("gadtools.library", 36L))) {
closewindow();
return( FALSE ); }
if( !(font = OpenFont(&Topaz80))) {
closewindow();
return( FALSE ); }
if( !(mysc = LockPubScreen(NULL))) {
closewindow();
return( FALSE ); }
if( !(vi = GetVisualInfo(mysc,TAG_DONE))) {
closewindow();
return( FALSE ); }
topborder = mysc->WBorTop + (mysc->Font->ta_YSize + 1);
NewList( &lh_skala );
for( i=0; i<=11; i++ )
{
sprintf( lt_skala[i], "%02d:%s", i, cskala[i] );
nd_skala[i].ln_Name = lt_skala[i];
AddTail( &lh_skala, &nd_skala[i] );
}
if( !CreateAllGadgets(&glist, vi, topborder)) {
closewindow();
return( FALSE ); }
maintask = SysBase->ThisTask;
windowtask = CreateTask( "AMsub", 0, windowtaskcode, 4000 );
return( windowtask != 0 );
}
void closewindow( void )
{
// SubTask bescheid sagen
if(windowtask)
{
Signal( windowtask, SIGBREAKF_CTRL_C );
while( mywin ) Delay(25);
windowtask=0;
}
if(GadToolsBase)
{
FreeVisualInfo(vi); vi=0;
FreeGadgets(glist); glist=0;
CloseLibrary(GadToolsBase); GadToolsBase=0;
}
if(mysc) UnlockPubScreen(NULL, mysc); mysc=0;
if(font) CloseFont(font); font=0;
if(IntuitionBase) CloseLibrary(IntuitionBase); IntuitionBase=0;
if(GfxBase) CloseLibrary(GfxBase); GfxBase=0;
}