mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
first cut at a combobox implementation
A lot of code ripped off from earlier PopBox implementation git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@447 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
48efe19639
commit
76674673f2
@ -5,7 +5,7 @@ RANLIB = ranlib
|
||||
INCLPATH = -I/usr/include \
|
||||
-I/usr/X11R6/include/. \
|
||||
-I./../../include \
|
||||
-I./../lib/ComboBox-1.33 \
|
||||
-I./../../lib/ComboBox-1.33 \
|
||||
-I./../lib/XmHTML-1.1.0/src \
|
||||
-I./../../lib/Xbae-4.6.2-linas
|
||||
|
||||
@ -26,7 +26,7 @@ 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 datecell.c pricecell.c \
|
||||
SRCS = basiccell.c cellblock.c combocell.c datecell.c pricecell.c \
|
||||
recncell.c register.c table.c textcell.c
|
||||
OBJS = ${SRCS:.c=.o}
|
||||
######################################################################
|
||||
|
@ -21,7 +21,7 @@ void xaccInitBasicCell (BasicCell *cell)
|
||||
cell->enter_cell = NULL;
|
||||
cell->modify_verify = NULL;
|
||||
cell->leave_cell = NULL;
|
||||
cell->block = NULL;
|
||||
cell->realize = NULL;
|
||||
}
|
||||
|
||||
void xaccSetBasicCellValue (BasicCell *cell, char *val)
|
||||
|
@ -1,16 +1,20 @@
|
||||
/*
|
||||
* FILE:
|
||||
* basiccell.h
|
||||
*/
|
||||
|
||||
#ifndef __XACC_BASIC_CELL_H__
|
||||
#define __XACC_BASIC_CELL_H__
|
||||
|
||||
/*
|
||||
*
|
||||
* FUNCTION:
|
||||
* The BasicCell struct provides an abstract base class
|
||||
* defining the handling of the editing of a cell of a table.
|
||||
* Classes that provide the actual handling for different
|
||||
* cell types should inherit from this class.
|
||||
*
|
||||
* MEMBERS:
|
||||
* The input_output member is zero if the cell is supposed
|
||||
* to only display values, but not accept user input. If
|
||||
* non-zero, then the callbacks below are used to when the
|
||||
* cell is entered.
|
||||
*
|
||||
* CALLBACKS:
|
||||
* The enter_cell() callback is called when the user first
|
||||
* makes a move to enter a cell. The current value of the
|
||||
* cell is passed as the argument. If the callback wishes
|
||||
@ -46,15 +50,22 @@
|
||||
* (3) if the callback chooses to not return "new", it must
|
||||
* malloc the memory for a new string. It does not need
|
||||
* to worry about garbage collection.
|
||||
*
|
||||
* GUI STUFF:
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __XACC_BASIC_CELL_H__
|
||||
#define __XACC_BASIC_CELL_H__
|
||||
|
||||
typedef struct _BasicCell {
|
||||
|
||||
short width; /* column width, in chars, not pixels */
|
||||
short alignment; /* column text alignment */
|
||||
char input_output; /* zero if output-only */
|
||||
|
||||
/* private data */
|
||||
char * value; /* current value */
|
||||
|
||||
const char * (*enter_cell) (struct _BasicCell *,
|
||||
@ -66,7 +77,9 @@ typedef struct _BasicCell {
|
||||
const char * (*leave_cell) (struct _BasicCell *,
|
||||
const char * current);
|
||||
|
||||
struct _CellBlock *block; /* back-pointer to parent container */
|
||||
/* private, GUI-specific initializer */
|
||||
void (* realize) (struct _BasicCell *, void *gui_handle);
|
||||
|
||||
} BasicCell;
|
||||
|
||||
|
||||
|
@ -115,9 +115,6 @@ xaccAddCell (CellBlock *arr, BasicCell *cell, int row, int col)
|
||||
arr->cells[row][col] = cell;
|
||||
arr->widths[col] = cell->width;
|
||||
arr->alignments[col] = cell->alignment;
|
||||
|
||||
/* install back-pointer to this container */
|
||||
cell->block = (struct _CellBlock *) arr;
|
||||
}
|
||||
|
||||
/* =================================================== */
|
||||
@ -140,7 +137,6 @@ xaccNextRight (CellBlock *arr, int row, int col,
|
||||
(arr->right_traverse_r)[row][col] = next_row;
|
||||
(arr->right_traverse_c)[row][col] = next_col;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* --------------- end of file ----------------- */
|
||||
|
@ -1,17 +1,27 @@
|
||||
/*
|
||||
* FILE:
|
||||
* cellblock.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* The CellBlock struct is a rectangular grid of cells that
|
||||
* define an arrangement of cells. It is typically used to
|
||||
* define a virtual cursor within a larger table of cells.
|
||||
*
|
||||
* The CellBlock also has utilities to define a tab group.
|
||||
* A tab group is an ordered group of cells that are traversed
|
||||
* when the user presses the tab key (and/or uses the arrow
|
||||
* keys).
|
||||
*
|
||||
* MEMBERS:
|
||||
* The right_traverse array indicates which cell chould be
|
||||
* traversed to when the tab key is pressed.
|
||||
*/
|
||||
|
||||
#ifndef __XACC_CELL_BLOCK_H__
|
||||
#define __XACC_CELL_BLOCK_H__
|
||||
|
||||
#include "basiccell.h"
|
||||
|
||||
/*
|
||||
* The CellBlock is a rectangular grid of cells that define
|
||||
* a traversal group for one entry in the register
|
||||
*
|
||||
* The right_traverse array indicates which cell chould be
|
||||
* traversed to when the tab key is pressed.
|
||||
*/
|
||||
|
||||
typedef struct _CellBlock {
|
||||
|
||||
short numRows;
|
||||
|
172
src/register/combocell.c
Normal file
172
src/register/combocell.c
Normal file
@ -0,0 +1,172 @@
|
||||
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <Xm/Xm.h>
|
||||
#include <ComboBox.h>
|
||||
|
||||
#include "combocell.h"
|
||||
|
||||
/* Some GUI-private date that is inappropriate for
|
||||
* the public interface. In this impelmentation,
|
||||
* it holds XtMotif data that we need.
|
||||
*/
|
||||
|
||||
typedef struct _PopBox {
|
||||
Widget combobox;
|
||||
Widget parent; /* the parent table widget */
|
||||
int currow;
|
||||
int curcol;
|
||||
} PopBox;
|
||||
|
||||
|
||||
static void selectCB (Widget w, XtPointer cd, XtPointer cb );
|
||||
static void dropDownCB (Widget w, XtPointer cd, XtPointer cb );
|
||||
|
||||
/* =============================================== */
|
||||
|
||||
ComboCell *xaccMallocComboCell (void)
|
||||
{
|
||||
ComboCell * cell;
|
||||
cell = (ComboCell *) malloc (sizeof (ComboCell));
|
||||
xaccInitComboCell (cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
void xaccInitComboCell (ComboCell *cell)
|
||||
{
|
||||
PopBox *box;
|
||||
|
||||
xaccInitBasicCell ( &(cell->cell));
|
||||
|
||||
cell->gui = (struct _PopBox *) box;
|
||||
}
|
||||
|
||||
/* =============================================== */
|
||||
|
||||
void RealizeCombo (struct _BasicCell *bcell, void *w)
|
||||
{
|
||||
ComboCell *cell;
|
||||
PopBox *box;
|
||||
Widget parent;
|
||||
Widget combobox;
|
||||
|
||||
int width = 10; /* hack alert --- */
|
||||
int drop_width = 10;
|
||||
|
||||
parent = (Widget) w;
|
||||
cell = (ComboCell *) bcell;
|
||||
|
||||
box = (PopBox *) malloc (sizeof (PopBox));
|
||||
box->parent = parent;
|
||||
box->currow = -1;
|
||||
box->curcol = -1;
|
||||
|
||||
cell->gui = (struct _PopBox *) box;
|
||||
|
||||
/* create the pop GUI */
|
||||
combobox = XtVaCreateManagedWidget
|
||||
("popbox", xmComboBoxWidgetClass, parent,
|
||||
XmNshadowThickness, 0, /* don't draw a shadow,
|
||||
* use bae shadows */
|
||||
XmNeditable, False, /* user can only pick from list */
|
||||
XmNsorted, False,
|
||||
XmNshowLabel, False,
|
||||
XmNmarginHeight, 0,
|
||||
XmNmarginWidth, 0,
|
||||
XmNselectionPolicy, XmSINGLE_SELECT,
|
||||
XmNvalue, "",
|
||||
XmNwidth, 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)box);
|
||||
XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)box);
|
||||
XtAddCallback (combobox, XmNdropDownCallback, dropDownCB, (XtPointer)box);
|
||||
}
|
||||
|
||||
/* =============================================== */
|
||||
|
||||
static void selectCB (Widget w, XtPointer cd, XtPointer cb )
|
||||
|
||||
{
|
||||
PopBox *ab = (PopBox *) cd;
|
||||
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 = "";
|
||||
|
||||
printf ("yo combo select %s \n", choice);
|
||||
|
||||
/* XbaeMatrixSetCell (ab->reg, ab->currow, ab->curcol, choice); */
|
||||
|
||||
/* 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.
|
||||
\********************************************************************/
|
||||
|
||||
static void dropDownCB (Widget w, XtPointer cd, XtPointer cb )
|
||||
|
||||
{
|
||||
PopBox *ab = (PopBox *) cd;
|
||||
XmComboBoxDropDownCallbackStruct *ddcb =
|
||||
(XmComboBoxDropDownCallbackStruct *) cb;
|
||||
|
||||
|
||||
if (XmCR_HIDE_LIST == ddcb->reason) {
|
||||
XmProcessTraversal(ab->parent, XmTRAVERSE_CURRENT);
|
||||
}
|
||||
|
||||
#ifdef USE_COMPLEX_TRAVERSAL_LOGIC
|
||||
/* continue traversal only under certain special curcumstances */
|
||||
if (XmCR_HIDE_LIST == ddcb->reason) {
|
||||
if (ddcb->event) {
|
||||
|
||||
/* don't leave if only a focus-out */
|
||||
if (FocusOut == ddcb->event->type) {
|
||||
XmProcessTraversal(ab->combobox, XmTRAVERSE_CURRENT);
|
||||
} else
|
||||
|
||||
/* if user selected something, then go to next cell */
|
||||
if (ButtonRelease == ddcb->event->type) {
|
||||
XmProcessTraversal(ab->reg, XmTRAVERSE_CURRENT);
|
||||
} else
|
||||
|
||||
/* if user hit the tab key, go to next cell */
|
||||
if ((KeyPress == ddcb->event->type) || (KeyRelease == ddcb->event->type
|
||||
)) {
|
||||
KeySym sim;
|
||||
XKeyEvent *kev = (XKeyEvent *) ddcb->event;
|
||||
sim = XLookupKeysym (kev, 0);
|
||||
if (XK_Tab == sim) { /* did the user hit the tab key ?? */
|
||||
XmProcessTraversal(ab->reg, XmTRAVERSE_CURRENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_COMPLEX_TRAVERSAL_LOGIC */
|
||||
}
|
||||
|
||||
/* =============== end of file =================== */
|
28
src/register/combocell.h
Normal file
28
src/register/combocell.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* FILE:
|
||||
* combocell.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* Implements a combobox cell
|
||||
*
|
||||
* HISTORY:
|
||||
* Created Jan 1998 Linas Vepstas
|
||||
* Copyright (c) 1998 Linas Vepstas
|
||||
*/
|
||||
|
||||
#ifndef __XACC_COMBO_CELL_C__
|
||||
#define __XACC_COMBO_CELL_C__
|
||||
|
||||
#include "basiccell.h"
|
||||
|
||||
typedef struct _ComboCell {
|
||||
BasicCell cell;
|
||||
struct _PopBox *gui; /* gui-private data */
|
||||
} ComboCell;
|
||||
|
||||
ComboCell * xaccMallocComboCell (void);
|
||||
void xaccInitComboCell (ComboCell *);
|
||||
|
||||
#endif /* __XACC_COMBO_CELL_C__ */
|
||||
|
||||
/* --------------- end of file ---------------------- */
|
@ -548,6 +548,7 @@ traverseCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
Widget
|
||||
xaccCreateTable (Table *table, Widget parent, char * name)
|
||||
{
|
||||
CellBlock *curs;
|
||||
unsigned char * alignments;
|
||||
short * widths;
|
||||
Widget reg;
|
||||
@ -565,11 +566,6 @@ xaccCreateTable (Table *table, Widget parent, char * name)
|
||||
haveQuarks = True;
|
||||
}
|
||||
|
||||
/* make sure that the table is consistent */
|
||||
/* hack alert -- remove for now, since may be inited?
|
||||
xaccInitTable (table, table->num_rows, table->num_cols);
|
||||
*/
|
||||
|
||||
/* if a header exists, get alignments, widths from there */
|
||||
alignments = NULL;
|
||||
widths = NULL;
|
||||
@ -585,6 +581,7 @@ xaccCreateTable (Table *table, Widget parent, char * name)
|
||||
/* copy header data into entries cache */
|
||||
xaccRefreshHeader (table);
|
||||
|
||||
/* create the matrix widget */
|
||||
reg = XtVaCreateWidget( name,
|
||||
xbaeMatrixWidgetClass, parent,
|
||||
XmNcells, table->entries,
|
||||
@ -607,12 +604,36 @@ xaccCreateTable (Table *table, Widget parent, char * name)
|
||||
|
||||
XtManageChild (reg);
|
||||
|
||||
/* add callbacks that handle cell editing */
|
||||
XtAddCallback (reg, XmNenterCellCallback, cellCB, (XtPointer)table);
|
||||
XtAddCallback (reg, XmNleaveCellCallback, cellCB, (XtPointer)table);
|
||||
XtAddCallback (reg, XmNmodifyVerifyCallback, cellCB, (XtPointer)table);
|
||||
XtAddCallback (reg, XmNtraverseCellCallback, cellCB, (XtPointer)table);
|
||||
|
||||
table->table_widget = reg;
|
||||
|
||||
/* if any of the cells have GUI specific compnents that need
|
||||
* initialization, initialize them now. */
|
||||
|
||||
curs = table->cursor;
|
||||
if (curs) {
|
||||
int i,j;
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
BasicCell *cell;
|
||||
cell = curs->cells[i][j];
|
||||
if (cell) {
|
||||
void (*xt_realize) (struct _BasicCell *, void *gui);
|
||||
xt_realize = cell->realize;
|
||||
if (xt_realize) {
|
||||
xt_realize (((struct _BasicCell *) cell), ((void *) reg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (reg);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user