CCL Home Page
Up Directory CCL ScianIcons.c
/*ScianIcons.c
  Eric Pepke
  March 22, 1990
  Does icon stuff in scian

  Added PostScript output to DrawIcon, 8/25/92, JEL
*/

#include "Scian.h"
#include "ScianTypes.h"
#include "ScianIcons.h"
#include "ScianColors.h"
#include "ScianArrays.h"
#include "ScianErrors.h"
#include "ScianLists.h"
#include "ScianIDs.h"
#include "ScianEvents.h"
#include "ScianControls.h"
#include "ScianScripts.h"
#include "ScianStyle.h"
#include "ScianDraw.h"
#include "ScianTextBoxes.h"
#include "ScianFontSystem.h"
#ifdef GRAPHICS
#include "ScianIconFonts.h"
#endif


ObjPtr iconClass = 0;
int iconXOff, iconYOff;		/*Offsets for icons on dragging*/

#define COLORICONXOFFSET	-5	/*X offset for color icon*/
#define COLORICONYOFFSET	0	/*Y offset for color icon*/

#define NRAINBOWCOLORS	5

int rainbowColor[NRAINBOWCOLORS] =
    {
	UIRED,
	UIYELLOW,
	UIGREEN,
	UICYAN,
	UIBLUE
    };


static ObjPtr ColorIconExtraDraw(object, x, y)
ObjPtr object;
int x, y;
/*Draws extra stuff for a color icon*/
{
#ifdef GRAPHICS
    short bx, by, ex, ey, k;

    bx = x + COLORICONXOFFSET;
    by = y + COLORICONYOFFSET;
    ex = x + ICONSIZE / 2;
    ey = by - (ex - bx) / 2;
    for (k = 0; k < NRAINBOWCOLORS; ++k)
    {
	SetUIColor(rainbowColor[k]);
	FillTri(bx, by, ex, ey, ex, ey + (ex - bx) / (NRAINBOWCOLORS - 1));
	ey += (ex - bx) / (NRAINBOWCOLORS - 1);
    }
#endif
}

#ifdef HAVE_PROTOTYPES
void DrawIcon(int x, int y, int whichIcon, char *iconTitle, char *subTitle, int backColor, int flags)
#else
void DrawIcon(x, y, whichIcon, iconTitle, subTitle, backColor, flags)
int x, y, whichIcon;
char *iconTitle;
char *subTitle;
int backColor;
int flags;
#endif
/*Draw icon whichIcon with its center at x, y with title
  iconTitle.  If iconTitle is NIL, doesn't draw a title.  
  Draws the background of the color in UIcolor backColor.
  Flags tells what parts to draw.
*/
{
#ifdef GRAPHICS
    Icoord v[4][2];
    char s[2];
    int texty;
    int k;
    int iconFont, iconChar, iconIndex;
    int fontSize;

    s[1] = '\0';

    /*Get the icon font and character*/
    iconFont = iconFontLocationTable[whichIcon - 32][0];
    iconChar = iconFontLocationTable[whichIcon - 32][1];

    if (drawingMode == DRAW_SCREEN)
    {
	font(ICONBEGFONTS + iconFont);
    }
    else if (drawingMode == DRAW_POSTSCRIPT && psFile)
    {
	RegisterFontUsed("icons");
	if ((iconIndex = RegisterIconUsed(whichIcon)) < 0) return;
	if (strcmp("icons", curFontName) != 0)
	{
	    fprintf(psFile,"/icons findfont 32 scalefont setfont\n");
	    strcpy(curFontName, "icons"); /* remember this */
	    curFontSize = 32;
	}
    }

    if (flags & DI_DRAWSHADOW)
    {
	SetUIColor(UISHADOW);
	if (drawingMode == DRAW_SCREEN)
	{
	    cmov2i(x - ICONSIZE / 2, y - ICONSIZE / 2 - ICONSHADOW);
	    s[0] = iconChar + 2;
	    charstr(s);
	}
	else if (drawingMode == DRAW_POSTSCRIPT && psFile)
	{
	    fprintf(psFile, "%f setgray\n", PSColor());
	    s[0] = 32 + 3*iconIndex + 2;
	    fprintf(psFile,"%d %d moveto (%s) show\n",
		x - ICONSIZE/2, y - ICONSIZE/2 - ICONSHADOW, PSShow(s));
	}
    }


    for (k = 0; k >= 0; --k)
    {
	if (flags & DI_DRAWBACK)
	{
	    SetUIColor(k ? UIICONGREYBACK : backColor);
	    if (drawingMode == DRAW_SCREEN)
	    {
		cmov2i(x - ICONSIZE / 2 + k * 2, y - ICONSIZE / 2 + k * 2);
		s[0] = iconChar + 1;
		charstr(s);
	    }
            else if (drawingMode == DRAW_POSTSCRIPT && psFile)
    	    {
		fprintf(psFile, "%f setgray\n", PSColor());
		s[0] = 32 + 3*iconIndex + 1;
                fprintf(psFile,"%d %d moveto (%s) show\n",
                    x - ICONSIZE/2 + k*2, y - ICONSIZE/2 + k*2, PSShow(s));
    	    }
	}

	if (flags & DI_DRAWFORE)
	{
	    if (flags & DI_GREY || k)
	    {
		SetUIColor(UIICONGREYFORE);
	    }
	    else
	    {
		SetUIColor(UIICONFORE);
	    }
	    if (drawingMode == DRAW_SCREEN)
	    {
		cmov2i(x - ICONSIZE / 2 + k * 2, y - ICONSIZE / 2 + k * 2);
		s[0] = iconChar;
		charstr(s);
	    }
            else if (drawingMode == DRAW_POSTSCRIPT && psFile)
            {
		fprintf(psFile, "%f setgray\n", PSColor());
		s[0] = 32 + 3*iconIndex;
                fprintf(psFile,"%d %d moveto (%s) show\n",
                    x - ICONSIZE/2 + k*2, y - ICONSIZE/2 + k*2, PSShow(s));
            }
 	}
    }

    texty = y - ICONSIZE / 2 - (flags & DI_DRAWSHADOW ? ICONSHADOW : 0) - ICONTEXTOFFSET;
    if (iconTitle)
    {
	char *s, *s2;

	SetUIColor(UITEXT);
	fontSize = flags & DI_SMALLTEXT ? ICONTEXTSMALLSIZE : ICONTEXTSIZE;
	SetUIFont(flags & DI_SMALLTEXT ? UIICONSUBFONT : UIICONFONT);

	s = iconTitle;
	s2 = tempStr;

	while (*s)
	{
	    if (*s == '\n')
	    {
		*s2 = 0;
		++s;
		s2 = tempStr;
		DrawAString(CENTERALIGN, x, 
		   texty,
		   tempStr);
		texty -= (fontSize);
	    }
	    else
	    {
		*s2 = *s;
		++s;
		++s2;
	    }
	}
	*s2 = 0;
	DrawAString(CENTERALIGN, x, 
		   texty,
		   tempStr);

    if (subTitle)
    {
	texty -= (fontSize + 2);
	SetUIColor(UITEXT);
	SetUIFont(UIICONSUBFONT);
	DrawAString(CENTERALIGN, x, 
	           texty,
		   subTitle);
    }
    }   
#endif
}

#ifdef HAVE_PROTOTYPES
void GenIconDef(FILE *outFile)
#else
void GenIconDef(outFile)
FILE *outFile;
#endif
/* output PostScript font definition for icons used in eps file */
{
#ifdef GRAPHICS
    int icon, c, i, j, k;

    if (!outFile || numIconsUsed < 1) return;
    
    /* generate font def header and Encoding array */
    fprintf(outFile, 
"%%%%BeginFont: icons\n\
/iconfont 10 dict def\n\
iconfont begin\n\
	/FontType 3 def\n\
	/FontMatrix [1 0 0 1 0 0] def\n\
	/FontBBox [0 0 32 32] def\n\
	/Encoding 256 array def\n\
	0 1 255 { Encoding exch /.notdef put } for\n\n");

    for (i=0, c=32; i} def\n");
	
	fprintf(outFile, "\t\t/back%02d\n\t\t{<\n\t\t", i);
	for (k=0; k<4; ++k)
	{
	  for (j=0; j<16; ++j)
	    fprintf(outFile,"%04X",*p++);
	  fprintf(outFile,"\n\t\t");
	}
	fprintf(outFile, ">} def\n");
	
	fprintf(outFile, "\t\t/shad%02d\n\t\t{<\n\t\t", i);
	for (k=0; k<4; ++k)
	{
	  for (j=0; j<16; ++j)
	    fprintf(outFile,"%04X",*p++);
	  fprintf(outFile,"\n\t\t");
	}
	fprintf(outFile, ">} def\n\n");
    }

    /* generate font def trailer */
    fprintf(outFile, 
"	end %%CharProcs\n\
\n\
	/BuildChar\n\
	{\n\
		32 0 0 0 32 32 setcachedevice\n\
		exch begin		%%icon font dict\n\
		Encoding exch get	%%get icon index\n\
		CharProcs exch get	%%get icon name\n\
		end\n\
		32 32\n\
		true\n\
		[32 0 0 32 0 0]\n\
		5 -1 roll               %%get name back on top\n\
		exec			%%get bits\n\
		imagemask		%%draw it\n\
	} def\n\
\n\
end %%iconfont\n\
\n\
/icons iconfont definefont pop\n\
%%%%EndFont\n\n");

#endif
    return;    
}

#ifdef HAVE_PROTOTYPES
void DrawIconGhost(ObjPtr icon, int xDisp, int yDisp)
#else
void DrawIconGhost(icon, xDisp, yDisp)
ObjPtr icon;
int xDisp, yDisp;
#endif
/*Draw a ghost of icon icon, displacint its center by xDisp, yDisp.*/
{
#ifdef GRAPHICS
    Icoord v[4][2];
    char s[2];
    ObjPtr theName, whichIconInt, theLoc;
    int x, y;
    real loc[2];
    int whichIcon;
    char *name;
    int iconFont, iconChar;

    theName = GetVar(icon, NAME);
    if (IsString(theName))
    {
	name = GetString(theName);
    }
    else
    {
	name = 0;
    }
    whichIconInt = GetVar(icon, WHICHICON);
    if (whichIconInt && IsInt(whichIconInt))
    {
	whichIcon = GetInt(whichIconInt);
    }
    else
    {
	return;
    }
    theLoc = GetFixedArrayVar("DrawIconGhost", icon, ICONLOC, 1, 2L);
    if (!theLoc)
    {
	return;
    }
    Array2CArray(loc, theLoc);
    x = loc[0] + xDisp;
    y = loc[1] + yDisp;

    iconFont = iconFontLocationTable[whichIcon - 32][0];
    iconChar = iconFontLocationTable[whichIcon - 32][1];
    font(ICONBEGFONTS + iconFont);

    s[1] = 0;
    s[0] = iconChar;

    cmov2i(x - ICONSIZE / 2, y - ICONSIZE / 2);
    charstr(s); 

    if (name)
    {
	SetUIFont(UIICONFONT);
	DrawAString(CENTERALIGN, x, 
		   y - ICONSIZE / 2 - ICONSHADOW - ICONTEXTOFFSET,
		   name);
    }
#endif
}

ObjPtr IconBoundsInvalid(icon, changeCount)
ObjPtr icon;
unsigned long changeCount;
/*Returns invalid bounds of icon*/
{
    ObjPtr var;

    MakeVar(icon, APPEARANCE);

    if (GetVarChangeCount(icon, CHANGEDBOUNDS) > changeCount)
    {
	real loc[2], bounds[4];


	var = GetVar(icon, ICONLOC);
	if (!var)
	{
	    return ObjTrue;
	}
	Array2CArray(loc, var);

	bounds[0] = loc[0] - ICONSIZE / 2 - 1 - ICONINVALEXTRA;
	bounds[1] = loc[0] + ICONSIZE / 2 + 1;
	bounds[2] = loc[1] - ICONSIZE / 2 - 1;
	bounds[3] = loc[1] + ICONSIZE / 2 + 1 + ICONINVALEXTRA;

	MakeVar(icon, NAME);
	if (GetVarChangeCount(icon, NAME) > changeCount)
	{
	    ObjPtr name, oldName;
	    int w1, w2, w;

	    SetUIFont(UIICONFONT);

	    name = GetVar(icon, NAME);
	    if (name)
	    {
		w1 = StrWidth(GetString(name));
	    }
	    else
	    {
		w1 = 0;
	    }

	    name = GetVar(icon, OLDNAME);
	    if (name)
	    {
		w2 = StrWidth(GetString(name));
	    }
	    else
	    {
		w2 = 0;
	    }

	    w = MAX(w1, w2);
	    if (w > 0)
	    {
		int m;
		m = ((int) (bounds[0] + bounds[1])) / 2;
		bounds[2] -= ICONSHADOW + ICONTEXTOFFSET + 6;
		bounds[0] = MIN(bounds[0], m - 2 - w/2);
		bounds[1] = MAX(bounds[1], m + 2 + w/2);
	    }
	}

	MakeVar(icon, FORMAT);
	if (GetVarChangeCount(icon, FORMAT) > changeCount)
	{
	    ObjPtr name, oldName;
	    int w1, w2, w;

	    SetUIFont(UIICONSUBFONT);

	    name = GetVar(icon, FORMAT);
	    if (name)
	    {
		w1 = StrWidth(GetString(name));
	    }
	    else
	    {
		w1 = 0;
	    }

	    name = GetVar(icon, OLDFORMAT);
	    if (name)
	    {
		w2 = StrWidth(GetString(name));
	    }
	    else
	    {
		w2 = 0;
	    }

	    w = MAX(w1, w2);
	    if (w > 0)
	    {
		int m;
		m = ((int) (bounds[0] + bounds[1])) / 2;
		bounds[2] -= 12;
		bounds[0] = MIN(bounds[0], m - 2 - w/2);
		bounds[1] = MAX(bounds[1], m + 2 + w/2);
	    }
	}

	var = NewRealArray(1, 4L);
	CArray2Array(var, bounds);
	return var;
    }
    else
    {
	return NULLOBJ;
    }
}

ObjPtr DrawIconObj(object)
ObjPtr object;
/*Draws this icon thing*/
{
#ifdef GRAPHICS
    ObjPtr theLoc;
    ObjPtr theName;
    char *title, *subTitle;
    ObjPtr whichIconInt;
    real loc[2];
    int whichIcon;
    FuncTyp method;
    ObjPtr repObj;
    Bool isGreyed;
    int backColor;
    ObjPtr var;

    theLoc = GetFixedArrayVar("DrawIconObj", object, ICONLOC, 1, 2L);
    if (!theLoc)
    {
	return NULLOBJ;
    }

    MakeVar(object, NAME);
    theName = GetVar(object, NAME);
    if (theName && IsString(theName))
    {
	title = GetString(theName);
    }
    else
    {
	title = (char *) 0;
    }

    MakeVar(object, FORMAT);
    theName = GetVar(object, FORMAT);
    if (theName && IsString(theName))
    {
	subTitle = GetString(theName);
    }
    else
    {
	subTitle = (char *) 0;
    }

    whichIconInt = GetVar(object, WHICHICON);
    if (whichIconInt && IsInt(whichIconInt))
    {
	whichIcon = GetInt(whichIconInt);
    }
    else
    {
	whichIcon = ICONQUESTION;
    }

    Array2CArray(loc, theLoc);

    MakeVar(object, ICONGREYED);
    isGreyed = GetPredicate(object, ICONGREYED);

    var = GetVar(object, BACKGROUND);
    if (var)
    {
	backColor = GetInt(var);
    }
    else
    {
	backColor = UIICONBACK;
    }

    repObj = GetVar(object, REPOBJ);

    DrawIcon((int) loc[0], (int) loc[1], whichIcon, 
		title, subTitle, 
		IsSelected(repObj ? repObj : object) ? UIICONSELBACK : 
		    (isGreyed ? UIICONGREYBACK : backColor),
		DI_DRAWFORE | DI_DRAWBACK | DI_DRAWSHADOW | 
		(GetPredicate(repObj, TEMPLATEP) ? DI_TEMPLATE : 0) |
		(isGreyed ? DI_GREY : 0));

    method = GetMethod(object, ICONEXTRADRAW);
    if (method)
    {
	(*method)(object, (int) loc[0], (int) loc[1]);
    }
#endif
    return ObjTrue;
}

ObjPtr NewIcon(x, y, whichIcon, name)
int x, y;
int whichIcon;
char *name;
/*Makes and returns a new icon of type whichIcon and name name*/
{
    ObjPtr retVal;

    retVal = NewObject(iconClass, 0);
    if (whichIcon == ICONCOLOR)
    {
	SetMethod(retVal, ICONEXTRADRAW, ColorIconExtraDraw);
    }
    if (retVal)
    {
	real loc[2];
	ObjPtr locArray;
	
	loc[0] = x;
	loc[1] = y;
	locArray = NewRealArray(1, (long) 2);
	if (locArray)
	{
	    CArray2Array(locArray, loc);
	    SetVar(retVal, ICONLOC, locArray);
	}

	SetVar(retVal, WHICHICON, NewInt(whichIcon));

	if (name)
	{
	    SetVar(retVal, NAME, NewString(name));
	}
    }

    return retVal;
}

ObjPtr MakeIconGreyed(icon)
ObjPtr icon;
/*Makes an icon greyed or not*/
{
    ObjPtr repObj;
    repObj = GetVar(icon, REPOBJ);
    if (repObj)
    {
	SetVar(icon, ICONGREYED, GetVar(repObj, HIDDEN));
    }
    else
    {
	SetVar(icon, ICONGREYED, ObjFalse);
    }
}

static ObjPtr MakeIconAppearance(icon)
ObjPtr icon;
/*Dummy make for icon appearance*/
{
    SetVar(icon, APPEARANCE, ObjTrue);
    ImInvalid(icon);
    return ObjTrue;
}

static ObjPtr MakeIconName(icon)
ObjPtr icon;
/*Makes an icon's name from its REPOBJ*/
{
    ObjPtr repObj;

    MakeVar(icon, REPOBJ);
    repObj = GetVar(icon, REPOBJ);
    if (repObj)
    {
	SetVar(icon, OLDNAME, GetVar(icon, NAME));
	SetVar(icon, NAME, GetVar(repObj, NAME));
	ImInvalid(icon);
    }
    else
    {
	SetVar(icon, NAME, GetVar(icon, NAME));
    }
    return ObjTrue;
}

static ObjPtr MakeIconFormat(icon)
ObjPtr icon;
/*Makes an icon's format from its REPOBJ*/
{
    ObjPtr repObj;

    MakeVar(icon, REPOBJ);
    repObj = GetVar(icon, REPOBJ);
    if (repObj)
    {
	SetVar(icon, OLDFORMAT, GetVar(icon, FORMAT));
	SetVar(icon, FORMAT, GetVar(repObj, FORMAT));
	ImInvalid(icon);
    }
    else
    {
	SetVar(icon, FORMAT, GetVar(icon, FORMAT));
    }
    return ObjTrue;
}

void InitIcons()
{
    iconClass = NewObject(screenClass, 0);
    AddToReferenceList(iconClass);
    SetVar(iconClass, CLASSID, NewInt(CLASS_ICON));
    SetMethod(iconClass, DRAW, DrawIconObj);
    SetVar(iconClass, TYPESTRING, NewString("icon"));
    DeclareIndirectDependency(iconClass, ICONGREYED, REPOBJ, HIDDEN);
    SetMethod(iconClass, ICONGREYED, MakeIconGreyed);
    DeclareIndirectDependency(iconClass, APPEARANCE, REPOBJ, SELECTED);
    DeclareIndirectDependency(iconClass, APPEARANCE, REPOBJ, HIDDEN);
    DeclareDependency(iconClass, APPEARANCE, NAME);
    DeclareDependency(iconClass, APPEARANCE, FORMAT);
    DeclareIndirectDependency(iconClass, NAME, REPOBJ, NAME);
    DeclareIndirectDependency(iconClass, FORMAT, REPOBJ, FORMAT);
    SetMethod(iconClass, APPEARANCE, MakeIconAppearance);
    SetMethod(iconClass, BOUNDSINVALID, IconBoundsInvalid);
    SetMethod(iconClass, NAME, MakeIconName);
    SetMethod(iconClass, FORMAT, MakeIconFormat);
    SetVar(iconClass, REPOBJONLY, ObjTrue);
}

void DefineIconFonts()
/*Initializes the icon system*/
{
    int i;
#ifdef GRAPHICS
    for (i = 0; i < NICONFONTS; ++i)
    {
	defrasterfont(ICONBEGFONTS + i,
		iconFontParameters[i] . ht,
		iconFontParameters[i] . nc,
		iconFontParameters[i] . chars,
		iconFontParameters[i] . rs,
		(void *) iconFontParameters[i] . rasters);
	/*Have to use (void *) cast to make compatible both
	 with SGI and IBM*/
    }
#endif
}

void KillIcons()
/*Kills the icons*/
{
    DeleteThing(iconClass);
}
Modified: Sun Nov 17 17:00:00 1996 GMT
Page accessed 4374 times since Sat Apr 17 21:55:02 1999 GMT