/* This file is part of the FElt finite element analysis package. Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson 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. */ /************************************************************************ * File: loadcase.c * * * * Description: This file contains the public and private function and * * type definitions for the loadcase dialog box. * ************************************************************************/ # include # include # include # include # include # include # include # include # include # include # include # include # include # include "Layout.h" # include "LoadCase.h" # include "TabGroup.h" # include "util.h" # include "objects.h" # include "post.h" # include "problem.h" # include "allocate.h" # include "error.h" # ifndef X_NOT_STDC_ENV # include # endif struct loadcase_dialog { Widget shell; /* topLevelShell */ Widget layout; /* Layout layout */ Widget name; /* AsciiText name */ Widget node [4]; /* AsciiText node{i} */ Widget element [4]; /* AsciiText element{i} */ Widget force [4]; /* AsciiText force{i} */ Widget load [4]; /* AsciiText load{i} */ Widget force_button; /* MenuButton force_button */ Widget force_menu; /* SimpleMenu force_menu */ Widget load_button; /* MenuButton load_button */ Widget load_menu; /* SimpleMenu load_menu */ Widget node_up; /* Command node_up */ Widget node_down; /* Command node_down */ Widget element_up; /* Command element_up */ Widget element_down; /* Command element_down */ Widget viewport; /* Viewport viewport */ Widget list; /* List list */ Widget help; /* MenuButton help */ Widget accept; /* Command accept */ Widget dismiss; /* Command dismiss */ Widget delete; /* Command delete */ Widget new; /* Command new */ Widget copy; /* Command copy */ String *loadcases; LoadCase active; Boolean new_copy; Tree tree; unsigned node_base; unsigned element_base; String force_assignments [100]; unsigned node_assignments [100]; String load_assignments [100]; unsigned element_assignments [100]; unsigned num_forces; unsigned num_loads; }; static String labels [ ] = { "Name:", "node", "element" }; static String names [ ] = { "nameLabel", "nodeLabel", "elementLabel" }; static LoadCaseDialog dialog; static Cardinal num_loadcases; static int list_index; /* Bitmaps */ #define up_width 12 #define up_height 12 static char up_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xf0, 0x00, 0xf8, 0x01, 0xfc, 0x03, 0xfe, 0x07, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #define down_width 12 #define down_height 12 static char down_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0xfe, 0x07, 0xfc, 0x03, 0xf8, 0x01, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static Pixmap up_bitmap; static Pixmap down_bitmap; /* Resources */ static Pixel highlight; static String dummy_list [ ] = { NULL }; static String layout_string = "vertical { \ horizontal { \ 4 \ vertical { \ 4 \ horizontal { \ nameLabel \ 4 \ name <+inf -100% *> \ } \ 4 \ viewport <+inf * +inf> \ 4 \ } \ 12 \ separator1 <* +inf -100%> \ 12 \ vertical { \ 4 \ horizontal { \ ((width node1 - width nodeLabel) / 2) \ nodeLabel \ ((width node1 - width nodeLabel) / 2) \ 16 \ ((width force1 - width force_button) / 2) \ force_button <+inf -100% *> \ ((width force1 - width force_button) / 2) \ } \ 4 \ horizontal { \ node1 \ 16 \ force1 <+inf -100% *> \ } \ 4 \ horizontal { \ node2 \ 16 \ force2 <+inf -100% *> \ } \ 4 \ horizontal { \ node3 \ 16 \ force3 <+inf -100% *> \ } \ 4 \ horizontal { \ node4 \ 16 \ force4 <+inf -100% *> \ } \ 8 \ horizontal { \ node_down \ 4 \ node_up \ } \ 4 \ } \ 12 \ separator3 <* +inf -100%> \ 12 \ vertical { \ 4 \ horizontal { \ ((width element1 - width elementLabel) / 2) \ elementLabel \ ((width element1 - width elementLabel) / 2) \ 16 \ ((width load1 - width load_button) / 2) \ load_button <+inf -100% *> \ ((width load1 - width load_button) / 2) \ } \ 4 \ horizontal { \ element1 \ 16 \ load1 <+inf -100% *> \ } \ 4 \ horizontal { \ element2 \ 16 \ load2 <+inf -100% *> \ } \ 4 \ horizontal { \ element3 \ 16 \ load3 <+inf -100% *> \ } \ 4 \ horizontal { \ element4 \ 16 \ load4 <+inf -100% *> \ } \ 8 \ horizontal { \ element_down \ 4 \ element_up \ } \ 4 \ } \ 12 \ } \ separator2 <+inf -100% *> \ 4 \ horizontal { \ 4 \ help \ 4 <+inf -100%> \ accept \ 4 <+inf -100%> \ dismiss \ 4 <+inf -100%> \ delete \ 4 <+inf -100%> \ new \ 4 <+inf -100%> \ copy \ 4 \ } \ 4 \ }"; static Arg color_args [ ] = { {XtNborderColor, (XtArgVal) &highlight}, }; static Arg shell_args [ ] = { {XtNtitle, (XtArgVal) NULL}, {XtNiconName, (XtArgVal) NULL}, }; static Arg layout_args [ ] = { {XtNlayout, (XtArgVal) NULL}, }; static Arg viewport_args [ ] = { {XtNallowVert, (XtArgVal) True}, {XtNforceBars, (XtArgVal) True}, {XtNborderWidth, (XtArgVal) 0}, }; static Arg list_args [ ] = { {XtNdefaultColumns, (XtArgVal) 1}, {XtNforceColumns, (XtArgVal) 1}, {XtNresize, (XtArgVal) True}, {XtNlist, (XtArgVal) dummy_list}, }; static Arg number_args [ ] = { {XtNeditType, (XtArgVal) XawtextEdit}, {XtNborderWidth, (XtArgVal) 0}, {XtNpieceSize, (XtArgVal) 32}, {XtNcursorName, (XtArgVal) "left_ptr"}, {XtNwidth, (XtArgVal) 40}, }; static Arg name_args [ ] = { {XtNeditType, (XtArgVal) XawtextEdit}, {XtNborderWidth, (XtArgVal) 0}, {XtNpieceSize, (XtArgVal) 32}, {XtNcursorName, (XtArgVal) "left_ptr"}, }; static Arg label_args [ ] = { {XtNlabel, (XtArgVal) ""}, {XtNborderWidth, (XtArgVal) 0}, }; static Arg core_args [ ] = { {XtNwidth, (XtArgVal) 3}, {XtNheight, (XtArgVal) 3}, }; static Arg repeater_args [ ] = { {XtNbitmap, (XtArgVal) NULL}, }; static Arg button_args [ ] = { {XtNlabel, (XtArgVal) ""}, {XtNmenuName, (XtArgVal) ""}, {XtNborderWidth, (XtArgVal) 0}, }; /* Translation tables */ static String text_table = "Return: LoadCaseDialogAction(accept)\n\ Escape: LoadCaseDialogAction(dismiss)\n\ Ctrld: LoadCaseDialogAction(delete)\n\ Ctrlc: LoadCaseDialogAction(copy)\n\ Ctrln: LoadCaseDialogAction(new)\n\ Ctrlh: LoadCaseDialogAction(help)\n\ : SetFocus() select-start()"; static XtTranslations text_translations; static String button_table = "Return: LoadCaseDialogAction(accept)\n\ Escape: LoadCaseDialogAction(dismiss)\n\ Ctrld: LoadCaseDialogAction(delete)\n\ Ctrlc: LoadCaseDialogAction(copy)\n\ Ctrln: LoadCaseDialogAction(new)\n\ Ctrlh: LoadCaseDialogAction(help)\n\ : PostMenu()\n\ space: PostMenu()"; static XtTranslations button_translations; static String repeater_table = "Return: LoadCaseDialogAction(accept)\n\ Escape: LoadCaseDialogAction(dismiss)\n\ Ctrld: LoadCaseDialogAction(delete)\n\ Ctrlc: LoadCaseDialogAction(copy)\n\ Ctrln: LoadCaseDialogAction(new)\n\ Ctrlh: LoadCaseDialogAction(help)\n\ space: AutoRepeat(off) set()\n\ space: AutoRepeat(saved) notify() unset()"; static XtTranslations repeater_translations; static String command_table = "Return: LoadCaseDialogAction(accept)\n\ Escape: LoadCaseDialogAction(dismiss)\n\ Ctrld: LoadCaseDialogAction(delete)\n\ Ctrlc: LoadCaseDialogAction(copy)\n\ Ctrln: LoadCaseDialogAction(new)\n\ Ctrlh: LoadCaseDialogAction(help)\n\ space: AutoRepeat(off) set()\n\ space: AutoRepeat(saved) notify() unset()"; static XtTranslations command_translations; static String viewport_table = "Return: LoadCaseDialogAction(accept)\n\ Escape: LoadCaseDialogAction(dismiss)\n\ Ctrld: LoadCaseDialogAction(delete)\n\ Ctrlc: LoadCaseDialogAction(copy)\n\ Ctrln: LoadCaseDialogAction(new)\n\ Ctrlh: LoadCaseDialogAction(help)\n\ : SetFocus()"; static XtTranslations viewport_translations; static String help_table = "Return: LoadCaseDialogAction(accept)\n\ Escape: LoadCaseDialogAction(dismiss)\n\ Ctrld: LoadCaseDialogAction(delete)\n\ Ctrlc: LoadCaseDialogAction(copy)\n\ Ctrln: LoadCaseDialogAction(new)\n\ Ctrlh: LoadCaseDialogAction(help)\n\ space: PostMenu()"; static XtTranslations help_translations; /* Help message. */ static String help_message =""; /************************************************************************ * Function: AppendLoadCaseName * * * * Description: Appends the loadcase name to the array of names. The * * index of the active loadcase is also set. * ************************************************************************/ static int AppendLoadCaseName (item) Item item; { if (dialog -> active == (LoadCase) item) list_index = num_loadcases; dialog -> loadcases [num_loadcases ++] = ((LoadCase) item) -> name; return 0; } /************************************************************************ * Function: Action * * * * Description: An action procedure which emulates pressing of the * * specified button. * ************************************************************************/ static void Action (w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params; { if (XtClass (w) == topLevelShellWidgetClass) w = XtNameToWidget (w, "layout.dismiss"); else w = XtNameToWidget (XtParent (w), params [0]); if (!strcmp (XtName (w), "help")) XtCallActionProc (w, "PostMenu", event, NULL, 0); else XtCallCallbacks (w, XtNcallback, NULL); } /************************************************************************ * Function: ScrollNode * * Description: ************************************************************************/ static void ScrollNode (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { Arg args [1]; LoadCaseDialog loadcased; unsigned current [4]; unsigned count; String value; char buffer [10]; unsigned node; unsigned i; unsigned base; int dir; loadcased = (LoadCaseDialog) client_data; base = loadcased -> node_base; /* * figure out which entries have numbers in them */ XtSetArg (args [0], XtNstring, &value); count = 0; for (i = 0 ; i < 4 ; i++) { XtGetValues (loadcased -> node [i], args, 1); node = atoi (value); if (node != 0) current [count++] = node; } /* * if necessary (and allowed) actually do the shift */ if (w == loadcased -> node_up && count == 4) dir = 1; else if (w == loadcased -> node_down && base > 0) dir = -1; else return; fprintf (stderr,"base = %d\n", base); fprintf (stderr,"count = %d\n", count); fprintf (stderr,"num_forces = %d\n", loadcased -> num_forces); if (base + count > loadcased -> num_forces) loadcased -> num_forces = base + count; else if (base + count < loadcased -> num_forces && base + count > 0) loadcased -> num_forces = base + count; /* * make a record of everything displayed before we shift anything * off screen (up shift) */ if (dir == 1) { for (i = 0 ; i < count ; i++) { loadcased -> node_assignments [base + i] = current [i]; XtGetValues (loadcased -> force [i], args, 1); loadcased -> force_assignments [base + i] = XtNewString (value); fprintf (stderr,"force %d = %s\n", base + i, loadcased -> force_assignments [base + i]); } } base = base + dir; /* * update the nodes that are actually displayed */ for (i = 0 ; i < 4 ; i++) { if (base + i < loadcased -> num_forces) { sprintf (buffer,"%d", loadcased -> node_assignments [base + i]); SetTextString (loadcased -> node [i], buffer); SetTextString (loadcased -> force [i], loadcased -> force_assignments [base + i]); } else { buffer [0] = 0; SetTextString (loadcased -> node [i], buffer); SetTextString (loadcased -> force [i], ""); } } loadcased -> node_base = base; return; } /************************************************************************ * Function: ScrollElement * * Description: ************************************************************************/ static void ScrollElement (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { Arg args [1]; LoadCaseDialog loadcased; unsigned current [4]; unsigned count; String value; char buffer [10]; unsigned element; unsigned i; unsigned base; int dir; loadcased = (LoadCaseDialog) client_data; base = loadcased -> element_base; /* * figure out which entries have numbers in them */ XtSetArg (args [0], XtNstring, &value); count = 0; for (i = 0 ; i < 4 ; i++) { XtGetValues (loadcased -> element [i], args, 1); element = atoi (value); if (element != 0) current [count++] = element; } /* * if necessary (and allowed) actually do the shift */ if (w == loadcased -> element_up && count == 4) dir = 1; else if (w == loadcased -> element_down && base > 0) dir = -1; else return; fprintf (stderr,"base = %d\n", base); fprintf (stderr,"count = %d\n", count); fprintf (stderr,"num_loads = %d\n", loadcased -> num_loads); if (base + count > loadcased -> num_loads) loadcased -> num_loads = base + count; else if (base + count < loadcased -> num_loads && base + count > 0) loadcased -> num_loads = base + count; /* * make a record of everything displayed before we shift anything * off screen (up shift) */ if (dir == 1) { for (i = 0 ; i < count ; i++) { loadcased -> element_assignments [base + i] = current [i]; XtGetValues (loadcased -> load [i], args, 1); loadcased -> load_assignments [base + i] = XtNewString (value); fprintf (stderr,"load %d = %s\n", base + i, loadcased -> load_assignments [base + i]); } } base = base + dir; /* * update the elements that are actually displayed */ for (i = 0 ; i < 4 ; i++) { if (base + i < loadcased -> num_loads) { sprintf (buffer,"%d", loadcased -> element_assignments [base + i]); SetTextString (loadcased -> element [i], buffer); SetTextString (loadcased -> load [i], loadcased -> load_assignments [base + i]); } else { buffer [0] = 0; SetTextString (loadcased -> element [i], buffer); SetTextString (loadcased -> load [i], ""); } } loadcased -> element_base = base; return; } /************************************************************************ * Function: ChangeForceAssignment * * Description: ************************************************************************/ static void ChangeForceAssignment (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { LoadCaseDialog loadcased; Widget current_force; int i; if (!(w = XawSimpleMenuGetActiveEntry (w))) return; loadcased = (LoadCaseDialog) client_data; current_force = GetFocus (loadcased -> name); for (i = 0 ; i < 4 ; i++) if (current_force == loadcased -> force [i]) break; if (i == 4) return; if (!strcmp (XtName (w), "- none -")) SetTextString (current_force, ""); else SetTextString (current_force, GetLabelString (w)); } /************************************************************************ * Function: ChangeLoadAssignment * * Description: ************************************************************************/ static void ChangeLoadAssignment (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { LoadCaseDialog loadcased; Widget current_load; int i; if (!(w = XawSimpleMenuGetActiveEntry (w))) return; loadcased = (LoadCaseDialog) client_data; current_load = GetFocus (loadcased -> name); for (i = 0 ; i < 4 ; i++) if (current_load == loadcased -> load [i]) break; if (i == 4) return; if (!strcmp (XtName (w), "- none -")) SetTextString (current_load, ""); else SetTextString (current_load, GetLabelString (w)); } /************************************************************************ * Function: Change * * * * Description: Changes the displayed values to either the currently * * selected loadcase if the widget is not null, or the * * active loadcase if the widget is null. The newly * * displayed loadcase is made the active loadcase and * * any new/copy operation is canceled. * ************************************************************************/ static void Change (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { char buffer [10]; unsigned i; LoadCase active; struct loadcase dummy; LoadCaseDialog loadcased; XawListReturnStruct *info; loadcased = (LoadCaseDialog) client_data; /* Retrieve the active loadcase from the tree if selected. */ if (w != NULL) { info = (XawListReturnStruct *) call_data; if (info -> list_index == XAW_LIST_NONE) return; dummy.name = info -> string; loadcased -> active = (LoadCase) TreeSearch (loadcased -> tree, &dummy); } active = loadcased -> active; loadcased -> new_copy = False; /* Update all of the entries. */ SetTextString (loadcased -> name, active -> name); loadcased -> node_base = 0; loadcased -> element_base = 0; loadcased -> num_forces = active -> numforces; loadcased -> num_loads = active -> numloads; for (i = 1 ; i <= active -> numforces ; i++) { if (i <= 4) { sprintf (buffer, "%d", active -> nodes [i] -> number); SetTextString (loadcased -> node [i-1], buffer); SetTextString (loadcased -> force [i-1], active -> forces [i] -> name); } loadcased -> node_assignments [i - 1] = active -> nodes [i] -> number; loadcased -> force_assignments [i - 1] = XtNewString (active -> forces [i] -> name); } for (i = 1 ; i <= active -> numloads ; i++) { if (i <= 4) { sprintf (buffer, "%d", active -> elements [i] -> number); SetTextString (loadcased -> element [i-1], buffer); SetTextString (loadcased -> load [i-1], active -> loads [i] -> name); } loadcased -> element_assignments [i - 1] = active -> elements [i] -> number; loadcased -> load_assignments [i - 1] = XtNewString (active -> loads [i] -> name); } } /************************************************************************ * Function: Accept * * * * Description: Accepts changes made to the current loadcase. * * If the name is empty or a duplicate name is given then * * an error is reported. Otherwise, a new loadcase is * * created if a new/copy operation is in effect. The * * loadcase is then redisplayed to correct any invalid * * entries. * ************************************************************************/ static void Accept (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { struct loadcase old; struct loadcase dummy; LoadCase found; LoadCase active; Boolean duplicate; LoadCaseDialog loadcased; struct node n; struct element e; struct force f; struct distributed l; unsigned i; loadcased = (LoadCaseDialog) client_data; /* Retrieve the name of the loadcase. */ dummy.name = GetTextString (loadcased -> name); found = (LoadCase) TreeSearch (loadcased -> tree, &dummy); duplicate = found && (found != loadcased -> active || loadcased -> new_copy); /* Check for a duplicate name. */ if (!dummy.name [0] || duplicate) { XBell (XtDisplay (loadcased -> name), 0); SetFocus (loadcased -> name); if (!loadcased -> new_copy) SetTextString (loadcased -> name, loadcased -> active -> name); else SetTextString (loadcased -> name, ""); } else { /* Create a new loadcase or new name as needed. */ if (loadcased -> new_copy) loadcased -> active = CreateLoadCase (XtNewString (dummy.name)); else if (strcmp (loadcased -> active -> name, dummy.name)) { old.name = loadcased -> active -> name; TreeDelete (loadcased -> tree, &old); XtFree (loadcased -> active -> name); loadcased -> active -> name = XtNewString (dummy.name); TreeInsert (loadcased -> tree, loadcased -> active); } active = loadcased -> active; /* * fill out the actual components of the active load case here */ if (loadcased -> num_forces) { active -> numforces = loadcased -> num_forces; ZeroOffset (active -> nodes); Deallocate (active -> nodes); ZeroOffset (active -> forces); Deallocate (active -> forces); active -> nodes = Allocate(Node, loadcased -> num_forces); active -> forces = Allocate(Force, loadcased -> num_forces); UnitOffset (active -> nodes); UnitOffset (active -> forces); for (i = 1 ; i <= active -> numforces ; i++) { n.number = loadcased -> node_assignments [i-1]; active -> nodes [i] = (Node) TreeSearch (problem.node_tree, &n); if (active -> nodes [i] == NULL) { error ("node %d is not defined", n.number); return; } f.name = loadcased -> force_assignments [i-1]; active -> forces [i] = (Force) TreeSearch (problem.force_tree, &f); if (active -> forces [i] == NULL) { error ("force %s is not defined", f.name); return; } } } if (loadcased -> num_loads) { active -> numloads = loadcased -> num_loads; ZeroOffset (active -> elements); Deallocate (active -> elements); ZeroOffset (active -> loads); Deallocate (active -> loads); active -> elements = Allocate(Element, loadcased -> num_loads); active -> loads = Allocate(Distributed, loadcased -> num_loads); UnitOffset (active -> elements); UnitOffset (active -> loads); for (i = 1 ; i <= active -> numloads ; i++) { e.number = loadcased -> element_assignments [i-1]; active -> elements [i] = (Element) TreeSearch (problem.element_tree, &e); if (active -> elements [i] == NULL) { error ("element %d is not defined", e.number); return; } l.name = loadcased -> load_assignments [i-1]; active -> loads [i] = (Distributed) TreeSearch (problem.distributed_tree, &l); if (active -> loads [i] == NULL) { error ("distributed load %s is not defined", l.name); return; } } } if (loadcased -> new_copy) TreeInsert (loadcased -> tree, loadcased -> active); LoadCaseDialogUpdate (loadcased, loadcased -> tree, NULL, NULL); } } /************************************************************************ * Function: Dismiss * * * * Description: Pops down the dialog box. * ************************************************************************/ static void Dismiss (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { LoadCaseDialog loadcased; loadcased = (LoadCaseDialog) client_data; XtPopdown (loadcased -> shell); } /************************************************************************ * Function: Delete * * * * Description: Deletes the active loadcase if a new/copy operation is * * not in effect. The dialog is then updated. * ************************************************************************/ static void Delete (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { LoadCaseDialog loadcased; loadcased = (LoadCaseDialog) client_data; if (!loadcased -> new_copy) { TreeDelete (loadcased -> tree, loadcased -> active); DestroyLoadCase (loadcased -> active); loadcased -> active = NULL; } LoadCaseDialogUpdate (loadcased, loadcased -> tree, NULL, NULL); } /************************************************************************ * Function: Copy * * * * Description: Clears the name entry only and sets the flag indicating * * that a new/copy operation is in effect. * ************************************************************************/ static void Copy (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { LoadCaseDialog loadcased; loadcased = (LoadCaseDialog) client_data; loadcased -> new_copy = True; SetFocus (loadcased -> name); XawListUnhighlight (loadcased -> list); SetTextString (loadcased -> name, ""); } /************************************************************************ * Function: New * * * * Description: Clears all entries in the loadcase dialog and sets the * * flag indicating that a new/copy operation is in effect. * ************************************************************************/ static void New (w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { LoadCaseDialog loadcased; unsigned i; loadcased = (LoadCaseDialog) client_data; Copy (NULL, client_data, NULL); for (i = 0 ; i < 4 ; i++) { SetTextString (loadcased -> node [i] , ""); SetTextString (loadcased -> element [i], ""); } loadcased -> num_forces = 0; loadcased -> num_loads = 0; loadcased -> node_base = 0; loadcased -> element_base = 0; } /************************************************************************ * Function: LoadCaseDialogCreate * * * * Description: Creates a new loadcase dialog. You would never want to * * have more than one of these but the interface is kept * * consistent with those of the other dialogs. * ************************************************************************/ LoadCaseDialog LoadCaseDialogCreate (parent, name, title) Widget parent; String name; String title; { Window window; Cardinal i; char buffer [128]; Arg args [2]; Widget group [28]; LoadCaseDialog loadcased; Dimension width; Position x; static XtAppContext app_context = NULL; static XtActionsRec actions [ ] = {{"LoadCaseDialogAction", Action}}; /* Perform one time initialization. */ if (app_context == NULL) { app_context = XtWidgetToApplicationContext (parent); XtAppAddActions (app_context, actions, XtNumber (actions)); AddAutoRepeatAction (app_context); layout_args [0].value = StringToLayout (parent, layout_string); text_translations = XtParseTranslationTable (text_table); command_translations = XtParseTranslationTable (command_table); viewport_translations = XtParseTranslationTable (viewport_table); help_translations = XtParseTranslationTable (help_table); repeater_translations = XtParseTranslationTable (repeater_table); button_translations = XtParseTranslationTable (button_table); window = RootWindowOfScreen (XtScreen (parent)); up_bitmap = XCreateBitmapFromData (XtDisplay (parent), window, up_bits, up_width, up_height); down_bitmap = XCreateBitmapFromData (XtDisplay (parent), window, down_bits, down_width, down_height); } /* Create the loadcase dialog and its widgets. */ XtSetArg (shell_args [0], XtNtitle, title); XtSetArg (shell_args [1], XtNiconName, title); loadcased = XtNew (struct loadcase_dialog); loadcased -> loadcases = NULL; loadcased -> active = NULL; loadcased -> shell = XtCreatePopupShell (name, topLevelShellWidgetClass, parent, shell_args, XtNumber (shell_args)); loadcased -> layout = XtCreateManagedWidget ("layout", layoutWidgetClass, loadcased -> shell, layout_args, XtNumber (layout_args)); loadcased -> viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, loadcased -> layout, viewport_args, XtNumber (viewport_args)); loadcased -> list = XtCreateManagedWidget ("list", listWidgetClass, loadcased -> viewport, list_args, XtNumber (list_args)); loadcased -> name = XtCreateManagedWidget ("name", asciiTextWidgetClass, loadcased -> layout, name_args, XtNumber (name_args)); for (i = 0 ; i < 4 ; i++) { sprintf (buffer,"node%d", i+1); loadcased -> node [i] = XtCreateManagedWidget (XtNewString (buffer), asciiTextWidgetClass, loadcased -> layout, number_args, XtNumber (number_args)); sprintf (buffer,"element%d", i+1); loadcased -> element [i] = XtCreateManagedWidget (XtNewString (buffer), asciiTextWidgetClass, loadcased -> layout, number_args, XtNumber (number_args)); sprintf (buffer,"force%d", i+1); loadcased -> force [i] = XtCreateManagedWidget (XtNewString (buffer), asciiTextWidgetClass, loadcased -> layout, name_args, XtNumber (name_args)); sprintf (buffer,"load%d", i+1); loadcased -> load [i] = XtCreateManagedWidget (XtNewString (buffer), asciiTextWidgetClass, loadcased -> layout, name_args, XtNumber (name_args)); } loadcased -> force_menu = XtCreateManagedWidget ("force_menu", simpleMenuWidgetClass, loadcased -> layout, NULL, 0); XtSetArg (button_args [0], XtNlabel, "forces"); XtSetArg (button_args [1], XtNmenuName, "force_menu"); loadcased -> force_button = XtCreateManagedWidget ("force_button", menuButtonWidgetClass, loadcased -> layout, button_args, XtNumber (button_args)); loadcased -> load_menu = XtCreateManagedWidget ("load_menu", simpleMenuWidgetClass, loadcased -> layout, NULL, 0); XtSetArg (button_args [0], XtNlabel, "loads"); XtSetArg (button_args [1], XtNmenuName, "load_menu"); loadcased -> load_button = XtCreateManagedWidget ("load_button", menuButtonWidgetClass, loadcased -> layout, button_args, XtNumber (button_args)); XtCreateManagedWidget ("- none -", smeBSBObjectClass, loadcased -> force_menu, NULL, 0); XtCreateManagedWidget ("- none -", smeBSBObjectClass, loadcased -> load_menu, NULL, 0); AddPostMenuActions (loadcased -> force_menu); AddPostMenuActions (loadcased -> load_menu); repeater_args [0].value = (XtArgVal) down_bitmap; loadcased -> node_down = XtCreateManagedWidget ("node_down", repeaterWidgetClass, loadcased -> layout, repeater_args, XtNumber (repeater_args)); loadcased -> element_down = XtCreateManagedWidget ("element_down", repeaterWidgetClass, loadcased -> layout, repeater_args, XtNumber (repeater_args)); repeater_args [0].value = (XtArgVal) up_bitmap; loadcased -> node_up = XtCreateManagedWidget ("node_up", repeaterWidgetClass, loadcased -> layout, repeater_args, XtNumber (repeater_args)); loadcased -> element_up = XtCreateManagedWidget ("element_up", repeaterWidgetClass, loadcased -> layout, repeater_args, XtNumber (repeater_args)); loadcased -> accept = XtCreateManagedWidget ("accept", commandWidgetClass, loadcased -> layout, NULL, 0); loadcased -> dismiss = XtCreateManagedWidget ("dismiss", commandWidgetClass, loadcased -> layout, NULL, 0); loadcased -> delete = XtCreateManagedWidget ("delete", commandWidgetClass, loadcased -> layout, NULL, 0); loadcased -> new = XtCreateManagedWidget ("new", commandWidgetClass, loadcased -> layout, NULL, 0); loadcased -> copy = XtCreateManagedWidget ("copy", commandWidgetClass, loadcased -> layout, NULL, 0); loadcased -> help = CreateHelpButton (loadcased -> layout, "help"); for (i = 0; i < XtNumber (labels); i ++) { label_args [0].value = (XtArgVal) labels [i]; XtCreateManagedWidget (names [i], labelWidgetClass, loadcased -> layout, label_args, XtNumber (label_args)); } XtCreateManagedWidget ("separator1", coreWidgetClass, loadcased -> layout, core_args, XtNumber (core_args)); XtCreateManagedWidget ("separator2", coreWidgetClass, loadcased -> layout, core_args, XtNumber (core_args)); XtCreateManagedWidget ("separator3", coreWidgetClass, loadcased -> layout, core_args, XtNumber (core_args)); /* Create a tab group for the loadcase dialog. */ i = 0; group [i++] = loadcased -> name; group [i++] = loadcased -> viewport; group [i++] = loadcased -> node[0]; group [i++] = loadcased -> force[0]; group [i++] = loadcased -> node[1]; group [i++] = loadcased -> force[1]; group [i++] = loadcased -> node[2]; group [i++] = loadcased -> force[2]; group [i++] = loadcased -> node[3]; group [i++] = loadcased -> force[3]; group [i++] = loadcased -> node_down; group [i++] = loadcased -> node_up; group [i++] = loadcased -> element[0]; group [i++] = loadcased -> load[0]; group [i++] = loadcased -> element[1]; group [i++] = loadcased -> load[1]; group [i++] = loadcased -> element[2]; group [i++] = loadcased -> load[2]; group [i++] = loadcased -> element[3]; group [i++] = loadcased -> load[3]; group [i++] = loadcased -> element_down; group [i++] = loadcased -> element_up; group [i++] = loadcased -> help; group [i++] = loadcased -> accept; group [i++] = loadcased -> dismiss; group [i++] = loadcased -> delete; group [i++] = loadcased -> new; group [i++] = loadcased -> copy; XtGetValues (loadcased -> layout, color_args, XtNumber (color_args)); CreateTabGroup (loadcased -> shell, group, XtNumber (group), highlight, True); XtRealizeWidget (loadcased -> shell); SetFocus (loadcased -> name); XtSetArg (args [0], XtNwidth, &width); XtGetValues (loadcased -> layout, args, 1); XtSetArg (args [0], XtNx, &x); XtGetValues (loadcased -> help, args, 1); UpdateHelpMessage (loadcased -> help, help_message, width - 2 * x); /* Add the translations to each widget. */ AddDeleteWindowProtocol (loadcased -> shell, "LoadCaseDialogAction()"); ListAddCursorTranslations (loadcased -> viewport); XtOverrideTranslations (loadcased -> name, text_translations); XtOverrideTranslations (loadcased -> node[0], text_translations); XtOverrideTranslations (loadcased -> node[1], text_translations); XtOverrideTranslations (loadcased -> node[2], text_translations); XtOverrideTranslations (loadcased -> node[3], text_translations); XtOverrideTranslations (loadcased -> force[0], text_translations); XtOverrideTranslations (loadcased -> force[1], text_translations); XtOverrideTranslations (loadcased -> force[2], text_translations); XtOverrideTranslations (loadcased -> force[3], text_translations); XtOverrideTranslations (loadcased -> element[0], text_translations); XtOverrideTranslations (loadcased -> element[1], text_translations); XtOverrideTranslations (loadcased -> element[2], text_translations); XtOverrideTranslations (loadcased -> element[3], text_translations); XtOverrideTranslations (loadcased -> load[0], text_translations); XtOverrideTranslations (loadcased -> load[1], text_translations); XtOverrideTranslations (loadcased -> load[2], text_translations); XtOverrideTranslations (loadcased -> load[3], text_translations); XtOverrideTranslations (loadcased -> force_button, button_translations); XtOverrideTranslations (loadcased -> load_button, button_translations); XtOverrideTranslations (loadcased -> element_up, repeater_translations); XtOverrideTranslations (loadcased -> element_down, repeater_translations); XtOverrideTranslations (loadcased -> node_up, repeater_translations); XtOverrideTranslations (loadcased -> node_down, repeater_translations); XtOverrideTranslations (loadcased -> accept, command_translations); XtOverrideTranslations (loadcased -> dismiss, command_translations); XtOverrideTranslations (loadcased -> delete, command_translations); XtOverrideTranslations (loadcased -> new, command_translations); XtOverrideTranslations (loadcased -> copy, command_translations); XtOverrideTranslations (loadcased -> viewport, viewport_translations); XtOverrideTranslations (loadcased -> help, help_translations); /* Add the necessary callbacks. */ XtAddCallback (loadcased -> list, XtNcallback, Change, (XtPointer) loadcased); XtAddCallback (loadcased -> accept, XtNcallback, Accept, (XtPointer) loadcased); XtAddCallback (loadcased -> dismiss, XtNcallback, Dismiss, (XtPointer) loadcased); XtAddCallback (loadcased -> delete, XtNcallback, Delete, (XtPointer) loadcased); XtAddCallback (loadcased -> new, XtNcallback, New, (XtPointer) loadcased); XtAddCallback (loadcased -> copy, XtNcallback, Copy, (XtPointer) loadcased); XtAddCallback (loadcased -> node_up, XtNcallback, ScrollNode, (XtPointer) loadcased); XtAddCallback (loadcased -> node_down, XtNcallback, ScrollNode, (XtPointer) loadcased); XtAddCallback (loadcased -> element_up, XtNcallback, ScrollElement, (XtPointer) loadcased); XtAddCallback (loadcased -> element_down, XtNcallback, ScrollElement, (XtPointer) loadcased); XtAddCallback (loadcased -> force_menu, XtNpopdownCallback, ChangeForceAssignment, (XtPointer) loadcased); XtAddCallback (loadcased -> load_menu, XtNpopdownCallback, ChangeLoadAssignment, (XtPointer) loadcased); loadcased -> node_base = 0; loadcased -> element_base = 0; loadcased -> num_forces = 0; loadcased -> num_loads = 0; return loadcased; } /************************************************************************ * Function: LoadCaseDialogPopup * * * * Description: Pops up the specified loadcase dialog. * ************************************************************************/ void LoadCaseDialogPopup (loadcased) LoadCaseDialog loadcased; { XtPopup (loadcased -> shell, XtGrabNone); } /************************************************************************ * Function: LoadCaseDialogActive * * * * Description: Returns the currently active loadcase. * ************************************************************************/ LoadCase LoadCaseDialogActive (loadcased) LoadCaseDialog loadcased; { return loadcased -> active; } /************************************************************************ * Function: LoadCaseDialogDisplay * * * * Description: Displays a specified loadcase. * ************************************************************************/ void LoadCaseDialogDisplay (loadcased, loadcase) LoadCaseDialog loadcased; LoadCase loadcase; { loadcased -> active = loadcase; LoadCaseDialogUpdate (loadcased, loadcased -> tree, NULL, NULL); } /* Menu creation variables */ static Cardinal child_number; static WidgetList children; static Dimension max_width; static XtWidgetGeometry preferred; /************************************************************************ * Function: SetForceEntry * * * * Description: Sets the label of the next menu entry to the name of * * the specified force. * ************************************************************************/ static int SetForceEntry (item) Item item; { SetLabelString (children [child_number], ((Force) item) -> name); XtQueryGeometry (children [child_number ++], NULL, &preferred); if (preferred.width > max_width) max_width = preferred.width; return 0; } /************************************************************************ * Function: SetLoadEntry * * * * Description: Sets the label of the next menu entry to the name of * * the specified load. * ************************************************************************/ static int SetLoadEntry (item) Item item; { SetLabelString (children [child_number], ((Distributed) item) -> name); XtQueryGeometry (children [child_number ++], NULL, &preferred); if (preferred.width > max_width) max_width = preferred.width; return 0; } /************************************************************************ * Function: LoadCaseDialogUpdate * * * * Description: Updates the given loadcase dialog with the specified * * tree. If no active loadcase exists, the first loadcase * * is made active. If no active loadcase still exists * * then a new operation is performed. Otherwise a change * * operation is performed to display the active values. * ************************************************************************/ void LoadCaseDialogUpdate (loadcased, tree, force_tree, load_tree) LoadCaseDialog loadcased; Tree tree; Tree force_tree; Tree load_tree; { char buffer [32]; Arg args [2]; Cardinal nbytes; Cardinal num_forces; Cardinal num_loads; Cardinal num_children; Cardinal i; Cardinal overflow; /* Determine a new active loadcase if necessary. */ if (tree == NULL) tree = loadcased -> tree; if (loadcased -> active == NULL || tree != loadcased -> tree) loadcased -> active = (LoadCase) TreeMinimum (tree); /* Construct the array of loadcase names. */ num_loadcases = 0; list_index = -1; dialog = loadcased; loadcased -> tree = tree; loadcased -> new_copy = False; nbytes = (TreeSize (loadcased -> tree) + 1) * sizeof (String); loadcased -> loadcases = (String *) XtRealloc ((char *) loadcased -> loadcases, nbytes); TreeSetIterator (loadcased -> tree, AppendLoadCaseName); TreeIterate (loadcased -> tree); loadcased -> loadcases [num_loadcases] = NULL; /* Update the list widget. */ XawListChange (loadcased -> list, loadcased -> loadcases, 0, 0, True); if (list_index >= 0) XawListHighlight (loadcased -> list, list_index); /* Update the force menu */ if (force_tree != NULL) { XtSetArg (args [0], XtNchildren, &children); XtSetArg (args [1], XtNnumChildren, &num_children); XtGetValues (loadcased -> force_menu, args, 2); num_forces = TreeSize (force_tree) + 1; for (i = num_children; i < num_forces; i ++) { sprintf (buffer, "force_entry%d", i); XtCreateManagedWidget (XtNewString (buffer), smeBSBObjectClass, loadcased -> force_menu, NULL, 0); } if (num_children > num_forces) { overflow = num_children - num_forces; XtUnmanageChildren (children + num_forces, overflow); } XtSetArg (args [0], XtNchildren, &children); XtSetArg (args [1], XtNnumChildren, &num_children); XtGetValues (loadcased -> force_menu, args, 2); XtQueryGeometry (children [0], NULL, &preferred); max_width = preferred.width; child_number = 1; TreeSetIterator (force_tree, SetForceEntry); TreeIterate (force_tree); XtSetArg (args [0], XtNwidth, max_width); XtSetValues (loadcased -> force_menu, args, 1); } /* Update the load menu */ if (load_tree != NULL) { XtSetArg (args [0], XtNchildren, &children); XtSetArg (args [1], XtNnumChildren, &num_children); XtGetValues (loadcased -> load_menu, args, 2); num_loads = TreeSize (load_tree) + 1; for (i = num_children; i < num_loads; i ++) { sprintf (buffer, "load_entry%d", i); XtCreateManagedWidget (XtNewString (buffer), smeBSBObjectClass, loadcased -> load_menu, NULL, 0); } if (num_children > num_loads) { overflow = num_children - num_loads; XtUnmanageChildren (children + num_loads, overflow); } XtSetArg (args [0], XtNchildren, &children); XtSetArg (args [1], XtNnumChildren, &num_children); XtGetValues (loadcased -> load_menu, args, 2); XtQueryGeometry (children [0], NULL, &preferred); max_width = preferred.width; child_number = 1; TreeSetIterator (load_tree, SetLoadEntry); TreeIterate (load_tree); XtSetArg (args [0], XtNwidth, max_width); XtSetValues (loadcased -> load_menu, args, 1); } /* Update the text entries. */ if (loadcased -> active == NULL) New (NULL, (XtPointer) loadcased, NULL); else Change (NULL, (XtPointer) loadcased, NULL); }