Commit 0d807395 authored by Richard M. Stallman's avatar Richard M. Stallman
Browse files

(destroy_all_children): New arg first_child_to_destroy.

(make_menu_in_widget): New arg keep_first_children.
(xm_update_menu): Preserve the first children even if later ones
have a structural change.
(update_one_menu_entry): Use this_one_change field.
parent 8e46e267
......@@ -147,9 +147,13 @@ resource_motif_string (widget, name)
return result;
}
/* Destroy all of the children of WIDGET
starting with number FIRST_CHILD_TO_DESTROY. */
static void
destroy_all_children (widget)
destroy_all_children (widget, first_child_to_destroy)
Widget widget;
int first_child_to_destroy;
{
Widget* children;
unsigned int number;
......@@ -158,17 +162,14 @@ destroy_all_children (widget)
children = XtCompositeChildren (widget, &number);
if (children)
{
XtUnmanageChildren (children + first_child_to_destroy,
number - first_child_to_destroy);
/* Unmanage all children and destroy them. They will only be
* really destroyed when we get out of DispatchEvent. */
for (i = 0; i < number; i++)
{
Widget child = children [i];
if (!child->core.being_destroyed)
{
XtUnmanageChild (child);
XtDestroyWidget (child);
}
}
really destroyed when we get out of DispatchEvent. */
for (i = first_child_to_destroy; i < number; i++)
XtDestroyWidget (children[i]);
XtFree ((char *) children);
}
}
......@@ -337,11 +338,14 @@ all_dashes_p (s)
return True;
}
/* KEEP_FIRST_CHILDREN gives the number of initial children to keep. */
static void
make_menu_in_widget (instance, widget, val)
make_menu_in_widget (instance, widget, val, keep_first_children)
widget_instance* instance;
Widget widget;
widget_value* val;
int keep_first_children;
{
Widget* children = 0;
int num_children;
......@@ -353,6 +357,11 @@ make_menu_in_widget (instance, widget, val)
int ac;
Boolean menubar_p;
Widget* old_children;
unsigned int old_num_children;
old_children = XtCompositeChildren (widget, &old_num_children);
/* Allocate the children array */
for (num_children = 0, cur = val; cur; num_children++, cur = cur->next);
children = (Widget*)XtMalloc (num_children * sizeof (Widget));
......@@ -368,7 +377,18 @@ make_menu_in_widget (instance, widget, val)
XtAddCallback (XtParent (widget), XmNpopdownCallback,
xm_pop_down_callback, (XtPointer)instance);
for (child_index = 0, cur = val; cur; child_index++, cur = cur->next)
/* Preserve the first KEEP_FIRST_CHILDREN old children. */
for (child_index = 0, cur = val; child_index < keep_first_children;
child_index++, cur = cur->next)
children[child_index] = old_children[child_index];
/* Check that those are all we have
(the caller should have deleted the rest). */
if (old_num_children != keep_first_children)
abort ();
/* Create the rest. */
for (child_index = keep_first_children; cur; child_index++, cur = cur->next)
{
ac = 0;
XtSetArg (al [ac], XmNsensitive, cur->enabled); ac++;
......@@ -405,7 +425,7 @@ make_menu_in_widget (instance, widget, val)
else
{
menu = XmCreatePulldownMenu (widget, cur->name, NULL, 0);
make_menu_in_widget (instance, menu, cur->contents);
make_menu_in_widget (instance, menu, cur->contents, 0);
XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
button = XmCreateCascadeButton (widget, cur->name, al, ac);
......@@ -430,6 +450,8 @@ make_menu_in_widget (instance, widget, val)
}
XtFree ((char *) children);
if (old_children)
XtFree ((char *) old_children);
}
static void
......@@ -444,7 +466,7 @@ update_one_menu_entry (instance, widget, val, deep_p)
Widget menu;
widget_value* contents;
if (val->change == NO_CHANGE)
if (val->this_one_change == NO_CHANGE)
return;
/* update the sensitivity and userdata */
......@@ -455,7 +477,7 @@ update_one_menu_entry (instance, widget, val, deep_p)
0);
/* update the menu button as a label. */
if (val->change >= VISIBLE_CHANGE)
if (val->this_one_change >= VISIBLE_CHANGE)
xm_update_label (instance, widget, val);
/* update the pulldown/pullaside as needed */
......@@ -471,7 +493,7 @@ update_one_menu_entry (instance, widget, val, deep_p)
if (contents)
{
menu = XmCreatePulldownMenu (XtParent (widget), XtName (widget), NULL, 0);
make_menu_in_widget (instance, menu, contents);
make_menu_in_widget (instance, menu, contents, 0);
ac = 0;
XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
XtSetValues (widget, al, ac);
......@@ -495,39 +517,64 @@ xm_update_menu (instance, widget, val, deep_p)
widget_value* val;
Boolean deep_p;
{
Widget* children;
unsigned int num_children;
int num_children_to_keep = 0;
int i;
widget_value* cur;
children = XtCompositeChildren (widget, &num_children);
/* Widget is a RowColumn widget whose contents have to be updated
* to reflect the list of items in val->contents */
if (val->contents->change == STRUCTURAL_CHANGE)
{
destroy_all_children (widget);
make_menu_in_widget (instance, widget, val->contents);
}
else
{
/* Update all the buttons of the RowColumn in order. */
Widget* children;
unsigned int num_children;
int i;
widget_value* cur;
children = XtCompositeChildren (widget, &num_children);
/* See how many buttons we can keep, and how many we
must completely replace. */
if (val->contents == 0)
num_children_to_keep = 0;
else if (val->contents->change == STRUCTURAL_CHANGE)
{
if (children)
{
for (i = 0, cur = val->contents; i < num_children; i++)
for (i = 0, cur = val->contents; i < num_children;
i++, cur = cur->next)
{
if (!cur)
abort ();
if (children [i]->core.being_destroyed
|| strcmp (XtName (children [i]), cur->name))
continue;
update_one_menu_entry (instance, children [i], cur, deep_p);
cur = cur->next;
if (cur->this_one_change == STRUCTURAL_CHANGE)
break;
}
XtFree ((char *) children);
num_children_to_keep = i;
}
}
else
num_children_to_keep = num_children;
/* Update all the buttons of the RowColumn, in order,
except for those we are going to replace entirely. */
if (children)
{
for (i = 0, cur = val->contents; i < num_children_to_keep; i++)
{
if (!cur)
abort ();
if (children [i]->core.being_destroyed
|| strcmp (XtName (children [i]), cur->name))
continue;
update_one_menu_entry (instance, children [i], cur, deep_p);
cur = cur->next;
}
if (cur)
abort ();
}
/* Now replace from scratch all the buttons after the last
place that the top-level structure changed. */
if (val->contents->change == STRUCTURAL_CHANGE)
{
destroy_all_children (widget, num_children_to_keep);
make_menu_in_widget (instance, widget, val->contents,
num_children_to_keep);
}
XtFree ((char *) children);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment