/* * $Header: /home/barad-dur/vision/forsyth/schenney/sced-0.94/c/RCS/edit_menu.c,v 1.0 1997/05/06 20:30:22 schenney Exp $ * * $Log: edit_menu.c,v $ * Revision 1.0 1997/05/06 20:30:22 schenney * Initial revision * */ #define PATCHLEVEL 0 /* ** ScEd: A Constraint Based Scene Editor. ** Copyright (C) 1994-1998 Stephen Chenney (schenney@cs.berkeley.edu) ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ** sced: A Constraint Based Object Scene Editor ** ** edit_menu.c : Functions for handling objects on the edit menu. ** They add, delete etc. */ #include #include #include #include #include #include static void Edit_Menu_Callback(Widget, XtPointer, XtPointer); void Create_Edit_Menu(WindowInfoPtr window) { Arg args[3]; int n; /* Create a structure to hold everything. */ window->edit_menu = New(MenuInfo, 1); /* Create the menu itself. */ window->edit_menu->menu = XtCreatePopupShell("EditMenu", simpleMenuWidgetClass, window->shell, NULL, 0); /* Put a line at the top, just to give it width and height. */ n = 0; XtSetArg(args[n], XtNlineWidth, 4); n++; XtSetArg(args[n], XtNwidth, 50); n++; XtCreateManagedWidget("menuLine", smeLineObjectClass, window->edit_menu->menu, args, n); /* Give it an arbitrary number of children for starters. */ window->edit_menu->num_children = 0; window->edit_menu->max_children = 5; window->edit_menu->children = New(Widget, 5); } /* void ** Edit_Objects_Function(Widget w, XtPointer cl_data, XtPointer ca_data) ** For a WindowInfoPtr passed as cl_data, adds the selected objects ** to the edit_objects. */ void Edit_Objects_Function(Widget w, XtPointer cl_data, XtPointer ca_data) { WindowInfoPtr window = (WindowInfoPtr)cl_data; Add_Instance_To_Edit(window, window->selected_instances, TRUE); } /* void ** Add_Instance_To_Edit(WindowInfoPtr window, InstanceList extras) ** Adds the new elmt to the list of edit objects for window. ** This also adds a new menu entry for the object. */ void Add_Instance_To_Edit(WindowInfoPtr window, InstanceList extras, Boolean exists) { InstanceList src_elmt; InstanceList new_elmt = NULL; char name[20]; Arg args[3]; int n; int count = 0; Boolean have_new = FALSE; for ( src_elmt = extras ; src_elmt != NULL ; src_elmt = src_elmt->next ) { count++; /* Add it to the place list if it's not already there. */ if ( ( new_elmt = Find_Object_In_Instances(src_elmt->the_instance, window->edit_instances) ) ) continue; if ( Layer_Is_Visible(src_elmt->the_instance->o_layer) ) { new_elmt = Append_Element(&(window->edit_instances), src_elmt->the_instance); /* Add a widget for it. */ if ( window->edit_menu->num_children == window->edit_menu->max_children ) { window->edit_menu->max_children += 5; window->edit_menu->children = More(window->edit_menu->children, Widget, window->edit_menu->max_children); } sprintf(name, "editEntry%d", window->edit_menu->num_children); n = 0; XtSetArg(args[n], XtNlabel, src_elmt->the_instance->o_label); n++; window->edit_menu->children[window->edit_menu->num_children] = XtCreateManagedWidget(name, smeBSBObjectClass, window->edit_menu->menu, args, n); XtAddCallback( window->edit_menu->children[window->edit_menu->num_children], XtNcallback, Edit_Menu_Callback, (XtPointer)window); have_new = TRUE; window->edit_menu->num_children++; } if ( ! exists ) { new_elmt = Append_Element(&(window->all_instances), src_elmt->the_instance); if ( Layer_Is_Visible(new_elmt->the_instance->o_layer) ) new_elmt->the_instance->o_flags |= ObjVisible; /* Only one can have been added, so do the redraw here. */ View_Update(window, new_elmt, CalcView); Update_Projection_Extents(new_elmt); changed_scene = TRUE; } } if ( have_new ) XtVaSetValues(window->edit_menu->button, XtNsensitive, TRUE, NULL); if ( exists && count == 1 ) Edit_Instance(window, new_elmt); } /* void ** Delete_Edit_Instance(WindowInfoPtr window, InstanceList victim) ** Deletes the victim from the place menu. */ void Delete_Edit_Instance(WindowInfo *window, InstanceList victim) { InstanceList elmt; int i, j; /* Find which widget it corresponds to. */ for ( i = 0, elmt = window->edit_instances ; elmt != victim ; i++, elmt = elmt->next ); XtDestroyWidget(window->edit_menu->children[i]); /* Shuffle the others down. */ for ( j = i + 1 ; j < window->edit_menu->num_children ; j++ ) window->edit_menu->children[j-1] = window->edit_menu->children[j]; window->edit_menu->num_children--; if ( ! window->edit_menu->num_children ) XtVaSetValues(window->edit_menu->button, XtNsensitive, FALSE, NULL); if ( window->edit_instances == victim ) window->edit_instances = window->edit_instances->next; Delete_Element(victim); free(victim); } /* void ** Edit_Menu_Callback(Widget w, XtPointer cl_data, XtPointer ca) ** The callback for all the children in the place menu. ** Calls the place object function for the appropriate entry. */ static void Edit_Menu_Callback(Widget w, XtPointer cl_data, XtPointer ca) { WindowInfo *window = (WindowInfo*)cl_data; InstanceList elmt; int i; /* Find which widget it corresponds to. */ for ( i = 0, elmt = window->edit_instances ; window->edit_menu->children[i] != w ; i++, elmt = elmt->next ); Edit_Instance(window, elmt); }