home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / MapObject / mapobject_ui.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-24  |  46.2 KB  |  1,511 lines

  1. /**************************************************************/
  2. /* Dialog creation and updaters, callbacks and event-handlers */
  3. /**************************************************************/
  4.  
  5. #include <libgimp/gimp.h>
  6. #include <libgimp/gimpui.h>
  7.  
  8. #include <gck/gck.h>
  9.  
  10. #include "arcball.h"
  11. #include "mapobject_ui.h"
  12. #include "mapobject_image.h"
  13. #include "mapobject_apply.h"
  14. #include "mapobject_preview.h"
  15. #include "mapobject_main.h"
  16.  
  17. #include "config.h"
  18. #include "libgimp/stdplugins-intl.h"
  19.  
  20. #include "amb1.xpm"
  21. #include "amb2.xpm"
  22. #include "diffint1.xpm"
  23. #include "diffint2.xpm"
  24. #include "diffref1.xpm"
  25. #include "diffref2.xpm"
  26. #include "specref1.xpm"
  27. #include "specref2.xpm"
  28. #include "high1.xpm"
  29. #include "high2.xpm"
  30.  
  31. #include "pixmaps/zoom_in.xpm"
  32. #include "pixmaps/zoom_out.xpm"
  33.  
  34.  
  35. GckVisualInfo *visinfo     = NULL;
  36. GdkGC         *gc          = NULL;
  37. GtkWidget     *previewarea = NULL;
  38.  
  39. static GtkWidget   *appwin            = NULL;
  40. static GtkNotebook *options_note_book = NULL;
  41.  
  42. static GtkWidget *pointlightwid;
  43. static GtkWidget *dirlightwid;
  44.  
  45. static GtkObject *xadj, *yadj, *zadj;
  46.  
  47. static GtkWidget *box_page      = NULL;
  48. static GtkWidget *cylinder_page = NULL;
  49.  
  50. static guint left_button_pressed = FALSE;
  51. static guint light_hit           = FALSE;
  52.  
  53. static gboolean run = FALSE;
  54.  
  55.  
  56. static void create_main_notebook       (GtkWidget     *container);
  57.  
  58. static gint preview_events             (GtkWidget     *area,
  59.                     GdkEvent      *event);
  60.  
  61. static void update_light_pos_entries   (void);
  62.  
  63. static void double_adjustment_update   (GtkAdjustment *adjustment,
  64.                     gpointer       data);
  65.  
  66. static void toggle_update              (GtkWidget     *widget,
  67.                     gpointer       data);
  68.  
  69. static void togglegrid_update          (GtkWidget     *widget,
  70.                     gpointer       data);
  71. static void toggletips_update          (GtkWidget     *widget,
  72.                     gpointer       data);
  73.  
  74. static void lightmenu_callback         (GtkWidget     *widget,
  75.                     gpointer       data);
  76.  
  77. static void preview_callback           (GtkWidget     *widget,
  78.                     gpointer       data);
  79. static void apply_callback             (GtkWidget     *widget,
  80.                     gpointer       data);
  81.  
  82. static gint box_constrain              (gint32         image_id,
  83.                     gint32         drawable_id,
  84.                     gpointer       data);
  85. static void box_drawable_callback      (gint32         id,
  86.                     gpointer       data);
  87.  
  88. static gint cylinder_constrain         (gint32   image_id,
  89.                     gint32   drawable_id,
  90.                     gpointer data);
  91. static void cylinder_drawable_callback (gint32   id,
  92.                     gpointer data);
  93.  
  94. static GtkWidget * create_options_page     (void);
  95. static GtkWidget * create_light_page       (void);
  96. static GtkWidget * create_material_page    (void);
  97. static GtkWidget * create_orientation_page (void);
  98. static GtkWidget * create_box_page         (void);
  99. static GtkWidget * create_cylinder_page    (void);
  100.  
  101.  
  102. /******************************************************/
  103. /* Update angle & position (redraw grid if necessary) */
  104. /******************************************************/
  105.  
  106. static void
  107. double_adjustment_update (GtkAdjustment *adjustment,
  108.               gpointer       data)
  109. {
  110.   gimp_double_adjustment_update (adjustment, data);
  111.  
  112.   if (mapvals.showgrid)
  113.     draw_preview_wireframe ();
  114. }
  115.  
  116. static void
  117. update_light_pos_entries (void)
  118. {
  119.   gtk_signal_handler_block_by_data (GTK_OBJECT (xadj),
  120.                     &mapvals.lightsource.position.x);
  121.   gtk_adjustment_set_value (GTK_ADJUSTMENT (xadj),
  122.                 mapvals.lightsource.position.x);
  123.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (xadj),
  124.                       &mapvals.lightsource.position.x);
  125.   
  126.   gtk_signal_handler_block_by_data (GTK_OBJECT (yadj),
  127.                     &mapvals.lightsource.position.y);
  128.   gtk_adjustment_set_value (GTK_ADJUSTMENT (yadj),
  129.                 mapvals.lightsource.position.x);
  130.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (yadj),
  131.                       &mapvals.lightsource.position.y);
  132.   
  133.   gtk_signal_handler_block_by_data (GTK_OBJECT (zadj),
  134.                     &mapvals.lightsource.position.z);
  135.   gtk_adjustment_set_value (GTK_ADJUSTMENT (zadj),
  136.                 mapvals.lightsource.position.z);
  137.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (zadj),
  138.                       &mapvals.lightsource.position.z);
  139. }
  140.  
  141. /**********************/
  142. /* Std. toggle update */
  143. /**********************/
  144.  
  145. static void
  146. toggle_update (GtkWidget *widget,
  147.            gpointer   data)
  148. {
  149.   gimp_toggle_button_update (widget, data);
  150.  
  151.   draw_preview_image (TRUE);
  152.   linetab[0].x1 = -1;
  153. }
  154.  
  155. /***************************/
  156. /* Show grid toggle update */
  157. /***************************/
  158.  
  159. static void
  160. togglegrid_update (GtkWidget *widget,
  161.            gpointer   data)
  162. {
  163.   gimp_toggle_button_update (widget, data);
  164.  
  165.   if (mapvals.showgrid && linetab[0].x1 == -1)
  166.     draw_preview_wireframe ();
  167.   else if (!mapvals.showgrid && linetab[0].x1 != -1)
  168.     {
  169.       gck_gc_set_foreground (visinfo, gc, 255, 255, 255);
  170.       gck_gc_set_background (visinfo, gc, 0, 0, 0);
  171.  
  172.       gdk_gc_set_function (gc, GDK_INVERT);
  173.  
  174.       clear_wireframe ();
  175.       linetab[0].x1 = -1;
  176.     }
  177. }
  178.  
  179. /**************************/
  180. /* Tooltips toggle update */
  181. /**************************/
  182.  
  183. static void
  184. toggletips_update (GtkWidget *widget,
  185.            gpointer   data)
  186. {
  187.   gimp_toggle_button_update (widget, data);
  188.  
  189.   if (mapvals.tooltips_enabled)
  190.     gimp_help_enable_tooltips ();
  191.   else
  192.     gimp_help_disable_tooltips ();
  193. }
  194.  
  195. /*****************************************/
  196. /* Main window light type menu callback. */
  197. /*****************************************/
  198.  
  199. static void
  200. lightmenu_callback (GtkWidget *widget,
  201.             gpointer   data)
  202. {
  203.   gimp_menu_item_update (widget, data);
  204.  
  205.   if (mapvals.lightsource.type == POINT_LIGHT)
  206.     {
  207.       gtk_widget_hide (dirlightwid);
  208.       gtk_widget_show (pointlightwid);
  209.     }
  210.   else if (mapvals.lightsource.type == DIRECTIONAL_LIGHT)
  211.     {
  212.       gtk_widget_hide (pointlightwid);
  213.       gtk_widget_show (dirlightwid);
  214.     }
  215.   else
  216.     {
  217.       gtk_widget_hide (pointlightwid);
  218.       gtk_widget_hide (dirlightwid);
  219.     }
  220. }
  221.  
  222. /***************************************/
  223. /* Main window map type menu callback. */
  224. /***************************************/
  225.  
  226. static void
  227. mapmenu_callback (GtkWidget *widget,
  228.           gpointer   data)
  229. {
  230.   gimp_menu_item_update (widget, data);
  231.  
  232.   draw_preview_image (TRUE);
  233.  
  234.   if (mapvals.showgrid && linetab[0].x1 == -1)
  235.     draw_preview_wireframe ();
  236.   else if (!mapvals.showgrid && linetab[0].x1 != -1)
  237.     {
  238.       gck_gc_set_foreground (visinfo, gc, 255, 255, 255);
  239.       gck_gc_set_background (visinfo, gc, 0, 0, 0);
  240.  
  241.       gdk_gc_set_function (gc, GDK_INVERT);
  242.   
  243.       clear_wireframe ();
  244.       linetab[0].x1 = -1;
  245.     }
  246.  
  247.   if (mapvals.maptype == MAP_BOX)
  248.     {
  249.       if (cylinder_page != NULL)
  250.         {
  251.           gtk_notebook_remove_page
  252.         (options_note_book, 
  253.          g_list_length (options_note_book->children) - 1);
  254.           cylinder_page = NULL;
  255.         }
  256.  
  257.       if (box_page == NULL)
  258.         {
  259.           box_page = create_box_page ();
  260.           gtk_notebook_append_page (options_note_book,
  261.                     box_page,
  262.                     gtk_label_new (_("Box")));
  263.         }
  264.     }
  265.   else if (mapvals.maptype == MAP_CYLINDER)
  266.     {
  267.       if (box_page != NULL)
  268.         {
  269.           gtk_notebook_remove_page
  270.         (options_note_book,
  271.          g_list_length (options_note_book->children) - 1);
  272.           box_page = NULL;
  273.         }
  274.  
  275.       if (cylinder_page == NULL)
  276.     {
  277.       cylinder_page = create_cylinder_page ();
  278.       gtk_notebook_append_page (options_note_book,
  279.                     cylinder_page,
  280.                     gtk_label_new (_("Cylinder")));
  281.     }
  282.     }
  283.   else
  284.     {
  285.       if (box_page != NULL)
  286.         {
  287.           gtk_notebook_remove_page
  288.         (options_note_book, 
  289.          g_list_length (options_note_book->children) - 1);
  290.         }
  291.  
  292.       if (cylinder_page != NULL)
  293.         {
  294.           gtk_notebook_remove_page
  295.         (options_note_book, 
  296.          g_list_length (options_note_book->children) - 1);
  297.         }
  298.  
  299.       box_page = NULL;
  300.       cylinder_page = NULL;
  301.     }
  302. }
  303.  
  304. /******************************************/
  305. /* Main window "Preview!" button callback */
  306. /******************************************/
  307.  
  308. static void
  309. preview_callback (GtkWidget *widget,
  310.           gpointer   data)
  311. {
  312.   draw_preview_image (TRUE);
  313.   linetab[0].x1 = -1;
  314. }
  315.  
  316. /*********************************************/
  317. /* Main window "-" (zoom in) button callback */
  318. /*********************************************/
  319.  
  320. static void
  321. zoomout_callback (GtkWidget *widget,
  322.           gpointer   data)
  323. {
  324.   if (mapvals.preview_zoom_factor < 2)
  325.     {
  326.       mapvals.preview_zoom_factor++;
  327.       if (linetab[0].x1 != -1)
  328.         clear_wireframe ();
  329.       draw_preview_image (TRUE);
  330.     }
  331. }
  332.  
  333. /**********************************************/
  334. /* Main window "+" (zoom out) button callback */
  335. /**********************************************/
  336.  
  337. static void
  338. zoomin_callback (GtkWidget *widget,
  339.          gpointer   data)
  340. {
  341.   if (mapvals.preview_zoom_factor > 0)
  342.     {
  343.       mapvals.preview_zoom_factor--;
  344.       if (linetab[0].x1 != -1)
  345.         clear_wireframe ();
  346.       draw_preview_image (TRUE);
  347.     }
  348. }
  349.  
  350. /**********************************************/
  351. /* Main window "Apply" button callback.       */ 
  352. /* Render to GIMP image, close down and exit. */
  353. /**********************************************/
  354.  
  355. static void
  356. apply_callback (GtkWidget *widget,
  357.         gpointer   data)
  358. {
  359.   run = TRUE;
  360.  
  361.   gtk_main_quit ();
  362. }
  363.  
  364. static gint
  365. box_constrain (gint32   image_id,
  366.            gint32   drawable_id,
  367.            gpointer data)
  368. {
  369.   if (drawable_id == -1)
  370.     return TRUE;
  371.  
  372.   return (gimp_drawable_is_rgb (drawable_id) &&
  373.       !gimp_drawable_is_indexed (drawable_id));
  374. }
  375.  
  376. static void
  377. box_drawable_callback (gint32   id,
  378.                gpointer data)
  379. {
  380.   gint i;
  381.   
  382.   i = (gint) gtk_object_get_data (GTK_OBJECT (data), "_mapwid_id");
  383.  
  384.   mapvals.boxmap_id[i] = id;
  385. }
  386.  
  387. static gint
  388. cylinder_constrain (gint32   image_id,
  389.             gint32   drawable_id,
  390.             gpointer data)
  391. {
  392.   if (drawable_id == -1)
  393.     return TRUE;
  394.  
  395.   return (gimp_drawable_is_rgb (drawable_id) &&
  396.       !gimp_drawable_is_indexed (drawable_id));
  397. }
  398.  
  399. static void
  400. cylinder_drawable_callback (gint32   id,
  401.                 gpointer data)
  402. {
  403.   gint i;
  404.   
  405.   i = (gint) gtk_object_get_data (GTK_OBJECT (data), "_mapwid_id");
  406.  
  407.   mapvals.cylindermap_id[i] = id;
  408. }
  409.  
  410. /******************************/
  411. /* Preview area event handler */
  412. /******************************/
  413.  
  414. static gint
  415. preview_events (GtkWidget *area,
  416.         GdkEvent  *event)
  417. {
  418.   HVect pos;
  419. /*  HMatrix RotMat;
  420.   gdouble a,b,c; */
  421.  
  422.   switch (event->type)
  423.     {
  424.       case GDK_EXPOSE:
  425.  
  426.         /* Is this the first exposure? */
  427.         /* =========================== */
  428.  
  429.         if (!gc)
  430.           {
  431.             gc = gdk_gc_new (area->window);
  432.             draw_preview_image (TRUE);
  433.           }
  434.         else
  435.           {
  436.             draw_preview_image (FALSE);
  437.             if (mapvals.showgrid == 1 && linetab[0].x1 != -1)
  438.               draw_preview_wireframe ();
  439.           }
  440.         break; 
  441.       case GDK_ENTER_NOTIFY:
  442.         break;
  443.       case GDK_LEAVE_NOTIFY:
  444.         break;
  445.       case GDK_BUTTON_PRESS:
  446.         light_hit = check_light_hit (event->button.x, event->button.y);
  447.         if (light_hit == FALSE)
  448.           {
  449.             pos.x = -(2.0 * (gdouble) event->button.x /
  450.               (gdouble) PREVIEW_WIDTH - 1.0);
  451.             pos.y = (2.0 * (gdouble) event->button.y /
  452.              (gdouble) PREVIEW_HEIGHT - 1.0);
  453.             /*ArcBall_Mouse(pos);
  454.             ArcBall_BeginDrag(); */
  455.           }
  456.         left_button_pressed = TRUE;
  457.         break;
  458.       case GDK_BUTTON_RELEASE:
  459.         if (light_hit == TRUE)
  460.           draw_preview_image (TRUE);
  461.         else
  462.           {
  463.             pos.x = -(2.0 * (gdouble) event->button.x /
  464.               (gdouble) PREVIEW_WIDTH - 1.0);
  465.             pos.y = (2.0 * (gdouble) event->button.y /
  466.              (gdouble) PREVIEW_HEIGHT - 1.0);
  467.             /*ArcBall_Mouse(pos);
  468.             ArcBall_EndDrag(); */
  469.           }
  470.         left_button_pressed = FALSE;
  471.         break;
  472.       case GDK_MOTION_NOTIFY:
  473.         if (left_button_pressed == TRUE)
  474.           {
  475.             if (light_hit == TRUE)
  476.               {
  477.                 update_light (event->motion.x, event->motion.y);
  478.                 update_light_pos_entries ();
  479.               }
  480.             else
  481.               {
  482.                 pos.x = -(2.0 * (gdouble) event->motion.x /
  483.               (gdouble) PREVIEW_WIDTH - 1.0);
  484.                 pos.y = (2.0 * (gdouble) event->motion.y /
  485.              (gdouble) PREVIEW_HEIGHT - 1.0);
  486. /*                ArcBall_Mouse(pos);
  487.                 ArcBall_Update();
  488.                 ArcBall_Values(&a,&b,&c);
  489.                 Alpha+=RadToDeg(-a);
  490.                 Beta+RadToDeg(-b);
  491.                 Gamma+=RadToDeg(-c);
  492.                 if (Alpha>180) Alpha-=360;
  493.                 if (Alpha<-180) Alpha+=360;
  494.                 if (Beta>180) Beta-=360;
  495.                 if (Beta<-180) Beta+=360;
  496.                 if (Gamma>180) Gamma-=360;
  497.                 if (Gamma<-180) Gamma+=360;
  498.                   UpdateAngleSliders(); */
  499.               }
  500.           }
  501.         break;
  502.       default:
  503.         break;
  504.     }
  505.  
  506.   return FALSE;
  507. }
  508.  
  509. /*******************************/
  510. /* Create general options page */
  511. /*******************************/
  512.  
  513. static GtkWidget *
  514. create_options_page (void)
  515. {
  516.   GtkWidget *page;
  517.   GtkWidget *frame;
  518.   GtkWidget *vbox;
  519.   GtkWidget *hbox;
  520.   GtkWidget *label;
  521.   GtkWidget *optionmenu;
  522.   GtkWidget *toggle;
  523.   GtkWidget *table;
  524.   GtkWidget *spinbutton;
  525.   GtkObject *adj;
  526.  
  527.   page = gtk_vbox_new (FALSE, 4);
  528.   gtk_container_set_border_width (GTK_CONTAINER (page), 4);
  529.  
  530.   /* General options */
  531.  
  532.   frame = gtk_frame_new (_("General Options"));
  533.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  534.   gtk_widget_show (frame);
  535.  
  536.   vbox = gtk_vbox_new (FALSE, 2);
  537.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  538.   gtk_container_add (GTK_CONTAINER (frame), vbox);
  539.   gtk_widget_show (vbox);
  540.  
  541.   hbox = gtk_hbox_new (FALSE, 4);
  542.   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  543.   gtk_widget_show (hbox);
  544.  
  545.   label = gtk_label_new (_("Map to:"));
  546.   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  547.   gtk_widget_show (label);
  548.  
  549.   optionmenu =
  550.     gimp_option_menu_new2 (FALSE, mapmenu_callback,
  551.                &mapvals.maptype,
  552.                (gpointer) mapvals.maptype,
  553.  
  554.                _("Plane"),    (gpointer) MAP_PLANE, NULL,
  555.                _("Sphere"),   (gpointer) MAP_SPHERE, NULL,
  556.                _("Box"),      (gpointer) MAP_BOX, NULL,
  557.                _("Cylinder"), (gpointer) MAP_CYLINDER, NULL,
  558.  
  559.                NULL);
  560.   gtk_box_pack_start (GTK_BOX (hbox), optionmenu, FALSE, FALSE, 0);
  561.   gtk_widget_show (optionmenu);
  562.  
  563.   gimp_help_set_help_data (optionmenu, _("Type of object to map to"), NULL);
  564.  
  565.   toggle = gtk_check_button_new_with_label (_("Transparent Background"));
  566.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
  567.                 mapvals.transparent_background);
  568.   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  569.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  570.               GTK_SIGNAL_FUNC (toggle_update),
  571.               &mapvals.transparent_background);
  572.   gtk_widget_show (toggle);
  573.  
  574.   gimp_help_set_help_data (toggle,
  575.                _("Make image transparent outside object"), NULL);
  576.  
  577.   toggle = gtk_check_button_new_with_label (_("Tile Source Image"));
  578.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
  579.                 mapvals.tiled);
  580.   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  581.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  582.               GTK_SIGNAL_FUNC (toggle_update),
  583.               &mapvals.tiled);
  584.   gtk_widget_show (toggle);
  585.  
  586.   gimp_help_set_help_data (toggle,
  587.                _("Tile source image: useful for infinite planes"),
  588.                NULL);
  589.  
  590.   toggle = gtk_check_button_new_with_label (_("Create New Image"));
  591.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
  592.                 mapvals.create_new_image);
  593.   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  594.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  595.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  596.               &mapvals.create_new_image);
  597.   gtk_widget_show (toggle);
  598.  
  599.   gimp_help_set_help_data (toggle,
  600.                _("Create a new image when applying filter"), NULL);
  601.  
  602.   toggle = gtk_check_button_new_with_label (_("Enable Tooltips"));
  603.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
  604.                 mapvals.tooltips_enabled);
  605.   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  606.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  607.               GTK_SIGNAL_FUNC (toggletips_update),
  608.               &mapvals.tooltips_enabled);
  609.   gtk_widget_show (toggle);
  610.  
  611.   gimp_help_set_help_data (toggle, _("Enable/disable tooltip messages"), NULL); 
  612.  
  613.   /* Antialiasing options */
  614.  
  615.   frame = gtk_frame_new (_("Antialiasing Options"));
  616.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  617.   gtk_widget_show (frame);
  618.  
  619.   vbox = gtk_vbox_new (FALSE, 4);
  620.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  621.   gtk_container_add (GTK_CONTAINER (frame), vbox);
  622.   gtk_widget_show (vbox);
  623.  
  624.   toggle = gtk_check_button_new_with_label (_("Enable Antialiasing"));
  625.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
  626.                 mapvals.antialiasing);
  627.   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  628.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  629.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  630.               &mapvals.antialiasing);
  631.   gtk_widget_show (toggle);
  632.  
  633.   gimp_help_set_help_data (toggle,
  634.                _("Enable/disable jagged edges removal "
  635.                  "(antialiasing)"), NULL);
  636.  
  637.   table = gtk_table_new (2, 3, FALSE);
  638.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  639.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  640.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  641.   gtk_widget_show (table);
  642.  
  643.   gtk_widget_set_sensitive (table, mapvals.antialiasing);
  644.   gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", table);
  645.  
  646.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  647.                   _("Depth:"), 0, 0,
  648.                   mapvals.maxdepth, 1.0, 5.0, 0.1, 1.0,
  649.                   1, TRUE, 0, 0,
  650.                   _("Antialiasing quality. Higher is better, "
  651.                    "but slower"), NULL);
  652.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  653.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  654.               &mapvals.maxdepth);
  655.  
  656.   spinbutton = gimp_spin_button_new (&adj, mapvals.pixeltreshold,
  657.                      0.001, 1000, 0.1, 1, 1, 0, 3);
  658.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  659.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  660.               &mapvals.pixeltreshold);
  661.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  662.                  _("Treshold:"), 1.0, 1.0,
  663.                  spinbutton, 1, TRUE);
  664.  
  665.   gimp_help_set_help_data (spinbutton,
  666.                _("Stop when pixel differences are smaller than "
  667.                  "this value"), NULL);
  668.  
  669.   gtk_widget_show (page);
  670.  
  671.   return page;
  672. }
  673.  
  674. /******************************/
  675. /* Create light settings page */
  676. /******************************/
  677.  
  678. static GtkWidget *
  679. create_light_page (void)
  680. {
  681.   GtkWidget *page;
  682.   GtkWidget *frame;
  683.   GtkWidget *table;
  684.   GtkWidget *optionmenu;
  685.   GtkWidget *colorbutton;
  686.   GtkWidget *spinbutton;
  687.   GtkObject *adj;
  688.  
  689.   page = gtk_vbox_new (FALSE, 4);
  690.   gtk_container_set_border_width (GTK_CONTAINER (page), 4);
  691.  
  692.   frame = gtk_frame_new (_("Light Settings"));
  693.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  694.   gtk_widget_show (frame);
  695.  
  696.   table = gtk_table_new (2, 2, FALSE);
  697.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  698.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  699.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  700.   gtk_container_add (GTK_CONTAINER (frame), table);  gtk_widget_show (table);
  701.  
  702.   optionmenu = gimp_option_menu_new2 (FALSE, lightmenu_callback,
  703.                       &mapvals.lightsource.type,
  704.                       (gpointer) mapvals.lightsource.type,
  705.  
  706.                       _("Point Light"),
  707.                       (gpointer) POINT_LIGHT, NULL,
  708.                       _("Directional Light"),
  709.                       (gpointer) DIRECTIONAL_LIGHT, NULL,
  710.                       _("No Light"),
  711.                       (gpointer) NO_LIGHT, NULL,
  712.  
  713.                       NULL);
  714.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  715.                  _("Lightsource Type:"), 1.0, 0.5,
  716.                  optionmenu, 1, TRUE);
  717.  
  718.   gimp_help_set_help_data (optionmenu, _("Type of light source to apply"), NULL);
  719.  
  720.   colorbutton = gimp_color_button_double_new (_("Select Lightsource Color"),
  721.                           64, 16,
  722.                           &mapvals.lightsource.color.r, 3);
  723.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  724.                  _("Lightsource Color:"), 1.0, 0.5,
  725.                  colorbutton, 1, TRUE);
  726.  
  727.   gimp_help_set_help_data (colorbutton,
  728.                _("Set light source color"), NULL);
  729.  
  730.   pointlightwid = gtk_frame_new (_("Position"));
  731.   gtk_box_pack_start (GTK_BOX (page), pointlightwid, FALSE, FALSE, 0);
  732.  
  733.   if (mapvals.lightsource.type == POINT_LIGHT)
  734.     gtk_widget_show (pointlightwid);
  735.  
  736.   table = gtk_table_new (3, 2, FALSE);
  737.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  738.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  739.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  740.   gtk_container_add (GTK_CONTAINER (pointlightwid), table);
  741.   gtk_widget_show (table);
  742.  
  743.   spinbutton = gimp_spin_button_new (&xadj, mapvals.lightsource.position.x,
  744.                      -G_MAXFLOAT, G_MAXFLOAT,
  745.                      0.1, 1.0, 1.0, 0.0, 2);
  746.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  747.                  _("X:"), 1.0, 0.5,
  748.                  spinbutton, 1, TRUE);
  749.   gtk_signal_connect (GTK_OBJECT (xadj), "value_changed",
  750.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  751.               &mapvals.lightsource.position.x);
  752.  
  753.   gimp_help_set_help_data (spinbutton,
  754.                _("Light source X position in XYZ space"), NULL);
  755.  
  756.   spinbutton = gimp_spin_button_new (&yadj, mapvals.lightsource.position.y,
  757.                      -G_MAXFLOAT, G_MAXFLOAT,
  758.                      0.1, 1.0, 1.0, 0.0, 2);
  759.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  760.                  _("Y:"), 1.0, 0.5,
  761.                  spinbutton, 1, TRUE);
  762.   gtk_signal_connect (GTK_OBJECT (yadj), "value_changed",
  763.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  764.               &mapvals.lightsource.position.y);
  765.  
  766.   gimp_help_set_help_data (spinbutton,
  767.                _("Light source Y position in XYZ space"), NULL);
  768.  
  769.   spinbutton = gimp_spin_button_new (&zadj, mapvals.lightsource.position.z,
  770.                      -G_MAXFLOAT, G_MAXFLOAT,
  771.                      0.1, 1.0, 1.0, 0.0, 2);
  772.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
  773.                  _("Z:"), 1.0, 0.5,
  774.                  spinbutton, 1, TRUE);
  775.   gtk_signal_connect (GTK_OBJECT (zadj), "value_changed",
  776.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  777.               &mapvals.lightsource.position.z);
  778.  
  779.   gimp_help_set_help_data (spinbutton,
  780.                _("Light source Z position in XYZ space"), NULL);
  781.  
  782.  
  783.   dirlightwid = gtk_frame_new (_("Direction Vector"));
  784.   gtk_box_pack_start (GTK_BOX (page), dirlightwid, FALSE, FALSE, 0);
  785.  
  786.   if (mapvals.lightsource.type == DIRECTIONAL_LIGHT)
  787.     gtk_widget_show (dirlightwid);
  788.  
  789.   table = gtk_table_new (3, 2, FALSE);
  790.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  791.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  792.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  793.   gtk_container_add (GTK_CONTAINER (dirlightwid), table);
  794.   gtk_widget_show (table);
  795.  
  796.   spinbutton = gimp_spin_button_new (&adj, mapvals.lightsource.direction.x,
  797.                      -1.0, 1.0, 0.01, 0.1, 1.0, 0.0, 2);
  798.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  799.                  _("X:"), 1.0, 0.5,
  800.                  spinbutton, 1, TRUE);
  801.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  802.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  803.               &mapvals.lightsource.direction.x);
  804.  
  805.   gimp_help_set_help_data (spinbutton,
  806.                _("Light source X direction in XYZ space"), NULL);
  807.  
  808.   spinbutton = gimp_spin_button_new (&adj, mapvals.lightsource.direction.y,
  809.                      -1.0, 1.0, 0.01, 0.1, 1.0, 0.0, 2);
  810.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  811.                  _("Y:"), 1.0, 0.5,
  812.                  spinbutton, 1, TRUE);
  813.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  814.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  815.               &mapvals.lightsource.direction.y);
  816.  
  817.   gimp_help_set_help_data (spinbutton,
  818.                _("Light source Y direction in XYZ space"), NULL);
  819.  
  820.   spinbutton = gimp_spin_button_new (&adj, mapvals.lightsource.direction.z,
  821.                      -1.0, 1.0, 0.01, 0.1, 1.0, 0.0, 2);
  822.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
  823.                  _("Z:"), 1.0, 0.5,
  824.                  spinbutton, 1, TRUE);
  825.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  826.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  827.               &mapvals.lightsource.direction.z);
  828.  
  829.   gimp_help_set_help_data (spinbutton,
  830.                _("Light source Z direction in XYZ space"), NULL);
  831.  
  832.   gtk_widget_show (page);
  833.  
  834.   return page;  
  835. }
  836.  
  837. /*********************************/
  838. /* Create material settings page */
  839. /*********************************/
  840.  
  841. static GtkWidget *
  842. create_material_page (void)
  843. {
  844.   GtkWidget *page;
  845.   GtkWidget *frame;
  846.   GtkWidget *table;
  847.   GtkWidget *hbox;
  848.   GtkWidget *spinbutton;
  849.   GtkObject *adj;
  850.   GtkWidget *pixmap;
  851.  
  852.   page = gtk_vbox_new (FALSE, 4);
  853.   gtk_container_set_border_width (GTK_CONTAINER (page), 4);
  854.  
  855.   frame = gtk_frame_new (_("Intensity Levels"));
  856.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  857.   gtk_widget_show (frame);
  858.  
  859.   hbox = gtk_hbox_new (FALSE, 0);
  860.   gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  861.   gtk_container_add (GTK_CONTAINER (frame), hbox);
  862.   gtk_widget_show (hbox);
  863.  
  864.   table = gtk_table_new (2, 4, FALSE);
  865.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  866.   gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0);
  867.   gtk_widget_show (table);
  868.  
  869.   /* Ambient intensity */
  870.  
  871.   pixmap = gimp_pixmap_new (amb1_xpm);
  872.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  873.                  _("Ambient:"), 1.0, 0.5,
  874.                  pixmap, 1, FALSE);
  875.  
  876.   spinbutton = gimp_spin_button_new (&adj, mapvals.material.ambient_int,
  877.                      0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
  878.   gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 0, 1,
  879.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  880.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  881.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  882.               &mapvals.material.ambient_int);
  883.   gtk_widget_show (spinbutton);
  884.  
  885.   gimp_help_set_help_data (spinbutton,
  886.                _("Amount of original color to show where no "
  887.                  "direct light falls"), NULL);
  888.  
  889.   pixmap = gimp_pixmap_new (amb2_xpm);
  890.   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 0, 1,
  891.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  892.   gtk_widget_show (pixmap);
  893.  
  894.   /* Diffuse intensity */
  895.  
  896.   pixmap = gimp_pixmap_new (diffint1_xpm);
  897.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  898.                  _("Diffuse:"), 1.0, 0.5,
  899.                  pixmap, 1, FALSE);
  900.  
  901.   spinbutton = gimp_spin_button_new (&adj, mapvals.material.diffuse_int,
  902.                      0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
  903.   gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 1, 2,
  904.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  905.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  906.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  907.               &mapvals.material.diffuse_int);
  908.   gtk_widget_show (spinbutton);
  909.  
  910.   gimp_help_set_help_data (spinbutton,
  911.                _("Intensity of original color when lit by a light "
  912.                  "source"), NULL);
  913.  
  914.   pixmap = gimp_pixmap_new (diffint2_xpm);
  915.   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 1, 2,
  916.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  917.   gtk_widget_show (pixmap);
  918.  
  919.   frame = gtk_frame_new (_("Reflectivity"));
  920.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  921.   gtk_widget_show (frame);
  922.  
  923.   hbox = gtk_hbox_new (FALSE, 0);
  924.   gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  925.   gtk_container_add (GTK_CONTAINER (frame), hbox);
  926.   gtk_widget_show (hbox);
  927.  
  928.   table = gtk_table_new (3, 4, FALSE);
  929.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  930.   gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0);
  931.   gtk_widget_show (table);
  932.  
  933.   /* Diffuse reflection */
  934.  
  935.   pixmap = gimp_pixmap_new (diffref1_xpm);
  936.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  937.                  _("Diffuse:"), 1.0, 0.5,
  938.                  pixmap, 1, FALSE);
  939.  
  940.   spinbutton = gimp_spin_button_new (&adj, mapvals.material.diffuse_ref,
  941.                      0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
  942.   gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 0, 1,
  943.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  944.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  945.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  946.               &mapvals.material.diffuse_ref);
  947.   gtk_widget_show (spinbutton);
  948.  
  949.   gimp_help_set_help_data (spinbutton,
  950.                _("Higher values makes the object reflect more "
  951.                  "light (appear lighter)"), NULL);
  952.  
  953.   pixmap = gimp_pixmap_new (diffref2_xpm);
  954.   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 0, 1,
  955.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  956.   gtk_widget_show (pixmap);
  957.  
  958.   /* Specular reflection */
  959.  
  960.   pixmap = gimp_pixmap_new (specref1_xpm);
  961.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  962.                  _("Specular:"), 1.0, 0.5,
  963.                  pixmap, 1, FALSE);
  964.  
  965.   spinbutton = gimp_spin_button_new (&adj, mapvals.material.specular_ref,
  966.                      0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
  967.   gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 1, 2,
  968.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  969.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  970.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  971.               &mapvals.material.specular_ref);
  972.   gtk_widget_show (spinbutton);
  973.  
  974.   gimp_help_set_help_data (spinbutton,
  975.                _("Controls how intense the highlights will be"),
  976.                NULL);
  977.  
  978.   pixmap = gimp_pixmap_new (specref2_xpm);
  979.   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 1, 2,
  980.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  981.   gtk_widget_show (pixmap);
  982.  
  983.   /* Highlight */
  984.  
  985.   pixmap = gimp_pixmap_new (high1_xpm);
  986.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
  987.                  _("Highlight:"), 1.0, 0.5,
  988.                  pixmap, 1, FALSE);
  989.  
  990.   spinbutton = gimp_spin_button_new (&adj, mapvals.material.highlight,
  991.                      0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
  992.   gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 2, 3,
  993.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  994.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  995.               GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
  996.               &mapvals.material.highlight);
  997.   gtk_widget_show (spinbutton);
  998.  
  999.   gimp_help_set_help_data (spinbutton,
  1000.                _("Higher values makes the highlights more focused"),
  1001.                NULL);
  1002.  
  1003.   pixmap = gimp_pixmap_new (high2_xpm);
  1004.   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 2, 3,
  1005.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  1006.   gtk_widget_show (pixmap);
  1007.  
  1008.   gtk_widget_show (page);
  1009.   
  1010.   return page;
  1011. }
  1012.  
  1013. /****************************************/
  1014. /* Create orientation and position page */
  1015. /****************************************/
  1016.  
  1017. static GtkWidget *
  1018. create_orientation_page (void)
  1019. {
  1020.   GtkWidget *page;
  1021.   GtkWidget *frame;
  1022.   GtkWidget *table;
  1023.   GtkObject *adj;
  1024.  
  1025.   page = gtk_vbox_new (FALSE, 4);
  1026.   gtk_container_set_border_width (GTK_CONTAINER (page), 4);
  1027.  
  1028.   frame = gtk_frame_new (_("Position"));
  1029.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  1030.   gtk_widget_show (frame);
  1031.  
  1032.   table = gtk_table_new (3, 3, FALSE);
  1033.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  1034.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  1035.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  1036.   gtk_container_add (GTK_CONTAINER (frame), table);
  1037.   gtk_widget_show (table);
  1038.  
  1039.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  1040.                   _("X:"), 0, 0,
  1041.                   mapvals.position.x, -1.0, 2.0, 0.01, 0.1, 5,
  1042.                   TRUE, 0, 0,
  1043.                   _("Object X position in XYZ space"), NULL);
  1044.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1045.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.01, 5);
  1046.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1047.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1048.               &mapvals.position.x);
  1049.  
  1050.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
  1051.                   _("Y:"), 0, 0,
  1052.                   mapvals.position.y, -1.0, 2.0, 0.01, 0.1, 5,
  1053.                   TRUE, 0, 0,
  1054.                   _("Object Y position in XYZ space"), NULL);
  1055.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1056.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.01, 5);
  1057.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1058.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1059.               &mapvals.position.y);
  1060.  
  1061.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 2,
  1062.                   _("Z:"), 0, 0,
  1063.                   mapvals.position.z, -1.0, 2.0, 0.01, 0.1, 5,
  1064.                   TRUE, 0, 0,
  1065.                   _("Object Z position in XYZ space"), NULL);
  1066.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1067.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.01, 5);
  1068.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1069.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1070.               &mapvals.position.z);
  1071.  
  1072.   frame = gtk_frame_new (_("Rotation"));
  1073.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  1074.   gtk_widget_show (frame);
  1075.  
  1076.   table = gtk_table_new (3, 3, FALSE);
  1077.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  1078.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  1079.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  1080.   gtk_container_add (GTK_CONTAINER (frame), table);
  1081.   gtk_widget_show (table);
  1082.  
  1083.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  1084.                   _("X:"), 0, 0,
  1085.                   mapvals.alpha, -180.0, 180.0, 1.0, 15.0, 1,
  1086.                   TRUE, 0, 0,
  1087.                   _("Rotation angle about X axis"), NULL);
  1088.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1089.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1090.               &mapvals.alpha);
  1091.  
  1092.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
  1093.                   _("Y:"), 0, 0,
  1094.                   mapvals.beta, -180.0, 180.0, 1.0, 15.0, 1,
  1095.                   TRUE, 0, 0,
  1096.                   _("Rotation angle about Y axis"), NULL);
  1097.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1098.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1099.               &mapvals.beta);
  1100.  
  1101.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 2,
  1102.                   _("Z:"), 0, 0,
  1103.                   mapvals.gamma, -180.0, 180.0, 1.0, 15.0, 1,
  1104.                   TRUE, 0, 0,
  1105.                   _("Rotation angle about Z axis"), NULL);
  1106.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1107.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1108.               &mapvals.gamma);
  1109.  
  1110.   gtk_widget_show (page);
  1111.  
  1112.   return page;
  1113. }
  1114.  
  1115. static GtkWidget *
  1116. create_box_page (void)
  1117. {
  1118.   GtkWidget *page;
  1119.   GtkWidget *frame;
  1120.   GtkWidget *vbox;
  1121.   GtkWidget *table;
  1122.   GtkWidget *optionmenu;
  1123.   GtkWidget *menu;
  1124.   GtkObject *adj;
  1125.   gint       i;
  1126.  
  1127.   static gchar *labels[] =
  1128.   {
  1129.     N_("Front:"), N_("Back:"),
  1130.     N_("Top:"),   N_("Bottom:"),
  1131.     N_("Left:"),  N_("Right:")
  1132.   };
  1133.  
  1134.   page = gtk_vbox_new (FALSE, 4);
  1135.   gtk_container_set_border_width (GTK_CONTAINER (page), 4);
  1136.  
  1137.   frame = gtk_frame_new (_("Map Images to Box Faces"));
  1138.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  1139.   gtk_widget_show (frame);
  1140.  
  1141.   vbox = gtk_vbox_new (FALSE, 2);
  1142.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  1143.   gtk_container_add (GTK_CONTAINER (frame), vbox);
  1144.   gtk_widget_show (vbox);
  1145.  
  1146.   table = gtk_table_new (6, 2, FALSE);
  1147.   gtk_table_set_row_spacings (GTK_TABLE(table), 2);
  1148.   gtk_table_set_col_spacings (GTK_TABLE(table), 4);
  1149.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 5);
  1150.   gtk_widget_show (table);
  1151.  
  1152.   /* Option menues */
  1153.  
  1154.   for (i = 0; i < 6; i++)
  1155.     {
  1156.       optionmenu = gtk_option_menu_new ();
  1157.       gtk_object_set_data (GTK_OBJECT (optionmenu), "_mapwid_id",
  1158.                (gpointer) i);
  1159.       menu = gimp_drawable_menu_new (box_constrain, box_drawable_callback,
  1160.                      (gpointer) optionmenu,
  1161.                      mapvals.boxmap_id[i]);
  1162.       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);      
  1163.  
  1164.       gimp_table_attach_aligned (GTK_TABLE (table), 0, i,
  1165.                  gettext (labels[i]), 1.0, 0.5,
  1166.                  optionmenu, 1, FALSE);
  1167.     }
  1168.  
  1169.   /* Scale scales */
  1170.  
  1171.   table = gtk_table_new (3, 3, FALSE);
  1172.   gtk_table_set_row_spacings (GTK_TABLE(table), 2);
  1173.   gtk_table_set_col_spacings (GTK_TABLE(table), 4);
  1174.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  1175.   gtk_widget_show (table);
  1176.  
  1177.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  1178.                   _("Scale X:"), 0, 0,
  1179.                   mapvals.scale.x, 0.0, 5.0, 0.01, 0.1, 2,
  1180.                   TRUE, 0, 0,
  1181.                   _("X scale (size)"), NULL);
  1182.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1183.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.1, 2);
  1184.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1185.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1186.               &mapvals.scale.x);
  1187.  
  1188.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
  1189.                   _("Y:"), 0, 0,
  1190.                   mapvals.scale.y, 0.0, 5.0, 0.01, 0.1, 2,
  1191.                   TRUE, 0, 0,
  1192.                   _("Y scale (size)"), NULL);
  1193.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1194.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.1, 2);
  1195.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1196.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1197.               &mapvals.scale.y);
  1198.  
  1199.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 2,
  1200.                   _("Z:"), 0, 0,
  1201.                   mapvals.scale.z, 0.0, 5.0, 0.01, 0.1, 2,
  1202.                   TRUE, 0, 0,
  1203.                   _("Z scale (size)"), NULL);
  1204.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1205.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.1, 2);
  1206.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1207.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1208.               &mapvals.scale.z);
  1209.  
  1210.   gtk_widget_show (page);
  1211.  
  1212.   return page;
  1213. }
  1214.  
  1215. static GtkWidget *
  1216. create_cylinder_page (void)
  1217. {
  1218.   GtkWidget *page;
  1219.   GtkWidget *frame;
  1220.   GtkWidget *table;
  1221.   GtkWidget *optionmenu;
  1222.   GtkWidget *menu;
  1223.   GtkObject *adj;
  1224.   gint       i;
  1225.  
  1226.   static gchar *labels[] = { N_("Top:"), N_("Bottom:") };
  1227.  
  1228.   page = gtk_vbox_new (FALSE, 4);
  1229.   gtk_container_set_border_width (GTK_CONTAINER (page), 4);
  1230.  
  1231.   frame = gtk_frame_new (_("Images for the Cap Faces"));
  1232.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  1233.   gtk_widget_show (frame);
  1234.  
  1235.   table = gtk_table_new (2, 2, FALSE);
  1236.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  1237.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  1238.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  1239.   gtk_container_add (GTK_CONTAINER (frame), table);
  1240.   gtk_widget_show (table);
  1241.  
  1242.   /* Option menus */
  1243.  
  1244.   for (i = 0; i < 2; i++)
  1245.     {
  1246.       optionmenu = gtk_option_menu_new ();
  1247.       gtk_object_set_data (GTK_OBJECT (optionmenu), "_mapwid_id",
  1248.                (gpointer) i);
  1249.       menu = gimp_drawable_menu_new (cylinder_constrain,
  1250.                      cylinder_drawable_callback,
  1251.                      (gpointer) optionmenu,
  1252.                      mapvals.cylindermap_id[i]);
  1253.       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
  1254.  
  1255.       gimp_table_attach_aligned (GTK_TABLE (table), 0, i,
  1256.                  gettext (labels[i]), 1.0, 0.5,
  1257.                  optionmenu, 1, FALSE);
  1258.     }
  1259.  
  1260.   frame = gtk_frame_new (_("Size"));
  1261.   gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
  1262.   gtk_widget_show (frame);
  1263.  
  1264.   table = gtk_table_new (2, 3, FALSE);
  1265.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  1266.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  1267.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  1268.   gtk_container_add (GTK_CONTAINER (frame), table);
  1269.   gtk_widget_show (table);
  1270.  
  1271.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  1272.                   _("Radius:"), 0, 0,
  1273.                   mapvals.cylinder_radius,
  1274.                   0.0, 2.0, 0.01, 0.1, 2,
  1275.                   TRUE, 0, 0,
  1276.                   _("Cylinder radius"), NULL);
  1277.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1278.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.1, 2);
  1279.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1280.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1281.               &mapvals.cylinder_radius);
  1282.  
  1283.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 1,
  1284.                   _("Length:"), 0, 0,
  1285.                   mapvals.cylinder_length,
  1286.                   0.0, 2.0, 0.01, 0.1, 2,
  1287.                   TRUE, 0, 0,
  1288.                   _("Cylinder length"), NULL);
  1289.   gtk_spin_button_configure (GIMP_SCALE_ENTRY_SPINBUTTON (adj),
  1290.                  GIMP_SCALE_ENTRY_SPINBUTTON_ADJ (adj), 0.1, 2);
  1291.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  1292.               GTK_SIGNAL_FUNC (double_adjustment_update),
  1293.               &mapvals.cylinder_length);
  1294.  
  1295.   gtk_widget_show (page);
  1296.  
  1297.   return page;
  1298. }
  1299.  
  1300. /****************************/
  1301. /* Create notbook and pages */
  1302. /****************************/
  1303.  
  1304. static void
  1305. create_main_notebook (GtkWidget *container)
  1306. {
  1307.   GtkWidget *page;
  1308.  
  1309.   options_note_book = GTK_NOTEBOOK (gtk_notebook_new ());
  1310.   gtk_container_add (GTK_CONTAINER (container), GTK_WIDGET (options_note_book));
  1311.  
  1312.   page = create_options_page ();
  1313.   gtk_notebook_append_page (options_note_book, page,
  1314.                 gtk_label_new (_("Options")));
  1315.   
  1316.   page = create_light_page ();
  1317.   gtk_notebook_append_page (options_note_book, page,
  1318.                 gtk_label_new (_("Light")));
  1319.   
  1320.   page = create_material_page ();
  1321.   gtk_notebook_append_page (options_note_book, page,
  1322.                 gtk_label_new (_("Material")));
  1323.   
  1324.   page = create_orientation_page ();
  1325.   gtk_notebook_append_page (options_note_book, page,
  1326.                 gtk_label_new (_("Orientation")));
  1327.  
  1328.   if (mapvals.maptype == MAP_BOX)
  1329.     {
  1330.       box_page = create_box_page ();
  1331.       gtk_notebook_append_page (options_note_book, box_page,
  1332.                 gtk_label_new (_("Box")));
  1333.     }
  1334.   else if (mapvals.maptype == MAP_CYLINDER)
  1335.     {
  1336.       cylinder_page = create_cylinder_page ();
  1337.       gtk_notebook_append_page (options_note_book, cylinder_page,
  1338.                 gtk_label_new (_("Cylinder")));
  1339.     }
  1340.  
  1341.   gtk_widget_show (GTK_WIDGET (options_note_book));
  1342. }
  1343.  
  1344. /********************************/
  1345. /* Create and show main dialog. */
  1346. /********************************/
  1347.  
  1348. gboolean
  1349. main_dialog (GimpDrawable *drawable)
  1350. {
  1351.   GtkWidget *main_hbox;
  1352.   GtkWidget *vbox;
  1353.   GtkWidget *hbox;
  1354.   GtkWidget *frame;
  1355.   GtkWidget *button;
  1356.   GtkWidget *toggle;
  1357.   gchar **argv;
  1358.   gint    argc;
  1359.  
  1360.   argc    = 1;
  1361.   argv    = g_new (gchar *, 1);
  1362.   argv[0] = g_strdup ("MapObject");
  1363.  
  1364.   gtk_init (&argc, &argv);
  1365.   gtk_rc_parse (gimp_gtkrc ());
  1366.  
  1367.   if (! gimp_use_xshm ())
  1368.     gdk_set_use_xshm (FALSE);
  1369.  
  1370.   /* Set up ArcBall stuff */
  1371.   /* ==================== */
  1372.  
  1373.   /*ArcBall_Init(); */
  1374.  
  1375.   visinfo = gck_visualinfo_new ();
  1376.  
  1377.   appwin = gimp_dialog_new (_("Map to Object"), "MapObject",
  1378.                 gimp_standard_help_func,
  1379.                 "filters/mapobject.html",
  1380.                 GTK_WIN_POS_MOUSE,
  1381.                 FALSE, TRUE, FALSE,
  1382.  
  1383.                 _("OK"), apply_callback,
  1384.                 NULL, NULL, NULL, TRUE, FALSE,
  1385.                 _("Cancel"), gtk_main_quit,
  1386.                 NULL, NULL, NULL, FALSE, TRUE,
  1387.  
  1388.                 NULL);
  1389.  
  1390.   gimp_help_init ();
  1391.  
  1392.   main_hbox = gtk_hbox_new (FALSE, 6);
  1393.   gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 6);
  1394.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (appwin)->vbox), main_hbox,
  1395.               FALSE, FALSE, 0);
  1396.   gtk_widget_show (main_hbox);
  1397.  
  1398.   /* Create the Preview */
  1399.  
  1400.   frame = gtk_frame_new (_("Preview"));
  1401.   gtk_box_pack_start (GTK_BOX (main_hbox), frame, FALSE, FALSE, 0);
  1402.   gtk_widget_show (frame);
  1403.  
  1404.   vbox = gtk_vbox_new (FALSE, 4);
  1405.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  1406.   gtk_container_add (GTK_CONTAINER (frame), vbox);
  1407.   gtk_widget_show (vbox);
  1408.  
  1409.   /* Add preview widget and various buttons to the first part */
  1410.  
  1411.   frame = gtk_frame_new (NULL);
  1412.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  1413.   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  1414.   gtk_widget_show (frame);
  1415.  
  1416.   gtk_widget_realize (appwin);
  1417.   previewarea = gtk_drawing_area_new ();
  1418.   gtk_drawing_area_size (GTK_DRAWING_AREA (previewarea),
  1419.              PREVIEW_WIDTH, PREVIEW_HEIGHT);
  1420.   gtk_widget_set_events (previewarea, (GDK_EXPOSURE_MASK |
  1421.                        GDK_BUTTON1_MOTION_MASK |
  1422.                        GDK_BUTTON_PRESS_MASK | 
  1423.                        GDK_BUTTON_RELEASE_MASK));
  1424.   gtk_signal_connect (GTK_OBJECT (previewarea), "event",
  1425.               GTK_SIGNAL_FUNC (preview_events),
  1426.               (gpointer) previewarea);
  1427.   gtk_container_add (GTK_CONTAINER (frame), previewarea);
  1428.   gtk_widget_show (previewarea);
  1429.  
  1430.   hbox = gtk_hbox_new (FALSE, 4);
  1431.   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  1432.   gtk_widget_show (hbox);
  1433.  
  1434.   button = gtk_button_new_with_label (_("Preview!"));
  1435.   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
  1436.   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
  1437.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  1438.               GTK_SIGNAL_FUNC (preview_callback),
  1439.               NULL);
  1440.   gtk_widget_show (button);
  1441.  
  1442.   gimp_help_set_help_data (button, _("Recompute preview image"), NULL);
  1443.  
  1444.   button = gimp_pixmap_button_new (zoom_out_xpm, NULL);
  1445.   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
  1446.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  1447.               GTK_SIGNAL_FUNC (zoomout_callback),
  1448.               NULL);
  1449.   gtk_widget_show (button);
  1450.  
  1451.   gimp_help_set_help_data (button, _("Zoom out (make image smaller)"), NULL);
  1452.  
  1453.   button = gimp_pixmap_button_new (zoom_in_xpm, NULL);
  1454.   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
  1455.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  1456.               GTK_SIGNAL_FUNC (zoomin_callback),
  1457.               NULL);
  1458.   gtk_widget_show (button);
  1459.  
  1460.   gimp_help_set_help_data (button, _("Zoom in (make image bigger)"), NULL);
  1461.  
  1462.   toggle = gtk_check_button_new_with_label (_("Show Preview Wireframe"));
  1463.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), mapvals.showgrid);
  1464.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  1465.               GTK_SIGNAL_FUNC (togglegrid_update),
  1466.               &mapvals.showgrid);
  1467.   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  1468.   gtk_widget_show (toggle);
  1469.  
  1470.   gimp_help_set_help_data (toggle, _("Show/hide preview wireframe"), NULL);
  1471.  
  1472.   create_main_notebook (main_hbox);
  1473.  
  1474.   /* Endmarkers for line table */
  1475.   
  1476.   linetab[0].x1 = -1;
  1477.  
  1478.   gtk_widget_show (appwin);
  1479.  
  1480.   {
  1481.     GdkCursor *newcursor;
  1482.  
  1483.     newcursor = gdk_cursor_new (GDK_HAND2);
  1484.     gdk_window_set_cursor (previewarea->window, newcursor);
  1485.     gdk_cursor_destroy (newcursor);
  1486.     gdk_flush ();
  1487.   }
  1488.  
  1489.   if (!mapvals.tooltips_enabled)
  1490.     gimp_help_disable_tooltips ();
  1491.  
  1492.   image_setup (drawable, TRUE);
  1493.  
  1494.   gtk_main ();
  1495.  
  1496.   if (preview_rgb_data != NULL)
  1497.     g_free (preview_rgb_data);
  1498.   
  1499.   if (image != NULL)
  1500.     gdk_image_destroy (image);
  1501.  
  1502.   gck_visualinfo_destroy (visinfo);
  1503.   gtk_widget_destroy(appwin);
  1504.  
  1505.   gimp_help_free ();
  1506.  
  1507.   gdk_flush ();
  1508.  
  1509.   return run;
  1510. }
  1511.