home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / rcm / rcm_dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-19  |  27.2 KB  |  792 lines

  1. /*
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This is a plug-in for the GIMP.
  5.  *
  6.  * Colormap-Rotation plug-in. Exchanges two color ranges.
  7.  *
  8.  * Copyright (C) 1999 Sven Anders (anderss@fmi.uni-passau.de)
  9.  *                    Based on code from Pavel Grinfeld (pavel@ml.com)
  10.  *
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25.  */
  26.  
  27. /*---------------------------------------------------------------------------
  28.  * Change log:
  29.  * 
  30.  * Version 2.0, 04 April 1999.
  31.  *  Nearly complete rewrite, made plug-in stable.
  32.  *  (Works with GIMP 1.1 and GTK+ 1.2)
  33.  *
  34.  * Version 1.0, 27 March 1997.
  35.  *  Initial (unstable) release by Pavel Grinfeld
  36.  *
  37.  *---------------------------------------------------------------------------*/
  38.  
  39. #include "config.h"
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43.  
  44. #include <gtk/gtk.h>
  45.  
  46. #include <libgimp/gimp.h>
  47. #include <libgimp/gimpui.h>
  48.  
  49. #include "libgimp/stdplugins-intl.h"
  50.  
  51. #include "rcm.h"
  52. #include "rcm_misc.h"
  53. #include "rcm_gdk.h"
  54. #include "rcm_callback.h"
  55. #include "rcm_dialog.h"
  56.  
  57. #include "pixmaps/rcm_360.xpm"
  58. #include "pixmaps/rcm_a_b.xpm"
  59. #include "pixmaps/rcm_cw.xpm"
  60.  
  61.  
  62. /*---------------------------------------------------------------------------*/
  63. /* Defines */
  64. /*---------------------------------------------------------------------------*/
  65.  
  66. #define INITIAL_ALPHA      0
  67. #define INITIAL_BETA       G_PI_2
  68. #define INITIAL_GRAY_SAT   0.0
  69. #define INITIAL_GRAY_RSAT  0.0
  70. #define INITIAL_GRAY_HUE   0.0
  71.  
  72. #define RANGE_ADJUST_MASK GDK_EXPOSURE_MASK | \
  73.                           GDK_ENTER_NOTIFY_MASK | \
  74.                           GDK_BUTTON_PRESS_MASK | \
  75.                           GDK_BUTTON_RELEASE_MASK | \
  76.                           GDK_BUTTON1_MOTION_MASK | \
  77.                           GDK_POINTER_MOTION_HINT_MASK
  78.  
  79. /*---------------------------------------------------------------------------*/
  80. /* Previews: create one preview */
  81. /*---------------------------------------------------------------------------*/
  82.  
  83. void 
  84. rcm_create_one_preview (GtkWidget **preview, 
  85.             GtkWidget **frame,
  86.             int         previewWidth, 
  87.             int         previewHeight)
  88. {
  89.   *frame = gtk_frame_new(NULL);
  90.   gtk_frame_set_shadow_type(GTK_FRAME(*frame), GTK_SHADOW_IN);
  91.   gtk_container_set_border_width(GTK_CONTAINER(*frame), 0);
  92.   gtk_widget_show(*frame);
  93.   
  94.   *preview = gtk_preview_new(GTK_PREVIEW_COLOR);
  95.  
  96.   gtk_preview_size(GTK_PREVIEW(*preview), previewWidth, previewHeight);
  97.   gtk_widget_show(*preview);
  98.   gtk_container_add(GTK_CONTAINER(*frame), *preview);
  99. }
  100.  
  101. /*---------------------------------------------------------------------------*/
  102. /* Previews */
  103. /*---------------------------------------------------------------------------*/
  104.  
  105. GtkWidget* 
  106. rcm_create_previews (void)
  107. {
  108.   GtkWidget *frame, *blabel, *alabel, *bframe, *aframe, *table;
  109.  
  110.   /* Previews: create the previews */
  111.   
  112.   rcm_create_one_preview (&Current.Bna->before, &bframe, 
  113.               Current.reduced->width, Current.reduced->height);
  114.  
  115.   rcm_create_one_preview (&Current.Bna->after, &aframe, 
  116.               Current.reduced->width, Current.reduced->height);
  117.  
  118.   /* Previews: frame */
  119.   frame = gtk_frame_new (_("Preview"));
  120.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  121.  
  122.   alabel = gtk_label_new (_("Rotated"));
  123.   gtk_widget_show (alabel);
  124.   
  125.   blabel = gtk_label_new (_("Original"));
  126.   gtk_widget_show (blabel);
  127.  
  128.   table = gtk_table_new (4, 1, FALSE);
  129.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  130.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  131.  
  132.   gtk_container_add (GTK_CONTAINER (frame), table);
  133.   
  134.   gtk_table_attach (GTK_TABLE (table), blabel, 0, 1, 0, 1, 
  135.             GTK_EXPAND, GTK_EXPAND | GTK_FILL, 0, 0);
  136.  
  137.   gtk_table_attach (GTK_TABLE (table), bframe, 0, 1, 1, 2,
  138.             GTK_EXPAND, GTK_EXPAND, 0, 0);
  139.  
  140.   gtk_table_attach (GTK_TABLE (table), alabel, 0, 1, 2, 3,
  141.             GTK_EXPAND, GTK_EXPAND | GTK_FILL, 0, 0);
  142.  
  143.   gtk_table_attach (GTK_TABLE (table), aframe, 0, 1, 3, 4,
  144.             GTK_EXPAND, GTK_EXPAND, 0, 0);
  145.  
  146.   gtk_widget_show (table);
  147.   gtk_widget_show (frame);
  148.  
  149.   return frame;
  150. }
  151.  
  152. /*---------------------------------------------------------------------------*/
  153. /* Main: Create one pixmap button */
  154. /*---------------------------------------------------------------------------*/
  155.  
  156. void 
  157. rcm_create_pixmap_button (GtkWidget     **label, 
  158.               GtkWidget     **xpm_button,
  159.               GtkWidget     **label_box, 
  160.               GtkSignalFunc   callback,
  161.               gpointer        data, 
  162.               gchar          *text, 
  163.               GtkWidget      *parent, 
  164.               gint            pos)
  165. {
  166.   /* create button */
  167.   *xpm_button = gtk_button_new();
  168.   gtk_signal_connect(GTK_OBJECT(*xpm_button), "clicked", callback, data);
  169.   gtk_widget_show(*xpm_button);
  170.  
  171.   gtk_table_attach(GTK_TABLE(parent), *xpm_button,
  172.            0, 1, pos, pos+1, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 2);
  173.  
  174.   /* create hbox */
  175.   *label_box = gtk_hbox_new(FALSE, 0);
  176.   gtk_widget_show(*label_box);
  177.  
  178.   /* create label */
  179.   *label = gtk_label_new(text);
  180.   gtk_widget_show(*label);
  181.  
  182.   /* put label and pixmap in hbox */
  183.   gtk_box_pack_end(GTK_BOX(*label_box), *label, TRUE, FALSE, 0);
  184.  
  185.   /* create hbox in button */
  186.   gtk_container_add(GTK_CONTAINER(*xpm_button), *label_box);
  187. }
  188.  
  189. /*---------------------------------------------------------------------------*/
  190. /* Set buttons pixmaps */
  191. /*---------------------------------------------------------------------------*/
  192.  
  193. void 
  194. rcm_set_pixmaps (RcmCircle *circle)
  195. {
  196.   rcm_set_pixmap(&circle->cw_ccw_pixmap, circle->cw_ccw_button->parent, circle->cw_ccw_box, rcm_cw_xpm);
  197.   rcm_set_pixmap(&circle->a_b_pixmap, circle->a_b_button->parent, circle->a_b_box, rcm_a_b_xpm);
  198.   rcm_set_pixmap(&circle->f360_pixmap, circle->f360_button->parent, circle->f360_box, rcm_360_xpm);
  199. }
  200.  
  201. /*---------------------------------------------------------------------------*/
  202. /* Main: One circles with values and buttons */
  203. /*---------------------------------------------------------------------------*/
  204.  
  205. RcmCircle*
  206. rcm_create_one_circle (gint   height, 
  207.                gchar *label_content)
  208. {
  209.   GtkWidget *frame, *button_table, *legend_table;
  210.   GtkWidget *label, *label_box, *xpm_button, *entry;
  211.   GtkAdjustment *adj;
  212.   RcmCircle *st;
  213.  
  214.   st = g_new(RcmCircle, 1);
  215.  
  216.   st->action_flag = VIRGIN;
  217.   st->angle = g_new(RcmAngle, 1);
  218.   st->angle->alpha = INITIAL_ALPHA;
  219.   st->angle->beta = INITIAL_BETA;
  220.   st->angle->cw_ccw = 1;
  221.  
  222.   /** Main: Circle: create (main) frame **/
  223.   st->frame = gtk_frame_new(label_content);
  224.   gtk_container_set_border_width(GTK_CONTAINER(st->frame), 0);
  225.   gtk_widget_show(st->frame);
  226.  
  227.   /** Main: Circle: create frame & preview **/
  228.  
  229.   /* create frame */
  230.   frame = gtk_frame_new(NULL);
  231.   gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
  232.   gtk_container_set_border_width(GTK_CONTAINER(frame), 0);
  233.   gtk_widget_show(frame);
  234.  
  235.   /* create preview */
  236.   st->preview = gtk_preview_new(GTK_PREVIEW_COLOR);
  237.   gtk_preview_size(GTK_PREVIEW(st->preview), height, height);
  238.   gtk_widget_show(st->preview);
  239.   gtk_container_add(GTK_CONTAINER(frame), st->preview);
  240.  
  241.   /* set signals */
  242.   gtk_widget_set_events(st->preview, RANGE_ADJUST_MASK);
  243.  
  244.   gtk_signal_connect_after(GTK_OBJECT(st->preview), "expose_event",
  245.                (GtkSignalFunc) rcm_expose_event, st);
  246.   
  247.   gtk_signal_connect(GTK_OBJECT(st->preview), "button_press_event",
  248.              (GtkSignalFunc) rcm_button_press_event, st);
  249.  
  250.   gtk_signal_connect(GTK_OBJECT(st->preview), "button_release_event",
  251.              (GtkSignalFunc) rcm_release_event, st);
  252.   
  253.   gtk_signal_connect(GTK_OBJECT(st->preview), "motion_notify_event",
  254.              (GtkSignalFunc) rcm_motion_notify_event, st);
  255.   
  256.   rcm_render_circle(st->preview, SUM, MARGIN);
  257.  
  258.   /** Main: Circle: create table for buttons **/ 
  259.   button_table = gtk_table_new(3, 1, FALSE);
  260.   gtk_widget_show(button_table);
  261.  
  262.   /** Main: Circle: Buttons **/
  263.   rcm_create_pixmap_button(&label, &xpm_button, &label_box, rcm_cw_ccw, st,
  264.                (st->angle->cw_ccw>0) ?
  265.                _("Switch to clockwise") : _("Switch to c/clockwise"),
  266.                button_table, 0);
  267.   st->cw_ccw_pixmap = NULL;
  268.   st->cw_ccw_button = xpm_button;
  269.   st->cw_ccw_box = label_box;
  270.   st->cw_ccw_label = label;
  271.  
  272.   rcm_create_pixmap_button(&label, &xpm_button, &label_box, rcm_a_to_b, st,
  273.                _("Change order of arrows"), button_table, 1);
  274.   st->a_b_pixmap = NULL;
  275.   st->a_b_box = label_box;
  276.   st->a_b_button = xpm_button;
  277.  
  278.   rcm_create_pixmap_button(&label, &xpm_button, &label_box, rcm_360_degrees, st,
  279.                _("Select all"), button_table, 2);
  280.   st->f360_pixmap = NULL;
  281.   st->f360_box = label_box;
  282.   st->f360_button = xpm_button;
  283.  
  284.   /** Main: Circle: Legend **/
  285.   legend_table = gtk_table_new(1, 6, FALSE);
  286.   gtk_widget_show(legend_table);
  287.  
  288.   /* spinbutton 1 */
  289.   label = gtk_label_new(_("From"));
  290.   gtk_widget_show(label);
  291.   gtk_table_attach(GTK_TABLE(legend_table), label, 0,1, 0,1,
  292.            0, GTK_EXPAND, 5, 5);
  293.  
  294.   st->angle->alpha = INITIAL_ALPHA;
  295.   adj = (GtkAdjustment *) gtk_adjustment_new(st->angle->alpha, 0.0, 2.0, 0.0001, 0.001, 0.0);
  296.   st->alpha_entry = entry = gtk_spin_button_new(adj, 0.01, 4);
  297.   gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(entry), TRUE);
  298.   gtk_widget_show(entry);
  299.   gtk_signal_connect(GTK_OBJECT(entry), "changed", (GtkSignalFunc)rcm_set_alpha, st);
  300.   gtk_table_attach(GTK_TABLE(legend_table), entry, 1,2, 0,1,
  301.            GTK_EXPAND|GTK_FILL, GTK_EXPAND, 2, 4);
  302.  
  303.   /* label */
  304.   st->alpha_units_label = gtk_label_new(rcm_units_string(Current.Units));
  305.   gtk_widget_show(st->alpha_units_label);
  306.  
  307.   gtk_table_attach(GTK_TABLE(legend_table), st->alpha_units_label, 2, 3, 0, 1,
  308.            0, GTK_EXPAND, 4, 4);
  309.  
  310.   /* spinbutton 2 */
  311.   label = gtk_label_new(_("To"));
  312.   gtk_widget_show(label);
  313.   gtk_table_attach(GTK_TABLE(legend_table), label, 3,4, 0,1,
  314.            0, GTK_EXPAND, 4, 4);
  315.  
  316.   st->angle->beta = INITIAL_BETA;
  317.   adj = (GtkAdjustment *) gtk_adjustment_new(st->angle->beta, 0.0, 2.0, 0.0001, 0.001, 0.0);
  318.   st->beta_entry = entry = gtk_spin_button_new(adj, 0.01, 4);
  319.   gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(entry), TRUE);
  320.   gtk_widget_show(entry);
  321.   gtk_signal_connect(GTK_OBJECT(entry), "changed", (GtkSignalFunc)rcm_set_beta, st);
  322.   gtk_table_attach(GTK_TABLE(legend_table), entry, 4,5, 0,1,
  323.            GTK_EXPAND|GTK_FILL, GTK_EXPAND, 2, 4);
  324.  
  325.   /* label */
  326.   st->beta_units_label = gtk_label_new(rcm_units_string(Current.Units));
  327.   gtk_widget_show(st->beta_units_label);
  328.  
  329.   gtk_table_attach(GTK_TABLE(legend_table), st->beta_units_label, 5,6, 0,1,
  330.            0, GTK_EXPAND, 4, 4);
  331.  
  332.   /* Main: Circle: create table for Preview / Buttons / Legend */
  333.   st->table= gtk_table_new(2, 2, FALSE);
  334.   gtk_widget_show(st->table);
  335.   
  336.   gtk_table_attach(GTK_TABLE(st->table), frame, 0, 1, 0, 1,
  337.              0, GTK_EXPAND, 4, 0);
  338.   
  339.   gtk_table_attach(GTK_TABLE(st->table), button_table, 1, 2, 0, 1,
  340.            0, GTK_EXPAND, 2, 0);
  341.   
  342.   gtk_table_attach(GTK_TABLE(st->table), legend_table, 0, 2, 1, 2,
  343.            GTK_EXPAND|GTK_FILL, GTK_EXPAND, 0, 2);
  344.  
  345.   /* add table to (main) frame */
  346.   gtk_container_add(GTK_CONTAINER(st->frame), st->table);
  347.  
  348.   return st;
  349. }
  350.  
  351. /*---------------------------------------------------------------------------*/
  352. /* Main */
  353. /*---------------------------------------------------------------------------*/
  354.  
  355. GtkWidget*
  356. rcm_create_main (void)
  357. {
  358.   GtkWidget *vbox;
  359.  
  360.   Current.From = rcm_create_one_circle (SUM, _("From"));
  361.   Current.To   = rcm_create_one_circle (SUM, _("To"));
  362.  
  363.   vbox = gtk_vbox_new (FALSE, 4);
  364.  
  365.   gtk_box_pack_start (GTK_BOX (vbox), Current.From->frame,
  366.               FALSE, FALSE, 0);
  367.   gtk_box_pack_start (GTK_BOX (vbox), Current.To->frame,
  368.               FALSE, FALSE, 0);
  369.  
  370.   gtk_widget_show (vbox);
  371.  
  372.   return vbox;
  373. }
  374.  
  375. /*---------------------------------------------------------------------------*/
  376. /* Misc: Gray */
  377. /*---------------------------------------------------------------------------*/
  378.  
  379. RcmGray*
  380. rcm_create_gray (void)
  381. {
  382.   GtkWidget *frame, *preview, *as_or_to_frame;
  383.   GtkWidget *table, *previewframe, *legend_table;
  384.   GtkWidget *mini_table;
  385.   GtkWidget *label, *entry;
  386.   GtkWidget *gray_sat_frame;
  387.   GtkWidget *radio_box, *button;
  388.   GSList *group = NULL;
  389.   RcmGray *st;
  390.   GtkAdjustment *adj;
  391.  
  392.   st = g_new (RcmGray, 1);
  393.   st->hue         = 0;
  394.   st->satur       = 0;
  395.   st->action_flag = VIRGIN;
  396.  
  397.   /** Gray **/
  398.   st->frame = frame = gtk_frame_new (_("Gray"));
  399.   gtk_widget_show (frame);
  400.  
  401.   /* Gray: Circle: Circle (Preview) */
  402.   previewframe = gtk_frame_new (NULL);
  403.   gtk_frame_set_shadow_type (GTK_FRAME (previewframe), GTK_SHADOW_IN);
  404.   gtk_widget_show (previewframe);
  405.    
  406.   st->preview = preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  407.   gtk_preview_size (GTK_PREVIEW (preview), GRAY_SUM, GRAY_SUM);
  408.   gtk_widget_show (preview);
  409.   gtk_container_add (GTK_CONTAINER (previewframe), preview);
  410.  
  411.   gtk_widget_set_events (preview, RANGE_ADJUST_MASK);
  412.  
  413.   gtk_signal_connect_after (GTK_OBJECT (preview), "expose_event",
  414.                 (GtkSignalFunc) rcm_gray_expose_event, st);
  415.  
  416.   gtk_signal_connect (GTK_OBJECT (preview), "button_press_event",
  417.               (GtkSignalFunc) rcm_gray_button_press_event, st);
  418.  
  419.   gtk_signal_connect (GTK_OBJECT (preview), "button_release_event",
  420.               (GtkSignalFunc) rcm_gray_release_event, st);
  421.  
  422.   gtk_signal_connect (GTK_OBJECT (preview), "motion_notify_event",
  423.               (GtkSignalFunc) rcm_gray_motion_notify_event, st);
  424.  
  425.   /* Gray: Circle: Legend */  
  426.   legend_table = gtk_table_new (2, 3, FALSE);
  427.   gtk_table_set_col_spacings (GTK_TABLE (legend_table), 4);
  428.   gtk_table_set_row_spacings (GTK_TABLE (legend_table), 2);
  429.   gtk_widget_show (legend_table);
  430.  
  431.   /* Gray: Circle: Spinbutton 1 */
  432.   label = gtk_label_new(_("Hue:"));
  433.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  434.   gtk_table_attach (GTK_TABLE (legend_table), label, 0, 1, 0, 1, 
  435.             GTK_FILL, GTK_FILL, 0, 0);
  436.   gtk_widget_show (label);
  437.  
  438.   st->hue = INITIAL_GRAY_HUE;
  439.   adj = (GtkAdjustment *) gtk_adjustment_new (st->hue, 0.0, 2.0, 0.0001, 0.001, 0.0);
  440.   st->hue_entry = entry = gtk_spin_button_new (adj, 0.01, 4);
  441.   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON(entry), TRUE);
  442.   gtk_widget_set_usize (entry, 75, 0);
  443.   gtk_signal_connect (GTK_OBJECT(entry), "changed",
  444.               (GtkSignalFunc) rcm_set_hue, st);
  445.   gtk_table_attach (GTK_TABLE (legend_table), entry, 1, 2, 0, 1,
  446.             GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 0);
  447.   gtk_widget_show (entry);
  448.  
  449.   /* Gray: Circle: units label */
  450.   st->hue_units_label = gtk_label_new (rcm_units_string (Current.Units));
  451.   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  452.   gtk_table_attach (GTK_TABLE (legend_table), st->hue_units_label, 2, 3, 0, 1,
  453.             GTK_EXPAND, GTK_EXPAND, 0, 0);
  454.   gtk_widget_show (st->hue_units_label);
  455.  
  456.   /* Gray: Circle: Spinbutton 2 */
  457.   label = gtk_label_new (_("Saturation:"));
  458.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  459.   gtk_table_attach (GTK_TABLE (legend_table), label, 0, 1, 1, 2, 
  460.             GTK_FILL, GTK_FILL, 0, 0);
  461.   gtk_widget_show (label);
  462.  
  463.   st->satur = INITIAL_GRAY_SAT;
  464.   adj = (GtkAdjustment *) gtk_adjustment_new (st->satur, 0.0, 1.0, 0.0001, 0.001, 0.0);
  465.   st->satur_entry = entry = gtk_spin_button_new (adj, 0.01, 4);
  466.   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (entry), TRUE);
  467.   gtk_widget_set_usize (entry, 75, 0);
  468.   gtk_signal_connect (GTK_OBJECT (entry), "changed",
  469.               (GtkSignalFunc) rcm_set_satur, st);
  470.   gtk_table_attach (GTK_TABLE (legend_table), entry, 1, 2, 1, 2, 
  471.             GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 2);
  472.   gtk_widget_show (entry);
  473.  
  474.   /** Gray: Operation-Mode **/
  475.   as_or_to_frame = gtk_frame_new (_("Mode"));
  476.   gtk_widget_show (as_or_to_frame);
  477.  
  478.   radio_box = gtk_vbox_new (FALSE, 2);
  479.   gtk_container_add (GTK_CONTAINER (as_or_to_frame), radio_box);
  480.   gtk_container_set_border_width (GTK_CONTAINER (radio_box), 4);
  481.   gtk_widget_show (radio_box);
  482.  
  483.   /* Gray: Operation-Mode: two radio buttons */
  484.   button = gtk_radio_button_new_with_label(group, _("Treat as this"));
  485.   gtk_widget_show (button);
  486.   gtk_box_pack_start (GTK_BOX (radio_box), button, FALSE, FALSE, 0);
  487.   if (Current.Gray_to_from == GRAY_FROM)
  488.     gtk_button_clicked (GTK_BUTTON (button));
  489.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  490.               (GtkSignalFunc) rcm_switch_to_gray_from,
  491.               &(Current.Gray_to_from));
  492.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  493.  
  494.   button = gtk_radio_button_new_with_label (group, _("Change to this"));
  495.   gtk_widget_show (button);
  496.   gtk_box_pack_start (GTK_BOX (radio_box), button, FALSE, FALSE, 0);
  497.   if (Current.Gray_to_from == GRAY_TO)
  498.     gtk_button_clicked (GTK_BUTTON (button));
  499.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  500.               (GtkSignalFunc) rcm_switch_to_gray_to,
  501.               &(Current.Gray_to_from));
  502.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  503.  
  504.   /** Gray: What is gray? **/ 
  505.   gray_sat_frame = gtk_frame_new(_("What is Gray?"));
  506.   gtk_widget_show (gray_sat_frame);
  507.  
  508.   table = gtk_table_new (1, 3, FALSE);
  509.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  510.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  511.   gtk_widget_show (table);
  512.  
  513.   label = gtk_label_new(_("Saturation"));
  514.   gtk_widget_show (label);
  515.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
  516.             GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 0);
  517.  
  518.   label = gtk_label_new ("<=");
  519.   gtk_widget_show (label);
  520.   gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
  521.             GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 0);
  522.  
  523.   st->gray_sat = INITIAL_GRAY_RSAT;
  524.   adj = (GtkAdjustment *) gtk_adjustment_new (st->gray_sat, 0.0, 1.0, 0.0001, 0.001, 0.0);
  525.  
  526.   st->gray_sat_entry = entry = gtk_spin_button_new (adj, 0.01, 4);
  527.   gtk_widget_set_usize (entry, 75, 0);
  528.   gtk_widget_show (entry);
  529.   gtk_signal_connect (GTK_OBJECT (entry), "changed",
  530.               (GtkSignalFunc) rcm_set_gray_sat, st);
  531.   gtk_table_attach (GTK_TABLE (table), entry, 2, 3, 0, 1,
  532.             GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 0);
  533.  
  534.   gtk_container_add (GTK_CONTAINER (gray_sat_frame), table);
  535.  
  536.   /** add all frames to table **/
  537.  
  538.   /* add preview and legend to table */
  539.   mini_table = gtk_table_new (2, 1, FALSE);
  540.   gtk_table_set_row_spacings (GTK_TABLE (mini_table), 4);
  541.   gtk_widget_show (mini_table);
  542.     
  543.   gtk_table_attach (GTK_TABLE (mini_table), previewframe, 0, 1, 0, 1,
  544.             GTK_SHRINK, GTK_SHRINK, 0, 0);
  545.     
  546.   gtk_table_attach (GTK_TABLE (mini_table), legend_table, 0, 1, 1, 2,
  547.             GTK_SHRINK, GTK_SHRINK, 0, 0);
  548.  
  549.   /* add mini_table & two frames to table */
  550.   table = gtk_table_new (2, 2, FALSE);
  551.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  552.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  553.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  554.   gtk_widget_show (table);
  555.  
  556.   gtk_table_attach (GTK_TABLE (table), mini_table, 0, 1, 0, 2,
  557.             GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  558.  
  559.   gtk_table_attach (GTK_TABLE (table), as_or_to_frame, 1, 2, 0, 1,
  560.             GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  561.  
  562.   gtk_table_attach (GTK_TABLE (table), gray_sat_frame, 1, 2, 1, 2,
  563.             GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  564.  
  565.   gtk_container_add (GTK_CONTAINER (frame), table);
  566.  
  567.   /* update circle (preview) */
  568.   rcm_render_circle (preview, GRAY_SUM, GRAY_MARGIN);
  569.  
  570.   return st;
  571. }
  572.  
  573. /*----------------------------------------------------------------------------*/
  574. /* Misc */
  575. /*----------------------------------------------------------------------------*/
  576.  
  577. GtkWidget *
  578. rcm_create_misc (void)
  579. {
  580.   GtkWidget *label, *table;
  581.   GtkWidget *units_frame, *units_vbox;
  582.   GtkWidget *preview_frame, *preview_vbox;
  583.   GtkWidget *item, *menu, *root, *hbox;
  584.   GtkWidget *button;
  585.  
  586.   GSList *units_group = NULL;
  587.   GSList *preview_group = NULL;
  588.   
  589.   /** Misc: Gray circle **/
  590.   Current.Gray = rcm_create_gray ();
  591.  
  592.   /** Misc: Used unit selection **/
  593.   units_frame = gtk_frame_new (_("Units"));
  594.   gtk_widget_show (units_frame);
  595.  
  596.   units_vbox = gtk_vbox_new (FALSE, 2);
  597.   gtk_container_add (GTK_CONTAINER (units_frame), units_vbox);
  598.   gtk_container_set_border_width (GTK_CONTAINER (units_vbox), 4);
  599.   gtk_widget_show (units_vbox);
  600.  
  601.   /* Misc: Used unit selection: 3 radio buttons */
  602.   button = gtk_radio_button_new_with_label (units_group, _("Radians"));
  603.   gtk_widget_show (button);
  604.   gtk_box_pack_start (GTK_BOX (units_vbox), button, FALSE, FALSE, 0);
  605.   if (Current.Units == RADIANS)
  606.     gtk_button_clicked (GTK_BUTTON (button));
  607.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  608.               (GtkSignalFunc) rcm_switch_to_radians, NULL);
  609.   units_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  610.  
  611.   button = gtk_radio_button_new_with_label (units_group, _("Radians/Pi"));
  612.   gtk_widget_show (button);
  613.   gtk_box_pack_start (GTK_BOX (units_vbox), button, FALSE, FALSE, 0);
  614.   if (Current.Units == RADIANS_OVER_PI)
  615.     gtk_button_clicked (GTK_BUTTON (button));
  616.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  617.               (GtkSignalFunc) rcm_switch_to_radians_over_PI, NULL);
  618.   units_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  619.  
  620.   button = gtk_radio_button_new_with_label (units_group, _("Degrees"));
  621.   gtk_widget_show (button);
  622.   gtk_box_pack_start (GTK_BOX (units_vbox), button, FALSE, FALSE, 0);
  623.   if (Current.Units == DEGREES)
  624.     gtk_button_clicked (GTK_BUTTON (button));
  625.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  626.               (GtkSignalFunc) rcm_switch_to_degrees, NULL);
  627.  
  628.   /** Misc: Preview settings **/
  629.  
  630.   /* Misc: Preview settings: Continuous update ?! */
  631.   preview_frame = gtk_frame_new (_("Preview"));
  632.   preview_vbox = gtk_vbox_new (FALSE, 4);
  633.   gtk_container_set_border_width (GTK_CONTAINER (preview_vbox), 4);
  634.   gtk_widget_show (preview_vbox);
  635.  
  636.   gtk_container_add (GTK_CONTAINER (preview_frame), preview_vbox);
  637.   gtk_widget_show (preview_frame);
  638.   
  639.   button = gtk_check_button_new_with_label (_("Continuous update"));
  640.   gtk_box_pack_start(GTK_BOX(preview_vbox), button, FALSE, FALSE, 0);
  641.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), Current.RealTime);
  642.    
  643.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  644.               (GtkSignalFunc) (GtkSignalFunc) rcm_preview_as_you_drag,
  645.               &(Current.RealTime));
  646.  
  647.   gtk_widget_show (button);
  648.  
  649.   /* Misc: Preview settings: Area */
  650.   hbox = gtk_hbox_new (FALSE, 4);
  651.   gtk_widget_show (hbox);
  652.   gtk_box_pack_start (GTK_BOX (preview_vbox), hbox, FALSE, FALSE, 4);
  653.  
  654.   label = gtk_label_new (_("Area:"));
  655.   gtk_widget_show (label);
  656.   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  657.  
  658.   /* create menu entries */
  659.   menu = gtk_menu_new ();
  660.  
  661.   item = gtk_radio_menu_item_new_with_label (preview_group, _("Entire Image"));
  662.   preview_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item));
  663.   gtk_menu_append (GTK_MENU (menu), item);
  664.   gtk_widget_show (item);
  665.   gtk_signal_connect (GTK_OBJECT (item), "activate",
  666.               (GtkSignalFunc) rcm_entire_image, NULL);
  667.     
  668.   item = gtk_radio_menu_item_new_with_label (preview_group, _("Selection"));
  669.   preview_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item));
  670.   gtk_menu_append (GTK_MENU (menu), item);
  671.   gtk_widget_show (item);
  672.   gtk_signal_connect (GTK_OBJECT (item), "activate",
  673.               (GtkSignalFunc) rcm_selection, NULL);
  674.  
  675.   item = gtk_radio_menu_item_new_with_label (preview_group, _("Context"));
  676.   preview_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item));
  677.   gtk_widget_show (item);
  678.   gtk_menu_append (GTK_MENU (menu), item);
  679.   gtk_signal_connect (GTK_OBJECT (item), "activate",
  680.               (GtkSignalFunc) rcm_selection_in_context, NULL);
  681.  
  682.   /* create (options) menu */
  683.   root =  gtk_option_menu_new ();
  684.   gtk_option_menu_set_menu (GTK_OPTION_MENU (root), menu);
  685.   gtk_option_menu_set_history (GTK_OPTION_MENU (root), 4);
  686.   gtk_widget_show (root);
  687.  
  688.   gtk_box_pack_start (GTK_BOX (hbox), root, FALSE, FALSE, 0);
  689.  
  690.   table = gtk_table_new (2, 2, FALSE);
  691.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  692.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  693.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  694.  
  695.   /** add frames (gray/preview/units) to table **/
  696.   gtk_table_attach (GTK_TABLE (table), Current.Gray->frame,  0, 2, 0, 1,
  697.             GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  698.  
  699.   gtk_table_attach (GTK_TABLE (table), preview_frame, 0, 1, 1, 2,
  700.             GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  701.  
  702.   gtk_table_attach (GTK_TABLE (table), units_frame, 1, 2, 1, 2,
  703.             GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  704.   
  705.   gtk_widget_show (table);
  706.  
  707.   return table;
  708. }
  709.  
  710. /*---------------------------------------------------------------------------*/
  711. /* create and call main dialog */
  712. /*---------------------------------------------------------------------------*/
  713.  
  714. gint 
  715. rcm_dialog (void)
  716. {
  717.   GtkWidget *table, *dlg, *hbox, *notebook;
  718.   GtkWidget *previews, *mains, *miscs;
  719.  
  720.   Current.Bna = g_new (RcmBna, 1);
  721.  
  722.   /* init GTK and install colormap */
  723.   gimp_ui_init ("rcm", TRUE);
  724.  
  725.   /* Create dialog */
  726.   dlg = gimp_dialog_new (_("Colormap Rotation"), "rcm",
  727.              gimp_standard_help_func, "filters/rcm.html",
  728.              GTK_WIN_POS_MOUSE,
  729.              FALSE, TRUE, FALSE,
  730.  
  731.              _("OK"), rcm_ok_callback,
  732.              NULL, NULL, NULL, TRUE, FALSE,
  733.              _("Cancel"), gtk_widget_destroy,
  734.              NULL, 1, NULL, FALSE, TRUE,
  735.  
  736.              NULL);
  737.  
  738.   Current.Bna->dlg = dlg;
  739.  
  740.   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
  741.               GTK_SIGNAL_FUNC (gtk_main_quit),
  742.               NULL);
  743.  
  744.   /* Create sub-dialogs */
  745.   Current.reduced = rcm_reduce_image (Current.drawable, Current.mask,
  746.                       MAX_PREVIEW_SIZE, ENTIRE_IMAGE);
  747.   previews = rcm_create_previews ();
  748.   mains    = rcm_create_main ();
  749.   miscs    = rcm_create_misc ();
  750.   Current.Bna->bna_frame = previews;
  751.  
  752.   rcm_render_preview (Current.Bna->before, ORIGINAL);
  753.   rcm_render_preview (Current.Bna->after, CURRENT);
  754.  
  755.   /* H-Box */
  756.   hbox = gtk_hbox_new (FALSE, 6);
  757.   gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
  758.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), hbox, TRUE, TRUE, 0);
  759.   gtk_widget_show (hbox);
  760.  
  761.   gtk_box_pack_start (GTK_BOX(hbox), previews, TRUE, TRUE, 0);
  762.  
  763.   /* Notebook */
  764.   notebook = gtk_notebook_new ();
  765.   gtk_notebook_set_tab_pos (GTK_NOTEBOOK(notebook), GTK_POS_TOP);
  766.   gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0);
  767.   gtk_widget_show (notebook);
  768.  
  769.   table = gtk_table_new (1, 2, FALSE);
  770.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  771.   gtk_widget_show (table);
  772.  
  773.   gtk_table_attach (GTK_TABLE (table), mains, 1, 2, 0, 1,
  774.             GTK_EXPAND | GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0);
  775.  
  776.   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table,
  777.                 gtk_label_new (_("Main")));
  778.  
  779.   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), miscs,
  780.                 gtk_label_new (_("Misc")));
  781.  
  782.   gtk_widget_show (dlg);
  783.  
  784.   rcm_set_pixmaps (Current.From);
  785.   rcm_set_pixmaps (Current.To);
  786.  
  787.   gdk_flush (); 
  788.   gtk_main ();
  789.  
  790.   return Current.Success;
  791. }
  792.