
Figure 15: Built-in Chart Editor.
The built-in resource editor can be invoked for a specific object using public function XintEditObjectManageResourceDialog. Action ResourceDialog (defined by the EditObject class) is also available for the end-user to interactively edit an object's resources. This action is connected as follows in the default translation table:
| Action | Default Dialog Translation |
|---|---|
| None <Btn1Down> | ResourceDialog() |
Note that action ResourceDialog actually checks for a double click, so it will only trigger on a double click of Button1.
You can disable the resource editor panel for a specific object by setting Graphic resource XmNresourceDialog to False when creating the object. You can disable all resource dialogs by registering callback XmNresourceDialogCallback on the EditObject widget and setting the doit flag member of the callback structure to False, as shown in the code sample below:
static void ResourceDialogCallback(widget, data, cb)
Widget widget;
XtPointer data;
XintEditObjectResourceDialogCallbackStruct *cb;
{
cb->doit = False
}
If you need to unmanage the parent of a chart object (EditObject widget), you should first invoke Graphic function XintGraphicUnmanageDialog on the chart to unmanage all built-in dialogs that may be active. Failure to do so will prevent those dialog panels from ever reappearing the next time the chart's parent is managed (Motif bug).
Note: all objects of the same class share the same built-in editor panel. So, any change to an object panel will automatically apply to all the other objects of the same class.
The widget(s) used to edit a particular resource are encapsulated inside a container widget (box). For example, an editor for a resource of type String is composed of a box containing a label and a Text widget. Function XintResEditGetBox retrieves the box widget ID for a particular resource.
Widget XintResEditGetBox(Object object, String resource_name, int num);
You can unmanage the box to prevent a particular resource from being displayed and edited. Argument num represents the number of components for the resource and it should be set to 1 in most cases. Some resources however, such as XmNlimits for the AxisObject, have several components (one to edit the minimum value and one to edit the maximum value). Setting argument num to 1 will retrieve the box used to edit the minimum value. Setting argument num to 2 will retrieve the box used to edit the maximum value.
Most resource editors use a label widget or gadget to display the text identifying which resource is being set (see strings "Chart Type", "Title", "Footer", "Show Legend" in Figure 15). Function XintResEditGetLabel retrieves the label ID for a particular resource if there is one. If no label is defined, the function returns NULL. This label ID can be used to modify the text displayed in the editor.
Widget XintResEditGetLabel(Object object, String resource_name, int num);
Some resources, such as XmNchartType, are edited using an option menu. Function XintResEditGetMenuButton can be used to retrieve the ID of a particular button in the option menu. Argument button_name is the name of the option as it is specified in the menu. Unmanage the button ID returned by function XintResEditGetMenuButton to remove an option from the menu.
Widget XintResEditGetMenuButton(Object object, String resource_name,
String button_name);
The following example illustrates how to use the above functions. We modify the chart editor shown in Figure 15 to a) remove the chart footer component, b) rename "Chart Type" to "Type" and, c) remove option "High Low" from the option menu used to select the chart type.
Object chart;
Widget button, label;
...
/* Unmanage XmNchartFooter editor */
box = XintResEditGetBox(chart, XmNchartFooter, 1);
if (box != NULL) XtUnmanageChild(box);
/* Change name of label from "Chart Type" to "Type" */
label = XintResEditGetLabel(chart, XmNchartType, 1);
if (label) {
XmString cstring;
cstring = XmStringCreateSimple("Type");
XtVaSetValues(label, XmNlabelString, cstring, NULL);
XmStringFree(cstring);
}
/* Unmanage High Low option in chart type option menu */
button = XintResEditGetMenuButton(chart, XmNchartType,"High Low");
if (button) XtUnmanageChild(button);
static void ResourceDialogCallback(widget, data, cb)
Widget widget;
XtPointer data;
XintEditObjectResourceDialogCallbackStruct *cb;
{
static Widget my_axis_panel = NULL;
static Widget axis_widgets[2];
Object selected_object;
int code;
if (XintIsChart(cb->object))
selected_object = XintChartGetSelectedComponent( cb->object, &code);
else
selected_object = cb->object;
if (XintIsAxisObject(selected_object)) {
/* Create my own panel if first time */
if (!my_axis_panel)
my_axis_panel = BuildAxisPanel(widget, axis_widgets);
/* load axis panel to contain current axis state */
LoadAxisPanel(axis_widgets, selected_object);
/* Display my panel */
XtManageChild(my_axis_panel);
/* Turn off built-in panel */
cb->doit = False;
}
}
Function BuildAxisPanel builds the dialog panel and fills the array axis_widgets with the widget ID's it will need later. This function uses an INT convenience function, IntCreateDialogPanel, that creates a dialog widget with a set of buttons as specified.
static Widget BuildAxisPanel(widget, axis_widget_list)
Widget widget;
Widget *axis_widget_list;
{
Widget panel, vbox;
panel = (Widget) IntCreateDialogPanel(XtParent(widget),
"My Axis Editor",
IntOK | IntAPPLY | IntCANCEL,
IntOK, EditAxisCallback,
(XtPointer)axis_widget_list,
XintVERTICAL, 5, 5, &vbox, NULL);
/* Create text to edit axis label */
axis_widget_list[0] = XtVaCreateManagedWidget("axis_label",
xmTextWidgetClass, vbox,
XmNcolumns, 20,
XmNeditMode, XmSINGLE_LINE_EDIT,
NULL);
/* Save edit object ID. We will need it in EditAxisCallback */
axis_widget_list[1] = widget;
return panel;
}
Function LoadAxisPanel retrieves the resources from the specified objects and loads the values into the panel before we manage it.
static void LoadAxisPanel(axis_widget_list, object)
Widget *axis_widget_list;
Object object;
{
char *label_string;
XtVaGetValues((Widget) object, XmNlabel, &label_string, NULL);
XmTextSetString(axis_widget_list[0], label_string);
}
Finally, here is the code for callback EditAxisCallback which is the callback invoked when the OK or APPLY button is selected from the custom menu.
static void EditAxisCallback(widget, axis_widget_list, cb)
Widget widget;
Widget *axis_widget_list;
XmAnyCallbackStruct *cb;
{
char *axis_label;
Object *list;
Object object;
int i, count;
int code;
if (cb->reason == IntOK || IntAPPLY) {
axis_label = XmTextGetString(axis_widget_list[0]);
/*
* get the list of selected object, and apply SetValues to the
* Axis object(s)
*/
list = XintEditObjectSelectList(axis_widget_list[1], &count);
for (i=0; i<count; i++) {
if (XintIsChart(list[i])) {
object = XintChartGetSelectedComponent(list[i], &code);
if (XintIsAxisObject(object))
XtVaSetValues((Widget) object,
XmNlabel, axis_label, NULL);
}
}
/* Cleanup */
if (list) XtFree((char *) list);
if (axis_label) XtFree(axis_label);
}
}