/********************************************************************** * * TITLE: * level.c * * AUTHOR: * Cassie Mulnix * * DESCRIPTION: * This module is part of the OPPS editor, xopps. It contains * object routines to handle level objects. * * CHANGE HISTORY * * $Log: level.c,v $ * Revision 1.23 1994/12/31 04:10:21 kevin * fixed memory allocation problem after DialogTextGet * * Revision 1.22 1994/08/10 22:02:18 cassie * fixed DialogFlagSet calls * * Revision 1.21 1994/07/20 19:06:35 clm * updated TRUE, ERROR etc in cancel & ok_button functions * to DIALOG_ constants * * Revision 1.20 1994/06/16 21:55:48 clm * updated to new dialog routines - extra parameter to DialogTextCreate * * Revision 1.19 1994/06/16 16:56:35 clm * updated to new gr_ routines using GR_ for font names * * Revision 1.18 1994/06/08 18:47:59 clm * removed Xm library includes since they are in dialog * * Revision 1.17 1994/06/01 22:27:07 clm * rewrote init functions to use dialog oellib functions * also don't initialize popups until object called * * Revision 1.16 1994/05/20 23:31:43 clm * updated with HP, SGI changes * * Revision 1.15 1994/05/04 23:34:36 clm * ported to ANSI C * * Revision 1.14 1993/05/18 22:39:41 clm * added meaningful error messages for check_num and check_day * * Revision 1.13 1993/05/18 20:58:30 clm * added new message.c function * * Revision 1.12 1993/04/13 22:24:05 clm * display word "Level" on top of text * * Revision 1.11 1993/04/12 22:23:18 clm * fix locate if radius is 0 or text width is greater than diameter * so rectangle encompasses everything * * Revision 1.10 1992/12/22 16:00:38 clm * fixed lim and load so objects cannot be loaded or moved outside chart lines * * Revision 1.9 1992/12/10 21:45:40 clm * fixed new_index so chart is always object 0 * * Revision 1.8 1992/10/02 20:20:36 clm * housekeeping * * Revision 1.7 1992/09/16 14:55:44 clm * fixed load function so doesn't add object if error in load * * Revision 1.6 1992/09/14 14:23:36 clm * fixed error checking of font in load_level * * Revision 1.5 1992/09/01 16:56:25 clm * added color menu * * Revision 1.4 1992/08/27 16:35:33 clm * fixed help callback * * Revision 1.3 1992/08/13 18:09:47 clm * fixed error checking for load module * * Revision 1.1 1992/08/10 18:04:23 clm * Initial revision * * *********************************************************************** * * WARNINGS: * * EXTERNAL CALLABLE COMPONENTS (PUBLIC): * * GLOBALS: * * WAIVERS: * * NOTES: * * MANPAGE: * ***********************************************************************/ #ifndef lint static char rcsid[] = "$Id: level.c,v 1.23 1994/12/31 04:10:21 kevin OEL $"; #endif /************************************************************************* global functions: add_level(x, y, text, font, point, radius, pages, layer) - add object to data base ***************************************************************************/ /* local functions: dsp_level(i) - display level object edt_level(i, new) - change contents of level field rem_level(i) - remove level object lim_level(i) - limit range of motion of level object loc_level(i) - locate position of level object on screen mov_level(i) - move level object cpy_level(to, from) - copy level object msg_level(i) - display message on screen sav_level(i, file) - save level to file */ #include "xopps.h" static int font_values[] = { GR_COURIER, GR_COURIER_BOLD, GR_HELVETICA, GR_HELVETICA_BOLD, GR_TIMES, GR_TIMES_BOLD }; static int font_sizes[] = { 8, 10, 12, 14, 18, 24 }; /* local functions */ static void create_dialog(void); static int load_level(char *); /* load a level object */ static void level_ok_button(void); /* Callback for ok button */ static void cancel_button(void); /* Callback for cancel button */ static void change_page(Widget, XtPointer, XtPointer); static void change_drawlyr(Widget, XtPointer, XtPointer); static void change_font(Widget, XtPointer, XtPointer); static void change_point(Widget, XtPointer, XtPointer); static void change_color(Widget, XtPointer, XtPointer); static void dsp_level(int); static void edt_level(int, int); static void rem_level(int, int); static void lim_level(int, int *, int *, int *, int *, int); static void loc_level(int, int); static void mov_level(int, int, int, int); static void cpy_level(struct obj *, struct obj *); static void msg_level(int, int); static void sav_level(int, FILE *, int); static void verify_fun(Widget, XtPointer, XtPointer); static struct ops lvl_ops = { dsp_level, edt_level, rem_level, lim_level, loc_level, mov_level, cpy_level, msg_level, sav_level }; static DialogText *text, *radius; static DialogOption *font, *point; static DialogOption *page, *drawlyr; static DialogOption *colorw; static Widget level_dialog; /* dialog shell for popup */ static Widget parent_shell; static int new_point; /* new point id */ static int new_font; /* new font id */ static int new_page; /* new page id */ static int new_drawlyr; /* new layer id */ static int new_color; /* new color id */ /*********************************************************************** * * FUNCTION: * init_level_object() * * * INPUTS: * parent (Widget) * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * registers the level object and sets the parent */ void init_level_object(Widget parent) { register_io_obj('B', load_level); /* register object */ parent_shell = parent; } /*********************************************************************** * * FUNCTION: * create_dialog() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * initializes the widgets for the level object dialog */ static void create_dialog(void) { static char *fonts[] = { "Courier", "Courier Bold", "Helvetica", "Helvetica Bold", "Times", "Times Bold" }; static char *points[] = { "8", "10", "12", "14", "18", "24" }; static char *pages[] = { "All Pages", "Current Page" }; static char *drawlyrs[] = { "0", "1", "2", "3" }; level_dialog = DialogInit(parent_shell, "Level Object", "level", verify_fun, (XtPointer)DIALOG_CANCEL); text = DialogTextCreate("Text ", 2, 2); DialogAddRow(2); font = DialogOptionCreate("Font ", 6, 5, change_font, DIALOG_OPT_STR_ARY, fonts, font_values); point = DialogOptionCreate("Point ", 6, 10, change_point, DIALOG_OPT_STR_ARY, points, font_sizes); radius = DialogTextCreate("Radius of Circle ", 3, 3); page = DialogOptionCreate("Page ", 2, 1, change_page, DIALOG_OPT_STR_ARY, pages, NULL); drawlyr = DialogOptionCreate("Draw Layer ", 4, 0, change_drawlyr, DIALOG_OPT_STR_ARY, drawlyrs, NULL); colorw = DialogOptionCreate("Color ", ncolor, 0, change_color, DIALOG_OPT_STR_ARY, color_name, color_index); DialogStdButtons(verify_fun, (XtPointer)DIALOG_UPDATE, verify_fun, (XtPointer)DIALOG_CANCEL, (XtCallbackProc)ShowHelp, "level"); } /*********************************************************************** * * FUNCTION: * add_level() * * INPUTS: * x, y, font, point, radius, page, layer, color (int) * text (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * adds new level object */ int add_level(int x, int y, char *text, int font, int point, int radius, int page, int layer, int color) { int i; /* index */ i = new_index(FALSE); objary[i].z.lvlptr = (struct lvl *)XtMalloc(sizeof(struct lvl)); objary[i].z.lvlptr->x = x; objary[i].z.lvlptr->y = y; objary[i].z.lvlptr->text = XtNewString(text); objary[i].z.lvlptr->font = font; objary[i].z.lvlptr->point = point; objary[i].z.lvlptr->radius = radius; objary[i].z.lvlptr->page = page; objary[i].z.lvlptr->color = color; objary[i].type = OBJ_LVL; objary[i].opsptr = &lvl_ops; objary[i].layer = layer; return i; } /*********************************************************************** * * FUNCTION: * cpy_level() * * INPUTS: * to, from (obj *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * copies level object from to level object to */ static void cpy_level(struct obj *to, struct obj *from) { if (from->type == OBJ_NUL) return; to->z.lvlptr = (struct lvl *)XtMalloc(sizeof(struct lvl)); to->z.lvlptr->x = from->z.lvlptr->x; to->z.lvlptr->y = from->z.lvlptr->y; to->z.lvlptr->text = XtNewString(from->z.lvlptr->text); to->z.lvlptr->font = from->z.lvlptr->font; to->z.lvlptr->point = from->z.lvlptr->point; to->z.lvlptr->radius = from->z.lvlptr->radius; to->z.lvlptr->page = from->z.lvlptr->page; to->z.lvlptr->color = from->z.lvlptr->color; to->type = OBJ_PAG; to->layer = from->layer; to->opsptr = &lvl_ops; to->rlist = copyRectList(from->rlist); } /*********************************************************************** * * FUNCTION: * rem_level() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * removes level object i */ static void rem_level(int i, int dir) { struct obj *objptr; switch (i) { case BACK: objptr = &objbck; break; case TEMP: objptr = &objtmp; break; default: objptr = &(objary[i]); break; } freeRectList(objptr->rlist); XtFree((char *)objptr->z.lvlptr); rem_object(objptr); } /*********************************************************************** * * FUNCTION: * lim_level() * * INPUTS: * i (int) * x1, y1, x2, y2 (int *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * limits range of motion of level object */ static void lim_level(int i, int *x1, int *y1, int *x2, int *y2, int dir) { XRectangle *(*r)[]; r = getMoveRect(objary[i].rlist); *x1 = xlnary[0].z.lnptr->cord; *y1 = ylnary[0].z.lnptr->cord; *x2 = xlnary[nxln-1].z.lnptr->cord - (1 + (*r)[0]->width); *y2 = ylnary[nyln-1].z.lnptr->cord - (1 + (*r)[0]->height); } /*********************************************************************** * * FUNCTION: * loc_level() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * locates position of level object i */ static void loc_level(int i, int dir) { struct lvl *lvlptr; /* local pointer */ int width, height; /* width and height of font */ XRectangle r; /* rectangle */ char buf[40]; /* temp buffer */ lvlptr = objary[i].z.lvlptr; (void)sprintf(buf, "Level"); width = gr_strwidth(buf, lvlptr->font|lvlptr->point); height = gr_txheight(lvlptr->font|lvlptr->point); if ((lvlptr->radius == 0) || (lvlptr->radius * 2 < width)) { /* * need to calculate differently if radius is 0 * or if width of text is larger than the circle */ r.width = width + 4; if (lvlptr->radius != 0) { r.height = lvlptr->radius * 2 + 3; } else { r.height = height * 2 + 2; } r.y = lvlptr->y - r.height/2 - 1; r.x = lvlptr->x - r.width/2 - 1; } else { r.width = lvlptr->radius * 2 + 2; r.height = lvlptr->radius * 2 + 2; r.y = lvlptr->y - lvlptr->radius - 1; r.x = lvlptr->x - lvlptr->radius - 1; } setRectList(objary[i].rlist, 1, &r, RL_PRIMARY); } /*********************************************************************** * * FUNCTION: * mov_level() * * INPUTS: * i, x, y (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * moves level object i to (x,y) */ static void mov_level(int i, int x, int y, int dir) { objary[i].z.lvlptr->x += x; objary[i].z.lvlptr->y += y; } /*********************************************************************** * * FUNCTION: * dsp_level() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays level object i on screen */ static void dsp_level(int i) { struct lvl *lvlptr; /* local pointer */ int height; /* width and height of text */ enum tog mask; /* mask for print */ char buf[40]; /* temp buffer */ lvlptr = objary[i].z.lvlptr; gr_set_color(color_name[lvlptr->color], color_gscale[lvlptr->color]); height = gr_txheight(lvlptr->font|lvlptr->point); if (objary[i].layer == 0) { mask = TOG_OFF; } else { mask = TOG_ON; } if ((lvlptr->page == current_page) || (lvlptr->page == 0)) { (void)sprintf(buf, "Level"); gr_text(lvlptr->x,lvlptr->y, buf, 1, lvlptr->font| lvlptr->point, (int)mask); gr_text(lvlptr->x, lvlptr->y + height, lvlptr->text, 1, lvlptr->font| lvlptr->point, (int)mask); if (lvlptr->radius > 0) { gr_circle(lvlptr->x, lvlptr->y, lvlptr->radius); } } } /*********************************************************************** * * FUNCTION * msg_level() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays level message on screen */ static void msg_level(int i, int dir) { char buf[64]; int len; (void)sprintf(buf, "Level"); len = 62 - strlen(buf); strncat(buf, objary[i].z.lvlptr->text, (unsigned)len); Message(buf); } /*********************************************************************** * * FUNCTION: * sav_level() * * INPUTS: * i (int) * fp (FILE *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * saves level record i to fp */ static void sav_level(int i, FILE *fp, int dir) { struct lvl *lvlptr; char buf[256]; lvlptr = objary[i].z.lvlptr; buf[0] = 'B'; buf[1] = ' '; record_print(buf + 2, "ddqdddddd", lvlptr->x, lvlptr->y, lvlptr->text, lvlptr->font, lvlptr->point, lvlptr->radius, lvlptr->page, objary[i].layer, lvlptr->color); fputs(buf, fp); } /*********************************************************************** * * FUNCTION: * load_level() * * INPUTS: * buf (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * loads level object record */ static int load_level(char *buf) { int x, y, font, point, radius, page, layer, color; char text[64]; int i; if (record_scan(buf + 1, "ddqdddddd", &x, &y, text, &font, &point, &radius, &page, &layer, &color) == 9) { if ((x < xlnary[0].z.lnptr->cord) || (x > xlnary[nxln-1].z.lnptr->cord)) { Warning("Illegal Level x %d", x); } else if ((y < ylnary[0].z.lnptr->cord) || (y > ylnary[nyln-1].z.lnptr->cord)) { Warning("Illegal Level y %d", y); } else if ((font != GR_COURIER) && (font != GR_COURIER_BOLD) && (font != GR_HELVETICA) && (font != GR_HELVETICA_BOLD) && (font != GR_TIMES) && (font != GR_TIMES_BOLD)) { Warning("Illegal Level font %d", font); } else if ((point != 8) && (point != 10) && (point != 12) && (point != 14) && (point != 18) && (point != 24)) { Warning("Illegal Level point %d", point); } else if ((radius < 0) || (radius > 100)) { Warning("Illegal Level radius %d", radius); } else if ((page < 0) || (page > 7)) { Warning("Illegal Level radius %d", page); } else if ((layer < 0) || (layer > 3)) { Warning("Illegal Level layer %d", layer); } else if ((color < 0) || (color > ncolor)) { Warning("Illegal Level color %d", color); } else { i = add_level(x, y, text, font, point, radius, page, layer, color); (*(objary[i].opsptr->loc))(i, OBJECT); return 0; } return -1; } else { return -1; } } /*********************************************************************** * * FUNCTION: * edt_level() * * INPUTS: * i, new (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * edits level object i */ static void edt_level(int i, int new) { char buf[4]; if (level_dialog == NULL) { create_dialog(); } (*(objary[i].opsptr->cpy))(&objtmp, &objary[i]); new_page = objtmp.z.lvlptr->page; new_drawlyr = objtmp.layer; new_font = objtmp.z.lvlptr->font; new_point = objtmp.z.lvlptr->point; new_color = objtmp.z.lvlptr->color; if (new) { (*(objary[i].opsptr->rem))(i, OBJECT); i = -1; } sprintf(buf, "%d", objtmp.z.lvlptr->radius); DialogTextSet(radius, buf); DialogTextSet(text, objtmp.z.lvlptr->text); DialogOptionSet(font, (int)new_font); DialogOptionSet(point, (int)new_point); DialogOptionSet(page, (int)new_page); DialogOptionSet(drawlyr, (int)new_drawlyr); DialogOptionSet(colorw, (int)new_color); EditObject(i, level_dialog); } /*********************************************************************** * * FUNCTION: * level_ok_button() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * checks input after ok button is pressed */ static void level_ok_button(void) { int change = DIALOG_NO_CHANGE; char *buf; int val; if (new_page != objtmp.z.lvlptr->page) { change |= DIALOG_UPDATE; } objtmp.z.lvlptr->page = DialogOptionGet(page); if (new_font != objtmp.z.lvlptr->font) { change |= DIALOG_UPDATE; } objtmp.z.lvlptr->font = DialogOptionGet(font); if (new_point != objtmp.z.lvlptr->point) { change |= DIALOG_UPDATE; } objtmp.z.lvlptr->point = DialogOptionGet(point); if (new_color != objtmp.z.lvlptr->color) { change |= DIALOG_UPDATE; } objtmp.z.lvlptr->color = DialogOptionGet(colorw); buf = DialogTextGet(text); if (strcmp(buf, objtmp.z.lvlptr->text)) { change |= DIALOG_UPDATE; XtFree(objtmp.z.lvlptr->text); objtmp.z.lvlptr->text = buf; } else { XtFree(buf); } val = DialogTextGetInt(radius); if ((val < 0) || (val > 100)) { Warning("Improper Radius Value"); change |= DIALOG_ERROR; } else if (val != objtmp.z.lvlptr->radius) { change |= DIALOG_UPDATE; objtmp.z.lvlptr->radius = val; } if (new_drawlyr != objtmp.layer) { change |= DIALOG_UPDATE; } objtmp.layer = DialogOptionGet(drawlyr); if (objtmp.z.lvlptr->page != 0) { /* * if not printed on all pages, set page value to current page # */ objtmp.z.lvlptr->page = current_page; change = DIALOG_UPDATE; } object_change = change; DialogFlagSet(change); } /*********************************************************************** * * FUNCTION: * cancel_button() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * discards any edits and closes edit window */ static void cancel_button(void) { object_change = DIALOG_CANCEL; DialogFlagSet(DIALOG_CANCEL); } /*********************************************************************** * * FUNCTION: * change_font() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new font for level object */ static void change_font(Widget button, XtPointer option, XtPointer any_data) { new_font = (int)option; } /*********************************************************************** * * FUNCTION: * change_point() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new point for level object */ static void change_point(Widget button, XtPointer option, XtPointer any_data) { new_point = (int)option; } /*********************************************************************** * * FUNCTION: * change_page() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new page for level object */ static void change_page(Widget button, XtPointer option, XtPointer any_data) { new_page = (int)option; } /*********************************************************************** * * FUNCTION: * change_drawlyr() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new drawlyr for level object */ static void change_drawlyr(Widget button, XtPointer option, XtPointer any_data) { new_drawlyr = (int)option; } /*********************************************************************** * * FUNCTION: * change_color() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new color for level object */ static void change_color(Widget button, XtPointer option, XtPointer any_data) { new_color = (int)option; } /*********************************************************************** * * FUNCTION: * verify_fun() * * INPUTS: * w (Widget) * x, y (XtPointer) * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * validates that the popup dialog can be closed */ static void verify_fun(Widget w, XtPointer x, XtPointer y) { if ((int)x == DIALOG_CANCEL) { if (!ShellValidateClose(w)) return; cancel_button(); } else if ((int)x == DIALOG_UPDATE) { level_ok_button(); } }