The current basis of the cget function for widgets is based upon code written over 20yrs ago and, whilst it works reasonably well for the simple setting of gtk widget properties, support for more complex custom options is hit and miss.
const char *optName;
enum GnoclOptionType type;
const char *propName;
gnoclOptFunc *func;
const char *description;
const char *values;
With the recent updating of the C sources which includes an expansion of the GnoclOption structure to accommodate documentation support, it well worth reviewing the way in which widget functions handle the return of options.
Rather than treating the retrieval of properties set by a function as the final call, perhaps it should be prioritized. If one is not present, then extract a value based upon the setting type.
case CgetIdx: {
int idx;
/* get the idx of the option in structure array */
Tcl_GetIndexFromObjStruct ( interp, objv[2], ( char ** ) &options[0].optName, sizeof ( GnoclOption ), "option", TCL_EXACT, &idx );
/* does the option have a function? */
if (options[idx].func != NULL) {
Tcl_Obj *res;
options[idx].func ( interp, &options[idx], grid, &res );
Tcl_SetObjResult ( interp, res );
} else {
switch ( gnoclCget ( interp, objc, objv, G_OBJECT ( grid ), options, &idx ) ) {
case GNOCL_CGET_ERROR: { return TCL_ERROR; }
case GNOCL_CGET_HANDLED: { return TCL_OK; }
case GNOCL_CGET_NOTHANDLED: {
return cget ( interp, grid, options, idx ); }
}
}
break;
}
return TCL_OK;
}
Placing this test at the head of the sequence is more intuitive as these provide the greates complication when dealing with extraction of settings.
A GnoclOpFun woudl then be something along the lines of:
static int gnoclOptBaseLineRow ( Tcl_Interp * interp, GnoclOption * opt, GObject * obj, Tcl_Obj **ret )
{
gint idx;
Tcl_GetIndexFromObj ( interp, opt->val.obj, baseLinePositions, "baseLinePosition", TCL_EXACT, &idx );
if ( ret == NULL ) { /* set value */
g_object_set ( obj, opt->propName, idx, NULL );
} else { /* get value */
g_object_get ( obj, opt->propName, &idx, NULL );
Tcl_SetObjResult ( interp, Tcl_NewStringObj ( baseLinePositions[idx], -1 ) );
}
return TCL_OK;
}
Comments