/******************************************************************** This file is part of the abs 0.907 distribution. abs is a spreadsheet with graphical user interface. Copyright (C) 1998-2001 André Bertin (Andre.Bertin@ping.be) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version if in the same spirit as version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Concact: abs@pi.be http://home.pi.be/bertin/abs.shtml *********************************************************************/ #include "entrypop.h" #include "param.h" #include "list.xpm" #include "rollup.xpm" #include "rolldown.xpm" #include "memory.h" #include "popnindex.h" #include "button.h" static XtActionsRec entrypop_actionsTable[] = { {"entrypopEnter", cb_entrypopEnter}, {"entrypopEdit", cb_entrypopEdit}, }; static char entrypop_Translations[] = "\ Return: entrypopEnter()\n\ KP_Enter: entrypopEnter()\n\ "; static Entry_Pop **record; static int nrecord = 0; int entrypop_setrange (Entry_Pop * pop, double val, double step, double vmin, double vmax) { char buf[64]; pop->val = val; pop->step = step; pop->vmin = vmin; pop->vmax = vmax; sprintf (buf, "%g", val); SetEntryString (pop->entry, buf); EntrySetInsertionPosition (pop->entry, 0); return 0; } double entrypop_getvalue (Entry_Pop * ep_obj) { char *name; if (ep_obj->type == roll) { XtVaGetValues (ep_obj->entry, XtNstring, &name, NULL); sscanf (name, "%lf", &(ep_obj->val)); if (ep_obj->val > ep_obj->vmax) ep_obj->val = ep_obj->vmax; if (ep_obj->val < ep_obj->vmin) ep_obj->val = ep_obj->vmin; return ep_obj->val; } return 0.0; } char * entrypop_gettext (Entry_Pop * ep_obj) { char *name; if (ep_obj != NULL) { XtVaGetValues (ep_obj->entry, XtNstring, &name, NULL); return name; } return NULL; } int entrypop_which (Entry_Pop * ep_obj) { char *name; int i; if (ep_obj != NULL) if (ep_obj->type == roll) { XtVaGetValues (ep_obj->entry, XtNstring, &name, NULL); for (i = 0; i < ep_obj->nitem; i++) if (strcmp (XtName (ep_obj->items[i]), name)) return i; } return 0; } void cb_entrypopEnter (w, event, params, num_params) Widget w; XEvent *event; String *params; int *num_params; { int i = 0; char *val; Widget item; EntrySetEditable (w, False); while (i < nrecord) { if (record[i]->entry == w) { XtVaGetValues (w, XtNstring, &val, NULL); item = entrypop_add_item (record[i], val); if (record[i]->callback != NULL) (*(record[i]->callback)) (item, XtName (item), NULL); return; } i++; } return; } void cb_entrypopEnterWin (Widget w, XtPointer pointer, XEvent * event, Boolean * ctd) { Entry_Pop *ep_obj = (Entry_Pop *) pointer; if (ep_obj->Editable) EntrySetEditable (w, True); } void cb_entrypopLeaveWin (Widget w, XtPointer pointer, XEvent * event, Boolean * ctd) { EntrySetEditable (w, False); } void cb_entrypopEdit (w, event, params, num_params) Widget w; XEvent *event; String *params; int *num_params; { } int entrypop_callback (pop, cbfunc) Entry_Pop *pop; void (*cbfunc) (); { pop->callback = cbfunc; return 0; } void nextentry (widget, pointer, junk) Widget widget; XtPointer pointer; XtPointer junk; { int i = 0; char buf[64]; Entry_Pop *ep_obj = (Entry_Pop *) pointer; entrypop_getvalue (ep_obj); ep_obj->val -= ep_obj->step; if (ep_obj->val < ep_obj->vmin) ep_obj->val = ep_obj->vmin; sprintf (buf, "%g", ep_obj->val); SetEntryString (ep_obj->entry, buf); EntrySetInsertionPosition (ep_obj->entry, 0); if (ep_obj->callback != NULL) (*(ep_obj->callback)) (ep_obj->items[i], XtName (ep_obj->items[i]), NULL ); } void previousentry (widget, pointer, junk) Widget widget; XtPointer pointer; XtPointer junk; { int i = 0; char buf[64]; Entry_Pop *ep_obj = (Entry_Pop *) pointer; entrypop_getvalue (ep_obj); ep_obj->val += ep_obj->step; if (ep_obj->val > ep_obj->vmax) ep_obj->val = ep_obj->vmax; sprintf (buf, "%g", ep_obj->val); SetEntryString (ep_obj->entry, buf); EntrySetInsertionPosition (ep_obj->entry, 0); if (ep_obj->callback != NULL) (*(ep_obj->callback)) (ep_obj->items[i], XtName (ep_obj->items[i]), NULL ); } void changeentry (widget, pointer, junk) Widget widget; XtPointer pointer; XtPointer junk; { int i = 0; Entry_Pop *ep_obj = (Entry_Pop *) pointer; while (widget != ep_obj->items[i] && i < ep_obj->nitem) i++; if (i == ep_obj->nitem) return; SetEntryString (ep_obj->entry, XtName (ep_obj->items[i])); EntrySetInsertionPosition (widget, 0); if (ep_obj->callback != NULL) (*(ep_obj->callback)) (ep_obj->items[i], XtName (ep_obj->items[i]), NULL); } int entrypop_set_val (ep_obj, name) Entry_Pop *ep_obj; char *name; { SetEntryString (ep_obj->entry, name); EntrySetInsertionPosition (ep_obj->entry, 0); return 0; } int entrypop_init_val (ep_obj, name) Entry_Pop *ep_obj; char *name; { SetEntryString (ep_obj->entry, name); return 0; } int entrypop_add_items (ep_obj, name) Entry_Pop *ep_obj; char **name; { int i = 0; if (ep_obj == NULL || name == NULL) return -1; while (name[i] != NULL) { entrypop_add_item (ep_obj, name[i]); i++; } return 0; } Widget entrypop_add_item (ep_obj, name) Entry_Pop *ep_obj; char *name; { Widget item = NULL; int pos = -1; int i; if (ep_obj->type == roll) { sscanf (name, "%lf", &(ep_obj->val)); if (ep_obj->val > ep_obj->vmax) ep_obj->val = ep_obj->vmax; if (ep_obj->val < ep_obj->vmin) ep_obj->val = ep_obj->vmin; return item; } if (ep_obj->type != popdown) return item; for (i = 0; i < ep_obj->nitem; i++) { int cmp = strcmp (XtName (ep_obj->items[i]), name); if (cmp == 0) return ep_obj->items[i]; if (cmp > 0 && pos < 0) pos = i; } item = XtCreateManagedWidget (name, smeBSBObjectClass, ep_obj->popuplist, NULL, (Cardinal) 0); XtAddCallback (item, XtNcallback, changeentry, (caddr_t) ep_obj); ep_obj->nitem++; ep_obj->items = (Widget *) realloc (ep_obj->items, sizeof (Widget) * ep_obj->nitem); if (pos > 0) { for (i = ep_obj->nitem - 1; i > pos; i--) ep_obj->items[i] = ep_obj->items[i - 1]; ep_obj->items[pos] = item; } else ep_obj->items[ep_obj->nitem - 1] = item; return item; } int entrypop_remove_item (Entry_Pop * ep_obj, char *name) { int j; int i = 0; if (ep_obj->type != popdown) return 0; while (i < ep_obj->nitem && strcmp (XtName (ep_obj->items[i]), name)) i++; if (i == ep_obj->nitem) return 0; XtUnmanageChild (ep_obj->items[i]); XtDestroyWidget (ep_obj->items[i]); ep_obj->nitem--; for (j = i; j < ep_obj->nitem; j++) ep_obj->items[j] = ep_obj->items[j + 1]; return 0; } Entry_Pop * newentrypop (Widget parent, char *name, poptype type, int textw, int texth) { Entry_Pop *ep_obj; XtTranslations trans_table; Arg args[2]; ep_obj = (Entry_Pop *) absmalloc (sizeof (Entry_Pop), "newentrypop:ep_obj "); record = (Entry_Pop **) absmalloc (sizeof (Entry_Pop *) * (nrecord + 1), "newentrypop:record "); record[nrecord] = ep_obj;; nrecord++; ep_obj->Editable = 1; ep_obj->parent = parent; ep_obj->type = type; w_n = 0; w_dim (textw + 20, texth); w_bord (0); w_inbord (0); w_noresize (); ep_obj->baseform = XtCreateManagedWidget ("entrypopbase", formWidgetClass, ep_obj->parent, w_args, w_n); ep_obj->entry = CreateEntry (ep_obj->baseform, "entry", 0, 15, textw, texth, "test"); w_n = 0; w_rel (NULL, 0, 0); w_bONw (); w_set (ep_obj->entry); EntrySetEditable (ep_obj->entry, False); if (type == popdown) { ep_obj->arrowbtndown = (Widget) make_menu_button_pixmap (ep_obj->baseform, "list", list_xpm, NULL, NULL); w_n = 0; w_relv (NULL, texth - 15); w_bONw (); w_relh (ep_obj->entry, 0); w_set (ep_obj->arrowbtndown); XtSetArg (args[0], XtNmenuName, name); XtSetValues (ep_obj->arrowbtndown, args, (Cardinal) 1); ep_obj->popuplist = XtCreatePopupShell (name, simpleMenuWidgetClass, ep_obj->arrowbtndown, NULL, 0); w_n = 0; w_bONw (); w_set (ep_obj->popuplist); } if (type == roll) { ep_obj->arrowbtnup = (Widget) make_repeater_pixmap (ep_obj->baseform, "rollup", rollup_xpm, previousentry, (caddr_t) ep_obj); w_n = 0; w_relv (NULL, 0); w_bONw (); w_relh (ep_obj->entry, 0); w_set (ep_obj->arrowbtnup); ep_obj->arrowbtndown = (Widget) make_repeater_pixmap (ep_obj->baseform, "rolldown", rolldown_xpm, nextentry, (caddr_t) ep_obj); w_n = 0; w_relv (ep_obj->arrowbtnup, 0); w_bONw (); w_relh (ep_obj->entry, 0); w_set (ep_obj->arrowbtndown); } ep_obj->nitem = 0; ep_obj->items = NULL; ep_obj->callback = NULL; XtAppAddActions (XtWidgetToApplicationContext (ep_obj->entry) ,entrypop_actionsTable, XtNumber (entrypop_actionsTable)); trans_table = XtParseTranslationTable (entrypop_Translations); XtOverrideTranslations (ep_obj->entry, trans_table); XtAddEventHandler (ep_obj->entry, EnterWindowMask, True, cb_entrypopEnterWin, (caddr_t) ep_obj); XtAddEventHandler (ep_obj->entry, LeaveWindowMask, True, cb_entrypopLeaveWin, (caddr_t) ep_obj); return ep_obj; }