Logo Search packages:      
Sourcecode: vertex version File versions

editorviewcb.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>

#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

#include "../include/string.h"

#include "cdialog.h"

#include "view.h"
#include "viewcb.h"
#include "viewdraw.h"
#include "editor.h"
#include "editorcb.h"
#include "editorhf.h"
#include "editorlist.h"
#include "editorselect.h"
#include "editorundo.h"

#include "vmastatusbar.h"
#include "vma.h"
#include "vmautils.h"

#ifdef MEMWATCH
# include "memwatch.h"
#endif


void EditorRedrawAllViews(ma_editor_struct *editor);
void EditorUpdateAllViewMenus(ma_editor_struct *editor);

static void EditorView2DEventSetVertexToCursor(
      ma_editor_struct *editor,
      vma_view_event_settocursor2d_struct *settocursor2d,
      gint model_num, v3d_model_struct *model_ptr,
      gint pn, gpointer p, gint value_num
);
static void EditorView2DEventSetCursor(
        ma_editor_struct *editor,  
        vma_view_event_cursor2d_struct *cursor2d
);
static void EditorView2DEventSetVertex(
        ma_editor_struct *editor,
        vma_view_event_set2d_struct *set2d,
        gint model_num, v3d_model_struct *model_ptr,
        gint pn, gpointer p, gint value_num
);
static void EditorView2DEventSetNormal(
        ma_editor_struct *editor,
        vma_view_event_set2d_struct *set2d,
      gint model_num, v3d_model_struct *model_ptr,
      gint pn, gpointer p, gint value_num
);
static void EditorView2DEventSelectRectangular(
        ma_editor_struct *editor,
        vma_view_event_select2d_struct *select2d,
      gint model_num, v3d_model_struct *model_ptr
);
void EditorView2DEventCB(void *client_data, void *event);
void EditorView3DEventCB(void *client_data, void *event);


#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))

#define RADTODEG(r)     ((r) * 180 / PI)


static mp_vertex_struct net_translate_delta;


/*
 *    Checks if editor has changes, if it does not then it will
 *    mark it as having changes.
 */
#define EDITOR_DO_UPDATE_HAS_CHANGES      \
{ \
 if(!editor->has_changes) \
  editor->has_changes = TRUE; \
}



/*
 *    Redraws all views on editor.
 */
void EditorRedrawAllViews(ma_editor_struct *editor)
{
      gint i;
      vma_view2d_struct *view2d;
      vma_view3d_struct *view3d;

      if(editor == NULL)
          return;

      if(!editor->initialized || !editor->map_state)
          return;

        for(i = 0; i < VMA_MAX_2D_VIEWS_PER_EDITOR; i++)
      {
          view2d = editor->view2d[i];
          if(view2d == NULL)
            continue;

            View2DDraw(view2d, &view2d->palette, 0, 0, TRUE);
      }
        for(i = 0; i < VMA_MAX_3D_VIEWS_PER_EDITOR; i++)
      {
          view3d = editor->view3d[i];
          if(view3d == NULL)
                continue;

            View3DDraw(view3d, &view3d->palette, 0, 0, TRUE);
      }
}

/*
 *    Updates all view menus.
 */
void EditorUpdateAllViewMenus(ma_editor_struct *editor)
{
      gint i;
        vma_view2d_struct *view2d;
        vma_view3d_struct *view3d;

        if(editor == NULL)
            return;

        if(!editor->initialized)
            return;

        for(i = 0; i < VMA_MAX_2D_VIEWS_PER_EDITOR; i++)
        {
            view2d = editor->view2d[i];
            if(view2d == NULL) 
                continue;

            View2DUpdateMenus(view2d);
        }
        for(i = 0; i < VMA_MAX_3D_VIEWS_PER_EDITOR; i++)
        {
            view3d =  editor->view3d[i];
            if(view3d == NULL)
                continue;

            View3DUpdateMenus(view3d);
        }
}



/* Simplified texture orient structure used in EditorView2DEvent*() to
 * record values.
 */
typedef struct {
        double i, j, di, dj;
} texorient_valrec_struct;
/* Simplified heightfield structure used in EditorView2DEvent*() to
 * record values.
 */
typedef struct {
      double x_length, y_length, z_length;
        double x, y, z;
      double heading, pitch, bank;  /* In radians. */
} heightfield_valrec_struct;



/*
 *      Handles a set vertex to cursor event, checks which primitive is
 *    selected on the editor and moves its vertex depending on the
 *    primitive type and which vertex is selected.
 *
 *    Only primtives with vertices supported.
 */
static void EditorView2DEventSetVertexToCursor(
        ma_editor_struct *editor,
        vma_view_event_settocursor2d_struct *settocursor2d,
        gint model_num, v3d_model_struct *model_ptr,
        gint pn, gpointer p, gint value_num
)
{
      gbool need_has_change = FALSE;
        gint ptype;
        vma_view2d_struct *v;
      mp_vertex_struct cv;
        static mp_vertex_struct old_v;

        gchar text[256], fmt_str[256];


        if((editor == NULL) || (settocursor2d == NULL))
            return;

        /* Get pointer to view from event structure. */
        v = settocursor2d->view2d;
        if(v == NULL)
            return;

        /* Given referances to model and primitives must be valid. */
        if((model_ptr == NULL) || (p == NULL))
            return;

      /* Get cursor position from editor. */
      cv.x = editor->vcursor_x;
        cv.y = editor->vcursor_y;
        cv.z = editor->vcursor_z;


        /* Get primitive type. */
        ptype = V3DMPGetType(p);

        /* There is a value item selected on the editor, check if no
         * operations were done above (check if need_has_change is false).
         */
        if(!need_has_change)
        {
            /* Set vertex. */
            gint vtx_num = value_num;
            mp_vertex_struct *vtx_ptr;


            /* Get pointer to vertex on primitive. */
            vtx_ptr = V3DMPGetVertex(p, vtx_num);
            if(vtx_ptr != NULL)
            {
                /* We now know that the primitive has vertices. */
                GtkWidget *w;

                /* Event is a initial position set? */
                if(settocursor2d->is_initial)
                {
                    /* Record original vertex position. */
                    old_v.x = vtx_ptr->x;
                    old_v.y = vtx_ptr->y;
                    old_v.z = vtx_ptr->z;
                }

            /* Update values prompts if exactly one value is
             * selected.
             */
            if((VMA_PRIMITIVES_MAX_VALUES > 2) && 
               (editor->total_selected_values == 1)
            )
            {
                    sprintf(fmt_str, "%%.%if", editor->vertex_decimals);
                    w = editor->values_text[0];
                    if(w != NULL)
                    {
                        sprintf(text, fmt_str, cv.x);
                        gtk_entry_set_text(GTK_ENTRY(w), text);
                    }
                    w = editor->values_text[1];
                    if(w != NULL)
                    {
                        sprintf(text, fmt_str, cv.y);
                        gtk_entry_set_text(GTK_ENTRY(w), text);
                    }
                    w = editor->values_text[2];
                    if(w != NULL)
                    {
                        sprintf(text, fmt_str, cv.z);
                        gtk_entry_set_text(GTK_ENTRY(w), text);
                    }
            }

            /* Set new vertex position. */
            vtx_ptr->x = cv.x;
            vtx_ptr->y = cv.y;
            vtx_ptr->z = cv.z;

            need_has_change = TRUE;

                /* Is event a final position set? */
                if(settocursor2d->is_final)
                {
                    /* Is a final position set event, record undo. */
                    vma_undo_set_vertex_struct *u = (vma_undo_set_vertex_struct *)VMAUndoNew(
                        VMA_UNDO_TYPE_SET_VERTEX, "Set Vertex"
                    );
                    if(u != NULL)
                    {
                        u->editor = editor;
                        u->model_num = model_num;
                        u->primitive_num = pn;
                        u->vertex_num = vtx_num;
                        u->v.x = old_v.x;
                        u->v.y = old_v.y;
                        u->v.z = old_v.z;
                        EditorUndoRecord(editor, u);
                    }
                }
            }
        }
        /* No vertexes were set above? */
        if(!need_has_change)
        {
          /* Add support for other object types here? */
      }


      /* Update displays if changes were made. */
        if(need_has_change)
        {
            EDITOR_DO_UPDATE_HAS_CHANGES
            if(settocursor2d->is_initial && !settocursor2d->is_final)
            {
                EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }
            if(settocursor2d->is_final)
            {
                if(editor->total_selected_values == 1)
                    EditorListValuePromptApply(
                        editor,
                        NULL,   /* Passing NULL means only apply vertices. */
                        FALSE   /* Do not record undo, we probably have
                                 * already done so above.
                                 */
                    );
                EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }
            EditorRedrawAllViews(editor);
        }

      return;
}

/*
 *    Handles a moved cursor event on the 2d view. Will update other
 *    views on the given editor and redraw those views.
 */
static void EditorView2DEventSetCursor(
      ma_editor_struct *editor,
      vma_view_event_cursor2d_struct *cursor2d
)
{
      gint v_num;
      vma_view2d_struct *v, *v_ptr;


      if((editor == NULL) || (cursor2d == NULL))
          return;

      /* Get pointer to view from event structure. */
      v = cursor2d->view2d;
      if(v == NULL)
          return;

      /* Go through each view on the editor. */
      for(v_num = 0; v_num < VMA_MAX_2D_VIEWS_PER_EDITOR; v_num++)
      {
          v_ptr = editor->view2d[v_num];
          if(v_ptr == NULL)
            continue;

          /* Skip event's view. */
          if(v_ptr == v)
            continue;

          /* Handle by view orientation type. */
          switch(v->type)
          {
            /* Event view is XY. */
              case VMA_VIEW2D_TYPE_XY:
                switch(v_ptr->type)
                {
                  case VMA_VIEW2D_TYPE_XY:
                    v_ptr->v_cur_i = cursor2d->vi;
                    v_ptr->v_cur_j = cursor2d->vj;
                    break;

                  case VMA_VIEW2D_TYPE_YZ:
                    v_ptr->v_cur_i = cursor2d->vj;
                    break;

                  case VMA_VIEW2D_TYPE_XZ:
                    v_ptr->v_cur_i = cursor2d->vi;
                    break;
                }
                break;

              /* Event view is YZ. */
              case VMA_VIEW2D_TYPE_YZ:
                switch(v_ptr->type)
            {
                  case VMA_VIEW2D_TYPE_XY:
                    v_ptr->v_cur_j = cursor2d->vi;
                    break;

                  case VMA_VIEW2D_TYPE_YZ:
                    v_ptr->v_cur_i = cursor2d->vi;
                    v_ptr->v_cur_j = cursor2d->vj;
                    break;

                  case VMA_VIEW2D_TYPE_XZ:
                    v_ptr->v_cur_j = cursor2d->vj;
                    break;
                }
                break;

              /* Event view is XZ. */
              case VMA_VIEW2D_TYPE_XZ:
                switch(v_ptr->type)
                {
                  case VMA_VIEW2D_TYPE_XY:
                    v_ptr->v_cur_i = cursor2d->vi;
                    break;

                  case VMA_VIEW2D_TYPE_YZ:
                    v_ptr->v_cur_j = cursor2d->vj;
                    break;

                  case VMA_VIEW2D_TYPE_XZ:
                    v_ptr->v_cur_i = cursor2d->vi;
                    v_ptr->v_cur_j = cursor2d->vj;
                    break;
                }
                break;
            }
            View2DDraw(v_ptr, &v_ptr->palette, 0, 0, TRUE);
        }

        /* Update view cursor position on editor structure. */

      /* Handle by event view orientation type. */
      switch(v->type)
        {
        case VMA_VIEW2D_TYPE_XY:
            editor->vcursor_x = cursor2d->vi;
            editor->vcursor_y = cursor2d->vj;
            break;

          case VMA_VIEW2D_TYPE_YZ:
            editor->vcursor_y = cursor2d->vi;
            editor->vcursor_z = cursor2d->vj;
            break;

          case VMA_VIEW2D_TYPE_XZ:
            editor->vcursor_x = cursor2d->vi;
            editor->vcursor_z = cursor2d->vj;
            break;
        }

      /* Update position of cursor on status bar. */
      VMAStatusBarCursorPosition(
          editor->sb,
          editor->vcursor_x, editor->vcursor_y,
          editor->vcursor_z
      );


      return;
}

/*      
 *    Handles a set vertex, checks which primitive is selected on the
 *    editor and moves its vertx depending on the primitive type and
 *    which vertex is selected.
 */
static void EditorView2DEventSetVertex(
        ma_editor_struct *editor,
        vma_view_event_set2d_struct *set2d,
        gint model_num, v3d_model_struct *model_ptr,
      gint pn, gpointer p, gint value_num
)
{
      gbool need_has_change = FALSE;
      gint ptype;
        vma_view2d_struct *v;
        static mp_vertex_struct old_v;
        static texorient_valrec_struct old_texorient;
        static heightfield_valrec_struct old_heightfield;

      gchar text[256], fmt_str[256];


        if((editor == NULL) || (set2d == NULL))
            return;

      /* Get pointer to view from event structure. */
      v = set2d->view2d;
        if(v == NULL)
            return;

      /* Given referances to model and primitives must be valid. */
      if((model_ptr == NULL) || (p == NULL))
          return;

      /* If this is a set vertex initial, then check where the initial
       * button press occured over. If it occured on the same primitive
       * and a particular vertex is selected, then select that vertex
       * first before continuing with setting so that setting affects
       * that particular vertex.
       */
      if(set2d->is_initial)
      {
          gint w_sel_offset = 8;    /* Selection tolorance in pixels. */
          gdouble vi_offset, vj_offset, wtov_coeff;
          gint new_pn, new_vtx_num;

          wtov_coeff = View2DGetWToVCoeff(v);
          if(wtov_coeff > 0.0)
          {
            GtkCList *values_list = (GtkCList *)editor->values_list;
            vi_offset = (w_sel_offset / 2) * wtov_coeff;
            vj_offset = (w_sel_offset / 2) * wtov_coeff;

            new_pn = EditorSelectPrimitiveRectangular(
                editor, v->type,
                set2d->vi - vi_offset, set2d->vj - vj_offset,
                set2d->vi + vi_offset, set2d->vj + vj_offset,
                0,            /* Start from beginning. */
                &new_vtx_num
            );
            /* New selected primitive number same as given? */
            if((new_pn == pn) && (values_list != NULL))
            {
                gint old_vtx_num = EditorGetSelected(
                  editor->selected_value, editor->total_selected_values,
                  0
                );

                /* Did we get a matched vertex and its different
                 * from the old one?
                 */
                if((new_vtx_num > -1) && (new_vtx_num != old_vtx_num))
                {
                  gtk_clist_select_row(
                      values_list, new_vtx_num, 0
                  );
                }

            }     /* New primitive number same as given? */
          }
      }


      /* Get primitive type. */
      ptype = V3DMPGetType(p);

      /* No value item currently selected? */
      if(value_num < 0)
      {
          /* No value item selected implies that we want to move
           * the entire object (all vertices on the primitive).
           */
          gint vtx_num;
          mp_vertex_struct *vtx_ptr;

          /* Go through each vertex on the primitive. */
          for(vtx_num = 0; 1; vtx_num++)
          {
            vtx_ptr = V3DMPGetVertex(p, vtx_num);
            if(vtx_ptr == NULL)
                break;

            /* Move vertex by view orientation type. */
            switch(v->type)
            {
              case VMA_VIEW2D_TYPE_XY:
                vtx_ptr->x += set2d->vdi;
                vtx_ptr->y += set2d->vdj;
                    break;
                  case VMA_VIEW2D_TYPE_YZ:
                    vtx_ptr->y += set2d->vdi;
                    vtx_ptr->z += set2d->vdj;
                    break;
                  case VMA_VIEW2D_TYPE_XZ:
                    vtx_ptr->x += set2d->vdi;
                    vtx_ptr->z += set2d->vdj;
                    break;
                }
            }
          /* Now vtx_num reflects the number of vertices set above,
           * check if any vertices were set.
           */
          if(vtx_num > 0)
          {
            EDITOR_DO_UPDATE_HAS_CHANGES

            /* Is event a final position set? */
            if(set2d->is_final)
            {
                /* We will need to record an undo for this translation
                 * of the primitive.
                 */
                vma_undo_translate_primitive_struct *ut;

                    /* Create a new undo structure. */
                    ut = (vma_undo_translate_primitive_struct *)VMAUndoNew(
                        VMA_UNDO_TYPE_TRANSLATE_PRIMITIVE,
                        "Translate Primitive"
                    );
                    if(ut != NULL)
                    {
                        ut->editor = editor;
                        ut->model_num = model_num;
                        ut->primitive_num = pn;
                        ut->dx = net_translate_delta.x;
                        ut->dy = net_translate_delta.y;
                        ut->dz = net_translate_delta.z;
                        EditorUndoRecord(editor, ut);
                    }

                    /* Clear and then reget editor's values list. */
                    EditorListDeleteValuesG(editor);
                    EditorListAddValuesRG(editor, p);

                /* Need to reselect the first value item on the
                 * editor's values list.
                 */
/* Don't need this anymore, when translating entire primtive no row
   on values list is selected.
                w = editor->values_list;
                row = 0;
                if(w != NULL)
                  gtk_clist_select_row(GTK_CLIST(w), row, 0);
 */
                    EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }

            EditorRedrawAllViews(editor);

            /* Return now, so that the editor's value prompts do not
             * get updated in this function.
             */
            return;
          }
          else
          {
            /* No vertexes were set, let function execution continue
             * to allow other vertex set conditions to be done
             * (as it might be some other kind of primitive.
             */
          }
      }

      /* There is a value item selected on the editor, check if no
       * operations were done above (check if need_has_change is false).
       */
      if(!need_has_change)
      {
          /* Set vertex. */
          gint vtx_num = value_num;
          mp_vertex_struct *vtx_ptr;


          /* Get pointer to vertex on primitive. */
          vtx_ptr = V3DMPGetVertex(p, vtx_num);
          if(vtx_ptr != NULL)
          {
            /* We now know that the primitive has vertexes. */
            GtkWidget *w;

                /* Event is a initial position set? */
            if(set2d->is_initial)
            {
                /* Record original vertex position. */
                old_v.x = vtx_ptr->x;
                old_v.y = vtx_ptr->y;
                old_v.z = vtx_ptr->z;
            }

            /* Handle by view orientation type. */
            switch(v->type)
                {
                  case VMA_VIEW2D_TYPE_XY:
                    if((VMA_PRIMITIVES_MAX_VALUES > 2) &&
                       (editor->total_selected_values == 1)
                    )
                    {
                        sprintf(fmt_str, "%%.%if", editor->vertex_decimals);
                        w = editor->values_text[0];
                        if(w != NULL)
                        {
                            sprintf(text, fmt_str, set2d->vi);
                            gtk_entry_set_text(GTK_ENTRY(w), text);
                        }
                        w = editor->values_text[1];
                        if(w != NULL)
                        {
                            sprintf(text, fmt_str, set2d->vj);
                            gtk_entry_set_text(GTK_ENTRY(w), text);
                        }
                }
                    vtx_ptr->x = set2d->vi;
                    vtx_ptr->y = set2d->vj;
                    need_has_change = TRUE;
                    break;

                  case VMA_VIEW2D_TYPE_YZ:
                    if((VMA_PRIMITIVES_MAX_VALUES > 2) &&
                   (editor->total_selected_values == 1)
                )
                {
                  sprintf(fmt_str, "%%.%if", editor->vertex_decimals);
                  w = editor->values_text[1];
                        if(w != NULL)
                        {
                            sprintf(text, fmt_str, set2d->vi);
                            gtk_entry_set_text(GTK_ENTRY(w), text);
                        }
                        w = editor->values_text[2];
                        if(w != NULL)
                        {
                            sprintf(text, fmt_str, set2d->vj);
                            gtk_entry_set_text(GTK_ENTRY(w), text);
                        }
                }
                    vtx_ptr->y = set2d->vi;
                    vtx_ptr->z = set2d->vj;
                    need_has_change = TRUE;
                    break;

                  case VMA_VIEW2D_TYPE_XZ:
                    if((VMA_PRIMITIVES_MAX_VALUES > 2) &&
                       (editor->total_selected_values == 1)
                    )
                    {
                        sprintf(fmt_str, "%%.%if", editor->vertex_decimals);
                        w = editor->values_text[0];
                        if(w != NULL)
                        {
                            sprintf(text, fmt_str, set2d->vi);
                            gtk_entry_set_text(GTK_ENTRY(w), text);
                        }
                        w = editor->values_text[2];
                        if(w != NULL)
                        {
                            sprintf(text, fmt_str, set2d->vj);
                            gtk_entry_set_text(GTK_ENTRY(w), text);
                        }
                }
                    vtx_ptr->x = set2d->vi;
                    vtx_ptr->z = set2d->vj;
                    need_has_change = TRUE;
                    break;
                }

            /* Is event a final position set? */
            if(set2d->is_final)
                {
                /* Is a final position set event, record undo. */
                    vma_undo_set_vertex_struct *u = (vma_undo_set_vertex_struct *)VMAUndoNew(
                        VMA_UNDO_TYPE_SET_VERTEX, "Set Vertex"
                    );
                    if(u != NULL)
                    {
                        u->editor = editor;
                        u->model_num = model_num;
                        u->primitive_num = pn;
                        u->vertex_num = vtx_num;
                        u->v.x = old_v.x;
                        u->v.y = old_v.y;
                        u->v.z = old_v.z;
                        EditorUndoRecord(editor, u);
                    }
                }
            }
        }
        /* No vertexes were set above? */
      if(!need_has_change)
      {
          /* No vertexes were handled above, so that implies this
           * is some other type of primitive. Handle it here.
           */
          GtkWidget *w;
          mp_texture_orient_xy_struct *mp_texture_xy;
            mp_texture_orient_yz_struct *mp_texture_yz;
            mp_texture_orient_xz_struct *mp_texture_xz;
            mp_heightfield_load_struct *mp_heightfield_load;

          /* Check if it is a texture orient or a heightfield. */
          switch(ptype)
          {
/* Sets values prompts to the position of the texture orient, this
 * is basically the set event position view value set on the first
 * two value prompts.
 */
#define DO_SET_TEXTURE_PROMPTS      \
{ \
 sprintf(fmt_str, "%%.%if", editor->vertex_decimals); \
 \
 if(VMA_PRIMITIVES_MAX_VALUES > 0) \
  w = editor->values_text[0]; \
 else \
  w = NULL; \
 if(w != NULL) \
 { \
  sprintf(text, fmt_str, set2d->vi); \
  gtk_entry_set_text(GTK_ENTRY(w), text); \
 } \
 if(VMA_PRIMITIVES_MAX_VALUES > 1) \
  w = editor->values_text[1]; \
 else \
  w = NULL; \
 if(w != NULL) \
 { \
  sprintf(text, fmt_str, set2d->vj); \
  gtk_entry_set_text(GTK_ENTRY(w), text); \
 } \
}
/* Records undo for texture orient, uses variables;
 * editor, model_num, pn, and old_tex_orient.
 */
#define DO_RECORD_TEXTURE_ORIENT_UNDO   \
{ \
 vma_undo_set_texorient_struct *u = (vma_undo_set_texorient_struct *)VMAUndoNew( \
  VMA_UNDO_TYPE_SET_TEXORIENT, "Set TexOrient" \
 ); \
 if(u != NULL) \
 { \
  u->editor = editor; \
  u->model_num = model_num; \
  u->primitive_num = pn; \
  u->i = old_texorient.i; \
  u->j = old_texorient.j; \
  u->di = old_texorient.di; \
  u->dj = old_texorient.dj; \
  EditorUndoRecord(editor, u); \
 } \
}
              case V3DMP_TYPE_TEXTURE_ORIENT_XY:
                mp_texture_xy = p;
                if(v->type != VMA_VIEW2D_TYPE_XY)
                    break;
                if(set2d->is_initial)
                {
                    old_texorient.i = mp_texture_xy->x;
                    old_texorient.j = mp_texture_xy->y;
                    old_texorient.di = mp_texture_xy->dx;
                    old_texorient.dj = mp_texture_xy->dy;
                }
                DO_SET_TEXTURE_PROMPTS
                mp_texture_xy->x = set2d->vi;
                mp_texture_xy->y = set2d->vj;
                need_has_change = TRUE;
                if(set2d->is_final)
                {
                    DO_RECORD_TEXTURE_ORIENT_UNDO
                }
                break;

              case V3DMP_TYPE_TEXTURE_ORIENT_YZ:
                mp_texture_yz = p;
                if(v->type != VMA_VIEW2D_TYPE_YZ)
                    break;
                if(set2d->is_initial)
                {  
                    old_texorient.i = mp_texture_yz->y;
                    old_texorient.j = mp_texture_yz->z;
                    old_texorient.di = mp_texture_yz->dy;
                    old_texorient.dj = mp_texture_yz->dz;
                }
                DO_SET_TEXTURE_PROMPTS
                mp_texture_yz->y = set2d->vi;
                mp_texture_yz->z = set2d->vj;
                need_has_change = TRUE;
                if(set2d->is_final)
                {
                    DO_RECORD_TEXTURE_ORIENT_UNDO
                }
                break;

              case V3DMP_TYPE_TEXTURE_ORIENT_XZ:
                mp_texture_xz = p;
                if(v->type != VMA_VIEW2D_TYPE_XZ)
                    break;
                if(set2d->is_initial)
                {
                    old_texorient.i = mp_texture_xz->x;
                    old_texorient.j = mp_texture_xz->z;
                    old_texorient.di = mp_texture_xz->dx;
                    old_texorient.dj = mp_texture_xz->dz;
                }
                DO_SET_TEXTURE_PROMPTS
                mp_texture_xz->x = set2d->vi;
                mp_texture_xz->z = set2d->vj;
                need_has_change = TRUE;
                if(set2d->is_final)
                {
                    DO_RECORD_TEXTURE_ORIENT_UNDO
                }
                break;

#undef DO_RECORD_TEXTURE_ORIENT_UNDO
#undef DO_SET_TEXTURE_PROMPTS

              case V3DMP_TYPE_HEIGHTFIELD_LOAD:
/* Updates value prompts based on new heightfield values.
 * Uses variables; editor, n, set2d, w, text, mp_heightfield_load, and
 * fmt_str.
 */
#define DO_SET_HEIGHTFIELD_PROMPTS  \
{ \
 if(value_num == 2) \
 { \
  sprintf(fmt_str, "%%.%if", editor->vertex_decimals); \
 \
  if(VMA_PRIMITIVES_MAX_VALUES > 0) \
   w = editor->values_text[0]; \
  else \
   w = NULL; \
  if(w != NULL) \
  { \
   sprintf(text, fmt_str, mp_heightfield_load->x); \
   gtk_entry_set_text(GTK_ENTRY(w), text); \
  } \
  if(VMA_PRIMITIVES_MAX_VALUES > 1) \
   w = editor->values_text[1]; \
  else \
   w = NULL; \
  if(w != NULL) \
  { \
   sprintf(text, fmt_str, mp_heightfield_load->y); \
   gtk_entry_set_text(GTK_ENTRY(w), text); \
  } \
  if(VMA_PRIMITIVES_MAX_VALUES > 2) \
   w = editor->values_text[2]; \
  else \
   w = NULL; \
  if(w != NULL) \
  { \
   sprintf(text, fmt_str, mp_heightfield_load->z); \
   gtk_entry_set_text(GTK_ENTRY(w), text); \
  } \
 } \
}
/* Records undo for texture orient, uses variables;
 * editor, model_num, pn, and old_tex_orient.
 */
#define DO_RECORD_HEIGHTFIELD_UNDO  \
{ \
 vma_undo_set_heightfield_struct *u = (vma_undo_set_heightfield_struct *)VMAUndoNew( \
  VMA_UNDO_TYPE_SET_HEIGHTFIELD, "Set HeightField" \
 ); \
 if(u != NULL) \
 { \
  u->editor = editor; \
  u->model_num = model_num; \
  u->primitive_num = pn; \
  u->x_length = old_heightfield.x_length; \
  u->y_length = old_heightfield.y_length; \
  u->z_length = old_heightfield.z_length; \
  u->x = old_heightfield.x; \
  u->y = old_heightfield.y; \
  u->z = old_heightfield.z; \
  u->heading = old_heightfield.heading; \
  u->pitch = old_heightfield.pitch; \
  u->bank = old_heightfield.bank; \
  EditorUndoRecord(editor, u); \
 } \
}
                mp_heightfield_load = (mp_heightfield_load_struct *)p;
                if(set2d->is_initial)
                {
                    old_heightfield.x_length =
                        mp_heightfield_load->x_length;
                    old_heightfield.y_length =
                        mp_heightfield_load->y_length;
                    old_heightfield.z_length =
                        mp_heightfield_load->z_length;

                    old_heightfield.x = mp_heightfield_load->x;
                    old_heightfield.y = mp_heightfield_load->y;
                    old_heightfield.z = mp_heightfield_load->z;

                    old_heightfield.heading =
                        mp_heightfield_load->heading;
                    old_heightfield.pitch =
                        mp_heightfield_load->pitch;
                    old_heightfield.bank =
                        mp_heightfield_load->bank;
                }
                /* Set heightfield by the view type, note that
                 * the selected value item number on the editor
                 * determines what attributes are set.
                 */
                switch(v->type)
                {
                  case VMA_VIEW2D_TYPE_XY:
                    if(value_num == 2)
                    {
                        mp_heightfield_load->x += set2d->vdi;
                        mp_heightfield_load->y += set2d->vdj;
                        need_has_change = TRUE;
                    }
                    break;

                  case VMA_VIEW2D_TYPE_YZ:
                    if(value_num == 2)
                    {
                        mp_heightfield_load->y += set2d->vdi;
                        mp_heightfield_load->z += set2d->vdj;
                        need_has_change = TRUE;
                    }
                    break;

                  case VMA_VIEW2D_TYPE_XZ:
                    if(value_num == 2)
                    {
                        mp_heightfield_load->x += set2d->vdi;
                        mp_heightfield_load->z += set2d->vdj;
                        need_has_change = TRUE;
                    }
                    break;
                }
            /* Was a heightfield attribute set above? */
                if(need_has_change)
                {
                    DO_SET_HEIGHTFIELD_PROMPTS

                /* Is event a final position set? */
                    if(set2d->is_final)
                    {
                        /* Clear and reget values list. */
                        EditorListDeleteValuesG(editor);
                        EditorListAddValuesRG(editor, p);

                        /* Need to reselect prev values item. */
                        w = editor->values_list;
                        if(w != NULL)
                            gtk_clist_select_row(GTK_CLIST(w), value_num, 0);

                  DO_RECORD_HEIGHTFIELD_UNDO
                    }
                }
#undef DO_SET_HEIGHTFIELD_PROMPTS
#undef DO_RECORD_HEIGHTFIELD_UNDO
                break;

/* Add support for other primitive types here. */
            }
        }

        /* Call values text prompts enter callback to set the new
       * changed values.
       */
        if(need_has_change)
        {
            EDITOR_DO_UPDATE_HAS_CHANGES
            if(set2d->is_initial && !set2d->is_final)
            {
                EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }
            if(set2d->is_final)
            {
            if(editor->total_selected_values == 1)
                EditorListValuePromptApply(
                  editor,
                  NULL, /* Passing NULL means only apply vertices. */
                  FALSE /* Do not record undo, we probably have
                         * already done so above.
                         */
                );
                EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }
            EditorRedrawAllViews(editor);
        }


      return;
}

/*
 *      Handles a set normal, checks which primitive is selected on the
 *      editor and moves its normal depending on the primitive type and
 *      which vertex is selected.
 */
static void EditorView2DEventSetNormal(
        ma_editor_struct *editor,
        vma_view_event_set2d_struct *set2d,
      gint model_num, v3d_model_struct *model_ptr,
        gint pn, gpointer p, gint value_num
)
{
      gbool need_has_change = FALSE;
      gint ptype;
        vma_view2d_struct *v;
        static mp_vertex_struct old_n;


        if((editor == NULL) || (set2d == NULL))
            return;

/* Return now, this function is still under construction. */
return;

        /* Get pointer to view from event structure. */
        v = set2d->view2d;
        if(v == NULL)
            return;

        /* Given referances to model and primitives must be valid. */
        if((model_ptr == NULL) || (p == NULL))
          return;


        /* Get primitive type. */
        ptype = (*(gint *)p);

        /* If not value item currently selected, then give up. */
        if(value_num < 0)
          return;

        /* There is a valie item selected on the editor, check if no
         * operations were done above (check if need_has_change is false).
         */
        if(!need_has_change)
        {
            /* Set normal. */
            int norm_num = value_num;
            mp_vertex_struct *norm_ptr;

            /* Get pointer to normal on primitive. */
            norm_ptr = V3DMPGetNormal(p, norm_num);
            if(norm_ptr != NULL)
            {
                /* We now know that the primitive has vertexes. */
/*          GtkWidget *w; */

                /* Event is a initial position set? */
                if(set2d->is_initial)
                {
                    /* Record original normal position. */
                    old_n.x = norm_ptr->x;
                    old_n.y = norm_ptr->y;
                    old_n.z = norm_ptr->z;
                }

                /* Handle by view orientation type. */
                switch(v->type)
            {
                  case VMA_VIEW2D_TYPE_XY:
                    if(VMA_PRIMITIVES_MAX_VALUES < 6)
                        break;
/* Need to work on this. */

/*              need_has_change = TRUE; */
                break;

                  case VMA_VIEW2D_TYPE_YZ:
                    if(VMA_PRIMITIVES_MAX_VALUES < 6)
                        break;
/* Need to work on this. */
        
/*                  need_has_change = TRUE; */
                    break;

                  case VMA_VIEW2D_TYPE_XZ:
                    if(VMA_PRIMITIVES_MAX_VALUES < 6)
                        break;
/* Need to work on this. */
        
/*                  need_has_change = TRUE; */
                    break;
                }
                     
                /* Is event a final position set? */
                if(set2d->is_final)
                {
                    /* Is a final position set event, record undo. */
                    vma_undo_set_normal_struct *u = (vma_undo_set_normal_struct *)VMAUndoNew(
                        VMA_UNDO_TYPE_SET_NORMAL, "Set Normal"
                    );
                    if(u != NULL)
                    {
                        u->editor = editor;
                        u->model_num = model_num;
                        u->primitive_num = pn;
                        u->vertex_num = norm_num;
                        u->n.x = old_n.x;
                        u->n.y = old_n.y;
                        u->n.z = old_n.z;
                        EditorUndoRecord(editor, u);
                    }
                }
            }
        }

        /* Call values text prompts enter callback to set the new
         * changed values.
         */
        if(need_has_change)
        {
            EDITOR_DO_UPDATE_HAS_CHANGES
            if(set2d->is_initial && !set2d->is_final)
            {
                EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }
            if(set2d->is_final)
            {
/* This is going to be a problem here, we need to have a way to
 * tell it to apply the normal and not the vertex.
 */
            /* Apply values from prompts only if one value was
             * selected.
             */
                if(editor->total_selected_values == 1)
                EditorListValuePromptApply(
                  editor,
                  NULL, /* Passing NULL means only apply vertexes. */
                  FALSE /* Do not record undo, we probably have
                         * already done so above.
                         */
                );
                EditorUpdateMenus(editor);
                EditorUpdateAllViewMenus(editor);
            }
            EditorRedrawAllViews(editor);
        }

      return;
}


/*
 *    Handles a select rectangular area, checks which primitive(s) on
 *    the given model is under the selection.
 */
static void EditorView2DEventSelectRectangular(
        ma_editor_struct *editor,
      vma_view_event_select2d_struct *select2d,
        gint model_num, v3d_model_struct *model_ptr
)
{
      GtkCList *primitives_list, *values_list;
        vma_view2d_struct *v;
      gint *matched_primitive = NULL;
      gint *matched_vertex = NULL;  /* Corresponding to each matched
                               * primitive.
                               */
      gint n, pn, total_matched_primitives = 0;
      gint vertex_num;


#define DO_FREE_LOCALS  \
{ \
 g_free(matched_primitive); matched_primitive = NULL; \
 g_free(matched_vertex); matched_vertex = NULL; \
 total_matched_primitives = 0; \
}
        if((editor == NULL) || (select2d == NULL))
      {
          DO_FREE_LOCALS
            return;
      }

      primitives_list = (GtkCList *)editor->primitives_list;
      if(primitives_list == NULL)
      {
          DO_FREE_LOCALS
          return;
      }
      values_list = (GtkCList *)editor->values_list;
        if(values_list == NULL)
      {
          DO_FREE_LOCALS
            return;
      }


        /* Get pointer to view from event structure. */
        v = select2d->view2d;
        if(v == NULL)
      {
          DO_FREE_LOCALS
            return;
      }

        /* Given referance to model must be valid. */
        if(model_ptr == NULL)
      {
          DO_FREE_LOCALS
            return;
      }


      /* Reset starting primitive number. */
      pn = -1;

      /* Begin allocating a list of matched primitives. */
      do
      {
          /* Match next primitive. */
          pn = EditorSelectPrimitiveRectangular(
            editor,
            v->type,          /* View plane. */
                select2d->vi0, select2d->vj0,
                select2d->vi1, select2d->vj1,
            pn + 1,                 /* Starting index. */
                &vertex_num         /* Matched vertex number return. */
            );
            if(pn > -1)
            {
            n = total_matched_primitives;
            total_matched_primitives = n + 1;
            matched_primitive = (gint *)g_realloc(
                matched_primitive,
                total_matched_primitives * sizeof(gint)
            );
            matched_vertex = (gint *)g_realloc(
                matched_vertex,
                total_matched_primitives * sizeof(gint)
                );
            if((matched_primitive == NULL) ||
               (matched_vertex == NULL)
            )
            {
                /* Memory allocation error. */
                DO_FREE_LOCALS
                break;  /* Give up. */
            }
            else
            {
                matched_primitive[n] = pn;
                matched_vertex[n] = vertex_num;
            }
          }

      } while(pn > -1);

      /* Got only one match? */
      if(total_matched_primitives == 1)
      {
          gint cur_pn = ((editor->total_selected_primitives == 1) ?
            editor->selected_primitive[0] : -1
          );
          gint cur_vertex_num = EditorGetSelected(
                editor->selected_value, editor->total_selected_values,
                0
            );

          n = 0;  /* Matched index value to use. */

          /* Newly matched primitive is not the same as the current
           * selected primitive on the editor or the vertexes are
           * not the same?
           */
          if((matched_primitive[n] != cur_pn) ||
               (matched_vertex[n] != cur_vertex_num)
          )
          {
            /* Unselect any selected rows on the editor's primitives
             * list.
             */
            if(editor->total_selected_primitives > 0)
                gtk_clist_unselect_all(primitives_list);

            /* Now select primitive item on primitives list by
             * instructing the primitives gui list to do so.
             * It should then call the callback to select the
             * row on the real list and update the values list.
             */
            gtk_clist_select_row(
                primitives_list,
                matched_primitive[n], 0   /* Row, column. */
            );

            /* Select vertex on values list? */
            if(matched_vertex[n] > -1)
                gtk_clist_select_row(
                  values_list, matched_vertex[n], 0
                );
          }
      }
      /* Got more than one match? */
      else if(total_matched_primitives > 0)
      {
          gint j, status;
          gbool need_break, yes_to_all = FALSE;
          gchar buf[1024];


          /* Unselect all primitives (if any). */
          gtk_clist_unselect_all(primitives_list);  

          /* Begin selecting each primitive one by one and querying
           * the user to continue.
           */
          for(n = 0; n < total_matched_primitives; n++)
          {
                /* Select primitive item on primitives list by
                 * instructing the primitives gui list to do so.
                 * It should then call the callback to select the
                 * row on the real list and update the values list.
                 */
                gtk_clist_select_row(
                    primitives_list,
                    matched_primitive[n], 0     /* Row, column. */
                );

                /* Select vertex on values list? */
                if(matched_vertex[n] > -1)
                    gtk_clist_select_row(
                        values_list,
                  matched_vertex[n], 0    /* Row, column. */
                    );

            /* Format message. */
            if(matched_vertex[n] > -1)
                sprintf(
                  buf,
"Selected primitive #%i (%i of %i) at vertex #%i.\n\
\n\
Click `yes' to keep select, `no' to skip select,\n\
or `cancel' to end select.",
                  matched_primitive[n],
                  n + 1, total_matched_primitives,
                  matched_vertex[n]
                );
            else
                sprintf(
                        buf,
"Selected primitive #%i (%i of %i).\n\
\n\
Click `yes' to keep select, `no' to skip select,\n\
or `cancel' to end select.",
                        matched_primitive[n],
                        n + 1, total_matched_primitives
                    );
            need_break = FALSE;
            if(yes_to_all)
            {
                status = CDIALOG_RESPONSE_YES;
            }
            else
            {
                CDialogSetTransientFor(editor->toplevel);
                status = CDialogGetResponse(
                  "Selected primitive",
                  buf,
                  NULL,
                  CDIALOG_ICON_QUESTION,
                  CDIALOG_BTNFLAG_YES | CDIALOG_BTNFLAG_YES_TO_ALL |
                  CDIALOG_BTNFLAG_NO | CDIALOG_BTNFLAG_CANCEL,
                  CDIALOG_BTNFLAG_YES
                );
            }
            switch(status)
            {
              case CDIALOG_RESPONSE_NOT_AVAILABLE:
              case CDIALOG_RESPONSE_CANCEL:
                    gtk_clist_unselect_row(
                        primitives_list,
                        matched_primitive[n], 0
                    );
                for(j = n; j < total_matched_primitives; j++)
                {
                  matched_primitive[j] = -1;
                        matched_vertex[j] = -1;
                }
                need_break = TRUE;
                break;

              case CDIALOG_RESPONSE_YES_TO_ALL:
                yes_to_all = TRUE;
                break;

              case CDIALOG_RESPONSE_NO:
                /* User responded with skip/no, so set this match
                 * to -1.
                 */
                    gtk_clist_unselect_row(
                        primitives_list,
                        matched_primitive[n], 0
                    );
                matched_primitive[n] = -1;
                matched_vertex[n] = -1;
                break;
            }
            CDialogSetTransientFor(NULL);
            if(need_break)
                break;
          }

          /* Begin implicitly selecting values backwards. Each value
           * corresponds to a primitive's vertex.
           */
          EditorUnselectAll(
            &editor->selected_value, &editor->total_selected_values
          );
          for(n = 0; n < total_matched_primitives; n++)
            {
                if(matched_primitive[n] < 0)
                    continue;

                EditorSelect(
                    &editor->selected_value,
                    &editor->total_selected_values,
                    matched_vertex[n]
            );
          }

            /* Need to reset all views' drag modifiers since the
             * confirmation dialog may have intercepted events from
             * the user that would other wise be used to indicate drag
             * end.
             */
/*
          for(n = 0; n < VMA_MAX_2D_VIEWS_PER_EDITOR; n++)
            View2DResetDragMods(editor->view2d[n]);
            for(n = 0; n < VMA_MAX_3D_VIEWS_PER_EDITOR; n++)
                View3DResetDragMods(editor->view3d[n]);
 */

          /* Update menus since we did some explicit selecting. */
          EditorUpdateMenus(editor);
          EditorUpdateAllViewMenus(editor);         
          EditorRedrawAllViews(editor);
      }

      /* Deallocate matched primitives and vertices list. */
      DO_FREE_LOCALS
#undef DO_FREE_LOCALS
}


/*
 *    2d view event callback (not a GUI event callback).
 *
 *    Handles events like VMA_VIEW_EVENT_TYPE_POINT_SELECT.
 *
 *    Argument 1 is the client_data, argument 2 is the
 *    vma_view_event_*_struct.
 */
void EditorView2DEventCB(
      void *client_data,      /* ma_editor_struct. */
      void *event       /* vma_view_event_*_struct. */
)
{
      gint i, vtype, model_num, pn, value_num;
      v3d_model_struct *model_ptr;
      gpointer p, u;
      vma_view2d_struct *v;
      vma_view_event_set2d_struct *set2d;
      vma_view_event_settocursor2d_struct *settocursor2d;
      ma_editor_struct *editor = (ma_editor_struct *)client_data;
      if((editor == NULL) || (event == NULL))
          return;

      /* Get current selected model on editor.*/
      model_num = EditorSelectedModelIndex(editor);
        model_ptr = V3DModelListGetPtr(
            editor->model, editor->total_models, model_num
        );
      if(model_ptr == NULL)
          model_num = -1;

      /* Model pointer may be NULL. */


#define RESET_NET_TRANSLATE_DELTAS  \
{ \
 net_translate_delta.x = net_translate_delta.y = \
  net_translate_delta.z = 0.0; \
}

      /* Handle by 2d view event type. */
      switch(*(gint *)event)
      {
        case VMA_VIEW_EVENT_TYPE_SETTOCURSOR2D:
            /* Model must be selected. */
            if(model_ptr == NULL)
                break;
                    
            /* Make sure write protect is off. */
            if(VMAWriteProtectCheck(editor))
                break;

            /* Get pointer to event structure. */
            settocursor2d = (vma_view_event_settocursor2d_struct *)event;
            /* Get pointer to view structure (must be valid). */
            v = settocursor2d->view2d;
            if(v == NULL)
                break;
          vtype = v->type;

            /* Is event is a initial position set? */
            if(settocursor2d->is_initial)
                RESET_NET_TRANSLATE_DELTAS

          /* Do not update net_translate_delta since setting to cursor
           * does not produce deltas.
           */

            /* Handle by vertex type. */
            switch(settocursor2d->vertex_type)
            {
              case 2:  
/* Need to work on setting texcoord. */
                break;

              case 1: 
/* Need to work on setting 3d normal. */
            break;

             default:
                /* Itterate through each selected primitive. */
                for(i = 0; i < editor->total_selected_primitives; i++)
                {
                    /* Get this selected primitive. */
                    pn = editor->selected_primitive[i];
                    p = V3DMPListGetPtr(
                        model_ptr->primitive, model_ptr->total_primitives, pn
                    );
                    if(p == NULL)
                        continue;

                    /* Get corresponding value number for the selected
                     * primitive.
                     */
                    value_num = EditorGetSelected(
                        editor->selected_value, editor->total_selected_values,
                        i
                    );

                    /* Process the primitive's vertex specified by
                     * value_num and record undo.
                     */
                    EditorView2DEventSetVertexToCursor(
                        editor, settocursor2d,
                        model_num, model_ptr,
                        pn, p, value_num
                    );
                }
                /* Update undo repeats for newest undo, so that the undo
                 * process will handle this entire series of undos.
                 */
                for(i = 0; i < editor->total_selected_primitives; i++)
                {
                    u = VMAUndoListGetPtr(
                        editor->undo, editor->total_undos,
                        editor->total_undos - i - 1
                    );
                    VMAUndoSetRepeats(u, editor->total_selected_primitives);
                }
            break;
          }
          break;

        /* Cursor update, cursor on the view has moved.
         * Need to update other views on editor about
         * cursor change and redraw those views.
         */
        case VMA_VIEW_EVENT_TYPE_CURSOR2D:
          EditorView2DEventSetCursor(
            editor, (vma_view_event_cursor2d_struct *)event
          );
          break;

        /* Set vertex, need to check which primitive is selected
         * on the editor and move its vertex depending on the
         * primitive type and which vertex is selected.
         */
        case VMA_VIEW_EVENT_TYPE_SET2D:
          /* Model must be selected. */
          if(model_ptr == NULL)
            break;

          /* Make sure write protect is off. */
            if(VMAWriteProtectCheck(editor))
            break;

          /* Get pointer to event structure. */
          set2d = (vma_view_event_set2d_struct *)event;
          /* Get pointer to view structure (must be valid). */
          v = set2d->view2d;
          if(v == NULL)
            break;
          vtype = v->type;

            /* Is event is a initial position set? */
            if(set2d->is_initial)
            RESET_NET_TRANSLATE_DELTAS

          /* Update net translation deltas. */
          switch(vtype)
          {
            case VMA_VIEW2D_TYPE_XY:
            net_translate_delta.x += set2d->vdi;
            net_translate_delta.y += set2d->vdj;
            break;
            case VMA_VIEW2D_TYPE_YZ:
            net_translate_delta.y += set2d->vdi;
            net_translate_delta.z += set2d->vdj;
            break;
              case VMA_VIEW2D_TYPE_XZ:
                net_translate_delta.x += set2d->vdi;
                net_translate_delta.z += set2d->vdj;
                break;
          }

          /* Handle by vertex type. */
          switch(set2d->vertex_type)
          {
            case 2:
/* Need to work on setting texcoord. */
            break;

            case 1:
                /* Itterate through each selected primitive. */
                for(i = 0; i < editor->total_selected_primitives; i++)
                {
                    /* Get this selected primitive. */
                    pn = editor->selected_primitive[i];
                    p = V3DMPListGetPtr(
                        model_ptr->primitive, model_ptr->total_primitives, pn
                    );
                    if(p == NULL)
                        continue;

                    /* Get corresponding value number for the selected
                     * primitive.
                     */
                    value_num = EditorGetSelected(
                        editor->selected_value, editor->total_selected_values,
                        i
                    );

                    /* Process the primitive's vertex normal specified by
                     * value_num and record undo.
                     */
                EditorView2DEventSetNormal(
                  editor, set2d,
                  model_num, model_ptr,
                  pn, p, value_num
                );
                }
                /* Update undo repeats for newest undo, so that the undo
             * process will handle this entire series of undos.
             */
/* Uncomment this when we actually do set the normal.
                for(i = 0; i < editor->total_selected_primitives; i++)
                {
                    u = VMAUndoListGetPtr(
                        editor->undo, editor->total_undos,
                        editor->total_undos - i - 1
                    );
                    VMAUndoSetRepeats(u, editor->total_selected_primitives);
                }
*/
            break;

            default:
            /* Itterate through each selected primitive. */
            for(i = 0; i < editor->total_selected_primitives; i++)
            {
                /* Get this selected primitive. */
                pn = editor->selected_primitive[i];
                p = V3DMPListGetPtr(
                  model_ptr->primitive, model_ptr->total_primitives, pn
                );
                if(p == NULL)
                  continue;

                /* Get corresponding value number for the selected
                 * primitive.
                 */
                value_num = EditorGetSelected(
                  editor->selected_value, editor->total_selected_values,
                  i
                );

                /* Process the primitive's vertex specified by 
                 * value_num and record undo.
                 */
                EditorView2DEventSetVertex(
                  editor, set2d,
                  model_num, model_ptr,
                  pn, p, value_num
                );
            }
                /* Update undo repeats for newest undo, so that the undo  
                 * process will handle this entire series of undos.
                 */
            for(i = 0; i < editor->total_selected_primitives; i++)
            {
                u = VMAUndoListGetPtr(
                  editor->undo, editor->total_undos,
                  editor->total_undos - i - 1
                );
                VMAUndoSetRepeats(u, editor->total_selected_primitives);
            }
            break;
          }
          break;

        /* Select rectangular, need to check which primitive is
         * selected by the given region.
         */
        case VMA_VIEW_EVENT_TYPE_SELECT2D:
            /* Model must be selected. */
            if(model_ptr == NULL)
                break;

          /* Handle rectangular select. */
          EditorView2DEventSelectRectangular(
            editor, (vma_view_event_select2d_struct *)event,
            model_num, model_ptr
          );
          break;
      }

#undef RESET_NET_TRANSLATE_DELTAS

      return;
}

/*
 *      3d view event callback.
 *
 *      Argument 1 is the client_data, argument 2 is the
 *      vma_view_event_*_struct.
 */
void EditorView3DEventCB(
        void *client_data,    /* ma_editor_struct. */
        void *event           /* vma_view_event_*_struct. */
)
{
        ma_editor_struct *editor = (ma_editor_struct *)client_data;
        if((editor == NULL) ||
           (event == NULL)
        )
          return;


      return;
}

Generated by  Doxygen 1.6.0   Back to index