home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / libgimp / gimpunitmenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-10  |  18.0 KB  |  627 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1999 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpunitmenu.c
  5.  * Copyright (C) 1999 Michael Natterer <mitch@gimp.org>
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include "config.h"
  24.  
  25. #include <gtk/gtk.h>
  26.  
  27. #include "gimpdialog.h"
  28. #include "gimpunitmenu.h"
  29.  
  30. #include "libgimp-intl.h"
  31.  
  32.  
  33. /*  private functions  */
  34. static const gchar * gimp_unit_menu_build_string (const gchar *format,
  35.                           GimpUnit     unit);
  36. static void          gimp_unit_menu_callback     (GtkWidget   *widget,
  37.                           gpointer     data);
  38.  
  39. enum
  40. {
  41.   UNIT_CHANGED,
  42.   LAST_SIGNAL
  43. };
  44.  
  45. static guint gimp_unit_menu_signals[LAST_SIGNAL] = { 0 };
  46.  
  47. static GtkOptionMenuClass *parent_class = NULL;
  48.  
  49. static void
  50. gimp_unit_menu_destroy (GtkObject *object)
  51. {
  52.   GimpUnitMenu *gum;
  53.  
  54.   g_return_if_fail (object != NULL);
  55.   g_return_if_fail (GIMP_IS_UNIT_MENU (object));
  56.  
  57.   gum = GIMP_UNIT_MENU (object);
  58.  
  59.   if (gum->format)
  60.     g_free (gum->format);
  61.  
  62.   if (GTK_OBJECT_CLASS (parent_class)->destroy)
  63.     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
  64. }
  65.  
  66. static void
  67. gimp_unit_menu_class_init (GimpUnitMenuClass *class)
  68. {
  69.   GtkObjectClass *object_class;
  70.  
  71.   object_class = (GtkObjectClass*) class;
  72.  
  73.   parent_class = gtk_type_class (gtk_option_menu_get_type ());
  74.  
  75.   gimp_unit_menu_signals[UNIT_CHANGED] = 
  76.     gtk_signal_new ("unit_changed",
  77.             GTK_RUN_FIRST,
  78.             object_class->type,
  79.             GTK_SIGNAL_OFFSET (GimpUnitMenuClass,
  80.                        unit_changed),
  81.             gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
  82.  
  83.   gtk_object_class_add_signals (object_class, gimp_unit_menu_signals, 
  84.                 LAST_SIGNAL);
  85.  
  86.   class->unit_changed = NULL;
  87.  
  88.   object_class->destroy = gimp_unit_menu_destroy;
  89. }
  90.  
  91. static void
  92. gimp_unit_menu_init (GimpUnitMenu *gum)
  93. {
  94.   gum->format       = NULL;
  95.   gum->unit         = GIMP_UNIT_PIXEL;
  96.   gum->show_pixels  = FALSE;
  97.   gum->show_percent = FALSE;
  98.   gum->selection    = NULL;
  99.   gum->clist        = NULL;
  100. }
  101.  
  102. GtkType
  103. gimp_unit_menu_get_type (void)
  104. {
  105.   static GtkType gum_type = 0;
  106.  
  107.   if (!gum_type)
  108.     {
  109.       GtkTypeInfo gum_info =
  110.       {
  111.     "GimpUnitMenu",
  112.     sizeof (GimpUnitMenu),
  113.     sizeof (GimpUnitMenuClass),
  114.     (GtkClassInitFunc) gimp_unit_menu_class_init,
  115.     (GtkObjectInitFunc) gimp_unit_menu_init,
  116.     /* reserved_1 */ NULL,
  117.     /* reserved_2 */ NULL,
  118.         (GtkClassInitFunc) NULL
  119.       };
  120.  
  121.       gum_type = gtk_type_unique (gtk_option_menu_get_type (), &gum_info);
  122.     }
  123.   
  124.   return gum_type;
  125. }
  126.  
  127. /**
  128.  * gimp_unit_menu_new:
  129.  * @format: A printf-like format string which is used to create the unit
  130.  *          strings.
  131.  * @unit: The initially selected unit.
  132.  * @show_pixels: #TRUE if the unit menu should contain an item for
  133.  *               GIMP_UNIT_PIXEL.
  134.  * @show_percent: #TRUE in the unit menu should contain an item for
  135.  *                GIMP_UNIT_PERCENT.
  136.  * @show_custom: #TRUE if the unit menu should contain a "More..." item for
  137.  *               opening the user-defined-unit selection dialog.
  138.  *
  139.  * Creates a new #GimpUnitMenu widget.
  140.  *
  141.  * The @format string supports the following percent expansions:
  142.  *
  143.  * Returns: A pointer to the new #GimpUnitMenu widget.
  144.  *
  145.  */
  146. GtkWidget *
  147. gimp_unit_menu_new (const gchar *format,
  148.             GimpUnit     unit,
  149.             gboolean     show_pixels,
  150.             gboolean     show_percent,
  151.             gboolean     show_custom)
  152. {
  153.   GimpUnitMenu *gum;
  154.   GtkWidget    *menu;
  155.   GtkWidget    *menuitem;
  156.   GimpUnit      u;
  157.  
  158.   g_return_val_if_fail ((unit >= GIMP_UNIT_PIXEL) &&
  159.             (unit < gimp_unit_get_number_of_units ()) ||
  160.             (unit == GIMP_UNIT_PERCENT), NULL);
  161.  
  162.   if ((unit >= gimp_unit_get_number_of_built_in_units ()) &&
  163.       (unit != GIMP_UNIT_PERCENT))
  164.     show_custom = TRUE;
  165.  
  166.   gum = gtk_type_new (gimp_unit_menu_get_type ());
  167.  
  168.   gum->format       = g_strdup (format);
  169.   gum->show_pixels  = show_pixels;
  170.   gum->show_percent = show_percent;
  171.  
  172.   menu = gtk_menu_new ();
  173.   for (u = show_pixels ? GIMP_UNIT_PIXEL : GIMP_UNIT_INCH;
  174.        u < gimp_unit_get_number_of_built_in_units ();
  175.        u++)
  176.     {
  177.       /*  special cases "pixels" and "percent"  */
  178.       if (u == GIMP_UNIT_INCH)
  179.     {
  180.       if (show_percent)
  181.         {
  182.           menuitem =
  183.         gtk_menu_item_new_with_label
  184.         (gimp_unit_menu_build_string (format, GIMP_UNIT_PERCENT));
  185.           gtk_menu_append (GTK_MENU (menu), menuitem);
  186.           gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
  187.                   GTK_SIGNAL_FUNC (gimp_unit_menu_callback),
  188.                   gum);
  189.           gtk_object_set_data (GTK_OBJECT (menuitem), "gimp_unit_menu",
  190.                    (gpointer) GIMP_UNIT_PERCENT);
  191.           gtk_widget_show (menuitem);
  192.         }
  193.  
  194.       if (show_pixels || show_percent)
  195.         {
  196.           menuitem = gtk_menu_item_new ();
  197.           gtk_menu_append (GTK_MENU (menu), menuitem);
  198.           gtk_widget_set_sensitive (menuitem, FALSE);
  199.           gtk_widget_show (menuitem);
  200.         }
  201.     }
  202.  
  203.       menuitem =
  204.     gtk_menu_item_new_with_label (gimp_unit_menu_build_string (format, u));
  205.       gtk_menu_append (GTK_MENU (menu), menuitem);
  206.       gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
  207.               GTK_SIGNAL_FUNC (gimp_unit_menu_callback),
  208.               gum);
  209.       gtk_object_set_data (GTK_OBJECT (menuitem), "gimp_unit_menu",
  210.                (gpointer) u);
  211.       gtk_widget_show (menuitem);
  212.     }
  213.  
  214.   if ((unit >= gimp_unit_get_number_of_built_in_units ()) &&
  215.       (unit != GIMP_UNIT_PERCENT))
  216.     {
  217.       menuitem = gtk_menu_item_new ();
  218.       gtk_menu_append (GTK_MENU (menu), menuitem);
  219.       gtk_widget_set_sensitive (menuitem, FALSE);
  220.       gtk_widget_show (menuitem);
  221.       
  222.       menuitem =
  223.     gtk_menu_item_new_with_label (gimp_unit_menu_build_string (format, unit));
  224.       gtk_menu_append (GTK_MENU (menu), menuitem);
  225.       gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
  226.               GTK_SIGNAL_FUNC (gimp_unit_menu_callback),
  227.               gum);
  228.       gtk_object_set_data (GTK_OBJECT (menuitem), "gimp_unit_menu",
  229.                (gpointer) unit);
  230.       gtk_widget_show (menuitem);
  231.     }
  232.  
  233.   if (show_custom)
  234.     {
  235.       menuitem = gtk_menu_item_new ();
  236.       gtk_menu_append (GTK_MENU (menu), menuitem);
  237.       gtk_widget_set_sensitive (menuitem, FALSE);
  238.       gtk_widget_show (menuitem);
  239.  
  240.       menuitem =
  241.     gtk_menu_item_new_with_label (_("More..."));
  242.       gtk_menu_append (GTK_MENU (menu), menuitem);
  243.       gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
  244.               GTK_SIGNAL_FUNC (gimp_unit_menu_callback),
  245.               gum);
  246.       gtk_object_set_data (GTK_OBJECT (menuitem), "gimp_unit_menu",
  247.                (gpointer) (GIMP_UNIT_PERCENT + 1));
  248.       gtk_widget_show (menuitem);
  249.     }
  250.  
  251.   gtk_option_menu_set_menu (GTK_OPTION_MENU (gum), menu);
  252.  
  253.   gum->unit = unit;
  254.   gtk_option_menu_set_history (GTK_OPTION_MENU (gum),
  255.                    (unit == GIMP_UNIT_PIXEL) ? 0 :
  256.                    ((unit == GIMP_UNIT_PERCENT) ?
  257.                 (show_pixels ? 1 : 0) :
  258.                 (((show_pixels || show_percent) ? 2 : 0) +
  259.                  ((show_pixels && show_percent) ? 1 : 0) +
  260.                  ((unit < GIMP_UNIT_END) ?
  261.                   (unit - 1) : GIMP_UNIT_END)))); 
  262.  
  263.   return GTK_WIDGET (gum);
  264. }
  265.  
  266. /**
  267.  * gimp_unit_menu_set_unit:
  268.  * @gum: The unit menu you want to set the unit for.
  269.  * @unit: The new unit.
  270.  *
  271.  * Sets a new #GimpUnit for the specified #GimpUnitMenu.
  272.  *
  273.  */
  274. void
  275. gimp_unit_menu_set_unit (GimpUnitMenu *gum,
  276.              GimpUnit      unit)
  277. {
  278.   GtkWidget *menuitem = NULL;
  279.   GList     *items;
  280.   gint       user_unit;
  281.  
  282.   g_return_if_fail (gum != NULL);
  283.   g_return_if_fail (GIMP_IS_UNIT_MENU (gum));
  284.   g_return_if_fail (((unit >= GIMP_UNIT_PIXEL) &&
  285.              ((unit > GIMP_UNIT_PIXEL) || gum->show_pixels) &&
  286.              (unit < gimp_unit_get_number_of_units ())) ||
  287.             ((unit == GIMP_UNIT_PERCENT) && gum->show_percent));
  288.  
  289.   if (unit == gum->unit)
  290.     return;
  291.  
  292.   items = GTK_MENU_SHELL (GTK_OPTION_MENU (gum)->menu)->children;
  293.   user_unit = (GIMP_UNIT_END +
  294.            (((gum->show_pixels || gum->show_percent) ? 2 : 0) +
  295.         ((gum->show_pixels && gum->show_percent) ? 1 : 0)));
  296.  
  297.   if ((unit >= GIMP_UNIT_END) && (unit != GIMP_UNIT_PERCENT))
  298.     {
  299.       if ((g_list_length (items) - 3) >= user_unit)
  300.     {
  301.       gtk_widget_destroy (GTK_WIDGET (g_list_nth_data (items,
  302.                                user_unit - 1)));
  303.       gtk_widget_destroy (GTK_WIDGET (g_list_nth_data (items,
  304.                                user_unit - 1)));
  305.     }
  306.  
  307.       menuitem = gtk_menu_item_new ();
  308.       gtk_menu_append (GTK_MENU (GTK_OPTION_MENU (gum)->menu), menuitem);
  309.       gtk_widget_set_sensitive (menuitem, FALSE);
  310.       gtk_menu_reorder_child (GTK_MENU (GTK_OPTION_MENU (gum)->menu),
  311.                   menuitem, user_unit - 1);
  312.       gtk_widget_show (menuitem);
  313.       
  314.       menuitem =
  315.     gtk_menu_item_new_with_label (gimp_unit_menu_build_string (gum->format,
  316.                                    unit));
  317.       gtk_menu_append (GTK_MENU (GTK_OPTION_MENU (gum)->menu), menuitem);
  318.       gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
  319.               GTK_SIGNAL_FUNC (gimp_unit_menu_callback),
  320.               gum);
  321.       gtk_object_set_data (GTK_OBJECT (menuitem), "gimp_unit_menu",
  322.                (gpointer) unit);
  323.       gtk_menu_reorder_child (GTK_MENU (GTK_OPTION_MENU (gum)->menu),
  324.                   menuitem, user_unit);
  325.       gtk_widget_show (menuitem);
  326.     }
  327.  
  328.   gum->unit = unit;
  329.   gtk_option_menu_set_history (GTK_OPTION_MENU (gum),
  330.                    (unit == GIMP_UNIT_PIXEL) ? 0 :
  331.                    ((unit == GIMP_UNIT_PERCENT) ?
  332.                 (gum->show_pixels ? 1 : 0) :
  333.                 (((gum->show_pixels ||
  334.                    gum->show_percent) ? 2 : 0) +
  335.                  ((gum->show_pixels &&
  336.                    gum->show_percent) ? 1 : 0) +
  337.                  ((unit < GIMP_UNIT_END) ?
  338.                   (unit - 1) : GIMP_UNIT_END))));
  339. }
  340.  
  341. /**
  342.  * gimp_unit_menu_get_unit:
  343.  * @gum: The unit menu you want to know the unit of.
  344.  *
  345.  * Returns the #GimpUnit the user has selected from the #GimpUnitMenu.
  346.  *
  347.  * Returns: The unit the user has selected.
  348.  *
  349.  */
  350. GimpUnit
  351. gimp_unit_menu_get_unit (GimpUnitMenu *gum)
  352. {
  353.   g_return_val_if_fail (gum != NULL, GIMP_UNIT_INCH);
  354.   g_return_val_if_fail (GIMP_IS_UNIT_MENU (gum), GIMP_UNIT_INCH);
  355.  
  356.   return gum->unit;
  357. }
  358.  
  359. /*  most of the next two functions is stolen from app/gdisplay.c  */
  360. static gint
  361. print (gchar       *buf,
  362.        gint         len,
  363.        gint         start,
  364.        const gchar *fmt,
  365.        ...)
  366. {
  367.   va_list args;
  368.   gint printed;
  369.  
  370.   va_start (args, fmt);
  371.  
  372.   printed = g_vsnprintf (buf + start, len - start, fmt, args);
  373.   if (printed < 0)
  374.     printed = len - start;
  375.  
  376.   va_end (args);
  377.  
  378.   return printed;
  379. }
  380.  
  381. static const gchar *
  382. gimp_unit_menu_build_string (const gchar *format,
  383.                  GimpUnit     unit)
  384. {
  385.   static gchar buffer[64];
  386.   gint i = 0;
  387.  
  388.   while (i < (sizeof (buffer) - 1) && *format)
  389.     {
  390.       switch (*format)
  391.     {
  392.     case '%':
  393.       format++;
  394.       switch (*format)
  395.         {
  396.         case 0:
  397.           g_warning ("unit-menu-format string ended within %%-sequence");
  398.           break;
  399.           
  400.         case '%':
  401.           buffer[i++] = '%';
  402.           break;
  403.  
  404.         case 'f': /* factor (how many units make up an inch) */
  405.           i += print (buffer, sizeof (buffer), i, "%f",
  406.               gimp_unit_get_factor (unit));
  407.           break;
  408.  
  409.         case 'y': /* symbol ("''" for inch) */
  410.           i += print (buffer, sizeof (buffer), i, "%s",
  411.               gimp_unit_get_symbol (unit));
  412.           break;
  413.  
  414.         case 'a': /* abbreviation */
  415.           i += print (buffer, sizeof (buffer), i, "%s",
  416.               gimp_unit_get_abbreviation (unit));
  417.           break;
  418.  
  419.         case 's': /* singular */
  420.           i += print (buffer, sizeof (buffer), i, "%s",
  421.               gimp_unit_get_singular (unit));
  422.           break;
  423.  
  424.         case 'p': /* plural */
  425.           i += print (buffer, sizeof (buffer), i, "%s",
  426.               gimp_unit_get_plural (unit));
  427.           break;
  428.  
  429.         default:
  430.           g_warning ("gimp_unit_menu_build_string(): "
  431.              "unit-menu-format contains unknown format sequence "
  432.              "'%%%c'", *format);
  433.           break;
  434.         }
  435.       break;
  436.  
  437.     default:
  438.       buffer[i++] = *format;
  439.       break;
  440.     }
  441.       
  442.       format++;
  443.     }
  444.  
  445.   buffer[MIN (i, sizeof (buffer) - 1)] = 0;
  446.  
  447.   return buffer;
  448. }
  449.  
  450. /*  private callback of gimp_unit_menu_create_selection ()  */
  451. static void
  452. gimp_unit_menu_selection_ok_callback (GtkWidget *widget,
  453.                       gpointer   data)
  454. {
  455.   GimpUnitMenu *gum;
  456.   GimpUnit      unit;
  457.  
  458.   gum = GIMP_UNIT_MENU (data);
  459.  
  460.   if (gum->selection && GTK_CLIST (gum->clist)->selection)
  461.     {
  462.       unit = (GimpUnit)
  463.     gtk_clist_get_row_data (GTK_CLIST (gum->clist),
  464.                 (gint) (GTK_CLIST (gum->clist)->selection->data));
  465.       gimp_unit_menu_set_unit (gum, unit);
  466.       gtk_signal_emit (GTK_OBJECT (gum),
  467.                gimp_unit_menu_signals[UNIT_CHANGED]);
  468.  
  469.       gtk_widget_destroy (gum->selection);
  470.     }
  471. }
  472.  
  473. static void
  474. gimp_unit_menu_selection_select_row_callback (GtkWidget      *widget,
  475.                           gint            row, 
  476.                           gint            column, 
  477.                           GdkEventButton *bevent,
  478.                           gpointer        data)
  479. {
  480.   if (bevent && bevent->type == GDK_2BUTTON_PRESS)
  481.     gimp_unit_menu_selection_ok_callback (NULL, data);
  482. }
  483.  
  484. /*  private function of gimp_unit_menu_callback ()  */
  485. static void
  486. gimp_unit_menu_create_selection (GimpUnitMenu *gum)
  487. {
  488.   GtkWidget *vbox;
  489.   GtkWidget *scrolled_win;
  490.   gchar     *titles[2];
  491.   gchar     *row[2];
  492.   GimpUnit   unit;
  493.   gint       num_units;
  494.   gint       unit_width;
  495.   gint       factor_width;
  496.  
  497.   gum->selection =
  498.     gimp_dialog_new (_("Unit Selection"), "unit_selection",
  499.              gimp_standard_help_func, "dialogs/unit_selection.html",
  500.              GTK_WIN_POS_MOUSE,
  501.              FALSE, TRUE, FALSE,
  502.  
  503.              _("OK"), gimp_unit_menu_selection_ok_callback,
  504.              gum, NULL, NULL, TRUE, FALSE,
  505.              _("Cancel"), gtk_widget_destroy,
  506.              NULL, 1, NULL, FALSE, TRUE,
  507.  
  508.              NULL);
  509.  
  510.   gtk_signal_connect (GTK_OBJECT (gum->selection), "destroy",
  511.                       GTK_SIGNAL_FUNC (gtk_widget_destroyed),
  512.                       &gum->selection);
  513.  
  514.   gtk_signal_connect_object_while_alive (GTK_OBJECT (gum), "destroy",
  515.                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
  516.                      GTK_OBJECT (gum->selection));
  517.   gtk_signal_connect_object_while_alive (GTK_OBJECT (gum), "unmap",
  518.                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
  519.                      GTK_OBJECT (gum->selection));
  520.  
  521.   /*  the main vbox  */
  522.   vbox = gtk_vbox_new (FALSE, 0);
  523.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
  524.   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (gum->selection)->vbox), vbox);
  525.   gtk_widget_show (vbox);
  526.  
  527.   /*  the selection list  */
  528.   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  529.   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
  530.                   GTK_POLICY_NEVER,
  531.                   GTK_POLICY_ALWAYS);
  532.   gtk_container_add (GTK_CONTAINER (vbox), scrolled_win);
  533.   gtk_widget_show (scrolled_win);
  534.  
  535.   titles[0] = _("Unit");
  536.   titles[1] = _("Factor");
  537.   gum->clist = gtk_clist_new_with_titles (2, titles);
  538.   gtk_clist_set_shadow_type (GTK_CLIST (gum->clist), GTK_SHADOW_IN);
  539.   gtk_clist_set_selection_mode (GTK_CLIST (gum->clist), GTK_SELECTION_BROWSE);
  540.   gtk_clist_column_titles_passive (GTK_CLIST (gum->clist));
  541.   /*  the unit lines  */
  542.   num_units = gimp_unit_get_number_of_units ();
  543.   for (unit = GIMP_UNIT_END; unit < num_units; unit++)
  544.     {
  545.       row[0] = g_strdup (gimp_unit_menu_build_string (gum->format, unit));
  546.       row[1] = g_strdup (gimp_unit_menu_build_string ("(%f)", unit));
  547.  
  548.       gtk_clist_append (GTK_CLIST (gum->clist), row);
  549.       gtk_clist_set_row_data (GTK_CLIST (gum->clist),
  550.                   unit - GIMP_UNIT_END,
  551.                   (gpointer) unit);
  552.  
  553.       g_free (row[0]);
  554.       g_free (row[1]);
  555.     }
  556.  
  557.   unit_width   = gtk_clist_optimal_column_width (GTK_CLIST (gum->clist), 0);
  558.   factor_width = gtk_clist_optimal_column_width (GTK_CLIST (gum->clist), 1);
  559.  
  560.   gtk_clist_set_column_width (GTK_CLIST (gum->clist), 0, unit_width);
  561.   gtk_clist_set_column_width (GTK_CLIST (gum->clist), 1, factor_width);
  562.  
  563.   gtk_widget_set_usize (gum->clist, -1, 150);
  564.  
  565.   gtk_container_add (GTK_CONTAINER (scrolled_win), gum->clist);
  566.   gtk_signal_connect (GTK_OBJECT (gum->clist), "select_row",
  567.               GTK_SIGNAL_FUNC (gimp_unit_menu_selection_select_row_callback),
  568.               gum);
  569.   gtk_widget_show (gum->clist);
  570.  
  571.   gtk_signal_connect (GTK_OBJECT (gum->clist), "destroy",
  572.                       GTK_SIGNAL_FUNC (gtk_widget_destroyed),
  573.                       &gum->clist);
  574.  
  575.   gtk_widget_show (vbox);
  576.   gtk_widget_show (gum->selection);
  577.  
  578.   if (gum->unit >= GIMP_UNIT_END)
  579.     {
  580.       gtk_clist_select_row (GTK_CLIST (gum->clist), 
  581.                 gum->unit - GIMP_UNIT_END, 0);
  582.       gtk_clist_moveto (GTK_CLIST (gum->clist), 
  583.             gum->unit - GIMP_UNIT_END, 0, 0.0, 0.0); 
  584.     }
  585. }
  586.  
  587. static void
  588. gimp_unit_menu_callback (GtkWidget *widget,
  589.              gpointer   data)
  590. {
  591.   GimpUnitMenu *gum;
  592.   GimpUnit      new_unit;
  593.  
  594.   gum = data;
  595.   new_unit = (guint) gtk_object_get_data (GTK_OBJECT (widget),
  596.                       "gimp_unit_menu"); 
  597.   
  598.   if (gum->unit == new_unit)
  599.     return;
  600.  
  601.   /*  was "More..." selected?  */
  602.   if (new_unit == (GIMP_UNIT_PERCENT + 1))
  603.     {
  604.       gtk_option_menu_set_history (GTK_OPTION_MENU (gum),
  605.                    (gum->unit == GIMP_UNIT_PIXEL) ? 0 :
  606.                    ((gum->unit == GIMP_UNIT_PERCENT) ?
  607.                     (gum->show_pixels ? 1 : 0) :
  608.                     ((gum->show_pixels ||
  609.                       gum->show_percent ? 2 : 0) +
  610.                      (gum->show_pixels &&
  611.                       gum->show_percent ? 1 : 0) +
  612.                      ((gum->unit < GIMP_UNIT_END) ?
  613.                       gum->unit - 1 : GIMP_UNIT_END))));
  614.       if (! gum->selection)
  615.     gimp_unit_menu_create_selection (gum);
  616.       return;
  617.     }
  618.   else if (gum->selection)
  619.     {
  620.       gtk_widget_destroy (gum->selection);
  621.     }
  622.  
  623.   gimp_unit_menu_set_unit (gum, new_unit);
  624.   gtk_signal_emit (GTK_OBJECT (gum),
  625.            gimp_unit_menu_signals[UNIT_CHANGED]);
  626. }
  627.