fix up more of the combobox behaviours,

although its still acting flaky.  Also, traversal
is still broken.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@451 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-01-27 22:33:23 +00:00
parent 126136538b
commit d020898f4b
6 changed files with 176 additions and 31 deletions

View File

@ -1,7 +1,7 @@
#include "actioncell.h"
static void realizeAction (struct _BasicCell *bcell, void *w);
static void realizeAction (struct _BasicCell *bcell, void *w, int width);
static void destroyAction (struct _BasicCell *bcell);
/* =============================================== */
@ -24,14 +24,14 @@ void xaccInitActionCell (ActionCell *cell)
/* =============================================== */
static
void realizeAction (struct _BasicCell *bcell, void *w)
void realizeAction (struct _BasicCell *bcell, void *w, int width)
{
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);
(cell->chain_realize) (bcell, w, width);
}
/* now, install our destroy */

View File

@ -17,7 +17,9 @@
typedef struct _ActionCell {
ComboCell cell;
void (* chain_realize) (struct _BasicCell *, void *gui_handle);
void (* chain_realize) (struct _BasicCell *,
void *gui_handle,
int pixel_width);
void (* chain_destroy) (struct _BasicCell *);
} ActionCell;

View File

@ -55,6 +55,12 @@
* The realize callback will be called when GUI-specific
* initalization needs to be done. For Xt/Motif, the second
* argument will be cast to the parent widget.
*
* HACK ALERT NOTES:
* The realize method takes a width argument only as a hack
* to work around the fact that the combo-box requires a width
* in pixels, rather than in characters. It would be nice if
* ComboBox supported the XmNunits resource, but it doesn't.
*/
#ifndef __XACC_BASIC_CELL_H__
@ -78,7 +84,9 @@ typedef struct _BasicCell {
const char * current);
/* private, GUI-specific initializer */
void (* realize) (struct _BasicCell *, void *gui_handle);
void (* realize) (struct _BasicCell *,
void *gui_handle,
int pixel_width);
/* private, GUI-specific callback to move gui element */
void (* move) (struct _BasicCell *, int phys_row, int phys_col);

View File

@ -21,9 +21,12 @@ 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 realizeCombo (struct _BasicCell *bcell, void *w, int width);
static void moveCombo (struct _BasicCell *bcell, int phys_row, int phys_col);
static void destroyCombo (struct _BasicCell *bcell);
static const char * enterCombo (struct _BasicCell *bcell, const char *value);
static const char * leaveCombo (struct _BasicCell *bcell, const char *value);
/* =============================================== */
@ -60,7 +63,7 @@ xaccAddComboCellMenuItem (ComboCell *cell, char * menustr)
/* =============================================== */
static
void realizeCombo (struct _BasicCell *bcell, void *w)
void realizeCombo (struct _BasicCell *bcell, void *w, int pixel_width)
{
ComboCell *cell;
PopBox *box;
@ -82,11 +85,18 @@ void realizeCombo (struct _BasicCell *bcell, void *w)
/* to mark cell as realized, remove the realize method */
cell->cell.realize = NULL;
cell->cell.move = moveCombo;
cell->cell.enter_cell = enterCombo;
cell->cell.leave_cell = leaveCombo;
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));
/* the combobox wants width in pixels, not in chars.
* It would be nice if ComboBox supported the XmNunits
* resource, but it doesn't. Also, while we are at it,
* increase the size of the drop-down box as well.
*/
width = pixel_width;
drop_width = (int) (1.3 * ((float) width));
if (15 > drop_width) drop_width = 15;
/* create the pop GUI */
combobox = XtVaCreateManagedWidget
@ -101,20 +111,17 @@ void realizeCombo (struct _BasicCell *bcell, void *w)
XmNselectionPolicy, XmSINGLE_SELECT,
XmNvalue, "",
XmNwidth, width,
XmNdropDownWidth, drop_width,
NULL);
box->combobox = combobox;
if (10 < drop_width) {
XtVaSetValues (combobox, XmNdropDownWidth, drop_width, NULL);
}
box->combobox = combobox;
/* add callbacks to detect a selection */
XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)cell);
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)cell);
XtAddCallback (combobox, XmNdropDownCallback, dropDownCB, (XtPointer)box);
moveCombo (bcell, -1, -1);
}
/* =============================================== */
@ -124,8 +131,6 @@ 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);
@ -133,6 +138,12 @@ void moveCombo (struct _BasicCell *bcell, int phys_row, int phys_col)
/* if the drop-down menu is showing, hide it now */
XmComboBoxHideList (box->combobox);
printf ("move from %d %d to %d %d \n",
box->currow,
box->curcol,
phys_row,
phys_col);
/* if there is an old widget, remove it */
if ((0 <= box->currow) && (0 <= box->curcol)) {
XbaeMatrixSetCellWidget (box->parent, box->currow, box->curcol, NULL);
@ -140,12 +151,34 @@ void moveCombo (struct _BasicCell *bcell, int phys_row, int phys_col)
box->currow = phys_row;
box->curcol = phys_col;
XtUnmanageChild (box->combobox);
}
/* =============================================== */
static
const char * enterCombo (struct _BasicCell *bcell, const char *value)
{
int phys_row, phys_col;
String choice;
XmString choosen;
ComboCell *cell;
PopBox *box;
cell = (ComboCell *) bcell;
box = (PopBox *) (cell->cell.gui_private);
phys_row = box->currow;
phys_col = box->curcol;
/* if the new position is valid, go to it,
* otherwise, unmanage the widget */
if ((0 <= box->currow) && (0 <= box->curcol)) {
if ((0 <= phys_row) && (0 <= phys_col)) {
/* Get the current cell contents, and set the
* combobox menu selction to match the contents */
* combobox menu selection to match the contents.
* We could use the value passed in, but things should
* be consitent, so we don't need it. */
choice = cell->cell.value;
/* do a menu selection only if the cell ain't empty. */
@ -170,10 +203,37 @@ void moveCombo (struct _BasicCell *bcell, int phys_row, int phys_col)
}
/* drop down the menu so that its ready to go. */
XmComboBoxShowList (box->combobox);
XmComboBoxShowList (box->combobox);
printf ("show at %d %d \n", phys_row, phys_col);
} else {
XtUnmanageChild (box->combobox);
}
return NULL;
}
/* =============================================== */
static
const char * leaveCombo (struct _BasicCell *bcell, const char *value)
{
ComboCell *cell;
PopBox *box;
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);
}
XtUnmanageChild (box->combobox);
return NULL;
}
/* =============================================== */
@ -196,6 +256,8 @@ void destroyCombo (struct _BasicCell *bcell)
cell->cell.gui_private = NULL;
cell->cell.realize = realizeCombo;
cell->cell.move = NULL;
cell->cell.enter_cell = NULL;
cell->cell.leave_cell = NULL;
cell->cell.destroy = NULL;
}
@ -222,6 +284,7 @@ static void selectCB (Widget w, XtPointer cd, XtPointer cb )
}
if (!choice) choice = XtNewString ("");
printf ("select %s \n", choice);
XbaeMatrixSetCell (box->parent, box->currow, box->curcol, choice);
xaccSetBasicCellValue (&(cell->cell), choice);
XtFree (choice);

View File

@ -140,8 +140,38 @@ void xaccMoveCursor (Table *table, int virt_row, int virt_col)
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 */
/* ==================================================== */
void xaccMoveCursorGUI (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; i<table->tile_height; i++) {
iphys = i + table->current_cursor_row * table->tile_height;
iphys += table->num_header_rows;
for (j=0; j<table->tile_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]);
/* if a cell has a GUI, move that too */
if (cell->move) {
(cell->move) (cell, iphys, jphys);
}
@ -175,6 +205,36 @@ void xaccCommitEdits (Table *table)
}
}
/* ==================================================== */
/* verifyCursorPosition checks the location of the cursor
* with respect to a row/column position, and repositions
* the cursor if necessary.
*/
static void
verifyCursorPosition (Table *table, int phys_row, int phys_col)
{
int virt_row, virt_col;
/* compute the virtual position */
virt_row = phys_row;
virt_row -= table->num_header_rows;
virt_row /= table->tile_height;
virt_col = phys_col;
virt_col /= table->tile_width;
if ((virt_row != table->current_cursor_row) ||
(virt_col != table->current_cursor_col)) {
/* before leaving, the current virtual position,
* commit any aedits that have been accumulated
* in the cursor */
xaccCommitEdits (table);
xaccMoveCursorGUI (table, virt_row, virt_col);
}
}
/* ==================================================== */
/* hack alert -- will core dump if numrows has changed, etc. */
@ -303,6 +363,7 @@ cellCB (Widget mw, XtPointer cd, XtPointer cb)
* this cell. Dispatch for processing. */
switch (cbs->reason) {
case XbaeEnterCellReason: {
verifyCursorPosition (table, row, col);
enterCB (mw, cd, cb);
break;
}
@ -315,6 +376,7 @@ cellCB (Widget mw, XtPointer cd, XtPointer cb)
break;
}
case XbaeTraverseCellReason: {
verifyCursorPosition (table, row, col);
traverseCB (mw, cd, cb);
break;
}
@ -358,14 +420,16 @@ enterCB (Widget mw, XtPointer cd, XtPointer cb)
/* OK, if there is a callback for this cell, call it */
enter = arr->cells[rel_row][rel_col]->enter_cell;
if (enter) {
const char *val, *retval;
const char *val;
char *retval;
val = table->entries[row][col];
retval = enter (arr->cells[rel_row][rel_col], val);
retval = (char *) enter (arr->cells[rel_row][rel_col], val);
if (NULL == retval) retval = (char *) val;
if (val != retval) {
if (table->entries[row][col]) free (table->entries[row][col]);
table->entries[row][col] = (char *) retval;
XbaeMatrixSetCell (mw, row, col, (char *) retval);
table->entries[row][col] = retval;
XbaeMatrixSetCell (mw, row, col, retval);
XbaeMatrixRefreshCell (mw, row, col);
/* don't map a text widget */
@ -505,8 +569,8 @@ leaveCB (Widget mw, XtPointer cd, XtPointer cb)
retval = leave (arr->cells[rel_row][rel_col], val);
newval = (char *) retval;
if (val == retval) newval = strdup (retval);
if (NULL == retval) newval = strdup ("");
if (val == retval) newval = strdup (val);
if (NULL == retval) newval = strdup (val);
/* save whatever was returned */
if (table->entries[row][col]) free (table->entries[row][col]);
@ -648,10 +712,15 @@ xaccCreateTable (Table *table, Widget parent, char * name)
BasicCell *cell;
cell = curs->cells[i][j];
if (cell) {
void (*xt_realize) (struct _BasicCell *, void *gui);
void (*xt_realize) (struct _BasicCell *,
void *gui,
int pixel_width);
xt_realize = cell->realize;
if (xt_realize) {
xt_realize (((struct _BasicCell *) cell), ((void *) reg));
int pixel_width;
pixel_width = XbaeMatrixGetColumnPixelWidth (reg, j);
xt_realize (((struct _BasicCell *) cell),
((void *) reg), pixel_width);
}
}
}

View File

@ -67,9 +67,12 @@ void xaccRefreshTable (Table *);
/* Make the indicated cell block be the cursor for this table */
void xaccSetCursor (Table *, CellBlock *);
/* move the cursor to the indicated location. */
/* move the cursor (but not the GUI) to the indicated location. */
void xaccMoveCursor (Table *, int virt_row, int virt_col);
/* move the cursor GUI to the indicated location. */
void xaccMoveCursorGUI (Table *, int virt_row, int virt_col);
/* copy text in the cursor cells to the table */
void xaccCommitEdits (Table *);