CCL Home Page
Up Directory CCL ScianGlobalFunctions
/*ScianGlobalFunctions.c
  Eric Pepke
  7 February 1993

  Does global functions, i.e., functions that are available from anywhere
  and don't work on specific objects.
*/

#include "Scian.h"
#include "ScianTypes.h"
#include "ScianLists.h"
#include "ScianWindows.h"
#include "ScianColors.h"
#include "ScianIDs.h"
#include "ScianObjWindows.h"
#include "ScianButtons.h"
#include "ScianErrors.h"
#include "ScianDraw.h"
#include "ScianControls.h"
#include "ScianArrays.h"
#include "ScianScripts.h"
#include "ScianVisWindows.h"
#include "ScianIcons.h"
#include "ScianEvents.h"
#include "ScianStyle.h"
#include "ScianObjFunctions.h"
#include "ScianGlobalFunctions.h"
#include "ScianHelp.h"
#include "ScianFilters.h"
#include "ScianFileSystem.h"
#include "ScianSockets.h"
#include "ScianPointers.h"
#include "ScianMenus.h"
#include "ScianPreferences.h"
#include "ScianFileSystem.h"
#include "ScianAnimation.h"

ObjPtr globalActionClass;

typedef struct
    {
	char *name;		/*Name of function*/
	void (*doRoutine)();	/*Routine to do it*/
	char *buttonHelp;	/*Button help*/
	char *menuHelp;		/*Menu help*/
	char *scriptLine;	/*Line for script*/
	ObjPtr menu;		/*Which menu this routine is in*/
	int menuGroup;		/*Which menu group this function is in*/
    } GlobalFunction;

int nGlobalFunctions = 0;	/*# of global functions*/

static GlobalFunction *globalFunctions;

#ifdef PROTO
int NameToGlobalFunction(char *name)
#else
int NameToGlobalFunction(name)
char *name;
#endif
/*Converts a name to a function number, or -1*/
{
    int funcNum;

    /*Search for the named function*/
    for (funcNum = 0; funcNum < nGlobalFunctions; ++funcNum)
    {
	if (0 == strcmp2(name, globalFunctions[funcNum] . name))
	{
	    break;
	}
    }

    if (funcNum >= nGlobalFunctions)
    {
	/*Not found, too bad.*/
	char nameStr[300];
	sprintf(nameStr, "Internal error: name '%s' not found", name);
	ReportError("NameToGlobalFunction", nameStr);
	return -1;
    }
    return funcNum;
}

#ifdef PROTO
Bool GlobalFunctionScriptLine(char *line)
#else
Bool GlobalFunctionScriptLine(line)
char *line;
#endif
/*If s is a script line, finds out if it is a valid script line for a
  global function.  If so, does it and returns true, otherwise does nothing
  and returns false.  Determines whether it is valid by matching the 
  script line*/
{
    int funcNum;
    register char *s, *p, *t;

    /*For all possible functions*/
    for (funcNum = 0; funcNum < nGlobalFunctions; ++funcNum)
    {
	/*Try to match script line against script*/
	s = line;
	p = globalFunctions[funcNum] . scriptLine;

	if (!p) continue;

	SKIPBLANKS(s);
	SKIPBLANKS(p);

	while (*p)
	{
	    if (isspace(*p))
	    {
		SKIPBLANKS(s);
		SKIPBLANKS(p);
	    }
	    else if (toupper(*p) != toupper(*s))
	    {
		/*Failure to match*/
		break;
	    }
	    else
	    {
		++s;
		++p;
	    }
	}

	if (*p == 0)
	{
	    ObjPtr list;
	    ThingListPtr runner;
	    ObjPtr object;
	    /*It's a match!  Do this function and return true*/

	    if (globalFunctions[funcNum] . scriptLine)
	    {
		Log(globalFunctions[funcNum] . scriptLine);
		Log("\n");
		InhibitLogging(true);
	    }
	    if (globalFunctions[funcNum] . doRoutine)
	    {
		(*(globalFunctions[funcNum] . doRoutine))();
	    }
	    if (globalFunctions[funcNum] . scriptLine)
	    {
		InhibitLogging(false);
	    }

	    return true;
	}
    }
    return false;
}

#ifdef PROTO
void DefineGlobalFunction(char *funcName, void (*doRoutine)(),
	char *scriptLine,
	char *buttonHelp,
	char *menuHelp, ObjPtr menu, int menuGroup)
#else
void DefineGlobalFunction(funcName, doRoutine, scriptLine,
	buttonHelp, menuHelp, menu, menuGroup)
char *funcName;
void (*doRoutine)();
char *scriptLine;
char *buttonHelp;
char *menuHelp;
ObjPtr menu;
int menuGroup;
#endif
/*Defines a global function
    funcName	    is the name of the function for the menu and buttons
    doRoutine	    is a routine to call to do it
    scriptLine	    is the script line
    buttonHelp	    is the help string for a button, or nothing for no button
    menuHelp	    is the help string for a menu
    menu	    is which menu to use, or NULLOBJ for none
    menuGroup	    is the menu group
*/
{
    if (nGlobalFunctions)
    {
	globalFunctions = Realloc(globalFunctions, (nGlobalFunctions + 1) * sizeof(GlobalFunction));
    }
    else
    {
	globalFunctions = Alloc((nGlobalFunctions + 1) * sizeof(GlobalFunction));
    }

    if (funcName)
    {
	globalFunctions[nGlobalFunctions] . name = Alloc(strlen(funcName) + 1);
	strcpy(globalFunctions[nGlobalFunctions] . name, funcName);
    }
    else
    {
	globalFunctions[nGlobalFunctions] . name = (char *) 0;
    }
    globalFunctions[nGlobalFunctions] . doRoutine = doRoutine;
    globalFunctions[nGlobalFunctions] . menu = menu;
    globalFunctions[nGlobalFunctions] . menuGroup = menuGroup;
    if (scriptLine)
    {
	globalFunctions[nGlobalFunctions] . scriptLine = Alloc(strlen(scriptLine) + 1);
	strcpy(globalFunctions[nGlobalFunctions] . scriptLine, scriptLine);
    }
    else
    {
	globalFunctions[nGlobalFunctions] . scriptLine = (char *) 0;
    }
    if (buttonHelp)
    {
	globalFunctions[nGlobalFunctions] . buttonHelp = Alloc(strlen(buttonHelp) + 1);
	strcpy(globalFunctions[nGlobalFunctions] . buttonHelp, buttonHelp);
    }
    else
    {
	globalFunctions[nGlobalFunctions] . buttonHelp = (char *) 0;
    }
    if (menuHelp)
    {
	globalFunctions[nGlobalFunctions] . menuHelp = Alloc(strlen(menuHelp) + 1);
	strcpy(globalFunctions[nGlobalFunctions] . menuHelp, menuHelp);
    }
    else
    {
	globalFunctions[nGlobalFunctions] . menuHelp = (char *) 0;
    }

    /*Put it on the appropriate menu*/
    if (menu)
    {
	/*Put it on menu*/
	ObjPtr action;

	action = NewAction(funcName, globalActionClass);
	SetVar(action, HELPSTRING, NewString(menuHelp));
	AddMenuItem(menu, action, menuGroup);
    }

    ++nGlobalFunctions;
}

ObjPtr GlobalAction(action)
ObjPtr action;
/*Does the action method of a global action*/
{
    int whichFunction;
    ObjPtr var;

    var = GetVar(action, NAME);
    if (var)
    {
	whichFunction = NameToGlobalFunction(GetString(var));
	if (contextHelp)
	{
	    /*Give help on the action*/
	    ContextHelp(action);
	    contextHelp = false;
	    MySetCursor(0);
	}
	else
	{
	    /*Log it*/
	    if (globalFunctions[whichFunction] . scriptLine)
	    {
		Log(globalFunctions[whichFunction] . scriptLine);
		Log("\n");
		InhibitLogging(true);
	    }
	    /*Do it*/
	    if (globalFunctions[whichFunction] . doRoutine)
	    {
		(*(globalFunctions[whichFunction] . doRoutine))();
	    }
	    if (globalFunctions[whichFunction] . scriptLine)
	    {
		InhibitLogging(false);
	    }
	}
    }
    return ObjTrue;
}

#ifdef PROTO
void InitGlobalFunctions(void)
#else
void InitGlobalFunctions()
#endif
/*Initializes global functions.  Assumes menus have been initialized*/
{
    /*Make the class for global actions*/
    globalActionClass = NewObject(actionClass, 0L);
    AddToReferenceList(globalActionClass);
    SetMethod(globalActionClass, ACTIONMETHOD, GlobalAction);

    DefineGlobalFunction(GF_HELP, DoShowHelp, "show help",
	"Pressing this button shows the SciAn help window, which gives you general help on using SciAn as well as the ability to get help on any control or menu item.",
	"Choosing this menu item shows the SciAn help window, which gives you general help on using SciAn as well as the ability to get help on any control or menu item.",
	mainMenu, 0);

    DefineGlobalFunction(GF_CONTEXTHELP, SetContextSensitiveHelp, (char *) 0,
	"Pressing this button prepares SciAn for giving you help in context.  \
After you press this press, you can click on any object in SciAn to get help on it.",
	"Choosing this menu item prepares SciAn for giving you help in context.  \
After you choose this item, you can click on any object in SciAn to get help on it.",
	hiddenMenu, 4);

#ifdef IRISNTSC
    DefineGlobalFunction(GF_TOGGLENTSC, ToggleNTSC, (char *) 0,
	"Pressing this button toggles in and out of NTSC mode.",
	"Choosing this menu item toggles in and out of NTSC mode.",
	hiddenMenu, 4);

    DefineGlobalFunction(GF_TOGGLESTEREO, ToggleStereo, (char *) 0,
	"Pressing this button toggles in and out of Crystal Eyes stereo mode.",
	"Choosing this menu item toggles in and out of Crystal Eyes stereo mode.",
	hiddenMenu, 4);
#endif

    DefineGlobalFunction(GF_PREFERENCES, DoShowPreferences, "show preferences",
	"Pressing this button shows a control panel that lets you change various interaction preferences and defaults within SciAn.",
	"Choosing this menu item shows a control panel that lets you change various interaction preferences and defaults within SciAn.",
	mainMenu, 0);

    DefineGlobalFunction(GF_QUIT, MaybeQuit, (char *) 0,
	"Pressing this button causes SciAn to quit.  You will be asked for a confirmation before the program quits.  If you do not want to see the confirmation, hold down the Alt key while pressing the button.",
	"Choosing this menu item causes SciAn to quit.  You will be asked for a confirmation before the program quits.  If you do not want to see the confirmation, hold down the Alt key before you release the mouse button.",
	mainMenu, 2);

    DefineGlobalFunction(GF_BROWSER, DoNewFileWindow, "new browser",
	"Pressing this button brings up a new file browser, which allows you \
to find and open disk files.  First you will \
see a dialog box asking for the directory to use.  If you know the name of the \
directory you want to use, enter it in the text box and press OK.  If you don't \
know the name of the directory, just press OK and navigate using the file browser.",
	"Choosing this menu item brings up a new file browser, which allows you \
to find and open disk files.  First you will \
see a dialog box asking for the directory to use.  If you know the name of the \
directory you want to use, enter it in the text box and press OK.  If you don't \
know the name of the directory, just press OK and navigate using the file browser.",
	fileMenu, 2);

    DefineGlobalFunction(GF_FILEREADERS, PopFileReadersWindow, "show file readers",
	"Pressing this button shows a window containing icons for all the file readers within SciAn.",
	"Choosing this menu item shows a window containing icons for all the file readers within SciAn.",
	fileMenu, 2);

#ifdef SOCKETS
    DefineGlobalFunction(GF_CONNECT, DoConnectToComputer, "connect",
	"Pressing this button connects you to another copy of SciAn over the network.  You will be asked for the address of the computer to which to connect.",
	"Choosing this menu item connects you to another copy of SciAn over the network.  You will be asked for the address of the computer to which to connect.",
	networkMenu, 2);
#endif

    DefineGlobalFunction(GF_DATASETS, PopDatasetsWindow, "show datasets",
	"Pressing this button shows a window containing icons for all the datasets that have been read into SciAn.",
	"Choosing this menu item shows a window containing icons for all the datasets that have been read into SciAn.",
	datasetsMenu, 2);

    DefineGlobalFunction(GF_SELECTALL, DoSelectAllIcons, (char *) 0,
	"Pressing this button selects all the icons in the window, if any.",
	"Choosing this menu item selects all the icons in the window, if any.",
	objectMenu, 2);
    DefineGlobalFunction(GF_DESELECTALL, DeselectAll, (char *) 0,
	"Pressing this button deselects all the currently selected objects, if any.",
	"Choosing this menu item deselects all the currently selected objects, if any.",
	objectMenu, 2);

#ifdef GODLIKE
    DefineGlobalFunction(GF_TOGGLEEDIT, ToggleShowBounds, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_SAVETEMPLATE, DoSaveTemplate, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWSLIDER, DoNewScreenSlider, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWSCALESLIDER, DoNewScreenScaleSlider, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWTITLEBOX, DoNewScreenTitleBox, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWRADIOBUTTON, DoNewScreenRadioButton, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWPLAINBUTTON, DoNewScreenPlainButton, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWSHORTBUTTON, DoNewScreenShortButton, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWCHECKBOX, DoNewScreenCheckBox, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWTEXTBOX, DoNewScreenTextBox, (char *) 0, "", "", deusMenu, 1);
    DefineGlobalFunction(GF_NEWEDITBOX, DoNewScreenEditableTextBox, (char *) 0, "", "", deusMenu, 1);
#endif

    DefineGlobalFunction(GF_RECORDERS, PopRecorderDriversWindow, "show recorders",
	"Pressing this button shows a window containing icons for all the animation recorder drivers within SciAn.",
	"Choosing this menu item shows a window containing icons for all the animation recorder drivers within SciAn.",
	animationMenu, 1);

#ifndef RELEASE
    DefineGlobalFunction(GF_NEWSEQUENCE, DoNewSequence, "new sequence",
	"Pressing this button creates a new animation sequence.",
	"Choosing this menu item creates a new animation sequence.",
	animationMenu, 1);
#endif

#ifndef RELEASE
    DefineGlobalFunction(GF_UNDO, Undo, (char *) 0,
	"Pressing this button undoes the last operation.  It doesn't really work on much yet.",
	"Choosing this menu item undoes the last operation.  It doesn't really work on much yet.",
	textMenu, 0);
#endif

    DefineGlobalFunction(GF_CLOSE, DoClose, "close",
	"Pressing this button closes the window.  On some systems such as the IBM RS/6000, \
this is the only safe way to close a window.  On other systems, such as Silicon Graphics \
workstations, you can also close a window using the Motif menu at the left side \
of the title bar.",
	"Choosing this menu item closes the window.  On some systems such as the IBM RS/6000, \
this is the only safe way to close a window.  On other systems, such as Silicon Graphics \
workstations, you can also close a window using the Motif menu at the left side \
of the title bar.",
	windowMenu, 4);
}

#ifdef PROTO
void KillGlobalFunctions(void)
#else
void KillGlobalFunctions(void);
#endif
{
    int k;

    for (k = 0; k < nGlobalFunctions; ++k)
    {
	SAFEFREE(globalFunctions[k] . name);
	SAFEFREE(globalFunctions[k] . scriptLine);
	SAFEFREE(globalFunctions[k] . menuHelp);
	SAFEFREE(globalFunctions[k] . buttonHelp);
    }
    SAFEFREE(globalFunctions);
    RemoveFromReferenceList(globalActionClass);
}


Modified: Sun Nov 17 17:00:00 1996 GMT
Page accessed 4583 times since Sat Apr 17 21:54:46 1999 GMT