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

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18. #include "config.h"
  19.  
  20. #include <string.h>
  21.  
  22. #include <gtk/gtk.h>
  23.  
  24. #include "apptypes.h"
  25.  
  26. #include "appenv.h"
  27. #include "dialog_handler.h"
  28. #include "gimprc.h"
  29. #include "gimpui.h"
  30. #include "info_dialog.h"
  31. #include "session.h"
  32.  
  33. #include "libgimp/gimpintl.h"
  34.  
  35.  
  36. /*  static functions  */
  37. static void info_field_new (InfoDialog *, InfoFieldType, char *, GtkWidget *,
  38.                 GtkObject *, void *, GtkSignalFunc, gpointer);
  39. static void update_field   (InfoField *);
  40. static gint info_dialog_delete_callback (GtkWidget *, GdkEvent *, gpointer);
  41.  
  42. static void
  43. info_field_new (InfoDialog    *idialog,
  44.         InfoFieldType  field_type,
  45.         gchar         *title,
  46.         GtkWidget     *widget,
  47.         GtkObject     *obj,
  48.         void          *value_ptr,
  49.         GtkSignalFunc  callback,
  50.         gpointer       client_data)
  51. {
  52.   GtkWidget *label;
  53.   InfoField *field;
  54.   gint       row;
  55.  
  56.   field = g_new (InfoField, 1);
  57.  
  58.   row = idialog->nfields + 1;
  59.   gtk_table_resize (GTK_TABLE (idialog->info_table), 2, row);
  60.  
  61.   label = gtk_label_new (title);
  62.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  63.   gtk_table_attach (GTK_TABLE (idialog->info_table), label,
  64.             0, 1, row - 1, row,
  65.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  66.   gtk_widget_show (label);
  67.  
  68.   gtk_table_attach_defaults (GTK_TABLE (idialog->info_table), widget,
  69.                  1, 2, row - 1, row);
  70.   gtk_widget_show (widget);
  71.  
  72.   gtk_table_set_col_spacing (GTK_TABLE (idialog->info_table), 0, 6);
  73.   gtk_table_set_row_spacings (GTK_TABLE (idialog->info_table), 2);
  74.  
  75.   field->field_type = field_type;
  76.   if (obj == NULL)
  77.     field->obj = GTK_OBJECT (widget);
  78.   else
  79.     field->obj = obj;
  80.   field->value_ptr = value_ptr;
  81.   field->callback = callback;
  82.   field->client_data = client_data;
  83.  
  84.   idialog->field_list =
  85.     g_slist_prepend (idialog->field_list, (void *) field);
  86.   idialog->nfields++;
  87. }
  88.  
  89. static void
  90. update_field (InfoField *field)
  91. {
  92.   gchar *old_text;
  93.   gint   num;
  94.   gint   i;
  95.  
  96.   if (field->value_ptr == NULL)
  97.     return;
  98.  
  99.   if (field->field_type != INFO_LABEL)
  100.     gtk_signal_handler_block_by_data (GTK_OBJECT (field->obj),
  101.                       field->client_data);
  102.  
  103.   switch (field->field_type)
  104.     {
  105.     case INFO_LABEL:
  106.       gtk_label_get (GTK_LABEL (field->obj), &old_text);
  107.       if (strcmp (old_text, (gchar*) field->value_ptr))
  108.     gtk_label_set_text (GTK_LABEL (field->obj), (gchar*) field->value_ptr);
  109.       break;
  110.  
  111.     case INFO_ENTRY:
  112.       old_text = gtk_entry_get_text (GTK_ENTRY (field->obj));
  113.       if (strcmp (old_text, (gchar*) field->value_ptr))
  114.     gtk_entry_set_text (GTK_ENTRY (field->obj), (gchar*) field->value_ptr);
  115.       break;
  116.  
  117.     case INFO_SCALE:
  118.     case INFO_SPINBUTTON:
  119.       gtk_adjustment_set_value (GTK_ADJUSTMENT (field->obj),
  120.                 *((gdouble*) field->value_ptr));
  121.       break;
  122.  
  123.     case INFO_SIZEENTRY:
  124.       num = GIMP_SIZE_ENTRY (field->obj)->number_of_fields;
  125.       for (i = 0; i < num; i++)
  126.     gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (field->obj), i,
  127.                     ((gdouble*) field->value_ptr)[i]);
  128.       break;
  129.  
  130.     default:
  131.       g_warning ("Unknown info_dialog field type.");
  132.       break;
  133.     }
  134.  
  135.   if (field->field_type != INFO_LABEL)
  136.     gtk_signal_handler_unblock_by_data (GTK_OBJECT (field->obj),
  137.                     field->client_data);
  138. }
  139.  
  140. static gint
  141. info_dialog_delete_callback (GtkWidget *widget,
  142.                  GdkEvent  *event,
  143.                  gpointer   data)
  144. {
  145.   info_dialog_popdown ((InfoDialog *) data);
  146.  
  147.   return TRUE;
  148. }
  149.  
  150. static InfoDialog *
  151. info_dialog_new_extended (gchar        *title,
  152.               GimpHelpFunc  help_func,
  153.               gpointer      help_data,
  154.               gboolean      in_notebook)
  155. {
  156.   InfoDialog *idialog;
  157.   GtkWidget  *shell;
  158.   GtkWidget  *vbox;
  159.   GtkWidget  *info_table;
  160.   GtkWidget  *info_notebook;
  161.  
  162.   idialog = g_new (InfoDialog, 1);
  163.   idialog->field_list = NULL;
  164.   idialog->nfields    = 0;
  165.  
  166.   shell = gtk_dialog_new ();
  167.   gtk_window_set_wmclass (GTK_WINDOW (shell), "info_dialog", "Gimp");
  168.   gtk_window_set_title (GTK_WINDOW (shell), title);
  169.   session_set_window_geometry (shell, &info_dialog_session_info, FALSE );
  170.  
  171.   dialog_register (shell);
  172.  
  173.   gtk_signal_connect (GTK_OBJECT (shell), "delete_event",
  174.               GTK_SIGNAL_FUNC (info_dialog_delete_callback),
  175.               idialog);
  176.  
  177.   vbox = gtk_vbox_new (FALSE, 0);
  178.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  179.   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell)->vbox), vbox);
  180.  
  181.   info_table = gtk_table_new (2, 0, FALSE);
  182.  
  183.   if (in_notebook)
  184.     {
  185.       info_notebook = gtk_notebook_new ();
  186.       gtk_container_set_border_width (GTK_CONTAINER (info_table), 4);
  187.       gtk_notebook_append_page (GTK_NOTEBOOK (info_notebook),
  188.                 info_table,
  189.                 gtk_label_new (_("General")));
  190.       gtk_box_pack_start (GTK_BOX (vbox), info_notebook, FALSE, FALSE, 0);
  191.     }
  192.   else
  193.     {
  194.       info_notebook = NULL;
  195.       gtk_box_pack_start (GTK_BOX (vbox), info_table, FALSE, FALSE, 0);
  196.     }
  197.  
  198.   idialog->shell = shell;
  199.   idialog->vbox = vbox;
  200.   idialog->info_table = info_table;
  201.   idialog->info_notebook = info_notebook;
  202.  
  203.   if (in_notebook)
  204.     gtk_widget_show (idialog->info_notebook);
  205.  
  206.   gtk_widget_show (idialog->info_table);
  207.   gtk_widget_show (idialog->vbox);
  208.  
  209.   /*  Connect the "F1" help key  */
  210.   gimp_help_connect_help_accel (idialog->shell, help_func, help_data);
  211.  
  212.   return idialog;
  213. }
  214.  
  215. /*  public functions  */
  216.  
  217. InfoDialog *
  218. info_dialog_notebook_new (gchar        *title,
  219.               GimpHelpFunc  help_func,
  220.               gpointer      help_data)
  221. {
  222.   return info_dialog_new_extended (title, help_func, help_data, TRUE);
  223. }
  224.  
  225. InfoDialog *
  226. info_dialog_new (gchar        *title,
  227.          GimpHelpFunc  help_func,
  228.          gpointer      help_data)
  229. {
  230.   return info_dialog_new_extended (title, help_func, help_data, FALSE);
  231. }
  232.  
  233. void
  234. info_dialog_free (InfoDialog *idialog)
  235. {
  236.   GSList *list;
  237.  
  238.   g_return_if_fail (idialog != NULL);
  239.  
  240.   /*  Free each item in the field list  */
  241.   for (list = idialog->field_list; list; list = g_slist_next (list))
  242.     g_free (list->data);
  243.  
  244.   /*  Free the actual field linked list  */
  245.   g_slist_free (idialog->field_list);
  246.  
  247.   dialog_unregister (idialog->shell);
  248.  
  249.   session_get_window_info (idialog->shell, &info_dialog_session_info);
  250.  
  251.   /*  Destroy the associated widgets  */
  252.   gtk_widget_destroy (idialog->shell);
  253.  
  254.   /*  Free the info dialog memory  */
  255.   g_free (idialog);
  256. }
  257.  
  258. void
  259. info_dialog_popup (InfoDialog *idialog)
  260. {
  261.   if (! idialog)
  262.     return;
  263.  
  264.   if (! GTK_WIDGET_VISIBLE (idialog->shell))
  265.     gtk_widget_show (idialog->shell);
  266.  
  267. }
  268.  
  269. void
  270. info_dialog_popdown (InfoDialog *idialog)
  271. {
  272.   if (! idialog)
  273.     return;
  274.   
  275.   if (GTK_WIDGET_VISIBLE (idialog->shell))
  276.     gtk_widget_hide (idialog->shell);
  277. }
  278.  
  279. void
  280. info_dialog_update (InfoDialog *idialog)
  281. {
  282.   GSList *list;
  283.  
  284.   if (! idialog)
  285.     return;
  286.  
  287.   for (list = idialog->field_list; list; list = g_slist_next (list))
  288.     update_field ((InfoField *) list->data);
  289. }
  290.  
  291. GtkWidget *
  292. info_dialog_add_label (InfoDialog    *idialog,
  293.                char          *title,
  294.                char          *text_ptr)
  295. {
  296.   GtkWidget *label;
  297.  
  298.   g_return_val_if_fail (idialog != NULL, NULL);
  299.  
  300.   label = gtk_label_new (text_ptr);
  301.   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  302.  
  303.   info_field_new (idialog, INFO_LABEL, title, label, NULL, (void*) text_ptr,
  304.           NULL, NULL);
  305.  
  306.   return label;
  307. }
  308.  
  309. GtkWidget *
  310. info_dialog_add_entry (InfoDialog    *idialog,
  311.                char          *title,
  312.                char          *text_ptr,
  313.                GtkSignalFunc  callback,
  314.                gpointer       data)
  315. {
  316.   GtkWidget *entry;
  317.  
  318.   g_return_val_if_fail (idialog != NULL, NULL);
  319.  
  320.   entry = gtk_entry_new ();
  321.   gtk_widget_set_usize (entry, 50, 0);
  322.   gtk_entry_set_text (GTK_ENTRY (entry), text_ptr ? text_ptr : "");
  323.  
  324.   if (callback)
  325.     gtk_signal_connect (GTK_OBJECT (entry), "changed",
  326.             GTK_SIGNAL_FUNC (callback), data);
  327.  
  328.   info_field_new (idialog, INFO_ENTRY, title, entry, NULL, (void*) text_ptr,
  329.           callback, data);
  330.  
  331.   return entry;
  332. }
  333.  
  334. GtkWidget *
  335. info_dialog_add_scale   (InfoDialog    *idialog,
  336.              gchar         *title,
  337.              gdouble       *value_ptr,
  338.              gfloat         lower,
  339.              gfloat         upper,
  340.              gfloat         step_increment,
  341.              gfloat         page_increment,
  342.              gfloat         page_size,
  343.              gint           digits,
  344.              GtkSignalFunc  callback,
  345.              gpointer       data)
  346. {
  347.   GtkObject *adjustment;
  348.   GtkWidget *scale;
  349.  
  350.   g_return_val_if_fail (idialog != NULL, NULL);
  351.  
  352.   adjustment = gtk_adjustment_new (value_ptr ? *value_ptr : 0, lower, upper,
  353.                    step_increment, page_increment, page_size);
  354.   scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
  355.  
  356.   if (digits >= 0)
  357.     gtk_scale_set_digits (GTK_SCALE (scale), MAX (digits, 6));
  358.   else
  359.     gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
  360.  
  361.   if (callback)
  362.     gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
  363.             GTK_SIGNAL_FUNC (callback), data);
  364.  
  365.   info_field_new (idialog, INFO_SCALE, title, scale, adjustment,
  366.           (void*) value_ptr, callback, data);
  367.  
  368.   return scale;
  369. }
  370.  
  371. GtkWidget *
  372. info_dialog_add_spinbutton (InfoDialog    *idialog,
  373.                 gchar         *title,
  374.                 gdouble       *value_ptr,
  375.                 gfloat         lower,
  376.                 gfloat         upper,
  377.                 gfloat         step_increment,
  378.                 gfloat         page_increment,
  379.                 gfloat         page_size,
  380.                 gfloat         climb_rate,
  381.                 gint           digits,
  382.                 GtkSignalFunc  callback,
  383.                 gpointer       data)
  384. {
  385.   GtkWidget *alignment;
  386.   GtkObject *adjustment;
  387.   GtkWidget *spinbutton;
  388.  
  389.   g_return_val_if_fail (idialog != NULL, NULL);
  390.  
  391.   alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
  392.  
  393.   adjustment = gtk_adjustment_new (value_ptr ? *value_ptr : 0, lower, upper,
  394.                    step_increment, page_increment, page_size);
  395.   spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment),
  396.                     climb_rate, MAX (MIN (digits, 6), 0));
  397.   gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
  398.                    GTK_SHADOW_NONE);
  399.   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
  400.   gtk_widget_set_usize (spinbutton, 75, 0);
  401.  
  402.   if (callback)
  403.     gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
  404.             GTK_SIGNAL_FUNC (callback), data);
  405.  
  406.   gtk_container_add (GTK_CONTAINER (alignment), spinbutton);
  407.   gtk_widget_show (spinbutton);
  408.  
  409.   info_field_new (idialog, INFO_SPINBUTTON, title, alignment, adjustment,
  410.           (void*) value_ptr, callback, data);
  411.  
  412.   return spinbutton;
  413. }
  414.  
  415. GtkWidget *
  416. info_dialog_add_sizeentry (InfoDialog                *idialog,
  417.                gchar                     *title,
  418.                gdouble                   *value_ptr,
  419.                gint                       nfields,
  420.                GimpUnit                   unit,
  421.                gchar                     *unit_format,
  422.                gboolean                   menu_show_pixels,
  423.                gboolean                   menu_show_percent,
  424.                gboolean                   show_refval,
  425.                GimpSizeEntryUpdatePolicy  update_policy,
  426.                GtkSignalFunc              callback,
  427.                gpointer                   data)
  428. {
  429.   GtkWidget *alignment;
  430.   GtkWidget *sizeentry;
  431.   gint       i;
  432.  
  433.   g_return_val_if_fail (idialog != NULL, NULL);
  434.  
  435.   alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
  436.  
  437.   sizeentry = gimp_size_entry_new (nfields, unit, unit_format,
  438.                    menu_show_pixels, menu_show_percent,
  439.                    show_refval, 75,
  440.                    update_policy);
  441.   if (value_ptr)
  442.     for (i = 0; i < nfields; i++)
  443.       gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), i, value_ptr[i]);
  444.  
  445.   if (callback)
  446.     gtk_signal_connect (GTK_OBJECT (sizeentry), "value_changed",
  447.             GTK_SIGNAL_FUNC (callback), data);
  448.  
  449.   gtk_container_add (GTK_CONTAINER (alignment), sizeentry);
  450.   gtk_widget_show (sizeentry);
  451.  
  452.   info_field_new (idialog, INFO_SIZEENTRY, title, alignment,
  453.           GTK_OBJECT (sizeentry),
  454.           (void*) value_ptr, callback, data);
  455.  
  456.   return sizeentry;
  457. }
  458.