From 9d2db7c955ada401dfacb97a07b346790f4c5bb3 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Tue, 27 Jan 1998 08:05:06 +0000 Subject: [PATCH] more combobox implementation filled in git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@448 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/register/Makefile | 3 +- src/register/actioncell.c | 64 +++++++++++++++ src/register/actioncell.h | 29 +++++++ src/register/basiccell.c | 5 +- src/register/basiccell.h | 8 ++ src/register/combocell.c | 168 +++++++++++++++++++++++++++++++------- src/register/combocell.h | 3 +- src/register/table.c | 24 ++++++ 8 files changed, 272 insertions(+), 32 deletions(-) create mode 100644 src/register/actioncell.c create mode 100644 src/register/actioncell.h diff --git a/src/register/Makefile b/src/register/Makefile index 31a592d46b..5ef33ce817 100644 --- a/src/register/Makefile +++ b/src/register/Makefile @@ -26,7 +26,8 @@ LIBXBAE = ../../lib/Xbae-4.6.2-linas/libXbae.a LIBCOMBO = ../lib/ComboBox-1.33/libComboBox.a LIBTRANS = ../Account.o ../Data.o ../FileIO.o ../Transaction.o ../date.o ###################################################################### -SRCS = basiccell.c cellblock.c combocell.c datecell.c pricecell.c \ +SRCS = actioncell.c basiccell.c cellblock.c combocell.c \ + datecell.c pricecell.c \ recncell.c register.c table.c textcell.c OBJS = ${SRCS:.c=.o} ###################################################################### diff --git a/src/register/actioncell.c b/src/register/actioncell.c new file mode 100644 index 0000000000..81a937c858 --- /dev/null +++ b/src/register/actioncell.c @@ -0,0 +1,64 @@ + +#include "actioncell.h" + +static void realizeAction (struct _BasicCell *bcell, void *w); +static void destroyAction (struct _BasicCell *bcell); + +/* =============================================== */ + +ActionCell *xaccMallocActionCell (void) +{ + ActionCell * cell; + cell = (ActionCell *) malloc (sizeof (ActionCell)); + xaccInitActionCell (cell); + return cell; +} + +void xaccInitActionCell (ActionCell *cell) +{ + xaccInitComboCell ( &(cell->cell)); + cell->chain_realize = cell->cell.cell.realize; + cell->cell.cell.realize = realizeAction; +} + +/* =============================================== */ + +static +void realizeAction (struct _BasicCell *bcell, void *w) +{ + ActionCell *cell = (ActionCell *) bcell; + + /* first, call the combobox realize */ + cell->cell.cell.realize = cell->chain_realize; + if (cell->chain_realize) { + (cell->chain_realize) (bcell, w); + } + + /* now, install our destroy */ + cell->chain_destroy = cell->cell.cell.destroy; + cell->cell.cell.destroy = destroyAction; + + /* finally, add menu items */ + xaccAddComboCellMenuItem ( &(cell->cell), "yo dude"); + xaccAddComboCellMenuItem ( &(cell->cell), "he haw"); +} + +/* =============================================== */ + +static +void destroyAction (struct _BasicCell *bcell) +{ + ActionCell *cell = (ActionCell *) bcell; + + /* first, call the combobox destroy */ + cell->cell.cell.destroy = cell->chain_destroy; + if (cell->chain_destroy) { + (cell->chain_destroy) (bcell); + } + + /* now, install our realize */ + cell->chain_realize = cell->cell.cell.realize; + cell->cell.cell.realize = realizeAction; +} + +/* =============== end of file =================== */ diff --git a/src/register/actioncell.h b/src/register/actioncell.h new file mode 100644 index 0000000000..0e1860c09f --- /dev/null +++ b/src/register/actioncell.h @@ -0,0 +1,29 @@ +/* + * FILE: + * actioncell.h + * + * FUNCTION: + * Implements a actionbox cell + * + * HISTORY: + * Created Jan 1998 Linas Vepstas + * Copyright (c) 1998 Linas Vepstas + */ + +#ifndef __XACC_ACTION_CELL_C__ +#define __XACC_ACTION_CELL_C__ + +#include "combocell.h" + +typedef struct _ActionCell { + ComboCell cell; + void (* chain_realize) (struct _BasicCell *, void *gui_handle); + void (* chain_destroy) (struct _BasicCell *); +} ActionCell; + +ActionCell * xaccMallocActionCell (void); +void xaccInitActionCell (ActionCell *); + +#endif /* __XACC_ACTION_CELL_C__ */ + +/* --------------- end of file ---------------------- */ diff --git a/src/register/basiccell.c b/src/register/basiccell.c index 3bdb2b9eb3..5646ed2a9d 100644 --- a/src/register/basiccell.c +++ b/src/register/basiccell.c @@ -22,14 +22,15 @@ void xaccInitBasicCell (BasicCell *cell) cell->modify_verify = NULL; cell->leave_cell = NULL; cell->realize = NULL; + cell->move = NULL; + cell->destroy = NULL; + cell->gui_private = NULL; } void xaccSetBasicCellValue (BasicCell *cell, char *val) { - if (cell->value) free (cell->value); cell->value = strdup (val); - } /* ------------------ end of file ---------------------- */ diff --git a/src/register/basiccell.h b/src/register/basiccell.h index dc2b1d6182..e49c5b4b6a 100644 --- a/src/register/basiccell.h +++ b/src/register/basiccell.h @@ -80,6 +80,14 @@ typedef struct _BasicCell { /* private, GUI-specific initializer */ void (* realize) (struct _BasicCell *, void *gui_handle); + /* private, GUI-specific callback to move gui element */ + void (* move) (struct _BasicCell *, int phys_row, int phys_col); + + /* private, GUI-specific callback to detroy gui element */ + void (* destroy) (struct _BasicCell *); + + /* general hook for gui-private data */ + void * gui_private; } BasicCell; diff --git a/src/register/combocell.c b/src/register/combocell.c index b543fa3a22..da9ba21765 100644 --- a/src/register/combocell.c +++ b/src/register/combocell.c @@ -21,6 +21,9 @@ typedef struct _PopBox { static void selectCB (Widget w, XtPointer cd, XtPointer cb ); static void dropDownCB (Widget w, XtPointer cd, XtPointer cb ); +static void realizeCombo (struct _BasicCell *bcell, void *w); +static void moveCombo (struct _BasicCell *bcell, int phys_row, int phys_col); +static void destroyCombo (struct _BasicCell *bcell); /* =============================================== */ @@ -34,34 +37,56 @@ ComboCell *xaccMallocComboCell (void) void xaccInitComboCell (ComboCell *cell) { - PopBox *box; - xaccInitBasicCell ( &(cell->cell)); - - cell->gui = (struct _PopBox *) box; + cell->cell.realize = realizeCombo; } /* =============================================== */ -void RealizeCombo (struct _BasicCell *bcell, void *w) +void +xaccAddComboCellMenuItem (ComboCell *cell, char * menustr) +{ + PopBox *box; + XmString str; + box = (PopBox *) (cell->cell.gui_private); + + if (!box) return; + + str = XmStringCreateLtoR (menustr, XmSTRING_DEFAULT_CHARSET); + XmComboBoxAddItem (box->combobox, str, 0); + XmStringFree (str); +} + +/* =============================================== */ + +static +void realizeCombo (struct _BasicCell *bcell, void *w) { ComboCell *cell; PopBox *box; Widget parent; Widget combobox; - - int width = 10; /* hack alert --- */ - int drop_width = 10; + int width, drop_width; parent = (Widget) w; cell = (ComboCell *) bcell; + /* initialize gui-specific, private data */ box = (PopBox *) malloc (sizeof (PopBox)); box->parent = parent; box->currow = -1; box->curcol = -1; - cell->gui = (struct _PopBox *) box; + cell->cell.gui_private = (void *) box; + + /* to mark cell as realized, remove the realize method */ + cell->cell.realize = NULL; + cell->cell.move = moveCombo; + cell->cell.destroy = destroyCombo; + + /* heuristic to increase the size of the drop-down box */ + width = cell->cell.width; + drop_width = (int) (1.2 * ((float) width)); /* create the pop GUI */ combobox = XtVaCreateManagedWidget @@ -87,45 +112,132 @@ void RealizeCombo (struct _BasicCell *bcell, void *w) box->combobox = combobox; /* add callbacks to detect a selection */ - XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)box); - XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)box); + XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)cell); + XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)cell); XtAddCallback (combobox, XmNdropDownCallback, dropDownCB, (XtPointer)box); } /* =============================================== */ +static +void moveCombo (struct _BasicCell *bcell, int phys_row, int phys_col) +{ + ComboCell *cell; + PopBox *box; + String choice; + XmString choosen; + + cell = (ComboCell *) bcell; + box = (PopBox *) (cell->cell.gui_private); + + /* if the drop-down menu is showing, hide it now */ + XmComboBoxHideList (box->combobox); + + /* if there is an old widget, remove it */ + if ((0 <= box->currow) && (0 <= box->curcol)) { + XbaeMatrixSetCellWidget (box->parent, box->currow, box->curcol, NULL); + } + box->currow = phys_row; + box->curcol = phys_col; + + /* if the new position is valid, go to it, + * otherwise, unmanage the widget */ + if ((0 <= box->currow) && (0 <= box->curcol)) { + + /* Get the current cell contents, and set the + * combobox menu selction to match the contents */ + choice = cell->cell.value; + + /* do a menu selection only if the cell ain't empty. */ + if (choice) { + if (0x0 != choice[0]) { + /* convert String to XmString ... arghhh */ + choosen = XmCvtCTToXmString (choice); + XmComboBoxSelectItem (box->combobox, choosen, False); + XmStringFree (choosen); + } else { + XmComboBoxClearItemSelection (box->combobox); + } + } else { + XmComboBoxClearItemSelection (box->combobox); + } + + /* set the cell widget */ + XbaeMatrixSetCellWidget (box->parent, phys_row, phys_col, box->combobox); + + if (!XtIsManaged (box->combobox)) { + XtManageChild (box->combobox); + } + + /* drop down the menu so that its ready to go. */ + XmComboBoxShowList (box->combobox); + } else { + XtUnmanageChild (box->combobox); + } +} + +/* =============================================== */ + +static +void destroyCombo (struct _BasicCell *bcell) +{ + ComboCell *cell; + PopBox *box; + + cell = (ComboCell *) bcell; + box = (PopBox *) (cell->cell.gui_private); + + moveCombo (bcell, -1, -1); + + XtDestroyWidget (box->combobox); + free (box); + + /* allow the widget to be created again */ + cell->cell.gui_private = NULL; + cell->cell.realize = realizeCombo; + cell->cell.move = NULL; + cell->cell.destroy = NULL; +} + +/* =============================================== */ + static void selectCB (Widget w, XtPointer cd, XtPointer cb ) { - PopBox *ab = (PopBox *) cd; - XmComboBoxSelectionCallbackStruct *selection = + ComboCell *cell; + PopBox *box; + char * choice = 0x0; + + XmComboBoxSelectionCallbackStruct *selection = (XmComboBoxSelectionCallbackStruct *) cb; - char * choice = 0x0; - /* check the reason, because the unslect callback - * doesn't even have a value field! */ - if ( (XmCR_SINGLE_SELECT == selection->reason) || - (XmCR_SINGLE_SELECT == selection->reason) ) { - choice = XmCvtXmStringToCT (selection->value); - } - if (!choice) choice = ""; + cell = (ComboCell *) cd; + box = (PopBox *) (cell->cell.gui_private); -printf ("yo combo select %s \n", choice); + /* check the reason, because the unslect callback + * doesn't even have a value field! */ + if ( (XmCR_SINGLE_SELECT == selection->reason) || + (XmCR_SINGLE_SELECT == selection->reason) ) { + choice = XmCvtXmStringToCT (selection->value); + } + if (!choice) choice = XtNewString (""); - /* XbaeMatrixSetCell (ab->reg, ab->currow, ab->curcol, choice); */ + XbaeMatrixSetCell (box->parent, box->currow, box->curcol, choice); + xaccSetBasicCellValue (&(cell->cell), choice); + XtFree (choice); - /* a diffeent way of getting the user's selection ... */ - /* text = XmComboBoxGetString (ab->combobox); */ + /* a diffeent way of getting the user's selection ... */ + /* text = XmComboBoxGetString (ab->combobox); */ } /* =============================================== */ -/********************************************************************\ +/*********************************************************\ * fix traversal by going back to the register window * when the pull-down menu goes away. We do NOT want to * go to the default next tab group, which is probably - * some button not in theregister window. -\********************************************************************/ + * some button not in the register window. +\*********************************************************/ static void dropDownCB (Widget w, XtPointer cd, XtPointer cb ) diff --git a/src/register/combocell.h b/src/register/combocell.h index a57cd1f72a..cde13f78f4 100644 --- a/src/register/combocell.h +++ b/src/register/combocell.h @@ -17,12 +17,13 @@ typedef struct _ComboCell { BasicCell cell; - struct _PopBox *gui; /* gui-private data */ } ComboCell; ComboCell * xaccMallocComboCell (void); void xaccInitComboCell (ComboCell *); +void xaccAddComboCellMenuItem (ComboCell *, char * menustr); + #endif /* __XACC_COMBO_CELL_C__ */ /* --------------- end of file ---------------------- */ diff --git a/src/register/table.c b/src/register/table.c index db1c0d4496..af66f2724e 100644 --- a/src/register/table.c +++ b/src/register/table.c @@ -119,11 +119,35 @@ xaccSetCursor (Table *table, CellBlock *curs) void xaccMoveCursor (Table *table, int virt_row, int virt_col) { + int i,j; + int iphys,jphys; + BasicCell *cell; + if ((0 > virt_row) || (0 > virt_col)) return; if (virt_row >= table->num_rows) return; if (virt_col >= table->num_cols) return; table->current_cursor_row = virt_row; table->current_cursor_col = virt_col; + + /* update the cell values to reflect the new position */ + /* also, move the cell GUI, if needed */ + for (i=0; itile_height; i++) { + iphys = i + table->current_cursor_row * table->tile_height; + iphys += table->num_header_rows; + for (j=0; jtile_width; j++) { + + cell = table->cursor->cells[i][j]; + if (cell) { + jphys = j + table->current_cursor_col * table->tile_width; + xaccSetBasicCellValue (cell, table->entries[iphys][jphys]); + + /* be sure to allow the GUI to move too */ + if (cell->move) { + (cell->move) (cell, iphys, jphys); + } + } + } + } } /* ==================================================== */