CCL Home Page
Up Directory CCL ScianWindowFunctions.c
/*ScianWindowFunctions.c
  Eric Pepke
  10 August 1993

  Does window functions, i.e., functions that work on individual windows.
*/

#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 "ScianWindowFunctions.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"
#include "ScianSymbols.h"

ObjPtr windowActionClass;
ObjPtr toggledWindowActionClass;

typedef struct
    {
	char *name;		/*Name of function*/
	NameTyp message;	/*Message to send to window*/
	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*/
    } WindowFunction;

int nWindowFunctions = 0;	/*# of window functions*/

static WindowFunction *windowFunctions;

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

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

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

#ifdef HAVE_PROTOTYPES
Bool WindowFunctionScriptLine(char *line)
#else
Bool WindowFunctionScriptLine(line)
char *line;
#endif
/*If s is a script line, finds out if it is a valid script line for a
  window 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 < nWindowFunctions; ++funcNum)
    {
	/*Try to match script line against script*/
	s = line;
	p = windowFunctions[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*/

	    Log(windowFunctions[funcNum] . scriptLine);
	    Log("\n");

	    DeferMessage((ObjPtr) selWinInfo, windowFunctions[funcNum] . message);

	    return true;
	}
    }
    return false;
}

#ifdef HAVE_PROTOTYPES
void DefineWindowFunction(char *funcName, NameTyp message,
	char *scriptLine,
	char *buttonHelp,
	char *menuHelp, ObjPtr menu, int menuGroup)
#else
void DefineWindowFunction(funcName, message, scriptLine,
	buttonHelp, menuHelp, menu, menuGroup)
char *funcName;
NameTyp message;
char *scriptLine;
char *buttonHelp;
char *menuHelp;
ObjPtr menu;
int menuGroup;
#endif
/*Defines a window function
    funcName	    is the name of the function for the menu and buttons
    message	    is a message 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 (nWindowFunctions)
    {
	windowFunctions = Realloc(windowFunctions, (nWindowFunctions + 1) * sizeof(WindowFunction));
    }
    else
    {
	windowFunctions = Alloc((nWindowFunctions + 1) * sizeof(WindowFunction));
    }

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

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

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

    ++nWindowFunctions;
}

#ifdef HAVE_PROTOTYPES
void DefineToggledWindowMenuItem(char *trueName, char *falseName, NameTyp flag, ObjPtr menu, int menuGroup)
#else
void DefineToggledWindowMenuItem(trueName, falseName, flag, menu, menuGroup)
char *trueName;
char *falseName;
NameTyp flag;
ObjPtr menu;
int menuGroup;
#endif
/*Defines a menu item that toggles between window functions trueName and falseName 
 based on flag in group at menu*/
{
    ObjPtr action;

    action = NewAction((char *) 0, toggledWindowActionClass);
    SetVar(action, WHICHVAR, NewSymbol(flag));
    SetVar(action, TRUENAME, NewString(trueName));
    SetVar(action, FALSENAME, NewString(falseName));

    DeclareDependency(action, NAME, MOUSEWINDOW);
    DeclareIndirectDependency(action, NAME, MOUSEWINDOW, flag);

    AddMenuItem(menu, action, menuGroup);
}

ObjPtr MakeToggledWindowActionName(action)
ObjPtr action;
/*Makes a toggled window action's name*/
{
    ObjPtr var;
    NameTyp whichVar;

    var = GetSymbolVar("MakeToggledWindowActionName", action, WHICHVAR);
    if (!var) return ObjFalse;
    whichVar = GetSymbolID(var);

    if (GetPredicate((ObjPtr) selWinInfo, whichVar))
    {
	SetVar(action, NAME, GetVar(action, TRUENAME));
    }
    else
    {
	SetVar(action, NAME, GetVar(action, FALSENAME));
    }

    return ObjTrue;
}

ObjPtr MakeToggledWindowMenuHelp(action, class)
ObjPtr action;
ObjPtr class;
/*Makes a toggled window action's menu help*/
{
    char help[600], *s;
    ObjPtr var, var2;
    int whichFunction;

    MakeVar(action, NAME);
    var = GetStringVar("MakeToggledWindowActionHelp", action, NAME);
    if (!var) return NULLOBJ;

    whichFunction = NameToWindowFunction(GetString(var));

    strcpy(help, windowFunctions[whichFunction] . menuHelp);
    s = help;
    while (*s) ++s;
    *s = '\0';

    var = GetStringVar("MakeToggledWindowActionHelp", action, TRUENAME);
    if (var)
    {
	var2 = GetStringVar("MakeToggledWindowActionHelp", action, FALSENAME);
	if (var2)
	{
	    sprintf(s, "\n\nThis menu item toggles between '%s' and '%s' depending on the state of the window.\n",
		GetString(var), GetString(var2));
	}
    }

    SetVar(class, HELPSTRING, NewString(help));

    return ObjTrue;
}

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

    var = GetVar(action, NAME);
    if (var)
    {
	whichFunction = NameToWindowFunction(GetString(var));
	if (contextHelp)
	{
	    /*Give help on the action*/
	    ContextHelp(action);
	    contextHelp = false;
	    MySetCursor(0);
	}
	else
	{
	    /*Log it*/
	    if (windowFunctions[whichFunction] . scriptLine)
	    {
		Log(windowFunctions[whichFunction] . scriptLine);
		Log("\n");
	    }
	    /*Do it*/
	    if (selWinInfo)
	    {
		DeferMessage((ObjPtr) selWinInfo, windowFunctions[whichFunction] . message);
	    }
	}
    }
    return ObjTrue;
}

ObjPtr ToggledWindowAction(action)
ObjPtr action;
/*Does the action method of a toggled window action*/
{
    int whichFunction;
    ObjPtr var;
    ObjPtr parent;

    MakeVar(action, NAME);
    var = GetVar(action, NAME);
    if (var)
    {
	whichFunction = NameToWindowFunction(GetString(var));
	if (contextHelp)
	{
	    /*Give help on the action*/
	    ContextHelp(action);
	    contextHelp = false;
	    MySetCursor(0);
	}
	else
	{
	    /*Log it*/
	    if (windowFunctions[whichFunction] . scriptLine)
	    {
		Log(windowFunctions[whichFunction] . scriptLine);
		Log("\n");
	    }
	    /*Do it*/
	    if (selWinInfo)
	    {
		DeferMessage((ObjPtr) selWinInfo, windowFunctions[whichFunction] . message);
	    }
	}
    }

    /*Make everything changed, so that it will have to remake menu*/
    SetVar(action, CHANGED, ObjTrue);

    parent = action;
    while (parent = GetVar(parent, PARENT))
    {
	SetVar(parent, ITEMS, GetVar(parent, ITEMS));
    }

    return ObjTrue;
}

static ObjPtr MakeWindowActionActivated(action)
ObjPtr action;
/*Makes a window action activated*/
{
    ObjPtr allSelected;
    ThingListPtr runner;
    int f;
    ObjPtr var;

    MakeVar(action, NAME);
    var = GetStringVar("MakeWindowActionActivated", action, NAME);
    if (!var) return ObjFalse;
    f = NameToWindowFunction(GetString(var));
    if (f < 0) return ObjFalse;

    if (selWinInfo)
    {
	if (GetMethod((ObjPtr) selWinInfo, windowFunctions[f] . message))
	{
	    SetVar(action, ACTIVATED, ObjTrue);
	    return ObjTrue;
	}
    }
    SetVar(action, ACTIVATED, ObjFalse);
    return ObjTrue;
}

#ifdef HAVE_PROTOTYPES
void InitWindowFunctions(void)
#else
void InitWindowFunctions()
#endif
/*Initializes the window function system*/
{
    /*Make the class for window actions*/
    windowActionClass = NewObject(actionClass, 0L);
    AddToReferenceList(windowActionClass);
    SetMethod(windowActionClass, ACTIONMETHOD, WindowAction);
    SetVar(windowActionClass, ACTIVATED, ObjFalse);
    SetMethod(windowActionClass, ACTIVATED, MakeWindowActionActivated);
    DeclareDependency(windowActionClass, ACTIVATED, READYTOACTIVATE);

    /*Make the class for toggled window actions*/
    toggledWindowActionClass = NewObject(windowActionClass, 0L);
    AddToReferenceList(toggledWindowActionClass);
    SetMethod(toggledWindowActionClass, ACTIONMETHOD, ToggledWindowAction);
    DeclareDependency(toggledWindowActionClass, NAME, CHANGED);
    SetMethod(toggledWindowActionClass, NAME, MakeToggledWindowActionName);
    SetMethod(toggledWindowActionClass, MAKE1HELPSTRING, MakeToggledWindowMenuHelp);

    /*Define the actions*/
    DefineWindowFunction(WF_SAVEWINDOW, SAVEWINDOW, "save window",
	"Pressing this button saves the image in the window to a file, using the window saver chosen in the Preferences control panel.",
	"Choosing this menu item saves the image in the window to a file, using the window saver chosen in the Preferences control panel.",
	windowMenu, 1);

    DefineWindowFunction(WF_SAVEFWINDOW, SAVEFWINDOW, "save framed window",
	"Pressing this button saves the image in the window including its frame to a file, using the window saver chosen in the Preferences control panel.",
	"Choosing this menu item saves the image in the window including its frame to a file, using the window saver chosen in the Preferences control panel.",
	windowMenu, 1);

    DefineWindowFunction(WF_SAVESCREEN, SAVESCREEN, "save screen",
	"Pressing this button saves the image on the screen to a file, using the window saver chosen in the Preferences control panel.",
	"Choosing this menu item saves the image on the screen to a file, using the window saver chosen in the Preferences control panel.",
	windowMenu, 1);

    DefineWindowFunction(WF_SHOWFRAME, SHOWFRAME, "show frame",
	"Pressing this button shows the frame of the window.",
	"Choosing this menu item shows the frame of the window.",
	windowMenu, 1);

    DefineWindowFunction(WF_HIDEFRAME, HIDEFRAME, "hide frame",
	"Pressing this button shows the frame of the window.",
	"Choosing this menu item shows the frame of the window.",
	windowMenu, 1);

    DefineWindowFunction(WF_SHOWPANEL, SHOWPANEL, "show panel",
	"Pressing this button shows the control panels of a visualization window.",
	"Choosing this menu item shows the control panels of a visualization window.",
	NULLOBJ, 1);

    DefineWindowFunction(WF_HIDEPANEL, HIDEPANEL, "hide panel",
	"Pressing this button hides the control panels of a visualization window.",
	"Choosing this menu item hides the control panels of a visualization window.",
	NULLOBJ, 1);

    DefineToggledWindowMenuItem(WF_SHOWPANEL, WF_HIDEPANEL, PANELHIDDEN, windowMenu, 1);

    DefineWindowFunction(WF_PREVSCREEN, PREVSCREEN, (char *) 0,
	"Pressing this button undoes the last change in window size and location.",
	"Choosing this menu item undoes the last change in window size and location.",
	locationMenu, 1);

    DefineWindowFunction(WF_FULLSCREEN, FULLSCREEN, (char *) 0,
	"Pressing this button expands the window to cover the full screen.",
	"Choosing this menu item expands the window to cover the full screen.",
	locationMenu, 1);

    DefineWindowFunction(WF_VIDEOSCREEN, VIDEOSCREEN, (char *) 0,
	"Pressing this button resizes and moves the window to cover the video screen at the lower left corner \
of the workstation screen.  This is useful for doing animations in Silicon Graphics 'NTSC' mode.",
	"Choosing this menu item resizes and moves the window to cover the video screen at the lower left corner \
of the workstation screen.  This is useful for doing animations in Silicon Graphics 'NTSC' mode.",
	locationMenu, 1);

    DefineWindowFunction(WF_DOUBLEVID, DOUBLEVIDSCREEN, (char *) 0,
	"Pressing this button resizes and moves the window to cover an area twice the size of the video screen at the lower left corner \
of the workstation screen.  This is useful for doing animations in Silicon Graphics 'NTSC' mode when the 4 to 1 reduction filter is on \
in the Renderer control panel.",
	"Choosing this menu item resizes and moves the window to cover an area twice the size of the video screen at the lower left corner \
of the workstation screen.  This is useful for doing animations in Silicon Graphics 'NTSC' mode when the 4 to 1 reduction filter is on \
in the Renderer control panel.",
	locationMenu, 1);

    DefineWindowFunction(WF_PHSCSCREEN, PHSCSCREEN, (char *) 0,
	"Pressing this button resizes and moves the window to cover an area at the lower left corner \
the right size and shape for saving images for a PHSCologram.  The image will appear on its side, skewed \
to compensate for the aspect ratio of the PHSCologram.  PHSColograms are barrier strip \
autostereograms produced by Ellen Sandor and Stephan Myers at the Art(n) Institute.",
	"Choosing this menu item resizes and moves the window to cover an area at the lower left corner \
the right size and shape for saving images for a PHSCologram.  The image will appear on its side, skewed \
to compensate for the aspect ratio of the PHSCologram.  PHSColograms are barrier strip \
autostereograms produced by Ellen Sandor and Stephan Myers at the Art(n) Institute.",
	locationMenu, 1);

   DefineWindowFunction(WF_SHOWFPCONTROLS, SHOWFPCONTROLS, "show front panel controls",
	"Pressing this button shows the controls for the 2-D panel in front of the space in this window.",
	"Choosing this menu item shows the controls for the 2-D panel in front of the space in this window.",
	windowMenu, 2);

   DefineWindowFunction(WF_SHOWBPCONTROLS, SHOWBPCONTROLS, "show back panel controls",
	"Pressing this button shows the controls for the 2-D panel in back of the space in this window.",
	"Choosing this menu item shows the controls for the 2-D panel in back of the space in this window.",
	windowMenu, 2);

   DefineWindowFunction(WF_SHOWSPCONTROLS, SHOWSPCONTROLS, "show space controls",
	"Pressing this button shows the controls for the space in this window.",
	"Choosing this menu item shows the controls for the space in this window.",
	windowMenu, 2);

    DefineWindowFunction(WF_TILEFULL, TILEFULL, (char *) 0,
	"Pressing this button tiles all the visualization windows to cover the full screen.",
	"Choosing this menu item tiles all the visualization windows to cover the full screen.",
	tileMenu, 1);

    DefineWindowFunction(WF_TILEVIDEO, TILEVIDEO, (char *) 0,
	"Pressing this button tiles all the visualization windows to cover the video screen at the lower left corner \
of the workstation screen.  This is useful for doing animations in Silicon Graphics 'NTSC' mode.",
	"Choosing this menu item tiles all the visualization windows to cover the video screen at the lower left corner \
of the workstation screen.  This is useful for doing animations in Silicon Graphics 'NTSC' mode.",
	tileMenu, 1);
}

#ifdef HAVE_PROTOTYPES
void KillWindowFunctions(void)
#else
void KillWindowFunctions()
#endif
/*Kills the window function system*/
{
    int k;

    for (k = 0; k < nWindowFunctions; ++k)
    {
	SAFEFREE(windowFunctions[k] . name);
	SAFEFREE(windowFunctions[k] . scriptLine);
	SAFEFREE(windowFunctions[k] . menuHelp);
	SAFEFREE(windowFunctions[k] . buttonHelp);
    }
    SAFEFREE(windowFunctions);
    RemoveFromReferenceList(windowActionClass);
    RemoveFromReferenceList(toggledWindowActionClass);
}

Modified: Sun Nov 17 17:00:00 1996 GMT
Page accessed 4470 times since Sat Apr 17 21:55:04 1999 GMT