Logo Search packages:      
Sourcecode: vertex version File versions

editorheadercb.c

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

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

#include "v3dmh.h"
#include "v3dmodel.h"
#include "guiutils.h"
#include "cdialog.h"
#include "fb.h"

#include "texbrowser.h"
#include "texbrowsercb.h"

#include "editor.h"
#include "editorcb.h"
#include "editoridialog.h"
#include "editorp.h"
#include "editortexture.h"
#include "editorviewcb.h"
#include "editorheadercb.h"

#include "msglist.h"
#include "messages.h"
#include "vma.h"
#include "vmautils.h"

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


#include "images/icon_header_general_20x20.xpm"
#include "images/icon_folder_opened_20x20.xpm"
#include "images/icon_texture_20x20.xpm"
#include "images/icon_reload_20x20.xpm"


static void EditorHeaderTexturesRefreshCB(GtkWidget *widget, gpointer *data);
static void EditorHeaderTexturesEditCB(GtkWidget *widget, gpointer *data);

static void EditorHeaderTexturesBaseBrowseCB(void *widget, void *data);
static void EditorHeaderHeightfieldBaseBrowseCB(void *widget, void *data);
static gint EditorHeaderSwitchPage1CB(
      GtkWidget *widget, GdkEvent *event, gpointer data
);
static gint EditorHeaderSwitchPage2CB(
        GtkWidget *widget, GdkEvent *event, gpointer data  
);
static gint EditorHeaderSwitchPage3CB(
        GtkWidget *widget, GdkEvent *event, gpointer data
);
static void EditorHeaderSwitchPageCB(
        GtkNotebook *notebook, GtkNotebookPage *page, guint page_num,
        gpointer data
);

static void EditorHeaderFetchValues(
        ma_editor_struct *editor, ma_editor_idialog_struct *d 
);

void EditorHeaderCB(GtkWidget *widget, gpointer data);
static void EditorHeaderOKCB(void *idialog, void *data);
static void EditorHeaderApplyCB(void *idialog, void *data);
static void EditorHeaderCancelCB(void *idialog, void *data);


#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)
#define DEGTORAD(d)     ((d) * PI / 180.0)


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


/*
 *    Reload textures button callback.
 */
static void EditorHeaderTexturesRefreshCB(GtkWidget *widget, gpointer *data)
{
        static gbool reenterant = FALSE;
      int i;
      void *h;
        GtkWidget *w;
      GtkCList *clist;
      mh_texture_load_struct *mh_texture_load;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
      ma_editor_struct *editor;
        if(d == NULL)
            return;

      editor = (ma_editor_struct *)d->editor_ptr;
      if(editor == NULL)
          return;

      w = EditorIDialogGetWidget(d, 4);
      if((w == NULL) ? 1 : !GTK_IS_CLIST(w))
          return;

      clist = GTK_CLIST(w);

        if(reenterant)
            return;
        else
            reenterant = TRUE;

      gtk_clist_freeze(clist);
      gtk_clist_clear(clist);

      for(i = 0; i < editor->total_mh_items; i++)
      {
          h = editor->mh_item[i];
          if(h == NULL)
            continue;

          switch(*(int *)h)
          {
              case V3DMH_TYPE_TEXTURE_LOAD:
                mh_texture_load = (mh_texture_load_struct *)h;
            if(clist != NULL)
                {
                    gchar *val[3];
                    char num_str[80];
                
                    val[0] = strdup((mh_texture_load->name == NULL) ?
                        "(null)" : mh_texture_load->name 
                    );
                    val[1] = strdup((mh_texture_load->path == NULL) ?
                        "(null)" : mh_texture_load->path
                    );
                    sprintf(num_str, "%f", mh_texture_load->priority);
                    val[2] = strdup(num_str);
                        
                    gtk_clist_append(clist, val);
         
                    free(val[0]);
                    free(val[1]);
                    free(val[2]);
                }
            break;

/* Ignore all other types. */
          }
      }

      gtk_clist_thaw(clist);


      reenterant = FALSE;
      return;
}

/*
 *    Edit textures button callback.
 */
static void EditorHeaderTexturesEditCB(GtkWidget *widget, gpointer *data)
{
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        ma_editor_struct *editor;
        if(d == NULL)
            return;

        editor = (ma_editor_struct *)d->editor_ptr;
        if(editor == NULL)
            return;

      EditorMapTextureBrowserCB(NULL, (gpointer)editor);

      return;
}


/*
 *    Browse textures base directory callback.
 */
static void EditorHeaderTexturesBaseBrowseCB(void *widget, void *data)
{
        static gbool reenterant = FALSE;
      gbool status;
      GtkWidget *w;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        if(d == NULL)
            return;

        if(reenterant)
            return;
        else
            reenterant = TRUE;

        /* Get widget 2, the textures base directory entry. */
        w = EditorIDialogGetWidget(d, 2);
        if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
        {
            const char *last_path;
            char **fb_path_rtn = NULL;
            int fb_path_total_rtns = 0; 
            fb_type_struct *fb_type_rtn = NULL;

            /* Get last path as current value on entry. */
            last_path = (const char *)gtk_entry_get_text(GTK_ENTRY(w));

          FileBrowserSetTransientFor(d->toplevel);
            status = FileBrowserGetResponse(
                "Textures Base Directory",
                "Select", "Cancel",
                last_path,              /* Last path. */
                ftype.select_directory, ftype.select_directory_total,
                &fb_path_rtn, &fb_path_total_rtns,
                &fb_type_rtn
            );
          FileBrowserSetTransientFor(NULL);

          if(status)
            {
                if((fb_path_rtn != NULL) && (fb_path_total_rtns > 0))
                {
                    const char *new_path = (const char *)fb_path_rtn[0];
                    if(new_path != NULL)
                        gtk_entry_set_text(GTK_ENTRY(w), new_path);
                }  
            }
        }

        reenterant = FALSE;
}

/*
 *      Browse heightfield base directory callback.
 */      
static void EditorHeaderHeightfieldBaseBrowseCB(void *widget, void *data)
{
        static gbool reenterant = FALSE;
      gbool status;
      GtkWidget *w;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        if(d == NULL)
            return;

        if(reenterant)
            return;
        else
            reenterant = TRUE;

        /* Get widget 3, the heightfield base directory entry. */
        w = EditorIDialogGetWidget(d, 3);
        if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
        {
          const char *last_path;
          char **fb_path_rtn = NULL;
          int fb_path_total_rtns = 0;
          fb_type_struct *fb_type_rtn = NULL;

          /* Get last path as current value on entry. */
          last_path = (const char *)gtk_entry_get_text(GTK_ENTRY(w));

          FileBrowserSetTransientFor(d->toplevel);
          status = FileBrowserGetResponse(
                "Heightfield Base Directory",
                "Select", "Cancel",
                last_path,          /* Last path. */
                ftype.select_directory, ftype.select_directory_total,
                &fb_path_rtn, &fb_path_total_rtns,
                &fb_type_rtn
            );
          FileBrowserSetTransientFor(NULL);

          if(status)
            {  
                if((fb_path_rtn != NULL) && (fb_path_total_rtns > 0))
                {
                const char *new_path = (const char *)fb_path_rtn[0];
                if(new_path != NULL)
                  gtk_entry_set_text(GTK_ENTRY(w), new_path);
                }
          }
        }   

        reenterant = FALSE;
}

/*
 *    Switch to page 1 button event callback.
 */
static gint EditorHeaderSwitchPage1CB(
        GtkWidget *widget, GdkEvent *event, gpointer data  
)
{
      const int page_num = 0;
        GtkWidget *w;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        if(d == NULL)
            return(FALSE);

        /* Get widget 0, the main notebook. */
        w = EditorIDialogGetWidget(d, 0);
        if(w != NULL)
            gtk_notebook_set_page(GTK_NOTEBOOK(w), page_num);

        return(TRUE);
}

/*
 *      Switch to page 2 button event callback.
 */
static gint EditorHeaderSwitchPage2CB(
        GtkWidget *widget, GdkEvent *event, gpointer data
)
{
      const int page_num = 1;
      GtkWidget *w;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        if(d == NULL)
            return(FALSE);

        /* Get widget 0, the main notebook. */
        w = EditorIDialogGetWidget(d, 0);
        if(w != NULL)
          gtk_notebook_set_page(GTK_NOTEBOOK(w), page_num);

      return(TRUE);
}

/*
 *      Switch to page 3 button event callback.
 */
static gint EditorHeaderSwitchPage3CB(
        GtkWidget *widget, GdkEvent *event, gpointer data
)  
{
        const int page_num = 2;
        GtkWidget *w;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        if(d == NULL)
            return(FALSE);

        /* Get widget 0, the main notebook. */
        w = EditorIDialogGetWidget(d, 0);
        if(w != NULL)
            gtk_notebook_set_page(GTK_NOTEBOOK(w), page_num);

        return(TRUE);
}

/*
 *    Edit header note book switch page callback.
 */
static void EditorHeaderSwitchPageCB(
        GtkNotebook *notebook, GtkNotebookPage *page, guint page_num,
        gpointer data
)
{
        static gbool reenterant = FALSE;
        GtkWidget *w;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)data;
        if((notebook == NULL) || (d == NULL))
            return;

        if(reenterant)
            return;
        else
            reenterant = TRUE;

        /* Get widget 0, the main notebook. */
        w = EditorIDialogGetWidget(d, 0);
        if((w != NULL) && (w == GTK_WIDGET(notebook)))
        {
            




            
        }

        reenterant = FALSE;
        return;
}           


/*
 *    Edit header fetch values, fetches values from the model header
 *    items on the given editor to the given input dialog that is
 *    assumed to be set up properly from a prior call to 
 *    EditorHeaderCB().
 *
 *    This function should only be called from EditorHeaderCB().
 */
static void EditorHeaderFetchValues(
      ma_editor_struct *editor, ma_editor_idialog_struct *d
)
{
      int i;
      void *h;
      mh_author_struct *mh_author;
      mh_heightfield_base_directory_struct *mh_heightfield_base;
      mh_texture_base_directory_struct *mh_texture_base;
      mh_texture_load_struct *mh_texture_load;
      GtkWidget *w;


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

      for(i = 0; i < editor->total_mh_items; i++)
      {
          h = editor->mh_item[i];
          if(h == NULL)
            continue;

          switch(*(int *)h)
          {
            case V3DMH_TYPE_AUTHOR:
            mh_author = (mh_author_struct *)h;
            /* Get widget 1, author entry. */
            w = EditorIDialogGetWidget(d, 1);
            if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
            {
                if(mh_author->author != NULL)
                  gtk_entry_set_text(GTK_ENTRY(w), mh_author->author);
            }
            break;

            case V3DMH_TYPE_HEIGHTFIELD_BASE_DIRECTORY:
            mh_heightfield_base = (mh_heightfield_base_directory_struct *)h;
                /* Get widget 3, heightfield base entry. */
                w = EditorIDialogGetWidget(d, 3);
                if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
                {
                    if(mh_heightfield_base->path != NULL)
                        gtk_entry_set_text(GTK_ENTRY(w), mh_heightfield_base->path);
                }
            break;

              case V3DMH_TYPE_TEXTURE_BASE_DIRECTORY:
                mh_texture_base = (mh_texture_base_directory_struct *)h;
                /* Get widget 2, texture base entry. */
                w = EditorIDialogGetWidget(d, 2);
                if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
                {
                    if(mh_texture_base->path != NULL)
                        gtk_entry_set_text(GTK_ENTRY(w), mh_texture_base->path);
                }
                break;

            case V3DMH_TYPE_TEXTURE_LOAD:
            mh_texture_load = (mh_texture_load_struct *)h;
            /* Skip this, we will load it afterwards by calling
             * EditorHeaderTexturesRefreshCB().
             */
            break;

/* Add additional model header item types that need their values fetched
 * here.
 */
          }
      }

      /* Reload all texture load model header items. */
      EditorHeaderTexturesRefreshCB(NULL, (gpointer)d);

      return;
}


/*
 *    Edit header callback.
 */
void EditorHeaderCB(GtkWidget *widget, gpointer data)
{
/*    const char *msglist[] = VMA_MSGLIST_EDITOR_TOOLTIPS; */
        GtkWidget *parent;
        ma_editor_idialog_struct *d;
        ma_editor_struct *editor = (ma_editor_struct *)data;
        if(editor == NULL)
            return;

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

        d = &editor->idialog;           /* Editor's input dialog. */

        /* Reset input dialog. */
        EditorIDialogReset(editor, d, FALSE); 

        /* Get input dialog's client vbox. */
        parent = EditorIDialogClientParent(d);
        if(parent != NULL)
        {
            /* Begin creating our widgets on input dialog, order;
             *
             *    0     Main notebook
           *
             *    1     Author entry
           *
           *      2     Textures base directory
           *      3     Heightfield base directory
           *
           *      4     Textures to load clist
           *      5     Refresh textures button
           *      6     Edit textures button
           *
           *      7     Predefined colors clist
           *      8     Refresh predefined colors clist
           *      *** more to come... ***
             */
          int     bw = (100 + (2 * 3)),
            bh = (30 + (2 * 3));
            void *entry, *browse_btn, *label;
            GtkWidget *w, *fixed, *parent2, *parent3, *parent4;
          gchar *heading[3];

            /* Set size of parent. */
            gtk_widget_set_usize(parent, 500, 300);


            /* Main notebook. */
            w = gtk_notebook_new();
            gtk_notebook_set_tab_pos(GTK_NOTEBOOK(w), GTK_POS_LEFT);
            gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
            gtk_notebook_set_scrollable(GTK_NOTEBOOK(w), TRUE);
            gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w), TRUE);
            gtk_notebook_set_show_border(GTK_NOTEBOOK(w), TRUE);
/*          gtk_notebook_set_page(GTK_NOTEBOOK(w), 0); */
            gtk_signal_connect(
                GTK_OBJECT(w), "switch_page",
                GTK_SIGNAL_FUNC(EditorHeaderSwitchPageCB),
                (gpointer)d
            );
            gtk_widget_show(w);
            /* Record as widget 0. */
            EditorIDialogRecordWidget(d, w);
            parent2 = w;


            /* Begin creating general info page. */
          fixed = w = (GtkWidget *)GUICreateMenuItemIcon(
            (u_int8_t **)icon_header_general_20x20_xpm
          );
            if(!GTK_WIDGET_NO_WINDOW(w))
            {
                gtk_widget_add_events(
                w,
                GDK_BUTTON_PRESS_MASK
            );
                gtk_signal_connect(
                    GTK_OBJECT(w), "button_press_event",
                    GTK_SIGNAL_FUNC(EditorHeaderSwitchPage1CB),
                   (gpointer)d
                );
          }
          gtk_widget_set_usize(fixed, 20, 20);
            w = gtk_vbox_new(FALSE, 5);
            gtk_notebook_append_page(
                GTK_NOTEBOOK(parent2), w,
                fixed
            );
            gtk_container_border_width(GTK_CONTAINER(w), 5);
            gtk_widget_show(w);
            parent3 = w;

          /* Author. */
          w = (GtkWidget *)GUIPromptBar(
                NULL, "Author:",
                NULL, &entry
            );
          gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
          gtk_widget_show(w);
          /* Record as widget 1. */
            EditorIDialogRecordWidget(d, (GtkWidget *)entry);


            /* Begin creating locations page. */
            fixed = w = (GtkWidget *)GUICreateMenuItemIcon(
                (u_int8_t **)icon_folder_opened_20x20_xpm
            );
            if(!GTK_WIDGET_NO_WINDOW(w))
            {
                gtk_widget_add_events(
                    w,
                    GDK_BUTTON_PRESS_MASK
                );   
                gtk_signal_connect(
                    GTK_OBJECT(w), "button_press_event",
                    GTK_SIGNAL_FUNC(EditorHeaderSwitchPage2CB),
                   (gpointer)d
                );
            }
            gtk_widget_set_usize(fixed, 20, 20);
            w = gtk_vbox_new(FALSE, 5);
            gtk_notebook_append_page(
                GTK_NOTEBOOK(parent2), w,
                fixed
            );
            gtk_container_border_width(GTK_CONTAINER(w), 5);
            gtk_widget_show(w);
            parent3 = w;

          /* Textures base directory. */
          w = (GtkWidget *)GUIPromptBarWithBrowse(
            NULL, "Textures Base:",
            NULL, &entry, &browse_btn,
            (void *)d,        /* Client data. */
            EditorHeaderTexturesBaseBrowseCB
          );
            gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
            gtk_widget_show(w);
            /* Record as widget 2. */
            EditorIDialogRecordWidget(d, (GtkWidget *)entry);

            /* Heightfield base directory. */
            w = (GtkWidget *)GUIPromptBarWithBrowse(
                NULL, "Heightfield Base:",
                NULL, &entry, &browse_btn,
                (void *)d,              /* Client data. */
                EditorHeaderHeightfieldBaseBrowseCB
            );
            gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
            gtk_widget_show(w);
            /* Record as widget 3. */
            EditorIDialogRecordWidget(d, (GtkWidget *)entry);


            /* Begin creating textures load page. */
            fixed = w = (GtkWidget *)GUICreateMenuItemIcon(
                (u_int8_t **)icon_texture_20x20_xpm
            );  
            if(!GTK_WIDGET_NO_WINDOW(w))
            {
                gtk_widget_add_events(
                    w,
                    GDK_BUTTON_PRESS_MASK 
                );
                gtk_signal_connect(
                    GTK_OBJECT(w), "button_press_event",
                    GTK_SIGNAL_FUNC(EditorHeaderSwitchPage3CB),
                   (gpointer)d
                );
            }
            gtk_widget_set_usize(fixed, 20, 20);
            w = gtk_vbox_new(FALSE, 5);
            gtk_notebook_append_page(
                GTK_NOTEBOOK(parent2), w,
                fixed
            );
            gtk_container_border_width(GTK_CONTAINER(w), 5);
            gtk_widget_show(w);
            parent3 = w;

          /* Texture load clist. */
            w = gtk_scrolled_window_new(NULL, NULL);
            gtk_scrolled_window_set_policy(
                GTK_SCROLLED_WINDOW(w), 
                GTK_POLICY_AUTOMATIC,
                GTK_POLICY_AUTOMATIC
            );
            gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
            gtk_widget_show(w);
            parent4 = w;

            heading[0] = strdup("Name");
            heading[1] = strdup("Path");
          heading[2] = strdup("Priority");
            w = gtk_clist_new_with_titles(3, heading);
            free(heading[0]);
            free(heading[1]);
          free(heading[2]);
            gtk_widget_set_usize(w, 350, 200);
            gtk_clist_column_titles_passive(GTK_CLIST(w));
            gtk_clist_set_selection_mode(GTK_CLIST(w), GTK_SELECTION_SINGLE);
            gtk_clist_set_row_height(GTK_CLIST(w), VMA_LIST_ROW_SPACING);
            gtk_clist_set_column_width(
                GTK_CLIST(w), 0, 120
            );
            gtk_clist_set_column_justification(
                GTK_CLIST(w), 0, GTK_JUSTIFY_LEFT   
            );
            gtk_clist_set_column_width(
                GTK_CLIST(w), 1, 160
            );
            gtk_clist_set_column_justification(
                GTK_CLIST(w), 1, GTK_JUSTIFY_LEFT   
            );
            gtk_clist_set_column_width(
                GTK_CLIST(w), 2, 30
            );
            gtk_clist_set_column_justification(
                GTK_CLIST(w), 2, GTK_JUSTIFY_LEFT   
            );
            gtk_container_add(GTK_CONTAINER(parent4), w);
            gtk_clist_set_shadow_type(GTK_CLIST(w), GTK_SHADOW_IN);
            gtk_widget_show(w);
            /* Record as widget 4. */
            EditorIDialogRecordWidget(d, w);


          /* Reload textures button. */
          w = gtk_hbox_new(TRUE, 5);
          gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
          gtk_widget_show(w);
          parent4 = w;

          w = (GtkWidget *)GUIButtonPixmapLabelH(
            (u_int8_t **)icon_reload_20x20_xpm,
            "Refresh", &label
          );
          gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
          gtk_widget_set_usize(w, bw, bh);
            GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
          gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorHeaderTexturesRefreshCB),
            (gpointer)d
          );
            gtk_widget_show(w);
            /* Record as widget 5. */
            EditorIDialogRecordWidget(d, w);

            w = (GtkWidget *)GUIButtonPixmapLabelH(
                (u_int8_t **)icon_texture_20x20_xpm,
                "Edit...", &label
            );
            gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
            gtk_widget_set_usize(w, bw, bh);
          GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
            gtk_signal_connect(
                GTK_OBJECT(w), "clicked",
                GTK_SIGNAL_FUNC(EditorHeaderTexturesEditCB),
                (gpointer)d
            );
            gtk_widget_show(w);
            /* Record as widget 6. */
            EditorIDialogRecordWidget(d, w);






          /* Fetch values from editor's model header items to
           * our set up input dialog.
           */
          EditorHeaderFetchValues(editor, d);
      }

        EditorIDialogMap(  
            editor, d,
            "Model Header",
            "OK", "Apply", "Cancel",
            (void *)editor,
            EditorHeaderOKCB,
            EditorHeaderApplyCB,
            EditorHeaderCancelCB
        );

      return;
}

/*
 *    Edit header ok callback.
 */
static void EditorHeaderOKCB(void *idialog, void *data)
{
        ma_editor_struct *editor;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)idialog;
        if(d == NULL)
            return;

        editor = (ma_editor_struct *)d->editor_ptr;
        if(editor == NULL)
            return;

      EditorHeaderApplyCB(idialog, data);

        EditorIDialogReset(editor, d, TRUE);

        return;
}

/*
 *    Edit header apply callback.
 */
static void EditorHeaderApplyCB(void *idialog, void *data)
{
        int i, mh_type, mh_item_num, total_mh_items;
        void **mh_item, *h;
        mh_author_struct *mh_author;
        mh_heightfield_base_directory_struct *mh_heightfield_base;
        mh_texture_base_directory_struct *mh_texture_base;
        GtkWidget *w;
        ma_editor_struct *editor;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)idialog;
        if(d == NULL)
            return;

        editor = (ma_editor_struct *)d->editor_ptr;
        if(editor == NULL)
            return;

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

      if(VMAWriteProtectCheck(editor))
            return;


      /* Create a local list of model header items, which will then
       * be transfered to the editor's list of model header items.
       * The old model header items on the editor will be deleted.
       */
      mh_item = NULL;
      total_mh_items = 0;

/* Creates a new model header item on the local mh_item list with the
 * given type specified by mh_type. On success h and mh_item_num will
 * be updated accordingly, or h will be NULL on error.
 */
#define DO_ADD_MH_ITEM_LOCAL  \
{ \
 mh_item_num = total_mh_items; \
 total_mh_items = mh_item_num + 1; \
 mh_item = (void **)realloc( \
  mh_item, \
  total_mh_items * sizeof(void *) \
 ); \
 if(mh_item == NULL) \
 { \
  mh_item_num = -1; \
  total_mh_items = 0; \
  h = NULL; \
 } \
 else \
 { \
  mh_item[mh_item_num] = h = (void *)V3DMHCreate(mh_type); \
 } \
}

      /* Widget 1, author entry. */
      w = EditorIDialogGetWidget(d, 1);
      if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
      {
          const char *cstrptr;

          mh_type = V3DMH_TYPE_AUTHOR;
          DO_ADD_MH_ITEM_LOCAL
          if(h != NULL)
          {
            mh_author = (mh_author_struct *)h;

            cstrptr = (const char *)gtk_entry_get_text(GTK_ENTRY(w));
            if(cstrptr != NULL)
            {
                free(mh_author->author);
                mh_author->author = strdup(cstrptr);
            }
          }
      }

      /* Widget 2, texture base entry. */
        w = EditorIDialogGetWidget(d, 2);
        if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
        {
            const char *cstrptr;

            mh_type = V3DMH_TYPE_TEXTURE_BASE_DIRECTORY;
            DO_ADD_MH_ITEM_LOCAL
            if(h != NULL)
            {
            mh_texture_base = (mh_texture_base_directory_struct *)h;

                cstrptr = (const char *)gtk_entry_get_text(GTK_ENTRY(w));
                if(cstrptr != NULL)
                {
                    free(mh_texture_base->path);
                    mh_texture_base->path = strdup(cstrptr);
                }
            }
        }

        /* Widget 3, heightfield base entry. */
        w = EditorIDialogGetWidget(d, 3);
        if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
        {
            const char *cstrptr;

            mh_type = V3DMH_TYPE_HEIGHTFIELD_BASE_DIRECTORY;
            DO_ADD_MH_ITEM_LOCAL
            if(h != NULL)
            {
                mh_heightfield_base = (mh_heightfield_base_directory_struct *)h;

                cstrptr = (const char *)gtk_entry_get_text(GTK_ENTRY(w));
                if(cstrptr != NULL)
                {
                    free(mh_heightfield_base->path);
                    mh_heightfield_base->path = strdup(cstrptr);
                }
            }
        }

      /* Transfer other model header items from the editor's model
       * header items list to our local list while filtering some
       * header item types that we do not want.
       */
      for(i = 0; i < editor->total_mh_items; i++)
        {
            h = editor->mh_item[i];
            if(h == NULL)
                continue;
          else
            mh_type = (*(int *)h);

          /* Skip these types because we already have them in our
           * local list, they will be left on the original list and
           * deleted afterwards.
           *
           * Add more types here as needed later on.
           */
          if((mh_type == V3DMH_TYPE_VERSION) ||
               (mh_type == V3DMH_TYPE_CREATOR) ||
               (mh_type == V3DMH_TYPE_AUTHOR) ||
               (mh_type == V3DMH_TYPE_HEIGHTFIELD_BASE_DIRECTORY) ||
               (mh_type == V3DMH_TYPE_TEXTURE_BASE_DIRECTORY)
          )
            continue;

          /* Allocate a new pointer on our local list. */
          mh_item_num = total_mh_items;
          total_mh_items = mh_item_num + 1;
          mh_item = (void **)realloc(
            mh_item,
            total_mh_items * sizeof(void *)
          );
            if(mh_item == NULL)
            {
                mh_item_num = -1;
                total_mh_items = 0;
            }
            else
            {
            /* Transfer from editor to our local list. */
                mh_item[mh_item_num] = editor->mh_item[i];

            /* Mark item as NULL on editor's model header items
             * list since it has been transfered.
             */
            editor->mh_item[i] = NULL;
          }
      }

      EDITOR_DO_UPDATE_HAS_CHANGES

      /* Delete existing model header items on editor. */
      V3DMHListDeleteAll(
          &editor->mh_item, &editor->total_mh_items
      );
      /* Transfer local mh_item list to editor's model header
       * items list.
       */
      editor->mh_item = mh_item;
      editor->total_mh_items = total_mh_items;

      mh_item = NULL;
      total_mh_items = 0;

      /* Reload textures and other resources specified by model
       * header items.
       */
      if(1)
      {
          ma_texture_browser_struct *tb = &editor->texture_browser;

          /* Delete all textures on the editor (this will also clear
           * the texture browser's list as well).
           */
          EditorTextureListDeleteAll(editor);

          /* Update texture browser's list of textures. */
          TexBrowserListDeleteAll(tb);    /* Should already be deleted. */
          TexBrowserListFetch(tb, editor);
          /* Update menus on texture browser. */
          TexBrowserUpdateMenus(tb);

          /* Reload all textures on editor. */
          EditorTextureLoadAll(editor);

          /* Re-realize all loaded primitives on all models. */
          for(i = 0; i < editor->total_models; i++)
            EditorPrimitiveRealizeAll(editor, i, TRUE);

          /* Update menus and redraw editor. */
          EditorUpdateMenus(editor);
            EditorUpdateAllViewMenus(editor);
            EditorRedrawAllViews(editor);
      }


#undef DO_ADD_MH_ITEM_LOCAL

      return;
}

/*
 *    Edit header cancel callback.
 */
static void EditorHeaderCancelCB(void *idialog, void *data)
{
        ma_editor_struct *editor;
        ma_editor_idialog_struct *d = (ma_editor_idialog_struct *)idialog;
        if(d == NULL)
            return;

        editor = (ma_editor_struct *)d->editor_ptr;
        if(editor == NULL)
            return;

        /* Reset input dialog and unmap it. */
        EditorIDialogReset(editor, d, TRUE);

        return;
}

Generated by  Doxygen 1.6.0   Back to index