mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
126136538b
commit
d020898f4b
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user