gimp/app/gui/info-dialog.c
Michael Natterer 7ee99ea3a3 Transform tool cleanup:
2002-11-14  Michael Natterer  <mitch@gimp.org>

	Transform tool cleanup:

	* libgimptool/gimptoolenums.[ch]: removed the TransformState enum.

	* app/tools/gimptransformtool.[ch]: don't dispatch everything
	through the transform() virtual function. Added new vitrual
	functions dialog(), prepare(), motion() and recalc(). Do only the
	actual transform in transform(). Moved lots of logic which was
	duplicated in each subclass' transform() here. Cleanup.

	* app/tools/gimpfliptool.c
	* app/tools/gimpperspectivetool.c
	* app/tools/gimprotatetool.c
	* app/tools/gimpscaletool.c
	* app/tools/gimpsheartool.c: changed accordingly: moved code from
	transform() to the other method imlementations. Removed duplicated
	logic which is now done by our parent class. Makes everything
	smaller and more readable.

	InfoDialog cleanup:

	* app/gui/info-dialog.c: removed the "delete_event" callback so
	InfoDialog users can decide themselves what to do.

	* app/gui/info-window.c
	* app/tools/gimpmeasuretool.c: changed accordingly.

	* app/tools/gimpcolorpickertool.c: ditto. Moved info_dialog
	creation to a utility function to improve code readbility.

	* app/tools/gimpcroptool.c: ditto. Added a "Cancel" button which
	really cancels the tool instead of just hiding the dialog.

	* app/tools/gimptransformtool.c: added a "Cancel" button here too.
2002-11-14 11:54:57 +00:00

470 lines
14 KiB
C

/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "gui-types.h"
#include "widgets/gimpviewabledialog.h"
#include "info-dialog.h"
#include "libgimp/gimpintl.h"
#define SB_WIDTH 10
/* local function prototypes */
static InfoDialog * info_dialog_new_extended (GimpViewable *viewable,
const gchar *title,
const gchar *wmclass_name,
const gchar *stock_id,
const gchar *desc,
GimpHelpFunc help_func,
gpointer help_data,
gboolean in_notebook);
static void info_dialog_field_new (InfoDialog *idialog,
InfoFieldType field_type,
gchar *title,
GtkWidget *widget,
GtkObject *object,
gpointer value_ptr,
GCallback callback,
gpointer callback_data);
static void info_dialog_update_field (InfoField *info_field);
/* public functions */
InfoDialog *
info_dialog_new (GimpViewable *viewable,
const gchar *title,
const gchar *wmclass_name,
const gchar *stock_id,
const gchar *desc,
GimpHelpFunc help_func,
gpointer help_data)
{
return info_dialog_new_extended (viewable, title, wmclass_name,
stock_id, desc,
help_func, help_data, FALSE);
}
InfoDialog *
info_dialog_notebook_new (GimpViewable *viewable,
const gchar *title,
const gchar *wmclass_name,
const gchar *stock_id,
const gchar *desc,
GimpHelpFunc help_func,
gpointer help_data)
{
return info_dialog_new_extended (viewable, title, wmclass_name,
stock_id, desc,
help_func, help_data, TRUE);
}
void
info_dialog_free (InfoDialog *idialog)
{
g_return_if_fail (idialog != NULL);
g_slist_foreach (idialog->field_list, (GFunc) g_free, NULL);
g_slist_free (idialog->field_list);
gtk_widget_destroy (idialog->shell);
g_free (idialog);
}
void
info_dialog_popup (InfoDialog *idialog)
{
g_return_if_fail (idialog != NULL);
if (! GTK_WIDGET_VISIBLE (idialog->shell))
gtk_widget_show (idialog->shell);
}
void
info_dialog_popdown (InfoDialog *idialog)
{
g_return_if_fail (idialog != NULL);
if (GTK_WIDGET_VISIBLE (idialog->shell))
gtk_widget_hide (idialog->shell);
}
void
info_dialog_update (InfoDialog *idialog)
{
GSList *list;
g_return_if_fail (idialog != NULL);
for (list = idialog->field_list; list; list = g_slist_next (list))
info_dialog_update_field ((InfoField *) list->data);
}
GtkWidget *
info_dialog_add_label (InfoDialog *idialog,
gchar *title,
gchar *text_ptr)
{
GtkWidget *label;
g_return_val_if_fail (idialog != NULL, NULL);
label = gtk_label_new (text_ptr);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
info_dialog_field_new (idialog, INFO_LABEL, title, label, NULL,
text_ptr,
NULL, NULL);
return label;
}
GtkWidget *
info_dialog_add_entry (InfoDialog *idialog,
gchar *title,
gchar *text_ptr,
GCallback callback,
gpointer callback_data)
{
GtkWidget *entry;
g_return_val_if_fail (idialog != NULL, NULL);
entry = gtk_entry_new ();
gtk_widget_set_size_request (entry, 50, -1);
gtk_entry_set_text (GTK_ENTRY (entry), text_ptr ? text_ptr : "");
if (callback)
g_signal_connect (G_OBJECT (entry), "changed",
callback,
callback_data);
info_dialog_field_new (idialog, INFO_ENTRY, title, entry, NULL,
text_ptr,
callback, callback_data);
return entry;
}
GtkWidget *
info_dialog_add_scale (InfoDialog *idialog,
gchar *title,
gdouble *value_ptr,
gfloat lower,
gfloat upper,
gfloat step_increment,
gfloat page_increment,
gfloat page_size,
gint digits,
GCallback callback,
gpointer callback_data)
{
GtkObject *adjustment;
GtkWidget *scale;
g_return_val_if_fail (idialog != NULL, NULL);
adjustment = gtk_adjustment_new (value_ptr ? *value_ptr : 0, lower, upper,
step_increment, page_increment, page_size);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
if (digits >= 0)
gtk_scale_set_digits (GTK_SCALE (scale), MAX (digits, 6));
else
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
if (callback)
g_signal_connect (G_OBJECT (adjustment), "value_changed",
callback,
callback_data);
info_dialog_field_new (idialog, INFO_SCALE, title, scale, adjustment,
value_ptr,
callback, callback_data);
return scale;
}
GtkWidget *
info_dialog_add_spinbutton (InfoDialog *idialog,
gchar *title,
gdouble *value_ptr,
gfloat lower,
gfloat upper,
gfloat step_increment,
gfloat page_increment,
gfloat page_size,
gfloat climb_rate,
gint digits,
GCallback callback,
gpointer callback_data)
{
GtkWidget *alignment;
GtkObject *adjustment;
GtkWidget *spinbutton;
g_return_val_if_fail (idialog != NULL, NULL);
alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
spinbutton = gimp_spin_button_new (&adjustment,
value_ptr ? *value_ptr : 0,
lower, upper,
step_increment, page_increment, page_size,
climb_rate, MAX (MIN (digits, 6), 0));
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
if (callback)
g_signal_connect (G_OBJECT (adjustment), "value_changed",
callback,
callback_data);
gtk_container_add (GTK_CONTAINER (alignment), spinbutton);
gtk_widget_show (spinbutton);
info_dialog_field_new (idialog, INFO_SPINBUTTON, title, alignment,
adjustment,
value_ptr,
callback, callback_data);
return spinbutton;
}
GtkWidget *
info_dialog_add_sizeentry (InfoDialog *idialog,
gchar *title,
gdouble *value_ptr,
gint nfields,
GimpUnit unit,
gchar *unit_format,
gboolean menu_show_pixels,
gboolean menu_show_percent,
gboolean show_refval,
GimpSizeEntryUpdatePolicy update_policy,
GCallback callback,
gpointer callback_data)
{
GtkWidget *alignment;
GtkWidget *sizeentry;
gint i;
g_return_val_if_fail (idialog != NULL, NULL);
alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
sizeentry = gimp_size_entry_new (nfields, unit, unit_format,
menu_show_pixels, menu_show_percent,
show_refval, SB_WIDTH,
update_policy);
if (value_ptr)
for (i = 0; i < nfields; i++)
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), i, value_ptr[i]);
if (callback)
g_signal_connect (G_OBJECT (sizeentry), "value_changed",
callback,
callback_data);
gtk_container_add (GTK_CONTAINER (alignment), sizeentry);
gtk_widget_show (sizeentry);
info_dialog_field_new (idialog, INFO_SIZEENTRY, title, alignment,
GTK_OBJECT (sizeentry),
value_ptr,
callback, callback_data);
return sizeentry;
}
/* private functions */
static InfoDialog *
info_dialog_new_extended (GimpViewable *viewable,
const gchar *title,
const gchar *wmclass_name,
const gchar *stock_id,
const gchar *desc,
GimpHelpFunc help_func,
gpointer help_data,
gboolean in_notebook)
{
InfoDialog *idialog;
GtkWidget *shell;
GtkWidget *vbox;
GtkWidget *info_table;
GtkWidget *info_notebook;
idialog = g_new (InfoDialog, 1);
idialog->field_list = NULL;
idialog->nfields = 0;
shell = gimp_viewable_dialog_new (viewable,
title, wmclass_name,
stock_id, desc,
help_func, help_data,
NULL);
vbox = gtk_vbox_new (FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell)->vbox), vbox);
info_table = gtk_table_new (2, 0, FALSE);
if (in_notebook)
{
info_notebook = gtk_notebook_new ();
gtk_container_set_border_width (GTK_CONTAINER (info_table), 4);
gtk_notebook_append_page (GTK_NOTEBOOK (info_notebook),
info_table,
gtk_label_new (_("General")));
gtk_box_pack_start (GTK_BOX (vbox), info_notebook, FALSE, FALSE, 0);
}
else
{
info_notebook = NULL;
gtk_box_pack_start (GTK_BOX (vbox), info_table, FALSE, FALSE, 0);
}
idialog->shell = shell;
idialog->vbox = vbox;
idialog->info_table = info_table;
idialog->info_notebook = info_notebook;
if (in_notebook)
gtk_widget_show (idialog->info_notebook);
gtk_widget_show (idialog->info_table);
gtk_widget_show (idialog->vbox);
return idialog;
}
static void
info_dialog_field_new (InfoDialog *idialog,
InfoFieldType field_type,
gchar *title,
GtkWidget *widget,
GtkObject *obj,
gpointer value_ptr,
GCallback callback,
gpointer callback_data)
{
GtkWidget *label;
InfoField *field;
gint row;
field = g_new (InfoField, 1);
row = idialog->nfields + 1;
gtk_table_resize (GTK_TABLE (idialog->info_table), 2, row);
label = gtk_label_new (title);
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (idialog->info_table), label,
0, 1, row - 1, row,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (label);
gtk_table_attach_defaults (GTK_TABLE (idialog->info_table), widget,
1, 2, row - 1, row);
gtk_widget_show (widget);
gtk_table_set_col_spacing (GTK_TABLE (idialog->info_table), 0, 6);
gtk_table_set_row_spacings (GTK_TABLE (idialog->info_table), 2);
field->field_type = field_type;
if (obj == NULL)
field->obj = GTK_OBJECT (widget);
else
field->obj = obj;
field->value_ptr = value_ptr;
field->callback = callback;
field->callback_data = callback_data;
idialog->field_list = g_slist_prepend (idialog->field_list, field);
idialog->nfields++;
}
static void
info_dialog_update_field (InfoField *field)
{
const gchar *old_text;
gint num;
gint i;
if (field->value_ptr == NULL)
return;
if (field->field_type != INFO_LABEL)
g_signal_handlers_block_by_func (G_OBJECT (field->obj),
field->callback,
field->callback_data);
switch (field->field_type)
{
case INFO_LABEL:
gtk_label_set_text (GTK_LABEL (field->obj), (gchar *) field->value_ptr);
break;
case INFO_ENTRY:
old_text = gtk_entry_get_text (GTK_ENTRY (field->obj));
if (strcmp (old_text, (gchar *) field->value_ptr))
gtk_entry_set_text (GTK_ENTRY (field->obj), (gchar *) field->value_ptr);
break;
case INFO_SCALE:
case INFO_SPINBUTTON:
gtk_adjustment_set_value (GTK_ADJUSTMENT (field->obj),
*((gdouble *) field->value_ptr));
break;
case INFO_SIZEENTRY:
num = GIMP_SIZE_ENTRY (field->obj)->number_of_fields;
for (i = 0; i < num; i++)
gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (field->obj), i,
((gdouble *) field->value_ptr)[i]);
break;
default:
g_warning ("%s: Unknown info_dialog field type.", G_STRLOC);
break;
}
if (field->field_type != INFO_LABEL)
g_signal_handlers_unblock_by_func (G_OBJECT (field->obj),
field->callback,
field->callback_data);
}