From: Richard M. Stallman Date: Mon, 25 Mar 1996 01:46:16 +0000 (+0000) Subject: (destroy_all_children): New arg first_child_to_destroy. X-Git-Tag: emacs-19.34~983 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0d807395f89eb2f199ed41b1b2930063ed118494;p=emacs.git (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. --- diff --git a/lwlib/lwlib-Xm.c b/lwlib/lwlib-Xm.c index 26ac76fad9e..72700641d2d 100644 --- a/lwlib/lwlib-Xm.c +++ b/lwlib/lwlib-Xm.c @@ -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); }