Logo Search packages:      
Sourcecode: felt version File versions  Download package

element.c

/*
    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:    element.c                                 *
 *                                                    *
 * Description:   This file contains the public and private function and      *
 *          definitions for the element dialog box.               *
 ************************************************************************/

# include <stdio.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <X11/Shell.h>
# include <X11/Xaw/AsciiText.h>
# include <X11/Xaw/Command.h>
# include <X11/Xaw/MenuButton.h>
# include <X11/Xaw/Repeater.h>
# include <X11/Xaw/SimpleMenu.h>
# include <X11/Xaw/SmeBSB.h>
# include <X11/Xaw/Viewport.h>
# include "Layout.h"
# include "Element.h"
# include "TabGroup.h"
# include "util.h"
# include "objects.h"
# include "post.h"
# include "problem.h"
# include "error.h"
# include "definition.h"

# ifndef X_NOT_STDC_ENV
# include <stdlib.h>
# else
extern int atoi ( );
# endif

struct element_dialog {
    Widget     shell;   /* topLevelShell  <specified>       */
    Widget     layout;  /*    Layout  layout                */
    Widget     number;  /*         Label  number            */
    Widget     type;    /*         Label  type        */
    Widget     up;            /*         Repeater  up       */
    Widget     down;    /*         Repeater  down           */
    Widget     left;    /*         Command  left            */
    Widget     right;   /*         Command  right           */
    Widget     node [6];      /*         AsciiText  node[1-6]     */
    Widget     m_name;  /*         AsciiText  materialName  */
    Widget     m_button;      /*         MenuButton  materialButton     */
    Widget     m_menu;  /*         SimpleMenu  materialMenu */
    Widget     l_name [3];    /*         AsciiText  load[1-3]Name */
    Widget     l_button [3];/*           MenuButton  load[1-3Button     */
    Widget     l_menu;  /*         SimpleMenu  loadMenu     */
    Widget     viewport;      /*         Viewport  viewport       */
    Widget     stresses;      /*            Label  stresses */
    Widget     help;    /*         MenuButton  help         */
    Widget     accept;  /*         Command  accept          */
    Widget     dismiss; /*         Command  dismiss         */
    Widget     delete;  /*         Command  delete          */
    Widget     new;           /*         Command  new       */
    Widget     copy;    /*         Command  copy            */
    XtCallbackProc callback;
    XtPointer        closure;
    unsigned         offset;
    unsigned         new_copy;
    Boolean    new_materials;
    Boolean    new_loads;
    Definition       definition;
    Element    active;
    unsigned         node_values [32];
    Tree       elements;
    Tree           materials;
    Tree           loads;
    Tree           nodes;
};

static String labels [ ] = {
    "Number:", "Type:", "Nodes:", "Stresses"
};

static String names [ ] = {
    "numberLabel", "typeLabel", "nodes", "stressLabel"
};


/* 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};

#define left_width 12
#define left_height 12
static char left_bits[] = {
   0x00, 0x00, 0x80, 0x01, 0xc0, 0x01, 0xe0, 0x01, 0xf0, 0x01, 0xf8, 0x01,
   0xf8, 0x01, 0xf0, 0x01, 0xe0, 0x01, 0xc0, 0x01, 0x80, 0x01, 0x00, 0x00};

#define right_width 12
#define right_height 12
static char right_bits[] = {
   0x00, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xf8, 0x01,
   0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0x38, 0x00, 0x18, 0x00, 0x00, 0x00};

static Pixmap up_bitmap;
static Pixmap down_bitmap;
static Pixmap left_bitmap;
static Pixmap right_bitmap;


/* Resources */

static Pixel highlight;

static String layout_string = "\
vertical { \
    4 \
    horizontal { \
      4 \
      up \
      4 \
      down \
      4 \
      numberLabel \
      4 \
      number \
      40 \
      typeLabel \
      4 \
      type \
      4 <+inf -100%> \
    } \
    4 \
    separator1 <+inf -100% *> \
    4 \
    horizontal { \
      4 \
      left \
      4 \
      right \
      4 \
      nodes \
      4 \
      node1 \
      node2 \
      node3 \
      node4 \
      node5 \
      node6 \
      4 <+inf -100%> \
    } \
    4 \
    separator2 <+inf -100% *> \
    4 \
    vertical { \
      horizontal { \
          4 \
          materialButton 4 materialName <+inf -100% *> 4 \
          load2Button 4 load2Name <+inf -100% *> 4 \
      } \
      4 \
      horizontal { \
          4 \
          load1Button 4 load1Name <+inf -100% *> 4 \
          load3Button 4 load3Name <+inf -100% *> 4 \
      } \
    } \
    4 \
    separator3 <+inf -100% *> \
    4 \
    horizontal { \
      4 \
      stressLabel \
      4 <+inf -100%> \
    } \
    4 \
    horizontal { \
      4 \
      viewport <+inf -100% * +inf -100%> \
      4 \
    } \
    4 \
    separator4 <+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 edit_text_args [ ] = {
    {XtNeditType,    (XtArgVal) XawtextEdit},
    {XtNborderWidth, (XtArgVal) 0},
    {XtNpieceSize,   (XtArgVal) 32},
    {XtNcursorName,  (XtArgVal) "left_ptr"},
};

static Arg node_args [ ] = {
    {XtNeditType,    (XtArgVal) XawtextEdit},
    {XtNborderWidth, (XtArgVal) 0},
    {XtNpieceSize,   (XtArgVal) 32},
    {XtNcursorName,  (XtArgVal) "left_ptr"},
    {XtNwidth,       (XtArgVal) 40},
};

static Arg stress_args [ ] = {
    {XtNresize,      (XtArgVal) True},
    {XtNjustify,     (XtArgVal) XtJustifyLeft},
    {XtNborderWidth, (XtArgVal) 0},
};

static Arg viewport_args [ ] = {
    {XtNallowVert,   (XtArgVal) True},
    {XtNallowHoriz,  (XtArgVal) True},
    {XtNuseBottom,   (XtArgVal) True},
    {XtNuseRight,    (XtArgVal) True},
    {XtNforceBars,   (XtArgVal) False},
    {XtNborderWidth, (XtArgVal) 0},
};

static Arg button_args [ ] = {
    {XtNlabel,       (XtArgVal) ""},
    {XtNmenuName,    (XtArgVal) ""},
    {XtNborderWidth, (XtArgVal) 0},
    {XtNresize,      (XtArgVal) False},
};

static Arg number_args [ ] = {
    {XtNlabel,       (XtArgVal) ""},
    {XtNresize,      (XtArgVal) True},
    {XtNborderWidth, (XtArgVal) 0},
};

static Arg label_args [ ] = {
    {XtNlabel,       (XtArgVal) ""},
    {XtNborderWidth, (XtArgVal) 0},
};

static Arg core_args [ ] = {
    {XtNwidth,  (XtArgVal) 3},
    {XtNheight, (XtArgVal) 3},
};

static Arg bitmap_args [ ] = {
    {XtNbitmap, (XtArgVal) NULL},
};


/* Translation tables */

static String text_table =
"<Key>Return: ElementDialogAction(accept)\n\
 <Key>Escape: ElementDialogAction(dismiss)\n\
 Ctrl<Key>d:  ElementDialogAction(delete)\n\
 Ctrl<Key>c:  ElementDialogAction(copy)\n\
 Ctrl<Key>n:  ElementDialogAction(new)\n\
 Ctrl<Key>h:  ElementDialogAction(help)\n\
 <Btn1Down>:  SetFocus() select-start()";

static XtTranslations text_translations;


static String command_table =
"<Key>Return:  ElementDialogAction(accept)\n\
 <Key>Escape:  ElementDialogAction(dismiss)\n\
 Ctrl<Key>d:   ElementDialogAction(delete)\n\
 Ctrl<Key>c:   ElementDialogAction(copy)\n\
 Ctrl<Key>n:   ElementDialogAction(new)\n\
 Ctrl<Key>h:   ElementDialogAction(help)\n\
 <Key>space:   AutoRepeat(off) set()\n\
 <KeyUp>space: AutoRepeat(saved) notify() unset()";

static XtTranslations command_translations;


static String button_table =
"<Key>Return: ElementDialogAction(accept)\n\
 <Key>Escape: ElementDialogAction(dismiss)\n\
 Ctrl<Key>d:  ElementDialogAction(delete)\n\
 Ctrl<Key>c:  ElementDialogAction(copy)\n\
 Ctrl<Key>n:  ElementDialogAction(new)\n\
 Ctrl<Key>h:  ElementDialogAction(help)\n\
 <BtnDown>:   ElementDialogMenu() PostMenu()\n\
 <Key>space:  ElementDialogMenu() PostMenu()";

static XtTranslations button_translations;


static String repeater_table =
"<Key>Return:  ElementDialogAction(accept)\n\
 <Key>Escape:  ElementDialogAction(dismiss)\n\
 Ctrl<Key>d:   ElementDialogAction(delete)\n\
 Ctrl<Key>c:   ElementDialogAction(copy)\n\
 Ctrl<Key>n:   ElementDialogAction(new)\n\
 Ctrl<Key>h:   ElementDialogAction(help)\n\
 <Key>space:   AutoRepeat(off) set()\n\
 <KeyUp>space: AutoRepeat(saved) notify() unset()";

static XtTranslations repeater_translations;


static String viewport_table =
"<Key>Return: ElementDialogAction(accept)\n\
 <Key>Escape: ElementDialogAction(dismiss)\n\
 Ctrl<Key>d:  ElementDialogAction(delete)\n\
 Ctrl<Key>c:  ElementDialogAction(copy)\n\
 Ctrl<Key>n:  ElementDialogAction(new)\n\
 Ctrl<Key>h:  ElementDialogAction(help)\n\
 <Btn1Down>:  SetFocus()";

static XtTranslations viewport_translations;


static String help_table =
"<Key>Return: ElementDialogAction(accept)\n\
 <Key>Escape: ElementDialogAction(dismiss)\n\
 Ctrl<Key>d:  ElementDialogAction(delete)\n\
 Ctrl<Key>c:  ElementDialogAction(copy)\n\
 Ctrl<Key>n:  ElementDialogAction(new)\n\
 Ctrl<Key>h:  ElementDialogAction(help)\n\
 <Key>space:  PostMenu()";

static XtTranslations help_translations;


/* Help message. */

static String help_message = "\
The element form is used to define, edit and delete elements.  Elements can \
also be selected by using the drawing area.  Use the arrows to change \
the current element.  The menus and fields above define the behavior of the \
current element.  Use the 'Accept' button to register your changes.  'Delete' \
erases the current element.  'New' empties all fields creating a new element.  \
'Copy' creates a new element without changing any fields.";


/* Menu creation variables */

static Cardinal         child_number;
static WidgetList children;
static Dimension  max_width;
static XtWidgetGeometry preferred;
static Widget           menu_button;


/************************************************************************
 * 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:      UpdateLoadMenu                                  *
 *                                                    *
 * Description:   Updates the load menu on popup if necessary to the list     *
 *          of current loads.                         *
 ************************************************************************/

static void UpdateLoadMenu (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    Arg             args [2];
    char      buffer [32];
    Cardinal        overflow;
    Cardinal        num_loads;
    Cardinal        i;
    Cardinal        num_children;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    if (eltd -> new_loads == False)
      return;

    XtSetArg (args [0], XtNchildren,    &children);
    XtSetArg (args [1], XtNnumChildren, &num_children);
    XtGetValues (w, args, 2);

    num_loads = TreeSize (eltd -> loads) + 1;

    for (i = num_children; i < num_loads; i ++) {
      sprintf (buffer, "load%d", i);
      XtCreateManagedWidget (XtNewString (buffer), smeBSBObjectClass,
                         eltd -> l_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 (w, args, 2);

    XtQueryGeometry (children [0], NULL, &preferred);
    max_width = preferred.width;

    child_number = 1;
    TreeSetIterator (eltd -> loads, SetLoadEntry);
    TreeIterate (eltd -> loads);
    eltd -> new_loads = False;

    XtSetArg (args [0], XtNwidth, max_width);
    XtSetValues (w, args, 1);
}


/************************************************************************
 * Function:      UpdateLoadName                                  *
 *                                                    *
 * Description:   Updates the load name on popdown if necessary.        *
 ************************************************************************/

static void UpdateLoadName (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    Cardinal        i;
    Widget    name;
    ElementDialog eltd;


    if (!(w = XawSimpleMenuGetActiveEntry (w)))
      return;

    name = NULL;
    eltd = (ElementDialog) client_data;

    for (i = 0; i < 3; i ++)
      if (menu_button == eltd -> l_button [i]) {
          name = eltd -> l_name [i];
          break;
      }

    if (!strcmp (XtName (w), "- none -"))
      SetTextString (name, "");
    else
      SetTextString (name, GetLabelString (w));
}


/************************************************************************
 * Function:      SetMaterialEntry                          *
 *                                                    *
 * Description:   Sets the label of the next menu entry to the name of  *
 *          the specified material.                         *
 ************************************************************************/

static int SetMaterialEntry (item)
    Item item;
{
    SetLabelString (children [child_number], ((Material) item) -> name);

    XtQueryGeometry (children [child_number ++], NULL, &preferred);
    if (preferred.width > max_width)
      max_width = preferred.width;

    return 0;
}


/************************************************************************
 * Function:      UpdateMaterialMenu                              *
 *                                                    *
 * Description:   Updates the material menu on popup if necessary to the      *
 *          list of current materials.                      *
 ************************************************************************/

static void UpdateMaterialMenu (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    Arg             args [2];
    char      buffer [32];
    Cardinal        overflow;
    Cardinal        num_materials;
    Cardinal        i;
    Cardinal        num_children;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    if (eltd -> new_materials == False)
      return;

    XtSetArg (args [0], XtNchildren,    &children);
    XtSetArg (args [1], XtNnumChildren, &num_children);
    XtGetValues (w, args, 2);

    num_materials = TreeSize (eltd -> materials);

    if (num_materials <= 0) {
      num_materials ++;
      SetLabelString (children [0], "- no materials defined -");
      XtQueryGeometry (children [0], NULL, &preferred);
      max_width = preferred.width;
    } else
      max_width = 0;

    for (i = num_children; i < num_materials; i ++) {
      sprintf (buffer, "material%d", i);
      XtCreateManagedWidget (XtNewString (buffer), smeBSBObjectClass,
                         eltd -> m_menu, NULL, 0);
    }

    if (num_children > num_materials) {
      overflow = num_children - num_materials;
      XtUnmanageChildren (children + num_materials, overflow);
    }

    XtSetArg (args [0], XtNchildren,    &children);
    XtSetArg (args [1], XtNnumChildren, &num_children);
    XtGetValues (w, args, 2);

    child_number = 0;
    TreeSetIterator (eltd -> materials, SetMaterialEntry);
    TreeIterate (eltd -> materials);

    XtSetArg (args [0], XtNwidth, max_width);
    XtSetValues (w, args, 1);
}


/************************************************************************
 * Function:      UpdateMaterialName                              *
 *                                                    *
 * Description:   Updates the material name on popdown if necessary.    *
 ************************************************************************/

static void UpdateMaterialName (w, client_data, call_data)
    Widget    w;
    XtPointer call_data;
    XtPointer client_data;
{
    String    label;
    ElementDialog eltd;


    if (!(w = XawSimpleMenuGetActiveEntry (w)))
      return;

    eltd = (ElementDialog) client_data;
    label = GetLabelString (w);

    if (!strcmp (label, "- no materials defined -"))
      SetTextString (eltd -> m_name, "");
    else
      SetTextString (eltd -> m_name, label);
}


/************************************************************************
 * Function:      SetNumber                                 *
 *                                                    *
 * Description:   Sets the label of the number widget.                  *
 ************************************************************************/

static void SetNumber (eltd, number)
    ElementDialog eltd;
    unsigned        number;
{
    char buffer [10];


    sprintf (buffer, "%u", number);
    SetLabelString (eltd -> number, buffer);
}


/************************************************************************
 * Function:      SetType                                         *
 *                                                    *
 * Description:   Sets the label of the type widget.              *
 ************************************************************************/

static void SetType (eltd, defn)
    ElementDialog eltd;
    Definition      defn;
{
    Cardinal i;
    unsigned numnodes;


    SetLabelString (eltd -> type, defn -> name);

    eltd -> offset = 0;
    eltd -> definition = defn;
    numnodes = eltd -> definition -> numnodes;

    if (numnodes >= 6)
      numnodes = 6;

    for (i = 0; i < numnodes; i ++)
      if (!XtIsSensitive (eltd -> node [i]))
          XtSetSensitive (eltd -> node [i], True);

    for (i = numnodes; i < 6; i ++) {
      SetTextString (eltd -> node [i], "");
      if (HasFocus (eltd -> node [i]))
          SetFocus (eltd -> node [numnodes - 1]);
      if (XtIsSensitive (eltd -> node [i]))
          XtSetSensitive (eltd -> node [i], False);
    }
}


/************************************************************************
 * Function:      DisplayNodes                                    *
 *                                                    *
 * Description:   Displays the node array.                        *
 ************************************************************************/

static void DisplayNodes (eltd)
    ElementDialog eltd;
{
    Cardinal i;
    Cardinal j;
    unsigned numnodes;
    char     buffer [32];


    numnodes = eltd -> definition -> numnodes;

    if (numnodes > 6)
      numnodes = 6;

    for (i = 0, j = eltd -> offset; i < numnodes; i ++, j ++)
      if (eltd -> node_values [j]) {
          sprintf (buffer, "%u", eltd -> node_values [j]);
          SetTextString (eltd -> node [i], buffer);
      } else
          SetTextString (eltd -> node [i], "");
}


/************************************************************************
 * Function:      RetrieveNodes                                   *
 *                                                    *
 * Description:   Retrieves the displayed nodes.                        *
 ************************************************************************/

static void RetrieveNodes (eltd)
    ElementDialog eltd;
{
    Cardinal i;
    Cardinal j;
    unsigned numnodes;

    numnodes = eltd -> definition -> numnodes;

    if (numnodes > 6)
      numnodes = 6;

    for (i = 0, j = eltd -> offset; i < numnodes; i ++, j ++)
      eltd -> node_values [j] = atoi (GetTextString (eltd -> node [i]));
}


/************************************************************************
 * Function:      Menu                                      *
 *                                                    *
 * Description:   Records the menu button which activated the menu.     *
 ************************************************************************/

static void Menu (w, event, params, num_params)
    Widget    w;
    XEvent   *event;
    String   *params;
    Cardinal *num_params;
{
    menu_button = w;
}


/************************************************************************
 * Function:      Action                                          *
 *                                                    *
 * Description:   An action procedure which emulates the 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:      Up                                        *
 *                                                    *
 * Description:   Displays the next highest numbered element.           *
 ************************************************************************/

static void Up (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    Element   element;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    if (eltd -> active == NULL)
      return;

    element = (Element) TreeSuccessor (eltd -> elements, eltd -> active);

    if (element != NULL)
      ElementDialogDisplay (eltd, element);
}


/************************************************************************
 * Function:      Down                                      *
 *                                                    *
 * Description:   Displays the next lowest numbered element.            *
 ************************************************************************/

static void Down (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    Element   element;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    if (eltd -> active == NULL)
      return;

    element = (Element) TreePredecessor (eltd -> elements, eltd -> active);

    if (element != NULL)
      ElementDialogDisplay (eltd, element);
}


/************************************************************************
 * Function:      Left                                      *
 *                                                    *
 * Description:   Shifts the list of displayed nodes to the right.      *
 ************************************************************************/

static void Left (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    unsigned        numnodes;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    numnodes = eltd -> definition -> numnodes;

    if (numnodes > 6 && eltd -> offset > 0) {
      RetrieveNodes (eltd);
      eltd -> offset --;
      DisplayNodes (eltd);
    }
}


/************************************************************************
 * Function:      Right                                     *
 *                                                    *
 * Description:   Shifts the list of displayed nodes to the left.       *
 ************************************************************************/

static void Right (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    unsigned        numnodes;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    numnodes = eltd -> definition -> numnodes;

    if (numnodes > 6 && eltd -> offset < numnodes - 6) {
      RetrieveNodes (eltd);
      eltd -> offset ++;
      DisplayNodes (eltd);
    }
}


/************************************************************************
 * Function:      Accept                                          *
 *                                                    *
 * Description:   Accepts changes made to the currently displayed       *
 *          element.  If the material is empty or the material or *
 *          or a load does not exist then an error is reported.   *
 *          Otherwise, a new element is created if a new/copy     *
 *          operation is in effect.  The element is then          *
 *          redisplayed to correct any invalid entries.           *
 ************************************************************************/

static void Accept (w, client_data, call_data)
    Widget    w;
    XtPointer client_data;
    XtPointer call_data;
{
    Cardinal             i;
    unsigned             numnodes;
    unsigned             shapenodes;
    Material             material;
    Distributed          load;
    struct element     original;
    struct distributed l_dummy;
    struct material    m_dummy;
    struct node          n_dummy;
    Element        active;
    ElementDialog      eltd;
    ElementDialogInfo  info;
    Node           node;
    Node           nodes [32];
    Node           original_nodes [32];


    eltd = (ElementDialog) client_data;


    /* Copy the original element if necessary. */

    if (eltd -> active != NULL) {
      original = *eltd -> active;
      original.node = original_nodes;
      for (i = 1; i <= eltd -> definition -> numnodes; i ++)
          original_nodes [i] = eltd -> active -> node [i];
    }


    /* Retrieve the material. */

    m_dummy.name = GetTextString (eltd -> m_name);
    material = (Material) TreeSearch (eltd -> materials, &m_dummy);
    if (material == NULL) {
      XBell (XtDisplay (eltd -> shell), 0);
      SetTextString (eltd -> m_name, "");
      SetFocus (eltd -> m_name);
      return;
    }


    /* Retrieve the nodes. */

    numnodes = eltd -> definition -> numnodes;
    shapenodes = eltd -> definition -> shapenodes;

    RetrieveNodes (eltd);

    for (i = 0; i < numnodes; i ++) {
      n_dummy.number = eltd -> node_values [i];
      if (n_dummy.number == 0) {
          if (i < shapenodes) {
            if (i < eltd -> offset) {
                eltd -> offset = i;
                DisplayNodes (eltd);
            } else if (i >= eltd -> offset + 6) {
                eltd -> offset = i - 5;
                DisplayNodes (eltd);
            }

            XBell (XtDisplay (eltd -> shell), 0);
            SetTextString (eltd -> node [i], "");
            SetFocus (eltd -> node [i]);
            return;
          }
          nodes [i] = NULL;

      } else {
          node = (Node) TreeSearch (eltd -> nodes, &n_dummy);
          if (node == NULL) {
            if (i < eltd -> offset) {
                eltd -> offset = i;
                DisplayNodes (eltd);
            } else if (i >= eltd -> offset + 6) {
                eltd -> offset = i - 5;
                DisplayNodes (eltd);
            }

            XBell (XtDisplay (eltd -> shell), 0);
            SetTextString (eltd -> node [i], "");
            SetFocus (eltd -> node [i]);
            return;
          }
          nodes [i] = node;
      }
    }


    /* Create a new element as needed. */

    if (eltd -> new_copy) {
      eltd -> active = CreateElement (eltd -> new_copy, eltd -> definition);
      TreeInsert (eltd -> elements, eltd -> active);
    }

    active = eltd -> active;
    active -> material = material;


    /* Retrieve the loads. */

    active -> numdistributed = 0;
    for (i = 0; i < 3; i ++) {
      l_dummy.name = GetTextString (eltd -> l_name [i]);
      load = (Distributed) TreeSearch (eltd -> loads, &l_dummy);
      if (load != NULL)
          active -> distributed [++ active -> numdistributed] = load;
    }

    for (i = active -> numdistributed + 1; i <= 3; i ++)
      active -> distributed [i] = NULL;


    /* Copy the nodes. */

    for (i = 0; i < numnodes; i ++)
      active -> node [i + 1] = nodes [i];

    if (eltd -> callback != NULL) {
      info.dialog   = eltd;
      info.element  = active;
      info.deleted  = False;
      info.proceed  = True;
      info.original = &original;
      eltd -> callback (eltd -> shell, eltd -> closure, &info);
    }

    ElementDialogUpdate (eltd, eltd -> elements, NULL, 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;
{
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;
    XtPopdown (eltd -> shell);
}


/************************************************************************
 * Function:      Delete                                          *
 *                                                    *
 * Description:   Deletes the active element 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;
{
    Element       active;
    Element       element;
    ElementDialog     eltd;
    ElementDialogInfo info;


    eltd = (ElementDialog) client_data;

    if (!eltd -> new_copy) {
      if (eltd -> callback) {
          w = eltd -> shell;
          info.dialog  = eltd;
          info.element = eltd -> active;
          info.deleted = True;
          info.proceed = True;
          eltd -> callback (w, eltd -> closure, &info);
          if (info.proceed == False)
            return;
      }

      active = eltd -> active;

      if (!(element = (Element) TreePredecessor (eltd -> elements, active)))
          element = (Element) TreeSuccessor (eltd -> elements, active);

      TreeDelete (eltd -> elements, active);
      DestroyElement (active);
      eltd -> active = element;
    }

    ElementDialogUpdate (eltd, eltd -> elements, NULL, NULL, NULL);
}



/************************************************************************
 * Function:      Copy                                      *
 *                                                    *
 * Description:   Selects a new element number, clears the stresses,    *
 *          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;
{
    Element   element;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    element = (Element) TreeMaximum (eltd -> elements);
    eltd -> new_copy = element != NULL ? element -> number + 1 : 1;

    SetNumber (eltd, eltd -> new_copy);
    SetLabelString (eltd -> stresses, "");
}


/************************************************************************
 * Function:      New                                       *
 *                                                    *
 * Description:   Selects a new element number, clears all entries in the     *
 *          element 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;
{
    Cardinal        i;
    unsigned        numnodes;
    ElementDialog eltd;


    eltd = (ElementDialog) client_data;

    Copy (NULL, client_data, NULL);
    SetTextString (eltd -> m_name, "");
    SetTextString (eltd -> l_name [0], "");
    SetTextString (eltd -> l_name [1], "");
    SetTextString (eltd -> l_name [2], "");

    numnodes = eltd -> definition -> numnodes;

    if (numnodes > 6)
      numnodes = 6;

    for (i = 0; i < numnodes; i ++)
      SetTextString (eltd -> node [i], "");
}


/************************************************************************
 * Function:      ElementDialogCreate                             *
 *                                                    *
 * Description:   Creates a new element dialog.  You would never want to      *
 *          have more than one of these but the interface is kept *
 *          consistent with those of the other dialogs.           *
 ************************************************************************/

ElementDialog ElementDialogCreate (parent, name, title, callback, closure)
    Widget     parent;
    String     name;
    String     title;
    XtCallbackProc callback;
    XtPointer        closure;
{
    Cardinal            i;
    Arg                 args [1];
    char          buffer [32];
    Widget        group [25];
    Window        window;
    ElementDialog eltd;
    Dimension           width;
    Position            x;
    static XtAppContext app_context = NULL;
    static XtActionsRec actions [ ] = {{"ElementDialogAction", Action},
                               {"ElementDialogMenu", Menu}};


    /* 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);
      button_translations = XtParseTranslationTable (button_table);
      command_translations = XtParseTranslationTable (command_table);
      repeater_translations = XtParseTranslationTable (repeater_table);
      viewport_translations = XtParseTranslationTable (viewport_table);
      help_translations = XtParseTranslationTable (help_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);

      left_bitmap = XCreateBitmapFromData (XtDisplay (parent), window,
                  left_bits, left_width, left_height);

      right_bitmap = XCreateBitmapFromData (XtDisplay (parent), window,
                   right_bits, right_width, right_height);
    }


    /* Create the element dialog and its widgets. */

    XtSetArg (shell_args [0], XtNtitle, title);
    XtSetArg (shell_args [1], XtNiconName, title);

    eltd = XtNew (struct element_dialog);
    eltd -> callback = callback;
    eltd -> closure = closure;
    eltd -> active = NULL;
    eltd -> new_loads = True;
    eltd -> new_materials = True;

    eltd -> shell     = XtCreatePopupShell (name,
                  topLevelShellWidgetClass, parent,
                  shell_args, XtNumber (shell_args));

    eltd -> layout    = XtCreateManagedWidget ("layout",
                  layoutWidgetClass, eltd -> shell,
                  layout_args, XtNumber (layout_args));

    eltd -> number    = XtCreateManagedWidget ("number",
                  labelWidgetClass, eltd -> layout,
                  number_args, XtNumber (number_args));

    eltd -> type      = XtCreateManagedWidget ("type",
                  labelWidgetClass, eltd -> layout,
                  number_args, XtNumber (number_args));

    bitmap_args [0].value = (XtArgVal) up_bitmap;

    eltd -> up        = XtCreateManagedWidget ("up",
                  repeaterWidgetClass, eltd -> layout,
                  bitmap_args, XtNumber (bitmap_args));

    bitmap_args [0].value = (XtArgVal) down_bitmap;

    eltd -> down      = XtCreateManagedWidget ("down",
                  repeaterWidgetClass, eltd -> layout,
                  bitmap_args, XtNumber (bitmap_args));

    bitmap_args [0].value = (XtArgVal) left_bitmap;

    eltd -> left      = XtCreateManagedWidget ("left",
                  commandWidgetClass, eltd -> layout,
                  bitmap_args, XtNumber (bitmap_args));

    bitmap_args [0].value = (XtArgVal) right_bitmap;

    eltd -> right     = XtCreateManagedWidget ("right",
                  commandWidgetClass, eltd -> layout,
                  bitmap_args, XtNumber (bitmap_args));

    eltd -> m_menu    = XtCreatePopupShell ("materialMenu",
                  simpleMenuWidgetClass, eltd -> layout,
                  NULL, 0);


    XtSetArg (button_args [0], XtNlabel,    "Material:");
    XtSetArg (button_args [1], XtNmenuName, "materialMenu");

    eltd -> m_button  = XtCreateManagedWidget ("materialButton",
                  menuButtonWidgetClass, eltd -> layout,
                  button_args, XtNumber (button_args));

    eltd -> m_name    = XtCreateManagedWidget ("materialName",
                  asciiTextWidgetClass, eltd -> layout,
                  edit_text_args, XtNumber (edit_text_args));


    XtSetArg (button_args [0], XtNlabel,    "Material:");
    XtSetArg (button_args [1], XtNmenuName, "loadMenu");

    eltd -> l_button [0] = XtCreateManagedWidget ("load1Button",
                     menuButtonWidgetClass, eltd -> layout,
                     button_args, XtNumber (button_args));

    eltd -> l_name [0]   = XtCreateManagedWidget ("load1Name",
                     asciiTextWidgetClass, eltd -> layout,
                     edit_text_args, XtNumber (edit_text_args));


    XtSetArg (button_args [0], XtNlabel, "Load 2:");

    eltd -> l_button [1] = XtCreateManagedWidget ("load2Button",
                     menuButtonWidgetClass, eltd -> layout,
                     button_args, XtNumber (button_args));

    eltd -> l_name [1]   = XtCreateManagedWidget ("load2Name",
                     asciiTextWidgetClass, eltd -> layout,
                     edit_text_args, XtNumber (edit_text_args));


    XtSetArg (button_args [0], XtNlabel, "Load 3:");

    eltd -> l_button [2] = XtCreateManagedWidget ("load3Button",
                     menuButtonWidgetClass, eltd -> layout,
                     button_args, XtNumber (button_args));

    eltd -> l_name [2]   = XtCreateManagedWidget ("load3Name",
                     asciiTextWidgetClass, eltd -> layout,
                     edit_text_args, XtNumber (edit_text_args));


    eltd -> l_menu    = XtCreatePopupShell ("loadMenu",
                  simpleMenuWidgetClass, eltd -> layout,
                  NULL, 0);

    eltd -> viewport  = XtCreateManagedWidget ("viewport",
                  viewportWidgetClass, eltd -> layout,
                  viewport_args, XtNumber (viewport_args));

    eltd -> stresses  = XtCreateManagedWidget ("stresses",
                  labelWidgetClass, eltd -> viewport,
                  stress_args, XtNumber (stress_args));

    eltd -> accept    = XtCreateManagedWidget ("accept",
                  commandWidgetClass, eltd -> layout,
                  NULL, 0);

    eltd -> dismiss   = XtCreateManagedWidget ("dismiss",
                  commandWidgetClass, eltd -> layout,
                  NULL, 0);

    eltd -> delete    = XtCreateManagedWidget ("delete",
                  commandWidgetClass, eltd -> layout,
                  NULL, 0);

    eltd -> new       = XtCreateManagedWidget ("new",
                  commandWidgetClass, eltd -> layout,
                  NULL, 0);

    eltd -> copy      = XtCreateManagedWidget ("copy",
                  commandWidgetClass, eltd -> layout,
                  NULL, 0);

    eltd -> help      = CreateHelpButton (eltd -> layout, "help");


    for (i = 0; i < 6; i ++) {
      sprintf (buffer, "node%d", i + 1);
      eltd -> node [i] = XtCreateManagedWidget (XtNewString (buffer),
                         asciiTextWidgetClass, eltd -> layout,
                         node_args, XtNumber (node_args));
    }


    for (i = 0; i < XtNumber (labels); i ++) {
      label_args [0].value = (XtArgVal) labels [i];
      XtCreateManagedWidget (names [i], labelWidgetClass,
                  eltd -> layout, label_args, XtNumber (label_args));
    }


    XtCreateManagedWidget ("separator1", coreWidgetClass,
                  eltd -> layout, core_args, XtNumber (core_args));

    XtCreateManagedWidget ("separator2", coreWidgetClass,
                  eltd -> layout, core_args, XtNumber (core_args));

    XtCreateManagedWidget ("separator3", coreWidgetClass,
                  eltd -> layout, core_args, XtNumber (core_args));

    XtCreateManagedWidget ("separator4", coreWidgetClass,
                  eltd -> layout, core_args, XtNumber (core_args));

    XtCreateManagedWidget ("- none -", smeBSBObjectClass,
                  eltd -> m_menu, NULL, 0);

    XtCreateManagedWidget ("- none -", smeBSBObjectClass,
                  eltd -> l_menu, NULL, 0);


    AddPostMenuActions (eltd -> m_menu);
    AddPostMenuActions (eltd -> l_menu);


    /* Create a tab group for the element dialog. */

    group [0]  = eltd -> up;
    group [1]  = eltd -> down;
    group [2]  = eltd -> left;
    group [3]  = eltd -> right;
    group [4]  = eltd -> node [0];
    group [5]  = eltd -> node [1];
    group [6]  = eltd -> node [2];
    group [7]  = eltd -> node [3];
    group [8]  = eltd -> node [4];
    group [9]  = eltd -> node [5];
    group [10] = eltd -> m_button;
    group [11] = eltd -> m_name;
    group [12] = eltd -> l_button [0];
    group [13] = eltd -> l_name [0];
    group [14] = eltd -> l_button [1];
    group [15] = eltd -> l_name [1];
    group [16] = eltd -> l_button [2];
    group [17] = eltd -> l_name [2];
    group [18] = eltd -> viewport;
    group [19] = eltd -> help;
    group [20] = eltd -> accept;
    group [21] = eltd -> dismiss;
    group [22] = eltd -> delete;
    group [23] = eltd -> new;
    group [24] = eltd -> copy;


    XtGetValues (eltd -> layout, color_args, XtNumber (color_args));
    CreateTabGroup (eltd -> shell, group, XtNumber(group), highlight, True);
    XtRealizeWidget (eltd -> shell);
    SetFocus (eltd -> up);
    SetType (eltd, (Definition) TreeMinimum (problem.definition_tree));

    button_args [0].value = (XtArgVal) "Load 1:";
    XtSetValues (eltd -> l_button [0], button_args, 1);

    XtSetArg (args [0], XtNwidth, &width);
    XtGetValues (eltd -> layout, args, 1);
    XtSetArg (args [0], XtNx, &x);
    XtGetValues (eltd -> help, args, 1);
    UpdateHelpMessage (eltd -> help, help_message, width - 2 * x);


    /* Add the translations to each widget. */

    AddDeleteWindowProtocol (eltd -> shell, "ElementDialogAction()");

    XtOverrideTranslations (eltd -> up,           repeater_translations);
    XtOverrideTranslations (eltd -> down,   repeater_translations);
    XtOverrideTranslations (eltd -> left,   repeater_translations);
    XtOverrideTranslations (eltd -> right,        repeater_translations);
    XtOverrideTranslations (eltd -> m_name,       text_translations);
    XtOverrideTranslations (eltd -> l_name [0],   text_translations);
    XtOverrideTranslations (eltd -> l_name [1],   text_translations);
    XtOverrideTranslations (eltd -> l_name [2],   text_translations);
    XtOverrideTranslations (eltd -> m_button,     button_translations);
    XtOverrideTranslations (eltd -> l_button [0], button_translations);
    XtOverrideTranslations (eltd -> l_button [1], button_translations);
    XtOverrideTranslations (eltd -> l_button [2], button_translations);
    XtOverrideTranslations (eltd -> accept,       command_translations);
    XtOverrideTranslations (eltd -> dismiss,      command_translations);
    XtOverrideTranslations (eltd -> delete,       command_translations);
    XtOverrideTranslations (eltd -> new,    command_translations);
    XtOverrideTranslations (eltd -> copy,   command_translations);
    XtOverrideTranslations (eltd -> viewport,     viewport_translations);
    XtOverrideTranslations (eltd -> help,   help_translations);

    for (i = 0; i < 6; i ++)
      XtOverrideTranslations (eltd -> node [i], text_translations);


    /* Add the necessary callbacks. */

    XtAddCallback (eltd -> up,      XtNcallback, Up,      (XtPointer) eltd);
    XtAddCallback (eltd -> down,    XtNcallback, Down,    (XtPointer) eltd);
    XtAddCallback (eltd -> left,    XtNcallback, Left,    (XtPointer) eltd);
    XtAddCallback (eltd -> right,   XtNcallback, Right,   (XtPointer) eltd);
    XtAddCallback (eltd -> accept,  XtNcallback, Accept,  (XtPointer) eltd);
    XtAddCallback (eltd -> dismiss, XtNcallback, Dismiss, (XtPointer) eltd);
    XtAddCallback (eltd -> delete,  XtNcallback, Delete,  (XtPointer) eltd);
    XtAddCallback (eltd -> new,     XtNcallback, New,     (XtPointer) eltd);
    XtAddCallback (eltd -> copy,    XtNcallback, Copy,    (XtPointer) eltd);

    XtAddCallback (eltd -> m_menu, XtNpopupCallback,
               UpdateMaterialMenu, (XtPointer) eltd);

    XtAddCallback (eltd -> m_menu, XtNpopdownCallback,
               UpdateMaterialName, (XtPointer) eltd);

    XtAddCallback (eltd -> l_menu, XtNpopupCallback,
               UpdateLoadMenu, (XtPointer) eltd);

    XtAddCallback (eltd -> l_menu, XtNpopdownCallback,
               UpdateLoadName, (XtPointer) eltd);

    return eltd;
}


/************************************************************************
 * Function:      ElementDialogPopup                              *
 *                                                    *
 * Description:   Pops up the specified element dialog.                 *
 ************************************************************************/

void ElementDialogPopup (eltd)
    ElementDialog eltd;
{
    XtPopup (eltd -> shell, XtGrabNone);
}


/************************************************************************
 * Function:      ElementDialogUpdate                             *
 *                                                    *
 * Description:   Updates the specified element dialog with the specified     *
 *          trees.                                          *
 ************************************************************************/

void ElementDialogUpdate (eltd, elements, materials, loads, nodes)
    ElementDialog eltd;
    Tree      elements;
    Tree      materials;
    Tree      loads;
    Tree      nodes;
{
    /* Remember to update the menus if necessary. */

    if (materials != NULL) {
      eltd -> materials = materials;
      eltd -> new_materials = True;
    }

    if (loads != NULL) {
      eltd -> loads = loads;
      eltd -> new_loads = True;
    }

    if (nodes != NULL)
      eltd -> nodes = nodes;


    /* Determine a new active element if necessary. */

    if (elements == NULL && eltd -> active == NULL)
      eltd -> active = (Element) TreeMinimum (eltd -> elements);

    if (elements && (eltd -> active == NULL || eltd -> elements != elements))
      eltd -> active = (Element) TreeMinimum (elements);

    if (elements != NULL) {
      eltd -> elements = elements;
      if (eltd -> active != NULL)
          ElementDialogDisplay (eltd, eltd -> active);
      else
          New (NULL, (XtPointer) eltd, NULL);
    }
}


/************************************************************************
 * Function:      ElementDialogActive                             *
 *                                                    *
 * Description:   Returns the currently displayed (active) element.     *
 ************************************************************************/

Element ElementDialogActive (eltd)
    ElementDialog eltd;
{
    return eltd -> active;
}


/************************************************************************
 * Function:      ElementDialogDisplay                            *
 *                                                    *
 * Description:   Displays the specified element.                       *
 ************************************************************************/

void ElementDialogDisplay (eltd, element)
    ElementDialog eltd;
    Element   element;
{
    unsigned      numnodes;
    Distributed   load;
    Cardinal      i;
    Cardinal      j;
    Cardinal      count;
    Element active;
    char    buffer [2048];


    /* Check if the element exists. */

    eltd -> active = element;

    if (eltd -> active == NULL)
      return;

    active = eltd -> active;
    eltd -> new_copy = 0;


    /* Update all of the entries. */

    SetNumber (eltd, active -> number);
    SetType   (eltd, active -> definition);

    if (active -> material != NULL)
      SetTextString (eltd -> m_name, active -> material -> name);
    else
      SetTextString (eltd -> m_name, "");

    for (i = 1; i <= 3; i ++)
      if (active -> numdistributed >= i && (load = active -> distributed [i]))
          SetTextString (eltd -> l_name [i - 1], load -> name);
      else
          SetTextString (eltd -> l_name [i - 1], "");


    numnodes = active -> definition -> numnodes;

    for (i = 1; i <= numnodes; i ++)
      if (element -> node [i] != NULL)
          eltd -> node_values [i - 1] = element -> node [i] -> number;
      else
          eltd -> node_values [i - 1] = 0;


    if (element -> ninteg == 0 || element -> stress == NULL)
      SetLabelString (eltd -> stresses, "No stresses available");
    else {
      count = 0;
      buffer [0] = 0;
      for (i = 1; i <= element -> ninteg; i ++)
          for (j = 1; j <= element -> definition -> numstresses; j ++) {
            sprintf (buffer + strlen (buffer), "%11.5g ",
                   element -> stress [i] -> values [j]);
            if (++ count == 6) {
                sprintf (buffer + strlen (buffer), "\n");
                count = 0;
            }
          }

      SetLabelString (eltd -> stresses, buffer);
    }

    XawViewportSetCoordinates (eltd -> viewport, 0, 0);

    DisplayNodes (eltd);
}

Generated by  Doxygen 1.6.0   Back to index