home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
System
/
ScalosPrefs
/
examples
/
C
/
big.c
< prev
next >
Wrap
C/C++ Source or Header
|
1980-08-02
|
14KB
|
443 lines
/* Big example, perhaps something like what you'd use in a program :) */
/* Always included first */
#include <exec/types.h>
/* So we can use the functions from these libraries */
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
#include <proto/preferences.h>
#include <proto/graphics.h>
/* Intuition stuff */
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
/* Gadtools stuff */
#include <libraries/gadtools.h>
/* For the MAKE_ID macro */
#include <libraries/iffparse.h>
/* For the PrefsStruct structure */
#include <scalos/preferences.h>
/* some standard stuff */
#include <stdio.h>
#include <string.h>
#include <clib/alib_protos.h>
/* Library bases */
struct Library *GadToolsBase;
struct IntuitionBase *IntuitionBase;
struct Library *PreferencesBase;
struct GfxBase *GfxBase;
/* Font (TextAttr) to use for the gadtools gadgets, simply hardcoded for this simple example.
* Pointers to each one of the gadgets, so it is easier to work with them after creation.
*/
struct TextAttr ta = {"topaz.font", 8, 0, 0};
struct Gadget *gadgets[3] = {0};
/* Function Prototypes */
int OpenLibs(void);
void CloseLibs(void);
struct Gadget *CreateGadList(struct Screen *scr, APTR vi, WORD ww, WORD wh);
void FreeGads(struct Gadget *glist);
struct Window *openwin(WORD wx, WORD wy, WORD ww, WORD wh);
struct Node *AllocNode(STRPTR name);
void FreeNode(struct Node *node);
int main(void)
{
struct Screen *scr; /* screen we want to open on */
struct Window *win; /* Pointer to window */
struct Gadget *gad; /* Pointer to gadtools gadgetlist */
APTR vi; /* visualinfo for the screen */
/* Window position and sizes */
WORD wx = 170;
WORD wy = 100;
WORD ww = 300;
WORD wh = 200;
int quit = 0; /* flag to show when to quit program */
struct IntuiMessage *imsg; /* For communicating with intuition */
ULONG cls; /* class of window event */
UWORD evc; /* eventcode */
struct Gadget *gadhit; /* for gadgetup events */
UWORD lasthit; /* last item in listview hit */
struct List textlist;
struct Node *ptr; /* working pointer for traversing list */
APTR prefhandle; /* handle for accessing our preferences */
char temp[256]; /* temporary storage for when reading string prefs */
NewList(&textlist); /* Initialise list */
/* Open all required libraries and exit if any were failed to open */
if(!OpenLibs())
{
CloseLibs();
return(20);
}
/* Try to read in some preferences */
if(NULL != (prefhandle = AllocPrefsHandle("Example")) )
{
/* First, try to read the file that the preferences were stored in */
ReadPrefsHandle(prefhandle, "example.prefs");
/* Read window position preferences. If the tags do not exist (i.e. if they
* were not in the preferences file, or the preferences file was not loaded)
* then nothing will be copied into the destination memory. This means that
* the current contents of the positions/sizes will not be corrupted.
* We use the tag values for OpenWindowTagList for the window positions/sizes
* for the simple reason is that it makes it clearer what we are doing - plus it
* saves us some thinking to create our own tag values (which of course can be
* anything) :)
*/
GetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Left, &wx, 2);
GetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Top, &wy, 2);
GetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Width, &ww, 2);
GetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Height, &wh, 2);
/* Read a list of strings from the preferences that have been stored.
* If we try to read an item from the list which does not exist, we have
* reached the end of the list (remember that it is a list, not an array and
* that inserting at position 2000 may not insert at exactly position 2000 -
* if the list has onoly one entry, then it will get inserted after that
* and effectively be inserted at position 2
*/
evc = 0; /* Treat this as the entry number */
while(GetEntry(prefhandle, MAKE_ID('T','E','X','T'), 1, temp, 256, evc))
{
ptr = AllocNode((STRPTR)temp); if(ptr) AddTail(&textlist, ptr);
evc++;
}
}
/* Get default public screen for our use */
if(NULL != (scr = LockPubScreen(NULL)) )
{
/* Get visual info for that screen (needed for creating gadtools gadgets)
* and then create the gadgets
*/
vi = GetVisualInfoA(scr, NULL);
if(NULL != (gad = CreateGadList(scr, vi, ww, wh)) )
{
/* Set the list of text items for the Listview to display and try
* to open our window
*/
GT_SetGadgetAttrs(gadgets[0], NULL, NULL, GTLV_Labels, &textlist, TAG_DONE);
if(NULL != (win = openwin(wx, wy, ww, wh)) )
{
/* Add gadget list to window. Refresh the gadget list (causing it to be
* drawn. Refresh the window with special processing for gadtools gadgets
*/
AddGList(win, gad, -1, -1, 0);
RefreshGList(gad, win, 0, -1);
GT_RefreshWindow(win, 0);
/* window opened, do stuff */
while(!quit)
{
/* Wait for messages on the window's IDCMP port */
Wait(1 << win->UserPort->mp_SigBit);
/* while messages can be read from the window's IDCMP port */
while(NULL != (imsg = GT_GetIMsg(win->UserPort)) )
{
/* Take a copy of the information we are interested in and the reply the
* message
*/
cls = imsg->Class;
evc = imsg->Code;
gadhit = (struct Gadget *)imsg->IAddress;
GT_ReplyIMsg(imsg);
switch(cls)
{
case IDCMP_CLOSEWINDOW:
/* window close gadget pressed, set flag to quit program */
quit = 1;
break;
case IDCMP_GADGETUP:
/* gadget has been released, do processing depending on what gadget was hit */
switch(gadhit->GadgetID)
{
case 1:
/* listview. take a copy of the number of the item that was pressed.
* move to that item in the list attached to the listview and
* set the string in the string gadget (and yes, I know that I could
* have used GTLV_ShowSelected with the pointer to the string gadget,
* but I didn't OK).
*/
lasthit = evc;
ptr = textlist.lh_Head;
while(evc-- && ptr->ln_Succ)
{
ptr = ptr->ln_Succ;
}
if(ptr->ln_Succ) GT_SetGadgetAttrs(gadgets[1], win, NULL, GTST_String, ptr->ln_Name, TAG_DONE);
break;
case 2:
/* string gadget. detach the list from the listview and then try to add
* a new node to the list which contains the string in the string gadget.
* re-attach the list to the listview
*/
GT_SetGadgetAttrs(gadgets[0], win, NULL, GTLV_Labels, ~0, TAG_DONE);
ptr = AllocNode((STRPTR)((struct StringInfo *)gadhit->SpecialInfo)->Buffer); if(ptr) AddTail(&textlist, ptr);
GT_SetGadgetAttrs(gadgets[0], win, NULL, GTLV_Labels, &textlist, TAG_DONE);
break;
case 3:
/* button. detach list from listview, move to position in list for the
* last item that was pressed in the listview. remove item from list
* and free the memory. re-attach the list to the listview
*/
GT_SetGadgetAttrs(gadgets[0], win, NULL, GTLV_Labels, ~0, TAG_DONE);
ptr = textlist.lh_Head;
while(lasthit-- && ptr->ln_Succ)
{
ptr = ptr->ln_Succ;
}
if(ptr->ln_Succ)
{
Remove(ptr);
FreeNode(ptr);
}
GT_SetGadgetAttrs(gadgets[0], win, NULL, GTLV_Labels, &textlist, TAG_DONE);
break;
}
break;
case IDCMP_NEWSIZE:
/* window has been resized. Take a copy of the new window sizes. Remove and free
* the gadgets from the window and try to re-create them with the new sizes.
*/
ww = win->Width;
wh = win->Height;
RemoveGList(win, gad, -1);
FreeGads(gad);
if(NULL == (gad = CreateGadList(scr, vi, ww, wh)) )
{
/* Gadgets were not created, so we just set the flag to quit the program */
quit = 1;
}
else
{
/* gadgets were created OK, so attach the list to the listview. add the gadgets
* to the window, clear the inside of the window (not borders). refresh the
* window borders, then the gadgets with special processing for gadtools ones
*/
GT_SetGadgetAttrs(gadgets[0], NULL, NULL, GTLV_Labels, &textlist, TAG_DONE);
AddGList(win, gad, -1, -1, 0);
SetAPen(win->RPort, 0);
RectFill(win->RPort, win->BorderLeft, win->BorderTop, win->Width-win->BorderRight, win->Height-win->BorderBottom);
RefreshWindowFrame(win);
RefreshGList(gad, win, 0, -1);
GT_RefreshWindow(win, 0);
}
break;
}
} /* while get message */
} /* while !quit */
/* take copy of final x/y position of window. don't need to take the sizes,
* as we already have them from the IDCMP_NEWSIZE messages. Remove gadgets from window
* and close the window.
*/
wx = win->LeftEdge;
wy = win->TopEdge;
RemoveGList(win, gad, -1);
CloseWindow(win);
}
/* Free gadgets */
FreeGads(gad);
} /* if opened window */
/* free visual info for screen and unlock the public screen */
FreeVisualInfo(vi);
UnlockPubScreen(NULL, scr);
} /* if opened default pubscreen */
/* Save prefs. If we do not have a valid PrefsHandle, try to allocate one here. */
if(!prefhandle) prefhandle = AllocPrefsHandle("Example");
if(prefhandle)
{
/* Set all the new window positions/sizes */
SetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Left, &wx, 2);
SetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Top, &wy, 2);
SetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Width, &ww, 2);
SetPreferences(prefhandle, MAKE_ID('W','N','D','O'), WA_Height, &wh, 2);
/* Clear the previous list preferences so that we are sure to only save what we add using SetEntry */
while(RemEntry(prefhandle, MAKE_ID('T','E','X','T'), 1, 0)){;}
/* go through the list that was attached to the listview and store each string
* as an item in a multiple preference per tag item.
*/
evc = 0; /* Treat this as the entry number */
ptr = textlist.lh_Head;
while(ptr->ln_Succ)
{
if(ptr->ln_Name) SetEntry(prefhandle, MAKE_ID('T','E','X','T'), 1, ptr->ln_Name, strlen(ptr->ln_Name)+1, evc);
evc++;
ptr = ptr->ln_Succ;
}
/* Save the preferences and then free them */
WritePrefsHandle(prefhandle, "example.prefs");
FreePrefsHandle(prefhandle);
}
/* Finally, free all memory for the list */
while(NULL != (ptr = RemHead(&textlist)) )
{
FreeNode(ptr);
}
CloseLibs();
}
/* Opens all required libraries for this program and returns true (for success) or
* false (for failure)
*/
int OpenLibs(void)
{
GadToolsBase = OpenLibrary("gadtools.library", 36);
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36);
PreferencesBase = OpenLibrary("preferences.library", 39);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 36);
if(GadToolsBase && IntuitionBase && PreferencesBase && GfxBase) return(1);
return(0);
}
/* closes all opened libraries */
void CloseLibs(void)
{
if(GadToolsBase) CloseLibrary(GadToolsBase);
if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
if(PreferencesBase) CloseLibrary(PreferencesBase);
if(GfxBase) CloseLibrary((struct Library *)GfxBase);
}
/* creates gadget list */
struct Gadget *CreateGadList(struct Screen *scr, APTR vi, WORD ww, WORD wh)
{
struct Gadget *gad, *glist;
struct NewGadget ng[] = {{8,20,0,0,NULL,&ta,1,0,0,0},
{8,0,0,14,NULL,&ta,2,0,0,0},
{0,0,40,14,"Del",&ta,3,16,0,0}};
ng[0].ng_Width = ww - 40;
ng[0].ng_Height = wh - 60;
ng[0].ng_VisualInfo = vi;
ng[1].ng_TopEdge = 20 + wh - 60;
ng[1].ng_Width = ww - 80;
ng[1].ng_VisualInfo = vi;
ng[2].ng_LeftEdge = 8 + ww - 80;
ng[2].ng_TopEdge = 20 + wh - 60;
ng[2].ng_VisualInfo = vi;
if(NULL == (gad = CreateContext(&glist)) ) return(NULL);
if(NULL == (gad = CreateGadget(LISTVIEW_KIND, gad, &ng[0], GTLV_Labels, NULL, TAG_DONE)) )
{
FreeGads(glist);
return(NULL);
}
gadgets[0] = gad;
if(NULL == (gad = CreateGadget(STRING_KIND, gad, &ng[1], GTST_MaxChars, 256, TAG_DONE)) )
{
FreeGads(glist);
return(NULL);
}
gadgets[1] = gad;
if(NULL == (gad = CreateGadgetA(BUTTON_KIND, gad, &ng[2], NULL)) )
{
FreeGads(glist);
return(NULL);
}
gadgets[2] = gad;
return(glist);
}
/* frees gadget list if it exists */
void FreeGads(struct Gadget *glist)
{
if(glist) FreeGadgets(glist);
}
/* open window (just takes the huge mess of the taglist out of the main function */
struct Window *openwin(WORD wx, WORD wy, WORD ww, WORD wh)
{
return(OpenWindowTags(NULL, WA_Left, wx,
WA_Top, wy,
WA_Width, ww,
WA_Height, wh,
WA_Flags, WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SIZEGADGET|WFLG_ACTIVATE|WFLG_NOCAREREFRESH,
WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|IDCMP_GADGETUP,
WA_MinWidth, 150,
WA_MinHeight, 150,
WA_MaxWidth, 640,
WA_MaxHeight, 480,
WA_AutoAdjust, 1,
WA_PubScreen, NULL,
TAG_DONE));
}
/* allocates a Node and some memory for the ln_Name and copies the specified name into it */
struct Node *AllocNode(STRPTR name)
{
struct Node *node;
if(NULL != (node = AllocVec(sizeof(struct Node), MEMF_PUBLIC|MEMF_CLEAR)) )
{
if(name)
{
if(NULL != (node->ln_Name = AllocVec(strlen(name)+1, MEMF_PUBLIC|MEMF_CLEAR)) )
{
CopyMem(name, node->ln_Name, strlen(name));
}
}
}
return(node);
}
/* Frees a Node and also the name */
void FreeNode(struct Node *node)
{
if(node)
{
if(node->ln_Name) FreeVec(node->ln_Name);
FreeVec(node);
}
}